diff --git a/.gitignore b/.gitignore
index 4e2183af5c..2fcab792e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -144,5 +144,5 @@ build/docs.zip
build/ui-docs.zip
build/csharp-docs.zip
build/msbuild.log
-
+.vs/
src/packages/
\ No newline at end of file
diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs
index 7e2bb88964..d7f4576137 100644
--- a/src/Umbraco.Core/Constants-Conventions.cs
+++ b/src/Umbraco.Core/Constants-Conventions.cs
@@ -122,6 +122,11 @@ namespace Umbraco.Core
/// MediaType alias for an image.
///
public const string Image = "Image";
+
+ ///
+ /// MediaType alias indicating allowing auto-selection.
+ ///
+ public const string AutoSelect = "umbracoAutoSelect";
}
///
diff --git a/src/Umbraco.Core/CoreRuntimeComponent.cs b/src/Umbraco.Core/CoreRuntimeComponent.cs
index 476c3a43d6..68ed71f484 100644
--- a/src/Umbraco.Core/CoreRuntimeComponent.cs
+++ b/src/Umbraco.Core/CoreRuntimeComponent.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Configuration;
using System.IO;
using AutoMapper;
using LightInject;
@@ -71,11 +72,16 @@ namespace Umbraco.Core
// register a server registrar, by default it's the db registrar unless the dev
// has the legacy dist calls enabled - fixme - should obsolete the legacy thing
- composition.Container.RegisterSingleton(factory => UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled
- ? (IServerRegistrar)new ConfigServerRegistrar(UmbracoConfig.For.UmbracoSettings())
- : (IServerRegistrar)new DatabaseServerRegistrar(
- new Lazy(factory.GetInstance),
- new DatabaseServerRegistrarOptions()));
+ composition.Container.RegisterSingleton(f =>
+ {
+ if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled)
+ return new ConfigServerRegistrar(UmbracoConfig.For.UmbracoSettings());
+ if ("true".InvariantEquals(ConfigurationManager.AppSettings["umbracoDisableElectionForSingleServer"]))
+ return new SingleServerRegistrar(f.GetInstance());
+ return new DatabaseServerRegistrar(
+ new Lazy(f.GetInstance),
+ new DatabaseServerRegistrarOptions());
+ });
// by default we'll use the database server messenger with default options (no callbacks),
// this will be overridden by either the legacy thing or the db thing in the corresponding
diff --git a/src/Umbraco.Core/DI/RepositoryCompositionRoot.cs b/src/Umbraco.Core/DI/RepositoryCompositionRoot.cs
index 638ca84656..d7975db96e 100644
--- a/src/Umbraco.Core/DI/RepositoryCompositionRoot.cs
+++ b/src/Umbraco.Core/DI/RepositoryCompositionRoot.cs
@@ -4,6 +4,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.IO;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
+using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Plugins;
@@ -26,6 +27,9 @@ namespace Umbraco.Core.DI
container.RegisterSingleton();
container.RegisterSingleton();
+ // register query factory
+ container.RegisterSingleton();
+
// register repository factory
container.RegisterSingleton();
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index a0b9bfa8f1..b822b66504 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -326,7 +326,7 @@ namespace Umbraco.Core.Models
}
}
- ///
+ ///
/// A boolean flag indicating if a property type has been removed from this instance.
///
///
diff --git a/src/Umbraco.Core/Models/PublicAccessEntry.cs b/src/Umbraco.Core/Models/PublicAccessEntry.cs
index 969e853f05..1ed15a8fb4 100644
--- a/src/Umbraco.Core/Models/PublicAccessEntry.cs
+++ b/src/Umbraco.Core/Models/PublicAccessEntry.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Models
NoAccessNodeId = noAccessNode.Id;
_protectedNodeId = protectedNode.Id;
- _ruleCollection = new ObservableCollection(ruleCollection);
+ _ruleCollection = new ObservableCollection(ruleCollection);
_ruleCollection.CollectionChanged += _ruleCollection_CollectionChanged;
}
@@ -81,7 +81,7 @@ namespace Umbraco.Core.Models
internal IEnumerable RemovedRules
{
get { return _removedRules; }
- }
+ }
public IEnumerable Rules
{
@@ -123,7 +123,7 @@ namespace Umbraco.Core.Models
get { return _noAccessNodeId; }
set { SetPropertyValueAndDetectChanges(value, ref _noAccessNodeId, Ps.Value.NoAccessNodeIdSelector); }
}
-
+
[DataMember]
public int ProtectedNodeId
{
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentModelFactory.cs
index e2134c952e..fe90bd9fff 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentModelFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentModelFactory.cs
@@ -12,5 +12,21 @@
/// The strongly-typed model representing the published content, or the published content
/// itself it the factory has no model for that content type.
IPublishedContent CreateModel(IPublishedContent content);
+
+ T CreateModel(IPublishedFragment content);
+
+ // fixme
+ // and we'd need a
+ // PublishedContentModel = ContentModel : ContentWrapper
+ // PublishedFragmentModel = FragmentModel : FragmentWrapper
+ //
+ // ModelFactory.Meta.Model("thing").ClrType (find the our post?)
+ //
+ // then
+ // make a plan to get NestedContent in
+ // and an equivalent of Vorto with different syntax
+ //
+ // then
+ // VARIANTS ARCHITECTURE FFS!
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedContentModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/NoopPublishedContentModelFactory.cs
index a92427191e..9fbcadb29b 100644
--- a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedContentModelFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/NoopPublishedContentModelFactory.cs
@@ -6,5 +6,10 @@
{
return content;
}
+
+ public T CreateModel(IPublishedFragment content)
+ {
+ throw new System.NotImplementedException();
+ }
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactory.cs
index 17c01b4785..d3d6b43170 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactory.cs
@@ -81,5 +81,10 @@ namespace Umbraco.Core.Models.PublishedContent
? constructor(content)
: content;
}
+
+ public T CreateModel(IPublishedFragment content)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs
index b385381e5b..c79daaf43d 100644
--- a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs
+++ b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs
@@ -12,7 +12,6 @@ namespace Umbraco.Core.Models.Rdbms
{
[Column("id")]
[PrimaryKeyColumn]
- [Index(IndexTypes.NonClustered, Name = "IX_cmsPropertyData")]
public int Id { get; set; }
[Column("contentNodeId")]
diff --git a/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs b/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs
index d6ad4f1f3c..a3e2eeea68 100644
--- a/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs
+++ b/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence
{
ValidateDatabase(database);
- database.Execute("UPDATE umbracoNode SET sortOrder = (CASE WHEN (sortOrder=1) THEN -1 ELSE 1 END) WHERE id=@id",
+ database.Execute("UPDATE umbracoLock SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id=@id",
new { @id = nodeId });
}
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Persistence
{
ValidateDatabase(database);
- database.ExecuteScalar("SELECT sortOrder FROM umbracoNode WHERE id=@id",
+ database.ExecuteScalar("SELECT value FROM umbracoLock WHERE id=@id",
new { @id = nodeId });
}
}
diff --git a/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs b/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs
index df45d87e75..d0b44f7ae2 100644
--- a/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs
+++ b/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs
@@ -28,7 +28,6 @@ namespace Umbraco.Core.Persistence
///
internal class DefaultDatabaseFactory : DisposableObject, IDatabaseFactory
{
- private readonly IMapperCollection _mappers;
private readonly IUmbracoDatabaseAccessor _umbracoDatabaseAccessor;
private readonly ISqlSyntaxProvider[] _sqlSyntaxProviders;
private readonly ILogger _logger;
@@ -42,7 +41,6 @@ namespace Umbraco.Core.Persistence
private ISqlSyntaxProvider _sqlSyntax;
private RetryPolicy _connectionRetryPolicy;
private RetryPolicy _commandRetryPolicy;
- private IQueryFactory _queryFactory;
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
///
@@ -51,10 +49,10 @@ namespace Umbraco.Core.Persistence
/// The collection of available sql syntax providers.
/// A logger.
///
- ///
+ ///
/// Used by LightInject.
- public DefaultDatabaseFactory(IEnumerable sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IMapperCollection mappers)
- : this(GlobalSettings.UmbracoConnectionName, sqlSyntaxProviders, logger, umbracoDatabaseAccessor, mappers)
+ public DefaultDatabaseFactory(IEnumerable sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IQueryFactory queryFactory)
+ : this(GlobalSettings.UmbracoConnectionName, sqlSyntaxProviders, logger, umbracoDatabaseAccessor, queryFactory)
{
if (Configured == false)
DatabaseContext.GiveLegacyAChance(this, logger);
@@ -67,17 +65,17 @@ namespace Umbraco.Core.Persistence
/// The collection of available sql syntax providers.
/// A logger
///
- ///
+ ///
/// Used by the other ctor and in tests.
- public DefaultDatabaseFactory(string connectionStringName, IEnumerable sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IMapperCollection mappers)
+ public DefaultDatabaseFactory(string connectionStringName, IEnumerable sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IQueryFactory queryFactory)
{
if (sqlSyntaxProviders == null) throw new ArgumentNullException(nameof(sqlSyntaxProviders));
if (logger == null) throw new ArgumentNullException(nameof(logger));
if (umbracoDatabaseAccessor == null) throw new ArgumentNullException(nameof(umbracoDatabaseAccessor));
if (string.IsNullOrWhiteSpace(connectionStringName)) throw new ArgumentNullOrEmptyException(nameof(connectionStringName));
- if (mappers == null) throw new ArgumentNullException(nameof(mappers));
+ if (queryFactory == null) throw new ArgumentNullException(nameof(queryFactory));
- _mappers = mappers;
+ QueryFactory = queryFactory;
_sqlSyntaxProviders = sqlSyntaxProviders.ToArray();
_logger = logger;
_umbracoDatabaseAccessor = umbracoDatabaseAccessor;
@@ -107,16 +105,16 @@ namespace Umbraco.Core.Persistence
/// The collection of available sql syntax providers.
/// A logger.
///
- ///
+ ///
/// Used in tests.
- public DefaultDatabaseFactory(string connectionString, string providerName, IEnumerable sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IMapperCollection mappers)
+ public DefaultDatabaseFactory(string connectionString, string providerName, IEnumerable sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IQueryFactory queryFactory)
{
if (sqlSyntaxProviders == null) throw new ArgumentNullException(nameof(sqlSyntaxProviders));
if (logger == null) throw new ArgumentNullException(nameof(logger));
if (umbracoDatabaseAccessor == null) throw new ArgumentNullException(nameof(umbracoDatabaseAccessor));
- if (mappers == null) throw new ArgumentNullException(nameof(mappers));
+ if (queryFactory == null) throw new ArgumentNullException(nameof(queryFactory));
- _mappers = mappers;
+ QueryFactory = queryFactory;
_sqlSyntaxProviders = sqlSyntaxProviders.ToArray();
_logger = logger;
_umbracoDatabaseAccessor = umbracoDatabaseAccessor;
@@ -156,14 +154,7 @@ namespace Umbraco.Core.Persistence
///
/// Gets the database query factory.
///
- public IQueryFactory QueryFactory
- {
- get
- {
- EnsureConfigured();
- return _queryFactory ?? (_queryFactory = new QueryFactory(SqlSyntax, _mappers));
- }
- }
+ public IQueryFactory QueryFactory { get; }
// will be configured by the database context
public void Configure(string connectionString, string providerName)
diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
index 26a14d2477..c9aa6f9775 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
@@ -39,6 +39,11 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
CreateUmbracoLockData();
}
+ if (tableName.Equals("umbracoLock"))
+ {
+ CreateUmbracoLockData();
+ }
+
if (tableName.Equals("cmsContentType"))
{
CreateCmsContentTypeData();
@@ -165,8 +170,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
private void CreateCmsContentTypeData()
{
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true });
- _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture" });
- _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document" });
+ _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true });
+ _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true });
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user" });
}
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/AddLockObjects.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/AddLockObjects.cs
new file mode 100644
index 0000000000..8ee31f4b07
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/AddLockObjects.cs
@@ -0,0 +1,37 @@
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Models.Rdbms;
+
+namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive
+{
+ [Migration("7.5.5", 101, GlobalSettings.UmbracoMigrationName)]
+ public class AddLockObjects : MigrationBase
+ {
+ public AddLockObjects(IMigrationContext context)
+ : base(context)
+ { }
+
+ public override void Up()
+ {
+ EnsureLockObject(Constants.Locks.Servers, "Servers");
+ }
+
+ public override void Down()
+ {
+ // not implemented
+ }
+
+ private void EnsureLockObject(int id, string name)
+ {
+ Execute.Code(db =>
+ {
+ var exists = db.Exists(id);
+ if (exists) return string.Empty;
+ // be safe: delete old umbracoNode lock objects if any
+ db.Execute("DELETE FROM umbracoNode WHERE id=@id;", new { id });
+ // then create umbracoLock object
+ db.Execute("INSERT umbracoLock (id, name, value) VALUES (@id, @name, 1);", new { id, name });
+ return string.Empty;
+ });
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/AddLockTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/AddLockTable.cs
new file mode 100644
index 0000000000..8d7f2ed8fb
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/AddLockTable.cs
@@ -0,0 +1,30 @@
+using System.Linq;
+using Umbraco.Core.Configuration;
+
+namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive
+{
+ [Migration("7.5.5", 100, GlobalSettings.UmbracoMigrationName)]
+ public class AddLockTable : MigrationBase
+ {
+ public AddLockTable(IMigrationContext context)
+ : base(context)
+ { }
+
+ public override void Up()
+ {
+ var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
+ if (tables.InvariantContains("umbracoLock") == false)
+ {
+ Create.Table("umbracoLock")
+ .WithColumn("id").AsInt32().PrimaryKey("PK_umbracoLock")
+ .WithColumn("value").AsInt32().NotNullable()
+ .WithColumn("name").AsString(64).NotNullable();
+ }
+ }
+
+ public override void Down()
+ {
+ // not implemented
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs
new file mode 100644
index 0000000000..5a95b9b8bf
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs
@@ -0,0 +1,25 @@
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence.SqlSyntax;
+
+namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive
+{
+ ///
+ /// See: http://issues.umbraco.org/issue/U4-4196
+ ///
+ [Migration("7.5.5", 1, GlobalSettings.UmbracoMigrationName)]
+ public class UpdateAllowedMediaTypesAtRoot : MigrationBase
+ {
+ public UpdateAllowedMediaTypesAtRoot(IMigrationContext context)
+ : base(context)
+ { }
+
+ public override void Up()
+ {
+ Execute.Sql("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1032 OR nodeId = 1033");
+ }
+
+ public override void Down()
+ { }
+ }
+}
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSixZero/RemovePropertyDataIdIndex.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSixZero/RemovePropertyDataIdIndex.cs
new file mode 100644
index 0000000000..dabba48334
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSixZero/RemovePropertyDataIdIndex.cs
@@ -0,0 +1,38 @@
+using System.Linq;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence.SqlSyntax;
+
+namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
+{
+ ///
+ /// See: http://issues.umbraco.org/issue/U4-9188
+ ///
+ [Migration("7.6.0", 0, GlobalSettings.UmbracoMigrationName)]
+ public class UpdateUniqueIndexOnCmsPropertyData : MigrationBase
+ {
+ public UpdateUniqueIndexOnCmsPropertyData(IMigrationContext context)
+ : base(context)
+ {
+ }
+
+ public override void Up()
+ {
+ //tuple = tablename, indexname, columnname, unique
+ var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
+ var found = indexes.FirstOrDefault(
+ x => x.Item1.InvariantEquals("cmsPropertyData")
+ && x.Item2.InvariantEquals("IX_cmsPropertyData"));
+
+ if (found != null)
+ {
+ //drop the index
+ Delete.Index("IX_cmsPropertyData").OnTable("cmsPropertyData");
+ }
+ }
+
+ public override void Down()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs
index d16cf7fe0f..d001358a97 100644
--- a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs
+++ b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence
public static Sql Where(this Sql sql, Expression> predicate)
{
- var expresionist = new PocoToSqlExpressionHelper(sql.SqlContext);
+ var expresionist = new PocoToSqlExpressionVisitor(sql.SqlContext);
var whereExpression = expresionist.Visit(predicate);
sql.Where(whereExpression, expresionist.GetSqlParameters());
return sql;
diff --git a/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/ExpressionVisitorBase.cs
similarity index 63%
rename from src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs
rename to src/Umbraco.Core/Persistence/Querying/ExpressionVisitorBase.cs
index 560e6f6eeb..9a7962230d 100644
--- a/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs
+++ b/src/Umbraco.Core/Persistence/Querying/ExpressionVisitorBase.cs
@@ -2,7 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
@@ -13,27 +12,117 @@ namespace Umbraco.Core.Persistence.Querying
{
// fixme.npoco - are we basically duplicating entire parts of NPoco just because of SqlSyntax ?!
- internal abstract class BaseExpressionHelper : BaseExpressionHelper
+ ///
+ /// Represents an expression which caches the visitor's result.
+ ///
+ internal class CachedExpression : Expression
{
- protected BaseExpressionHelper(ISqlSyntaxProvider sqlSyntax)
- : base(sqlSyntax)
+ private string _visitResult;
+
+ ///
+ /// Gets or sets the inner Expression.
+ ///
+ public Expression InnerExpression { get; private set; }
+
+ ///
+ /// Gets or sets the compiled SQL statement output.
+ ///
+ public string VisitResult
{
+ get { return _visitResult; }
+ set
+ {
+ if (Visited)
+ throw new InvalidOperationException("Cached expression has already been visited.");
+ _visitResult = value;
+ Visited = true;
+ }
}
- protected abstract string VisitMemberAccess(MemberExpression m);
+ ///
+ /// Gets or sets a value indicating whether the cache Expression has been compiled already.
+ ///
+ public bool Visited { get; private set; }
- protected internal virtual string Visit(Expression exp)
+ ///
+ /// Replaces the inner expression.
+ ///
+ /// expression.
+ /// The new expression is assumed to have different parameter but produce the same SQL statement.
+ public void Wrap(Expression expression)
{
+ InnerExpression = expression;
+ }
+ }
- if (exp == null) return string.Empty;
- switch (exp.NodeType)
+ ///
+ /// An expression tree parser to create SQL statements and SQL parameters based on a strongly typed expression.
+ ///
+ /// This object is stateful and cannot be re-used to parse an expression.
+ internal abstract class ExpressionVisitorBase
+ {
+ protected ExpressionVisitorBase(ISqlSyntaxProvider sqlSyntax)
+ {
+ SqlSyntax = sqlSyntax;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the visited expression has been visited already,
+ /// in which case visiting will just populate the SQL parameters.
+ ///
+ protected bool Visited { get; set; }
+
+ ///
+ /// Gets or sets the SQL syntax provider for the current database.
+ ///
+ protected ISqlSyntaxProvider SqlSyntax { get; private set; }
+
+ ///
+ /// Gets the list of SQL parameters.
+ ///
+ protected readonly List
private class DataTypePreValueRepository : NPocoRepositoryBase
{
- public DataTypePreValueRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public DataTypePreValueRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
index 95574fe05e..dc2c0559e3 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
@@ -21,13 +21,10 @@ namespace Umbraco.Core.Persistence.Repositories
internal class DictionaryRepository : NPocoRepositoryBase, IDictionaryRepository
{
private IRepositoryCachePolicy _cachePolicy;
- private readonly IMapperCollection _mappers;
- public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
- {
- _mappers = mappers;
- }
+ public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
+ { }
protected override IRepositoryCachePolicy CachePolicy
{
@@ -243,13 +240,13 @@ namespace Umbraco.Core.Persistence.Repositories
public IDictionaryItem Get(Guid uniqueId)
{
- var uniqueIdRepo = new DictionaryByUniqueIdRepository(this, UnitOfWork, RepositoryCache, Logger, _mappers);
+ var uniqueIdRepo = new DictionaryByUniqueIdRepository(this, UnitOfWork, RepositoryCache, Logger, QueryFactory);
return uniqueIdRepo.Get(uniqueId);
}
public IDictionaryItem Get(string key)
{
- var keyRepo = new DictionaryByKeyRepository(this, UnitOfWork, RepositoryCache, Logger, _mappers);
+ var keyRepo = new DictionaryByKeyRepository(this, UnitOfWork, RepositoryCache, Logger, QueryFactory);
return keyRepo.Get(key);
}
@@ -297,8 +294,8 @@ namespace Umbraco.Core.Persistence.Repositories
private IRepositoryCachePolicy _cachePolicy;
private readonly DictionaryRepository _dictionaryRepository;
- public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
_dictionaryRepository = dictionaryRepository;
}
@@ -358,8 +355,8 @@ namespace Umbraco.Core.Persistence.Repositories
private IRepositoryCachePolicy _cachePolicy;
private readonly DictionaryRepository _dictionaryRepository;
- public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
_dictionaryRepository = dictionaryRepository;
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
index a5231b8ea6..0acbbd1262 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
@@ -6,12 +6,8 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
-using Umbraco.Core.Persistence.FaultHandling;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -22,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy _cachePolicy;
- public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs
index 96a1999f4d..0944ec811f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs
@@ -22,8 +22,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly Guid _containerObjectType;
- public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers, Guid containerObjectType)
- : base(work, cache, logger, mappers)
+ public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory, Guid containerObjectType)
+ : base(work, cache, logger, queryFactory)
{
var allowedContainers = new[] {Constants.ObjectTypes.DocumentTypeContainerGuid, Constants.ObjectTypes.MediaTypeContainerGuid, Constants.ObjectTypes.DataTypeContainerGuid};
_containerObjectType = containerObjectType;
diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
index c2f1c503eb..4977363510 100644
--- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
@@ -6,9 +6,7 @@ using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -21,12 +19,12 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class EntityRepository : DisposableObject, IEntityRepository
{
- private readonly QueryFactory _queryFactory;
+ private readonly IQueryFactory _queryFactory;
- public EntityRepository(IDatabaseUnitOfWork work, IMapperCollection mappers)
+ public EntityRepository(IDatabaseUnitOfWork work, IQueryFactory queryFactory)
{
UnitOfWork = work;
- _queryFactory = new QueryFactory(work.Database.SqlSyntax, mappers);
+ _queryFactory = queryFactory;
}
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs
index 2d43ee5d9f..4871c8c84f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs
@@ -9,17 +9,15 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Identity;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class ExternalLoginRepository : NPocoRepositoryBase, IExternalLoginRepository
{
- public ExternalLoginRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public ExternalLoginRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/DataTypeContainerRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/DataTypeContainerRepository.cs
index 0be6f8fde9..006e99d83d 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/DataTypeContainerRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/DataTypeContainerRepository.cs
@@ -1,14 +1,14 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
-using Umbraco.Core.Persistence.Mappers;
+using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
class DataTypeContainerRepository : EntityContainerRepository, IDataTypeContainerRepository
{
- public DataTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(uow, cache, logger, mappers, Constants.ObjectTypes.DataTypeContainerGuid)
+ public DataTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(uow, cache, logger, queryFactory, Constants.ObjectTypes.DataTypeContainerGuid)
{ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/DocumentTypeContainerRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/DocumentTypeContainerRepository.cs
index 8eaa210a97..516ecbd815 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/DocumentTypeContainerRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/DocumentTypeContainerRepository.cs
@@ -1,14 +1,15 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Mappers;
+using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
class DocumentTypeContainerRepository : EntityContainerRepository, IDocumentTypeContainerRepository
{
- public DocumentTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(uow, cache, logger, mappers, Constants.ObjectTypes.DocumentTypeContainerGuid)
+ public DocumentTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(uow, cache, logger, queryFactory, Constants.ObjectTypes.DocumentTypeContainerGuid)
{ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/MediaTypeContainerRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/MediaTypeContainerRepository.cs
index b11d241040..5a7947a6e5 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/MediaTypeContainerRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/MediaTypeContainerRepository.cs
@@ -1,14 +1,15 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Mappers;
+using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
class MediaTypeContainerRepository : EntityContainerRepository, IMediaTypeContainerRepository
{
- public MediaTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(uow, cache, logger, mappers, Constants.ObjectTypes.MediaTypeContainerGuid)
+ public MediaTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(uow, cache, logger, queryFactory, Constants.ObjectTypes.MediaTypeContainerGuid)
{ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
index b97576b5a6..00eca6635b 100644
--- a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
@@ -9,9 +9,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -23,8 +21,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy _cachePolicy;
- public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs
index d49ab92efd..8250388ff9 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs
@@ -9,9 +9,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -19,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories
internal class MacroRepository : NPocoRepositoryBase, IMacroRepository
{
- public MacroRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public MacroRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
index 75794912ac..c8c325480e 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
-using System.Xml.Linq;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
@@ -11,12 +10,9 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
-
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -29,8 +25,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly IMediaTypeRepository _mediaTypeRepository;
private readonly ITagRepository _tagRepository;
- public MediaRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection, IMapperCollection mappers)
- : base(work, cache, logger, contentSection, mappers)
+ public MediaRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection, IQueryFactory queryFactory)
+ : base(work, cache, logger, contentSection, queryFactory)
{
if (mediaTypeRepository == null) throw new ArgumentNullException(nameof(mediaTypeRepository));
if (tagRepository == null) throw new ArgumentNullException(nameof(tagRepository));
@@ -76,7 +72,7 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Where("umbracoNode.id in (@ids)", new { /*ids =*/ ids });
}
- return ProcessQuery(sql);
+ return MapQueryDtos(Database.Fetch(sql));
}
protected override IEnumerable PerformGetByQuery(IQuery query)
@@ -86,7 +82,7 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = translator.Translate()
.OrderBy(x => x.SortOrder);
- return ProcessQuery(sql);
+ return MapQueryDtos(Database.Fetch(sql));
}
#endregion
@@ -144,6 +140,15 @@ namespace Umbraco.Core.Persistence.Repositories
#region Overrides of VersionableRepositoryBase
+ public override IEnumerable GetAllVersions(int id)
+ {
+ var sql = GetBaseQuery(false)
+ .Where(GetBaseWhereClause(), new { Id = id })
+ .OrderByDescending(x => x.VersionDate);
+
+ return MapQueryDtos(Database.Fetch(sql), true);
+ }
+
public override IMedia GetByVersion(Guid versionId)
{
var sql = GetBaseQuery(false);
@@ -421,46 +426,66 @@ namespace Umbraco.Core.Persistence.Repositories
}
return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords,
- MapQueryDtos, orderBy, orderDirection, orderBySystemField, "cmsContentVersion",
+ x => MapQueryDtos(x), orderBy, orderDirection, orderBySystemField, "cmsContentVersion",
filterSql);
}
- private IEnumerable ProcessQuery(Sql sql)
+ private IEnumerable MapQueryDtos(List dtos, bool withCache = false)
{
- //NOTE: This doesn't allow properties to be part of the query
- var dtos = Database.Fetch(sql);
- return MapQueryDtos(dtos);
- }
+ var content = new IMedia[dtos.Count];
+ var defs = new List();
- private IEnumerable MapQueryDtos(List dtos)
- {
- var ids = dtos.Select(x => x.ContentDto.ContentTypeId).ToArray();
+ for (var i = 0; i < dtos.Count; i++)
+ {
+ var dto = dtos[i];
- //content types
- var contentTypes = ids.Length == 0 ? Enumerable.Empty() : _mediaTypeRepository.GetAll(ids).ToArray();
+ // if the cache contains the item, use it
+ if (withCache)
+ {
+ var cached = RuntimeCache.GetCacheItem(GetCacheIdKey(dto.NodeId));
+ if (cached != null)
+ {
+ content[i] = cached;
+ continue;
+ }
+ }
- var dtosWithContentTypes = dtos
- //This select into and null check are required because we don't have a foreign damn key on the contentType column
- // http://issues.umbraco.org/issue/U4-5503
- .Select(x => new { dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentDto.ContentTypeId) })
- .Where(x => x.contentType != null)
- .ToArray();
+ // else, need to fetch from the database
+ // content type repository is full-cache so OK to get each one independently
+ var contentType = _mediaTypeRepository.Get(dto.ContentDto.ContentTypeId);
+ var factory = new MediaFactory(contentType, NodeObjectTypeId, dto.NodeId);
+ content[i] = factory.BuildEntity(dto);
- //Go get the property data for each document
- var docDefs = dtosWithContentTypes.Select(d => new DocumentDefinition(
- d.dto.NodeId,
- d.dto.VersionId,
- d.dto.VersionDate,
- d.dto.ContentDto.NodeDto.CreateDate,
- d.contentType))
- .ToArray();
+ // need properties
+ defs.Add(new DocumentDefinition(
+ dto.NodeId,
+ dto.VersionId,
+ dto.VersionDate,
+ dto.ContentDto.NodeDto.CreateDate,
+ contentType
+ ));
+ }
- var propertyData = GetPropertyCollection(docDefs);
+ // load all properties for all documents from database in 1 query
+ var propertyData = GetPropertyCollection(defs.ToArray());
- return dtosWithContentTypes.Select(d => CreateMediaFromDto(
- d.dto,
- contentTypes.First(ct => ct.Id == d.dto.ContentDto.ContentTypeId),
- propertyData[d.dto.NodeId]));
+ // assign
+ var dtoIndex = 0;
+ foreach (var def in defs)
+ {
+ // move to corresponding item (which has to exist)
+ while (dtos[dtoIndex].NodeId != def.Id) dtoIndex++;
+
+ // complete the item
+ var cc = content[dtoIndex];
+ cc.Properties = propertyData[cc.Id];
+
+ //on initial construction we don't want to have dirty properties tracked
+ // http://issues.umbraco.org/issue/U4-1946
+ ((Entity)cc).ResetDirtyProperties(false);
+ }
+
+ return content;
}
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
index b07ea0c5bc..1980d5110f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
@@ -6,7 +6,6 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -19,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy _cachePolicy;
- public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy CachePolicy
diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
index b2a361dc10..367166f177 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
@@ -10,7 +10,6 @@ using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Cache;
-using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Persistence.Repositories
{
@@ -18,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories
internal class MemberGroupRepository : NPocoRepositoryBase, IMemberGroupRepository
{
- public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{ }
private readonly MemberGroupFactory _modelFactory = new MemberGroupFactory();
diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
index 9d0517bda2..9654906de9 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
@@ -11,7 +11,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
-
+using Umbraco.Core.Cache;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -30,8 +30,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ITagRepository _tagRepository;
private readonly IMemberGroupRepository _memberGroupRepository;
- public MemberRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, IContentSection contentSection, IMapperCollection mappers)
- : base(work, cache, logger, contentSection, mappers)
+ public MemberRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, IContentSection contentSection, IQueryFactory queryFactory)
+ : base(work, cache, logger, contentSection, queryFactory)
{
if (memberTypeRepository == null) throw new ArgumentNullException(nameof(memberTypeRepository));
if (tagRepository == null) throw new ArgumentNullException(nameof(tagRepository));
@@ -564,7 +564,7 @@ namespace Umbraco.Core.Persistence.Repositories
// better to create the query text only once!
return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords,
- MapQueryDtos, orderBy, orderDirection, orderBySystemField, "cmsMember",
+ x => MapQueryDtos(x), orderBy, orderDirection, orderBySystemField, "cmsMember",
filterSql);
}
@@ -598,56 +598,62 @@ namespace Umbraco.Core.Persistence.Repositories
return base.GetDatabaseFieldNameForOrderBy(orderBy);
}
- private IEnumerable MapQueryDtos(List dtos)
+ private IEnumerable MapQueryDtos(List dtos, bool withCache = false)
{
- var ids = dtos.Select(x => x.ContentVersionDto.ContentDto.ContentTypeId).ToArray();
+ var content = new IMember[dtos.Count];
+ var defs = new List();
- //content types
- var contentTypes = ids.Length == 0 ? Enumerable.Empty() : _memberTypeRepository.GetAll(ids).ToArray();
+ for (var i = 0; i < dtos.Count; i++)
+ {
+ var dto = dtos[i];
- var dtosWithContentTypes = dtos
- //This select into and null check are required because we don't have a foreign damn key on the contentType column
- // http://issues.umbraco.org/issue/U4-5503
- .Select(x => new { dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentVersionDto.ContentDto.ContentTypeId) })
- .Where(x => x.contentType != null)
- .ToArray();
+ // if the cache contains the item, use it
+ if (withCache)
+ {
+ var cached = RuntimeCache.GetCacheItem(GetCacheIdKey(dto.NodeId));
+ if (cached != null)
+ {
+ content[i] = cached;
+ continue;
+ }
+ }
- //Go get the property data for each document
- IEnumerable docDefs = dtosWithContentTypes.Select(d => new DocumentDefinition(
- d.dto.NodeId,
- d.dto.ContentVersionDto.VersionId,
- d.dto.ContentVersionDto.VersionDate,
- d.dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
- d.contentType));
+ // else, need to fetch from the database
+ // content type repository is full-cache so OK to get each one independently
+ var contentType = _memberTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId);
+ var factory = new MemberFactory(contentType, NodeObjectTypeId, dto.NodeId);
+ content[i] = factory.BuildEntity(dto);
- var propertyData = GetPropertyCollection(docDefs.ToArray());
+ // need properties
+ defs.Add(new DocumentDefinition(
+ dto.NodeId,
+ dto.ContentVersionDto.VersionId,
+ dto.ContentVersionDto.VersionDate,
+ dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
+ contentType
+ ));
+ }
- return dtosWithContentTypes.Select(d => CreateMemberFromDto(
- d.dto,
- contentTypes.First(ct => ct.Id == d.dto.ContentVersionDto.ContentDto.ContentTypeId),
- propertyData[d.dto.NodeId]));
- }
+ // load all properties for all documents from database in 1 query
+ var propertyData = GetPropertyCollection(defs.ToArray());
- ///
- /// Private method to create a member object from a MemberDto
- ///
- ///
- ///
- ///
- ///
- private IMember CreateMemberFromDto(MemberDto dto,
- IMemberType contentType,
- PropertyCollection propCollection)
- {
- var factory = new MemberFactory(contentType, NodeObjectTypeId, dto.ContentVersionDto.NodeId);
- var member = factory.BuildEntity(dto);
+ // assign
+ var dtoIndex = 0;
+ foreach (var def in defs)
+ {
+ // move to corresponding item (which has to exist)
+ while (dtos[dtoIndex].NodeId != def.Id) dtoIndex++;
- member.Properties = propCollection;
+ // complete the item
+ var cc = content[dtoIndex];
+ cc.Properties = propertyData[cc.Id];
- //on initial construction we don't want to have dirty properties tracked
- // http://issues.umbraco.org/issue/U4-1946
- ((Entity)member).ResetDirtyProperties(false);
- return member;
+ //on initial construction we don't want to have dirty properties tracked
+ // http://issues.umbraco.org/issue/U4-1946
+ ((Entity)cc).ResetDirtyProperties(false);
+ }
+
+ return content;
}
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
index 983fc6ca5a..1cdc36807d 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
@@ -21,8 +21,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy _cachePolicy;
- public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy CachePolicy
diff --git a/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs
index d47f579ea4..376e620eeb 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs
@@ -10,17 +10,15 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class MigrationEntryRepository : NPocoRepositoryBase, IMigrationEntryRepository
{
- public MigrationEntryRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public MigrationEntryRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs
index 80a85c8b00..9c9843ba1e 100644
--- a/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs
@@ -4,7 +4,6 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -25,11 +24,11 @@ namespace Umbraco.Core.Persistence.Repositories
/// A database unit of work.
/// A cache helper.
/// A logger.
- /// A mappers collection.
- protected NPocoRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
+ /// A query factory.
+ protected NPocoRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger)
{
- QueryFactory = new QueryFactory(SqlSyntax, mappers);
+ QueryFactory = queryFactory;
}
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
index 2b0bbb25a5..03eaf6b839 100644
--- a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
@@ -7,9 +7,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -18,8 +16,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy _cachePolicy;
- public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy CachePolicy
diff --git a/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
index 7dc04f2681..a0720320ee 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
@@ -4,6 +4,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
+using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -12,8 +13,8 @@ namespace Umbraco.Core.Persistence.Repositories
where TEntity : class, IUmbracoEntity
where TRepository : class, IRepository
{
- protected RecycleBinRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IMapperCollection mappers)
- : base(work, cache, logger, contentSection, mappers)
+ protected RecycleBinRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IQueryFactory queryFactory)
+ : base(work, cache, logger, contentSection, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs
index 0a5f8c0237..dc1345d845 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -16,8 +13,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class RedirectUrlRepository : NPocoRepositoryBase, IRedirectUrlRepository
{
- public RedirectUrlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public RedirectUrlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{ }
protected override int PerformCount(IQuery query)
diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs
index ee4a4689f7..e31d2d31b8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs
@@ -11,9 +11,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -25,8 +23,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IRelationTypeRepository _relationTypeRepository;
- public RelationRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IRelationTypeRepository relationTypeRepository, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public RelationRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IRelationTypeRepository relationTypeRepository, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
_relationTypeRepository = relationTypeRepository;
}
@@ -47,34 +45,17 @@ namespace Umbraco.Core.Persistence.Repositories
throw new Exception(string.Format("RelationType with Id: {0} doesn't exist", dto.RelationType));
var factory = new RelationFactory(relationType);
- var entity = factory.BuildEntity(dto);
-
- //on initial construction we don't want to have dirty properties tracked
- // http://issues.umbraco.org/issue/U4-1946
- ((TracksChangesEntityBase)entity).ResetDirtyProperties(false);
-
- return entity;
+ return DtoToEntity(dto, factory);
}
- //TODO: Fix N+1 !
-
protected override IEnumerable PerformGetAll(params int[] ids)
{
- if (ids.Any())
- {
- foreach (var id in ids)
- {
- yield return Get(id);
- }
- }
- else
- {
- var dtos = Database.Fetch("WHERE id > 0");
- foreach (var dto in dtos)
- {
- yield return Get(dto.Id);
- }
- }
+ var sql = GetBaseQuery(false);
+ if (ids.Length > 0)
+ sql.WhereIn(x => x.Id, ids);
+ sql.OrderBy(x => x.RelationType);
+ var dtos = Database.Fetch(sql);
+ return DtosToEntities(dtos);
}
protected override IEnumerable PerformGetByQuery(IQuery query)
@@ -82,13 +63,36 @@ namespace Umbraco.Core.Persistence.Repositories
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator(sqlClause, query);
var sql = translator.Translate();
-
+ sql.OrderBy(x => x.RelationType);
var dtos = Database.Fetch(sql);
+ return DtosToEntities(dtos);
+ }
- foreach (var dto in dtos)
+ private IEnumerable DtosToEntities(IEnumerable dtos)
+ {
+ // in most cases, the relation type will be the same for all of them,
+ // plus we've ordered the relations by type, so try to allocate as few
+ // factories as possible - bearing in mind that relation types are cached
+ RelationFactory factory = null;
+ var relationTypeId = -1;
+
+ return dtos.Select(x =>
{
- yield return Get(dto.Id);
- }
+ if (relationTypeId != x.RelationType)
+ factory = new RelationFactory(_relationTypeRepository.Get(relationTypeId = x.RelationType));
+ return DtoToEntity(x, factory);
+ });
+ }
+
+ private static IRelation DtoToEntity(RelationDto dto, RelationFactory factory)
+ {
+ var entity = factory.BuildEntity(dto);
+
+ //on initial construction we don't want to have dirty properties tracked
+ // http://issues.umbraco.org/issue/U4-1946
+ ((TracksChangesEntityBase)entity).ResetDirtyProperties(false);
+
+ return entity;
}
#endregion
diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs
index a609b8c023..c8299cd118 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs
@@ -1,19 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using LightInject;
using NPoco;
using Umbraco.Core.Cache;
-using Umbraco.Core.DI;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
-
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -23,50 +18,45 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class RelationTypeRepository : NPocoRepositoryBase, IRelationTypeRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
- public RelationTypeRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public RelationTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
+ { }
+
+ protected override IRepositoryCachePolicy CachePolicy
{
+ get
+ {
+ if (_cachePolicy != null) return _cachePolicy;
+
+ // assuming we don't have tons of relation types, use a FullDataSet policy, ie
+ // cache the entire GetAll result once in a single collection - which can expire
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ true);
+
+ return _cachePolicy;
+ }
}
#region Overrides of RepositoryBase
protected override IRelationType PerformGet(int id)
{
- var sql = GetBaseQuery(false);
- sql.Where(GetBaseWhereClause(), new { Id = id });
-
- var dto = Database.Fetch(SqlSyntax.SelectTop(sql, 1)).FirstOrDefault();
- if (dto == null)
- return null;
-
- var factory = new RelationTypeFactory();
- var entity = factory.BuildEntity(dto);
-
- //on initial construction we don't want to have dirty properties tracked
- // http://issues.umbraco.org/issue/U4-1946
- ((TracksChangesEntityBase)entity).ResetDirtyProperties(false);
-
- return entity;
+ // use the underlying GetAll which will force cache all content types
+ return GetAll().FirstOrDefault(x => x.Id == id);
}
protected override IEnumerable PerformGetAll(params int[] ids)
{
+ var sql = GetBaseQuery(false);
+
+ // should not happen due to the cache policy
if (ids.Any())
- {
- foreach (var id in ids)
- {
- yield return Get(id);
- }
- }
- else
- {
- var dtos = Database.Fetch("WHERE id > 0");
- foreach (var dto in dtos)
- {
- yield return Get(dto.Id);
- }
- }
+ throw new NotImplementedException();
+
+ var dtos = Database.Fetch(sql);
+ var factory = new RelationTypeFactory();
+ return dtos.Select(x => DtoToEntity(x, factory));
}
protected override IEnumerable PerformGetByQuery(IQuery query)
@@ -76,11 +66,19 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = translator.Translate();
var dtos = Database.Fetch(sql);
+ var factory = new RelationTypeFactory();
+ return dtos.Select(x => DtoToEntity(x, factory));
+ }
- foreach (var dto in dtos)
- {
- yield return Get(dto.Id);
- }
+ private static IRelationType DtoToEntity(RelationTypeDto dto, RelationTypeFactory factory)
+ {
+ var entity = factory.BuildEntity(dto);
+
+ //on initial construction we don't want to have dirty properties tracked
+ // http://issues.umbraco.org/issue/U4-1946
+ ((TracksChangesEntityBase) entity).ResetDirtyProperties(false);
+
+ return entity;
}
#endregion
diff --git a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
index de8ee024c3..ea3dfb46ec 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
@@ -71,6 +71,12 @@ namespace Umbraco.Core.Persistence.Repositories
///
public abstract IQueryFactory QueryFactory { get; }
+ #region Static Queries
+
+ private IQuery _hasIdQuery;
+
+ #endregion
+
protected virtual TId GetEntityId(TEntity entity)
{
return (TId)(object)entity.Id;
@@ -91,9 +97,14 @@ namespace Umbraco.Core.Persistence.Repositories
var options = new RepositoryCachePolicyOptions(() =>
{
+ //create it once if it is needed (no need for locking here)
+ if (_hasIdQuery == null)
+ {
+ _hasIdQuery = Query.Where(x => x.Id != 0);
+ }
+
//Get count of all entities of current type (TEntity) to ensure cached result is correct
- var query = Query.Where(x => x.Id != 0);
- return PerformCount(query);
+ return PerformCount(_hasIdQuery);
});
_cachePolicy = new DefaultRepositoryCachePolicy(RuntimeCache, options);
diff --git a/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs
index 4132d9de6a..f0b913a41f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs
@@ -5,10 +5,8 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -18,8 +16,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy _cachePolicy;
- public ServerRegistrationRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IMapperCollection mappers)
- : base(work, CacheHelper.CreateDisabledCacheHelper(), logger, mappers)
+ public ServerRegistrationRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IQueryFactory queryFactory)
+ : base(work, CacheHelper.CreateDisabledCacheHelper(), logger, queryFactory)
{ }
protected override IRepositoryCachePolicy CachePolicy => _cachePolicy
diff --git a/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs b/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs
index 9c471a98e0..9b63a3b4f6 100644
--- a/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs
@@ -5,9 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -20,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories
where TDto: class
{
- protected SimpleGetRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ protected SimpleGetRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs
index 77224a0eaa..0b92ccf0b9 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs
@@ -9,17 +9,15 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class TagRepository : NPocoRepositoryBase, ITagRepository
{
- public TagRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public TagRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs
index 0585540f09..e5304376a8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs
@@ -1,27 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using AutoMapper;
using LightInject;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.DI;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class TaskRepository : NPocoRepositoryBase, ITaskRepository
{
- public TaskRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public TaskRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs
index 442daed787..ee739b0125 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs
@@ -9,17 +9,15 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
-using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class TaskTypeRepository : NPocoRepositoryBase, ITaskTypeRepository
{
- public TaskTypeRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public TaskTypeRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
index 4feff6db71..58321fb4b1 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
@@ -37,8 +37,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly MasterPageHelper _masterPageHelper;
private IRepositoryCachePolicy _cachePolicy;
- public TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
_masterpagesFileSystem = masterpageFileSystem;
_viewsFileSystem = viewFileSystem;
diff --git a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs
index 5103da91f0..62a40569f9 100644
--- a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs
@@ -28,8 +28,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly CacheHelper _cacheHelper;
private PermissionRepository _permissionRepository;
- public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository, IMapperCollection mappers)
- : base(work, cacheHelper, logger, mappers)
+ public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository, IQueryFactory queryFactory)
+ : base(work, cacheHelper, logger, queryFactory)
{
_userTypeRepository = userTypeRepository;
_cacheHelper = cacheHelper;
diff --git a/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs
index c1aabb4fe3..0e7f1d8208 100644
--- a/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs
@@ -20,8 +20,8 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class UserTypeRepository : NPocoRepositoryBase, IUserTypeRepository
{
- public UserTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ public UserTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
index 3213ce9745..a34a2389b4 100644
--- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
@@ -50,8 +50,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
//private readonly IContentSection _contentSection;
- protected VersionableRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IMapperCollection mappers)
- : base(work, cache, logger, mappers)
+ protected VersionableRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IQueryFactory queryFactory)
+ : base(work, cache, logger, queryFactory)
{
//_contentSection = contentSection;
}
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
index 51f19fe57d..7672860f2c 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
@@ -7,7 +7,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Persistence.SqlSyntax
{
///
- /// Represents an SqlSyntaxProvider for Sql Server
+ /// Represents an SqlSyntaxProvider for Sql Server.
///
[SqlSyntaxProvider(Constants.DbProviderNames.SqlServer)]
public class SqlServerSyntaxProvider : MicrosoftSqlSyntaxProviderBase
@@ -38,6 +38,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
V2008 = 4,
V2012 = 5,
V2014 = 6,
+ V2016 = 7,
Other = 99
}
@@ -70,6 +71,9 @@ namespace Umbraco.Core.Persistence.SqlSyntax
case "??":
ProductVersionName = VersionName.Invalid;
break;
+ case "13":
+ ProductVersionName = VersionName.V2016;
+ break;
case "12":
ProductVersionName = VersionName.V2014;
break;
@@ -136,7 +140,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
{
var items = db.Fetch("SELECT TableName = t.Name,ColumnName = c.Name,dc.Name,dc.[Definition] FROM sys.tables t INNER JOIN sys.default_constraints dc ON t.object_id = dc.parent_object_id INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND c.column_id = dc.parent_column_id");
return items.Select(x => new Tuple(x.TableName, x.ColumnName, x.Name, x.Definition));
- }
+ }
public override IEnumerable GetTablesInSchema(Database db)
{
@@ -181,9 +185,9 @@ from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id
inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id]
WHERE I.name NOT LIKE 'PK_%'
order by T.name, I.name");
- return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
+ return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
item.UNIQUE == 1)).ToList();
-
+
}
public override bool DoesTableExist(Database db, string tableName)
@@ -225,7 +229,7 @@ order by T.name, I.name");
switch (systemMethod)
{
case SystemMethods.NewGuid:
- return "NEWID()";
+ return "NEWID()";
case SystemMethods.CurrentDateTime:
return "GETDATE()";
//case SystemMethods.NewSequentialId:
@@ -239,7 +243,6 @@ order by T.name, I.name");
public override string DeleteDefaultConstraint => "ALTER TABLE [{0}] DROP CONSTRAINT [DF_{0}_{1}]";
-
public override string DropIndex => "DROP INDEX {0} ON {1}";
public override string RenameColumn => "sp_rename '{0}.{1}', '{2}', 'COLUMN'";
diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index ef52635030..4c21b643c3 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -28,14 +28,22 @@ namespace Umbraco.Core.Services
IDatabaseUnitOfWorkProvider provider,
ILogger logger,
IEventMessagesFactory eventMessagesFactory,
+ IQueryFactory queryFactory,
MediaFileSystem mediaFileSystem)
: base(provider, logger, eventMessagesFactory)
{
_mediaFileSystem = mediaFileSystem;
+ _notTrashedQuery = queryFactory.Create().Where(x => x.Trashed == false);
}
#endregion
+ #region Static Queries
+
+ private readonly IQuery _notTrashedQuery;
+
+ #endregion
+
#region Count
public int CountPublished(string contentTypeAlias = null)
@@ -826,8 +834,7 @@ namespace Umbraco.Core.Services
{
uow.ReadLock(Constants.Locks.ContentTree);
var repository = uow.CreateRepository();
- var query = repository.Query.Where(x => x.Trashed == false);
- var content = repository.GetByPublishedVersion(query);
+ var content = repository.GetByPublishedVersion(_notTrashedQuery);
uow.Complete();
return content;
}
diff --git a/src/Umbraco.Core/Services/EntityService.cs b/src/Umbraco.Core/Services/EntityService.cs
index ca8e936c3a..5acf19bc21 100644
--- a/src/Umbraco.Core/Services/EntityService.cs
+++ b/src/Umbraco.Core/Services/EntityService.cs
@@ -20,17 +20,18 @@ namespace Umbraco.Core.Services
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly Dictionary>> _supportedObjectTypes;
-
public EntityService(IDatabaseUnitOfWorkProvider provider, ILogger logger, IEventMessagesFactory eventMessagesFactory,
- IContentService contentService, IContentTypeService contentTypeService,
+ IContentService contentService, IContentTypeService contentTypeService,
IMediaService mediaService, IMediaTypeService mediaTypeService,
IDataTypeService dataTypeService,
IMemberService memberService, IMemberTypeService memberTypeService,
+ IQueryFactory queryFactory,
IRuntimeCacheProvider runtimeCache)
: base(provider, logger, eventMessagesFactory)
{
_runtimeCache = runtimeCache;
+ _rootEntityQuery = queryFactory.Create().Where(x => x.ParentId == -1);
_supportedObjectTypes = new Dictionary>>
{
@@ -60,12 +61,18 @@ namespace Umbraco.Core.Services
// ParentId = found.ParentId
// };
// }
-
+
//})}
};
}
+ #region Static Queries
+
+ private readonly IQuery _rootEntityQuery;
+
+ #endregion
+
///
/// Returns the integer id for a given GUID
///
@@ -108,7 +115,7 @@ namespace Umbraco.Core.Services
}
uow.Complete();
return id;
- }
+ }
});
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt.Fail();
}
@@ -435,8 +442,7 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.CreateUnitOfWork())
{
var repository = uow.CreateRepository();
- var query = repository.Query.Where(x => x.ParentId == -1);
- var entities = repository.GetByQuery(query, objectTypeId);
+ var entities = repository.GetByQuery(_rootEntityQuery, objectTypeId);
uow.Complete();
return entities;
}
diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs
index a3b6e6a58c..9478c0f4c8 100644
--- a/src/Umbraco.Core/Services/IMediaService.cs
+++ b/src/Umbraco.Core/Services/IMediaService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Xml.Linq;
using Umbraco.Core.Configuration;
using System.IO;
using Umbraco.Core.Models;
diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs
index 8cb8345046..e4258cd9b0 100644
--- a/src/Umbraco.Core/StringExtensions.cs
+++ b/src/Umbraco.Core/StringExtensions.cs
@@ -181,7 +181,7 @@ namespace Umbraco.Core
///
///
///
- internal static string CleanForXss(this string input, params char[] ignoreFromClean)
+ public static string CleanForXss(this string input, params char[] ignoreFromClean)
{
//remove any html
input = input.StripHtml();
diff --git a/src/Umbraco.Core/Sync/SingleServerRegistrar.cs b/src/Umbraco.Core/Sync/SingleServerRegistrar.cs
new file mode 100644
index 0000000000..dec0342fc0
--- /dev/null
+++ b/src/Umbraco.Core/Sync/SingleServerRegistrar.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Sync
+{
+ public class SingleServerRegistrar : IServerRegistrar
+ {
+ private readonly IRuntimeState _runtime;
+ private readonly Lazy _registrations;
+
+ public IEnumerable Registrations => _registrations.Value;
+
+ public SingleServerRegistrar(IRuntimeState runtime)
+ {
+ _runtime = runtime;
+ _registrations = new Lazy(() => new[] { new ServerAddressImpl(_runtime.ApplicationUrl.ToString()) });
+ }
+
+ public ServerRole GetCurrentServerRole()
+ {
+ return ServerRole.Single;
+ }
+
+ public string GetCurrentServerUmbracoApplicationUrl()
+ {
+ return _runtime.ApplicationUrl.ToString();
+ }
+
+ private class ServerAddressImpl : IServerAddress
+ {
+ public ServerAddressImpl(string serverAddress)
+ {
+ ServerAddress = serverAddress;
+ }
+
+ public string ServerAddress { get; }
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index f7a7fb1b28..bb942ccef5 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -331,7 +331,6 @@
-
@@ -349,7 +348,6 @@
- Component
@@ -374,6 +372,7 @@
+
@@ -386,7 +385,7 @@
-
+
@@ -398,6 +397,9 @@
+
+
+
@@ -407,6 +409,7 @@
+
@@ -442,6 +445,7 @@
+
@@ -503,6 +507,7 @@
+
@@ -987,10 +992,10 @@
-
-
+
+
-
+
@@ -1256,6 +1261,7 @@
+
@@ -1365,7 +1371,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Welcome to The Friendly CMS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome to The Friendly CMS
Thank you for choosing Umbraco - we think this could be the beginning of something beautiful. While it may feel overwhelming at first, we've done a lot to make the learning curve as smooth and fast as possible.
- Umbraco.TV will help you go from zero to Umbraco
- hero at a pace that suits you. Our easy to follow
- online training videos will give you the fundamental
- knowledge to start building awesome Umbraco websites.
-
- Our Umbraco - the official community site is your one
- stop for everything Umbraco. Whether you need a
- question answered or looking for cool plugins, the
- worlds best community is just a click away.
-
+ Umbraco.TV will help you go from zero to Umbraco
+ hero at a pace that suits you. Our easy to follow
+ online training videos will give you the fundamental
+ knowledge to start building awesome Umbraco websites.
+
+ Our Umbraco - the official community site is your one
+ stop for everything Umbraco. Whether you need a
+ question answered or looking for cool plugins, the
+ worlds best community is just a click away.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/media/move.html b/src/Umbraco.Web.UI.Client/src/views/media/move.html
index 95c30dfc40..3f71340ee3 100644
--- a/src/Umbraco.Web.UI.Client/src/views/media/move.html
+++ b/src/Umbraco.Web.UI.Client/src/views/media/move.html
@@ -3,8 +3,10 @@
- Choose where to move {{currentNode.name}} to in the tree structure below
-
+ Choose where to move
+ {{currentNode.name}}
+ to in the tree structure below
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.controller.js b/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.controller.js
index e4afb661e3..5ae1d4bf2c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.controller.js
@@ -30,6 +30,7 @@
vm.openLightbox = openLightbox;
vm.closeLightbox = closeLightbox;
vm.search = search;
+ vm.installCompleted = false;
var currSort = "Latest";
//used to cancel any request in progress if another one needs to take it's place
@@ -215,10 +216,8 @@
localStorageService.set("packageInstallUri", result.postInstallationPath);
}
- //reload on next digest (after cookie)
- $timeout(function() {
- window.location.reload(true);
- });
+ vm.installState.status = localizationService.localize("packager_installStateCompleted");
+ vm.installCompleted = true;
},
error);
@@ -277,6 +276,13 @@
searchDebounced();
}
+ vm.reloadPage = function () {
+ //reload on next digest (after cookie)
+ $timeout(function () {
+ window.location.reload(true);
+ });
+ }
+
init();
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.html b/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.html
index 3975dc96d9..e7b14182ca 100644
--- a/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.html
+++ b/src/Umbraco.Web.UI.Client/src/views/packager/views/repo.html
@@ -340,6 +340,16 @@
{{vm.installState.status}}
+
+
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html
index 4360996b55..16c5efe799 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html
@@ -39,7 +39,8 @@
on-drag-enter="vm.dragEnter()">
+
+ Web.Template.config
@@ -1068,6 +1070,7 @@
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2-Fluid.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2-Fluid.cshtml
index 446a82f510..f6b93139ce 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2-Fluid.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2-Fluid.cshtml
@@ -64,21 +64,29 @@
JObject cfg = contentItem.config;
if(cfg != null)
- foreach (JProperty property in cfg.Properties()) {
- attrs.Add(property.Name + "='" + property.Value.ToString() + "'");
+ foreach (JProperty property in cfg.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
-
+
JObject style = contentItem.styles;
- if (style != null) {
- var cssVals = new List();
- foreach (JProperty property in style.Properties())
- cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
+ if (style != null) {
+ var cssVals = new List();
+ foreach (JProperty property in style.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ if (string.IsNullOrWhiteSpace(propertyValue) == false)
+ {
+ cssVals.Add(property.Name + ":" + propertyValue + ";");
+ }
+ }
- if (cssVals.Any())
- attrs.Add("style='" + string.Join(" ", cssVals) + "'");
+ if (cssVals.Any())
+ attrs.Add("style='" + string.Join(" ", cssVals) + "'");
}
-
+
return new MvcHtmlString(string.Join(" ", attrs));
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2.cshtml
index 6bc730e1f8..c5fabe2abf 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap2.cshtml
@@ -64,21 +64,29 @@
JObject cfg = contentItem.config;
if(cfg != null)
- foreach (JProperty property in cfg.Properties()) {
- attrs.Add(property.Name + "=\"" + property.Value.ToString() + "\"");
+ foreach (JProperty property in cfg.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
-
+
JObject style = contentItem.styles;
- if (style != null) {
- var cssVals = new List();
- foreach (JProperty property in style.Properties())
- cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
+ if (style != null) {
+ var cssVals = new List();
+ foreach (JProperty property in style.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ if (string.IsNullOrWhiteSpace(propertyValue) == false)
+ {
+ cssVals.Add(property.Name + ":" + propertyValue + ";");
+ }
+ }
- if (cssVals.Any())
- attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
+ if (cssVals.Any())
+ attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
}
-
+
return new MvcHtmlString(string.Join(" ", attrs));
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3-Fluid.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3-Fluid.cshtml
index 1244821d7e..b7e8ef34fb 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3-Fluid.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3-Fluid.cshtml
@@ -5,6 +5,7 @@
@*
Razor helpers located at the bottom of this file
*@
+
@if (Model != null && Model.sections != null)
{
var oneColumn = ((System.Collections.ICollection)Model.sections).Count == 1;
@@ -59,21 +60,29 @@
JObject cfg = contentItem.config;
if(cfg != null)
- foreach (JProperty property in cfg.Properties()) {
- attrs.Add(property.Name + "='" + property.Value.ToString() + "'");
+ foreach (JProperty property in cfg.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
-
+
JObject style = contentItem.styles;
- if (style != null) {
- var cssVals = new List();
- foreach (JProperty property in style.Properties())
- cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
+ if (style != null) {
+ var cssVals = new List();
+ foreach (JProperty property in style.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ if (string.IsNullOrWhiteSpace(propertyValue) == false)
+ {
+ cssVals.Add(property.Name + ":" + propertyValue + ";");
+ }
+ }
- if (cssVals.Any())
- attrs.Add("style='" + string.Join(" ", cssVals) + "'");
+ if (cssVals.Any())
+ attrs.Add("style='" + string.Join(" ", cssVals) + "'");
}
-
+
return new MvcHtmlString(string.Join(" ", attrs));
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3.cshtml
index f76028d296..3a4fa3b8e2 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Bootstrap3.cshtml
@@ -64,21 +64,29 @@
JObject cfg = contentItem.config;
if(cfg != null)
- foreach (JProperty property in cfg.Properties()) {
- attrs.Add(property.Name + "=\"" + property.Value.ToString() + "\"");
+ foreach (JProperty property in cfg.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
-
+
JObject style = contentItem.styles;
- if (style != null) {
- var cssVals = new List();
- foreach (JProperty property in style.Properties())
- cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
+ if (style != null) {
+ var cssVals = new List();
+ foreach (JProperty property in style.Properties())
+ {
+ var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
+ if (string.IsNullOrWhiteSpace(propertyValue) == false)
+ {
+ cssVals.Add(property.Name + ":" + propertyValue + ";");
+ }
+ }
- if (cssVals.Any())
- attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
+ if (cssVals.Any())
+ attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
}
-
+
return new MvcHtmlString(string.Join(" ", attrs));
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Base.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Base.cshtml
index a86c04819a..ffb7603048 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Base.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Base.cshtml
@@ -1,5 +1,4 @@
@model dynamic
-@using Umbraco.Web.Templates
@functions {
public static string EditorView(dynamic contentItem)
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Embed.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Embed.cshtml
index 4fd66ddb90..c27be6bcdf 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Embed.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Embed.cshtml
@@ -1,3 +1,2 @@
@model dynamic
-@using Umbraco.Web.Templates
@Html.Raw(Model.value)
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Macro.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Macro.cshtml
index e0822808d8..ed08bb2484 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Macro.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Macro.cshtml
@@ -1,6 +1,4 @@
@inherits UmbracoViewPage
-@using Umbraco.Web.Templates
-
@if (Model.value != null)
{
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Media.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Media.cshtml
index f5dfc6459c..5b5adbdc7d 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Media.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Media.cshtml
@@ -1,5 +1,4 @@
@model dynamic
-@using Umbraco.Web.Templates
@if (Model.value != null)
{
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/TextString.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/TextString.cshtml
index a031c658a9..5a570efdb5 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/TextString.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/TextString.cshtml
@@ -4,10 +4,9 @@
@if (Model.editor.config.markup != null)
{
string markup = Model.editor.config.markup.ToString();
-
var UmbracoHelper = new UmbracoHelper(UmbracoContext.Current);
- markup = markup.Replace("#value#", UmbracoHelper.ReplaceLineBreaksForHtml(Model.value.ToString()));
+ markup = markup.Replace("#value#", UmbracoHelper.ReplaceLineBreaksForHtml(TemplateUtilities.CleanForXss(Model.value.ToString())));
markup = markup.Replace("#style#", Model.editor.config.style.ToString());
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml
index 104c81be7e..a6b7766eac 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml
@@ -30,6 +30,9 @@
Genindlæs elementerGenudgiv hele sitetGendan
+ Sæt rettigheder for siden %0%
+ Hvor vil du flytte
+ hen til i træstrukturen?RettighederFortryd ændringerSend til udgivelse
@@ -202,12 +205,12 @@
Færdig
-
+
Slettede %0% elementSlettede %0% elementerSlettede %0% ud af %1% elementSlettede %0% ud af %1% elementer
-
+
Udgav %0% elementUdgav %0% elementerUdgav %0% ud af %1% element
@@ -274,17 +277,11 @@
VælgSe cache elementOpret mappe...
-
Relatér til original
-
+ Inkludér undersiderLink til side
-
- Åbner det linket dokument i et nyt vindue eller fane
- Åbner det linket dokument i fuld visning af vinduet
- Åbner det linket dokument i "parent frame"
-
+ Åben linket i et nyt vindue eller faneLink til medie
-
Vælg medieVælg ikonVælg item
@@ -293,20 +290,18 @@
Vælg indholdVælg medlemVælg medlemsgruppe
-
Der er ingen parametre for denne makro
-
Link dit
- Fjern link fra dit
-
+ Fjern link fra ditkonto
-
Vælg editor
-
+ Du tilføjer flere sprog under 'sprog' i menuen til venstre
- ]]>
+ ]]>
+
KulturnavnRediger navnet på ordbogselementet.
@@ -327,17 +322,17 @@
Indtast nøgleord (tryk på Enter efter hvert nøgleord)...
- Tillad på rodniveau
+ Tillad på rodniveauKun dokumenttyper med denne indstilling aktiveret oprettes i rodniveau under Inhold og MediearkivTilladte typer
- Sammensætning af dokumenttyper
+ Sammensætning af dokumenttyperOpretSlet faneBeskrivelseNy faneFaneThumbnail
- Aktiver listevisning
+ Aktiver listevisningViser undersider i en søgbar liste, undersider vises ikke i indholdstræetNuværende listevisningDen aktive listevisningsdatatype
@@ -372,7 +367,7 @@
Der skete en fejl på severen
- Denne filttype er blevet deaktiveret af administratoren
+ Denne filttype er blevet deaktiveret af administratorenOBS! Selvom CodeMirror er slået til i konfigurationen, så er den deaktiveret i Internet Explorer fordi den ikke er stabil nok.Du skal udfylde både Alias & Navn på den nye egenskabstype!Der mangler læse/skrive rettigheder til bestemte filer og mapper
@@ -388,7 +383,7 @@
Du kan ikke opdele en celle, som ikke allerede er delt.Fejl i XSLT kodeDin XSLT er ikke opdateret, da det indeholdt en fejl
- Der er et problem med den datatype, der bruges til denn egenskab. Kontroller konfigurationen og prøv igen.
+ Der er et problem med den datatype, der bruges til denn egenskab. Kontroller konfigurationen og prøv igen.Om
@@ -474,7 +469,8 @@
Hvilken side skal vises efter at formularen er sendtStørrelseSortér
- Indsend
+ Indsend
+
TypeSkriv for at søge...Op
@@ -513,22 +509,22 @@
- Tilføj fane
- Tilføj egenskab
- Tilføj editor
- Tilføj skabelon
- Tilføj child node
- Tilføj child
+ Tilføj fane
+ Tilføj egenskab
+ Tilføj editor
+ Tilføj skabelon
+ Tilføj child node
+ Tilføj child
- Rediger datatype
+ Rediger datatype
- Naviger sektioner
+ Naviger sektioner
- Genveje
- Vis genveje
+ Genveje
+ Vis genveje
- Brug listevisning
- Tillad på rodniveau
+ Brug listevisning
+ Tillad på rodniveau
@@ -546,13 +542,17 @@
Kunne ikke gemme web.config filen. Du bedes venligst manuelt ændre database forbindelses strengen.Din database er blevet fundet og identificeret somDatabase konfiguration
-
+ installér knappen for at installere Umbraco %0% databasen
- ]]>
+ ]]>
+ installér knappen for at installere Umbraco %0% databasen]]>Næste for at fortsætte.]]>
- Databasen er ikke fundet. Kontrollér venligst at informationen i database forbindelsesstrengen i "web.config" filen er korrekt.
-
For at fortsætte bedes du venligst rette "web.config" filen (ved at bruge Visual Studio eller dit favoritprogram), scroll til bunden, tilføj forbindelsesstrengen til din database i feltet som hedder "umbracoDbDSN" og gem filen.
]]>
+
+ Databasen er ikke fundet. Kontrollér venligst at informationen i database forbindelsesstrengen i "web.config" filen er korrekt.
+
For at fortsætte bedes du venligst rette "web.config" filen (ved at bruge Visual Studio eller dit favoritprogram), scroll til bunden, tilføj forbindelsesstrengen til din database i feltet som hedder "umbracoDbDSN" og gem filen.
]]>
+ Kontakt venligst din ISP hvis det er nødvendigt. Hvis du installerer på en lokal maskine eller server kan du muligvis få informationerne fra din systemadministrator.]]>Tryk på Opgradér knappen for at opgradere din database til Umbraco %0%
Bare rolig - intet indhold vil blive slettet og alt vil stadig fungere bagefter!
]]>Tryk på Næste for at fortsætte.]]>
@@ -598,8 +598,10 @@
Yderligere hjælpe og informationer Få hjælp fra vores prisvindende fællesskab, gennemse dokumentationen eller se nogle gratis videoer om hvordan du opsætter et simpelt site, hvordan du bruger pakker og en 'quick guide' til Umbraco terminologier]]>Umbraco %0% er installeret og klar til brug/web.config filen og opdatére 'AppSetting' feltet UmbracoConfigurationStatus i bunden til '%0%'.]]>
- komme igang med det samme ved at klikke på "Start Umbraco" knappen nedenfor. Hvis du er ny med Umbraco, kan du finde masser af ressourcer på vores 'getting started' sider.
-]]>
+
+ komme igang med det samme ved at klikke på "Start Umbraco" knappen nedenfor. Hvis du er ny med Umbraco, kan du finde masser af ressourcer på vores 'getting started' sider.
+]]>
+ Start UmbracoFor at administrere dit website skal du blot åbne Umbraco administrationen og begynde at tilføje indhold, opdatere skabelonerne og stylesheets'ene eller tilføje ny funktionalitet.]]>Forbindelse til databasen fejlede.Umbraco Version 3
@@ -674,12 +676,15 @@ Gå til http://%4%/#/content/content/edit/%5% for at redigere.
Ha' en dejlig dag!
Mange hilsner fra Umbraco robotten
- ]]>
- Hej %0%
+ ]]>
+
+
+ Hej %0%
Dette er en automatisk mail for at informere dig om at opgaven '%1%'
er blevet udførtpå siden '%2%' af brugeren '%3%'
]]>
+
[%0%] Notificering om %1% udført på %2%Notificeringer
@@ -700,8 +705,10 @@ Mange hilsner fra Umbraco robotten
Pakken blev fjernetPakken er på succefuld vis blevet fjernetAfinstallér pakke
-
-Bemærk: at dokumenter og medier som afhænger af denne pakke vil muligvis holde op med at virke, så vær forsigtig. Hvis i tvivl, kontakt personen som har udviklet pakken.]]>
+
+
+Bemærk: at dokumenter og medier som afhænger af denne pakke vil muligvis holde op med at virke, så vær forsigtig. Hvis i tvivl, kontakt personen som har udviklet pakken.]]>
+ Download opdatering fra opbevaringsbasenOpdatér pakkeOpdateringsinstrukser
@@ -734,6 +741,19 @@ Mange hilsner fra Umbraco robotten
Hvis du blot ønsker at opsætte simpel beskyttelse ved hjælp af et enkelt login og kodeord
+ Udgivelsen kunne ikke udgives da publiceringsdato er sat
+
+
+
+
+
+
+ Udgivelsen fejlede fordi en overordnet side ikke er publiceret
+
%0% kunne ikke udgives, fordi et 3. parts modul annullerede handlingenMedtag ikke-udgivede undersiderPublicerer - vent venligst...
@@ -807,58 +827,58 @@ Mange hilsner fra Umbraco robotten
- Kompositioner
- Du har ikke tilføjet nogle faner
- Tilføj ny fane
- Tilføj endnu en fane
- Nedarvet fra
- Tilføj property
- Påkrævet label
+ Kompositioner
+ Du har ikke tilføjet nogle faner
+ Tilføj ny fane
+ Tilføj endnu en fane
+ Nedarvet fra
+ Tilføj property
+ Påkrævet label
- Aktiver listevisning
- Konfigurer indholdet til at blive vist i en sorterbar og søgbar liste, dens børn vil ikke blive vist i træet
+ Aktiver listevisning
+ Konfigurer indholdet til at blive vist i en sorterbar og søgbar liste, dens børn vil ikke blive vist i træet
- Tilladte skabeloner
- Vælg hvilke skabeloner der er tilladt at bruge på dette indhold
+ Tilladte skabeloner
+ Vælg hvilke skabeloner der er tilladt at bruge på dette indhold
- Tillad på rodniveau
- Kun dokumenttyper med denne indstilling aktiveret oprettes i rodniveau under inhold og mediearkiv
- Ja – indhold af denne type er tilladt i roden
+ Tillad på rodniveau
+ Kun dokumenttyper med denne indstilling aktiveret oprettes i rodniveau under inhold og mediearkiv
+ Ja – indhold af denne type er tilladt i roden
- Tilladte typer
- Tillad at oprette indhold af en specifik type under denne
+ Tilladte typer
+ Tillad at oprette indhold af en specifik type under denne
- Vælg child node
+ Vælg child node
- Nedarv faner og egenskaber fra en anden dokumenttype. Nye faner vil blive tilføjet den nuværende dokumenttype eller sammenflettet hvis fanenavnene er ens.
- Indholdstypen bliver brugt i en komposition og kan derfor ikke blive anvendt som komposition
- Der er ingen indholdstyper tilgængelige at bruge som komposition
+ Nedarv faner og egenskaber fra en anden dokumenttype. Nye faner vil blive tilføjet den nuværende dokumenttype eller sammenflettet hvis fanenavnene er ens.
+ Indholdstypen bliver brugt i en komposition og kan derfor ikke blive anvendt som komposition
+ Der er ingen indholdstyper tilgængelige at bruge som komposition
- Tilgængelige editors
- Genbrug
- Editor indstillinger
+ Tilgængelige editors
+ Genbrug
+ Editor indstillinger
- Konfiguration
+ Konfiguration
- Ja, slet
+ Ja, slet
- blev flyttet til
- Vælg hvor
- skal flyttes til
+ blev flyttet til
+ Vælg hvor
+ skal flyttes til
- Alle dokumenttyper
- Alle dokumenter
- Alle medier
+ Alle dokumenttyper
+ Alle dokumenter
+ Alle medier
- som benytter denne dokumenttype vil blive slettet permanent. Bekræft at du også vil slette dem.
- som benytter denne medietype vil blive slettet permanent. Bekræft at du også vil slette dem.
- som benytter denne medlemstype vil blive slettet permanent. Bekræft at du også vil slette dem.
+ som benytter denne dokumenttype vil blive slettet permanent. Bekræft at du også vil slette dem.
+ som benytter denne medietype vil blive slettet permanent. Bekræft at du også vil slette dem.
+ som benytter denne medlemstype vil blive slettet permanent. Bekræft at du også vil slette dem.
- og alle dokumenter, som benytter denne type
- og alle medier, som benytter denne type
- og alle medlemmer, som benytter denne type
+ og alle dokumenter, som benytter denne type
+ og alle medier, som benytter denne type
+ og alle medlemmer, som benytter denne type
- der bruger denne editor vil blive opdateret med de nye indstillinger
+ der bruger denne editor vil blive opdateret med de nye indstillinger
@@ -922,8 +942,6 @@ Mange hilsner fra Umbraco robotten
AnnulleretHandlingen blev annulleret af et 3. part tilføjelsesprogram
- Udgivelsen blev standset af et 3. parts modul
- Udgivelsen kunne ikke udgives da publiceringsdato er satProperty type eksisterer alleredeEgenskabstype oprettet DataType: %1%]]>
@@ -937,7 +955,6 @@ Mange hilsner fra Umbraco robotten
Stylesheet gemt uden fejlDatatype gemtOrdbogsnøgle gemt
- Udgivelsen fejlede fordi en overordnet side ikke er publiceretIndhold publiceretog nu synligt for besøgendeIndhold gemt
@@ -1141,11 +1158,28 @@ Mange hilsner fra Umbraco robotten
Session udløber
- Validation
- Valider som email
- Valider som tal
- Valider som Url
- ...eller indtast din egen validering
- Feltet er påkrævet
+ Validation
+ Valider som email
+ Valider som tal
+ Valider som Url
+ ...eller indtast din egen validering
+ Feltet er påkrævet
+
+
+ Slå URL tracker fra
+ Slå URL tracker til
+ Original URL
+ Viderestillet til
+ Der er ikke lavet nogen viderestillinger
+ Når en udgivet side bliver omdøbt eller flyttet, vil en viderestilling automatisk blive lavet til den nye side.
+ Fjern
+ Er du sikker på at du vil fjerne viderestillingen fra '%0%' til '%1%'?
+ Viderestillings URL fjernet.
+ Fejl under fjernelse af viderestillings URL.
+ Er du sikker på at du vil slå URL trackeren fra?
+ URL tracker er nu slået fra.
+ Der opstod en fejl under forsøget på at slå URL trackeren fra, der findes mere information i logfilen.
+ URL tracker er nu slået fra.
+ Der opstod en fejl under forsøget på at slå URL trackeren til, der findes mere information i logfilen.
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml
index 5f0180259a..87012194e3 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml
@@ -28,6 +28,9 @@
ReloadRepublish entire siteRestore
+ Set permissions for the page %0%
+ Choose where to move
+ to in the tree structure belowPermissionsRollbackSend To Publish
@@ -287,18 +290,12 @@
Pick itemView Cache ItemCreate folder...
-
Relate to original
+ Include descendantsThe friendliest community
-
Link to page
-
Opens the linked document in a new window or tab
- Opens the linked document in the full body of the window
- Opens the linked document in the parent frame
-
Link to media
-
Select mediaSelect iconSelect item
@@ -308,19 +305,14 @@
Select memberSelect member groupNo icons were found
-
There are no parameters for this macro
-
External login providersException DetailsStacktraceInner Exception
-
Link yourUn-Link your
-
account
-
Select editor
@@ -826,6 +818,7 @@ To manage your website, simply open the Umbraco back office and start adding con
Installing...Restarting, please wait...All done, your browser will now refresh, please wait...
+ Please click finish to complete installation and reload page.Paste with full formatting (Not recommended)
@@ -1345,7 +1338,7 @@ To manage your website, simply open the Umbraco back office and start adding con
Custom errors successfully set to '%0%'.MacroErrors are set to '%0%'.
- MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely when there's any errors in macros. Rectifying this will set the value to '%1%'.
+ MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'.MacroErrors are now set to '%0%'.
+ ZatwierdźTypSzukajW górę
@@ -356,8 +356,8 @@ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]>
Witaj...SzerokośćTak
- Reorder
- I am done reordering
+ Zmień kolejność
+ Kolejność została zmienionaKolor tła
@@ -789,7 +789,7 @@ Miłego dnia!]]>
AdministratorPole kategorii
- TRANSLATE ME: 'Change Your Password'
+ Zmień hasło!TRANSLATE ME: 'You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button'ZawartośćOpis
@@ -803,10 +803,10 @@ Miłego dnia!]]>
SekcjeWyłącz dostęp do UmbracoHasło
- TRANSLATE ME: 'Your password has been changed!'
- TRANSLATE ME: 'Please confirm the new password'
- TRANSLATE ME: 'Enter your new password'
- TRANSLATE ME: 'Your new password cannot be blank!'
+ Twoje hasło zostało zmienione!
+ Proszę potwierdź nowe hasło!
+ Wprowadź nowe hasło
+ Nowe hasło nie może byc puste!TRANSLATE ME: 'There was a difference between the new password and the confirmed password. Please try again!'TRANSLATE ME: 'The confirmed password doesn't match the new password!'Zastąp prawa dostępu dla węzłów potomnych
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
index 071f5fbd05..1c4592adb0 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
@@ -340,18 +340,11 @@
Выберите элементПросмотр элемента кэшаСоздать папку...
-
Связать с оригиналомСамое дружелюбное сообщество
-
Ссылка на страницу
-
Открывает документ по ссылке в новом окне или вкладке браузера
- Открывает документ по ссылке в полноэкранном режиме
- Открывает документ по ссылке в родительском фрейме
-
Ссылка на медиа-файл
-
Выбрать медиаВыбрать значокВыбрать элемент
@@ -360,19 +353,14 @@
Выбрать содержимоеВыбрать участникаВыбрать группу участников
-
Это макрос без параметров
-
Провайдеры аутентификацииПодробное сообщение об ошибкеТрассировка стекаВнутренняя ошибка
-
СвязатьРазорвать связь
-
учетную запись
-
Выбрать редактор
@@ -380,6 +368,12 @@
Ниже Вы можете указать различные переводы данной статьи словаря '%0%' Добавить другие языки можно, воспользовавшись пунктом 'Языки' в меню слева
]]>
Название языка (культуры)
+ Редактировать элемент (ключ) словаря
+
+
+ Допустим как корневой
@@ -655,7 +649,7 @@
Медиа - всего в XML: %0%, всего: %1%Б с ошибками: %2%Содержимое - всего в XML: %0%, всего опубликовано: %1%, с ошибками: %2%
- Сертификат Вашего сайта отмечен как проверенный.
+ Сертификат Вашего веб-сайта отмечен как проверенный.Ошибка проверки сертификата: '%0%'Ошибка проверки адреса URL %0% - '%1%'Сейчас Вы %0% просматриваете сайт, используя протокол HTTPS.
diff --git a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js
index e40e59e792..f8d1061cbe 100644
--- a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js
+++ b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js
@@ -281,7 +281,7 @@ Umbraco.Application.Actions = function() {
actionRePublish: function() {
///
- UmbClientMgr.openModalWindow('dialogs/republish.aspx?rnd=' + this._utils.generateRandom(), 'Republishing entire site', true, 450, 210);
+ UmbClientMgr.openModalWindow('dialogs/republish.aspx?rnd=' + this._utils.generateRandom(), uiKeys['actions_republish'], true, 450, 210);
},
actionAssignDomain: function() {
diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
index 061fc57775..f254028ceb 100644
--- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
+++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
@@ -353,5 +353,19 @@ namespace Umbraco.Web.Cache
}
#endregion
+
+ #region Relation type cache
+
+ public static void RefreshRelationTypeCache(this DistributedCache dc, int id)
+ {
+ dc.Refresh(RelationTypeCacheRefresher.UniqueId, id);
+ }
+
+ public static void RemoveRelationTypeCache(this DistributedCache dc, int id)
+ {
+ dc.Remove(RelationTypeCacheRefresher.UniqueId, id);
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Cache/RelationTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/RelationTypeCacheRefresher.cs
new file mode 100644
index 0000000000..798a5e5ebb
--- /dev/null
+++ b/src/Umbraco.Web/Cache/RelationTypeCacheRefresher.cs
@@ -0,0 +1,56 @@
+using System;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Models;
+using Umbraco.Core.Persistence.Repositories;
+
+namespace Umbraco.Web.Cache
+{
+ public sealed class RelationTypeCacheRefresher : CacheRefresherBase
+ {
+ public RelationTypeCacheRefresher(CacheHelper cacheHelper)
+ : base(cacheHelper)
+ { }
+
+ #region Define
+
+ protected override RelationTypeCacheRefresher Instance => this;
+
+ public static readonly Guid UniqueId = Guid.Parse("D8375ABA-4FB3-4F86-B505-92FBA1B6F7C9");
+
+ public override Guid RefresherUniqueId => UniqueId;
+
+ public override string Name => "Relation Type Cache Refresher";
+
+ #endregion
+
+ #region Refresher
+
+ public override void RefreshAll()
+ {
+ ClearAllIsolatedCacheByEntityType();
+ base.RefreshAll();
+ }
+
+ public override void Refresh(int id)
+ {
+ var cache = CacheHelper.IsolatedRuntimeCache.GetCache();
+ if (cache) cache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id));
+ base.Refresh(id);
+ }
+
+ public override void Refresh(Guid id)
+ {
+ throw new NotSupportedException();
+ //base.Refresh(id);
+ }
+
+ public override void Remove(int id)
+ {
+ var cache = CacheHelper.IsolatedRuntimeCache.GetCache();
+ if (cache) cache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id));
+ base.Remove(id);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs
index 2a9fc3e8a1..67539734fd 100644
--- a/src/Umbraco.Web/Editors/MediaController.cs
+++ b/src/Umbraco.Web/Editors/MediaController.cs
@@ -517,8 +517,17 @@ namespace Umbraco.Web.Editors
{
var mediaType = Constants.Conventions.MediaTypes.File;
- if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext))
- mediaType = Constants.Conventions.MediaTypes.Image;
+ if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.AutoSelect)
+ {
+ if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext))
+ {
+ mediaType = Constants.Conventions.MediaTypes.Image;
+ }
+ }
+ else
+ {
+ mediaType = result.FormData["contentTypeAlias"];
+ }
//TODO: make the media item name "nice" since file names could be pretty ugly, we have
// string extensions to do much of this but we'll need:
diff --git a/src/Umbraco.Web/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs
index 3cef732311..4dcdf91c2f 100644
--- a/src/Umbraco.Web/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs
+++ b/src/Umbraco.Web/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
[HealthCheck(
"92ABBAA2-0586-4089-8AE2-9A843439D577",
"Excessive Headers",
- Description = "Checks to see if your site is revealing information in it's headers that gives away unnecessary details about the technology used to build and host it.",
+ Description = "Checks to see if your site is revealing information in its headers that gives away unnecessary details about the technology used to build and host it.",
Group = "Security")]
public class ExcessiveHeadersCheck : HealthCheck
{
diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
index ee169c27c8..2d50c6e7fe 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
@@ -42,38 +42,18 @@ namespace Umbraco.Web.Models.Mapping
//FROM IContent TO ContentItemDisplay
config.CreateMap()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.Updater,
- expression => expression.ResolveUsing(new CreatorResolver(_userService)))
- .ForMember(
- dto => dto.Icon,
- expression => expression.MapFrom(content => content.ContentType.Icon))
- .ForMember(
- dto => dto.ContentTypeAlias,
- expression => expression.MapFrom(content => content.ContentType.Alias))
- .ForMember(
- dto => dto.ContentTypeName,
- expression => expression.MapFrom(content => content.ContentType.Name))
- .ForMember(
- dto => dto.IsContainer,
- expression => expression.MapFrom(content => content.ContentType.IsContainer))
- .ForMember(display => display.IsChildOfListView, expression => expression.Ignore())
- .ForMember(
- dto => dto.Trashed,
- expression => expression.MapFrom(content => content.Trashed))
- .ForMember(
- dto => dto.PublishDate,
- expression => expression.MapFrom(content => GetPublishedDate(_contentService, content)))
- .ForMember(
- dto => dto.TemplateAlias, expression => expression.MapFrom(content => content.Template.Alias))
- .ForMember(
- dto => dto.HasPublishedVersion,
- expression => expression.MapFrom(content => content.HasPublishedVersion))
- .ForMember(
- dto => dto.Urls,
+ .ForMember(display => display.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(display => display.Updater, expression => expression.ResolveUsing(new CreatorResolver(_userService)))
+ .ForMember(display => display.Icon, expression => expression.MapFrom(content => content.ContentType.Icon))
+ .ForMember(display => display.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias))
+ .ForMember(display => display.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name))
+ .ForMember(display => display.IsContainer, expression => expression.MapFrom(content => content.ContentType.IsContainer))
+ .ForMember(display => display.IsChildOfListView, expression => expression.Ignore())
+ .ForMember(display => display.Trashed, expression => expression.MapFrom(content => content.Trashed))
+ .ForMember(display => display.PublishDate, expression => expression.MapFrom(content => GetPublishedDate(_contentService, content)))
+ .ForMember(display => display.TemplateAlias, expression => expression.MapFrom(content => content.Template.Alias))
+ .ForMember(display => display.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion))
+ .ForMember(display => display.Urls,
expression => expression.MapFrom(content =>
UmbracoContext.Current == null
? new[] {"Cannot generate urls without a current Umbraco Context"}
@@ -87,47 +67,27 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(display => display.Tabs, expression => expression.ResolveUsing(new TabsAndPropertiesResolver(_textService)))
.ForMember(display => display.AllowedActions, expression => expression.ResolveUsing(
new ActionButtonsResolver(new Lazy(() => _userService))))
- .AfterMap((media, display) => AfterMap(media, display, _dataTypeService, _textService,
- _contentTypeService, _contentService));
+ .AfterMap((content, display) => AfterMap(content, display, _dataTypeService, _textService, _contentTypeService, _contentService));
//FROM IContent TO ContentItemBasic
config.CreateMap>()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.Updater,
- expression => expression.ResolveUsing(new CreatorResolver(_userService)))
- .ForMember(
- dto => dto.Icon,
- expression => expression.MapFrom(content => content.ContentType.Icon))
- .ForMember(
- dto => dto.Trashed,
- expression => expression.MapFrom(content => content.Trashed))
- .ForMember(
- dto => dto.HasPublishedVersion,
- expression => expression.MapFrom(content => content.HasPublishedVersion))
- .ForMember(
- dto => dto.ContentTypeAlias,
- expression => expression.MapFrom(content => content.ContentType.Alias))
- .ForMember(display => display.Alias, expression => expression.Ignore());
+ .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(dto => dto.Updater, expression => expression.ResolveUsing(new CreatorResolver(_userService)))
+ .ForMember(dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon))
+ .ForMember(dto => dto.Trashed, expression => expression.MapFrom(content => content.Trashed))
+ .ForMember(dto => dto.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion))
+ .ForMember(dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias))
+ .ForMember(dto => dto.Alias, expression => expression.Ignore());
//FROM IContent TO ContentItemDto
config.CreateMap>()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.HasPublishedVersion,
- expression => expression.MapFrom(content => content.HasPublishedVersion))
- .ForMember(display => display.Updater, expression => expression.Ignore())
- .ForMember(display => display.Icon, expression => expression.Ignore())
- .ForMember(display => display.Alias, expression => expression.Ignore());
-
-
+ .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(dto => dto.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion))
+ .ForMember(dto => dto.Updater, expression => expression.Ignore())
+ .ForMember(dto => dto.Icon, expression => expression.Ignore())
+ .ForMember(dto => dto.Alias, expression => expression.Ignore());
}
-
///
/// Maps the generic tab with custom properties for content
///
@@ -137,7 +97,7 @@ namespace Umbraco.Web.Models.Mapping
///
///
///
- private static void AfterMap(IContent content, ContentItemDisplay display, IDataTypeService dataTypeService,
+ private static void AfterMap(IContent content, ContentItemDisplay display, IDataTypeService dataTypeService,
ILocalizedTextService localizedText, IContentTypeService contentTypeService, IContentService contentService)
{
//map the IsChildOfListView (this is actually if it is a descendant of a list view!)
@@ -165,7 +125,6 @@ namespace Umbraco.Web.Models.Mapping
display.IsChildOfListView = ancesctorListView != null;
}
}
-
//map the tree node url
if (HttpContext.Current != null)
@@ -174,9 +133,9 @@ namespace Umbraco.Web.Models.Mapping
var url = urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(display.Id.ToString(), null));
display.TreeNodeUrl = url;
}
-
+
//fill in the template config to be passed to the template drop down.
- var templateItemConfig = new Dictionary { { "", "Choose..." } };
+ var templateItemConfig = new Dictionary {{"", "Choose..."}};
foreach (var t in content.ContentType.AllowedTemplates
.Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false))
{
@@ -187,7 +146,7 @@ namespace Umbraco.Web.Models.Mapping
{
TabsAndPropertiesResolver.AddListView(display, "content", dataTypeService, localizedText);
}
-
+
var properties = new List
{
new ContentPropertyDisplay
@@ -197,7 +156,7 @@ namespace Umbraco.Web.Models.Mapping
Value = localizedText.UmbracoDictionaryTranslate(display.ContentTypeName),
View = Current.PropertyEditors[Constants.PropertyEditors.NoEditAlias].ValueEditor.View
},
- new ContentPropertyDisplay
+ new ContentPropertyDisplay
{
Alias = string.Format("{0}releasedate", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
Label = localizedText.Localize("content/releaseDate"),
@@ -209,7 +168,7 @@ namespace Umbraco.Web.Models.Mapping
{"offsetTime", "1"}
}
//TODO: Fix up hard coded datepicker
- } ,
+ },
new ContentPropertyDisplay
{
Alias = string.Format("{0}expiredate", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
@@ -260,21 +219,21 @@ namespace Umbraco.Web.Models.Mapping
var docTypeLink = string.Format("#/settings/documenttypes/edit/{0}", currentDocumentTypeId);
//Replace the doc type property
- var docTypeProp = genericProperties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
- docTypeProp.Value = new List
+ var docTypeProperty = genericProperties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
+ docTypeProperty.Value = new List
{
new
{
linkText = currentDocumentTypeName,
url = docTypeLink,
- target = "_self", icon = "icon-item-arrangement"
+ target = "_self",
+ icon = "icon-item-arrangement"
}
};
//TODO: Hard coding this because the templatepicker doesn't necessarily need to be a resolvable (real) property editor
- docTypeProp.View = "urllist";
+ docTypeProperty.View = "urllist";
}
});
-
}
///
@@ -319,13 +278,13 @@ namespace Umbraco.Web.Models.Mapping
var svc = _userService.Value;
var permissions = svc.GetPermissions(
- //TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is
- // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null
- // refrence exception :(
- UmbracoContext.Current.Security.CurrentUser,
- // Here we need to do a special check since this could be new content, in which case we need to get the permissions
- // from the parent, not the existing one otherwise permissions would be coming from the root since Id is 0.
- source.HasIdentity ? source.Id : source.ParentId)
+ //TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is
+ // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null
+ // refrence exception :(
+ UmbracoContext.Current.Security.CurrentUser,
+ // Here we need to do a special check since this could be new content, in which case we need to get the permissions
+ // from the parent, not the existing one otherwise permissions would be coming from the root since Id is 0.
+ source.HasIdentity ? source.Id : source.ParentId)
.FirstOrDefault();
return permissions == null
@@ -333,6 +292,5 @@ namespace Umbraco.Web.Models.Mapping
: permissions.AssignedPermissions.Where(x => x.Length == 1).Select(x => x.ToUpperInvariant()[0]);
}
}
-
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs
index f686297927..7394f9b099 100644
--- a/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs
@@ -39,22 +39,12 @@ namespace Umbraco.Web.Models.Mapping
{
//FROM IMedia TO MediaItemDisplay
config.CreateMap()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.Icon,
- expression => expression.MapFrom(content => content.ContentType.Icon))
- .ForMember(
- dto => dto.ContentTypeAlias,
- expression => expression.MapFrom(content => content.ContentType.Alias))
+ .ForMember(display => display.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(display => display.Icon, expression => expression.MapFrom(content => content.ContentType.Icon))
+ .ForMember(display => display.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias))
.ForMember(display => display.IsChildOfListView, expression => expression.Ignore())
- .ForMember(
- dto => dto.Trashed,
- expression => expression.MapFrom(content => content.Trashed))
- .ForMember(
- dto => dto.ContentTypeName,
- expression => expression.MapFrom(content => content.ContentType.Name))
+ .ForMember(display => display.Trashed, expression => expression.MapFrom(content => content.Trashed))
+ .ForMember(display => display.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name))
.ForMember(display => display.Properties, expression => expression.Ignore())
.ForMember(display => display.TreeNodeUrl, expression => expression.Ignore())
.ForMember(display => display.Notifications, expression => expression.Ignore())
@@ -63,39 +53,29 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(display => display.Updater, expression => expression.Ignore())
.ForMember(display => display.Alias, expression => expression.Ignore())
.ForMember(display => display.IsContainer, expression => expression.Ignore())
- .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore())
+ .ForMember(display => display.HasPublishedVersion, expression => expression.Ignore())
.ForMember(display => display.Tabs, expression => expression.ResolveUsing(new TabsAndPropertiesResolver(_textService)))
.AfterMap((media, display) => AfterMap(media, display, _dataTypeService, _textService, _logger, _mediaService));
//FROM IMedia TO ContentItemBasic
config.CreateMap>()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.Icon,
- expression => expression.MapFrom(content => content.ContentType.Icon))
- .ForMember(
- dto => dto.Trashed,
- expression => expression.MapFrom(content => content.Trashed))
- .ForMember(
- dto => dto.ContentTypeAlias,
- expression => expression.MapFrom(content => content.ContentType.Alias))
- .ForMember(x => x.Published, expression => expression.Ignore())
- .ForMember(x => x.Updater, expression => expression.Ignore())
- .ForMember(x => x.Alias, expression => expression.Ignore())
- .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore());
+ .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon))
+ .ForMember(dto => dto.Trashed, expression => expression.MapFrom(content => content.Trashed))
+ .ForMember(dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias))
+ .ForMember(dto => dto.Published, expression => expression.Ignore())
+ .ForMember(dto => dto.Updater, expression => expression.Ignore())
+ .ForMember(dto => dto.Alias, expression => expression.Ignore())
+ .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore());
//FROM IMedia TO ContentItemDto
config.CreateMap>()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(x => x.Published, expression => expression.Ignore())
- .ForMember(x => x.Updater, expression => expression.Ignore())
- .ForMember(x => x.Icon, expression => expression.Ignore())
- .ForMember(x => x.Alias, expression => expression.Ignore())
- .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore());
+ .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(dto => dto.Published, expression => expression.Ignore())
+ .ForMember(dto => dto.Updater, expression => expression.Ignore())
+ .ForMember(dto => dto.Icon, expression => expression.Ignore())
+ .ForMember(dto => dto.Alias, expression => expression.Ignore())
+ .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore());
}
private static void AfterMap(IMedia media, MediaItemDisplay display, IDataTypeService dataTypeService, ILocalizedTextService localizedText, ILogger logger, IMediaService mediaService)
@@ -165,8 +145,28 @@ namespace Umbraco.Web.Models.Mapping
genericProperties.Add(link);
}
- TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties);
- }
+ TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties, properties =>
+ {
+ if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null
+ && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
+ {
+ var mediaTypeLink = string.Format("#/settings/mediatypes/edit/{0}", media.ContentTypeId);
+ //Replace the doctype property
+ var docTypeProperty = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
+ docTypeProperty.Value = new List
+ {
+ new
+ {
+ linkText = media.ContentType.Name,
+ url = mediaTypeLink,
+ target = "_self",
+ icon = "icon-item-arrangement"
+ }
+ };
+ docTypeProperty.View = "urllist";
+ }
+ });
+ }
}
}
diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs
index 0c38879c7d..5eca1843d0 100644
--- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs
@@ -40,10 +40,10 @@ namespace Umbraco.Web.Models.Mapping
//FROM MembershipUser TO MediaItemDisplay - used when using a non-umbraco membership provider
config.CreateMap()
.ConvertUsing(user =>
- {
- var member = Mapper.Map(user);
- return Mapper.Map(member);
- });
+ {
+ var member = Mapper.Map(user);
+ return Mapper.Map(member);
+ });
//FROM MembershipUser TO IMember - used when using a non-umbraco membership provider
config.CreateMap()
@@ -73,23 +73,13 @@ namespace Umbraco.Web.Models.Mapping
//FROM IMember TO MediaItemDisplay
config.CreateMap()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.Icon,
- expression => expression.MapFrom(content => content.ContentType.Icon))
- .ForMember(
- dto => dto.ContentTypeAlias,
- expression => expression.MapFrom(content => content.ContentType.Alias))
- .ForMember(
- dto => dto.ContentTypeName,
- expression => expression.MapFrom(content => content.ContentType.Name))
+ .ForMember(display => display.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(display => display.Icon, expression => expression.MapFrom(content => content.ContentType.Icon))
+ .ForMember(display => display.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias))
+ .ForMember(display => display.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name))
.ForMember(display => display.Properties, expression => expression.Ignore())
- .ForMember(display => display.Tabs,
- expression => expression.ResolveUsing(new MemberTabsAndPropertiesResolver(_textService)))
- .ForMember(display => display.MemberProviderFieldMapping,
- expression => expression.ResolveUsing(new MemberProviderFieldMappingResolver()))
+ .ForMember(display => display.Tabs, expression => expression.ResolveUsing(new MemberTabsAndPropertiesResolver(_textService)))
+ .ForMember(display => display.MemberProviderFieldMapping, expression => expression.ResolveUsing(new MemberProviderFieldMappingResolver()))
.ForMember(display => display.MembershipScenario,
expression => expression.ResolveUsing(new MembershipScenarioMappingResolver(new Lazy(() => _memberTypeService))))
.ForMember(display => display.Notifications, expression => expression.Ignore())
@@ -101,31 +91,21 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(display => display.Trashed, expression => expression.Ignore())
.ForMember(display => display.IsContainer, expression => expression.Ignore())
.ForMember(display => display.TreeNodeUrl, expression => expression.Ignore())
- .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore())
+ .ForMember(display => display.HasPublishedVersion, expression => expression.Ignore())
.AfterMap((member, display) => MapGenericCustomProperties(_memberService, member, display, _textService));
//FROM IMember TO MemberBasic
config.CreateMap()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(
- dto => dto.Icon,
- expression => expression.MapFrom(content => content.ContentType.Icon))
- .ForMember(
- dto => dto.ContentTypeAlias,
- expression => expression.MapFrom(content => content.ContentType.Alias))
- .ForMember(
- dto => dto.Email,
- expression => expression.MapFrom(content => content.Email))
- .ForMember(
- dto => dto.Username,
- expression => expression.MapFrom(content => content.Username))
- .ForMember(display => display.Trashed, expression => expression.Ignore())
- .ForMember(x => x.Published, expression => expression.Ignore())
- .ForMember(x => x.Updater, expression => expression.Ignore())
- .ForMember(x => x.Alias, expression => expression.Ignore())
- .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore());
+ .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon))
+ .ForMember(dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias))
+ .ForMember(dto => dto.Email, expression => expression.MapFrom(content => content.Email))
+ .ForMember(dto => dto.Username, expression => expression.MapFrom(content => content.Username))
+ .ForMember(dto => dto.Trashed, expression => expression.Ignore())
+ .ForMember(dto => dto.Published, expression => expression.Ignore())
+ .ForMember(dto => dto.Updater, expression => expression.Ignore())
+ .ForMember(dto => dto.Alias, expression => expression.Ignore())
+ .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore());
//FROM MembershipUser TO MemberBasic
config.CreateMap()
@@ -134,41 +114,31 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(member => member.CreateDate, expression => expression.MapFrom(user => user.CreationDate))
.ForMember(member => member.UpdateDate, expression => expression.MapFrom(user => user.LastActivityDate))
.ForMember(member => member.Key, expression => expression.MapFrom(user => user.ProviderUserKey.TryConvertTo().Result.ToString("N")))
- .ForMember(
- dto => dto.Owner,
- expression => expression.UseValue(new UserBasic {Name = "Admin", UserId = 0}))
- .ForMember(
- dto => dto.Icon,
- expression => expression.UseValue("icon-user"))
+ .ForMember(member => member.Owner, expression => expression.UseValue(new UserBasic {Name = "Admin", UserId = 0}))
+ .ForMember(member => member.Icon, expression => expression.UseValue("icon-user"))
.ForMember(member => member.Name, expression => expression.MapFrom(user => user.UserName))
- .ForMember(
- dto => dto.Email,
- expression => expression.MapFrom(content => content.Email))
- .ForMember(
- dto => dto.Username,
- expression => expression.MapFrom(content => content.UserName))
+ .ForMember(member => member.Email, expression => expression.MapFrom(content => content.Email))
+ .ForMember(member => member.Username, expression => expression.MapFrom(content => content.UserName))
.ForMember(member => member.Properties, expression => expression.Ignore())
.ForMember(member => member.ParentId, expression => expression.Ignore())
.ForMember(member => member.Path, expression => expression.Ignore())
.ForMember(member => member.SortOrder, expression => expression.Ignore())
.ForMember(member => member.AdditionalData, expression => expression.Ignore())
- .ForMember(x => x.Published, expression => expression.Ignore())
- .ForMember(x => x.Updater, expression => expression.Ignore())
- .ForMember(dto => dto.Trashed, expression => expression.Ignore())
- .ForMember(x => x.Alias, expression => expression.Ignore())
- .ForMember(x => x.ContentTypeAlias, expression => expression.Ignore())
+ .ForMember(member => member.Published, expression => expression.Ignore())
+ .ForMember(member => member.Updater, expression => expression.Ignore())
+ .ForMember(member => member.Trashed, expression => expression.Ignore())
+ .ForMember(member => member.Alias, expression => expression.Ignore())
+ .ForMember(member => member.ContentTypeAlias, expression => expression.Ignore())
.ForMember(member => member.HasPublishedVersion, expression => expression.Ignore());
//FROM IMember TO ContentItemDto
config.CreateMap>()
- .ForMember(
- dto => dto.Owner,
- expression => expression.ResolveUsing(new OwnerResolver(_userService)))
- .ForMember(x => x.Published, expression => expression.Ignore())
- .ForMember(x => x.Updater, expression => expression.Ignore())
- .ForMember(x => x.Icon, expression => expression.Ignore())
- .ForMember(x => x.Alias, expression => expression.Ignore())
- .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore())
+ .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver(_userService)))
+ .ForMember(dto => dto.Published, expression => expression.Ignore())
+ .ForMember(dto => dto.Updater, expression => expression.Ignore())
+ .ForMember(dto => dto.Icon, expression => expression.Ignore())
+ .ForMember(dto => dto.Alias, expression => expression.Ignore())
+ .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore())
//do no map the custom member properties (currently anyways, they were never there in 6.x)
.ForMember(dto => dto.Properties, expression => expression.ResolveUsing(new MemberDtoPropertiesValueResolver()));
@@ -253,8 +223,28 @@ namespace Umbraco.Web.Models.Mapping
}
};
+ TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties =>
+ {
+ if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null
+ && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
+ {
+ var memberTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId);
- TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties);
+ //Replace the doctype property
+ var docTypeProperty = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
+ docTypeProperty.Value = new List
+ {
+ new
+ {
+ linkText = member.ContentType.Name,
+ url = memberTypeLink,
+ target = "_self",
+ icon = "icon-item-arrangement"
+ }
+ };
+ docTypeProperty.View = "urllist";
+ }
+ });
//check if there's an approval field
var provider = membersProvider as IUmbracoMemberTypeMembershipProvider;
@@ -267,7 +257,6 @@ namespace Umbraco.Web.Models.Mapping
prop.Value = 1;
}
}
-
}
///
@@ -276,6 +265,7 @@ namespace Umbraco.Web.Models.Mapping
///
///
///
+ ///
///
///
/// If the membership provider installed is the umbraco membership provider, then we will allow changing the username, however if
@@ -285,11 +275,11 @@ namespace Umbraco.Web.Models.Mapping
internal static ContentPropertyDisplay GetLoginProperty(IMemberService memberService, IMember member, MemberDisplay display, ILocalizedTextService localizedText)
{
var prop = new ContentPropertyDisplay
- {
- Alias = string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
- Label = localizedText.Localize("login"),
- Value = display.Username
- };
+ {
+ Alias = string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
+ Label = localizedText.Localize("login"),
+ Value = display.Username
+ };
var scenario = memberService.GetMembershipScenario();
@@ -342,8 +332,8 @@ namespace Umbraco.Web.Models.Mapping
var exclude = defaultProps.Select(x => x.Value.Alias).ToArray();
return source.Properties
- .Where(x => exclude.Contains(x.Alias) == false)
- .Select(Mapper.Map);
+ .Where(x => exclude.Contains(x.Alias) == false)
+ .Select(Mapper.Map);
}
}
@@ -396,7 +386,7 @@ namespace Umbraco.Web.Models.Mapping
}
else
{
- var umbracoProvider = (IUmbracoMemberTypeMembershipProvider)provider;
+ var umbracoProvider = (IUmbracoMemberTypeMembershipProvider) provider;
//This is kind of a hack because a developer is supposed to be allowed to set their property editor - would have been much easier
// if we just had all of the membeship provider fields on the member table :(
@@ -410,8 +400,6 @@ namespace Umbraco.Web.Models.Mapping
return result;
}
-
-
}
}
@@ -434,8 +422,8 @@ namespace Umbraco.Web.Models.Mapping
}
var memberType = _memberTypeService.Value.Get(Constants.Conventions.MemberTypes.DefaultAlias);
return memberType != null
- ? MembershipScenario.CustomProviderWithUmbracoLink
- : MembershipScenario.StandaloneCustomProvider;
+ ? MembershipScenario.CustomProviderWithUmbracoLink
+ : MembershipScenario.StandaloneCustomProvider;
}
}
@@ -459,7 +447,7 @@ namespace Umbraco.Web.Models.Mapping
}
else
{
- var umbracoProvider = (IUmbracoMemberTypeMembershipProvider)provider;
+ var umbracoProvider = (IUmbracoMemberTypeMembershipProvider) provider;
return new Dictionary
{
@@ -468,10 +456,7 @@ namespace Umbraco.Web.Models.Mapping
{Constants.Conventions.Member.Comments, umbracoProvider.CommentPropertyTypeAlias}
};
}
-
-
}
}
-
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs
index 72f81b97fe..7eb48817cc 100644
--- a/src/Umbraco.Web/Templates/TemplateUtilities.cs
+++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs
@@ -7,96 +7,101 @@ using Umbraco.Core.Logging;
namespace Umbraco.Web.Templates
{
- //NOTE: I realize there is only one class in this namespace but I'm pretty positive that there will be more classes in
- //this namespace once we start migrating and cleaning up more code.
+ //NOTE: I realize there is only one class in this namespace but I'm pretty positive that there will be more classes in
+ //this namespace once we start migrating and cleaning up more code.
- ///
- /// Utility class used for templates
- ///
- public static class TemplateUtilities
- {
+ ///
+ /// Utility class used for templates
+ ///
+ public static class TemplateUtilities
+ {
//TODO: Pass in an Umbraco context!!!!!!!! Don't rely on the singleton so things are more testable
internal static string ParseInternalLinks(string text, bool preview)
- {
+ {
using (UmbracoContext.Current.ForcedPreview(preview)) // force for url provider
{
text = ParseInternalLinks(text);
}
return text;
- }
+ }
- ///
- /// Parses the string looking for the {localLink} syntax and updates them to their correct links.
- ///
- ///
- ///
- public static string ParseInternalLinks(string text)
- {
+ ///
+ /// Parses the string looking for the {localLink} syntax and updates them to their correct links.
+ ///
+ ///
+ ///
+ public static string ParseInternalLinks(string text)
+ {
//TODO: Pass in an Umbraco context!!!!!!!! Don't rely on the singleton so things are more testable, better yet, pass in urlprovider, routing context, separately
- //don't attempt to proceed without a context as we cannot lookup urls without one
+ //don't attempt to proceed without a context as we cannot lookup urls without one
if (UmbracoContext.Current == null)
- {
- return text;
- }
+ {
+ return text;
+ }
- var urlProvider = UmbracoContext.Current.UrlProvider;
+ var urlProvider = UmbracoContext.Current.UrlProvider;
- // Parse internal links
- var tags = Regex.Matches(text, @"href=""[/]?(?:\{|\%7B)localLink:([0-9]+)(?:\}|\%7D)", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
- foreach (Match tag in tags)
- if (tag.Groups.Count > 0)
- {
- var id = tag.Groups[1].Value; //.Remove(tag.Groups[1].Value.Length - 1, 1);
- var newLink = urlProvider.GetUrl(int.Parse(id));
- text = text.Replace(tag.Value, "href=\"" + newLink);
- }
+ // Parse internal links
+ var tags = Regex.Matches(text, @"href=""[/]?(?:\{|\%7B)localLink:([0-9]+)(?:\}|\%7D)", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+ foreach (Match tag in tags)
+ if (tag.Groups.Count > 0)
+ {
+ var id = tag.Groups[1].Value; //.Remove(tag.Groups[1].Value.Length - 1, 1);
+ var newLink = urlProvider.GetUrl(int.Parse(id));
+ text = text.Replace(tag.Value, "href=\"" + newLink);
+ }
return text;
- }
+ }
- // static compiled regex for faster performance
- private readonly static Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+ // static compiled regex for faster performance
+ private readonly static Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
- ///
- /// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path.
- ///
- ///
- ///
- ///
- /// When used with a Virtual-Directory set-up, this would resolve all URLs correctly.
- /// The recommendation is that the "ResolveUrlsFromTextString" option (in umbracoSettings.config) is set to false for non-Virtual-Directory installs.
- ///
- public static string ResolveUrlsFromTextString(string text)
- {
+ ///
+ /// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path.
+ ///
+ ///
+ ///
+ ///
+ /// When used with a Virtual-Directory set-up, this would resolve all URLs correctly.
+ /// The recommendation is that the "ResolveUrlsFromTextString" option (in umbracoSettings.config) is set to false for non-Virtual-Directory installs.
+ ///
+ public static string ResolveUrlsFromTextString(string text)
+ {
if (UmbracoConfig.For.UmbracoSettings().Content.ResolveUrlsFromTextString == false) return text;
using (var timer = Current.ProfilingLogger.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete"))
- {
- // find all relative urls (ie. urls that contain ~)
- var tags = ResolveUrlPattern.Matches(text);
+ {
+ // find all relative urls (ie. urls that contain ~)
+ var tags = ResolveUrlPattern.Matches(text);
Current.Logger.Debug(typeof(IOHelper), "After regex: " + timer.Stopwatch.ElapsedMilliseconds + " matched: " + tags.Count);
- foreach (Match tag in tags)
- {
- var url = "";
- if (tag.Groups[1].Success)
- url = tag.Groups[1].Value;
+ foreach (Match tag in tags)
+ {
+ var url = "";
+ if (tag.Groups[1].Success)
+ url = tag.Groups[1].Value;
- // The richtext editor inserts a slash in front of the url. That's why we need this little fix
- // if (url.StartsWith("/"))
- // text = text.Replace(url, ResolveUrl(url.Substring(1)));
- // else
- if (String.IsNullOrEmpty(url) == false)
- {
- var resolvedUrl = (url.Substring(0, 1) == "/") ? IOHelper.ResolveUrl(url.Substring(1)) : IOHelper.ResolveUrl(url);
- text = text.Replace(url, resolvedUrl);
- }
- }
- }
+ // The richtext editor inserts a slash in front of the url. That's why we need this little fix
+ // if (url.StartsWith("/"))
+ // text = text.Replace(url, ResolveUrl(url.Substring(1)));
+ // else
+ if (String.IsNullOrEmpty(url) == false)
+ {
+ var resolvedUrl = (url.Substring(0, 1) == "/") ? IOHelper.ResolveUrl(url.Substring(1)) : IOHelper.ResolveUrl(url);
+ text = text.Replace(url, resolvedUrl);
+ }
+ }
+ }
- return text;
- }
+ return text;
+ }
- }
+ public static string CleanForXss(string text, params char[] ignoreFromClean)
+ {
+ return text.CleanForXss(ignoreFromClean);
+ }
+ }
}
diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs
index e960705495..c980958b78 100644
--- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs
+++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs
@@ -263,7 +263,7 @@ namespace Umbraco.Web.Trees
return Attempt.Succeed(
new LegacyUrlAction(
"dialogs/republish.aspx?rnd=" + DateTime.UtcNow.Ticks,
- "Republishing entire site"));
+ Current.Services.TextService.Localize("actions/republish")));
case "UmbClientMgr.appActions().actionAssignDomain()":
return Attempt.Succeed(
new LegacyUrlAction(
@@ -424,4 +424,4 @@ namespace Umbraco.Web.Trees
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 1bfb4935e7..681a385056 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -172,6 +172,7 @@
+
@@ -1740,11 +1741,13 @@
umbraco_org_umbraco_update_CheckForUpgrade
+ 11.0$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs
index 27eadf265b..e25fe4763b 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs
@@ -30,7 +30,7 @@ namespace umbraco.dialogs
protected void Page_Load(object sender, EventArgs e)
{
Button1.Text = Services.TextService.Localize("update");
- pane_form.Text = "Set permissions for the page " + _node.Text;
+ pane_form.Text = Services.TextService.Localize("actions/SetPermissionsForThePage",_node.Text);
}
override protected void OnInit(EventArgs e)
diff --git a/src/UmbracoExamine/UmbracoContentIndexer.cs b/src/UmbracoExamine/UmbracoContentIndexer.cs
index e562e38497..67033e42f7 100644
--- a/src/UmbracoExamine/UmbracoContentIndexer.cs
+++ b/src/UmbracoExamine/UmbracoContentIndexer.cs
@@ -28,28 +28,31 @@ namespace UmbracoExamine
///
public class UmbracoContentIndexer : BaseUmbracoIndexer
{
- protected IContentService ContentService { get; private set; }
- protected IMediaService MediaService { get; private set; }
- protected IUserService UserService { get; private set; }
+ protected IContentService ContentService { get; }
+ protected IMediaService MediaService { get; }
+ protected IUserService UserService { get; }
+
private readonly IEnumerable _urlSegmentProviders;
private readonly IQueryFactory _queryFactory;
private int? _parentId;
#region Constructors
- ///
- /// Default constructor
- ///
+ // default - bad, should inject instead
+ // usage: none
public UmbracoContentIndexer()
- : base()
{
ContentService = Current.Services.ContentService;
MediaService = Current.Services.MediaService;
UserService = Current.Services.UserService;
+
_urlSegmentProviders = Current.UrlSegmentProviders;
_queryFactory = Current.DatabaseContext.QueryFactory;
+
+ InitializeQueries();
}
+ // usage: IndexInitializer (tests)
public UmbracoContentIndexer(
IEnumerable fieldDefinitions,
Directory luceneDirectory,
@@ -66,12 +69,12 @@ namespace UmbracoExamine
IDictionary> indexValueTypes = null)
: base(fieldDefinitions, luceneDirectory, defaultAnalyzer, profilingLogger, validator, facetConfiguration, indexValueTypes)
{
- if (contentService == null) throw new ArgumentNullException("contentService");
- if (mediaService == null) throw new ArgumentNullException("mediaService");
- if (userService == null) throw new ArgumentNullException("userService");
- if (urlSegmentProviders == null) throw new ArgumentNullException("urlSegmentProviders");
- if (validator == null) throw new ArgumentNullException("validator");
- if (options == null) throw new ArgumentNullException("options");
+ if (contentService == null) throw new ArgumentNullException(nameof(contentService));
+ if (mediaService == null) throw new ArgumentNullException(nameof(mediaService));
+ if (userService == null) throw new ArgumentNullException(nameof(userService));
+ if (urlSegmentProviders == null) throw new ArgumentNullException(nameof(urlSegmentProviders));
+ if (validator == null) throw new ArgumentNullException(nameof(validator));
+ if (options == null) throw new ArgumentNullException(nameof(options));
if (queryFactory == null) throw new ArgumentNullException(nameof(queryFactory));
SupportProtectedContent = options.SupportProtectedContent;
@@ -87,8 +90,15 @@ namespace UmbracoExamine
UserService = userService;
_urlSegmentProviders = urlSegmentProviders;
_queryFactory = queryFactory;
+
+ InitializeQueries();
}
+ private void InitializeQueries()
+ {
+ if (_publishedQuery == null)
+ _publishedQuery = _queryFactory.Create().Where(x => x.Published);
+ }
#endregion
@@ -131,7 +141,7 @@ namespace UmbracoExamine
SupportProtectedContent = supportProtected;
else
SupportProtectedContent = false;
-
+
base.Initialize(name, config);
}
@@ -168,11 +178,8 @@ namespace UmbracoExamine
#endregion
-
#region Public methods
-
-
///
/// Deletes a node from the index.
///
@@ -209,6 +216,11 @@ namespace UmbracoExamine
#region Protected
+ ///
+ /// This is a static query, it's parameters don't change so store statically
+ ///
+ private static IQuery _publishedQuery;
+
protected override void PerformIndexAll(string type)
{
const int pageSize = 10000;
@@ -217,7 +229,6 @@ namespace UmbracoExamine
switch (type)
{
case IndexTypes.Content:
-
var contentParentId = -1;
if (ParentId.HasValue && ParentId.Value > 0)
{
@@ -237,9 +248,7 @@ namespace UmbracoExamine
else
{
//add the published filter
- var qry = _queryFactory.Create().Where(x => x.Published == true);
-
- descendants = ContentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "Path", Direction.Ascending, true, qry);
+ descendants = ContentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "Path", Direction.Ascending, true, _publishedQuery);
}
//if specific types are declared we need to post filter them
@@ -256,19 +265,21 @@ namespace UmbracoExamine
IndexItems(GetValueSets(content));
pageIndex++;
-
-
} while (content.Length == pageSize);
-
break;
case IndexTypes.Media:
-
var mediaParentId = -1;
+
if (ParentId.HasValue && ParentId.Value > 0)
{
mediaParentId = ParentId.Value;
}
+
+ // merge note: 7.5 changes this to use mediaService.GetPagedXmlEntries but we cannot merge the
+ // change here as mediaService does not provide access to Xml in v8 - and actually Examine should
+ // not assume that Umbraco provides Xml at all.
+
IMedia[] media;
do
@@ -321,10 +332,10 @@ namespace UmbracoExamine
{"writerName", new object[] {c.GetWriterProfile(UserService).Name}},
{"writerID", new object[] {c.WriterId}},
{"version", new object[] {c.Version}},
- {"template", new object[] {c.Template == null ? 0 : c.Template.Id}}
+ {"template", new object[] {c.Template?.Id ?? 0}}
};
- foreach (var property in c.Properties.Where(p => p != null && p.Value != null && p.Value.ToString().IsNullOrWhiteSpace() == false))
+ foreach (var property in c.Properties.Where(p => p?.Value != null && p.Value.ToString().IsNullOrWhiteSpace() == false))
{
values.Add(property.Alias, new[] {property.Value});
}
@@ -358,7 +369,7 @@ namespace UmbracoExamine
{"creatorName", new object[] {m.GetCreatorProfile(UserService).Name}}
};
- foreach (var property in m.Properties.Where(p => p != null && p.Value != null && p.Value.ToString().IsNullOrWhiteSpace() == false))
+ foreach (var property in m.Properties.Where(p => p?.Value != null && p.Value.ToString().IsNullOrWhiteSpace() == false))
{
values.Add(property.Alias, new[] { property.Value });
}
diff --git a/src/umbraco.cms/businesslogic/Packager/Installer.cs b/src/umbraco.cms/businesslogic/Packager/Installer.cs
index 03d687a905..f21a1aa5b0 100644
--- a/src/umbraco.cms/businesslogic/Packager/Installer.cs
+++ b/src/umbraco.cms/businesslogic/Packager/Installer.cs
@@ -380,7 +380,7 @@ namespace umbraco.cms.businesslogic.packager
if (languageItemsElement != null)
{
var insertedLanguages = packagingService.ImportLanguages(languageItemsElement);
- insPack.Data.Languages.AddRange(insertedLanguages.Select(l => l.Id.ToString()));
+ insPack.Data.Languages.AddRange(insertedLanguages.Select(l => l.Id.ToString(CultureInfo.InvariantCulture)));
}
#endregion
@@ -390,24 +390,17 @@ namespace umbraco.cms.businesslogic.packager
if (dictionaryItemsElement != null)
{
var insertedDictionaryItems = packagingService.ImportDictionaryItems(dictionaryItemsElement);
- insPack.Data.DictionaryItems.AddRange(insertedDictionaryItems.Select(d => d.Id.ToString()));
+ insPack.Data.DictionaryItems.AddRange(insertedDictionaryItems.Select(d => d.Id.ToString(CultureInfo.InvariantCulture)));
}
#endregion
#region Macros
- foreach (XmlNode n in Config.DocumentElement.SelectNodes("//macro"))
+ var macroItemsElement = rootElement.Descendants("Macros").FirstOrDefault();
+ if (macroItemsElement != null)
{
- //TODO: Fix this, this should not use the legacy API
- Macro m = Macro.Import(n);
-
- if (m != null)
- {
- insPack.Data.Macros.Add(m.Id.ToString(CultureInfo.InvariantCulture));
- //saveNeeded = true;
- }
+ var insertedMacros = packagingService.ImportMacros(macroItemsElement);
+ insPack.Data.Macros.AddRange(insertedMacros.Select(m => m.Id.ToString(CultureInfo.InvariantCulture)));
}
-
- //if (saveNeeded) { insPack.Save(); saveNeeded = false; }
#endregion
#region Templates
@@ -445,7 +438,7 @@ namespace umbraco.cms.businesslogic.packager
{
StyleSheet s = StyleSheet.Import(n, currentUser);
- insPack.Data.Stylesheets.Add(s.Id.ToString());
+ insPack.Data.Stylesheets.Add(s.Id.ToString(CultureInfo.InvariantCulture));
//saveNeeded = true;
}
diff --git a/src/umbraco.cms/businesslogic/macro/Macro.cs b/src/umbraco.cms/businesslogic/macro/Macro.cs
index 39a7367bc1..d441d4c00e 100644
--- a/src/umbraco.cms/businesslogic/macro/Macro.cs
+++ b/src/umbraco.cms/businesslogic/macro/Macro.cs
@@ -1,11 +1,8 @@
using System;
-using System.Data;
-using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
-using System.Runtime.CompilerServices;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.IO;
@@ -177,22 +174,25 @@ namespace umbraco.cms.businesslogic.macro
}
}
- ///
- /// Macro initializer
- ///
- public Macro()
+ ///
+ /// Macro initializer
+ ///
+ [Obsolete("This should no longer be used, use the IMacroService and related models instead")]
+ public Macro()
{
}
- ///
- /// Macro initializer
- ///
- /// The id of the macro
- public Macro(int Id)
+ ///
+ /// Macro initializer
+ ///
+ /// The id of the macro
+ [Obsolete("This should no longer be used, use the IMacroService and related models instead")]
+ public Macro(int Id)
{
Setup(Id);
}
+ [Obsolete("This should no longer be used, use the IMacroService and related models instead")]
internal Macro(IMacro macro)
{
MacroEntity = macro;
@@ -202,15 +202,17 @@ namespace umbraco.cms.businesslogic.macro
/// Initializes a new instance of the class.
///
/// The alias.
+ [Obsolete("This should no longer be used, use the IMacroService and related models instead")]
public Macro(string alias)
{
Setup(alias);
}
- ///
- /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
- ///
- public virtual void Save()
+ ///
+ /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
+ ///
+ [Obsolete("This should no longer be used, use the IMacroService and related models instead")]
+ public virtual void Save()
{
Current.Services.MacroService.Save(MacroEntity);
}
@@ -223,8 +225,7 @@ namespace umbraco.cms.businesslogic.macro
Current.Services.MacroService.Delete(MacroEntity);
}
- //TODO: Fix this, this should wrap a new API!
-
+ [Obsolete("This is no longer used, use the IMacroService and related models instead")]
public static Macro Import(XmlNode n)
{
var alias = XmlHelper.GetNodeValue(n.SelectSingleNode("alias"));
diff --git a/src/umbraco.presentation.targets b/src/umbraco.presentation.targets
index c38a1da485..2a33705d6f 100644
--- a/src/umbraco.presentation.targets
+++ b/src/umbraco.presentation.targets
@@ -55,6 +55,10 @@
$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll
+
+
+ $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll
+