Merge branch '7.0.1' of https://github.com/umbraco/Umbraco-CMS into 7.0.1
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using HtmlAgilityPack;
|
||||
|
||||
namespace Umbraco.Core.Macros
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace Umbraco.Core.Macros
|
||||
/// </summary>
|
||||
internal class MacroTagParser
|
||||
{
|
||||
private static readonly Regex MacroRteContent = new Regex(@"(<div.*?>.*?<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(.*?</div>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
private static readonly Regex MacroRteContent = new Regex(@"(<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(\s*?-->)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO macroAlias=[""'](\w+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
|
||||
/// <summary>
|
||||
@@ -88,7 +89,33 @@ namespace Umbraco.Core.Macros
|
||||
/// </remarks>
|
||||
internal static string FormatRichTextContentForPersistence(string rteContent)
|
||||
{
|
||||
return MacroRteContent.Replace(rteContent, match =>
|
||||
if (string.IsNullOrEmpty(rteContent))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var html = new HtmlDocument();
|
||||
html.LoadHtml(rteContent);
|
||||
|
||||
//get all the comment nodes we want
|
||||
var commentNodes = html.DocumentNode.SelectNodes("//comment()[contains(., '<?UMBRACO_MACRO')]");
|
||||
if (commentNodes == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//replace each containing parent <div> with the comment node itself.
|
||||
foreach (var c in commentNodes)
|
||||
{
|
||||
var div = c.ParentNode;
|
||||
var divContainer = div.ParentNode;
|
||||
divContainer.ReplaceChild(c, div);
|
||||
}
|
||||
|
||||
var parsed = html.DocumentNode.OuterHtml;
|
||||
|
||||
//now replace all the <!-- and --> with nothing
|
||||
return MacroRteContent.Replace(parsed, match =>
|
||||
{
|
||||
if (match.Groups.Count >= 3)
|
||||
{
|
||||
@@ -96,7 +123,7 @@ namespace Umbraco.Core.Macros
|
||||
return match.Groups[2].Value;
|
||||
}
|
||||
//replace with nothing if we couldn't find the syntax for whatever reason
|
||||
return "";
|
||||
return string.Empty;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
|
||||
|
||||
public IDeleteColumnFromTableSyntax Column(string columnName)
|
||||
{
|
||||
var expression = _databaseProviders == null
|
||||
var expression = _databaseProviders == null
|
||||
? new DeleteColumnExpression { ColumnNames = { columnName } }
|
||||
: new DeleteColumnExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ColumnNames = { columnName } };
|
||||
_context.Expressions.Add(expression);
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
|
||||
|
||||
public IDeleteForeignKeyFromTableSyntax ForeignKey()
|
||||
{
|
||||
var expression = _databaseProviders == null
|
||||
var expression = _databaseProviders == null
|
||||
? new DeleteForeignKeyExpression()
|
||||
: new DeleteForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders);
|
||||
_context.Expressions.Add(expression);
|
||||
@@ -45,7 +45,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
|
||||
|
||||
public IDeleteForeignKeyOnTableSyntax ForeignKey(string foreignKeyName)
|
||||
{
|
||||
var expression = _databaseProviders == null
|
||||
var expression = _databaseProviders == null
|
||||
? new DeleteForeignKeyExpression { ForeignKey = { Name = foreignKeyName } }
|
||||
: new DeleteForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ForeignKey = { Name = foreignKeyName } };
|
||||
_context.Expressions.Add(expression);
|
||||
@@ -68,17 +68,17 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
|
||||
|
||||
public IDeleteIndexForTableSyntax Index(string indexName)
|
||||
{
|
||||
var expression = new DeleteIndexExpression {Index = {Name = indexName}};
|
||||
var expression = new DeleteIndexExpression { Index = { Name = indexName } };
|
||||
_context.Expressions.Add(expression);
|
||||
return new DeleteIndexBuilder(expression);
|
||||
}
|
||||
|
||||
public IDeleteConstraintOnTableSyntax PrimaryKey(string primaryKeyName)
|
||||
{
|
||||
var expression = new DeleteConstraintExpression(ConstraintType.PrimaryKey)
|
||||
{
|
||||
Constraint = { ConstraintName = primaryKeyName }
|
||||
};
|
||||
var expression = new DeleteConstraintExpression(_context.CurrentDatabaseProvider, _databaseProviders, ConstraintType.PrimaryKey)
|
||||
{
|
||||
Constraint = { ConstraintName = primaryKeyName }
|
||||
};
|
||||
_context.Expressions.Add(expression);
|
||||
return new DeleteConstraintBuilder(expression);
|
||||
}
|
||||
@@ -86,16 +86,16 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
|
||||
public IDeleteConstraintOnTableSyntax UniqueConstraint(string constraintName)
|
||||
{
|
||||
var expression = new DeleteConstraintExpression(ConstraintType.Unique)
|
||||
{
|
||||
Constraint = { ConstraintName = constraintName }
|
||||
};
|
||||
{
|
||||
Constraint = { ConstraintName = constraintName }
|
||||
};
|
||||
_context.Expressions.Add(expression);
|
||||
return new DeleteConstraintBuilder(expression);
|
||||
}
|
||||
|
||||
public IDeleteDefaultConstraintOnTableSyntax DefaultConstraint()
|
||||
{
|
||||
var expression = _databaseProviders == null
|
||||
var expression = _databaseProviders == null
|
||||
? new DeleteDefaultConstraintExpression()
|
||||
: new DeleteDefaultConstraintExpression(_context.CurrentDatabaseProvider, _databaseProviders);
|
||||
_context.Expressions.Add(expression);
|
||||
|
||||
@@ -10,13 +10,40 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
Constraint = new ConstraintDefinition(type);
|
||||
}
|
||||
|
||||
public DeleteConstraintExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders, ConstraintType type)
|
||||
: base(current, databaseProviders)
|
||||
{
|
||||
Constraint = new ConstraintDefinition(type);
|
||||
}
|
||||
|
||||
public ConstraintDefinition Constraint { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
// Test for MySQL primary key situation.
|
||||
if (CurrentDatabaseProvider == DatabaseProviders.MySql)
|
||||
{
|
||||
if (Constraint.IsPrimaryKeyConstraint)
|
||||
{
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
"PRIMARY KEY",
|
||||
"");
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
"FOREIGN KEY",
|
||||
"");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
if (ForeignKey.ForeignTable == null)
|
||||
throw new ArgumentNullException("Table name not specified, ensure you have appended the OnTable extension. Format should be Delete.ForeignKey(KeyName).OnTable(TableName)");
|
||||
|
||||
if(CurrentDatabaseProvider == DatabaseProviders.MySql)
|
||||
if (CurrentDatabaseProvider == DatabaseProviders.MySql)
|
||||
{
|
||||
//MySql naming "convention" for foreignkeys, which aren't explicitly named
|
||||
if (string.IsNullOrEmpty(ForeignKey.Name))
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
|
||||
"FOREIGN KEY ",
|
||||
"FOREIGN KEY",
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
//create a new col which we will make a foreign key, but first needs to be populated with data.
|
||||
Alter.Table("cmsTagRelationship").AddColumn("propertyTypeId").AsInt32().Nullable();
|
||||
|
||||
//drop the foreign key on umbracoNode. Must drop foreign key first before primary key can be removed in MySql.
|
||||
Delete.ForeignKey("FK_cmsTagRelationship_umbracoNode_id").OnTable("cmsTagRelationship");
|
||||
|
||||
//we need to drop the primary key
|
||||
Delete.PrimaryKey("PK_cmsTagRelationship").FromTable("cmsTagRelationship");
|
||||
|
||||
//drop the foreign key on umbracoNode
|
||||
Delete.ForeignKey("FK_cmsTagRelationship_umbracoNode_id").OnTable("cmsTagRelationship");
|
||||
}
|
||||
|
||||
private void Upgrade()
|
||||
@@ -57,9 +57,9 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
var propertyTypes = propertyTypeIdRef.Where(x => x.NodeId == tr.NodeId).ToArray();
|
||||
if (propertyTypes.Length == 0)
|
||||
{
|
||||
LogHelper.Warn<AlterTagRelationsTable>("There was no cmsContent reference for cmsTagRelationship for nodeId "
|
||||
LogHelper.Warn<AlterTagRelationsTable>("There was no cmsContent reference for cmsTagRelationship for nodeId "
|
||||
+ tr.NodeId +
|
||||
". The new tag system only supports tags with references to content in the cmsContent and cmsPropertyType tables. This row will be deleted: "
|
||||
". The new tag system only supports tags with references to content in the cmsContent and cmsPropertyType tables. This row will be deleted: "
|
||||
+ string.Format("nodeId: {0}, tagId: {1}", tr.NodeId, tr.TagId));
|
||||
Delete.FromTable("cmsTagRelationship").Row(new { nodeId = tr.NodeId, tagId = tr.TagId });
|
||||
}
|
||||
@@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
Alter.Table("cmsTagRelationship").AlterColumn("propertyTypeId").AsInt32().NotNullable();
|
||||
|
||||
//we need to re-add the new primary key on all 3 columns
|
||||
Create.PrimaryKey("PK_cmsTagRelationship").OnTable("cmsTagRelationship").Columns(new[] {"nodeId", "propertyTypeId", "tagId"});
|
||||
Create.PrimaryKey("PK_cmsTagRelationship").OnTable("cmsTagRelationship").Columns(new[] { "nodeId", "propertyTypeId", "tagId" });
|
||||
|
||||
//now we need to add a foreign key to the propertyTypeId column and change it's constraints
|
||||
Create.ForeignKey("FK_cmsTagRelationship_cmsPropertyType")
|
||||
@@ -102,7 +102,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
.PrimaryColumn("id")
|
||||
.OnDelete(Rule.None)
|
||||
.OnUpdate(Rule.None);
|
||||
|
||||
|
||||
//now we need to add a foreign key to the nodeId column to cmsContent (intead of the original umbracoNode)
|
||||
Create.ForeignKey("FK_cmsTagRelationship_cmsContent")
|
||||
.FromTable("cmsTagRelationship")
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
TimeColumnDefinition = "time";
|
||||
DecimalColumnDefinition = "decimal(38,6)";
|
||||
GuidColumnDefinition = "char(36)";
|
||||
|
||||
|
||||
InitColumnTypeMap();
|
||||
|
||||
DefaultValueFormat = "DEFAULT '{0}'";
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @TableSchema",
|
||||
new {TableSchema = db.Connection.Database});
|
||||
new { TableSchema = db.Connection.Database });
|
||||
list = items.Select(x => x.TABLE_NAME).Cast<string>().ToList();
|
||||
}
|
||||
finally
|
||||
@@ -67,7 +67,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
"SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @TableSchema",
|
||||
new {TableSchema = db.Connection.Database});
|
||||
new { TableSchema = db.Connection.Database });
|
||||
list =
|
||||
items.Select(
|
||||
item =>
|
||||
@@ -90,7 +90,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
"SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = @TableSchema",
|
||||
new {TableSchema = db.Connection.Database});
|
||||
new { TableSchema = db.Connection.Database });
|
||||
list = items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
finally
|
||||
@@ -109,7 +109,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
"SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = @TableSchema",
|
||||
new {TableSchema = db.Connection.Database});
|
||||
new { TableSchema = db.Connection.Database });
|
||||
list =
|
||||
items.Select(
|
||||
item =>
|
||||
@@ -133,7 +133,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
|
||||
"WHERE TABLE_NAME = @TableName AND " +
|
||||
"TABLE_SCHEMA = @TableSchema",
|
||||
new {TableName = tableName, TableSchema = db.Connection.Database});
|
||||
new { TableName = tableName, TableSchema = db.Connection.Database });
|
||||
|
||||
}
|
||||
finally
|
||||
@@ -213,7 +213,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
return string.Format(CreateIndex,
|
||||
GetQuotedName(name),
|
||||
GetQuotedTableName(index.TableName),
|
||||
GetQuotedTableName(index.TableName),
|
||||
columns);
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException("Default constraints are not supported in MySql");
|
||||
return "ALTER TABLE {0} ALTER COLUMN {1} DROP DEFAULT";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
public override string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD FOREIGN KEY ({1}) REFERENCES {2} ({3}){4}{5}"; } }
|
||||
|
||||
public override string DeleteConstraint { get { return "ALTER TABLE {0} DROP {1}{2}"; } }
|
||||
public override string DeleteConstraint { get { return "ALTER TABLE {0} DROP {1} {2}"; } }
|
||||
|
||||
public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } }
|
||||
|
||||
@@ -318,11 +318,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
db.OpenSharedConnection();
|
||||
// Need 4 @ signs as it is regarded as a parameter, @@ escapes it once, @@@@ escapes it twice
|
||||
var lowerCaseTableNames = db.Fetch<int>("SELECT @@@@Global.lower_case_table_names");
|
||||
|
||||
if(lowerCaseTableNames.Any())
|
||||
|
||||
if (lowerCaseTableNames.Any())
|
||||
supportsCaseInsensitiveQueries = lowerCaseTableNames.First() == 1;
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.LogHelper.Error<MySqlSyntaxProvider>("Error querying for lower_case support", ex);
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ namespace Umbraco.Core
|
||||
|
||||
//return false but specify this exception type so we can detect it
|
||||
if (typeElement == null)
|
||||
return Attempt<IEnumerable<string>>.Fail(new CachedPluginNotFoundInFile());
|
||||
return Attempt<IEnumerable<string>>.Fail(new CachedPluginNotFoundInFileException());
|
||||
|
||||
//return success
|
||||
return Attempt.Succeed(typeElement.Elements("add")
|
||||
@@ -459,24 +459,24 @@ namespace Umbraco.Core
|
||||
private readonly HashSet<TypeList> _types = new HashSet<TypeList>();
|
||||
private IEnumerable<Assembly> _assemblies;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns all found property editors
|
||||
/// Returns all found property editors (based on the resolved Iparameter editors - this saves a scan)
|
||||
/// </summary>
|
||||
internal IEnumerable<Type> ResolvePropertyEditors()
|
||||
{
|
||||
//return all proeprty editor types found except for the base property editor type
|
||||
return ResolveTypes<PropertyEditor>().ToArray()
|
||||
.Except(new[] {typeof (PropertyEditor)});
|
||||
return ResolveTypes<IParameterEditor>()
|
||||
.Where(x => x.IsType<PropertyEditor>())
|
||||
.Except(new[] { typeof(PropertyEditor) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all found parameter editors
|
||||
/// Returns all found parameter editors (which includes property editors)
|
||||
/// </summary>
|
||||
internal IEnumerable<Type> ResolveParameterEditors()
|
||||
{
|
||||
//return all paramter editor types found except for the base property editor type
|
||||
return ResolveTypes<IParameterEditor>().ToArray()
|
||||
return ResolveTypes<IParameterEditor>()
|
||||
.Except(new[] { typeof(ParameterEditor), typeof(PropertyEditor) });
|
||||
}
|
||||
|
||||
@@ -671,8 +671,15 @@ namespace Umbraco.Core
|
||||
{
|
||||
//check if the TypeList already exists, if so return it, if not we'll create it
|
||||
var typeList = _types.SingleOrDefault(x => x.IsTypeList<T>(resolutionType));
|
||||
|
||||
//need to put some logging here to try to figure out why this is happening: http://issues.umbraco.org/issue/U4-3505
|
||||
if (cacheResult && typeList != null)
|
||||
{
|
||||
LogHelper.Debug<PluginManager>("Existing typeList found for {0} with resolution type {1}", () => typeof(T), () => resolutionType);
|
||||
}
|
||||
|
||||
//if we're not caching the result then proceed, or if the type list doesn't exist then proceed
|
||||
if (!cacheResult || typeList == null)
|
||||
if (cacheResult == false || typeList == null)
|
||||
{
|
||||
//upgrade to a write lock since we're adding to the collection
|
||||
readLock.UpgradeToWriteLock();
|
||||
@@ -681,15 +688,17 @@ namespace Umbraco.Core
|
||||
|
||||
//we first need to look into our cache file (this has nothing to do with the 'cacheResult' parameter which caches in memory).
|
||||
//if assemblies have not changed and the cache file actually exists, then proceed to try to lookup by the cache file.
|
||||
if (!HaveAssembliesChanged && File.Exists(GetPluginListFilePath()))
|
||||
if (HaveAssembliesChanged == false && File.Exists(GetPluginListFilePath()))
|
||||
{
|
||||
var fileCacheResult = TryGetCachedPluginsFromFile<T>(resolutionType);
|
||||
|
||||
//here we need to identify if the CachedPluginNotFoundInFile was the exception, if it was then we need to re-scan
|
||||
//in some cases the plugin will not have been scanned for on application startup, but the assemblies haven't changed
|
||||
//so in this instance there will never be a result.
|
||||
if (fileCacheResult.Exception != null && fileCacheResult.Exception is CachedPluginNotFoundInFile)
|
||||
if (fileCacheResult.Exception != null && fileCacheResult.Exception is CachedPluginNotFoundInFileException)
|
||||
{
|
||||
LogHelper.Debug<PluginManager>("Tried to find typelist for type {0} and resolution {1} in file cache but the type was not found so loading types by assembly scan ", () => typeof(T), () => resolutionType);
|
||||
|
||||
//we don't have a cache for this so proceed to look them up by scanning
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, resolutionType, finder);
|
||||
}
|
||||
@@ -717,20 +726,22 @@ namespace Umbraco.Core
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!successfullyLoadedFromCache)
|
||||
if (successfullyLoadedFromCache == false)
|
||||
{
|
||||
//we need to manually load by scanning if loading from the file was not successful.
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, resolutionType, finder);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Debug<PluginManager>("Loaded plugin types " + typeof(T).FullName + " from persisted cache");
|
||||
LogHelper.Debug<PluginManager>("Loaded plugin types {0} with resolution {1} from persisted cache", () => typeof(T), () => resolutionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Debug<PluginManager>("Assembly changes detected, loading types {0} for resolution {1} by assembly scan", () => typeof(T), () => resolutionType);
|
||||
|
||||
//we don't have a cache for this so proceed to look them up by scanning
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, resolutionType, finder);
|
||||
}
|
||||
@@ -739,7 +750,10 @@ namespace Umbraco.Core
|
||||
if (cacheResult)
|
||||
{
|
||||
//add the type list to the collection
|
||||
_types.Add(typeList);
|
||||
var added = _types.Add(typeList);
|
||||
|
||||
LogHelper.Debug<PluginManager>("Caching of typelist for type {0} and resolution {1} was successful = {2}", () => typeof(T), () => resolutionType, () => added);
|
||||
|
||||
}
|
||||
}
|
||||
typesFound = typeList.GetTypes().ToList();
|
||||
@@ -863,14 +877,14 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the current TypeList is of the same type and of the same type
|
||||
/// Returns true if the current TypeList is of the same lookup type
|
||||
/// </summary>
|
||||
/// <typeparam name="TLookup"></typeparam>
|
||||
/// <param name="resolutionType"></param>
|
||||
/// <returns></returns>
|
||||
public override bool IsTypeList<TLookup>(TypeResolutionKind resolutionType)
|
||||
{
|
||||
return _resolutionType == resolutionType && (typeof(T)).IsType<TLookup>();
|
||||
return _resolutionType == resolutionType && (typeof(T)) == typeof(TLookup);
|
||||
}
|
||||
|
||||
public override IEnumerable<Type> GetTypes()
|
||||
@@ -883,7 +897,7 @@ namespace Umbraco.Core
|
||||
/// This class is used simply to determine that a plugin was not found in the cache plugin list with the specified
|
||||
/// TypeResolutionKind.
|
||||
/// </summary>
|
||||
internal class CachedPluginNotFoundInFile : Exception
|
||||
internal class CachedPluginNotFoundInFileException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -166,7 +166,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
var sql = new Sql();
|
||||
sql.Select("app").From<User2AppDto>().Where("[user] = @userID", new {userID = user.Id});
|
||||
sql.Select("app").From<User2AppDto>()
|
||||
.Where<User2AppDto>(dto => dto.UserId == (int)user.Id);
|
||||
return uow.Database.Fetch<string>(sql);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
<Reference Include="AutoMapper.Net4">
|
||||
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HtmlAgilityPack">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll</HintPath>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="AutoMapper" version="3.0.0" targetFramework="net45" />
|
||||
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net45" />
|
||||
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
|
||||
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
|
||||
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net40" />
|
||||
|
||||
@@ -158,5 +158,22 @@ asdfsdf
|
||||
</body>
|
||||
</html>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Format_RTE_Data_For_Persistence_Custom_Single_Entry()
|
||||
{
|
||||
var content = @"<div class=""umb-macro-holder Test mceNonEditable umb-macro-mce_1""><!-- <?UMBRACO_MACRO macroAlias=""Test"" content=""1089"" textArea=""asdfasdf"" title="""" bool=""0"" number="""" contentType="""" multiContentType="""" multiProperties="""" properties="""" tabs="""" multiTabs="""" /> --><ins>
|
||||
<div class=""facts-box"">
|
||||
<div class=""fatcs-box-header"">
|
||||
<h3>null</h3>
|
||||
</div>
|
||||
<div class=""fatcs-box-body"">1089</div>
|
||||
</div>
|
||||
</ins></div>";
|
||||
var result = MacroTagParser.FormatRichTextContentForPersistence(content);
|
||||
|
||||
Assert.AreEqual(@"<?UMBRACO_MACRO macroAlias=""Test"" content=""1089"" textArea=""asdfasdf"" title="""" bool=""0"" number="""" contentType="""" multiContentType="""" multiProperties="""" properties="""" tabs="""" multiTabs="""" />", result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -9,8 +10,10 @@ using NUnit.Framework;
|
||||
using SqlCE4Umbraco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using umbraco;
|
||||
using umbraco.DataLayer;
|
||||
using umbraco.MacroEngines;
|
||||
@@ -333,6 +336,29 @@ namespace Umbraco.Tests
|
||||
var types = PluginManager.Current.ResolveXsltExtensions();
|
||||
Assert.AreEqual(3, types.Count());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This demonstrates this issue: http://issues.umbraco.org/issue/U4-3505 - the TypeList was returning a list of assignable types
|
||||
/// not explicit types which is sort of ideal but is confusing so we'll do it the less confusing way.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TypeList_Resolves_Explicit_Types()
|
||||
{
|
||||
var types = new HashSet<PluginManager.TypeList>();
|
||||
|
||||
var propEditors = new PluginManager.TypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes);
|
||||
propEditors.AddType(typeof (LabelPropertyEditor));
|
||||
types.Add(propEditors);
|
||||
|
||||
var found = types.SingleOrDefault(x => x.IsTypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
|
||||
|
||||
Assert.IsNotNull(found);
|
||||
|
||||
//This should not find a type list of this type
|
||||
var shouldNotFind = types.SingleOrDefault(x => x.IsTypeList<IParameterEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
|
||||
|
||||
Assert.IsNull(shouldNotFind);
|
||||
}
|
||||
|
||||
[XsltExtension("Blah.Blah")]
|
||||
public class MyXsltExtension
|
||||
|
||||
@@ -647,11 +647,6 @@
|
||||
<None Include="Config\404handlers.Release.config">
|
||||
<DependentUpon>404handlers.config</DependentUpon>
|
||||
</None>
|
||||
<Content Include="Config\appSettings.config" />
|
||||
<None Include="Config\appSettings.Release.config">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>appSettings.config</DependentUpon>
|
||||
</None>
|
||||
<None Include="Config\ClientDependency.Release.config">
|
||||
<DependentUpon>ClientDependency.config</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
@@ -662,10 +657,6 @@
|
||||
<None Include="Config\BaseRestExtensions.Release.config">
|
||||
<DependentUpon>BaseRestExtensions.config</DependentUpon>
|
||||
</None>
|
||||
<Content Include="Config\connectionStrings.config" />
|
||||
<None Include="Config\connectionStrings.Release.config">
|
||||
<DependentUpon>connectionStrings.config</DependentUpon>
|
||||
</None>
|
||||
<None Include="Config\log4net.Release.config">
|
||||
<DependentUpon>log4net.config</DependentUpon>
|
||||
</None>
|
||||
@@ -2654,10 +2645,6 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
|
||||
<Target Name="BeforeBuild">
|
||||
<!-- Create web.config file from Template if it doesn't exist -->
|
||||
<Copy SourceFiles="$(ProjectDir)web.Template.config" DestinationFiles="$(ProjectDir)Web.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)Web.config')" />
|
||||
<!-- Create connectionStrings.config file from Template if it doesn't exist -->
|
||||
<Copy SourceFiles="$(ProjectDir)config\connectionStrings.Release.config" DestinationFiles="$(ProjectDir)config\connectionStrings.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)config\connectionStrings.config')" />
|
||||
<!-- Create appSettings.config file from Template if it doesn't exist -->
|
||||
<Copy SourceFiles="$(ProjectDir)config\appSettings.Release.config" DestinationFiles="$(ProjectDir)config\appSettings.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)config\appSettings.config')" />
|
||||
<!-- Transform the local Web.config file in Visual Studio -->
|
||||
<TransformXml Source="$(ProjectDir)Web.config" Transform="$(ProjectDir)web.Template.$(Configuration).config" Destination="$(ProjectDir)Web.$(Configuration).config.transformed" Condition="$(BuildingInsideVisualStudio) == true" />
|
||||
<!-- Always transform the Template file when not in VS (ie: build.bat) -->
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<appSettings>
|
||||
<!--
|
||||
Umbraco web.config configuration documentation can be found here:
|
||||
http://our.umbraco.org/documentation/using-umbraco/config-files/#webconfig
|
||||
-->
|
||||
<add key="umbracoConfigurationStatus" value="" />
|
||||
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
|
||||
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
|
||||
<add key="umbracoPath" value="~/umbraco" />
|
||||
<add key="umbracoHideTopLevelNodeFromPath" value="true" />
|
||||
<add key="umbracoUseDirectoryUrls" value="true" />
|
||||
<add key="umbracoTimeOutInMinutes" value="20" />
|
||||
<add key="umbracoDefaultUILanguage" value="en" />
|
||||
<add key="umbracoUseSSL" value="false" />
|
||||
|
||||
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
|
||||
<add key="webpages:Enabled" value="false"/>
|
||||
<add key="enableSimpleMembership" value="false"/>
|
||||
<add key="autoFormsAuthentication" value="false"/>
|
||||
|
||||
<add key="log4net.Config" value="config\log4net.config" />
|
||||
|
||||
</appSettings>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<connectionStrings>
|
||||
<remove name="umbracoDbDSN"/>
|
||||
<add name="umbracoDbDSN" connectionString="" providerName="" />
|
||||
<!-- Important: If you're upgrading Umbraco, do not clear the connection string / provider name during your web.config merge. -->
|
||||
</connectionStrings>
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
The transforms in this file only apply to debugging, not to the web.config that will be released, see web.Template.Release.config for that
|
||||
|
||||
2012-11-08 SJ - Add Medium trust for everybody so we'll see any MedTrust related errors early on
|
||||
-->
|
||||
|
||||
|
||||
@@ -46,11 +45,29 @@
|
||||
<dashBoard configSource="config\Dashboard.config"/>
|
||||
</umbracoConfiguration>
|
||||
|
||||
<appSettings xdt:Transform="Remove" />
|
||||
<appSettings configSource="config\appSettings.config" xdt:Transform="InsertAfter(/configuration/umbracoConfiguration)" />
|
||||
<appSettings xdt:Transform="Remove" xdt:Locator="Condition(@configSource != '')" />
|
||||
<appSettings xdt:Transform="InsertIfMissing" >
|
||||
<add key="umbracoConfigurationStatus" value="" />
|
||||
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
|
||||
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
|
||||
<add key="umbracoPath" value="~/umbraco" />
|
||||
<add key="umbracoHideTopLevelNodeFromPath" value="true" />
|
||||
<add key="umbracoUseDirectoryUrls" value="true" />
|
||||
<add key="umbracoTimeOutInMinutes" value="20" />
|
||||
<add key="umbracoDefaultUILanguage" value="en" />
|
||||
<add key="umbracoUseSSL" value="false" />
|
||||
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
|
||||
<add key="webpages:Enabled" value="false"/>
|
||||
<add key="enableSimpleMembership" value="false"/>
|
||||
<add key="autoFormsAuthentication" value="false"/>
|
||||
<add key="log4net.Config" value="config\log4net.config" />
|
||||
</appSettings>
|
||||
|
||||
<connectionStrings xdt:Transform="Remove" />
|
||||
<connectionStrings configSource="config\connectionStrings.config" xdt:Transform="InsertAfter(/configuration/appSettings)" />
|
||||
<connectionStrings xdt:Transform="Remove" xdt:Locator="Condition(@configSource != '')" />
|
||||
<connectionStrings xdt:Transform="InsertIfMissing">
|
||||
<remove name="umbracoDbDSN"/>
|
||||
<add name="umbracoDbDSN" connectionString="" providerName="" />
|
||||
</connectionStrings>
|
||||
|
||||
<system.web>
|
||||
<xhtmlConformance xdt:Transform="Remove"/>
|
||||
|
||||
@@ -29,8 +29,34 @@
|
||||
<ExamineLuceneIndexSets configSource="config\ExamineIndex.config" />
|
||||
<log4net configSource="config\log4net.config" />
|
||||
|
||||
<appSettings configSource="config\appSettings.config" />
|
||||
<connectionStrings configSource="config\connectionStrings.config" />
|
||||
<appSettings>
|
||||
<!--
|
||||
Umbraco web.config configuration documentation can be found here:
|
||||
http://our.umbraco.org/documentation/using-umbraco/config-files/#webconfig
|
||||
-->
|
||||
<add key="umbracoConfigurationStatus" value="" />
|
||||
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
|
||||
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
|
||||
<add key="umbracoPath" value="~/umbraco" />
|
||||
<add key="umbracoHideTopLevelNodeFromPath" value="true" />
|
||||
<add key="umbracoUseDirectoryUrls" value="true" />
|
||||
<add key="umbracoTimeOutInMinutes" value="20" />
|
||||
<add key="umbracoDefaultUILanguage" value="en" />
|
||||
<add key="umbracoUseSSL" value="false" />
|
||||
|
||||
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
|
||||
<add key="webpages:Enabled" value="false"/>
|
||||
<add key="enableSimpleMembership" value="false"/>
|
||||
<add key="autoFormsAuthentication" value="false"/>
|
||||
|
||||
<add key="log4net.Config" value="config\log4net.config" />
|
||||
|
||||
</appSettings>
|
||||
<connectionStrings>
|
||||
<remove name="umbracoDbDSN"/>
|
||||
<add name="umbracoDbDSN" connectionString="" providerName="" />
|
||||
<!-- Important: If you're upgrading Umbraco, do not clear the connection string / provider name during your web.config merge. -->
|
||||
</connectionStrings>
|
||||
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
|
||||
@@ -28,18 +28,9 @@ namespace Umbraco.Web.Editors
|
||||
/// </summary>
|
||||
[PluginController("UmbracoApi")]
|
||||
[ValidationFilter]
|
||||
[AngularJsonOnlyConfiguration]
|
||||
public class AuthenticationController : UmbracoApiController
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Remove the xml formatter... only support JSON!
|
||||
/// </summary>
|
||||
/// <param name="controllerContext"></param>
|
||||
protected override void Initialize(HttpControllerContext controllerContext)
|
||||
{
|
||||
base.Initialize(controllerContext);
|
||||
controllerContext.EnsureJsonOutputOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a special method that will return the current users' remaining session seconds, the reason
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Umbraco.Web.Editors
|
||||
/// methods that are not called by Angular or don't contain a valid csrf header will NOT work.
|
||||
/// </remarks>
|
||||
[ValidateAngularAntiForgeryToken]
|
||||
[AngularJsonOnlyConfiguration]
|
||||
public abstract class UmbracoAuthorizedJsonController : UmbracoAuthorizedApiController
|
||||
{
|
||||
protected UmbracoAuthorizedJsonController()
|
||||
@@ -22,17 +23,5 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the xml formatter... only support JSON!
|
||||
/// </summary>
|
||||
/// <param name="controllerContext"></param>
|
||||
protected override void Initialize(HttpControllerContext controllerContext)
|
||||
{
|
||||
base.Initialize(controllerContext);
|
||||
controllerContext.EnsureJsonOutputOnly();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,21 +20,10 @@ using umbraco;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
|
||||
[AngularJsonOnlyConfiguration]
|
||||
[PluginController("UmbracoTrees")]
|
||||
public class ApplicationTreeController : UmbracoAuthorizedApiController
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Remove the xml formatter... only support JSON!
|
||||
/// </summary>
|
||||
/// <param name="controllerContext"></param>
|
||||
protected override void Initialize(global::System.Web.Http.Controllers.HttpControllerContext controllerContext)
|
||||
{
|
||||
base.Initialize(controllerContext);
|
||||
controllerContext.EnsureJsonOutputOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the tree nodes for an application
|
||||
/// </summary>
|
||||
|
||||
@@ -15,18 +15,9 @@ namespace Umbraco.Web.Trees
|
||||
/// A base controller reference for non-attributed trees (un-registered). Developers should inherit from
|
||||
/// TreeController.
|
||||
/// </summary>
|
||||
[AngularJsonOnlyConfiguration]
|
||||
public abstract class TreeControllerBase : UmbracoAuthorizedApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// Remove the xml formatter... only support JSON!
|
||||
/// </summary>
|
||||
/// <param name="controllerContext"></param>
|
||||
protected override void Initialize(global::System.Web.Http.Controllers.HttpControllerContext controllerContext)
|
||||
{
|
||||
base.Initialize(controllerContext);
|
||||
controllerContext.EnsureJsonOutputOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method called to render the contents of the tree structure
|
||||
/// </summary>
|
||||
|
||||
@@ -976,35 +976,32 @@ namespace Umbraco.Web
|
||||
{
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml("<p>" + html + "</p>");
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
var targets = new List<HtmlNode>();
|
||||
var targets = new List<HtmlNode>();
|
||||
|
||||
var nodes = doc.DocumentNode.FirstChild.SelectNodes(".//*");
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
//is element
|
||||
if (node.NodeType != HtmlNodeType.Element) continue;
|
||||
var filterAllTags = (tags == null || !tags.Any());
|
||||
if (filterAllTags || tags.Any(tag => string.Equals(tag, node.Name, StringComparison.CurrentCultureIgnoreCase)))
|
||||
{
|
||||
targets.Add(node);
|
||||
}
|
||||
}
|
||||
foreach (var target in targets)
|
||||
{
|
||||
HtmlNode content = doc.CreateTextNode(target.InnerText);
|
||||
target.ParentNode.ReplaceChild(content, target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new HtmlString(html);
|
||||
}
|
||||
return new HtmlString(doc.DocumentNode.FirstChild.InnerHtml);
|
||||
}
|
||||
var nodes = doc.DocumentNode.FirstChild.SelectNodes(".//*");
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
//is element
|
||||
if (node.NodeType != HtmlNodeType.Element) continue;
|
||||
var filterAllTags = (tags == null || !tags.Any());
|
||||
if (filterAllTags || tags.Any(tag => string.Equals(tag, node.Name, StringComparison.CurrentCultureIgnoreCase)))
|
||||
{
|
||||
targets.Add(node);
|
||||
}
|
||||
}
|
||||
foreach (var target in targets)
|
||||
{
|
||||
HtmlNode content = doc.CreateTextNode(target.InnerText);
|
||||
target.ParentNode.ReplaceChild(content, target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new HtmlString(html);
|
||||
}
|
||||
return new HtmlString(doc.DocumentNode.FirstChild.InnerHtml);
|
||||
}
|
||||
|
||||
public string Coalesce(params object[] args)
|
||||
|
||||
@@ -96,22 +96,38 @@ namespace Umbraco.Web.WebApi
|
||||
jsonFormatter.SerializerSettings.Converters.Add(new CustomDateTimeConvertor("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the xml formatter so it only outputs angularized json (with the json vulnerability prefix added)
|
||||
/// </summary>
|
||||
/// <param name="controllerContext"></param>
|
||||
internal static void EnsureJsonOutputOnly(this HttpControllerContext controllerContext)
|
||||
{
|
||||
///// <summary>
|
||||
///// Removes the xml formatter so it only outputs angularized json (with the json vulnerability prefix added)
|
||||
///// </summary>
|
||||
///// <param name="controllerContext"></param>
|
||||
//internal static void EnsureJsonOutputOnly(this HttpControllerContext controllerContext)
|
||||
//{
|
||||
// controllerContext.Configuration.Formatters = new MediaTypeFormatterCollection();
|
||||
|
||||
// //remove all json/xml formatters then add our custom one
|
||||
// var toRemove = controllerContext.Configuration.Formatters.Where(t => (t is JsonMediaTypeFormatter) || (t is XmlMediaTypeFormatter)).ToList();
|
||||
// foreach (var r in toRemove)
|
||||
// {
|
||||
// controllerContext.Configuration.Formatters.Remove(r);
|
||||
// }
|
||||
// controllerContext.Configuration.Formatters.Add(new AngularJsonMediaTypeFormatter());
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applying this attribute to any webapi controller will ensure that it only contains one json formatter compatible with the angular json vulnerability prevention.
|
||||
/// </summary>
|
||||
public class AngularJsonOnlyConfigurationAttribute : Attribute, IControllerConfiguration
|
||||
{
|
||||
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
|
||||
{
|
||||
//remove all json/xml formatters then add our custom one
|
||||
for (var i = 0; i < controllerContext.Configuration.Formatters.Count;i++)
|
||||
var toRemove = controllerSettings.Formatters.Where(t => (t is JsonMediaTypeFormatter) || (t is XmlMediaTypeFormatter)).ToList();
|
||||
foreach (var r in toRemove)
|
||||
{
|
||||
if ((controllerContext.Configuration.Formatters[i] is JsonMediaTypeFormatter)
|
||||
|| (controllerContext.Configuration.Formatters[i] is XmlMediaTypeFormatter))
|
||||
{
|
||||
controllerContext.Configuration.Formatters.RemoveAt(i);
|
||||
}
|
||||
controllerSettings.Formatters.Remove(r);
|
||||
}
|
||||
controllerContext.Configuration.Formatters.Add(new AngularJsonMediaTypeFormatter());
|
||||
controllerSettings.Formatters.Add(new AngularJsonMediaTypeFormatter());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -796,7 +796,9 @@ namespace umbraco
|
||||
{
|
||||
if (attributes.ContainsKey(mp.Key.ToLower()))
|
||||
{
|
||||
mp.Value = attributes[mp.Key.ToLower()].ToString();
|
||||
var item = attributes[mp.Key.ToLower()];
|
||||
|
||||
mp.Value = item == null ? string.Empty : item.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Web;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.WebPages;
|
||||
using Umbraco.Core;
|
||||
using umbraco.MacroEngines.Resources;
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
using umbraco.interfaces;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -16,6 +17,7 @@ namespace umbraco.MacroEngines
|
||||
public class RazorMacroEngine : IMacroEngine, IMacroEngineResultStatus {
|
||||
|
||||
public const string RazorTempDirectory = "~/App_Data/TEMP/Razor/";
|
||||
private const string RazorWebConfig = "~/App_Data/TEMP/Razor/web.config";
|
||||
|
||||
public string GetVirtualPathFromPhysicalPath(string physicalPath) {
|
||||
string rootpath = HttpContext.Current.Server.MapPath("~/");
|
||||
@@ -40,6 +42,7 @@ namespace umbraco.MacroEngines
|
||||
var relativePath = RazorTempDirectory + fileName;
|
||||
var physicalPath = IOHelper.MapPath(relativePath);
|
||||
var physicalDirectoryPath = IOHelper.MapPath(RazorTempDirectory);
|
||||
var webconfig = IOHelper.MapPath(RazorWebConfig);
|
||||
|
||||
if (skipIfFileExists && File.Exists(physicalPath))
|
||||
return relativePath;
|
||||
@@ -47,6 +50,16 @@ namespace umbraco.MacroEngines
|
||||
File.Delete(physicalPath);
|
||||
if (!Directory.Exists(physicalDirectoryPath))
|
||||
Directory.CreateDirectory(physicalDirectoryPath);
|
||||
|
||||
//Ensure the correct razor web.config is there
|
||||
if (File.Exists(webconfig) == false)
|
||||
{
|
||||
using (var writer = File.CreateText(webconfig))
|
||||
{
|
||||
writer.Write(Strings.WebConfig);
|
||||
}
|
||||
}
|
||||
|
||||
using (var file = new StreamWriter(physicalPath, false, Encoding.UTF8))
|
||||
{
|
||||
file.Write(razorSyntax);
|
||||
|
||||
78
src/umbraco.MacroEngines/Resources/Strings.Designer.cs
generated
Normal file
78
src/umbraco.MacroEngines/Resources/Strings.Designer.cs
generated
Normal file
@@ -0,0 +1,78 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34003
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace umbraco.MacroEngines.Resources {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Strings {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Strings() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("umbraco.MacroEngines.Resources.Strings", typeof(Strings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0"?>
|
||||
///<configuration>
|
||||
///
|
||||
/// <configSections>
|
||||
/// <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
/// <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
/// <section name="page [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string WebConfig {
|
||||
get {
|
||||
return ResourceManager.GetString("WebConfig", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
124
src/umbraco.MacroEngines/Resources/Strings.resx
Normal file
124
src/umbraco.MacroEngines/Resources/Strings.resx
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="WebConfig" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\..\umbraco.web.ui\macroscripts\web.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -180,6 +180,11 @@
|
||||
<Compile Include="RazorCore\RazorMacroEngine.cs" />
|
||||
<Compile Include="RazorDynamicNode\Res.cs" />
|
||||
<Compile Include="RazorDynamicNode\Signature.cs" />
|
||||
<Compile Include="Resources\Strings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
|
||||
@@ -216,8 +221,17 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Umbraco.Web.UI\MacroScripts\Web.config">
|
||||
<Link>Resources\Web.config</Link>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Strings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
|
||||
Reference in New Issue
Block a user