From e1896319ec02a5628294fde61936c9a7efe09ffe Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 7 Dec 2012 08:48:46 -0100 Subject: [PATCH 01/35] Initial refactoring of the Document class to use the new public api. And some experiments with medium trust and dynamic method. --- src/Umbraco.Core/Models/ContentExtensions.cs | 14 +++++ src/Umbraco.Core/Models/Rdbms/ContentDto.cs | 2 +- .../Models/Rdbms/ContentVersionDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/DocumentDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/NodeDto.cs | 2 +- src/Umbraco.Core/Persistence/PetaPoco.cs | 6 +- src/Umbraco.Core/Properties/AssemblyInfo.cs | 6 +- src/Umbraco.Core/Services/ContentService.cs | 25 +++++++++ src/Umbraco.Core/Services/IContentService.cs | 15 +++++ .../Services/ContentServiceTests.cs | 20 +++++++ src/umbraco.cms/businesslogic/CMSNode.cs | 20 ++++++- src/umbraco.cms/businesslogic/ContentType.cs | 56 ------------------- src/umbraco.cms/businesslogic/web/Document.cs | 44 +++++++++++++-- 13 files changed, 144 insertions(+), 70 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 4f68bd994e..3352d5553d 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -3,6 +3,7 @@ using System.Linq; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Repositories; +using Umbraco.Core.Services; namespace Umbraco.Core.Models { @@ -44,6 +45,19 @@ namespace Umbraco.Core.Models } } + /// + /// Checks whether an item has any published versions + /// + /// + /// True if the content has any published versiom otherwise False + public static bool HasPublishedVersion(this IContent content) + { + if (content.HasIdentity == false) + return false; + + return ServiceContext.Current.ContentService.HasPublishedVersion(content.Id); + } + /// /// Gets the for the Creator of this content. /// diff --git a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs index fde47f410e..fbed397c80 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("cmsContent")] [PrimaryKey("pk")] [ExplicitColumns] - internal class ContentDto + public class ContentDto { [Column("pk")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs index e63d4e27da..a7ae66df23 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("cmsContentVersion")] [PrimaryKey("id")] [ExplicitColumns] - internal class ContentVersionDto + public class ContentVersionDto { [Column("id")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs index 612084812e..9b3bf5c0dd 100644 --- a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("cmsDocument")] [PrimaryKey("versionId", autoIncrement = false)] [ExplicitColumns] - internal class DocumentDto + public class DocumentDto { [Column("nodeId")] [ForeignKey(typeof(ContentDto), Column = "nodeId")] diff --git a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs index abf1f01ca1..6b7a97891b 100644 --- a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("umbracoNode")] [PrimaryKey("id")] [ExplicitColumns] - internal class NodeDto + public class NodeDto { [Column("id")] [PrimaryKeyColumn(Name = "PK_structure", IdentitySeed = 1045)] diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs index 96ae439a2c..daa5d73b5c 100644 --- a/src/Umbraco.Core/Persistence/PetaPoco.cs +++ b/src/Umbraco.Core/Persistence/PetaPoco.cs @@ -13,6 +13,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security; +using System.Security.Permissions; using System.Text; using System.Configuration; using System.Data.Common; @@ -935,7 +937,7 @@ namespace Umbraco.Core.Persistence } // Instance data used by the Multipoco factory delegate - essentially a list of the nested poco factories to call - class MultiPocoFactory + public class MultiPocoFactory { public List m_Delegates; public Delegate GetItem(int index) { return m_Delegates[index]; } @@ -944,7 +946,7 @@ namespace Umbraco.Core.Persistence // Create a multi-poco factory Func CreateMultiPocoFactory(Type[] types, string sql, IDataReader r) { - var m = new DynamicMethod("petapoco_multipoco_factory", typeof(TRet), new Type[] { typeof(MultiPocoFactory), typeof(IDataReader), typeof(object) }, typeof(MultiPocoFactory)); + var m = new DynamicMethod("petapoco_multipoco_factory", typeof(TRet), new Type[] { typeof(MultiPocoFactory), typeof(IDataReader), typeof(object) }, typeof(MultiPocoFactory), true); var il = m.GetILGenerator(); // Load the callback diff --git a/src/Umbraco.Core/Properties/AssemblyInfo.cs b/src/Umbraco.Core/Properties/AssemblyInfo.cs index c05f9e4a60..2c428fab52 100644 --- a/src/Umbraco.Core/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Core/Properties/AssemblyInfo.cs @@ -1,6 +1,8 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -18,7 +20,9 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("130a6b5c-50e7-4df3-a0dd-e9e7eb0b7c5c")] -//[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)] +//[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)] +//[assembly: AllowPartiallyTrustedCallers] +//[assembly: SecurityTransparent] [assembly: InternalsVisibleTo("umbraco")] [assembly: InternalsVisibleTo("Umbraco.Tests")] diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 528fe2936d..25f4f0323d 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -149,6 +149,18 @@ namespace Umbraco.Core.Services return contents; } + /// + /// Gets a specific version of an item. + /// + /// Id of the to retrieve version from + /// Id of the version to retrieve + /// An item + public IContent GetByIdVersion(int id, Guid versionId) + { + var repository = RepositoryResolver.ResolveByType(_unitOfWork); + return repository.GetByVersion(id, versionId); + } + /// /// Gets a collection of an objects versions by Id /// @@ -217,6 +229,19 @@ namespace Umbraco.Core.Services return contents; } + /// + /// Checks whether an item has any published versions + /// + /// Id of the + /// True if the content has any published versiom otherwise False + public bool HasPublishedVersion(int id) + { + var repository = RepositoryResolver.ResolveByType(_unitOfWork); + var query = Query.Builder.Where(x => x.Published == true && x.Id == id); + int count = repository.Count(query); + return count > 0; + } + /// /// Re-Publishes all Content /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index ab60a661be..13479bf726 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -255,5 +255,20 @@ namespace Umbraco.Core.Services /// Optional Id of the User issueing the rollback of the Content /// The newly created object IContent Rollback(int id, Guid versionId, int userId = -1); + + /// + /// Cheacks whether an item has any published versions + /// + /// Id of the + /// True if the content has any published versiom otherwise False + bool HasPublishedVersion(int id); + + /// + /// Gets a specific version of an item. + /// + /// Id of the to retrieve version from + /// Id of the version to retrieve + /// An item + IContent GetByIdVersion(int id, Guid versionId); } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index c8c9956fe1..00e1aa2ac1 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -693,6 +693,26 @@ namespace Umbraco.Tests.Services Assert.That(c2.Value.ParentId > 0, Is.True); } + [Test] + public void Can_Verify_Content_Has_Published_Version() + { + // Arrange + var contentService = ServiceContext.ContentService; + var content = contentService.GetById(1046); + bool published = contentService.PublishWithChildren(content, 0); + var homepage = contentService.GetById(1046); + homepage.Name = "Homepage"; + ServiceContext.ContentService.Save(homepage); + + // Act + bool hasPublishedVersion = ServiceContext.ContentService.HasPublishedVersion(1046); + + // Assert + Assert.That(published, Is.True); + Assert.That(homepage.Published, Is.False); + Assert.That(hasPublishedVersion, Is.True); + } + [TearDown] public override void TearDown() { diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index a18a4bc91b..cddf069a49 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Data; using System.Xml; - +using Umbraco.Core.Models; using umbraco.cms.businesslogic.web; using umbraco.DataLayer; using umbraco.BusinessLogic; @@ -11,11 +11,13 @@ using System.IO; using System.Text.RegularExpressions; using System.ComponentModel; using umbraco.IO; -using umbraco.cms.businesslogic.media; using System.Collections; using umbraco.cms.businesslogic.task; using umbraco.cms.businesslogic.workflow; using umbraco.cms.businesslogic.Tags; +using File = System.IO.File; +using Media = umbraco.cms.businesslogic.media.Media; +using Task = umbraco.cms.businesslogic.task.Task; namespace umbraco.cms.businesslogic { @@ -1064,6 +1066,20 @@ order by level,sortOrder"; _isTrashed = dr.GetBoolean("trashed"); } + internal protected void PopulateCMSNodeFromContent(IContent content, Guid objectType) + { + _uniqueID = content.Key; + _nodeObjectType = objectType; + _level = content.Level; + _path = content.Path; + _parentid = content.ParentId; + _text = content.Name; + _sortOrder = content.SortOrder; + _userId = content.CreatorId; + _createDate = content.CreateDate; + _isTrashed = content.Trashed; + } + #endregion #region Private Methods diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 797184218c..8bc742e03e 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -45,24 +45,6 @@ namespace umbraco.cms.businesslogic public ContentType(Guid id, bool noSetup) : base(id, noSetup) { } - ///// - ///// Initializes a new instance of the class. - ///// - ///// The id. - ///// if set to true [use optimized mode] which loads in the data from the - ///// database in an optimized manner (less queries) - ///// - //public ContentType(bool optimizedMode, int id) - // : base(id, optimizedMode) - //{ - // this._optimizedMode = optimizedMode; - - // if (optimizedMode) - // { - - // } - //} - /// /// Creates a new content type object manually. /// @@ -1507,43 +1489,5 @@ namespace umbraco.cms.businesslogic } #endregion - - ///// - ///// Analyzes the content types. - ///// - ///// Type of the object. - ///// if set to true [force update]. - //protected void AnalyzeContentTypes(Guid ObjectType, bool ForceUpdate) - //{ - // if (!_analyzedContentTypes.ContainsKey(ObjectType) || ForceUpdate) - // { - // using (IRecordsReader dr = SqlHelper.ExecuteReader( - // "select id from umbracoNode where nodeObjectType = @objectType", - // SqlHelper.CreateParameter("@objectType", ObjectType))) - // { - // while (dr.Read()) - // { - // ContentType ct = new ContentType(dr.GetInt("id")); - // if (!_optimizedContentTypes.ContainsKey(ct.UniqueId)) - // _optimizedContentTypes.Add(ct.UniqueId, false); - - // _optimizedContentTypes[ct.UniqueId] = usesUmbracoDataOnly(ct); - // } - // } - // } - //} - - ///// - ///// Determines whether this instance is optimized. - ///// - ///// - ///// true if this instance is optimized; otherwise, false. - ///// - //protected bool IsOptimized() - //{ - // return (bool) _optimizedContentTypes[UniqueId]; - //} - - } } diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 5f2ccee29a..50353255c2 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -5,10 +5,10 @@ using System.Linq; using System.Web; using System.Xml; using Umbraco.Core.IO; +using Umbraco.Core.Models; +using Umbraco.Core.Services; using umbraco.BusinessLogic; using umbraco.BusinessLogic.Actions; -using umbraco.cms.businesslogic.property; -using umbraco.cms.businesslogic.relation; using umbraco.cms.helpers; using umbraco.DataLayer; using umbraco.IO; @@ -17,6 +17,9 @@ using umbraco.cms.businesslogic.datatype.controls; using System.IO; using System.Diagnostics; using Umbraco.Core; +using Property = umbraco.cms.businesslogic.property.Property; +using Relation = umbraco.cms.businesslogic.relation.Relation; +using RelationType = umbraco.cms.businesslogic.relation.RelationType; namespace umbraco.cms.businesslogic.web { @@ -229,6 +232,7 @@ namespace umbraco.cms.businesslogic.web private User _writer; private int? _writerId; private bool _optimizedMode; + private IContent _content; /// /// This is used to cache the child documents of Document when the children property @@ -1663,8 +1667,38 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); #region Protected Methods protected override void setupNode() { - base.setupNode(); + _content = Version == Guid.Empty + ? ServiceContext.Current.ContentService.GetById(Id) + : ServiceContext.Current.ContentService.GetByIdVersion(Id, Version); + if(_content == null) + throw new ArgumentException(string.Format("No Document exists with id '{0}'", Id)); + + //Setting private properties from IContent replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() + var objectType = new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"); + base.PopulateCMSNodeFromContent(_content, objectType); + + //If the version is empty we update with the latest version from the current IContent. + if (Version == Guid.Empty) + Version = _content.Version; + + //Setting private properties from IContent replacing Document.setupNode() + _creator = User.GetUser(_content.CreatorId); + _writer = User.GetUser(_content.WriterId); + _updated = _content.UpdateDate; + + if(_content.Template != null) + _template = _content.Template.Id; + + if (_content.ExpireDate.HasValue) + _expire = _content.ExpireDate.Value; + + if (_content.ReleaseDate.HasValue) + _release = _content.ReleaseDate.Value; + + _published = _content.HasPublishedVersion(); + + /*base.setupNode(); using (var dr = SqlHelper.ExecuteReader("select published, documentUser, coalesce(templateId, cmsDocumentType.templateNodeId) as templateId, text, releaseDate, expireDate, updateDate from cmsDocument inner join cmsContent on cmsDocument.nodeId = cmsContent.Nodeid left join cmsDocumentType on cmsDocumentType.contentTypeNodeId = cmsContent.contentType and cmsDocumentType.IsDefault = 1 where versionId = @versionId", SqlHelper.CreateParameter("@versionId", Version))) @@ -1688,8 +1722,8 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); throw new ArgumentException(string.Format("No Document exists with Version '{0}'", Version)); } } - - _published = HasPublishedVersion(); + + _published = HasPublishedVersion();*/ } protected void InitializeDocument(User InitUser, User InitWriter, string InitText, int InitTemplate, From 6a6302335dca9d77e92688521ea82d57ed57c3ab Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 7 Dec 2012 09:28:40 -0100 Subject: [PATCH 02/35] Setting trust level to full for the time being --- src/Umbraco.Web.UI/web.Template.Debug.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index 0e0a90365f..05f860c72d 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -19,6 +19,6 @@ - + \ No newline at end of file From 170293da41806c5d2ce59879773ccf2d5911058f Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 11 Dec 2012 12:15:37 -0100 Subject: [PATCH 03/35] Adding a few new methods to the ContentService and refactoring a few quirks. Refactoring following methods in the Document class: setupNode MakeNew GetRootDocuments GetDocumentsOfDocumentType GetDocumentsForExpiration GetDocumentsForRelease Rollback GetVersions GetPublishedVersion GetDescendants MoveToTrash --- src/Umbraco.Core/Persistence/PetaPoco.cs | 1 + .../Persistence/PetaPocoSqlExtensions.cs | 9 + .../Repositories/ContentRepository.cs | 38 ++- .../Repositories/ContentTypeRepository.cs | 20 +- src/Umbraco.Core/Services/ContentService.cs | 72 +++++- src/Umbraco.Core/Services/IContentService.cs | 21 ++ .../TestHelpers/BaseDatabaseFactoryTest.cs | 9 +- src/umbraco.cms/businesslogic/web/Document.cs | 243 +++++------------- 8 files changed, 220 insertions(+), 193 deletions(-) diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs index daa5d73b5c..3a7c709b9b 100644 --- a/src/Umbraco.Core/Persistence/PetaPoco.cs +++ b/src/Umbraco.Core/Persistence/PetaPoco.cs @@ -2304,6 +2304,7 @@ namespace Umbraco.Core.Persistence public SqlJoinClause InnerJoin(string table) { return Join("INNER JOIN ", table); } public SqlJoinClause LeftJoin(string table) { return Join("LEFT JOIN ", table); } + public SqlJoinClause LeftOuterJoin(string table) { return Join("LEFT OUTER JOIN ", table); } public SqlJoinClause RightJoin(string table) { return Join("RIGHT JOIN ", table); } public class SqlJoinClause diff --git a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs index 71e6d0c1bd..f38392fcc4 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs @@ -86,6 +86,15 @@ namespace Umbraco.Core.Persistence return sql.LeftJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); } + public static Sql.SqlJoinClause LeftOuterJoin(this Sql sql) + { + var type = typeof(T); + var tableNameAttribute = type.FirstAttribute(); + string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + return sql.LeftOuterJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); + } + public static Sql.SqlJoinClause RightJoin(this Sql sql) { var type = typeof (T); diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 8452f81ac9..895e536d70 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Models.Rdbms; @@ -226,6 +228,10 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date and Version Guid ((Content)entity).UpdatingEntity(); + //Look up parent to get and set the correct Path + var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + var factory = new ContentFactory(NodeObjectTypeId, entity.Id); //Look up Content entry to get Primary for updating the DTO var contentDto = Database.SingleOrDefault("WHERE nodeId = @Id", new { Id = entity.Id }); @@ -273,7 +279,37 @@ namespace Umbraco.Core.Persistence.Repositories ((ICanBeDirty)entity).ResetDirtyProperties(); } - + + protected override void PersistDeletedItem(IContent entity) + { + var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); + var uploadFieldId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"); + //Loop through properties to check if the content contains media that should be deleted + foreach (var property in entity.Properties) + { + if (property.PropertyType.DataTypeControlId == uploadFieldId && + string.IsNullOrEmpty(property.Value.ToString()) == false + && fs.FileExists(IOHelper.MapPath(property.Value.ToString()))) + { + var relativeFilePath = fs.GetRelativePath(property.Value.ToString()); + var parentDirectory = System.IO.Path.GetDirectoryName(relativeFilePath); + + // don't want to delete the media folder if not using directories. + if (UmbracoSettings.UploadAllowDirectories && parentDirectory != fs.GetRelativePath("/")) + { + //issue U4-771: if there is a parent directory the recursive parameter should be true + fs.DeleteDirectory(parentDirectory, String.IsNullOrEmpty(parentDirectory) == false); + } + else + { + fs.DeleteFile(relativeFilePath, true); + } + } + } + + base.PersistDeletedItem(entity); + } + #endregion #region Implementation of IContentRepository diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs index 6ae710f903..73b601071b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs @@ -91,11 +91,11 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - var documentTypeDtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); - foreach (var dto in documentTypeDtos) + foreach (var dto in dtos.DistinctBy(x => x.ContentTypeDto.NodeId)) { - yield return Get(dto.ContentTypeNodeId); + yield return Get(dto.ContentTypeDto.NodeId); } } @@ -114,14 +114,20 @@ namespace Umbraco.Core.Persistence.Repositories protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); //TODO Investigate the proper usage of IsDefault on cmsDocumentType - sql.Select(isCount ? "COUNT(*)" : "*"); - sql.From("cmsDocumentType"); + /*sql.From("cmsDocumentType"); sql.RightJoin("cmsContentType ON ([cmsContentType].[nodeId] = [cmsDocumentType].[contentTypeNodeId])"); sql.InnerJoin("umbracoNode ON ([cmsContentType].[nodeId] = [umbracoNode].[id])"); sql.Where("[umbracoNode].[nodeObjectType] = @NodeObjectType", new { NodeObjectType = NodeObjectTypeId }); - sql.Where("[cmsDocumentType].[IsDefault] = @IsDefault", new { IsDefault = true }); + sql.Where("[cmsDocumentType].[IsDefault] = @IsDefault", new { IsDefault = true });*/ + + var sql = new Sql(); + sql.Select(isCount ? "COUNT(*)" : "*"); + sql.From(); + sql.RightJoin().On(x => x.NodeId, y => y.ContentTypeNodeId); + sql.InnerJoin().On(x => x.NodeId, y => y.NodeId); + sql.Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index bbbb827381..f24ab9c863 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -158,6 +158,37 @@ namespace Umbraco.Core.Services return contents; } + /// + /// Gets a collection of objects by Parent Id + /// + /// Id of the Parent to retrieve Descendants from + /// An Enumerable list of objects + public IEnumerable GetDescendants(int id) + { + var repository = _contentRepository; + var content = repository.Get(id); + + var query = Query.Builder.Where(x => x.Path.StartsWith(content.Path)); + var contents = repository.GetByQuery(query); + + return contents; + } + + /// + /// Gets a collection of objects by Parent Id + /// + /// item to retrieve Descendants from + /// An Enumerable list of objects + public IEnumerable GetDescendants(IContent content) + { + var repository = _contentRepository; + + var query = Query.Builder.Where(x => x.Path.StartsWith(content.Path)); + var contents = repository.GetByQuery(query); + + return contents; + } + /// /// Gets a specific version of an item. /// @@ -166,7 +197,7 @@ namespace Umbraco.Core.Services /// An item public IContent GetByIdVersion(int id, Guid versionId) { - var repository = RepositoryResolver.ResolveByType(_unitOfWork); + var repository = _contentRepository; return repository.GetByVersion(id, versionId); } @@ -182,6 +213,17 @@ namespace Umbraco.Core.Services return versions; } + /// + /// Gets the published version of an item + /// + /// Id of the to retrieve version from + /// An item + public IContent GetPublishedVersion(int id) + { + var version = GetVersions(id); + return version.FirstOrDefault(x => x.Published == true); + } + /// /// Gets a collection of objects, which reside at the first level / root /// @@ -193,7 +235,7 @@ namespace Umbraco.Core.Services var query = Query.Builder.Where(x => x.ParentId == -1); var contents = repository.GetByQuery(query); - return contents; + return contents.OrderBy(x => x.SortOrder); } /// @@ -245,7 +287,7 @@ namespace Umbraco.Core.Services /// True if the content has any published versiom otherwise False public bool HasPublishedVersion(int id) { - var repository = RepositoryResolver.ResolveByType(_unitOfWork); + var repository = _contentRepository; var query = Query.Builder.Where(x => x.Published == true && x.Id == id); int count = repository.Count(query); return count > 0; @@ -627,10 +669,21 @@ namespace Umbraco.Core.Services if (!e.Cancel) { - foreach (var content in contents) + foreach (var content in contents.OrderByDescending(x => x.ParentId)) { - ((Content) content).ChangeTrashedState(true); - repository.AddOrUpdate(content); + //Look for children of current content and move that to trash before the current content is deleted + var c = content; + var childQuery = Query.Builder.Where(x => x.Path.StartsWith(c.Path)); + var children = repository.GetByQuery(childQuery); + + foreach (var child in children) + { + ((Content)child).ChangeTrashedState(true); + repository.AddOrUpdate(child); + } + + //Permantly delete the content + repository.Delete(content); } _unitOfWork.Commit(); @@ -638,7 +691,7 @@ namespace Umbraco.Core.Services if (Deleted != null) Deleted(contents, e); - Audit.Add(AuditTypes.Delete, string.Format("Delete Content of Type {0} performed by user", contentTypeId), userId == -1 ? 0 : userId, -1); + Audit.Add(AuditTypes.Delete, string.Format("Delete Content of Type with Id: '{0}' performed by user", contentTypeId), userId == -1 ? 0 : userId, -1); } } @@ -794,6 +847,8 @@ namespace Umbraco.Core.Services /// Optional Id of the User moving the Content public void Move(IContent content, int parentId, int userId = -1) { + //TODO Verify that SortOrder + Path is updated correctly + //TODO Add a check to see if parentId = -20 because then we should change the TrashState var e = new MoveEventArgs { ParentId = parentId }; if (Moving != null) Moving(content, e); @@ -858,6 +913,9 @@ namespace Umbraco.Core.Services /// The newly created object public IContent Copy(IContent content, int parentId, int userId = -1) { + //TODO Current implementation doesn't account for files, so should be updated to check properties for files that should be copied/re-created. + //TODO Add overload for creating a relation between New vs. Old copy + //TODO Children should also be copied (?) var e = new CopyEventArgs{ParentId = parentId}; if (Copying != null) Copying(content, e); diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 45f94f990f..d94df5ebdf 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -271,5 +271,26 @@ namespace Umbraco.Core.Services /// Id of the version to retrieve /// An item IContent GetByIdVersion(int id, Guid versionId); + + /// + /// Gets the published version of an item + /// + /// Id of the to retrieve version from + /// An item + IContent GetPublishedVersion(int id); + + /// + /// Gets a collection of objects by Parent Id + /// + /// Id of the Parent to retrieve Descendants from + /// An Enumerable list of objects + IEnumerable GetDescendants(int id); + + /// + /// Gets a collection of objects by Parent Id + /// + /// item to retrieve Descendants from + /// An Enumerable list of objects + IEnumerable GetDescendants(IContent content); } } \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index a613ab097a..b618c48708 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -36,6 +36,9 @@ namespace Umbraco.Tests.TestHelpers UmbracoSettings.UseLegacyXmlSchema = false; + DataTypesResolver.Current = new DataTypesResolver( + PluginManager.Current.ResolveDataTypes()); + RepositoryResolver.Current = new RepositoryResolver( new RepositoryFactory()); @@ -71,13 +74,15 @@ namespace Umbraco.Tests.TestHelpers { TestHelper.CleanContentDirectories(); + DataTypesResolver.Reset(); + RepositoryResolver.Reset(); + //reset the app context DatabaseContext = null; ApplicationContext.Current = null; ServiceContext = null; - Resolution.IsFrozen = false; - RepositoryResolver.Reset(); + Resolution.IsFrozen = false; string path = TestHelper.CurrentAssemblyDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", null); diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 8f0cbfb291..cd3e7d2b3f 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -12,12 +12,8 @@ using umbraco.BusinessLogic; using umbraco.BusinessLogic.Actions; using umbraco.cms.helpers; using umbraco.DataLayer; -using umbraco.IO; using umbraco.interfaces; using umbraco.cms.businesslogic.datatype.controls; -using System.IO; -using System.Diagnostics; -using Umbraco.Core; using Property = umbraco.cms.businesslogic.property.Property; using Relation = umbraco.cms.businesslogic.relation.Relation; using RelationType = umbraco.cms.businesslogic.relation.RelationType; @@ -375,54 +371,30 @@ namespace umbraco.cms.businesslogic.web { //allows you to cancel a document before anything goes to the DB var newingArgs = new DocumentNewingEventArgs() - { - Text = Name, - DocumentType = dct, - User = u, - ParentId = ParentId - }; + { + Text = Name, + DocumentType = dct, + User = u, + ParentId = ParentId + }; Document.OnNewing(newingArgs); if (newingArgs.Cancel) { return null; } - - Guid newId = Guid.NewGuid(); - - // Updated to match level from base node - CMSNode n = new CMSNode(ParentId); - int newLevel = n.Level; - newLevel++; - - //create the cms node first - CMSNode newNode = MakeNew(ParentId, _objectType, u.Id, newLevel, Name, newId); - - //we need to create an empty document and set the underlying text property - Document tmp = new Document(newId, true); - tmp.SetText(Name); - - //create the content data for the new document - tmp.CreateContent(dct); - - //now create the document data - SqlHelper.ExecuteNonQuery("insert into cmsDocument (newest, nodeId, published, documentUser, versionId, updateDate, Text) values (1, " + - tmp.Id + ", 0, " + - u.Id + ", @versionId, @updateDate, @text)", - SqlHelper.CreateParameter("@versionId", tmp.Version), - SqlHelper.CreateParameter("@updateDate", DateTime.Now), - SqlHelper.CreateParameter("@text", tmp.Text)); + //Create a new IContent object based on the passed in DocumentType's alias, set the name and save it + IContent content = ServiceContext.Current.ContentService.CreateContent(ParentId, dct.Alias, u.Id); + content.Name = Name; + ServiceContext.Current.ContentService.Save(content); //read the whole object from the db - Document d = new Document(newId); + Document d = new Document(content.Id); //event NewEventArgs e = new NewEventArgs(); d.OnNew(e); - // Log - Log.Add(LogTypes.New, u, d.Id, ""); - // Run Handler umbraco.BusinessLogic.Actions.Action.RunActionHandlers(d, ActionNew.Instance); @@ -454,26 +426,14 @@ namespace umbraco.cms.businesslogic.web return isDoc; } + /// /// Used to get the firstlevel/root documents of the hierachy /// /// Root documents public static Document[] GetRootDocuments() { - Guid[] topNodeIds = TopMostNodeIds(_objectType); - - var docs = new List(); - for (int i = 0; i < topNodeIds.Length; i++) - { - try - { - docs.Add(new Document(topNodeIds[i])); - } - catch (Exception ee) - { - LogHelper.Error("GetRootDocuments", ee); - } - } - return docs.ToArray(); + var content = ServiceContext.Current.ContentService.GetRootContent(); + return content.Select(c => new Document(c.Id)).ToArray(); } public static int CountSubs(int parentId, bool publishedOnly) @@ -518,22 +478,8 @@ namespace umbraco.cms.businesslogic.web public static IEnumerable GetDocumentsOfDocumentType(int docTypeId) { - var tmp = new List(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedMany.Trim(), "cmsContent.contentType = @contentTypeId", "umbracoNode.sortOrder"), - SqlHelper.CreateParameter("@nodeObjectType", Document._objectType), - SqlHelper.CreateParameter("@contentTypeId", docTypeId))) - { - while (dr.Read()) - { - Document d = new Document(dr.GetInt("id"), true); - d.PopulateDocumentFromReader(dr); - tmp.Add(d); - } - } - - return tmp.ToArray(); + var contents = ServiceContext.Current.ContentService.GetContentOfContentType(docTypeId); + return contents.Select(x => new Document(x.Id)).ToArray(); } public static void RemoveTemplateFromDocument(int templateId) @@ -642,7 +588,10 @@ namespace umbraco.cms.businesslogic.web /// A list of documents with expirationdates than today public static Document[] GetDocumentsForExpiration() { - ArrayList docs = new ArrayList(); + var contents = ServiceContext.Current.ContentService.GetContentForExpiration(); + return contents.Select(x => new Document(x.Id)).ToArray(); + + /*ArrayList docs = new ArrayList(); IRecordsReader dr = SqlHelper.ExecuteReader("select distinct nodeId from cmsDocument where published = 1 and not expireDate is null and expireDate <= @today", SqlHelper.CreateParameter("@today", DateTime.Now)); @@ -652,7 +601,7 @@ namespace umbraco.cms.businesslogic.web Document[] retval = new Document[docs.Count]; for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); - return retval; + return retval;*/ } /// @@ -661,7 +610,10 @@ namespace umbraco.cms.businesslogic.web /// Retrieve a list of documents with with releasedate greater than today public static Document[] GetDocumentsForRelease() { - ArrayList docs = new ArrayList(); + var contents = ServiceContext.Current.ContentService.GetContentForRelease(); + return contents.Select(x => new Document(x.Id)).ToArray(); + + /*ArrayList docs = new ArrayList(); IRecordsReader dr = SqlHelper.ExecuteReader("select distinct nodeId, level, sortOrder from cmsDocument inner join umbracoNode on umbracoNode.id = cmsDocument.nodeId where newest = 1 and not releaseDate is null and releaseDate <= @today order by [level], sortOrder", SqlHelper.CreateParameter("@today", DateTime.Now)); while (dr.Read()) @@ -672,7 +624,7 @@ namespace umbraco.cms.businesslogic.web Document[] retval = new Document[docs.Count]; for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); - return retval; + return retval;*/ } #endregion @@ -909,48 +861,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); } } - - /// - /// Indexed property to return the property value by name - /// - /// - /// - //public object this[string alias] - //{ - // get - // { - // if (this._optimizedMode) - // { - // return this._knownProperties.Single(p => propertyTypeByAlias(p, alias)).Value; - // } - // else - // { - // return this.getProperty(alias).Value; - // } - // } - // set - // { - // if (this._optimizedMode) - // { - // if (this._knownProperties.SingleOrDefault(p => propertyTypeByAlias(p, alias)).Key == null) - // { - // var pt = this.getProperty(alias); - - // this._knownProperties.Add(pt, pt.Value); - // } - // else - // { - // var pt = this._knownProperties.Single(p => propertyTypeByAlias(p, alias)).Key; - // this._knownProperties[pt] = value; - // } - // } - // else - // { - // this.getProperty(alias).Value = value; - // } - // } - //} - #endregion #region Public Methods @@ -1086,7 +996,9 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); if (!e.Cancel) { - DateTime versionDate = DateTime.Now; + _content = ServiceContext.Current.ContentService.Rollback(Id, VersionId, u.Id); + + /*DateTime versionDate = DateTime.Now; Guid newVersion = createNewVersion(versionDate); if (_template != 0) @@ -1128,7 +1040,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); catch { // property doesn't exists - } + }*/ FireAfterRollBack(e); } @@ -1201,16 +1113,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); if (!e.Cancel) { - - //if (this._optimizedMode) - //{ - // foreach (var property in this._knownProperties) - // { - // var pt = property.Key; - // pt.Value = property.Value; - // } - //} - UpdateDate = DateTime.Now; //set the updated date to now base.Save(); @@ -1223,6 +1125,9 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); public bool HasPublishedVersion() { + if (_content != null) + return _content.HasPublishedVersion(); + return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); } @@ -1244,7 +1149,12 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); /// Previous published versions of the document public DocumentVersionList[] GetVersions() { - ArrayList versions = new ArrayList(); + var versions = ServiceContext.Current.ContentService.GetVersions(Id); + return + versions.Select(x => new DocumentVersionList(x.Version, x.UpdateDate, x.Name, User.GetUser(x.CreatorId))) + .ToArray(); + + /*ArrayList versions = new ArrayList(); using (IRecordsReader dr = SqlHelper.ExecuteReader("select documentUser, versionId, updateDate, text from cmsDocument where nodeId = @nodeId order by updateDate", SqlHelper.CreateParameter("@nodeId", Id))) @@ -1267,7 +1177,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); retVal[i] = dv; i++; } - return retVal; + return retVal;*/ } /// @@ -1276,7 +1186,13 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); /// The published version of this document public DocumentVersionList GetPublishedVersion() { - using (IRecordsReader dr = + var version = ServiceContext.Current.ContentService.GetPublishedVersion(Id); + if (version == null) + return null; + + return new DocumentVersionList(version.Version, version.UpdateDate, version.Name, User.GetUser(version.CreatorId)); + + /*using (IRecordsReader dr = SqlHelper.ExecuteReader("select top 1 documentUser, versionId, updateDate, text from cmsDocument where nodeId = @nodeId and published = 1 order by updateDate desc", SqlHelper.CreateParameter("@nodeId", Id))) { @@ -1289,7 +1205,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); } } - return null; + return null;*/ } /// @@ -1442,7 +1358,13 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); /// public override IEnumerable GetDescendants() { - var tmp = new List(); + var descendants = _content == null + ? ServiceContext.Current.ContentService.GetDescendants(Id) + : ServiceContext.Current.ContentService.GetDescendants(_content); + + return descendants.Select(x => new Document(x.Id, true)); + + /*var tmp = new List(); using (IRecordsReader dr = SqlHelper.ExecuteReader( string.Format(m_SQLOptimizedMany.Trim(), "umbracoNode.path LIKE '%," + this.Id + ",%'", "umbracoNode.level"), SqlHelper.CreateParameter("@nodeObjectType", Document._objectType))) @@ -1455,7 +1377,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); } } - return tmp.ToArray(); + return tmp.ToArray();*/ } /// @@ -1479,18 +1401,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); public override void XmlGenerate(XmlDocument xd) { XmlNode x = generateXmlWithoutSaving(xd); - /* - if (!UmbracoSettings.UseFriendlyXmlSchema) - { - } else - { - XmlNode childNodes = xmlHelper.addTextNode(xd, "data", ""); - x.AppendChild(childNodes); - XmlPopulate(xd, ref childNodes, false); - } - */ - - // Save to db saveXml(x); } @@ -1673,8 +1583,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); throw new ArgumentException(string.Format("No Document exists with id '{0}'", Id)); //Setting private properties from IContent replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() - var objectType = new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"); - base.PopulateCMSNodeFromContent(_content, objectType); + base.PopulateCMSNodeFromContent(_content, _objectType); //If the version is empty we update with the latest version from the current IContent. if (Version == Guid.Empty) @@ -1695,33 +1604,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); _release = _content.ReleaseDate.Value; _published = _content.HasPublishedVersion(); - - /*base.setupNode(); - using (var dr = - SqlHelper.ExecuteReader("select published, documentUser, coalesce(templateId, cmsDocumentType.templateNodeId) as templateId, text, releaseDate, expireDate, updateDate from cmsDocument inner join cmsContent on cmsDocument.nodeId = cmsContent.Nodeid left join cmsDocumentType on cmsDocumentType.contentTypeNodeId = cmsContent.contentType and cmsDocumentType.IsDefault = 1 where versionId = @versionId", - SqlHelper.CreateParameter("@versionId", Version))) - { - if (dr.Read()) - { - _creator = User; - _writer = User.GetUser(dr.GetInt("documentUser")); - - if (!dr.IsNull("templateId")) - _template = dr.GetInt("templateId"); - if (!dr.IsNull("releaseDate")) - _release = dr.GetDateTime("releaseDate"); - if (!dr.IsNull("expireDate")) - _expire = dr.GetDateTime("expireDate"); - if (!dr.IsNull("updateDate")) - _updated = dr.GetDateTime("updateDate"); - } - else - { - throw new ArgumentException(string.Format("No Document exists with Version '{0}'", Version)); - } - } - - _published = HasPublishedVersion();*/ } protected void InitializeDocument(User InitUser, User InitWriter, string InitText, int InitTemplate, @@ -1879,7 +1761,16 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'")); { umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); UnPublish(); - Move((int)RecycleBin.RecycleBinType.Content); + //Move((int)RecycleBin.RecycleBinType.Content); + if (_content != null) + { + ServiceContext.Current.ContentService.MoveToRecycleBin(_content); + } + else + { + _content = ServiceContext.Current.ContentService.GetById(Id); + ServiceContext.Current.ContentService.MoveToRecycleBin(_content); + } FireAfterMoveToTrash(e); } return !e.Cancel; From 64b91ae1e4653db30ad1a82c71ef75ef7a2b8db7 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 11 Dec 2012 13:34:00 -0100 Subject: [PATCH 04/35] Refactoring DocumentType class to use new public api in the following methods: MakeNew setupNode GetByAlias GetAllAsList --- src/umbraco.cms/businesslogic/CMSNode.cs | 14 +++++++ src/umbraco.cms/businesslogic/ContentType.cs | 16 +++++++- .../businesslogic/web/DocumentType.cs | 40 ++++++++++++++----- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index cddf069a49..e13871a818 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -1080,6 +1080,20 @@ order by level,sortOrder"; _isTrashed = content.Trashed; } + internal protected void PopulateCMSNodeFromContentType(IContentType contentType, Guid objectType) + { + _uniqueID = contentType.Key; + _nodeObjectType = objectType; + _level = contentType.Level; + _path = contentType.Path; + _parentid = contentType.ParentId; + _text = contentType.Name; + _sortOrder = contentType.SortOrder; + _userId = contentType.CreatorId; + _createDate = contentType.CreateDate; + _isTrashed = false; + } + #endregion #region Private Methods diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 8bc742e03e..aeedc4983e 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -5,13 +5,15 @@ using System.Diagnostics; using System.Threading; using System.Runtime.CompilerServices; using System.Linq; +using Umbraco.Core.Models; using umbraco.cms.businesslogic.cache; -using umbraco.cms.businesslogic.datatype; -using umbraco.cms.businesslogic.language; using umbraco.cms.businesslogic.propertytype; using umbraco.cms.businesslogic.web; using umbraco.DataLayer; using umbraco.BusinessLogic; +using DataTypeDefinition = umbraco.cms.businesslogic.datatype.DataTypeDefinition; +using Language = umbraco.cms.businesslogic.language.Language; +using PropertyType = umbraco.cms.businesslogic.propertytype.PropertyType; namespace umbraco.cms.businesslogic { @@ -955,6 +957,16 @@ namespace umbraco.cms.businesslogic #region Protected Methods + internal protected void PopulateContentTypeFromContentType(IContentType contentType, Guid objectType) + { + _alias = contentType.Alias; + _iconurl = contentType.Icon; + _isContainerContentType = contentType.IsContainer; + _allowAtRoot = contentType.AllowedAsRoot; + _thumbnail = contentType.Thumbnail; + _description = contentType.Description; + } + protected void PopulateContentTypeNodeFromReader(IRecordsReader dr) { _alias = dr.GetString("Alias"); diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index 5a419373be..c874220361 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -3,11 +3,13 @@ using System.Collections; using System.Text; using System.Xml; using System.Linq; +using Umbraco.Core.Models; +using Umbraco.Core.Services; using umbraco.BusinessLogic; -using umbraco.cms.businesslogic.propertytype; using umbraco.DataLayer; using System.Collections.Generic; using Umbraco.Core; +using PropertyType = umbraco.cms.businesslogic.propertytype.PropertyType; namespace umbraco.cms.businesslogic.web { @@ -47,6 +49,7 @@ namespace umbraco.cms.businesslogic.web private int _defaultTemplate; private bool _hasChildrenInitialized = false; private bool _hasChildren; + private IContentType _contentType; #endregion @@ -115,11 +118,14 @@ namespace umbraco.cms.businesslogic.web { try { - return + var contentType = ServiceContext.Current.ContentTypeService.GetContentType(Alias); + return new DocumentType(contentType.Id); + + /*return new DocumentType( SqlHelper.ExecuteScalar(@"SELECT nodeid from cmsContentType INNER JOIN umbracoNode on cmsContentType.nodeId = umbracoNode.id WHERE nodeObjectType=@nodeObjectType AND alias=@alias", SqlHelper.CreateParameter("@nodeObjectType", DocumentType._objectType), - SqlHelper.CreateParameter("@alias", Alias))); + SqlHelper.CreateParameter("@alias", Alias)));*/ } catch { @@ -129,13 +135,17 @@ namespace umbraco.cms.businesslogic.web public static DocumentType MakeNew(User u, string Text) { - int ParentId = -1; + /*int ParentId = -1; int level = 1; Guid uniqueId = Guid.NewGuid(); CMSNode n = MakeNew(ParentId, _objectType, u.Id, level, Text, uniqueId); Create(n.Id, Text, ""); - DocumentType newDt = new DocumentType(n.Id); + DocumentType newDt = new DocumentType(n.Id);*/ + + var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text}; + ServiceContext.Current.ContentTypeService.Save(contentType); + var newDt = new DocumentType(contentType.Id); //event NewEventArgs e = new NewEventArgs(); @@ -155,10 +165,10 @@ namespace umbraco.cms.businesslogic.web public static List GetAllAsList() { + var contentTypes = ServiceContext.Current.ContentTypeService.GetAllContentTypes(); + var documentTypes = contentTypes.Select(x => new DocumentType(x.Id)); - var documentTypes = new List(); - - using (IRecordsReader dr = + /*using (IRecordsReader dr = SqlHelper.ExecuteReader(m_SQLOptimizedGetAll.Trim(), SqlHelper.CreateParameter("@nodeObjectType", DocumentType._objectType))) { while (dr.Read()) @@ -184,7 +194,7 @@ namespace umbraco.cms.businesslogic.web dt.PopulateDocumentTypeNodeFromReader(dr); } } - } + }*/ return documentTypes.OrderBy(x => x.Text).ToList(); @@ -476,7 +486,15 @@ namespace umbraco.cms.businesslogic.web protected override void setupNode() { - base.setupNode(); + _contentType = ServiceContext.Current.ContentTypeService.GetContentType(Id); + _templateIds = new ArrayList { _contentType.AllowedTemplates.Select(x => x.Id) }; + if(_contentType.DefaultTemplate != null) + _defaultTemplate = _contentType.DefaultTemplate.Id; + + base.PopulateContentTypeFromContentType(_contentType, _objectType); + base.PopulateCMSNodeFromContentType(_contentType, _objectType); + + /*base.setupNode(); using (IRecordsReader dr = SqlHelper.ExecuteReader("Select templateNodeId, IsDefault from cmsDocumentType where contentTypeNodeId = @id", SqlHelper.CreateParameter("@id", Id))) @@ -485,7 +503,7 @@ namespace umbraco.cms.businesslogic.web { PopulateDocumentTypeNodeFromReader(dr); } - } + }*/ } From 1eaa117883364082d1db2730bdd448bb78b11669 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 11 Dec 2012 14:27:18 -0100 Subject: [PATCH 05/35] Adding HasChildren check to ContentService and ContentTypeService. Correcting an issue with loading of template ids in DocumentType class. --- src/Umbraco.Core/Services/ContentService.cs | 15 ++++++++++- .../Services/ContentTypeService.cs | 26 +++++++++++++++++++ src/Umbraco.Core/Services/IContentService.cs | 9 ++++++- .../Services/IContentTypeService.cs | 14 ++++++++++ src/umbraco.cms/businesslogic/web/Document.cs | 7 +++-- .../businesslogic/web/DocumentType.cs | 10 +++++-- 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index f24ab9c863..526d8a4886 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -280,11 +280,24 @@ namespace Umbraco.Core.Services return contents; } + /// + /// Checks whether an item has any children + /// + /// Id of the + /// True if the content has any children otherwise False + public bool HasChildren(int id) + { + var repository = _contentRepository; + var query = Query.Builder.Where(x => x.ParentId == id); + int count = repository.Count(query); + return count > 0; + } + /// /// Checks whether an item has any published versions /// /// Id of the - /// True if the content has any published versiom otherwise False + /// True if the content has any published version otherwise False public bool HasPublishedVersion(int id) { var repository = _contentRepository; diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index bfd786d8db..044c2895cc 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -99,6 +99,19 @@ namespace Umbraco.Core.Services return contentTypes; } + /// + /// Checks whether an item has any children + /// + /// Id of the + /// True if the content type has any children otherwise False + public bool HasChildren(int id) + { + var repository = _contentTypeRepository; + var query = Query.Builder.Where(x => x.ParentId == id); + int count = repository.Count(query); + return count > 0; + } + /// /// Saves a single object /// @@ -297,6 +310,19 @@ namespace Umbraco.Core.Services return contentTypes; } + /// + /// Checks whether an item has any children + /// + /// Id of the + /// True if the media type has any children otherwise False + public bool MediaTypeHasChildren(int id) + { + var repository = _mediaTypeRepository; + var query = Query.Builder.Where(x => x.ParentId == id); + int count = repository.Count(query); + return count > 0; + } + /// /// Saves a single object /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index d94df5ebdf..c4d58dc4bb 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -261,7 +261,7 @@ namespace Umbraco.Core.Services /// Cheacks whether an item has any published versions /// /// Id of the - /// True if the content has any published versiom otherwise False + /// True if the content has any published version otherwise False bool HasPublishedVersion(int id); /// @@ -292,5 +292,12 @@ namespace Umbraco.Core.Services /// item to retrieve Descendants from /// An Enumerable list of objects IEnumerable GetDescendants(IContent content); + + /// + /// Checks whether an item has any children + /// + /// Id of the + /// True if the content has any children otherwise False + bool HasChildren(int id); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/IContentTypeService.cs b/src/Umbraco.Core/Services/IContentTypeService.cs index 0a53c2b1bb..de948fdc21 100644 --- a/src/Umbraco.Core/Services/IContentTypeService.cs +++ b/src/Umbraco.Core/Services/IContentTypeService.cs @@ -147,5 +147,19 @@ namespace Umbraco.Core.Services /// /// The DTD as a string string GetContentTypesDtd(); + + /// + /// Checks whether an item has any children + /// + /// Id of the + /// True if the content type has any children otherwise False + bool HasChildren(int id); + + /// + /// Checks whether an item has any children + /// + /// Id of the + /// True if the media type has any children otherwise False + bool MediaTypeHasChildren(int id); } } \ No newline at end of file diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index cd3e7d2b3f..77657e104b 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -495,7 +495,10 @@ namespace umbraco.cms.businesslogic.web /// public static Document[] GetChildrenForTree(int NodeId) { - var tmp = new List(); + var children = ServiceContext.Current.ContentService.GetChildren(NodeId); + var list = children.Select(x => new Document(x.Id)); + return list.ToArray(); + /*var tmp = new List(); using (IRecordsReader dr = SqlHelper.ExecuteReader( string.Format(m_SQLOptimizedMany.Trim(), "umbracoNode.parentID = @parentId", "umbracoNode.sortOrder"), @@ -510,7 +513,7 @@ namespace umbraco.cms.businesslogic.web } } - return tmp.ToArray(); + return tmp.ToArray();*/ } public static List GetChildrenBySearch(int NodeId, string searchString) diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index c874220361..a0aaa6757a 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -209,7 +209,8 @@ namespace umbraco.cms.businesslogic.web { if (!_hasChildrenInitialized) { - HasChildren = SqlHelper.ExecuteScalar("select count(childContentTypeId) as tmp from cmsContentType2ContentType where parentContentTypeId = @id", SqlHelper.CreateParameter("@id", Id)) > 0; + HasChildren = ServiceContext.Current.ContentTypeService.HasChildren(Id); + //HasChildren = SqlHelper.ExecuteScalar("select count(childContentTypeId) as tmp from cmsContentType2ContentType where parentContentTypeId = @id", SqlHelper.CreateParameter("@id", Id)) > 0; } return _hasChildren; } @@ -487,7 +488,12 @@ namespace umbraco.cms.businesslogic.web protected override void setupNode() { _contentType = ServiceContext.Current.ContentTypeService.GetContentType(Id); - _templateIds = new ArrayList { _contentType.AllowedTemplates.Select(x => x.Id) }; + + foreach (var template in _contentType.AllowedTemplates) + { + _templateIds.Add(template.Id); + } + if(_contentType.DefaultTemplate != null) _defaultTemplate = _contentType.DefaultTemplate.Id; From 29762e227a21a3a98fd94732c9132fcecb193981 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 12 Dec 2012 10:22:58 -0100 Subject: [PATCH 06/35] Refactoring the usage of Copy in the ContentService, so that it could be implemented in the Document class. --- src/Umbraco.Core/Models/Relation.cs | 3 +- .../Persistence/Factories/RelationFactory.cs | 5 +- .../Repositories/RelationRepository.cs | 4 +- src/Umbraco.Core/Services/ContentService.cs | 72 +++++++++-- src/Umbraco.Core/Services/IContentService.cs | 3 +- .../Repositories/RelationRepositoryTest.cs | 6 +- .../Services/ContentServiceTests.cs | 2 +- src/umbraco.cms/businesslogic/Content.cs | 36 ------ src/umbraco.cms/businesslogic/web/Document.cs | 118 +----------------- 9 files changed, 80 insertions(+), 169 deletions(-) diff --git a/src/Umbraco.Core/Models/Relation.cs b/src/Umbraco.Core/Models/Relation.cs index a501a2e341..8193d529c9 100644 --- a/src/Umbraco.Core/Models/Relation.cs +++ b/src/Umbraco.Core/Models/Relation.cs @@ -18,10 +18,11 @@ namespace Umbraco.Core.Models private RelationType _relationType; private string _comment; - public Relation(int parentId, int childId) + public Relation(int parentId, int childId, RelationType relationType) { _parentId = parentId; _childId = childId; + _relationType = relationType; } private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId); diff --git a/src/Umbraco.Core/Persistence/Factories/RelationFactory.cs b/src/Umbraco.Core/Persistence/Factories/RelationFactory.cs index 9c5d23682d..030cad9254 100644 --- a/src/Umbraco.Core/Persistence/Factories/RelationFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/RelationFactory.cs @@ -16,13 +16,12 @@ namespace Umbraco.Core.Persistence.Factories public Relation BuildEntity(RelationDto dto) { - var entity = new Relation(dto.ParentId, dto.ChildId) + var entity = new Relation(dto.ParentId, dto.ChildId, _relationType) { Comment = dto.Comment, CreateDate = dto.Datetime, Id = dto.Id, - UpdateDate = dto.Datetime, - RelationType = _relationType + UpdateDate = dto.Datetime }; return entity; } diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs index 1dd7bf60dd..9ece5507a0 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs @@ -124,7 +124,7 @@ namespace Umbraco.Core.Persistence.Repositories { entity.AddingEntity(); - var factory = new RelationFactory(null); + var factory = new RelationFactory(entity.RelationType); var dto = factory.BuildDto(entity); var id = Convert.ToInt32(Database.Insert(dto)); @@ -137,7 +137,7 @@ namespace Umbraco.Core.Persistence.Repositories { entity.UpdatingEntity(); - var factory = new RelationFactory(null); + var factory = new RelationFactory(entity.RelationType); var dto = factory.BuildDto(entity); Database.Update(dto); diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 526d8a4886..af553ebbc9 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; using Umbraco.Core.Auditing; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -43,8 +44,6 @@ namespace Umbraco.Core.Services _contentTypeRepository = RepositoryResolver.Current.Factory.CreateContentTypeRepository(_unitOfWork); } - //TODO Add GetLatestUnpublishedVersions(int id){} - /// /// Creates an object using the alias of the /// that this Content is based on. @@ -922,13 +921,11 @@ namespace Umbraco.Core.Services /// /// The to copy /// Id of the Content's new Parent + /// Boolean indicating whether the copy should be related to the original /// Optional Id of the User copying the Content /// The newly created object - public IContent Copy(IContent content, int parentId, int userId = -1) + public IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = -1) { - //TODO Current implementation doesn't account for files, so should be updated to check properties for files that should be copied/re-created. - //TODO Add overload for creating a relation between New vs. Old copy - //TODO Children should also be copied (?) var e = new CopyEventArgs{ParentId = parentId}; if (Copying != null) Copying(content, e); @@ -943,16 +940,75 @@ namespace Umbraco.Core.Services var repository = _contentRepository; - SetWriter(content, userId); + SetWriter(copy, userId); repository.AddOrUpdate(copy); _unitOfWork.Commit(); + + //NOTE This 'Relation' part should eventually be delegated to a RelationService + if (relateToOriginal) + { + var relationTypeRepository = RepositoryResolver.Current.Factory.CreateRelationTypeRepository(_unitOfWork); + var relationRepository = RepositoryResolver.Current.Factory.CreateRelationRepository(_unitOfWork); + + var relationType = relationTypeRepository.Get(1); + + var relation = new Relation(content.Id, copy.Id, relationType); + relationRepository.AddOrUpdate(relation); + _unitOfWork.Commit(); + + Audit.Add(AuditTypes.Copy, + string.Format("Copied content with Id: '{0}' related to original content with Id: '{1}'", + copy.Id, content.Id), copy.WriterId, copy.Id); + } + + var uploadFieldId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"); + if (content.Properties.Any(x => x.PropertyType.DataTypeControlId == uploadFieldId)) + { + bool isUpdated = false; + var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); + + //Loop through properties to check if the content contains media that should be deleted + foreach (var property in content.Properties.Where(x => x.PropertyType.DataTypeControlId == uploadFieldId + && string.IsNullOrEmpty(x.Value.ToString()) == false)) + { + if (fs.FileExists(IOHelper.MapPath(property.Value.ToString()))) + { + var currentPath = fs.GetRelativePath(property.Value.ToString()); + var propertyId = copy.Properties.First(x => x.Alias == property.Alias).Id; + var newPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(currentPath)); + + fs.CopyFile(currentPath, newPath); + copy.SetValue(property.Alias, fs.GetUrl(newPath)); + + //Copy thumbnails + foreach (var thumbPath in fs.GetThumbnails(currentPath)) + { + var newThumbPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(thumbPath)); + fs.CopyFile(thumbPath, newThumbPath); + } + isUpdated = true; + } + } + + if (isUpdated) + { + repository.AddOrUpdate(copy); + _unitOfWork.Commit(); + } + } + + var children = GetChildren(content.Id); + foreach (var child in children) + { + Copy(child, copy.Id, relateToOriginal, userId); + } } if(Copied != null) Copied(copy, e); - Audit.Add(AuditTypes.Delete, "Copy Content performed by user", content.WriterId, content.Id); + Audit.Add(AuditTypes.Copy, "Copy Content performed by user", content.WriterId, content.Id); return copy; } diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index c4d58dc4bb..8ad57647ea 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -235,9 +235,10 @@ namespace Umbraco.Core.Services /// /// The to copy /// Id of the Content's new Parent + /// Boolean indicating whether the copy should be related to the original /// Optional Id of the User copying the Content /// The newly created object - IContent Copy(IContent content, int parentId, int userId = -1); + IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = -1); /// /// Sends an to Publication, which executes handlers and events for the 'Send to Publication' action. diff --git a/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs index 9fba87f316..8730dc3aad 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var relationType = repositoryType.Get(1); - var relation = new Relation(1047, 1048) { RelationType = relationType }; + var relation = new Relation(1047, 1048, relationType); repository.AddOrUpdate(relation); unitOfWork.Commit(); @@ -270,8 +270,8 @@ namespace Umbraco.Tests.Persistence.Repositories Content subpage2 = MockedContent.CreateSimpleContent(contentType, "Text Page 2", textpage.Id); ServiceContext.ContentService.Save(subpage2, 0); - var relation = new Relation(textpage.Id, subpage.Id) {RelationType = relateContent, Comment = string.Empty}; - var relation2 = new Relation(textpage.Id, subpage2.Id) { RelationType = relateContent, Comment = string.Empty}; + var relation = new Relation(textpage.Id, subpage.Id, relateContent) { Comment = string.Empty }; + var relation2 = new Relation(textpage.Id, subpage2.Id, relateContent) { Comment = string.Empty }; relationRepository.AddOrUpdate(relation); relationRepository.AddOrUpdate(relation2); unitOfWork.Commit(); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index ce4a5febaf..64a9b61c76 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -630,7 +630,7 @@ namespace Umbraco.Tests.Services var content = contentService.GetById(1048); // Act - var copy = contentService.Copy(content, content.ParentId, 0); + var copy = contentService.Copy(content, content.ParentId, false, 0); // Assert Assert.That(copy, Is.Not.Null); diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index ad9d992d07..72dca87bed 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -219,22 +219,6 @@ namespace umbraco.cms.businesslogic { EnsureProperties(); return m_LoadedProperties.ToArray(); - - //if (this.ContentType == null) - // return new Property[0]; - - //List result = new List(); - //foreach (PropertyType prop in this.ContentType.PropertyTypes) - //{ - // if (prop == null) - // continue; - // Property p = getProperty(prop); - // if (p == null) - // continue; - // result.Add(p); - //} - - //return result.ToArray(); } } @@ -300,26 +284,6 @@ namespace umbraco.cms.businesslogic /// The property with the given propertytype public Property getProperty(PropertyType pt) { - - //object o = SqlHelper.ExecuteScalar( - // "select id from cmsPropertyData where versionId=@version and propertyTypeId=@propertyTypeId", - // SqlHelper.CreateParameter("@version", this.Version), - // SqlHelper.CreateParameter("@propertyTypeId", pt.Id)); - //if (o == null) - // return null; - //int propertyId; - //if (!int.TryParse(o.ToString(), out propertyId)) - // return null; - //try - //{ - // return new Property(propertyId, pt); - //} - //catch (Exception ex) - //{ - // Log.Add(LogTypes.Error, this.Id, "An error occurred retreiving property. EXCEPTION: " + ex.Message); - // return null; - //} - EnsureProperties(); var prop = m_LoadedProperties diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index a23496292a..44c55d47af 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -237,14 +237,9 @@ namespace umbraco.cms.businesslogic.web /// private IEnumerable _children = null; - // special for passing httpcontext object - //private HttpContext _httpContext; - // special for tree performance private int _userId = -1; - //private Dictionary _knownProperties = new Dictionary(); - //private Func, string, bool> propertyTypeByAlias = (pt, alias) => pt.Key.PropertyType.Alias == alias; #endregion #region Static Methods @@ -1156,31 +1151,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); return versions.Select(x => new DocumentVersionList(x.Version, x.UpdateDate, x.Name, User.GetUser(x.CreatorId))) .ToArray(); - - /*ArrayList versions = new ArrayList(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader("select documentUser, versionId, updateDate, text from cmsDocument where nodeId = @nodeId order by updateDate", - SqlHelper.CreateParameter("@nodeId", Id))) - { - while (dr.Read()) - { - DocumentVersionList dv = - new DocumentVersionList(dr.GetGuid("versionId"), - dr.GetDateTime("updateDate"), - dr.GetString("text"), - User.GetUser(dr.GetInt("documentUser"))); - versions.Add(dv); - } - } - - DocumentVersionList[] retVal = new DocumentVersionList[versions.Count]; - int i = 0; - foreach (DocumentVersionList dv in versions) - { - retVal[i] = dv; - i++; - } - return retVal;*/ } /// @@ -1194,21 +1164,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); return null; return new DocumentVersionList(version.Version, version.UpdateDate, version.Name, User.GetUser(version.CreatorId)); - - /*using (IRecordsReader dr = - SqlHelper.ExecuteReader("select top 1 documentUser, versionId, updateDate, text from cmsDocument where nodeId = @nodeId and published = 1 order by updateDate desc", - SqlHelper.CreateParameter("@nodeId", Id))) - { - if (dr.Read()) - { - return new DocumentVersionList(dr.GetGuid("versionId"), - dr.GetDateTime("updateDate"), - dr.GetString("text"), - User.GetUser(dr.GetInt("documentUser"))); - } - } - - return null;*/ } /// @@ -1248,9 +1203,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// public Document Copy(int CopyTo, User u, bool RelateToOrignal) { - var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); - - CopyEventArgs e = new CopyEventArgs(); + var e = new CopyEventArgs(); e.CopyTo = CopyTo; FireBeforeCopy(e); Document newDoc = null; @@ -1258,74 +1211,11 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); if (!e.Cancel) { // Make the new document - newDoc = MakeNew(Text, new DocumentType(ContentType.Id), u, CopyTo); - - if (newDoc != null) - { - // update template if a template is set - if (this.Template > 0) - newDoc.Template = Template; - - //update the trashed property as it could be copied inside the recycle bin - newDoc.IsTrashed = this.IsTrashed; - - // Copy the properties of the current document - var props = GenericProperties; - foreach (Property p in props) - { - //copy file if it's an upload property (so it doesn't get removed when original doc get's deleted) - - IDataType uploadField = new Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c")); - - if (p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id - && p.Value.ToString() != "" - && fs.FileExists(fs.GetRelativePath(p.Value.ToString()))) - { - var currentPath = fs.GetRelativePath(p.Value.ToString()); - - var propId = newDoc.getProperty(p.PropertyType.Alias).Id; - var newPath = fs.GetRelativePath(propId, System.IO.Path.GetFileName(currentPath)); - - fs.CopyFile(currentPath, newPath); - - newDoc.getProperty(p.PropertyType.Alias).Value = fs.GetUrl(newPath); - - //copy thumbs - foreach (var thumbPath in fs.GetThumbnails(currentPath)) - { - var newThumbPath = fs.GetRelativePath(propId, System.IO.Path.GetFileName(thumbPath)); - fs.CopyFile(thumbPath, newThumbPath); - } - - } - else - { - newDoc.getProperty(p.PropertyType.Alias).Value = p.Value; - } - - } - - // Relate? - if (RelateToOrignal) - { - Relation.MakeNew(Id, newDoc.Id, RelationType.GetByAlias("relateDocumentOnCopy"), ""); - - // Add to audit trail - Log.Add(LogTypes.Copy, u, newDoc.Id, "Copied and related from " + Text + " (id: " + Id.ToString() + ")"); - } - - - // Copy the children - //store children array here because iterating over an Array object is very inneficient. - var c = Children; - foreach (Document d in c) - d.Copy(newDoc.Id, u, RelateToOrignal); - - e.NewDocument = newDoc; - } + var content = ServiceContext.Current.ContentService.Copy(_content, CopyTo, RelateToOrignal, u.Id); + newDoc = new Document(content.Id); + e.NewDocument = newDoc; FireAfterCopy(e); - } return newDoc; From 3f35f1df0072ed2a35d626cee87b6e8a6cad6a6b Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 12 Dec 2012 15:17:48 -0100 Subject: [PATCH 07/35] Refactoring Document class to use new public api. Adding Obsolete attributes to methods in Document class that has been updated. Updating the PublishingStrategy to fire final event after content and xml has been properly updated in the db. Adding a few new methods to the ContentService. --- src/Umbraco.Core/Models/Content.cs | 6 +- src/Umbraco.Core/Models/IContent.cs | 1 - .../Repositories/ContentRepository.cs | 34 +- .../Publishing/BasePublishingStrategy.cs | 28 ++ .../Publishing/IPublishingStrategy.cs | 28 ++ .../Publishing/PublishingStrategy.cs | 59 +++- src/Umbraco.Core/Services/ContentService.cs | 92 ++++-- src/Umbraco.Core/Services/FileService.cs | 14 +- src/Umbraco.Core/Services/IContentService.cs | 10 +- src/Umbraco.Core/Services/IFileService.cs | 9 +- .../ContentTypeDefinitionFactory.cs | 2 +- src/Umbraco.Web/Strategies/DeletedTemplate.cs | 14 - src/Umbraco.Web/Strategies/TrashedContent.cs | 9 - src/Umbraco.Web/Umbraco.Web.csproj | 2 - src/umbraco.cms/businesslogic/web/Document.cs | 301 +++++++----------- 15 files changed, 343 insertions(+), 266 deletions(-) delete mode 100644 src/Umbraco.Web/Strategies/DeletedTemplate.cs delete mode 100644 src/Umbraco.Web/Strategies/TrashedContent.cs diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index 8741b09e04..adc172b413 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -296,10 +296,10 @@ namespace Umbraco.Core.Models public override bool IsPropertyDirty(string propertyName) { bool existsInEntity = base.IsPropertyDirty(propertyName); + if (existsInEntity) + return true; - bool anyDirtyProperties = Properties.Any(x => x.IsPropertyDirty(propertyName)); - - return existsInEntity || anyDirtyProperties; + return Properties.Any(x => x.IsPropertyDirty(propertyName)); } /// diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index 2d88a56cc0..6583184d76 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.Serialization; namespace Umbraco.Core.Models { diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 895e536d70..ff927c6d72 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -129,18 +129,19 @@ namespace Umbraco.Core.Persistence.Repositories { var list = new List { - string.Format("DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id"), - string.Format("DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id"), - string.Format("DELETE FROM umbracoRelation WHERE parentId = @Id"), - string.Format("DELETE FROM umbracoRelation WHERE childId = @Id"), - string.Format("DELETE FROM cmsTagRelationship WHERE nodeId = @Id"), - string.Format("DELETE FROM cmsDocument WHERE NodeId = @Id"), - string.Format("DELETE FROM cmsPropertyData WHERE contentNodeId = @Id"), - string.Format("DELETE FROM cmsPreviewXml WHERE nodeId = @Id"), - string.Format("DELETE FROM cmsContentVersion WHERE ContentId = @Id"), - string.Format("DELETE FROM cmsContentXml WHERE nodeID = @Id"), - string.Format("DELETE FROM cmsContent WHERE NodeId = @Id"), - string.Format("DELETE FROM umbracoNode WHERE id = @Id") + "DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id", + "DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id", + "DELETE FROM umbracoRelation WHERE parentId = @Id", + "DELETE FROM umbracoRelation WHERE childId = @Id", + "DELETE FROM cmsTagRelationship WHERE nodeId = @Id", + "DELETE FROM umbracoDomains WHERE domainRootStructureID = @Id", + "DELETE FROM cmsDocument WHERE NodeId = @Id", + "DELETE FROM cmsPropertyData WHERE contentNodeId = @Id", + "DELETE FROM cmsPreviewXml WHERE nodeId = @Id", + "DELETE FROM cmsContentVersion WHERE ContentId = @Id", + "DELETE FROM cmsContentXml WHERE nodeID = @Id", + "DELETE FROM cmsContent WHERE NodeId = @Id", + "DELETE FROM umbracoNode WHERE id = @Id" }; return list; } @@ -228,9 +229,12 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date and Version Guid ((Content)entity).UpdatingEntity(); - //Look up parent to get and set the correct Path - var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); - entity.Path = string.Concat(parent.Path, ",", entity.Id); + //Look up parent to get and set the correct Path if ParentId has changed + if (((ICanBeDirty) entity).IsPropertyDirty("ParentId")) + { + var parent = Database.First("WHERE id = @ParentId", new {ParentId = entity.ParentId}); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + } var factory = new ContentFactory(NodeObjectTypeId, entity.Id); //Look up Content entry to get Primary for updating the DTO diff --git a/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs b/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs index 2673426ade..e413732278 100644 --- a/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs @@ -99,5 +99,33 @@ namespace Umbraco.Core.Publishing if (UnPublished != null) UnPublished(content, e); } + + /// + /// Call to fire event that updating the published content has finalized. + /// + /// + /// This seperation of the OnPublished event is done to ensure that the Content + /// has been properly updated (committed unit of work) and xml saved in the db. + /// + /// thats being published + public abstract void PublishingFinalized(IContent content); + + /// + /// Call to fire event that updating the published content has finalized. + /// + /// An enumerable list of thats being published + public abstract void PublishingFinalized(IEnumerable content); + + /// + /// Call to fire event that updating the unpublished content has finalized. + /// + /// thats being unpublished + public abstract void UnPublishingFinalized(IContent content); + + /// + /// Call to fire event that updating the unpublished content has finalized. + /// + /// An enumerable list of thats being unpublished + public abstract void UnPublishingFinalized(IEnumerable content); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Publishing/IPublishingStrategy.cs b/src/Umbraco.Core/Publishing/IPublishingStrategy.cs index c2861eac8b..4535e896cd 100644 --- a/src/Umbraco.Core/Publishing/IPublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/IPublishingStrategy.cs @@ -39,5 +39,33 @@ namespace Umbraco.Core.Publishing /// Id of the User issueing the unpublish operation /// True if the unpublish operation was successfull and not cancelled, otherwise false bool UnPublish(IEnumerable content, int userId); + + /// + /// Call to fire event that updating the published content has finalized. + /// + /// + /// This seperation of the OnPublished event is done to ensure that the Content + /// has been properly updated (committed unit of work) and xml saved in the db. + /// + /// thats being published + void PublishingFinalized(IContent content); + + /// + /// Call to fire event that updating the published content has finalized. + /// + /// An enumerable list of thats being published + void PublishingFinalized(IEnumerable content); + + /// + /// Call to fire event that updating the unpublished content has finalized. + /// + /// thats being unpublished + void UnPublishingFinalized(IContent content); + + /// + /// Call to fire event that updating the unpublished content has finalized. + /// + /// An enumerable list of thats being unpublished + void UnPublishingFinalized(IEnumerable content); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Publishing/PublishingStrategy.cs b/src/Umbraco.Core/Publishing/PublishingStrategy.cs index ffd5077af4..165a2339db 100644 --- a/src/Umbraco.Core/Publishing/PublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/PublishingStrategy.cs @@ -63,9 +63,16 @@ namespace Umbraco.Core.Publishing content.Name, content.Id)); //Fire Published event - OnPublished(content, e); + //OnPublished(content, e); //NOTE: Ideally the xml cache should be refreshed here - as part of the publishing + //but the updated content hasn't been saved yet + //Consider creating a method in the PublishingStrategy that is called when updating a content-being-publishing item is final + //and thus more legit to fire the OnPublished event + //PublishingFinalized(IContent content) { OnPublished(content, new PublishingEventArgs()); } + //PublishingFinalized(IEnumerable content) { OnPublished(content, new PublishingEventArgs()); } + //UnPublishingFinalized(IContent content) { OnUnPublished(content, new PublishingEventArgs()); } + //UnPublishingFinalized(IEnumerable content) { OnUnPublished(content, new PublishingEventArgs()); } return true; } @@ -127,10 +134,10 @@ namespace Umbraco.Core.Publishing item.Name, item.Id)); //Fire Published event - OnPublished(item, e); + //OnPublished(item, e); } - OnPublished(content, e); + //OnPublished(content, e); //NOTE: Ideally the xml cache should be refreshed here - as part of the publishing //OnCacheContentAfterPublish(content, e) @@ -171,7 +178,7 @@ namespace Umbraco.Core.Publishing content.Name, content.Id)); //Fire UnPublishing event - OnUnPublished(content, e); + //OnUnPublished(content, e); //NOTE: Ideally the xml cache should be refreshed here - as part of the unpublishing //OnRemoveCacheContentAfterPublish(content, e) @@ -218,14 +225,54 @@ namespace Umbraco.Core.Publishing item.Name, item.Id)); //Fire AfterUnPublish event - OnUnPublished(item, e); + //OnUnPublished(item, e); } - OnUnPublished(content, e); + //OnUnPublished(content, e); //NOTE: Ideally the xml cache should be refreshed here - as part of the publishing return true; } + + /// + /// Call to fire event that updating the published content has finalized. + /// + /// + /// This seperation of the OnPublished event is done to ensure that the Content + /// has been properly updated (committed unit of work) and xml saved in the db. + /// + /// thats being published + public override void PublishingFinalized(IContent content) + { + OnPublished(content, new PublishingEventArgs()); + } + + /// + /// Call to fire event that updating the published content has finalized. + /// + /// An enumerable list of thats being published + public override void PublishingFinalized(IEnumerable content) + { + OnPublished(content, new PublishingEventArgs()); + } + + /// + /// Call to fire event that updating the unpublished content has finalized. + /// + /// thats being unpublished + public override void UnPublishingFinalized(IContent content) + { + OnUnPublished(content, new PublishingEventArgs()); + } + + /// + /// Call to fire event that updating the unpublished content has finalized. + /// + /// An enumerable list of thats being unpublished + public override void UnPublishingFinalized(IEnumerable content) + { + OnUnPublished(content, new PublishingEventArgs()); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index af553ebbc9..fe25a8f58f 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -157,6 +157,22 @@ namespace Umbraco.Core.Services return contents; } + /// + /// Gets a collection of objects by its name or partial name + /// + /// Id of the Parent to retrieve Children from + /// Full or partial name of the children + /// An Enumerable list of objects + public IEnumerable GetChildrenByName(int parentId, string name) + { + var repository = _contentRepository; + + var query = Query.Builder.Where(x => x.ParentId == parentId && x.Name.Contains(name)); + var contents = repository.GetByQuery(query); + + return contents; + } + /// /// Gets a collection of objects by Parent Id /// @@ -312,9 +328,11 @@ namespace Umbraco.Core.Services /// True if publishing succeeded, otherwise False public bool RePublishAll(int userId = -1) { + //TODO delete from cmsContentXml or truncate table cmsContentXml before generating and saving xml to db var repository = _contentRepository; var list = new List(); + var updated = new List(); //Consider creating a Path query instead of recursive method: //var query = Query.Builder.Where(x => x.Path.StartsWith("-1")); @@ -338,12 +356,13 @@ namespace Umbraco.Core.Services { SetWriter(item, userId); repository.AddOrUpdate(item); + updated.Add(item); } _unitOfWork.Commit(); - //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class. - //global::umbraco.library.RefreshContent(); + //Updating content to published state is finished, so we fire event through PublishingStrategy to have cache updated + _publishingStrategy.PublishingFinalized(updated); Audit.Add(AuditTypes.Publish, "RePublish All performed by user", userId == -1 ? 0 : userId, -1); } @@ -370,6 +389,7 @@ namespace Umbraco.Core.Services /// True if publishing succeeded, otherwise False public bool PublishWithChildren(IContent content, int userId = -1) { + //TODO Should Publish generate xml of content and save it in the db? var repository = _contentRepository; //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published @@ -393,6 +413,7 @@ namespace Umbraco.Core.Services //Consider creating a Path query instead of recursive method: //var query = Query.Builder.Where(x => x.Path.StartsWith(content.Path)); + var updated = new List(); var list = new List(); list.Add(content); list.AddRange(GetChildrenDeep(content.Id)); @@ -406,13 +427,13 @@ namespace Umbraco.Core.Services { SetWriter(item, userId); repository.AddOrUpdate(item); + updated.Add(item); } _unitOfWork.Commit(); - //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class. - //TODO Need to investigate if it will also update the cache for children of the Content object - //global::umbraco.library.UpdateDocumentCache(content.Id); + //Save xml to db and call following method to fire event: + _publishingStrategy.PublishingFinalized(updated); Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId == -1 ? 0 : userId, content.Id); } @@ -456,8 +477,8 @@ namespace Umbraco.Core.Services _unitOfWork.Commit(); - //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content class. - //global::umbraco.library.UnPublishSingleNode(content.Id); + //Delete xml from db? and call following method to fire event through PublishingStrategy to update cache + _publishingStrategy.UnPublishingFinalized(content); Audit.Add(AuditTypes.Publish, "UnPublish performed by user", userId == -1 ? 0 : userId, content.Id); } @@ -499,6 +520,7 @@ namespace Umbraco.Core.Services /// True if publishing succeeded, otherwise False public bool SaveAndPublish(IContent content, int userId = -1) { + //TODO Should Publish generate xml of content and save it in the db? var e = new SaveEventArgs(); if (Saving != null) Saving(content, e); @@ -535,14 +557,14 @@ namespace Umbraco.Core.Services repository.AddOrUpdate(content); _unitOfWork.Commit(); - //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class. - //global::umbraco.library.UpdateDocumentCache(content.Id); + //Save xml to db and call following method to fire event through PublishingStrategy to update cache + _publishingStrategy.PublishingFinalized(content); } if (Saved != null) Saved(content, e); - Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId == -1 ? 0 : userId, content.Id); + Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", content.WriterId, content.Id); return published; } @@ -690,16 +712,14 @@ namespace Umbraco.Core.Services foreach (var child in children) { - ((Content)child).ChangeTrashedState(true); - repository.AddOrUpdate(child); + if(child.ContentType.Id != contentTypeId) + MoveToRecycleBin(child, userId); } //Permantly delete the content - repository.Delete(content); + Delete(content, userId); } - _unitOfWork.Commit(); - if (Deleted != null) Deleted(contents, e); @@ -708,23 +728,35 @@ namespace Umbraco.Core.Services } /// - /// Permanently deletes an object + /// Permanently deletes an object. /// + /// + /// This method will also delete associated media files, child content and possibly associated domains. + /// /// Please note that this method will completely remove the Content from the database /// The to delete /// Optional Id of the User deleting the Content public void Delete(IContent content, int userId = -1) { - //TODO Ensure that content is unpublished when deleted - //TODO This method should handle/react to errors when there is a constraint issue with the content being deleted - //TODO Children should either be deleted or moved to the recycle bin - var e = new DeleteEventArgs { Id = content.Id }; if (Deleting != null) Deleting(content, e); if (!e.Cancel) { + //Make sure that published content is unpublished before being deleted + if (content.HasPublishedVersion()) + { + UnPublish(content, userId); + } + + //Delete children before deleting the 'possible parent' + var children = GetChildren(content.Id); + foreach (var child in children) + { + Delete(child, userId); + } + var repository = _contentRepository; SetWriter(content, userId); repository.Delete(content); @@ -733,7 +765,7 @@ namespace Umbraco.Core.Services if (Deleted != null) Deleted(content, e); - Audit.Add(AuditTypes.Delete, "Delete Content performed by user", userId == -1 ? 0 : userId, content.Id); + Audit.Add(AuditTypes.Delete, "Delete Content performed by user", userId == -1 ? 0 : content.WriterId, content.Id); } } @@ -824,15 +856,25 @@ namespace Umbraco.Core.Services /// Optional Id of the User deleting the Content public void MoveToRecycleBin(IContent content, int userId = -1) { - //TODO If content item has children those should also be moved to the recycle bin - //TODO Unpublish deleted content + children - var e = new MoveEventArgs { ParentId = -20 }; if (Trashing != null) Trashing(content, e); if (!e.Cancel) { + //Make sure that published content is unpublished before being moved to the Recycle Bin + if (content.HasPublishedVersion()) + { + UnPublish(content, userId); + } + + //Move children to Recycle Bin before the 'possible parent' is moved there + var children = GetChildren(content.Id); + foreach (var child in children) + { + MoveToRecycleBin(child, userId); + } + var repository = _contentRepository; SetWriter(content, userId); content.ChangeTrashedState(true); @@ -1019,7 +1061,7 @@ namespace Umbraco.Core.Services /// The to send to publication /// Optional Id of the User issueing the send to publication /// True if sending publication was succesfull otherwise false - public bool SendToPublication(IContent content, int userId = -1) + internal bool SendToPublication(IContent content, int userId = -1) { //TODO Implement something similar to this var e = new SendToPublishEventArgs(); diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index 2de318ef54..8ad3696693 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Umbraco.Core.Auditing; using Umbraco.Core.Models; using Umbraco.Core.Persistence; @@ -205,12 +206,23 @@ namespace Umbraco.Core.Services /// /// Alias of the template /// A object - public ITemplate GetTemplateByAlias(string alias) + public ITemplate GetTemplate(string alias) { var repository = _templateRepository; return repository.Get(alias); } + /// + /// Gets a object by its alias + /// + /// Id of the template + /// A object + public ITemplate GetTemplate(int id) + { + var repository = _templateRepository; + return repository.Get(id); + } + /// /// Saves a /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 8ad57647ea..d3fc54aea7 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -246,7 +246,7 @@ namespace Umbraco.Core.Services /// The to send to publication /// Optional Id of the User issueing the send to publication /// True if sending publication was succesfull otherwise false - bool SendToPublication(IContent content, int userId = -1); + //bool SendToPublication(IContent content, int userId = -1); /// /// Rollback an object to a previous version. @@ -300,5 +300,13 @@ namespace Umbraco.Core.Services /// Id of the /// True if the content has any children otherwise False bool HasChildren(int id); + + /// + /// Gets a collection of objects by its name or partial name + /// + /// Id of the Parent to retrieve Children from + /// Full or partial name of the children + /// An Enumerable list of objects + IEnumerable GetChildrenByName(int parentId, string name); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 58839f7673..8793987ca6 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -87,7 +87,14 @@ namespace Umbraco.Core.Services /// /// Alias of the template /// A object - ITemplate GetTemplateByAlias(string alias); + ITemplate GetTemplate(string alias); + + /// + /// Gets a object by its alias + /// + /// Id of the template + /// A object + ITemplate GetTemplate(int id); /// /// Saves a diff --git a/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs b/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs index 97c138606a..fa45acc960 100644 --- a/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs +++ b/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs @@ -316,7 +316,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions ? templateName.Replace(".cshtml", "").Replace(".vbhtml", "") : templateName.Replace(".masterpage", ""); - var template = ServiceFactory.FileService.GetTemplateByAlias(@alias); + var template = ServiceFactory.FileService.GetTemplate(@alias); if(template == null) { var name = engine == RenderingEngine.Mvc diff --git a/src/Umbraco.Web/Strategies/DeletedTemplate.cs b/src/Umbraco.Web/Strategies/DeletedTemplate.cs deleted file mode 100644 index 2e2bcb27c1..0000000000 --- a/src/Umbraco.Web/Strategies/DeletedTemplate.cs +++ /dev/null @@ -1,14 +0,0 @@ -using umbraco.interfaces; - -namespace Umbraco.Web.Strategies -{ - /// - /// Subscribes to Template Deleted event in order to remove Foreign key reference - /// from cmsDocument table (Template Id set explicitly on content), and from cmsDocumentType - /// table where the ContentType references the Template Allowed/Default. - /// - internal class DeletedTemplate : IApplicationStartupHandler - { - - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Strategies/TrashedContent.cs b/src/Umbraco.Web/Strategies/TrashedContent.cs deleted file mode 100644 index 731b995f6b..0000000000 --- a/src/Umbraco.Web/Strategies/TrashedContent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using umbraco.interfaces; - -namespace Umbraco.Web.Strategies -{ - internal class TrashedContent : IApplicationStartupHandler - { - - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 26e75659f8..e8dbf2d967 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -328,8 +328,6 @@ - - diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 44c55d47af..20fa8ba65d 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Web; using System.Xml; -using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Logging; using Umbraco.Core.Services; @@ -12,11 +11,7 @@ using umbraco.BusinessLogic; using umbraco.BusinessLogic.Actions; using umbraco.cms.helpers; using umbraco.DataLayer; -using umbraco.interfaces; -using umbraco.cms.businesslogic.datatype.controls; using Property = umbraco.cms.businesslogic.property.Property; -using Relation = umbraco.cms.businesslogic.relation.Relation; -using RelationType = umbraco.cms.businesslogic.relation.RelationType; namespace umbraco.cms.businesslogic.web { @@ -26,6 +21,7 @@ namespace umbraco.cms.businesslogic.web /// /// Pubished Documents are exposed to the runtime/the public website in a cached xml document. /// + [Obsolete("Deprecated, Use Umbraco.Core.Models.Content", false)] public class Document : Content { #region Constructors @@ -79,8 +75,25 @@ namespace umbraco.cms.businesslogic.web : base(id, optimizedMode) { this._optimizedMode = optimizedMode; + _content = ServiceContext.Current.ContentService.GetById(id); + bool hasChildren = ServiceContext.Current.ContentService.HasChildren(id); + + SetupDocumentForTree(_content.Key, _content.Level, _content.ParentId, _content.CreatorId, _content.WriterId, + _content.Published, _content.Path, _content.Name, _content.CreateDate, + _content.UpdateDate, _content.UpdateDate, _content.ContentType.Icon, hasChildren, + _content.ContentType.Alias, _content.ContentType.Thumbnail, + _content.ContentType.Description, null, _content.ContentType.Id, _content.Template.Id, + _content.ContentType.IsContainer); - if (optimizedMode) + var tmpReleaseDate = _content.ReleaseDate.HasValue ? _content.ReleaseDate.Value : new DateTime(); + var tmpExpireDate = _content.ExpireDate.HasValue ? _content.ExpireDate.Value : new DateTime(); + var creator = new User(_content.CreatorId, true); + var writer = new User(_content.WriterId, true); + + InitializeContent(_content.ContentType.Id, _content.Version, _content.UpdateDate, _content.ContentType.Icon); + InitializeDocument(creator, writer, _content.Name, _content.Template.Id, tmpReleaseDate, tmpExpireDate, _content.UpdateDate, _content.Published); + + /*if (optimizedMode) { using (IRecordsReader dr = @@ -140,7 +153,7 @@ namespace umbraco.cms.businesslogic.web ); } } - } + }*/ } #endregion @@ -362,6 +375,7 @@ namespace umbraco.cms.businesslogic.web /// The usercontext under which the action are performed /// The id of the parent to the document /// The newly created document + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.CreateContent()", false)] public static Document MakeNew(string Name, DocumentType dct, User u, int ParentId) { //allows you to cancel a document before anything goes to the DB @@ -425,6 +439,7 @@ namespace umbraco.cms.businesslogic.web /// Used to get the firstlevel/root documents of the hierachy /// /// Root documents + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetRootContent()", false)] public static Document[] GetRootDocuments() { var content = ServiceContext.Current.ContentService.GetRootContent(); @@ -449,28 +464,13 @@ namespace umbraco.cms.businesslogic.web /// Note: use with care: this method can result in wast amount of data being deleted. /// /// The type of which documents should be deleted + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.DeleteContentOfType()", false)] public static void DeleteFromType(DocumentType dt) { - //get all document for the document type and order by level (top level first) - var docs = Document.GetDocumentsOfDocumentType(dt.Id) - .OrderByDescending(x => x.Level); - - foreach (Document doc in docs) - { - //before we delete this document, we need to make sure we don't end up deleting other documents that - //are not of this document type that are children. So we'll move all of it's children to the trash first. - foreach (Document c in doc.GetDescendants()) - { - if (c.ContentType.Id != dt.Id) - { - c.MoveToTrash(); - } - } - - doc.DeletePermanently(); - } + ServiceContext.Current.ContentService.DeleteContentOfType(dt.Id); } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentOfContentType()", false)] public static IEnumerable GetDocumentsOfDocumentType(int docTypeId) { var contents = ServiceContext.Current.ContentService.GetContentOfContentType(docTypeId); @@ -488,48 +488,19 @@ namespace umbraco.cms.businesslogic.web /// /// The parentdocuments id /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetChildren()", false)] public static Document[] GetChildrenForTree(int NodeId) { var children = ServiceContext.Current.ContentService.GetChildren(NodeId); var list = children.Select(x => new Document(x.Id)); return list.ToArray(); - /*var tmp = new List(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedMany.Trim(), "umbracoNode.parentID = @parentId", "umbracoNode.sortOrder"), - SqlHelper.CreateParameter("@nodeObjectType", Document._objectType), - SqlHelper.CreateParameter("@parentId", NodeId))) - { - while (dr.Read()) - { - Document d = new Document(dr.GetInt("id"), true); - d.PopulateDocumentFromReader(dr); - tmp.Add(d); - } - } - - return tmp.ToArray();*/ } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetChildrenByName()", false)] public static List GetChildrenBySearch(int NodeId, string searchString) { - var tmp = new List(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedMany.Trim(), "umbracoNode.parentID = @parentId and umbracoNode.text like @search", "umbracoNode.sortOrder"), - SqlHelper.CreateParameter("@nodeObjectType", Document._objectType), - SqlHelper.CreateParameter("@search", searchString), - SqlHelper.CreateParameter("@parentId", NodeId))) - { - while (dr.Read()) - { - Document d = new Document(dr.GetInt("id"), true); - d.PopulateDocumentFromReader(dr); - tmp.Add(d); - } - } - - return tmp; + var children = ServiceContext.Current.ContentService.GetChildrenByName(NodeId, searchString); + return children.Select(x => new Document(x.Id)).ToList(); } @@ -584,45 +555,22 @@ namespace umbraco.cms.businesslogic.web /// Retrieve a list of documents with an expirationdate greater than today /// /// A list of documents with expirationdates than today + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentForExpiration()", false)] public static Document[] GetDocumentsForExpiration() { var contents = ServiceContext.Current.ContentService.GetContentForExpiration(); return contents.Select(x => new Document(x.Id)).ToArray(); - - /*ArrayList docs = new ArrayList(); - IRecordsReader dr = - SqlHelper.ExecuteReader("select distinct nodeId from cmsDocument where published = 1 and not expireDate is null and expireDate <= @today", - SqlHelper.CreateParameter("@today", DateTime.Now)); - while (dr.Read()) - docs.Add(dr.GetInt("nodeId")); - dr.Close(); - - Document[] retval = new Document[docs.Count]; - for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); - return retval;*/ } /// /// Retrieve a list of documents with with releasedate greater than today /// /// Retrieve a list of documents with with releasedate greater than today + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentForRelease()", false)] public static Document[] GetDocumentsForRelease() { var contents = ServiceContext.Current.ContentService.GetContentForRelease(); return contents.Select(x => new Document(x.Id)).ToArray(); - - /*ArrayList docs = new ArrayList(); - IRecordsReader dr = SqlHelper.ExecuteReader("select distinct nodeId, level, sortOrder from cmsDocument inner join umbracoNode on umbracoNode.id = cmsDocument.nodeId where newest = 1 and not releaseDate is null and releaseDate <= @today order by [level], sortOrder", - SqlHelper.CreateParameter("@today", DateTime.Now)); - while (dr.Read()) - docs.Add(dr.GetInt("nodeId")); - dr.Close(); - - - Document[] retval = new Document[docs.Count]; - for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); - - return retval;*/ } #endregion @@ -713,6 +661,7 @@ namespace umbraco.cms.businesslogic.web /// A document can be published yet not visible, because of one or more of its /// parents being unpublished. Use PathPublished to get a value indicating whether /// the node and all its parents are published, and therefore whether the node is visible. + [Obsolete("Deprecated, Use Published property on Umbraco.Core.Models.Content", false)] public bool Published { get { return _published; } @@ -720,8 +669,9 @@ namespace umbraco.cms.businesslogic.web set { _published = value; - SqlHelper.ExecuteNonQuery( - string.Format("update cmsDocument set published = {0} where nodeId = {1}", Id, value ? 1 : 0)); + _content.ChangePublishedState(value); + /*SqlHelper.ExecuteNonQuery( + string.Format("update cmsDocument set published = {0} where nodeId = {1}", Id, value ? 1 : 0));*/ } } @@ -740,76 +690,82 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); } } + [Obsolete("Deprecated, Use Name property on Umbraco.Core.Models.Content", false)] public override string Text { get { - return base.Text; + return _content.Name; + //return base.Text; } set { value = value.Trim(); base.Text = value; - SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", + _content.Name = value; + + /*SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", SqlHelper.CreateParameter("@text", value), - SqlHelper.CreateParameter("@versionId", Version)); - //CMSNode c = new CMSNode(Id); - //c.Text = value; + SqlHelper.CreateParameter("@versionId", Version));*/ } } /// /// The date of the last update of the document /// + [Obsolete("Deprecated, Use UpdateDate property on Umbraco.Core.Models.Content", false)] public DateTime UpdateDate { get { return _updated; } set { _updated = value; - SqlHelper.ExecuteNonQuery("update cmsDocument set updateDate = @value where versionId = @versionId", + _content.UpdateDate = value; + /*SqlHelper.ExecuteNonQuery("update cmsDocument set updateDate = @value where versionId = @versionId", SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version)); + SqlHelper.CreateParameter("@versionId", Version));*/ } } /// /// A datestamp which indicates when a document should be published, used in automated publish/unpublish scenarios /// + [Obsolete("Deprecated, Use ReleaseDate property on Umbraco.Core.Models.Content", false)] public DateTime ReleaseDate { get { return _release; } set { _release = value; - - if (_release.Year != 1 || _release.Month != 1 || _release.Day != 1) + _content.ReleaseDate = value; + /*if (_release.Year != 1 || _release.Month != 1 || _release.Day != 1) SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = @value where versionId = @versionId", SqlHelper.CreateParameter("@value", value), SqlHelper.CreateParameter("@versionId", Version)); else SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = NULL where versionId = @versionId", - SqlHelper.CreateParameter("@versionId", Version)); + SqlHelper.CreateParameter("@versionId", Version));*/ } } /// /// A datestamp which indicates when a document should be unpublished, used in automated publish/unpublish scenarios /// + [Obsolete("Deprecated, Use ExpireDate property on Umbraco.Core.Models.Content", false)] public DateTime ExpireDate { get { return _expire; } set { _expire = value; - - if (_expire.Year != 1 || _expire.Month != 1 || _expire.Day != 1) + _content.ExpireDate = value; + /*if (_expire.Year != 1 || _expire.Month != 1 || _expire.Day != 1) SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = @value where versionId=@versionId", SqlHelper.CreateParameter("@value", value), SqlHelper.CreateParameter("@versionId", Version)); else SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = NULL where versionId=@versionId", - SqlHelper.CreateParameter("@versionId", Version)); + SqlHelper.CreateParameter("@versionId", Version));*/ } } @@ -823,6 +779,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// ?altTemplate=[templatealias] /// + [Obsolete("Deprecated, Use Template property on Umbraco.Core.Models.Content", false)] public int Template { get { return _template; } @@ -830,6 +787,15 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); { _template = value; if (value == 0) + { + _content.Template = null; + } + else + { + var template = ServiceContext.Current.FileService.GetTemplate(value); + _content.Template = template; + } + /*if (value == 0) { SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = @value where versionId = @versionId", SqlHelper.CreateParameter("@value", DBNull.Value), @@ -840,22 +806,23 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = @value where versionId = @versionId", SqlHelper.CreateParameter("@value", _template), SqlHelper.CreateParameter("@versionId", Version)); - } + }*/ } } /// /// A collection of documents imidiately underneath this document ie. the childdocuments /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetChildren()", false)] public new Document[] Children { get { //cache the documents children so that this db call doesn't have to occur again - if (this._children == null) - this._children = Document.GetChildrenForTree(this.Id); + if (_children == null) + _children = GetChildrenForTree(Id); - return this._children.ToArray(); + return _children.ToArray(); } } @@ -893,9 +860,11 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// the data. /// /// The usercontext under which the action are performed + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Publish()", false)] public void Publish(User u) { - PublishWithResult(u); + ServiceContext.Current.ContentService.Publish(_content, u.Id); + //PublishWithResult(u); } /// @@ -907,6 +876,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// The usercontext under which the action are performed /// True if the publishing succeed. Possible causes for not publishing is if an event aborts the publishing + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Publish()", false)] public bool PublishWithResult(User u) { PublishEventArgs e = new PublishEventArgs(); @@ -914,10 +884,11 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); if (!e.Cancel) { + var result = ServiceContext.Current.ContentService.Publish(_content, u.Id); // make a lookup to see if template is 0 as the template is not initialized in the optimized // Document.Children method which is used in PublishWithChildrenWithResult methhod - if (_template == 0) + /*if (_template == 0) { _template = new DocumentType(this.ContentType.Id).DefaultTemplate; } @@ -952,11 +923,11 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); newDoc.ExpireDate = ExpireDate; // Update xml in db using the new document (has correct version date) - newDoc.XmlGenerate(new XmlDocument()); + newDoc.XmlGenerate(new XmlDocument());*/ FireAfterPublish(e); - return true; + return result; } else { @@ -964,9 +935,12 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); } } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.PublishWithChildren()", false)] public bool PublishWithChildrenWithResult(User u) { - if (PublishWithResult(u)) + return ServiceContext.Current.ContentService.PublishWithChildren(_content, u.Id); + + /*if (PublishWithResult(u)) { foreach (cms.businesslogic.web.Document dc in Children.ToList()) { @@ -978,7 +952,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); return false; } - return true; + return true;*/ } /// @@ -987,59 +961,16 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// The usercontext under which the action are performed /// The unique Id of the version to roll back to + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Rollback()", false)] public void RollBack(Guid VersionId, User u) { - RollBackEventArgs e = new RollBackEventArgs(); + var e = new RollBackEventArgs(); FireBeforeRollBack(e); if (!e.Cancel) { _content = ServiceContext.Current.ContentService.Rollback(Id, VersionId, u.Id); - /*DateTime versionDate = DateTime.Now; - Guid newVersion = createNewVersion(versionDate); - - if (_template != 0) - { - SqlHelper.ExecuteNonQuery("insert into cmsDocument (nodeId, published, documentUser, versionId, updateDate, Text, TemplateId) values (" + - Id + - ", 0, " + u.Id + ", @versionId, @text, " + - _template + ")", - SqlHelper.CreateParameter("@versionId", newVersion), - SqlHelper.CreateParameter("@updateDate", versionDate), - SqlHelper.CreateParameter("@text", Text)); - } - else - { - SqlHelper.ExecuteNonQuery("insert into cmsDocument (nodeId, published, documentUser, versionId, updateDate, Text) values (" + - Id + - ", 0, " + u.Id + ", @versionId, @text )", - SqlHelper.CreateParameter("@versionId", newVersion), - SqlHelper.CreateParameter("@updateDate", versionDate), - SqlHelper.CreateParameter("@text", Text)); - } - - // Get new version - Document dNew = new Document(Id, newVersion); - - // Old version - Document dOld = new Document(Id, VersionId); - - // Revert title - dNew.Text = dOld.Text; - - // Revert all properties - var props = dOld.getProperties; - foreach (Property p in props) - try - { - dNew.getProperty(p.PropertyType).Value = p.Value; - } - catch - { - // property doesn't exists - }*/ - FireAfterRollBack(e); } } @@ -1052,7 +983,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// The usercontext under which the action are performed public void PublishWithSubs(User u) { - PublishEventArgs e = new PublishEventArgs(); FireBeforePublish(e); @@ -1085,6 +1015,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); } } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.UnPublish()", false)] public void UnPublish() { UnPublishEventArgs e = new UnPublishEventArgs(); @@ -1093,9 +1024,10 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); if (!e.Cancel) { - SqlHelper.ExecuteNonQuery(string.Format("update cmsDocument set published = 0 where nodeId = {0}", Id)); + //SqlHelper.ExecuteNonQuery(string.Format("update cmsDocument set published = 0 where nodeId = {0}", Id)); + //_published = false; - _published = false; + ServiceContext.Current.ContentService.UnPublish(_content); FireAfterUnPublish(e); } @@ -1104,14 +1036,15 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// Used to persist object changes to the database. /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Save()", false)] public override void Save() { - SaveEventArgs e = new SaveEventArgs(); + var e = new SaveEventArgs(); FireBeforeSave(e); if (!e.Cancel) { - UpdateDate = DateTime.Now; //set the updated date to now + ServiceContext.Current.ContentService.Save(_content); base.Save(); // update preview xml @@ -1121,6 +1054,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); } } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.HasPublishedVersion()", false)] public bool HasPublishedVersion() { if (_content != null) @@ -1145,6 +1079,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// Used for rolling back documents to a previous version /// /// Previous published versions of the document + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetVersions()", false)] public DocumentVersionList[] GetVersions() { var versions = ServiceContext.Current.ContentService.GetVersions(Id); @@ -1157,6 +1092,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// Returns the published version of this document /// /// The published version of this document + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetPublishedVersion()", false)] public DocumentVersionList GetPublishedVersion() { var version = ServiceContext.Current.ContentService.GetPublishedVersion(Id); @@ -1170,6 +1106,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// /// Returns a breadcrumlike path for the document like: /ancestorname/ancestorname + [Obsolete("Method is not used anywhere, so its marked for deletion", false)] public string GetTextPath() { string tempPath = ""; @@ -1189,6 +1126,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// The parentid where the document should be copied to /// The usercontext under which the action are performed + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Copy()", false)] public Document Copy(int CopyTo, User u) { return Copy(CopyTo, u, false); @@ -1201,6 +1139,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Copy()", false)] public Document Copy(int CopyTo, User u, bool RelateToOrignal) { var e = new CopyEventArgs(); @@ -1224,6 +1163,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// /// Puts the current document in the trash /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.MoveToRecycleBin()", false)] public override void delete() { MoveToTrash(); @@ -1256,21 +1196,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); : ServiceContext.Current.ContentService.GetDescendants(_content); return descendants.Select(x => new Document(x.Id, true)); - - /*var tmp = new List(); - using (IRecordsReader dr = SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedMany.Trim(), "umbracoNode.path LIKE '%," + this.Id + ",%'", "umbracoNode.level"), - SqlHelper.CreateParameter("@nodeObjectType", Document._objectType))) - { - while (dr.Read()) - { - Document d = new Document(dr.GetInt("id"), true); - d.PopulateDocumentFromReader(dr); - tmp.Add(d); - } - } - - return tmp.ToArray();*/ } /// @@ -1434,7 +1359,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); public override List GetNodesForPreview(bool childrenOnly) { - List nodes = new List(); + var nodes = new List(); string pathExp = childrenOnly ? Path + ",%" : Path; @@ -1466,6 +1391,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); #endregion #region Protected Methods + [Obsolete("Deprecated", false)] protected override void setupNode() { _content = Version == Guid.Empty @@ -1499,6 +1425,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); _published = _content.HasPublishedVersion(); } + [Obsolete("Deprecated", false)] protected void InitializeDocument(User InitUser, User InitWriter, string InitText, int InitTemplate, DateTime InitReleaseDate, DateTime InitExpireDate, DateTime InitUpdateDate, bool InitPublished) @@ -1521,6 +1448,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); _published = InitPublished; } + [Obsolete("Deprecated", false)] protected void PopulateDocumentFromReader(IRecordsReader dr) { bool _hc = false; @@ -1563,6 +1491,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); #endregion #region Private Methods + [Obsolete("Deprecated", false)] private void SetupDocumentForTree(Guid uniqueId, int level, int parentId, int creator, int writer, bool publish, string path, string text, DateTime createDate, DateTime updateDate, DateTime versionDate, string icon, bool hasChildren, string contentTypeAlias, string contentTypeThumb, @@ -1611,6 +1540,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// Used internally to permanently delete the data from the database /// /// returns true if deletion isn't cancelled + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Delete()", false)] private bool DeletePermanently() { DeleteEventArgs e = new DeleteEventArgs(); @@ -1619,21 +1549,18 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); if (!e.Cancel) { - foreach (Document d in Children.ToList()) + umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); + if (_content != null) { - d.DeletePermanently(); + ServiceContext.Current.ContentService.Delete(_content); + } + else + { + _content = ServiceContext.Current.ContentService.GetById(Id); + ServiceContext.Current.ContentService.Delete(_content); } - umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); - - // Remove all files - DeleteAssociatedMediaFiles(); - - //remove any domains associated - var domains = Domain.GetDomainsById(this.Id).ToList(); - domains.ForEach(x => x.Delete()); - - SqlHelper.ExecuteNonQuery("delete from cmsDocument where NodeId = " + Id); + //Keeping the base.delete() as it looks to be clear 'private/internal cache' base.delete(); FireAfterDelete(e); @@ -1645,6 +1572,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// Used internally to move the node to the recyle bin /// /// Returns true if the move was not cancelled + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.MoveToRecycleBin()", false)] private bool MoveToTrash() { MoveToTrashEventArgs e = new MoveToTrashEventArgs(); @@ -1654,7 +1582,6 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); { umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); UnPublish(); - //Move((int)RecycleBin.RecycleBinType.Content); if (_content != null) { ServiceContext.Current.ContentService.MoveToRecycleBin(_content); From 6dd63aa0b3f49ca2ec8486f9f78912d604dfadc2 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 12 Dec 2012 15:26:28 -0100 Subject: [PATCH 08/35] Adding comment --- src/Umbraco.Core/Models/PropertyExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Models/PropertyExtensions.cs b/src/Umbraco.Core/Models/PropertyExtensions.cs index 460174e8c0..51967c9c69 100644 --- a/src/Umbraco.Core/Models/PropertyExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyExtensions.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Models : xd.CreateTextNode(property.Value.ToString()); xmlNode.AppendChild(child); - + //TODO Revisit this by correcting test setup or refactoring DefaultData class to use PetaPoco instead of SqlHelper. //This seems to fail during testing //xmlNode.AppendChild(property.PropertyType.DataType(property.Id).Data.ToXMl(xd)); From 0cdb7af3eb951f2d8d4f7feb1db34b3dda0141bb Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 12 Dec 2012 18:44:55 -0100 Subject: [PATCH 09/35] Adding internal constructor overloads to Document, Content and CMSNode for better setup of legacy objects using new objects. --- src/umbraco.cms/businesslogic/CMSNode.cs | 6 ++++ src/umbraco.cms/businesslogic/Content.cs | 23 ++++++++----- src/umbraco.cms/businesslogic/web/Document.cs | 33 ++++++++++++------- src/umbraco.controls/umbraco.controls.csproj | 4 +++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index e13871a818..2ccd66749f 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -4,6 +4,7 @@ using System.Data; using System.Xml; using Umbraco.Core.Models; +using Umbraco.Core.Models.EntityBase; using umbraco.cms.businesslogic.web; using umbraco.DataLayer; using umbraco.BusinessLogic; @@ -399,6 +400,11 @@ namespace umbraco.cms.businesslogic PopulateCMSNodeFromReader(reader); } + protected internal CMSNode(IEntity entity) + { + _id = entity.Id; + } + #endregion #region Public Methods diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index 72dca87bed..b2ff163d59 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -1,21 +1,17 @@ using System; using System.Collections.Generic; using System.Linq; - -using System.Data; using System.Xml; using Umbraco.Core.IO; +using Umbraco.Core.Models; using umbraco.cms.businesslogic.property; -using umbraco.cms.businesslogic.propertytype; using umbraco.DataLayer; using System.Runtime.CompilerServices; using umbraco.cms.helpers; -using umbraco.BusinessLogic; -using umbraco.interfaces; -using System.IO; -using umbraco.IO; using umbraco.cms.businesslogic.datatype.controls; -using Umbraco.Core; +using File = System.IO.File; +using Property = umbraco.cms.businesslogic.property.Property; +using PropertyType = umbraco.cms.businesslogic.propertytype.PropertyType; namespace umbraco.cms.businesslogic { @@ -40,6 +36,7 @@ namespace umbraco.cms.businesslogic private string _contentTypeIcon; private ContentType _contentType; private Properties m_LoadedProperties = null; + private IContentBase _contentBase; #endregion @@ -53,6 +50,16 @@ namespace umbraco.cms.businesslogic protected Content(Guid id, bool noSetup) : base(id, noSetup) { } + protected internal Content(IContentBase contentBase) + : base(contentBase) + { + _contentBase = contentBase; + _version = _contentBase.Version; + _versionDate = _contentBase.UpdateDate; + _versionDateInitialized = true; + + } + #endregion #region Static Methods diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 20fa8ba65d..faf507923e 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -156,6 +156,11 @@ namespace umbraco.cms.businesslogic.web }*/ } + internal Document(IContent content) : base(content) + { + setupNode(content); + } + #endregion #region Constants and Static members @@ -398,7 +403,7 @@ namespace umbraco.cms.businesslogic.web ServiceContext.Current.ContentService.Save(content); //read the whole object from the db - Document d = new Document(content.Id); + Document d = new Document(content); //event NewEventArgs e = new NewEventArgs(); @@ -443,7 +448,7 @@ namespace umbraco.cms.businesslogic.web public static Document[] GetRootDocuments() { var content = ServiceContext.Current.ContentService.GetRootContent(); - return content.Select(c => new Document(c.Id)).ToArray(); + return content.Select(c => new Document(c)).ToArray(); } public static int CountSubs(int parentId, bool publishedOnly) @@ -474,7 +479,7 @@ namespace umbraco.cms.businesslogic.web public static IEnumerable GetDocumentsOfDocumentType(int docTypeId) { var contents = ServiceContext.Current.ContentService.GetContentOfContentType(docTypeId); - return contents.Select(x => new Document(x.Id)).ToArray(); + return contents.Select(x => new Document(x)).ToArray(); } public static void RemoveTemplateFromDocument(int templateId) @@ -492,7 +497,7 @@ namespace umbraco.cms.businesslogic.web public static Document[] GetChildrenForTree(int NodeId) { var children = ServiceContext.Current.ContentService.GetChildren(NodeId); - var list = children.Select(x => new Document(x.Id)); + var list = children.Select(x => new Document(x)); return list.ToArray(); } @@ -500,7 +505,7 @@ namespace umbraco.cms.businesslogic.web public static List GetChildrenBySearch(int NodeId, string searchString) { var children = ServiceContext.Current.ContentService.GetChildrenByName(NodeId, searchString); - return children.Select(x => new Document(x.Id)).ToList(); + return children.Select(x => new Document(x)).ToList(); } @@ -559,7 +564,7 @@ namespace umbraco.cms.businesslogic.web public static Document[] GetDocumentsForExpiration() { var contents = ServiceContext.Current.ContentService.GetContentForExpiration(); - return contents.Select(x => new Document(x.Id)).ToArray(); + return contents.Select(x => new Document(x)).ToArray(); } /// @@ -570,7 +575,7 @@ namespace umbraco.cms.businesslogic.web public static Document[] GetDocumentsForRelease() { var contents = ServiceContext.Current.ContentService.GetContentForRelease(); - return contents.Select(x => new Document(x.Id)).ToArray(); + return contents.Select(x => new Document(x)).ToArray(); } #endregion @@ -1151,7 +1156,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); { // Make the new document var content = ServiceContext.Current.ContentService.Copy(_content, CopyTo, RelateToOrignal, u.Id); - newDoc = new Document(content.Id); + newDoc = new Document(content); e.NewDocument = newDoc; FireAfterCopy(e); @@ -1394,13 +1399,19 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); [Obsolete("Deprecated", false)] protected override void setupNode() { - _content = Version == Guid.Empty + var content = Version == Guid.Empty ? ServiceContext.Current.ContentService.GetById(Id) : ServiceContext.Current.ContentService.GetByIdVersion(Id, Version); - if(_content == null) + if(content == null) throw new ArgumentException(string.Format("No Document exists with id '{0}'", Id)); + setupNode(content); + } + + private void setupNode(IContent content) + { + _content = content; //Setting private properties from IContent replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() base.PopulateCMSNodeFromContent(_content, _objectType); @@ -1413,7 +1424,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); _writer = User.GetUser(_content.WriterId); _updated = _content.UpdateDate; - if(_content.Template != null) + if (_content.Template != null) _template = _content.Template.Id; if (_content.ExpireDate.HasValue) diff --git a/src/umbraco.controls/umbraco.controls.csproj b/src/umbraco.controls/umbraco.controls.csproj index e88a9def9a..4ae38fb1ea 100644 --- a/src/umbraco.controls/umbraco.controls.csproj +++ b/src/umbraco.controls/umbraco.controls.csproj @@ -124,6 +124,10 @@ {ccd75ec3-63db-4184-b49d-51c1dd337230} umbraco.cms + + {31785bc3-256c-4613-b2f5-a1b0bdded8c1} + Umbraco.Core + {C7CB79F0-1C97-4B33-BFA7-00731B579AE2} umbraco.datalayer From fa80356a4931faab71dff5ea0781278a9eddc775 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 12 Dec 2012 19:47:28 -0100 Subject: [PATCH 10/35] Implements two subscribers for the PublishingStrategy for updating cache after publish and unpublish. With this in place it should only be necessary to call Publish in the ContentService, and not worry about refreshing the cache. --- src/Umbraco.Core/EventArgs.cs | 9 +- .../Publishing/BasePublishingStrategy.cs | 3 +- .../Publishing/IPublishingStrategy.cs | 3 +- .../Publishing/PublishingStrategy.cs | 5 +- src/Umbraco.Core/Services/ContentService.cs | 4 +- .../Publishing/PublishingStrategyTests.cs | 23 +- .../Strategies/UpdateCacheAfterPublish.cs | 100 ++++++++ .../Strategies/UpdateCacheAfterUnPublish.cs | 59 +++++ .../Strategies/UpdateContentCache.cs | 238 ------------------ .../Strategies/UpdateMultipleContentCache.cs | 19 -- src/Umbraco.Web/Umbraco.Web.csproj | 4 +- 11 files changed, 176 insertions(+), 291 deletions(-) create mode 100644 src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs create mode 100644 src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs delete mode 100644 src/Umbraco.Web/Strategies/UpdateContentCache.cs delete mode 100644 src/Umbraco.Web/Strategies/UpdateMultipleContentCache.cs diff --git a/src/Umbraco.Core/EventArgs.cs b/src/Umbraco.Core/EventArgs.cs index 2d5fee1bcd..4b6a3fb2e3 100644 --- a/src/Umbraco.Core/EventArgs.cs +++ b/src/Umbraco.Core/EventArgs.cs @@ -1,9 +1,10 @@ -using Umbraco.Core.Models; - -namespace Umbraco.Core +namespace Umbraco.Core { //Publishing Events - public class PublishingEventArgs : System.ComponentModel.CancelEventArgs { } + public class PublishingEventArgs : System.ComponentModel.CancelEventArgs + { + public bool IsAllRepublished { get; set; } + } public class SendToPublishEventArgs : System.ComponentModel.CancelEventArgs { } //Moving object Events diff --git a/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs b/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs index e413732278..36656e5e27 100644 --- a/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs @@ -114,7 +114,8 @@ namespace Umbraco.Core.Publishing /// Call to fire event that updating the published content has finalized. /// /// An enumerable list of thats being published - public abstract void PublishingFinalized(IEnumerable content); + /// Boolean indicating whether its all content that is republished + public abstract void PublishingFinalized(IEnumerable content, bool isAllRepublished); /// /// Call to fire event that updating the unpublished content has finalized. diff --git a/src/Umbraco.Core/Publishing/IPublishingStrategy.cs b/src/Umbraco.Core/Publishing/IPublishingStrategy.cs index 4535e896cd..0408409488 100644 --- a/src/Umbraco.Core/Publishing/IPublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/IPublishingStrategy.cs @@ -54,7 +54,8 @@ namespace Umbraco.Core.Publishing /// Call to fire event that updating the published content has finalized. /// /// An enumerable list of thats being published - void PublishingFinalized(IEnumerable content); + /// Boolean indicating whether its all content that is republished + void PublishingFinalized(IEnumerable content, bool isAllRepublished); /// /// Call to fire event that updating the unpublished content has finalized. diff --git a/src/Umbraco.Core/Publishing/PublishingStrategy.cs b/src/Umbraco.Core/Publishing/PublishingStrategy.cs index 165a2339db..8b3bc8821a 100644 --- a/src/Umbraco.Core/Publishing/PublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/PublishingStrategy.cs @@ -252,9 +252,10 @@ namespace Umbraco.Core.Publishing /// Call to fire event that updating the published content has finalized. /// /// An enumerable list of thats being published - public override void PublishingFinalized(IEnumerable content) + /// Boolean indicating whether its all content that is republished + public override void PublishingFinalized(IEnumerable content, bool isAllRepublished) { - OnPublished(content, new PublishingEventArgs()); + OnPublished(content, new PublishingEventArgs{ IsAllRepublished = isAllRepublished}); } /// diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index fe25a8f58f..6a3e670fab 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -362,7 +362,7 @@ namespace Umbraco.Core.Services _unitOfWork.Commit(); //Updating content to published state is finished, so we fire event through PublishingStrategy to have cache updated - _publishingStrategy.PublishingFinalized(updated); + _publishingStrategy.PublishingFinalized(updated, true); Audit.Add(AuditTypes.Publish, "RePublish All performed by user", userId == -1 ? 0 : userId, -1); } @@ -433,7 +433,7 @@ namespace Umbraco.Core.Services _unitOfWork.Commit(); //Save xml to db and call following method to fire event: - _publishingStrategy.PublishingFinalized(updated); + _publishingStrategy.PublishingFinalized(updated, false); Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId == -1 ? 0 : userId, content.Id); } diff --git a/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs b/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs index 9e6ea58ed8..ec2fff63a7 100644 --- a/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs +++ b/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs @@ -1,7 +1,5 @@ using System; using System.IO; -using System.Web; -using System.Xml; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Configuration; @@ -11,7 +9,6 @@ using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Web.Strategies; using umbraco.editorControls.tinyMCE3; using umbraco.interfaces; @@ -66,25 +63,7 @@ namespace Umbraco.Tests.Publishing [Test] public void Can_Publish_And_Update_Xml_Cache() { - // Arrange - var httpContext = base.GetUmbracoContext("/test", 1234).HttpContext; - var updateContentCache = new UpdateContentCache(httpContext); - var contentService = ServiceContext.ContentService; - var content = contentService.GetById(1046); - - // Act - bool published = contentService.Publish(content, 0); - - // Assert - Assert.That(published, Is.True); - Assert.That(content.Published, Is.True); - Assert.IsTrue(httpContext.Items.Contains("UmbracoXmlContextContent")); - - var document = httpContext.Items["UmbracoXmlContextContent"] as XmlDocument; - Console.Write(document.OuterXml); - document.Save("umbraco.config"); - - updateContentCache.Unsubscribe(); + //TODO Make new test } public void CreateTestData() diff --git a/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs b/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs new file mode 100644 index 0000000000..52bd6da466 --- /dev/null +++ b/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Models; +using Umbraco.Core.Publishing; +using umbraco; +using umbraco.cms.businesslogic.web; +using umbraco.interfaces; +using umbraco.presentation.cache; + +namespace Umbraco.Web.Strategies +{ + /// + /// Represents the UpdateCacheAfterPublish class, which subscribes to the Published event + /// of the class and is responsible for doing the actual + /// cache refresh after a content item has been published. + /// + /// + /// This implementation is meant as a seperation of the cache refresh from the ContentService + /// and PublishingStrategy. + /// + public class UpdateCacheAfterPublish : IApplicationStartupHandler + { + public UpdateCacheAfterPublish() + { + PublishingStrategy.Published += PublishingStrategy_Published; + } + + void PublishingStrategy_Published(object sender, Core.PublishingEventArgs e) + { + if (sender is IContent) + { + var content = sender as IContent; + UpdateSingleContentCache(content); + } + else if (sender is IEnumerable) + { + if (e.IsAllRepublished) + { + var content = sender as IEnumerable; + UpdateMultipleContentCache(content); + } + else + { + UpdateEntireCache(); + } + } + } + + /// + /// Refreshes the xml cache for all nodes + /// + private void UpdateEntireCache() + { + if (UmbracoSettings.UseDistributedCalls) + { + dispatcher.RefreshAll(new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66")); + } + else + { + content.Instance.RefreshContentFromDatabaseAsync(); + } + } + + /// + /// Refreshes the xml cache for nodes in list + /// + private void UpdateMultipleContentCache(IEnumerable content) + { + if (UmbracoSettings.UseDistributedCalls) + { + foreach (var c in content) + { + dispatcher.Refresh(new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), c.Id); + } + } + else + { + var documents = content.Select(x => new Document(x)).ToList(); + global::umbraco.content.Instance.UpdateDocumentCache(documents); + } + } + + /// + /// Refreshes the xml cache for a single node + /// + private void UpdateSingleContentCache(IContent content) + { + if (UmbracoSettings.UseDistributedCalls) + { + dispatcher.Refresh(new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), content.Id); + } + else + { + var doc = new Document(content); + global::umbraco.content.Instance.UpdateDocumentCache(doc); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs b/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs new file mode 100644 index 0000000000..22eefc70af --- /dev/null +++ b/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using Umbraco.Core.Models; +using Umbraco.Core.Publishing; +using umbraco; +using umbraco.interfaces; +using umbraco.presentation.cache; + +namespace Umbraco.Web.Strategies +{ + /// + /// Represents the UpdateCacheAfterUnPublish class, which subscribes to the UnPublished event + /// of the class and is responsible for doing the actual + /// cache refresh after a content item has been unpublished. + /// + /// + /// This implementation is meant as a seperation of the cache refresh from the ContentService + /// and PublishingStrategy. + /// + public class UpdateCacheAfterUnPublish : IApplicationStartupHandler + { + public UpdateCacheAfterUnPublish() + { + PublishingStrategy.UnPublished += PublishingStrategy_UnPublished; + } + + void PublishingStrategy_UnPublished(object sender, Core.PublishingEventArgs e) + { + if (sender is IContent) + { + var content = sender as IContent; + UnPublishSingle(content); + } + else if (sender is IEnumerable) + { + var content = sender as IEnumerable; + foreach (var c in content) + { + UnPublishSingle(c); + } + } + } + + /// + /// Refreshes the xml cache for a single node by removing it + /// + private void UnPublishSingle(IContent content) + { + if (UmbracoSettings.UseDistributedCalls) + { + dispatcher.Remove(new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), content.Id); + } + else + { + global::umbraco.content.Instance.ClearDocumentCache(content.Id); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Strategies/UpdateContentCache.cs b/src/Umbraco.Web/Strategies/UpdateContentCache.cs deleted file mode 100644 index 4dc81a5576..0000000000 --- a/src/Umbraco.Web/Strategies/UpdateContentCache.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Web; -using System.Web.Caching; -using System.Xml; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.Models; -using Umbraco.Core.Publishing; -using Umbraco.Core.Services; -using umbraco.interfaces; -using umbraco.presentation.nodeFactory; -using Node = umbraco.NodeFactory.Node; - -namespace Umbraco.Web.Strategies -{ - internal class UpdateContentCache : IApplicationStartupHandler - { - // Sync access to internal cache - private static readonly object XmlContentInternalSyncLock = new object(); - private const string XmlContextContentItemKey = "UmbracoXmlContextContent"; - private readonly HttpContextBase _httpContext; - private readonly ServiceContext _serviceContext; - - public UpdateContentCache() - { - _httpContext = new HttpContextWrapper(HttpContext.Current); - _serviceContext = ServiceContext.Current; - - PublishingStrategy.Published += PublishingStrategy_Published; - } - - public UpdateContentCache(HttpContextBase httpContext) - { - _httpContext = httpContext; - _serviceContext = ServiceContext.Current; - - PublishingStrategy.Published += PublishingStrategy_Published; - } - - void PublishingStrategy_Published(object sender, PublishingEventArgs e) - { - if((sender is IContent) == false) return; - - //var e = new DocumentCacheEventArgs(); - //FireBeforeUpdateDocumentCache(d, e); - - var content = sender as IContent; - - // lock the xml cache so no other thread can write to it at the same time - // note that some threads could read from it while we hold the lock, though - lock (XmlContentInternalSyncLock) - { - XmlDocument wip = XmlContent; - - ClearContextCache(); - - XmlContent = UpdateXmlAndSitemap(content, wip, false);//Update sitemap is usually set to true - } - - // clear cached field values - if (_httpContext != null) - { - Cache httpCache = _httpContext.Cache; - string cachedFieldKeyStart = String.Format("contentItem{0}_", content.Id); - var foundKeys = new List(); - foreach (DictionaryEntry cacheItem in httpCache) - { - string key = cacheItem.Key.ToString(); - if (key.StartsWith(cachedFieldKeyStart)) - foundKeys.Add(key); - } - foreach (string foundKey in foundKeys) - { - httpCache.Remove(foundKey); - } - } - - //Action.RunActionHandlers(d, ActionPublish.Instance); - //FireAfterUpdateDocumentCache(d, e); - } - - private XmlDocument UpdateXmlAndSitemap(IContent content, XmlDocument xmlContentCopy, bool updateSitemapProvider) - { - // check if document *is* published, it could be unpublished by an event - if (content.Published) - { - int parentId = content.Level == 1 ? -1 : content.ParentId; - var contentXmlNode = content.ToXml(false).GetXmlNode(); - var xmlNode = xmlContentCopy.ImportNode(contentXmlNode, true); - xmlContentCopy = AppendContentXml(content.Id, content.Level, parentId, xmlNode, xmlContentCopy); - - // update sitemapprovider - if (updateSitemapProvider && SiteMap.Provider is UmbracoSiteMapProvider) - { - try - { - var prov = (UmbracoSiteMapProvider)SiteMap.Provider; - var n = new Node(content.Id, true); - if (!String.IsNullOrEmpty(n.Url) && n.Url != "/#") - { - prov.UpdateNode(n); - } - else - { - //Log.Add(LogTypes.Error, content.Id, "Can't update Sitemap Provider due to empty Url in node"); - } - } - catch (Exception ee) - { - //Log.Add(LogTypes.Error, content.Id, string.Format("Error adding node to Sitemap Provider in PublishNodeDo(): {0}", ee)); - } - } - } - - return xmlContentCopy; - } - - private XmlDocument AppendContentXml(int id, int level, int parentId, XmlNode docNode, XmlDocument xmlContentCopy) - { - // Find the document in the xml cache - XmlNode x = xmlContentCopy.GetElementById(id.ToString()); - - // if the document is not there already then it's a new document - // we must make sure that its document type exists in the schema - var xmlContentCopy2 = xmlContentCopy; - if (x == null && UmbracoSettings.UseLegacyXmlSchema == false) - { - //TODO Look into the validate schema method - seems a bit odd - //Move to Contract ? - xmlContentCopy = ValidateSchema(docNode.Name, xmlContentCopy); - if (xmlContentCopy != xmlContentCopy2) - docNode = xmlContentCopy.ImportNode(docNode, true); - } - - // Find the parent (used for sortering and maybe creation of new node) - XmlNode parentNode; - if (level == 1) - parentNode = xmlContentCopy.DocumentElement; - else - parentNode = xmlContentCopy.GetElementById(parentId.ToString()); - - if (parentNode != null) - { - if (x == null) - { - x = docNode; - parentNode.AppendChild(x); - } - else - { - //TODO - //TransferValuesFromDocumentXmlToPublishedXml(docNode, x); - } - - // TODO: Update with new schema! - string xpath = UmbracoSettings.UseLegacyXmlSchema ? "./node" : "./* [@id]"; - XmlNodeList childNodes = parentNode.SelectNodes(xpath); - - // Maybe sort the nodes if the added node has a lower sortorder than the last - if (childNodes.Count > 0) - { - int siblingSortOrder = - int.Parse(childNodes[childNodes.Count - 1].Attributes.GetNamedItem("sortOrder").Value); - int currentSortOrder = int.Parse(x.Attributes.GetNamedItem("sortOrder").Value); - if (childNodes.Count > 1 && siblingSortOrder > currentSortOrder) - { - //SortNodes(ref parentNode); - } - } - } - - return xmlContentCopy; - } - - /// - /// Clear HTTPContext cache if any - /// - private void ClearContextCache() - { - // If running in a context very important to reset context cache or else new nodes are missing - if (_httpContext != null && _httpContext.Items.Contains(XmlContextContentItemKey)) - _httpContext.Items.Remove(XmlContextContentItemKey); - } - - private XmlDocument ValidateSchema(string docTypeAlias, XmlDocument xmlDoc) - { - // check if doctype is defined in schema else add it - // can't edit the doctype of an xml document, must create a new document - - var doctype = xmlDoc.DocumentType; - var subset = doctype.InternalSubset; - if (!subset.Contains(string.Format("", docTypeAlias))) - { - subset = string.Format("\r\n\r\n{1}", docTypeAlias, subset); - var xmlDoc2 = new XmlDocument(); - doctype = xmlDoc2.CreateDocumentType("root", null, null, subset); - xmlDoc2.AppendChild(doctype); - var root = xmlDoc2.ImportNode(xmlDoc.DocumentElement, true); - xmlDoc2.AppendChild(root); - - // apply - xmlDoc = xmlDoc2; - } - - return xmlDoc; - } - - private XmlDocument XmlContent - { - get - { - var content = _httpContext.Items[XmlContextContentItemKey] as XmlDocument; - if (content == null) - { - //content = global::umbraco.content.Instance.XmlContent; - var dtd = _serviceContext.ContentTypeService.GetDtd(); - - content = new XmlDocument(); - content.LoadXml( - String.Format("{0}{1}{0}", - Environment.NewLine, - dtd)); - - _httpContext.Items[XmlContextContentItemKey] = content; - } - return content; - } - set { _httpContext.Items[XmlContextContentItemKey] = value; } - } - - internal void Unsubscribe() - { - PublishingStrategy.Published -= PublishingStrategy_Published; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Strategies/UpdateMultipleContentCache.cs b/src/Umbraco.Web/Strategies/UpdateMultipleContentCache.cs deleted file mode 100644 index fa06e82927..0000000000 --- a/src/Umbraco.Web/Strategies/UpdateMultipleContentCache.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models; -using Umbraco.Core.Publishing; - -namespace Umbraco.Web.Strategies -{ - public class UpdateMultipleContentCache - { - public UpdateMultipleContentCache() - { - PublishingStrategy.Published += PublishingStrategy_Published; - } - - void PublishingStrategy_Published(object sender, Core.PublishingEventArgs e) - { - if ((sender is IEnumerable) == false) return; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index b46e7337e5..399a2e15bc 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -327,9 +327,9 @@ + + - - ASPXCodeBehind From 207c6517430422e4a4da72080a9c5f0f2c16bbce Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 13 Dec 2012 13:05:23 -0100 Subject: [PATCH 11/35] Refactoring the Document class for publishing and unpublishing. Bumped into an issue with nullable datetime and petapoco, which now has a workaround in our IMapper. Fix a few issues around the Published state on previous versions. --- src/Umbraco.Core/Models/Content.cs | 4 +- src/Umbraco.Core/Models/ContentExtensions.cs | 66 +++++++++++++++++ src/Umbraco.Core/Models/PropertyExtensions.cs | 10 +-- .../Persistence/Factories/ContentFactory.cs | 15 +++- .../Persistence/Mappers/ModelDtoMapper.cs | 13 ++++ .../Repositories/ContentRepository.cs | 12 +++ src/Umbraco.Core/Services/ContentService.cs | 73 +++++++++++++++---- src/Umbraco.Core/Services/IContentService.cs | 20 ++--- src/Umbraco.Tests/Models/ContentXmlTest.cs | 8 +- src/Umbraco.Web/ContentExtensions.cs | 70 ------------------ src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../businesslogic/datatype/DefaultData.cs | 9 +++ src/umbraco.cms/businesslogic/web/Document.cs | 65 ++++++++++------- 13 files changed, 223 insertions(+), 143 deletions(-) delete mode 100644 src/Umbraco.Web/ContentExtensions.cs diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index adc172b413..f53bc2b43c 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -87,10 +87,10 @@ namespace Umbraco.Core.Models if(Trashed) return ContentStatus.Trashed; - if(ExpireDate.HasValue && DateTime.UtcNow > ExpireDate.Value) + if(ExpireDate.HasValue && ExpireDate.Value > DateTime.MinValue && DateTime.UtcNow > ExpireDate.Value) return ContentStatus.Expired; - if(ReleaseDate.HasValue && ReleaseDate.Value > DateTime.UtcNow) + if(ReleaseDate.HasValue && ReleaseDate.Value > DateTime.MinValue && ReleaseDate.Value > DateTime.UtcNow) return ContentStatus.AwaitingRelease; if(Published) diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index dda7c98c58..46debeed07 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Xml.Linq; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Repositories; @@ -78,5 +79,70 @@ namespace Umbraco.Core.Models new PetaPocoUnitOfWork()); return repository.GetProfileById(content.WriterId); } + + /// + /// Creates the xml representation for the object + /// + /// to generate xml for + /// Xml representation of the passed in + public static XElement ToXml(this IContent content) + { + //nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias); + //var nodeName = content.ContentType.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true); + var nodeName = content.ContentType.Alias; + var niceUrl = content.Name.Replace(" ", "-").ToLower(); + + /* NOTE Not entirely sure if this is needed, but either way the niceUrlProvider is not + * available from here, so it would have to be delegated + */ + /*if (UmbracoContext.Current != null) + { + var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider; + niceUrl = niceUrlsProvider.GetNiceUrl(content.Id); + }*/ + + var xml = new XElement(nodeName, + new XAttribute("id", content.Id), + new XAttribute("parentID", content.Level > 1 ? content.ParentId : -1), + new XAttribute("level", content.Level), + new XAttribute("writerID", content.WriterId), + new XAttribute("creatorID", content.CreatorId), + new XAttribute("nodeType", content.ContentType.Id), + new XAttribute("template", content.Template == null ? "0": content.Template.Id.ToString()), + new XAttribute("sortOrder", content.SortOrder), + new XAttribute("createDate", content.CreateDate.ToString("s")), + new XAttribute("updateDate", content.UpdateDate.ToString("s")), + new XAttribute("nodeName", content.Name), + new XAttribute("urlName", niceUrl),//Format Url ? + new XAttribute("writerName", content.GetWriterProfile().Name), + new XAttribute("creatorName", content.GetCreatorProfile().Name), + new XAttribute("path", content.Path)); + + foreach (var property in content.Properties) + { + if (property == null) continue; + + xml.Add(property.ToXml()); + + //Check for umbracoUrlName convention + if (property.Alias == "umbracoUrlName" && property.Value.ToString().Trim() != string.Empty) + xml.SetAttributeValue("urlName", property.Value); + } + + return xml; + } + + /// + /// Creates the xml representation for the object + /// + /// to generate xml for + /// Boolean indicating whether the xml should be generated for preview + /// Xml representation of the passed in + public static XElement ToXml(this IContent content, bool isPreview) + { + //TODO Do a proper implementation of this + //If current IContent is published we should get latest unpublished version + return content.ToXml(); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/PropertyExtensions.cs b/src/Umbraco.Core/Models/PropertyExtensions.cs index 51967c9c69..cea46bb927 100644 --- a/src/Umbraco.Core/Models/PropertyExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyExtensions.cs @@ -18,14 +18,8 @@ namespace Umbraco.Core.Models var xd = new XmlDocument(); XmlNode xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, ""); - XmlNode child = property.PropertyType.DataTypeDatabaseType == DataTypeDatabaseType.Ntext - ? xd.CreateCDataSection(property.Value.ToString()) as XmlNode - : xd.CreateTextNode(property.Value.ToString()); - - xmlNode.AppendChild(child); - //TODO Revisit this by correcting test setup or refactoring DefaultData class to use PetaPoco instead of SqlHelper. - //This seems to fail during testing - //xmlNode.AppendChild(property.PropertyType.DataType(property.Id).Data.ToXMl(xd)); + //NOTE Possibly revisit this by correcting test setup or refactoring DefaultData class to use PetaPoco instead of SqlHelper. + xmlNode.AppendChild(property.PropertyType.DataType(property.Id).Data.ToXMl(xd)); var element = xmlNode.GetXElement(); return element; diff --git a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs index 83ba2cf3e3..c3545f8be1 100644 --- a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs @@ -49,8 +49,8 @@ namespace Umbraco.Core.Persistence.Factories Published = dto.Published, CreateDate = dto.ContentVersionDto.ContentDto.NodeDto.CreateDate, UpdateDate = dto.ContentVersionDto.VersionDate, - ExpireDate = dto.ExpiresDate, - ReleaseDate = dto.ReleaseDate, + ExpireDate = dto.ExpiresDate.HasValue ? dto.ExpiresDate.Value : (DateTime?) null, + ReleaseDate = dto.ReleaseDate.HasValue ? dto.ReleaseDate.Value : (DateTime?) null, Version = dto.ContentVersionDto.VersionId }; } @@ -60,17 +60,24 @@ namespace Umbraco.Core.Persistence.Factories //NOTE Currently doesn't add Alias and templateId (legacy stuff that eventually will go away) var documentDto = new DocumentDto { - ExpiresDate = entity.ExpireDate, Newest = true, NodeId = entity.Id, Published = entity.Published, - ReleaseDate = entity.ReleaseDate, Text = entity.Name, UpdateDate = entity.UpdateDate, WriterUserId = entity.WriterId, VersionId = entity.Version, + ExpiresDate = null, + ReleaseDate = null, ContentVersionDto = BuildContentVersionDto(entity) }; + + if (entity.ExpireDate.HasValue) + documentDto.ExpiresDate = entity.ExpireDate.Value; + + if (entity.ReleaseDate.HasValue) + documentDto.ReleaseDate = entity.ReleaseDate.Value; + return documentDto; } diff --git a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs index c44512a6fb..8410a6dfb3 100644 --- a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs @@ -155,6 +155,19 @@ namespace Umbraco.Core.Persistence.Mappers public Func GetToDbConverter(Type sourceType) { + //We need this check to ensure that PetaPoco doesn't try to insert an invalid date from a nullable DateTime property + if (sourceType == typeof (DateTime)) + { + return datetimeVal => + { + var datetime = datetimeVal as DateTime?; + if(datetime.HasValue && datetime.Value > DateTime.MinValue) + return datetime.Value; + + return null; + }; + } + return null; } } diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index ff927c6d72..fc90f71a6a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -263,6 +263,18 @@ namespace Umbraco.Core.Persistence.Repositories Database.Update(docDto); } + //If Published state has changed previous versions should have their publish state reset + if (((ICanBeDirty) entity).IsPropertyDirty("Published") && entity.Published) + { + var publishedDocs = Database.Fetch("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true }); + foreach (var doc in publishedDocs) + { + var docDto = doc; + docDto.Published = false; + Database.Update(docDto); + } + } + //Create a new version - cmsContentVersion //Assumes a new Version guid and Version date (modified date) has been set var contentVersionDto = dto.ContentVersionDto; diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 6a3e670fab..a66a2f7c05 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -2,11 +2,13 @@ using System; using System.Collections.Generic; using System.Linq; using System.Web; +using System.Xml.Linq; using Umbraco.Core.Auditing; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; +using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Repositories; @@ -325,10 +327,10 @@ namespace Umbraco.Core.Services /// Re-Publishes all Content /// /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this RePublish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - public bool RePublishAll(int userId = -1) + public bool RePublishAll(int userId = -1, bool omitCacheRefresh = false) { - //TODO delete from cmsContentXml or truncate table cmsContentXml before generating and saving xml to db var repository = _contentRepository; var list = new List(); @@ -361,8 +363,19 @@ namespace Umbraco.Core.Services _unitOfWork.Commit(); + foreach (var c in updated) + { + var xml = c.ToXml(); + var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) }; + var exists = DatabaseContext.Current.Database.IsNew(poco); + int result = exists + ? DatabaseContext.Current.Database.Update(poco) + : Convert.ToInt32(DatabaseContext.Current.Database.Insert(poco)); + } + //Updating content to published state is finished, so we fire event through PublishingStrategy to have cache updated - _publishingStrategy.PublishingFinalized(updated, true); + if(omitCacheRefresh == false) + _publishingStrategy.PublishingFinalized(updated, true); Audit.Add(AuditTypes.Publish, "RePublish All performed by user", userId == -1 ? 0 : userId, -1); } @@ -375,10 +388,11 @@ namespace Umbraco.Core.Services /// /// The to publish /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - public bool Publish(IContent content, int userId = -1) + public bool Publish(IContent content, int userId = -1, bool omitCacheRefresh = false) { - return SaveAndPublish(content, userId); + return SaveAndPublish(content, userId, omitCacheRefresh); } /// @@ -386,10 +400,10 @@ namespace Umbraco.Core.Services /// /// The to publish along with its children /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - public bool PublishWithChildren(IContent content, int userId = -1) + public bool PublishWithChildren(IContent content, int userId = -1, bool omitCacheRefresh = false) { - //TODO Should Publish generate xml of content and save it in the db? var repository = _contentRepository; //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published @@ -432,8 +446,19 @@ namespace Umbraco.Core.Services _unitOfWork.Commit(); + foreach (var c in updated) + { + var xml = c.ToXml(); + var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) }; + var exists = DatabaseContext.Current.Database.FirstOrDefault("WHERE nodeId = @Id", new { Id = c.Id }) != null; + int result = exists + ? DatabaseContext.Current.Database.Update(poco) + : Convert.ToInt32(DatabaseContext.Current.Database.Insert(poco)); + } + //Save xml to db and call following method to fire event: - _publishingStrategy.PublishingFinalized(updated, false); + if(omitCacheRefresh == false) + _publishingStrategy.PublishingFinalized(updated, false); Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId == -1 ? 0 : userId, content.Id); } @@ -446,8 +471,9 @@ namespace Umbraco.Core.Services /// /// The to publish /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will update the cache. /// True if unpublishing succeeded, otherwise False - public bool UnPublish(IContent content, int userId = -1) + public bool UnPublish(IContent content, int userId = -1, bool omitCacheRefresh = false) { var repository = _contentRepository; @@ -477,8 +503,19 @@ namespace Umbraco.Core.Services _unitOfWork.Commit(); + //Remove 'published' xml from the cmsContentXml table for the unpublished content and its (possible) children + DatabaseContext.Current.Database.Delete("WHERE nodeId = @Id", new {Id = content.Id}); + if (hasChildren) + { + foreach (var child in children) + { + DatabaseContext.Current.Database.Delete("WHERE nodeId = @Id", new { Id = child.Id }); + } + } + //Delete xml from db? and call following method to fire event through PublishingStrategy to update cache - _publishingStrategy.UnPublishingFinalized(content); + if(omitCacheRefresh == false) + _publishingStrategy.UnPublishingFinalized(content); Audit.Add(AuditTypes.Publish, "UnPublish performed by user", userId == -1 ? 0 : userId, content.Id); } @@ -517,10 +554,10 @@ namespace Umbraco.Core.Services /// /// The to save and publish /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - public bool SaveAndPublish(IContent content, int userId = -1) + public bool SaveAndPublish(IContent content, int userId = -1, bool omitCacheRefresh = false) { - //TODO Should Publish generate xml of content and save it in the db? var e = new SaveEventArgs(); if (Saving != null) Saving(content, e); @@ -530,7 +567,7 @@ namespace Umbraco.Core.Services var repository = _contentRepository; //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published - if (content.ParentId != -1 && content.ParentId != -20 && GetById(content.ParentId).Published == false) + if (content.ParentId != -1 && content.ParentId != -20 && HasPublishedVersion(content.ParentId) == false) { LogHelper.Info( string.Format( @@ -557,8 +594,16 @@ namespace Umbraco.Core.Services repository.AddOrUpdate(content); _unitOfWork.Commit(); + var xml = content.ToXml(); + var poco = new ContentXmlDto{NodeId = content.Id, Xml = xml.ToString(SaveOptions.None)}; + var exists = DatabaseContext.Current.Database.FirstOrDefault("WHERE nodeId = @Id", new {Id = content.Id}) != null; + int result = exists + ? DatabaseContext.Current.Database.Update(poco) + : Convert.ToInt32(DatabaseContext.Current.Database.Insert(poco)); + //Save xml to db and call following method to fire event through PublishingStrategy to update cache - _publishingStrategy.PublishingFinalized(content); + if(omitCacheRefresh == false) + _publishingStrategy.PublishingFinalized(content); } if (Saved != null) diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index d3fc54aea7..1e194e1a45 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -19,11 +19,6 @@ namespace Umbraco.Core.Services /// IContent CreateContent(int parentId, string contentTypeAlias, int userId = -1); - //TODO Add GetLatestUnpublishedVersions(int id){} - //TODO Add CreateNewVersion method? Its currently used in the Document API when Publishing - latest version is published, - //but then a new version is created so latest version is not published. - //IContent CreateNewVersion(int id); -> should not be necessary as Version number is changed when updating - /// /// Gets an object by Id /// @@ -94,40 +89,45 @@ namespace Umbraco.Core.Services /// Re-Publishes all Content /// /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this RePublish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - bool RePublishAll(int userId = -1); + bool RePublishAll(int userId = -1, bool omitCacheRefresh = false); /// /// Publishes a single object /// /// The to publish /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - bool Publish(IContent content, int userId = -1); + bool Publish(IContent content, int userId = -1, bool omitCacheRefresh = false); /// /// Publishes a object and all its children /// /// The to publish along with its children /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - bool PublishWithChildren(IContent content, int userId = -1); + bool PublishWithChildren(IContent content, int userId = -1, bool omitCacheRefresh = false); /// /// UnPublishes a single object /// /// The to publish /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will update the cache. /// True if unpublishing succeeded, otherwise False - bool UnPublish(IContent content, int userId = -1); + bool UnPublish(IContent content, int userId = -1, bool omitCacheRefresh = false); /// /// Saves and Publishes a single object /// /// The to save and publish /// Optional Id of the User issueing the publishing + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// True if publishing succeeded, otherwise False - bool SaveAndPublish(IContent content, int userId = -1); + bool SaveAndPublish(IContent content, int userId = -1, bool omitCacheRefresh = false); /// /// Saves a single object diff --git a/src/Umbraco.Tests/Models/ContentXmlTest.cs b/src/Umbraco.Tests/Models/ContentXmlTest.cs index 0512a94116..a564eaaac0 100644 --- a/src/Umbraco.Tests/Models/ContentXmlTest.cs +++ b/src/Umbraco.Tests/Models/ContentXmlTest.cs @@ -29,9 +29,6 @@ namespace Umbraco.Tests.Models typeof(tinyMCE3dataType).Assembly }; - DataTypesResolver.Current = new DataTypesResolver( - PluginManager.Current.ResolveDataTypes()); - base.Initialize(); } @@ -39,9 +36,6 @@ namespace Umbraco.Tests.Models public override void TearDown() { DatabaseContext.Database.Dispose(); - - //reset the app context - DataTypesResolver.Reset(); base.TearDown(); } @@ -63,6 +57,8 @@ namespace Umbraco.Tests.Models // Assert Assert.That(element, Is.Not.Null); Assert.That(element.Name.LocalName, Is.EqualTo(nodeName)); + + Console.WriteLine(element.ToString(SaveOptions.DisableFormatting)); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/ContentExtensions.cs b/src/Umbraco.Web/ContentExtensions.cs deleted file mode 100644 index e135dcf24e..0000000000 --- a/src/Umbraco.Web/ContentExtensions.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Xml.Linq; -using Umbraco.Core; -using Umbraco.Core.Models; - -namespace Umbraco.Web -{ - public static class ContentExtensions - { - /// - /// Creates the xml representation for the object - /// - /// to generate xml for - /// Xml representation of the passed in - public static XElement ToXml(this IContent content) - { - //nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias); - var nodeName = content.ContentType.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true); - var niceUrl = content.Name.Replace(" ", "-").ToLower(); - - if (UmbracoContext.Current != null) - { - var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider; - niceUrl = niceUrlsProvider.GetNiceUrl(content.Id); - } - - var xml = new XElement(nodeName, - new XAttribute("id", content.Id), - new XAttribute("parentID", content.Level > 1 ? content.ParentId : -1), - new XAttribute("level", content.Level), - new XAttribute("writerID", content.WriterId), - new XAttribute("creatorID", content.CreatorId), - new XAttribute("nodeType", content.ContentType.Id), - new XAttribute("template", content.Template == null ? string.Empty : content.Template.Id.ToString()), - new XAttribute("sortOrder", content.SortOrder), - new XAttribute("createDate", content.CreateDate), - new XAttribute("updateDate", content.UpdateDate), - new XAttribute("nodeName", content.Name), - new XAttribute("urlName", niceUrl),//Format Url ? - new XAttribute("writerName", content.GetWriterProfile().Name), - new XAttribute("creatorName", content.GetCreatorProfile().Name), - new XAttribute("path", content.Path)); - - foreach (var property in content.Properties) - { - if (property == null) continue; - - xml.Add(property.ToXml()); - - //Check for umbracoUrlName convention - if (property.Alias == "umbracoUrlName" && property.Value.ToString().Trim() != string.Empty) - xml.SetAttributeValue("urlName", property.Value); - } - - return xml; - } - - /// - /// Creates the xml representation for the object - /// - /// to generate xml for - /// Boolean indicating whether the xml should be generated for preview - /// Xml representation of the passed in - public static XElement ToXml(this IContent content, bool isPreview) - { - //TODO Do a proper implementation of this - //If current IContent is published we should get latest unpublished version - return content.ToXml(); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 399a2e15bc..863b0a8901 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -247,7 +247,6 @@ - diff --git a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs index 8eaa3760f7..cdd321858d 100644 --- a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs +++ b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs @@ -1,6 +1,8 @@ using System; using System.Data; +using Umbraco.Core; using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; using umbraco.DataLayer; using umbraco.BusinessLogic; using umbraco.interfaces; @@ -24,6 +26,13 @@ namespace umbraco.cms.businesslogic.datatype get { return Application.SqlHelper; } } + //TODO Refactor this class to use the Database object instead of the SqlHelper + //NOTE DatabaseContext.Current.Database should eventually be replaced with that from the Repository-Resolver refactor branch. + internal static Database Database + { + get { return DatabaseContext.Current.Database; } + } + /// /// Initializes a new instance of the class. /// diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index faf507923e..25555c2848 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -75,24 +75,30 @@ namespace umbraco.cms.businesslogic.web : base(id, optimizedMode) { this._optimizedMode = optimizedMode; - _content = ServiceContext.Current.ContentService.GetById(id); - bool hasChildren = ServiceContext.Current.ContentService.HasChildren(id); - - SetupDocumentForTree(_content.Key, _content.Level, _content.ParentId, _content.CreatorId, _content.WriterId, - _content.Published, _content.Path, _content.Name, _content.CreateDate, - _content.UpdateDate, _content.UpdateDate, _content.ContentType.Icon, hasChildren, - _content.ContentType.Alias, _content.ContentType.Thumbnail, - _content.ContentType.Description, null, _content.ContentType.Id, _content.Template.Id, - _content.ContentType.IsContainer); + if (optimizedMode) + { + _content = ServiceContext.Current.ContentService.GetById(id); + bool hasChildren = ServiceContext.Current.ContentService.HasChildren(id); + int templateId = _content.Template == null ? 0 : _content.Template.Id; - var tmpReleaseDate = _content.ReleaseDate.HasValue ? _content.ReleaseDate.Value : new DateTime(); - var tmpExpireDate = _content.ExpireDate.HasValue ? _content.ExpireDate.Value : new DateTime(); - var creator = new User(_content.CreatorId, true); - var writer = new User(_content.WriterId, true); + SetupDocumentForTree(_content.Key, _content.Level, _content.ParentId, _content.CreatorId, + _content.WriterId, + _content.Published, _content.Path, _content.Name, _content.CreateDate, + _content.UpdateDate, _content.UpdateDate, _content.ContentType.Icon, hasChildren, + _content.ContentType.Alias, _content.ContentType.Thumbnail, + _content.ContentType.Description, null, _content.ContentType.Id, + templateId, _content.ContentType.IsContainer); - InitializeContent(_content.ContentType.Id, _content.Version, _content.UpdateDate, _content.ContentType.Icon); - InitializeDocument(creator, writer, _content.Name, _content.Template.Id, tmpReleaseDate, tmpExpireDate, _content.UpdateDate, _content.Published); + var tmpReleaseDate = _content.ReleaseDate.HasValue ? _content.ReleaseDate.Value : new DateTime(); + var tmpExpireDate = _content.ExpireDate.HasValue ? _content.ExpireDate.Value : new DateTime(); + var creator = new User(_content.CreatorId, true); + var writer = new User(_content.WriterId, true); + InitializeContent(_content.ContentType.Id, _content.Version, _content.UpdateDate, + _content.ContentType.Icon); + InitializeDocument(creator, writer, _content.Name, templateId, tmpReleaseDate, tmpExpireDate, + _content.UpdateDate, _content.Published); + } /*if (optimizedMode) { @@ -868,7 +874,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Publish()", false)] public void Publish(User u) { - ServiceContext.Current.ContentService.Publish(_content, u.Id); + ServiceContext.Current.ContentService.Publish(_content, u.Id, true); //PublishWithResult(u); } @@ -884,12 +890,13 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Publish()", false)] public bool PublishWithResult(User u) { - PublishEventArgs e = new PublishEventArgs(); + var e = new PublishEventArgs(); FireBeforePublish(e); if (!e.Cancel) { - var result = ServiceContext.Current.ContentService.Publish(_content, u.Id); + var result = ServiceContext.Current.ContentService.Publish(_content, u.Id, true); + _published = result; // make a lookup to see if template is 0 as the template is not initialized in the optimized // Document.Children method which is used in PublishWithChildrenWithResult methhod @@ -943,7 +950,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.PublishWithChildren()", false)] public bool PublishWithChildrenWithResult(User u) { - return ServiceContext.Current.ContentService.PublishWithChildren(_content, u.Id); + return ServiceContext.Current.ContentService.PublishWithChildren(_content, u.Id, true); /*if (PublishWithResult(u)) { @@ -986,6 +993,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// Envoking this method will publish the documents and all children recursive. /// /// The usercontext under which the action are performed + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.PublishWithChildren()", false)] public void PublishWithSubs(User u) { PublishEventArgs e = new PublishEventArgs(); @@ -993,7 +1001,9 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); if (!e.Cancel) { - _published = true; + var published = ServiceContext.Current.ContentService.PublishWithChildren(_content, u.Id, true); + + /*_published = true; string tempVersion = Version.ToString(); DateTime versionDate = DateTime.Now; Guid newVersion = createNewVersion(versionDate); @@ -1014,7 +1024,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); XmlGenerate(new XmlDocument()); foreach (Document dc in Children.ToList()) - dc.PublishWithSubs(u); + dc.PublishWithSubs(u);*/ FireAfterPublish(e); } @@ -1032,7 +1042,7 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); //SqlHelper.ExecuteNonQuery(string.Format("update cmsDocument set published = 0 where nodeId = {0}", Id)); //_published = false; - ServiceContext.Current.ContentService.UnPublish(_content); + ServiceContext.Current.ContentService.UnPublish(_content, 0, true); FireAfterUnPublish(e); } @@ -1062,10 +1072,8 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.HasPublishedVersion()", false)] public bool HasPublishedVersion() { - if (_content != null) - return _content.HasPublishedVersion(); - - return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); + return _content.HasPublishedVersion(); + //return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); } /// @@ -1076,8 +1084,9 @@ where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'")); /// public bool HasPendingChanges() { - double timeDiff = new TimeSpan(UpdateDate.Ticks - VersionDate.Ticks).TotalMilliseconds; - return timeDiff > 2000; + return _content.Published == false; + //double timeDiff = new TimeSpan(UpdateDate.Ticks - VersionDate.Ticks).TotalMilliseconds; + //return timeDiff > 2000; } /// From 0cce4a1a9ece011b8d212162ef9f6763a55949dd Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 14 Dec 2012 11:43:16 -0100 Subject: [PATCH 12/35] Updating DefaultData and ContentControl to better support saving through the new api. DataTypes doesn't save directly to the db, but keeps the value in-memory so the save can be handled by the new api. Correcting the usage of versioning in the ContentRepository. --- src/Umbraco.Core/Models/ContentExtensions.cs | 4 +- .../Persistence/Factories/ContentFactory.cs | 2 +- .../Persistence/Factories/PropertyFactory.cs | 13 +- .../Repositories/ContentRepository.cs | 68 +++++++--- .../Publishing/PublishingStrategy.cs | 34 ----- src/Umbraco.Core/Services/ContentService.cs | 30 +++-- src/Umbraco.Web.UI/web.Template.config | 5 +- .../umbraco/controls/ContentControl.cs | 27 ++-- .../umbraco/editContent.aspx.cs | 10 +- src/umbraco.cms/businesslogic/Content.cs | 4 +- .../businesslogic/datatype/DefaultData.cs | 5 +- src/umbraco.cms/businesslogic/web/Document.cs | 118 +++++++++--------- 12 files changed, 162 insertions(+), 158 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 46debeed07..a2c49b56aa 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Xml.Linq; +using Umbraco.Core.Configuration; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Repositories; @@ -116,7 +117,8 @@ namespace Umbraco.Core.Models new XAttribute("urlName", niceUrl),//Format Url ? new XAttribute("writerName", content.GetWriterProfile().Name), new XAttribute("creatorName", content.GetCreatorProfile().Name), - new XAttribute("path", content.Path)); + new XAttribute("path", content.Path), + new XAttribute("isDoc", "")); foreach (var property in content.Properties) { diff --git a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs index c3545f8be1..c860d714bd 100644 --- a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs @@ -126,7 +126,7 @@ namespace Umbraco.Core.Persistence.Factories { //TODO: Change this once the Language property is public on IContent var content = entity as Content; - var nodeName = content == null ? entity.Name : content.NodeName; + var nodeName = content != null && string.IsNullOrEmpty(content.NodeName) == false ? content.NodeName : entity.Name; var nodeDto = new NodeDto { diff --git a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs index ccd2071b76..196aa0c05f 100644 --- a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs @@ -45,18 +45,15 @@ namespace Umbraco.Core.Persistence.Factories public IEnumerable BuildDto(IEnumerable properties) { var propertyDataDtos = new List(); - /*var serviceStackSerializer = new ServiceStackXmlSerializer(); - var service = new SerializationService(serviceStackSerializer);*/ foreach (var property in properties) { var dto = new PropertyDataDto { NodeId = _id, PropertyTypeId = property.PropertyTypeId, VersionId = _version }; - //TODO Add complex (PropertyEditor) ValueModels to the Ntext/Nvarchar column as a serialized 'Object' (DataTypeDatabaseType.Object) - /*if (property.Value is IEditorModel) - { - var result = service.ToStream(property.Value); - dto.Text = result.ResultStream.ToJsonString(); - }*/ + + //Check if property has an Id and set it, so that it can be updated if it already exists + if (property.HasIdentity) + dto.Id = property.Id; + if (property.DataTypeDatabaseType == DataTypeDatabaseType.Integer && property.Value != null) { dto.Integer = int.Parse(property.Value.ToString()); diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index fc90f71a6a..6fcfe59817 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -226,8 +226,17 @@ namespace Umbraco.Core.Persistence.Repositories protected override void PersistUpdatedItem(IContent entity) { - //Updates Modified date and Version Guid - ((Content)entity).UpdatingEntity(); + //A new version should only be created if published state has changed + bool hasPublishedStateChanged = ((ICanBeDirty) entity).IsPropertyDirty("Published"); + if (hasPublishedStateChanged) + { + //Updates Modified date and Version Guid + ((Content)entity).UpdatingEntity(); + } + else + { + entity.UpdateDate = DateTime.UtcNow; + } //Look up parent to get and set the correct Path if ParentId has changed if (((ICanBeDirty) entity).IsPropertyDirty("ParentId")) @@ -254,17 +263,8 @@ namespace Umbraco.Core.Persistence.Repositories Database.Update(newContentDto); } - //Look up (newest) entries by id in cmsDocument table to set newest = false - var documentDtos = Database.Fetch("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true }); - foreach (var documentDto in documentDtos) - { - var docDto = documentDto; - docDto.Newest = false; - Database.Update(docDto); - } - - //If Published state has changed previous versions should have their publish state reset - if (((ICanBeDirty) entity).IsPropertyDirty("Published") && entity.Published) + //If Published state has changed then previous versions should have their publish state reset + if (hasPublishedStateChanged && entity.Published) { var publishedDocs = Database.Fetch("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true }); foreach (var doc in publishedDocs) @@ -275,14 +275,35 @@ namespace Umbraco.Core.Persistence.Repositories } } - //Create a new version - cmsContentVersion - //Assumes a new Version guid and Version date (modified date) has been set var contentVersionDto = dto.ContentVersionDto; - Database.Insert(contentVersionDto); + if (hasPublishedStateChanged) + { + //Look up (newest) entries by id in cmsDocument table to set newest = false + //NOTE: This is only relevant when a new version is created, which is why its done inside this if-statement. + var documentDtos = Database.Fetch("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true }); + foreach (var documentDto in documentDtos) + { + var docDto = documentDto; + docDto.Newest = false; + Database.Update(docDto); + } - //Create the Document specific data for this version - cmsDocument - //Assumes a new Version guid has been generated - Database.Insert(dto); + //Create a new version - cmsContentVersion + //Assumes a new Version guid and Version date (modified date) has been set + Database.Insert(contentVersionDto); + //Create the Document specific data for this version - cmsDocument + //Assumes a new Version guid has been generated + Database.Insert(dto); + } + else + { + //In order to update the ContentVersion we need to retreive its primary key id + var contentVerDto = Database.SingleOrDefault("WHERE VersionId = @Version", new { Version = entity.Version }); + contentVersionDto.Id = contentVerDto.Id; + + Database.Update(contentVersionDto); + Database.Update(dto); + } //Create the PropertyData for this version - cmsPropertyData var propertyFactory = new PropertyFactory(((Content)entity).ContentType, entity.Version, entity.Id); @@ -290,7 +311,14 @@ namespace Umbraco.Core.Persistence.Repositories //Add Properties foreach (var propertyDataDto in propertyDataDtos) { - Database.Insert(propertyDataDto); + if (hasPublishedStateChanged == false && propertyDataDto.Id > 0) + { + Database.Update(propertyDataDto); + } + else + { + Database.Insert(propertyDataDto); + } } ((ICanBeDirty)entity).ResetDirtyProperties(); diff --git a/src/Umbraco.Core/Publishing/PublishingStrategy.cs b/src/Umbraco.Core/Publishing/PublishingStrategy.cs index 8b3bc8821a..7401bf349d 100644 --- a/src/Umbraco.Core/Publishing/PublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/PublishingStrategy.cs @@ -62,18 +62,6 @@ namespace Umbraco.Core.Publishing string.Format("Content '{0}' with Id '{1}' has been published.", content.Name, content.Id)); - //Fire Published event - //OnPublished(content, e); - - //NOTE: Ideally the xml cache should be refreshed here - as part of the publishing - //but the updated content hasn't been saved yet - //Consider creating a method in the PublishingStrategy that is called when updating a content-being-publishing item is final - //and thus more legit to fire the OnPublished event - //PublishingFinalized(IContent content) { OnPublished(content, new PublishingEventArgs()); } - //PublishingFinalized(IEnumerable content) { OnPublished(content, new PublishingEventArgs()); } - //UnPublishingFinalized(IContent content) { OnUnPublished(content, new PublishingEventArgs()); } - //UnPublishingFinalized(IEnumerable content) { OnUnPublished(content, new PublishingEventArgs()); } - return true; } @@ -132,16 +120,8 @@ namespace Umbraco.Core.Publishing LogHelper.Info( string.Format("Content '{0}' with Id '{1}' has been published.", item.Name, item.Id)); - - //Fire Published event - //OnPublished(item, e); } - //OnPublished(content, e); - - //NOTE: Ideally the xml cache should be refreshed here - as part of the publishing - //OnCacheContentAfterPublish(content, e) - return true; } @@ -176,13 +156,6 @@ namespace Umbraco.Core.Publishing LogHelper.Info( string.Format("Content '{0}' with Id '{1}' has been unpublished.", content.Name, content.Id)); - - //Fire UnPublishing event - //OnUnPublished(content, e); - - //NOTE: Ideally the xml cache should be refreshed here - as part of the unpublishing - //OnRemoveCacheContentAfterPublish(content, e) - return true; } @@ -223,15 +196,8 @@ namespace Umbraco.Core.Publishing LogHelper.Info( string.Format("Content '{0}' with Id '{1}' has been unpublished.", item.Name, item.Id)); - - //Fire AfterUnPublish event - //OnUnPublished(item, e); } - //OnUnPublished(content, e); - - //NOTE: Ideally the xml cache should be refreshed here - as part of the publishing - return true; } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index a66a2f7c05..1a679f105d 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -517,7 +517,7 @@ namespace Umbraco.Core.Services if(omitCacheRefresh == false) _publishingStrategy.UnPublishingFinalized(content); - Audit.Add(AuditTypes.Publish, "UnPublish performed by user", userId == -1 ? 0 : userId, content.Id); + Audit.Add(AuditTypes.UnPublish, "UnPublish performed by user", userId == -1 ? 0 : userId, content.Id); } return unpublished; @@ -588,12 +588,14 @@ namespace Umbraco.Core.Services //Publish and then update the database with new status bool published = _publishingStrategy.Publish(content, userId); + + //Since this is the Save and Publish method, the content should be saved even though the publish fails or isn't allowed + SetWriter(content, userId); + repository.AddOrUpdate(content); + _unitOfWork.Commit(); + if (published) { - SetWriter(content, userId); - repository.AddOrUpdate(content); - _unitOfWork.Commit(); - var xml = content.ToXml(); var poco = new ContentXmlDto{NodeId = content.Id, Xml = xml.ToString(SaveOptions.None)}; var exists = DatabaseContext.Current.Database.FirstOrDefault("WHERE nodeId = @Id", new {Id = content.Id}) != null; @@ -633,7 +635,11 @@ namespace Umbraco.Core.Services var repository = _contentRepository; SetWriter(content, userId); - content.ChangePublishedState(false); + + //Only change the publish state if the "previous" version was actually published + if(content.Published) + content.ChangePublishedState(false); + repository.AddOrUpdate(content); _unitOfWork.Commit(); @@ -669,7 +675,11 @@ namespace Umbraco.Core.Services foreach (var content in contents) { SetWriter(content, userId); - content.ChangePublishedState(false); + + //Only change the publish state if the "previous" version was actually published + if (content.Published) + content.ChangePublishedState(false); + repository.AddOrUpdate(content); _unitOfWork.Commit(); } @@ -716,7 +726,11 @@ namespace Umbraco.Core.Services foreach (var content in contents) { SetWriter(content.Value, userId); - content.Value.ChangePublishedState(false); + + //Only change the publish state if the "previous" version was actually published + if (content.Value.Published) + content.Value.ChangePublishedState(false); + repository.AddOrUpdate(content.Value); _unitOfWork.Commit(); } diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 57bbb4ae7c..b845c4f682 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -264,7 +264,10 @@ - + + + + diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs index 2b8df31950..68c6a18c9c 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs @@ -2,21 +2,18 @@ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; -using System.IO; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using umbraco.BasePages; using umbraco.cms.businesslogic; -using umbraco.cms.businesslogic.datatype.controls; using umbraco.cms.businesslogic.media; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic.propertytype; using umbraco.cms.businesslogic.web; using umbraco.interfaces; using umbraco.uicontrols; -using Umbraco.Core.IO; using Content = umbraco.cms.businesslogic.Content; using SystemDirectories = umbraco.IO.SystemDirectories; @@ -30,7 +27,7 @@ namespace umbraco.controls public class ContentControl : TabView { private Content _content; - private ArrayList _dataFields = new ArrayList(); + internal Dictionary DataTypes = new Dictionary(); private UmbracoEnsuredPage prntpage; public event EventHandler SaveAndPublish; public event EventHandler SaveToPublish; @@ -248,9 +245,10 @@ namespace umbraco.controls return; } } - foreach (IDataEditor df in _dataFields) + + foreach (var type in DataTypes) { - df.Save(); + type.Value.DataEditor.Save(); } if (!string.IsNullOrEmpty(NameTxt.Text)) @@ -308,15 +306,14 @@ namespace umbraco.controls dt.DataEditor.Editor.ID = string.Format("prop_{0}", p.PropertyType.Alias); dt.Data.PropertyId = p.Id; + //Add the DataType to an internal dictionary, which will be used to call the save method on the IDataEditor + //and to retrieve the value from IData in editContent.aspx.cs, so that it can be set on the legacy Document class. + DataTypes.Add(p.PropertyType.Alias, dt); + // check for buttons IDataFieldWithButtons df1 = dt.DataEditor.Editor as IDataFieldWithButtons; if (df1 != null) { - // df1.Alias = p.PropertyType.Alias; - /* - // df1.Version = _content.Version; - editDataType.Data.PropertyId = p.Id; - */ ((Control)df1).ID = p.PropertyType.Alias; @@ -389,14 +386,6 @@ namespace umbraco.controls menuElement.ElementClass, menuElement.ExtraMenuWidth); } - - // fieldData.Alias = p.PropertyType.Alias; - // ((Control) fieldData).ID = p.PropertyType.Alias; - // fieldData.Text = p.Value.ToString(); - - _dataFields.Add(dt.DataEditor.Editor); - - Pane pp = new Pane(); Control holder = new Control(); holder.Controls.Add(dt.DataEditor.Editor); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 73e3a172ba..abc9179108 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -291,8 +291,14 @@ namespace umbraco.cms.presentation } } - - + //The value of the properties has been set on IData through IDataEditor in the ContentControl + //so we need to 'retrieve' that value and set it on the property of the new IContent object. + //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property + //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). + foreach (var item in cControl.DataTypes) + { + _document.Content.SetValue(item.Key, item.Value.Data.Value); + } // Run Handler BusinessLogic.Actions.Action.RunActionHandlers(_document, ActionUpdate.Instance); diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index b2ff163d59..1ebd88ade9 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -670,9 +670,7 @@ namespace umbraco.cms.businesslogic continue; //get the propertyId - var property = propData - .Where(x => x.PropertyTypeId == pt.Id) - .SingleOrDefault(); + var property = propData.LastOrDefault(x => x.PropertyTypeId == pt.Id); if (property == null) continue; var propertyId = property.Id; diff --git a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs index cdd321858d..4a850f8aed 100644 --- a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs +++ b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs @@ -138,7 +138,7 @@ namespace umbraco.cms.businesslogic.datatype } set { - if (!PreviewMode) + /*if (!PreviewMode) { // Try to set null values if possible try @@ -168,8 +168,9 @@ namespace umbraco.cms.businesslogic.datatype if (value == null) value = ""; SqlHelper.ExecuteNonQuery("update cmsPropertyData set " + _dataType.DataFieldName + " = @value where id = " + m_PropertyId, SqlHelper.CreateParameter("@value", value)); } - } + }*/ m_Value = value; + m_ValueLoaded = true; } } diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index a82aa6693c..26e19a22d3 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -77,27 +77,27 @@ namespace umbraco.cms.businesslogic.web this._optimizedMode = optimizedMode; if (optimizedMode) { - _content = ServiceContext.Current.ContentService.GetById(id); + Content = ServiceContext.Current.ContentService.GetById(id); bool hasChildren = ServiceContext.Current.ContentService.HasChildren(id); - int templateId = _content.Template == null ? 0 : _content.Template.Id; + int templateId = Content.Template == null ? 0 : Content.Template.Id; - SetupDocumentForTree(_content.Key, _content.Level, _content.ParentId, _content.CreatorId, - _content.WriterId, - _content.Published, _content.Path, _content.Name, _content.CreateDate, - _content.UpdateDate, _content.UpdateDate, _content.ContentType.Icon, hasChildren, - _content.ContentType.Alias, _content.ContentType.Thumbnail, - _content.ContentType.Description, null, _content.ContentType.Id, - templateId, _content.ContentType.IsContainer); + SetupDocumentForTree(Content.Key, Content.Level, Content.ParentId, Content.CreatorId, + Content.WriterId, + Content.Published, Content.Path, Content.Name, Content.CreateDate, + Content.UpdateDate, Content.UpdateDate, Content.ContentType.Icon, hasChildren, + Content.ContentType.Alias, Content.ContentType.Thumbnail, + Content.ContentType.Description, null, Content.ContentType.Id, + templateId, Content.ContentType.IsContainer); - var tmpReleaseDate = _content.ReleaseDate.HasValue ? _content.ReleaseDate.Value : new DateTime(); - var tmpExpireDate = _content.ExpireDate.HasValue ? _content.ExpireDate.Value : new DateTime(); - var creator = new User(_content.CreatorId, true); - var writer = new User(_content.WriterId, true); + var tmpReleaseDate = Content.ReleaseDate.HasValue ? Content.ReleaseDate.Value : new DateTime(); + var tmpExpireDate = Content.ExpireDate.HasValue ? Content.ExpireDate.Value : new DateTime(); + var creator = new User(Content.CreatorId, true); + var writer = new User(Content.WriterId, true); - InitializeContent(_content.ContentType.Id, _content.Version, _content.UpdateDate, - _content.ContentType.Icon); - InitializeDocument(creator, writer, _content.Name, templateId, tmpReleaseDate, tmpExpireDate, - _content.UpdateDate, _content.Published); + InitializeContent(Content.ContentType.Id, Content.Version, Content.UpdateDate, + Content.ContentType.Icon); + InitializeDocument(creator, writer, Content.Name, templateId, tmpReleaseDate, tmpExpireDate, + Content.UpdateDate, Content.Published); } /*if (optimizedMode) { @@ -253,7 +253,7 @@ namespace umbraco.cms.businesslogic.web private User _writer; private int? _writerId; private bool _optimizedMode; - private IContent _content; + protected internal IContent Content; /// /// This is used to cache the child documents of Document when the children property @@ -680,7 +680,7 @@ namespace umbraco.cms.businesslogic.web set { _published = value; - _content.ChangePublishedState(value); + Content.ChangePublishedState(value); /*SqlHelper.ExecuteNonQuery( string.Format("update cmsDocument set published = {0} where nodeId = {1}", Id, value ? 1 : 0));*/ } @@ -710,14 +710,14 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); { get { - return _content.Name; + return Content.Name; //return base.Text; } set { value = value.Trim(); base.Text = value; - _content.Name = value; + Content.Name = value; /*SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", SqlHelper.CreateParameter("@text", value), @@ -735,7 +735,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); set { _updated = value; - _content.UpdateDate = value; + Content.UpdateDate = value; /*SqlHelper.ExecuteNonQuery("update cmsDocument set updateDate = @value where versionId = @versionId", SqlHelper.CreateParameter("@value", value), SqlHelper.CreateParameter("@versionId", Version));*/ @@ -752,7 +752,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); set { _release = value; - _content.ReleaseDate = value; + Content.ReleaseDate = value; /*if (_release.Year != 1 || _release.Month != 1 || _release.Day != 1) SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = @value where versionId = @versionId", SqlHelper.CreateParameter("@value", value), @@ -773,7 +773,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); set { _expire = value; - _content.ExpireDate = value; + Content.ExpireDate = value; /*if (_expire.Year != 1 || _expire.Month != 1 || _expire.Day != 1) SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = @value where versionId=@versionId", SqlHelper.CreateParameter("@value", value), @@ -803,12 +803,12 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); _template = value; if (value == 0) { - _content.Template = null; + Content.Template = null; } else { var template = ServiceContext.Current.FileService.GetTemplate(value); - _content.Template = template; + Content.Template = template; } /*if (value == 0) { @@ -878,7 +878,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Publish()", false)] public void Publish(User u) { - ServiceContext.Current.ContentService.Publish(_content, u.Id, true); + ServiceContext.Current.ContentService.Publish(Content, u.Id, true); //PublishWithResult(u); } @@ -899,7 +899,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - var result = ServiceContext.Current.ContentService.Publish(_content, u.Id, true); + var result = ServiceContext.Current.ContentService.Publish(Content, u.Id, true); _published = result; // make a lookup to see if template is 0 as the template is not initialized in the optimized @@ -954,7 +954,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.PublishWithChildren()", false)] public bool PublishWithChildrenWithResult(User u) { - return ServiceContext.Current.ContentService.PublishWithChildren(_content, u.Id, true); + return ServiceContext.Current.ContentService.PublishWithChildren(Content, u.Id, true); /*if (PublishWithResult(u)) { @@ -985,7 +985,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - _content = ServiceContext.Current.ContentService.Rollback(Id, VersionId, u.Id); + Content = ServiceContext.Current.ContentService.Rollback(Id, VersionId, u.Id); FireAfterRollBack(e); } @@ -1005,7 +1005,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - var published = ServiceContext.Current.ContentService.PublishWithChildren(_content, u.Id, true); + var published = ServiceContext.Current.ContentService.PublishWithChildren(Content, u.Id, true); /*_published = true; string tempVersion = Version.ToString(); @@ -1046,7 +1046,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); //SqlHelper.ExecuteNonQuery(string.Format("update cmsDocument set published = 0 where nodeId = {0}", Id)); //_published = false; - ServiceContext.Current.ContentService.UnPublish(_content, 0, true); + ServiceContext.Current.ContentService.UnPublish(Content, 0, true); FireAfterUnPublish(e); } @@ -1063,7 +1063,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - ServiceContext.Current.ContentService.Save(_content); + ServiceContext.Current.ContentService.Save(Content); base.Save(); // update preview xml @@ -1076,7 +1076,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.HasPublishedVersion()", false)] public bool HasPublishedVersion() { - return _content.HasPublishedVersion(); + return Content.HasPublishedVersion(); //return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); } @@ -1088,7 +1088,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// public bool HasPendingChanges() { - return _content.Published == false; + return Content.Published == false; //double timeDiff = new TimeSpan(UpdateDate.Ticks - VersionDate.Ticks).TotalMilliseconds; //return timeDiff > 2000; } @@ -1168,7 +1168,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { // Make the new document - var content = ServiceContext.Current.ContentService.Copy(_content, CopyTo, RelateToOrignal, u.Id); + var content = ServiceContext.Current.ContentService.Copy(Content, CopyTo, RelateToOrignal, u.Id); newDoc = new Document(content); e.NewDocument = newDoc; @@ -1209,9 +1209,9 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// public override IEnumerable GetDescendants() { - var descendants = _content == null + var descendants = Content == null ? ServiceContext.Current.ContentService.GetDescendants(Id) - : ServiceContext.Current.ContentService.GetDescendants(_content); + : ServiceContext.Current.ContentService.GetDescendants(Content); return descendants.Select(x => new Document(x.Id, true)); } @@ -1424,29 +1424,29 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); private void setupNode(IContent content) { - _content = content; + Content = content; //Setting private properties from IContent replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() - base.PopulateCMSNodeFromContent(_content, _objectType); + base.PopulateCMSNodeFromContent(Content, _objectType); //If the version is empty we update with the latest version from the current IContent. if (Version == Guid.Empty) - Version = _content.Version; + Version = Content.Version; //Setting private properties from IContent replacing Document.setupNode() - _creator = User.GetUser(_content.CreatorId); - _writer = User.GetUser(_content.WriterId); - _updated = _content.UpdateDate; + _creator = User.GetUser(Content.CreatorId); + _writer = User.GetUser(Content.WriterId); + _updated = Content.UpdateDate; - if (_content.Template != null) - _template = _content.Template.Id; + if (Content.Template != null) + _template = Content.Template.Id; - if (_content.ExpireDate.HasValue) - _expire = _content.ExpireDate.Value; + if (Content.ExpireDate.HasValue) + _expire = Content.ExpireDate.Value; - if (_content.ReleaseDate.HasValue) - _release = _content.ReleaseDate.Value; + if (Content.ReleaseDate.HasValue) + _release = Content.ReleaseDate.Value; - _published = _content.HasPublishedVersion(); + _published = Content.HasPublishedVersion(); } [Obsolete("Deprecated", false)] @@ -1574,14 +1574,14 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); - if (_content != null) + if (Content != null) { - ServiceContext.Current.ContentService.Delete(_content); + ServiceContext.Current.ContentService.Delete(Content); } else { - _content = ServiceContext.Current.ContentService.GetById(Id); - ServiceContext.Current.ContentService.Delete(_content); + Content = ServiceContext.Current.ContentService.GetById(Id); + ServiceContext.Current.ContentService.Delete(Content); } //Keeping the base.delete() as it looks to be clear 'private/internal cache' @@ -1606,14 +1606,14 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); { umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); UnPublish(); - if (_content != null) + if (Content != null) { - ServiceContext.Current.ContentService.MoveToRecycleBin(_content); + ServiceContext.Current.ContentService.MoveToRecycleBin(Content); } else { - _content = ServiceContext.Current.ContentService.GetById(Id); - ServiceContext.Current.ContentService.MoveToRecycleBin(_content); + Content = ServiceContext.Current.ContentService.GetById(Id); + ServiceContext.Current.ContentService.MoveToRecycleBin(Content); } FireAfterMoveToTrash(e); } From 30d7381ee3f16671b7989d0ce471780f327bc824 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Mon, 17 Dec 2012 11:16:09 -0100 Subject: [PATCH 13/35] Correcting all usages of getProperties to GenericProperties since its marked as Obsolete and shouldn't be used anymore. Starting refactor of legacy Content class. Refactoring DefaultData to use new datalayer. Updating usages of the ServiceContext after as its no longer a singleton. Correcting a few merge issues. --- src/Umbraco.Core/ApplicationContext.cs | 1 - src/Umbraco.Core/Models/ContentExtensions.cs | 68 +---- .../Models/Rdbms/PropertyDataDto.cs | 2 +- .../Persistence/Mappers/ModelDtoMapper.cs | 27 ++ .../Persistence/Mappers/PropertyMapper.cs | 47 +++ .../Services/ContentTypeService.cs | 20 +- src/Umbraco.Core/Services/FileService.cs | 7 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../ContentTypeDefinitionFactory.cs | 2 +- .../Strategies/UpdateCacheAfterPublish.cs | 3 +- .../Strategies/UpdateCacheAfterUnPublish.cs | 3 +- .../umbraco/Trees/BaseMediaTree.cs | 2 +- .../controls/Images/UploadMediaImage.ascx.cs | 2 +- .../umbraco/dialogs/rollBack.aspx.cs | 2 +- src/umbraco.cms/businesslogic/Content.cs | 40 ++- .../businesslogic/Property/Property.cs | 13 +- .../businesslogic/datatype/DefaultData.cs | 101 ++----- .../businesslogic/translation/Translation.cs | 2 +- src/umbraco.cms/businesslogic/web/Document.cs | 285 +++--------------- .../businesslogic/web/DocumentType.cs | 10 +- .../businesslogic/workflow/Notification.cs | 2 +- .../documents/documentService.cs | 2 +- src/umbraco.webservices/media/mediaService.cs | 2 +- .../members/memberService.cs | 2 +- 24 files changed, 226 insertions(+), 420 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index 964e771850..776714b839 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -4,7 +4,6 @@ using System.Web; using System.Web.Caching; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; -using Umbraco.Core.Persistence; using Umbraco.Core.Services; diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index b4a56f708a..d6c70654ef 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -57,7 +57,7 @@ namespace Umbraco.Core.Models if (content.HasIdentity == false) return false; - return ServiceContext.Current.ContentService.HasPublishedVersion(content.Id); + return ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id); } /// @@ -141,71 +141,5 @@ namespace Umbraco.Core.Models //If current IContent is published we should get latest unpublished version return content.ToXml(); } - - /// - /// Creates the xml representation for the object - /// - /// to generate xml for - /// Xml representation of the passed in - public static XElement ToXml(this IContent content) - { - //nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias); - //var nodeName = content.ContentType.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true); - var nodeName = content.ContentType.Alias; - var niceUrl = content.Name.Replace(" ", "-").ToLower(); - - /* NOTE Not entirely sure if this is needed, but either way the niceUrlProvider is not - * available from here, so it would have to be delegated - */ - /*if (UmbracoContext.Current != null) - { - var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider; - niceUrl = niceUrlsProvider.GetNiceUrl(content.Id); - }*/ - - var xml = new XElement(nodeName, - new XAttribute("id", content.Id), - new XAttribute("parentID", content.Level > 1 ? content.ParentId : -1), - new XAttribute("level", content.Level), - new XAttribute("writerID", content.WriterId), - new XAttribute("creatorID", content.CreatorId), - new XAttribute("nodeType", content.ContentType.Id), - new XAttribute("template", content.Template == null ? "0": content.Template.Id.ToString()), - new XAttribute("sortOrder", content.SortOrder), - new XAttribute("createDate", content.CreateDate.ToString("s")), - new XAttribute("updateDate", content.UpdateDate.ToString("s")), - new XAttribute("nodeName", content.Name), - new XAttribute("urlName", niceUrl),//Format Url ? - new XAttribute("writerName", content.GetWriterProfile().Name), - new XAttribute("creatorName", content.GetCreatorProfile().Name), - new XAttribute("path", content.Path), - new XAttribute("isDoc", "")); - - foreach (var property in content.Properties) - { - if (property == null) continue; - - xml.Add(property.ToXml()); - - //Check for umbracoUrlName convention - if (property.Alias == "umbracoUrlName" && property.Value.ToString().Trim() != string.Empty) - xml.SetAttributeValue("urlName", property.Value); - } - - return xml; - } - - /// - /// Creates the xml representation for the object - /// - /// to generate xml for - /// Boolean indicating whether the xml should be generated for preview - /// Xml representation of the passed in - public static XElement ToXml(this IContent content, bool isPreview) - { - //TODO Do a proper implementation of this - //If current IContent is published we should get latest unpublished version - return content.ToXml(); - } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs index f125c6eaf3..4b50d835fe 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs @@ -75,7 +75,7 @@ namespace Umbraco.Core.Models.Rdbms return Text; } - return null; + return string.Empty; } } } diff --git a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs index 8410a6dfb3..acfffc8971 100644 --- a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs @@ -2,6 +2,8 @@ using System.Reflection; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Mappers { @@ -15,6 +17,21 @@ namespace Umbraco.Core.Persistence.Mappers public bool MapPropertyToColumn(Type t, PropertyInfo pi, ref string columnName, ref bool resultColumn) { + if (t == typeof (PropertyDataDto)) + { + var tableNameAttribute = t.FirstAttribute(); + var columnAttribute = pi.FirstAttribute(); + + if (tableNameAttribute != null && columnAttribute != null && string.IsNullOrEmpty(columnAttribute.Name) == false) + { + columnName = string.Format("{0}.{1}", + SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName( + tableNameAttribute.Value), + SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnAttribute.Name)); + } + return true; + } + if (t == typeof(Content) || t == typeof(IContent)) { var mappedName = ContentMapper.Instance.Map(pi.Name); @@ -125,6 +142,16 @@ namespace Umbraco.Core.Persistence.Mappers return true; } + if (t == typeof(Property)) + { + var mappedName = PropertyMapper.Instance.Map(pi.Name); + if (!string.IsNullOrEmpty(mappedName)) + { + columnName = mappedName; + } + return true; + } + if (t == typeof(PropertyType)) { var mappedName = PropertyTypeMapper.Instance.Map(pi.Name); diff --git a/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs b/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs new file mode 100644 index 0000000000..795e5a9216 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; + +namespace Umbraco.Core.Persistence.Mappers +{ + internal sealed class PropertyMapper : BaseMapper + { + private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + + internal static PropertyMapper Instance = new PropertyMapper(); + + private PropertyMapper() + { + BuildMap(); + } + + #region Overrides of BaseMapper + + internal override void BuildMap() + { + CacheMap(src => src.Id, dto => dto.Id); + CacheMap(src => src.Version, dto => dto.VersionId); + CacheMap(src => src.PropertyTypeId, dto => dto.PropertyTypeId); + } + + internal override string Map(string propertyName) + { + if (!PropertyInfoCache.ContainsKey(propertyName)) + return string.Empty; + + var dtoTypeProperty = PropertyInfoCache[propertyName]; + + return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); + } + + internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) + { + var property = base.ResolveMapping(sourceMember, destinationMember); + PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index b4db01a6d6..0b74538730 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -114,10 +114,12 @@ namespace Umbraco.Core.Services /// True if the content type has any children otherwise False public bool HasChildren(int id) { - var repository = _contentTypeRepository; - var query = Query.Builder.Where(x => x.ParentId == id); - int count = repository.Count(query); - return count > 0; + using (var repository = _repositoryFactory.CreateContentTypeRepository(_uowProvider.GetUnitOfWork())) + { + var query = Query.Builder.Where(x => x.ParentId == id); + int count = repository.Count(query); + return count > 0; + } } /// @@ -340,6 +342,7 @@ namespace Umbraco.Core.Services var query = Query.Builder.Where(x => x.ParentId == id); var contentTypes = repository.GetByQuery(query); return contentTypes; + } } /// @@ -349,10 +352,11 @@ namespace Umbraco.Core.Services /// True if the media type has any children otherwise False public bool MediaTypeHasChildren(int id) { - var repository = _mediaTypeRepository; - var query = Query.Builder.Where(x => x.ParentId == id); - int count = repository.Count(query); - return count > 0; + using (var repository = _repositoryFactory.CreateMediaTypeRepository(_uowProvider.GetUnitOfWork())) + { + var query = Query.Builder.Where(x => x.ParentId == id); + int count = repository.Count(query); + return count > 0; } } diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index bb57d00685..74ee65d237 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Umbraco.Core.Auditing; using Umbraco.Core.Events; using Umbraco.Core.Models; @@ -239,6 +238,7 @@ namespace Umbraco.Core.Services using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork())) { return repository.Get(alias); + } } /// @@ -248,8 +248,9 @@ namespace Umbraco.Core.Services /// A object public ITemplate GetTemplate(int id) { - var repository = _templateRepository; - return repository.Get(id); + using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork())) + { + return repository.Get(id); } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index f46668a936..df74f19a78 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -236,6 +236,7 @@ + diff --git a/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs b/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs index 5996ea9e1b..329c237d5d 100644 --- a/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs +++ b/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs @@ -316,7 +316,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions ? templateName.Replace(".cshtml", "").Replace(".vbhtml", "") : templateName.Replace(".masterpage", ""); - var template = ApplicationContext.Current.Services.FileService.GetTemplateByAlias(@alias); + var template = ApplicationContext.Current.Services.FileService.GetTemplate(@alias); if(template == null) { var name = engine == RenderingEngine.Mvc diff --git a/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs b/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs index 52bd6da466..c7c91f87eb 100644 --- a/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs +++ b/src/Umbraco.Web/Strategies/UpdateCacheAfterPublish.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Publishing; using umbraco; @@ -26,7 +27,7 @@ namespace Umbraco.Web.Strategies PublishingStrategy.Published += PublishingStrategy_Published; } - void PublishingStrategy_Published(object sender, Core.PublishingEventArgs e) + void PublishingStrategy_Published(object sender, PublishingEventArgs e) { if (sender is IContent) { diff --git a/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs b/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs index 22eefc70af..be9bd22839 100644 --- a/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs +++ b/src/Umbraco.Web/Strategies/UpdateCacheAfterUnPublish.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Publishing; using umbraco; @@ -24,7 +25,7 @@ namespace Umbraco.Web.Strategies PublishingStrategy.UnPublished += PublishingStrategy_UnPublished; } - void PublishingStrategy_UnPublished(object sender, Core.PublishingEventArgs e) + void PublishingStrategy_UnPublished(object sender, PublishingEventArgs e) { if (sender is IContent) { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs index f9a440f219..b9d51f90c0 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs @@ -137,7 +137,7 @@ function openMedia(id) { /// public virtual string GetLinkValue(Media dd, string nodeLink) { - var props = dd.getProperties; + var props = dd.GenericProperties; foreach (Property p in props) { Guid currId = p.PropertyType.DataTypeDefinition.DataType.Id; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Images/UploadMediaImage.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Images/UploadMediaImage.ascx.cs index 1bbc5d0ea8..6f3c67609d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Images/UploadMediaImage.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Images/UploadMediaImage.ascx.cs @@ -71,7 +71,7 @@ namespace umbraco.controls.Images parent = BusinessLogic.User.GetCurrent().StartNodeId; Media m = Media.MakeNew(TextBoxTitle.Text, cms.businesslogic.media.MediaType.GetByAlias("image"), BasePage.Current.getUser(), int.Parse(MediaPickerControl.Value)); - var props = m.getProperties; + var props = m.GenericProperties; foreach (cms.businesslogic.property.Property p in props) { if (p.PropertyType.DataTypeDefinition.DataType.Id == UploadField.Id) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs index 83bd442486..88e9933945 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs @@ -41,7 +41,7 @@ namespace umbraco.presentation.dialogs lt_notice.Text = ui.Text("rollback", "htmlHelp"); - var props = rollback.getProperties; + var props = rollback.GenericProperties; foreach (Property p in props) { try { diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index 1ebd88ade9..fb393e115a 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Xml; +using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Models; using umbraco.cms.businesslogic.property; @@ -25,6 +26,7 @@ namespace umbraco.cms.businesslogic /// Note that Content data in umbraco is *not* tablular but in a treestructure. /// /// + [Obsolete("Deprecated, Use Umbraco.Core.Models.Content or Umbraco.Core.Models.Media", false)] public class Content : CMSNode { #region Private Members @@ -40,7 +42,7 @@ namespace umbraco.cms.businesslogic #endregion - #region Constructors + #region Constructors public Content(int id) : base(id) { } @@ -57,7 +59,6 @@ namespace umbraco.cms.businesslogic _version = _contentBase.Version; _versionDate = _contentBase.UpdateDate; _versionDateInitialized = true; - } #endregion @@ -69,18 +70,17 @@ namespace umbraco.cms.businesslogic /// /// The ContentType /// A list of Content objects sharing the ContentType defined. + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentOfContentType() or Umbraco.Core.Services.MediaService.GetMediaOfMediaType()", false)] public static Content[] getContentOfContentType(ContentType ct) { - IRecordsReader dr = SqlHelper.ExecuteReader("Select nodeId from cmsContent INNER JOIN umbracoNode ON cmsContent.nodeId = umbracoNode.id where ContentType = " + ct.Id + " ORDER BY umbracoNode.text "); - System.Collections.ArrayList tmp = new System.Collections.ArrayList(); + var list = new List(); + var content = ApplicationContext.Current.Services.ContentService.GetContentOfContentType(ct.Id); + list.AddRange(content.OrderBy(x => x.Name).Select(x => new Content(x))); - while (dr.Read()) tmp.Add(dr.GetInt("nodeId")); - dr.Close(); + var media = ApplicationContext.Current.Services.MediaService.GetMediaOfMediaType(ct.Id); + list.AddRange(media.OrderBy(x => x.Name).Select(x => new Content(x))); - Content[] retval = new Content[tmp.Count]; - for (int i = 0; i < tmp.Count; i++) retval[i] = new Content((int)tmp[i]); - - return retval; + return list.ToArray(); } /// @@ -88,10 +88,22 @@ namespace umbraco.cms.businesslogic /// /// The version identifier /// The Content object from the given version + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetByIdVersion() or Umbraco.Core.Services.MediaService.GetByIdVersion()", false)] public static Content GetContentFromVersion(Guid version) { - int tmpContentId = SqlHelper.ExecuteScalar("Select ContentId from cmsContentVersion where versionId = '" + version.ToString() + "'"); - return new Content(tmpContentId); + int id = + ApplicationContext.Current.DatabaseContext.Database.ExecuteScalar( + "Select ContentId from cmsContentVersion where versionId = @VersionId", new {VersionId = version}); + + var content = ApplicationContext.Current.Services.ContentService.GetByIdVersion(id, version); + if (content != null) + { + return new Content(content); + } + + //TODO Change to use GetByIdVersion once that method has been implemented in the MediaService + var media = ApplicationContext.Current.Services.MediaService.GetById(id); + return new Content(media); } #endregion @@ -393,7 +405,7 @@ namespace umbraco.cms.businesslogic public virtual void XmlPopulate(XmlDocument xd, ref XmlNode x, bool Deep) { - var props = this.getProperties; + var props = this.GenericProperties; foreach (property.Property p in props) if (p != null) x.AppendChild(p.ToXml(xd)); @@ -483,7 +495,7 @@ namespace umbraco.cms.businesslogic /// Creates a new Content object from the ContentType. /// /// - protected void CreateContent(ContentType ct) + protected virtual void CreateContent(ContentType ct) { SqlHelper.ExecuteNonQuery("insert into cmsContent (nodeId,ContentType) values (" + this.Id + "," + ct.Id + ")"); createNewVersion(DateTime.Now); diff --git a/src/umbraco.cms/businesslogic/Property/Property.cs b/src/umbraco.cms/businesslogic/Property/Property.cs index aec8ab3f83..1d88e4f8ff 100644 --- a/src/umbraco.cms/businesslogic/Property/Property.cs +++ b/src/umbraco.cms/businesslogic/Property/Property.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.Data; using System.Runtime.CompilerServices; using System.Xml; - +using Umbraco.Core; +using Umbraco.Core.Persistence; using umbraco.DataLayer; using umbraco.BusinessLogic; @@ -15,9 +16,8 @@ namespace umbraco.cms.businesslogic.property /// public class Property { - private static string _connstring = GlobalSettings.DbDSN; - propertytype.PropertyType _pt; - interfaces.IData _data; + private propertytype.PropertyType _pt; + private interfaces.IData _data; private int _id; protected static ISqlHelper SqlHelper @@ -25,6 +25,11 @@ namespace umbraco.cms.businesslogic.property get { return Application.SqlHelper; } } + internal static Database Database + { + get { return ApplicationContext.Current.DatabaseContext.Database; } + } + public Property(int Id, propertytype.PropertyType pt) { diff --git a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs index 4a850f8aed..d450c5d0df 100644 --- a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs +++ b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs @@ -1,7 +1,7 @@ using System; -using System.Data; +using System.Linq; using Umbraco.Core; -using Umbraco.Core.Logging; +using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; using umbraco.DataLayer; using umbraco.BusinessLogic; @@ -21,6 +21,7 @@ namespace umbraco.cms.businesslogic.datatype private bool m_PreviewMode; private bool m_ValueLoaded = false; + [Obsolete("Deprecated, For querying the database use the new UmbracoDatabase object ApplicationContext.Current.DatabaseContext.Database", false)] protected static ISqlHelper SqlHelper { get { return Application.SqlHelper; } @@ -30,7 +31,7 @@ namespace umbraco.cms.businesslogic.datatype //NOTE DatabaseContext.Current.Database should eventually be replaced with that from the Repository-Resolver refactor branch. internal static Database Database { - get { return DatabaseContext.Current.Database; } + get { return ApplicationContext.Current.DatabaseContext.Database; } } /// @@ -58,33 +59,29 @@ namespace umbraco.cms.businesslogic.datatype /// protected virtual void LoadValueFromDatabase() { + var sql = new Sql(); + sql.Select("*") + .From() + .InnerJoin() + .On(x => x.Id, y => y.PropertyTypeId) + .InnerJoin() + .On(x => x.DataTypeId, y => y.DataTypeId) + .Where("cmsPropertyData.id = @Id", new {Id = m_PropertyId}); + var dto = Database.Fetch(sql).FirstOrDefault(); - //this is an optimized version of this query. In one call it will return the data type - //and the values, this will then set the underlying db type and value of the BaseDataType object - //instead of having it query the database itself. - var sql = @" - SELECT dataInt, dataDate, dataNvarchar, dataNtext, dbType FROM cmsPropertyData - INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid - INNER JOIN cmsDataType ON cmsDataType.nodeId = cmsPropertyType.dataTypeId - WHERE cmsPropertyData.id = " + m_PropertyId; - - using (var r = SqlHelper.ExecuteReader(sql)) + if (dto != null) { - if (r.Read()) - { - //the type stored in the cmsDataType table - var strDbType = r.GetString("dbType"); - //get the enum of the data type - var dbType = BaseDataType.GetDBType(strDbType); - //get the column name in the cmsPropertyData table that stores the correct information for the data type - var fieldName = BaseDataType.GetDataFieldName(dbType); - //get the value for the data type, if null, set it to an empty string - m_Value = r.GetObject(fieldName) ?? string.Empty; - - //now that we've set our value, we can update our BaseDataType object with the correct values from the db - //instead of making it query for itself. This is a peformance optimization enhancement. - _dataType.SetDataTypeProperties(fieldName, dbType); - } + //the type stored in the cmsDataType table + var strDbType = dto.PropertyTypeDto.DataTypeDto.DbType; + //get the enum of the data type + var dbType = BaseDataType.GetDBType(strDbType); + //get the column name in the cmsPropertyData table that stores the correct information for the data type + var fieldName = BaseDataType.GetDataFieldName(dbType); + //get the value for the data type, if null, set it to an empty string + m_Value = dto.GetValue; + //now that we've set our value, we can update our BaseDataType object with the correct values from the db + //instead of making it query for itself. This is a peformance optimization enhancement. + _dataType.SetDataTypeProperties(fieldName, dbType); } } @@ -92,7 +89,7 @@ namespace umbraco.cms.businesslogic.datatype { get { - return this._dataType.DBType; + return _dataType.DBType; } } @@ -115,7 +112,7 @@ namespace umbraco.cms.businesslogic.datatype public virtual XmlNode ToXMl(XmlDocument data) { string sValue = Value!=null ? Value.ToString() : String.Empty; - if (this._dataType.DBType == DBTypes.Ntext) + if (_dataType.DBType == DBTypes.Ntext) return data.CreateCDataSection(sValue); return data.CreateTextNode(sValue); } @@ -138,37 +135,6 @@ namespace umbraco.cms.businesslogic.datatype } set { - /*if (!PreviewMode) - { - // Try to set null values if possible - try - { - //CHANGE:by Allan Laustsen to fix copy nodes - //if (value == null) - if (value == null || - (string.IsNullOrEmpty(value.ToString()) && - (this._dataType.DBType == DBTypes.Integer || this._dataType.DBType == DBTypes.Date))) - SqlHelper.ExecuteNonQuery("update cmsPropertyData set " + _dataType.DataFieldName + - " = NULL where id = " + m_PropertyId); - else - { - // we need to be sure that the value doesn't contain malformatted xml - if (_dataType.DBType == DBTypes.Ntext || _dataType.DBType == DBTypes.Nvarchar) - { - value = cms.helpers.xhtml.RemoveIllegalXmlCharacters(value.ToString()); - } - SqlHelper.ExecuteNonQuery( - "update cmsPropertyData set " + _dataType.DataFieldName + " = @value where id = " + - m_PropertyId, SqlHelper.CreateParameter("@value", value)); - } - } - catch (Exception e) - { - LogHelper.Error("Error updating item", e); - if (value == null) value = ""; - SqlHelper.ExecuteNonQuery("update cmsPropertyData set " + _dataType.DataFieldName + " = @value where id = " + m_PropertyId, SqlHelper.CreateParameter("@value", value)); - } - }*/ m_Value = value; m_ValueLoaded = true; } @@ -216,12 +182,9 @@ namespace umbraco.cms.businesslogic.datatype public virtual Guid Version { get - { - using (IRecordsReader dr = SqlHelper.ExecuteReader("SELECT versionId FROM cmsPropertyData WHERE id = " + PropertyId)) - { - dr.Read(); - return dr.GetGuid("versionId"); - } + { + var dto = Database.FirstOrDefault("WHERE id = @Id", new {Id = PropertyId}); + return dto.VersionId.HasValue ? dto.VersionId.Value : Guid.Empty; } } @@ -232,8 +195,8 @@ namespace umbraco.cms.businesslogic.datatype public virtual int NodeId { get - { - return SqlHelper.ExecuteScalar("Select contentNodeid from cmsPropertyData where id = " + PropertyId); + { + return Database.ExecuteScalar("Select contentNodeid from cmsPropertyData where id = @Id", new {Id = PropertyId}); } } diff --git a/src/umbraco.cms/businesslogic/translation/Translation.cs b/src/umbraco.cms/businesslogic/translation/Translation.cs index cbea78c37c..ab0d0d9482 100644 --- a/src/umbraco.cms/businesslogic/translation/Translation.cs +++ b/src/umbraco.cms/businesslogic/translation/Translation.cs @@ -92,7 +92,7 @@ namespace umbraco.cms.businesslogic.translation Document d = new Document(DocumentId); int words = CountWordsInString(d.Text); - var props = d.getProperties; + var props = d.GenericProperties; foreach (Property p in props) { if (p.Value.GetType() == "".GetType()) diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 26e19a22d3..d528c44cf2 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -2,11 +2,10 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Web; using System.Xml; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Logging; -using Umbraco.Core.Services; using umbraco.BusinessLogic; using umbraco.BusinessLogic.Actions; using umbraco.cms.helpers; @@ -77,8 +76,8 @@ namespace umbraco.cms.businesslogic.web this._optimizedMode = optimizedMode; if (optimizedMode) { - Content = ServiceContext.Current.ContentService.GetById(id); - bool hasChildren = ServiceContext.Current.ContentService.HasChildren(id); + Content = ApplicationContext.Current.Services.ContentService.GetById(id); + bool hasChildren = ApplicationContext.Current.Services.ContentService.HasChildren(id); int templateId = Content.Template == null ? 0 : Content.Template.Id; SetupDocumentForTree(Content.Key, Content.Level, Content.ParentId, Content.CreatorId, @@ -99,67 +98,6 @@ namespace umbraco.cms.businesslogic.web InitializeDocument(creator, writer, Content.Name, templateId, tmpReleaseDate, tmpExpireDate, Content.UpdateDate, Content.Published); } - /*if (optimizedMode) - { - - using (IRecordsReader dr = - SqlHelper.ExecuteReader(string.Format(m_SQLOptimizedSingle.Trim(), "umbracoNode.id = @id", "cmsContentVersion.id desc"), - SqlHelper.CreateParameter("@nodeObjectType", Document._objectType), - SqlHelper.CreateParameter("@id", id))) - { - if (dr.Read()) - { - // Initialize node and basic document properties - bool _hc = false; - if (dr.GetInt("children") > 0) - _hc = true; - SetupDocumentForTree(dr.GetGuid("uniqueId") - , dr.GetShort("level") - , dr.GetInt("parentId") - , dr.GetInt("nodeUser") - , dr.GetInt("documentUser") - , dr.GetBoolean("published") - , dr.GetString("path") - , dr.GetString("text") - , dr.GetDateTime("createDate") - , dr.GetDateTime("updateDate") - , dr.GetDateTime("versionDate") - , dr.GetString("icon") - , _hc - , dr.GetString("alias") - , dr.GetString("thumbnail") - , dr.GetString("description") - , null - , dr.GetInt("contentTypeId") - , dr.GetInt("templateId") - , dr.GetBoolean("isContainer") - ); - - // initialize content object - InitializeContent(dr.GetInt("ContentType"), dr.GetGuid("versionId"), - dr.GetDateTime("versionDate"), dr.GetString("icon")); - - // initialize final document properties - DateTime tmpReleaseDate = new DateTime(); - DateTime tmpExpireDate = new DateTime(); - if (!dr.IsNull("releaseDate")) - tmpReleaseDate = dr.GetDateTime("releaseDate"); - if (!dr.IsNull("expireDate")) - tmpExpireDate = dr.GetDateTime("expireDate"); - - InitializeDocument( - new User(dr.GetInt("nodeUser"), true), - new User(dr.GetInt("documentUser"), true), - dr.GetString("documentText"), - dr.GetInt("templateId"), - tmpReleaseDate, - tmpExpireDate, - dr.GetDateTime("updateDate"), - dr.GetBoolean("published") - ); - } - } - }*/ } internal Document(IContent content) : base(content) @@ -404,9 +342,9 @@ namespace umbraco.cms.businesslogic.web } //Create a new IContent object based on the passed in DocumentType's alias, set the name and save it - IContent content = ServiceContext.Current.ContentService.CreateContent(ParentId, dct.Alias, u.Id); + IContent content = ApplicationContext.Current.Services.ContentService.CreateContent(ParentId, dct.Alias, u.Id); content.Name = Name; - ServiceContext.Current.ContentService.Save(content); + ApplicationContext.Current.Services.ContentService.Save(content); //read the whole object from the db Document d = new Document(content); @@ -429,19 +367,13 @@ namespace umbraco.cms.businesslogic.web /// /// /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetById()", false)] public static bool IsDocument(int nodeId) { bool isDoc = false; - using (IRecordsReader dr = - SqlHelper.ExecuteReader(string.Format("select nodeId from cmsDocument where nodeId = @id"), - SqlHelper.CreateParameter("@id", nodeId))) - { - if (dr.Read()) - { - isDoc = true; - } - } + var content = ApplicationContext.Current.Services.ContentService.GetById(nodeId); + isDoc = content != null; return isDoc; } @@ -453,7 +385,7 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetRootContent()", false)] public static Document[] GetRootDocuments() { - var content = ServiceContext.Current.ContentService.GetRootContent(); + var content = ApplicationContext.Current.Services.ContentService.GetRootContent(); return content.Select(c => new Document(c)).ToArray(); } @@ -463,10 +395,10 @@ namespace umbraco.cms.businesslogic.web { return CountSubs(parentId); } - else - { - return SqlHelper.ExecuteScalar("SELECT COUNT(*) FROM (select distinct umbracoNode.id from umbracoNode INNER JOIN cmsDocument ON cmsDocument.published = 1 and cmsDocument.nodeId = umbracoNode.id WHERE ','+path+',' LIKE '%," + parentId.ToString() + ",%') t"); - } + + return ApplicationContext.Current.DatabaseContext.Database.ExecuteScalar( + "SELECT COUNT(*) FROM (select distinct umbracoNode.id from umbracoNode INNER JOIN cmsDocument ON cmsDocument.published = 1 and cmsDocument.nodeId = umbracoNode.id WHERE ','+path+',' LIKE '%," + + parentId.ToString() + ",%') t"); } /// @@ -478,20 +410,20 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.DeleteContentOfType()", false)] public static void DeleteFromType(DocumentType dt) { - ServiceContext.Current.ContentService.DeleteContentOfType(dt.Id); + ApplicationContext.Current.Services.ContentService.DeleteContentOfType(dt.Id); } [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentOfContentType()", false)] public static IEnumerable GetDocumentsOfDocumentType(int docTypeId) { - var contents = ServiceContext.Current.ContentService.GetContentOfContentType(docTypeId); + var contents = ApplicationContext.Current.Services.ContentService.GetContentOfContentType(docTypeId); return contents.Select(x => new Document(x)).ToArray(); } public static void RemoveTemplateFromDocument(int templateId) { - SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = NULL where templateId = @templateId", - SqlHelper.CreateParameter("@templateId", templateId)); + ApplicationContext.Current.DatabaseContext.Database.Execute( + "update cmsDocument set templateId = NULL where templateId = @TemplateId", new {TemplateId = templateId}); } /// @@ -502,7 +434,7 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetChildren()", false)] public static Document[] GetChildrenForTree(int NodeId) { - var children = ServiceContext.Current.ContentService.GetChildren(NodeId); + var children = ApplicationContext.Current.Services.ContentService.GetChildren(NodeId); var list = children.Select(x => new Document(x)); return list.ToArray(); } @@ -510,11 +442,11 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetChildrenByName()", false)] public static List GetChildrenBySearch(int NodeId, string searchString) { - var children = ServiceContext.Current.ContentService.GetChildrenByName(NodeId, searchString); + var children = ApplicationContext.Current.Services.ContentService.GetChildrenByName(NodeId, searchString); return children.Select(x => new Document(x)).ToList(); } - + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.RePublishAll()", false)] public static void RePublishAll() { XmlDocument xd = new XmlDocument(); @@ -569,7 +501,7 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentForExpiration()", false)] public static Document[] GetDocumentsForExpiration() { - var contents = ServiceContext.Current.ContentService.GetContentForExpiration(); + var contents = ApplicationContext.Current.Services.ContentService.GetContentForExpiration(); return contents.Select(x => new Document(x)).ToArray(); } @@ -580,7 +512,7 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetContentForRelease()", false)] public static Document[] GetDocumentsForRelease() { - var contents = ServiceContext.Current.ContentService.GetContentForRelease(); + var contents = ApplicationContext.Current.Services.ContentService.GetContentForRelease(); return contents.Select(x => new Document(x)).ToArray(); } @@ -650,22 +582,6 @@ namespace umbraco.cms.businesslogic.web } } - /// - /// The current HTTPContext - /// - [Obsolete("DO NOT USE THIS! Get the HttpContext via regular ASP.Net methods instead")] - public HttpContext HttpContext - { - set { /*THERE IS NO REASON TO DO THIS. _httpContext = value; */} - get - { - //if (_httpContext == null) - // _httpContext = HttpContext.Current; - //return _httpContext; - return System.Web.HttpContext.Current; - } - } - /// /// Gets or sets a value indicating whether the document is published. /// @@ -753,13 +669,6 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); { _release = value; Content.ReleaseDate = value; - /*if (_release.Year != 1 || _release.Month != 1 || _release.Day != 1) - SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version)); - else - SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = NULL where versionId = @versionId", - SqlHelper.CreateParameter("@versionId", Version));*/ } } @@ -774,13 +683,6 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); { _expire = value; Content.ExpireDate = value; - /*if (_expire.Year != 1 || _expire.Month != 1 || _expire.Day != 1) - SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = @value where versionId=@versionId", - SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version)); - else - SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = NULL where versionId=@versionId", - SqlHelper.CreateParameter("@versionId", Version));*/ } } @@ -807,21 +709,9 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); } else { - var template = ServiceContext.Current.FileService.GetTemplate(value); + var template = ApplicationContext.Current.Services.FileService.GetTemplate(value); Content.Template = template; } - /*if (value == 0) - { - SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", DBNull.Value), - SqlHelper.CreateParameter("@versionId", Version)); - } - else - { - SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", _template), - SqlHelper.CreateParameter("@versionId", Version)); - }*/ } } @@ -878,8 +768,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Publish()", false)] public void Publish(User u) { - ServiceContext.Current.ContentService.Publish(Content, u.Id, true); - //PublishWithResult(u); + ApplicationContext.Current.Services.ContentService.Publish(Content, u.Id, true); } /// @@ -899,48 +788,9 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - var result = ServiceContext.Current.ContentService.Publish(Content, u.Id, true); + var result = ApplicationContext.Current.Services.ContentService.Publish(Content, u.Id, true); _published = result; - // make a lookup to see if template is 0 as the template is not initialized in the optimized - // Document.Children method which is used in PublishWithChildrenWithResult methhod - /*if (_template == 0) - { - _template = new DocumentType(this.ContentType.Id).DefaultTemplate; - } - - _published = true; - DateTime versionDate = DateTime.Now; - string tempVersion = Version.ToString(); - Guid newVersion = createNewVersion(versionDate); - - Log.Add(LogTypes.Publish, u, Id, ""); - - //PPH make sure that there is only 1 newest node, this is important in regard to schedueled publishing... - SqlHelper.ExecuteNonQuery("update cmsDocument set newest = 0 where nodeId = " + Id); - - SqlHelper.ExecuteNonQuery("insert into cmsDocument (newest, nodeId, published, documentUser, versionId, updateDate, Text, TemplateId) values (1,@id, 0, @userId, @versionId, @updateDate, @text, @template)", - SqlHelper.CreateParameter("@id", Id), - SqlHelper.CreateParameter("@template", _template > 0 ? (object)_template : (object)DBNull.Value), //pass null in if the template doesn't have a valid id - SqlHelper.CreateParameter("@userId", u.Id), - SqlHelper.CreateParameter("@versionId", newVersion), - SqlHelper.CreateParameter("@updateDate", versionDate), - SqlHelper.CreateParameter("@text", Text)); - - SqlHelper.ExecuteNonQuery("update cmsDocument set published = 0 where nodeId = " + Id); - SqlHelper.ExecuteNonQuery("update cmsDocument set published = 1, newest = 0 where versionId = @versionId", - SqlHelper.CreateParameter("@versionId", tempVersion)); - - // update release and expire dates - Document newDoc = new Document(Id, newVersion); - if (ReleaseDate != new DateTime()) - newDoc.ReleaseDate = ReleaseDate; - if (ExpireDate != new DateTime()) - newDoc.ExpireDate = ExpireDate; - - // Update xml in db using the new document (has correct version date) - newDoc.XmlGenerate(new XmlDocument());*/ - FireAfterPublish(e); return result; @@ -954,21 +804,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.PublishWithChildren()", false)] public bool PublishWithChildrenWithResult(User u) { - return ServiceContext.Current.ContentService.PublishWithChildren(Content, u.Id, true); - - /*if (PublishWithResult(u)) - { - foreach (cms.businesslogic.web.Document dc in Children.ToList()) - { - dc.PublishWithChildrenWithResult(u); - } - } - else - { - return false; - } - - return true;*/ + return ApplicationContext.Current.Services.ContentService.PublishWithChildren(Content, u.Id, true); } /// @@ -985,7 +821,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - Content = ServiceContext.Current.ContentService.Rollback(Id, VersionId, u.Id); + Content = ApplicationContext.Current.Services.ContentService.Rollback(Id, VersionId, u.Id); FireAfterRollBack(e); } @@ -1005,30 +841,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - var published = ServiceContext.Current.ContentService.PublishWithChildren(Content, u.Id, true); - - /*_published = true; - string tempVersion = Version.ToString(); - DateTime versionDate = DateTime.Now; - Guid newVersion = createNewVersion(versionDate); - - SqlHelper.ExecuteNonQuery("insert into cmsDocument (nodeId, published, documentUser, versionId, updateDate, Text) values (" + - Id + ", 0, " + u.Id + - ", @versionId, @text)", - SqlHelper.CreateParameter("@versionId", newVersion), - SqlHelper.CreateParameter("@updateDate", versionDate), - SqlHelper.CreateParameter("@text", Text)); - - SqlHelper.ExecuteNonQuery("update cmsDocument set published = 0 where nodeId = " + Id); - SqlHelper.ExecuteNonQuery("update cmsDocument set published = 1 where versionId = @versionId", SqlHelper.CreateParameter("@versionId", tempVersion)); - - LogHelper.Debug("PublishWithSubs: " + newVersion.ToString() + " - " + Id.ToString()); - - // Update xml in db - XmlGenerate(new XmlDocument()); - - foreach (Document dc in Children.ToList()) - dc.PublishWithSubs(u);*/ + var published = ApplicationContext.Current.Services.ContentService.PublishWithChildren(Content, u.Id, true); FireAfterPublish(e); } @@ -1043,10 +856,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - //SqlHelper.ExecuteNonQuery(string.Format("update cmsDocument set published = 0 where nodeId = {0}", Id)); - //_published = false; - - ServiceContext.Current.ContentService.UnPublish(Content, 0, true); + ApplicationContext.Current.Services.ContentService.UnPublish(Content, 0, true); FireAfterUnPublish(e); } @@ -1063,7 +873,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - ServiceContext.Current.ContentService.Save(Content); + ApplicationContext.Current.Services.ContentService.Save(Content); base.Save(); // update preview xml @@ -1077,7 +887,6 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); public bool HasPublishedVersion() { return Content.HasPublishedVersion(); - //return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); } /// @@ -1086,11 +895,10 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// then this is considered a change. /// /// + [Obsolete("Deprecated, Instead of calling this just check if the latest version of the content is published", false)] public bool HasPendingChanges() { return Content.Published == false; - //double timeDiff = new TimeSpan(UpdateDate.Ticks - VersionDate.Ticks).TotalMilliseconds; - //return timeDiff > 2000; } /// @@ -1100,7 +908,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetVersions()", false)] public DocumentVersionList[] GetVersions() { - var versions = ServiceContext.Current.ContentService.GetVersions(Id); + var versions = ApplicationContext.Current.Services.ContentService.GetVersions(Id); return versions.Select(x => new DocumentVersionList(x.Version, x.UpdateDate, x.Name, User.GetUser(x.CreatorId))) .ToArray(); @@ -1113,7 +921,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetPublishedVersion()", false)] public DocumentVersionList GetPublishedVersion() { - var version = ServiceContext.Current.ContentService.GetPublishedVersion(Id); + var version = ApplicationContext.Current.Services.ContentService.GetPublishedVersion(Id); if (version == null) return null; @@ -1124,7 +932,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// /// /// Returns a breadcrumlike path for the document like: /ancestorname/ancestorname - [Obsolete("Method is not used anywhere, so its marked for deletion", false)] + [Obsolete("Method is not used anywhere, so its marked for deletion")] public string GetTextPath() { string tempPath = ""; @@ -1168,7 +976,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { // Make the new document - var content = ServiceContext.Current.ContentService.Copy(Content, CopyTo, RelateToOrignal, u.Id); + var content = ApplicationContext.Current.Services.ContentService.Copy(Content, CopyTo, RelateToOrignal, u.Id); newDoc = new Document(content); e.NewDocument = newDoc; @@ -1191,6 +999,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// With either move the document to the trash or permanently remove it from the database. /// /// flag to set whether or not to completely remove it from the database or just send to trash + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.Delete() or Umbraco.Core.Services.ContentService.MoveToRecycleBin()", false)] public void delete(bool deletePermanently) { if (!deletePermanently) @@ -1207,11 +1016,12 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// Returns all decendants of the current document /// /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetDescendants()", false)] public override IEnumerable GetDescendants() { var descendants = Content == null - ? ServiceContext.Current.ContentService.GetDescendants(Id) - : ServiceContext.Current.ContentService.GetDescendants(Content); + ? ApplicationContext.Current.Services.ContentService.GetDescendants(Id) + : ApplicationContext.Current.Services.ContentService.GetDescendants(Content); return descendants.Select(x => new Document(x.Id, true)); } @@ -1221,6 +1031,7 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); /// /// The source xmldocument /// The previous xmlrepresentation of the document + [Obsolete("Deprecated, Doesn't appear to be used anywhere", false)] public void XmlNodeRefresh(XmlDocument xd, ref XmlNode x) { x.Attributes.RemoveAll(); @@ -1413,8 +1224,8 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); protected override void setupNode() { var content = Version == Guid.Empty - ? ServiceContext.Current.ContentService.GetById(Id) - : ServiceContext.Current.ContentService.GetByIdVersion(Id, Version); + ? ApplicationContext.Current.Services.ContentService.GetById(Id) + : ApplicationContext.Current.Services.ContentService.GetByIdVersion(Id, Version); if(content == null) throw new ArgumentException(string.Format("No Document exists with id '{0}'", Id)); @@ -1576,12 +1387,12 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); if (Content != null) { - ServiceContext.Current.ContentService.Delete(Content); + ApplicationContext.Current.Services.ContentService.Delete(Content); } else { - Content = ServiceContext.Current.ContentService.GetById(Id); - ServiceContext.Current.ContentService.Delete(Content); + Content = ApplicationContext.Current.Services.ContentService.GetById(Id); + ApplicationContext.Current.Services.ContentService.Delete(Content); } //Keeping the base.delete() as it looks to be clear 'private/internal cache' @@ -1608,12 +1419,12 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); UnPublish(); if (Content != null) { - ServiceContext.Current.ContentService.MoveToRecycleBin(Content); + ApplicationContext.Current.Services.ContentService.MoveToRecycleBin(Content); } else { - Content = ServiceContext.Current.ContentService.GetById(Id); - ServiceContext.Current.ContentService.MoveToRecycleBin(Content); + Content = ApplicationContext.Current.Services.ContentService.GetById(Id); + ApplicationContext.Current.Services.ContentService.MoveToRecycleBin(Content); } FireAfterMoveToTrash(e); } diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index a0aaa6757a..ecbd84112b 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -118,7 +118,7 @@ namespace umbraco.cms.businesslogic.web { try { - var contentType = ServiceContext.Current.ContentTypeService.GetContentType(Alias); + var contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(Alias); return new DocumentType(contentType.Id); /*return @@ -144,7 +144,7 @@ namespace umbraco.cms.businesslogic.web DocumentType newDt = new DocumentType(n.Id);*/ var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text}; - ServiceContext.Current.ContentTypeService.Save(contentType); + ApplicationContext.Current.Services.ContentTypeService.Save(contentType); var newDt = new DocumentType(contentType.Id); //event @@ -165,7 +165,7 @@ namespace umbraco.cms.businesslogic.web public static List GetAllAsList() { - var contentTypes = ServiceContext.Current.ContentTypeService.GetAllContentTypes(); + var contentTypes = ApplicationContext.Current.Services.ContentTypeService.GetAllContentTypes(); var documentTypes = contentTypes.Select(x => new DocumentType(x.Id)); /*using (IRecordsReader dr = @@ -209,7 +209,7 @@ namespace umbraco.cms.businesslogic.web { if (!_hasChildrenInitialized) { - HasChildren = ServiceContext.Current.ContentTypeService.HasChildren(Id); + HasChildren = ApplicationContext.Current.Services.ContentTypeService.HasChildren(Id); //HasChildren = SqlHelper.ExecuteScalar("select count(childContentTypeId) as tmp from cmsContentType2ContentType where parentContentTypeId = @id", SqlHelper.CreateParameter("@id", Id)) > 0; } return _hasChildren; @@ -487,7 +487,7 @@ namespace umbraco.cms.businesslogic.web protected override void setupNode() { - _contentType = ServiceContext.Current.ContentTypeService.GetContentType(Id); + _contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(Id); foreach (var template in _contentType.AllowedTemplates) { diff --git a/src/umbraco.cms/businesslogic/workflow/Notification.cs b/src/umbraco.cms/businesslogic/workflow/Notification.cs index 8240efa835..e5f8f8003a 100644 --- a/src/umbraco.cms/businesslogic/workflow/Notification.cs +++ b/src/umbraco.cms/businesslogic/workflow/Notification.cs @@ -80,7 +80,7 @@ namespace umbraco.cms.businesslogic.workflow // build summary var summary = new StringBuilder(); - Property[] props = documentObject.getProperties; + var props = documentObject.GenericProperties; foreach (Property p in props) { // check if something was changed and display the changes otherwise display the fields diff --git a/src/umbraco.webservices/documents/documentService.cs b/src/umbraco.webservices/documents/documentService.cs index caea93c368..6292c02d6b 100644 --- a/src/umbraco.webservices/documents/documentService.cs +++ b/src/umbraco.webservices/documents/documentService.cs @@ -293,7 +293,7 @@ namespace umbraco.webservices.documents carrier.Published = doc.Published; carrier.HasChildren = doc.HasChildren; - var props = doc.getProperties; + var props = doc.GenericProperties; foreach (umbraco.cms.businesslogic.property.Property prop in props) { documentProperty carrierprop = new documentProperty(); diff --git a/src/umbraco.webservices/media/mediaService.cs b/src/umbraco.webservices/media/mediaService.cs index 1d62141bf5..e4ca16996c 100644 --- a/src/umbraco.webservices/media/mediaService.cs +++ b/src/umbraco.webservices/media/mediaService.cs @@ -278,7 +278,7 @@ namespace umbraco.webservices.media carrier.ParentId = -1; } - foreach (Property p in m.getProperties) + foreach (Property p in m.GenericProperties) { mediaProperty carrierprop = new mediaProperty(); diff --git a/src/umbraco.webservices/members/memberService.cs b/src/umbraco.webservices/members/memberService.cs index 48fd0748d9..269cf8a4dc 100644 --- a/src/umbraco.webservices/members/memberService.cs +++ b/src/umbraco.webservices/members/memberService.cs @@ -216,7 +216,7 @@ namespace umbraco.webservices.members } // Loading properties to carrier - var props = member.getProperties; + var props = member.GenericProperties; foreach (umbraco.cms.businesslogic.property.Property prop in props) { memberProperty carrierprop = new memberProperty(); From 806c2a7ea4313b794474686c365e381e7ef7d505 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Mon, 17 Dec 2012 15:07:08 -0100 Subject: [PATCH 14/35] Refactoring legacy Content, Property and propertytype though still a WIP. --- src/umbraco.cms/businesslogic/Content.cs | 29 ++++++++-------- .../businesslogic/Property/Property.cs | 34 +++++++++++++++---- .../propertytype/propertytype.cs | 23 +++++++++++-- src/umbraco.cms/businesslogic/web/Document.cs | 22 +++++++++++- 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index fb393e115a..a083d4f1d7 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -91,18 +91,13 @@ namespace umbraco.cms.businesslogic [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.GetByIdVersion() or Umbraco.Core.Services.MediaService.GetByIdVersion()", false)] public static Content GetContentFromVersion(Guid version) { - int id = - ApplicationContext.Current.DatabaseContext.Database.ExecuteScalar( - "Select ContentId from cmsContentVersion where versionId = @VersionId", new {VersionId = version}); - - var content = ApplicationContext.Current.Services.ContentService.GetByIdVersion(id, version); + var content = ApplicationContext.Current.Services.ContentService.GetByVersion(version); if (content != null) { return new Content(content); } - //TODO Change to use GetByIdVersion once that method has been implemented in the MediaService - var media = ApplicationContext.Current.Services.MediaService.GetById(id); + var media = ApplicationContext.Current.Services.MediaService.GetByVersion(version); return new Content(media); } @@ -285,7 +280,7 @@ namespace umbraco.cms.businesslogic /// /// Propertyalias (defined in the documenttype) /// The property with the given alias - public Property getProperty(string alias) + public virtual Property getProperty(string alias) { ContentType ct = this.ContentType; if (ct == null) @@ -301,7 +296,7 @@ namespace umbraco.cms.businesslogic /// /// PropertyType /// The property with the given propertytype - public Property getProperty(PropertyType pt) + public virtual Property getProperty(PropertyType pt) { EnsureProperties(); @@ -318,7 +313,7 @@ namespace umbraco.cms.businesslogic /// The PropertyType of the Property /// The version of the document on which the property should be add'ed /// The new Property - public Property addProperty(PropertyType pt, Guid versionId) + public virtual Property addProperty(PropertyType pt, Guid versionId) { ClearLoadedProperties(); @@ -486,6 +481,7 @@ namespace umbraco.cms.businesslogic if (_contentType == null) _contentType = ContentType.GetContentType(InitContentType); + _version = InitVersion; _versionDate = InitVersionDate; _contentTypeIcon = InitContentTypeIcon; @@ -500,12 +496,9 @@ namespace umbraco.cms.businesslogic SqlHelper.ExecuteNonQuery("insert into cmsContent (nodeId,ContentType) values (" + this.Id + "," + ct.Id + ")"); createNewVersion(DateTime.Now); } - - - + /// - /// Method for creating a new version of the data associated to the Content. - /// + /// Method for creating a new version of the data associated to the Content. /// /// The new version Id protected Guid createNewVersion(DateTime versionDate = default(DateTime)) @@ -657,6 +650,12 @@ namespace umbraco.cms.businesslogic { m_LoadedProperties = new Properties(); + if (_contentBase != null) + { + m_LoadedProperties.AddRange(_contentBase.Properties.Select(x => new Property(x))); + return; + } + if (this.ContentType == null) return; diff --git a/src/umbraco.cms/businesslogic/Property/Property.cs b/src/umbraco.cms/businesslogic/Property/Property.cs index 1d88e4f8ff..6a8f9f92fd 100644 --- a/src/umbraco.cms/businesslogic/Property/Property.cs +++ b/src/umbraco.cms/businesslogic/Property/Property.cs @@ -1,12 +1,12 @@ using System; -using System.Collections.Generic; -using System.Data; using System.Runtime.CompilerServices; using System.Xml; using Umbraco.Core; using Umbraco.Core.Persistence; using umbraco.DataLayer; using umbraco.BusinessLogic; +using umbraco.cms.businesslogic.datatype; +using umbraco.cms.businesslogic.propertytype; namespace umbraco.cms.businesslogic.property { @@ -16,7 +16,9 @@ namespace umbraco.cms.businesslogic.property /// public class Property { - private propertytype.PropertyType _pt; + private Umbraco.Core.Models.PropertyType _propertyType; + private Umbraco.Core.Models.Property _property; + private PropertyType _pt; private interfaces.IData _data; private int _id; @@ -42,12 +44,26 @@ namespace umbraco.cms.businesslogic.property public Property(int Id) { _id = Id; - _pt = umbraco.cms.businesslogic.propertytype.PropertyType.GetPropertyType( - SqlHelper.ExecuteScalar("select propertytypeid from cmsPropertyData where id = @id", SqlHelper.CreateParameter("@id", Id))); + _pt = PropertyType.GetPropertyType( + SqlHelper.ExecuteScalar("select propertytypeid from cmsPropertyData where id = @id", + SqlHelper.CreateParameter("@id", Id))); _data = _pt.DataTypeDefinition.DataType.Data; _data.PropertyId = Id; } + internal Property(Umbraco.Core.Models.Property property) + { + _id = property.Id; + _property = property; + _propertyType = property.PropertyType; + + var dataTypeDefinition = DataTypeDefinition.GetDataTypeDefinition(property.PropertyType.DataTypeId); + _data = dataTypeDefinition.DataType.Data; + + //Just to ensure that there is a PropertyType available + _pt = PropertyType.GetPropertyType(property.PropertyTypeId); + } + public Guid VersionId { get @@ -65,7 +81,13 @@ namespace umbraco.cms.businesslogic.property } public propertytype.PropertyType PropertyType { - get { return _pt; } + get + { + /*if (_propertyType != null) + return new PropertyType(_propertyType);*/ + + return _pt; + } } public object Value diff --git a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs index 29d17b5759..9c6c61c710 100644 --- a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs +++ b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs @@ -22,8 +22,6 @@ namespace umbraco.cms.businesslogic.propertytype { #region Declarations - private static string _connstring = GlobalSettings.DbDSN; - private static readonly object propertyTypeCacheSyncLock = new object(); private static readonly string UmbracoPropertyTypeCacheKey = "UmbracoPropertyTypeCache"; private readonly int _contenttypeid; @@ -38,6 +36,8 @@ namespace umbraco.cms.businesslogic.propertytype private int _propertyTypeGroup; private string _validationRegExp = ""; + private Umbraco.Core.Models.PropertyType _propertyType; + #endregion protected static ISqlHelper SqlHelper @@ -73,6 +73,24 @@ namespace umbraco.cms.businesslogic.propertytype } } + internal PropertyType(Umbraco.Core.Models.PropertyType propertyType) + { + _propertyType = propertyType; + + //_contenttypeid + //_propertyTypeGroup + //_tabId + + _mandatory = propertyType.Mandatory; + _sortOrder = propertyType.SortOrder; + _alias = propertyType.Alias; + _name = propertyType.Name; + _validationRegExp = propertyType.ValidationRegExp; + _DataTypeId = propertyType.DataTypeId; + _description = propertyType.Description; + + } + #endregion #region Properties @@ -112,6 +130,7 @@ namespace umbraco.cms.businesslogic.propertytype InvalidateCache(); } } + public int PropertyTypeGroup { get { return _propertyTypeGroup; } diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index d528c44cf2..b6fce2f123 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -873,6 +873,12 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { + //NOTE This seems to currently override the data set in the content control + foreach (var property in GenericProperties) + { + //Content.SetValue(property.PropertyType.Alias, property.Value); + } + ApplicationContext.Current.Services.ContentService.Save(Content); base.Save(); @@ -1219,13 +1225,27 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); #endregion + #region Public Methods - Overides Content for legacy api refactor + public override Property getProperty(string alias) + { + var prop = Content.Properties.FirstOrDefault(x => x.Alias == alias); + return new Property(prop); + } + + public override Property getProperty(propertytype.PropertyType pt) + { + var prop = Content.Properties.FirstOrDefault(x => x.Alias == pt.Alias); + return new Property(prop); + } + #endregion + #region Protected Methods [Obsolete("Deprecated", false)] protected override void setupNode() { var content = Version == Guid.Empty ? ApplicationContext.Current.Services.ContentService.GetById(Id) - : ApplicationContext.Current.Services.ContentService.GetByIdVersion(Id, Version); + : ApplicationContext.Current.Services.ContentService.GetByVersion(Version); if(content == null) throw new ArgumentException(string.Format("No Document exists with id '{0}'", Id)); From bae4352e77823154fb6a78a9fc9f83b1651152e2 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 18 Dec 2012 11:46:05 -0100 Subject: [PATCH 15/35] Refactoring the saving of properties, so that its consistent for Content, Media and Member that all use the ContentControl. Adding a clear cache call in the MediaType and DocumentType Save method to ensure the correct loading of properties/propertytypes. Adding IsPublishable method to ContentService, so we have a way to check if a content can be published depending on the state of the ancestors. --- src/Umbraco.Core/Models/Content.cs | 10 ++-- .../Repositories/ContentRepository.cs | 2 +- src/Umbraco.Core/Services/ContentService.cs | 60 +++++++++++++++++-- src/Umbraco.Core/Services/IContentService.cs | 7 +++ .../umbraco/controls/ContentControl.cs | 5 +- .../umbraco/dialogs/publish.aspx.cs | 2 +- .../umbraco/editContent.aspx.cs | 19 +----- .../umbraco/editMedia.aspx.cs | 19 +++--- .../umbraco/members/EditMember.aspx.cs | 12 ++++ src/umbraco.cms/businesslogic/Content.cs | 16 ++--- .../datatype/DataTypeDefinition.cs | 11 +++- .../businesslogic/datatype/DefaultData.cs | 2 +- src/umbraco.cms/businesslogic/media/Media.cs | 56 +++++++++++++++-- .../businesslogic/media/MediaType.cs | 4 ++ .../businesslogic/member/Member.cs | 51 ++++++++++++++++ .../propertytype/propertytype.cs | 20 ------- src/umbraco.cms/businesslogic/web/Document.cs | 30 ++-------- .../businesslogic/web/DocumentType.cs | 4 ++ 18 files changed, 226 insertions(+), 104 deletions(-) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index f53bc2b43c..43892051df 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -141,11 +141,12 @@ namespace Umbraco.Core.Models get { return _releaseDate; } set { - if(value.HasValue && value.Value > DateTime.UtcNow && Published) + //Thought this type of check would be clever, but it only seems to cause problems + /*if(value.HasValue && value.Value > DateTime.UtcNow && Published) _published = false; if (value.HasValue && value.Value < DateTime.UtcNow && !Published) - _published = true; + _published = true;*/ _releaseDate = value; OnPropertyChanged(ReleaseDateSelector); @@ -161,8 +162,9 @@ namespace Umbraco.Core.Models get { return _expireDate; } set { - if(value.HasValue && DateTime.UtcNow > value.Value && Published) - _published = false; + //Thought this type of check would be clever, but it only seems to cause problems + /*if(value.HasValue && DateTime.UtcNow > value.Value && Published) + _published = false;*/ _expireDate = value; OnPropertyChanged(ExpireDateSelector); diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index efdafa91d8..d947c1c0fa 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -260,7 +260,7 @@ namespace Umbraco.Core.Persistence.Repositories protected override void PersistUpdatedItem(IContent entity) { - //A new version should only be created if published state has changed + //A new version should only be created if published state (or language) has changed bool shouldCreateNewVersion = ((ICanBeDirty)entity).IsPropertyDirty("Published") || ((ICanBeDirty)entity).IsPropertyDirty("Language"); if (shouldCreateNewVersion) { diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index b28f8ca395..86c87d11d2 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -357,6 +357,24 @@ namespace Umbraco.Core.Services } } + /// + /// Checks if the passed in can be published based on the anscestors publish state. + /// + /// to check if anscestors are published + /// True if the Content can be published, otherwise False + public bool IsPublishable(IContent content) + { + //If the passed in content has yet to be saved we "fallback" to checking the Parent + //because if the Parent is publishable then the current content can be Saved and Published + if (content.HasIdentity == false) + { + IContent parent = GetById(content.ParentId); + return IsPublishable(parent, true); + } + + return IsPublishable(content, false); + } + /// /// Re-Publishes all Content /// @@ -445,11 +463,11 @@ namespace Umbraco.Core.Services //TODO Refactor this so omitCacheRefresh isn't exposed in the public method, but only in an internal one as its purely there for legacy reasons. //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published - if (content.ParentId != -1 && content.ParentId != -20 && HasPublishedVersion(content.ParentId) == false) + if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) { LogHelper.Info( string.Format( - "Content '{0}' with Id '{1}' could not be published because its parent is not published.", + "Content '{0}' with Id '{1}' could not be published because its parent or one of its ancestors is not published.", content.Name, content.Id)); return false; } @@ -587,11 +605,11 @@ namespace Umbraco.Core.Services if (!e.Cancel) { //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published - if (content.ParentId != -1 && content.ParentId != -20 && HasPublishedVersion(content.ParentId) == false) + if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) { LogHelper.Info( string.Format( - "Content '{0}' with Id '{1}' could not be published because its parent is not published.", + "Content '{0}' with Id '{1}' could not be published because its parent or one of its ancestors is not published.", content.Name, content.Id)); return false; } @@ -1255,6 +1273,40 @@ namespace Umbraco.Core.Services return list; } + /// + /// Checks if the passed in can be published based on the anscestors publish state. + /// + /// + /// Check current is only used when falling back to checking the Parent of non-saved content, as + /// non-saved content doesn't have a valid path yet. + /// + /// to check if anscestors are published + /// Boolean indicating whether the passed in content should also be checked for published versions + /// True if the Content can be published, otherwise False + private bool IsPublishable(IContent content, bool checkCurrent) + { + var ids = content.Path.Split(',').Select(int.Parse).ToList(); + foreach (var id in ids) + { + //If Id equals that of the recycle bin we return false because nothing in the bin can be published + if (id == -20) + return false; + + //We don't chech the System Root, so just continue + if (id == -1) continue; + + //If the current id equals that of the passed in content and if current shouldn't be checked we skip it. + if (checkCurrent == false && id == content.Id) continue; + + //Check if the content for the current id has a published version - escape the loop if we encounter content with no published version + bool hasPublishedVersion = HasPublishedVersion(id); + if (hasPublishedVersion == false) + return false; + } + + return true; + } + /// /// Updates a content object with the User (id), who created the content. /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index e2c08418d6..0869af4638 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -285,5 +285,12 @@ namespace Umbraco.Core.Services /// Optional Id of the User copying the Content /// The newly created object IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = -1); + + /// + /// Checks if the passed in can be published based on the anscestors publish state. + /// + /// to check if anscestors are published + /// True if the Content can be published, otherwise False + bool IsPublishable(IContent content); } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs index 68c6a18c9c..bd24324bcf 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs @@ -132,7 +132,6 @@ namespace umbraco.controls // ge : had a bit of a corrupt db and got weird NRE errors so rewrote this to catch the error and rethrow with detail foreach (PropertyType propertyType in tab.GetPropertyTypes(_content.ContentType.Id)) { - // table.Rows.Add(addControl(_content.getProperty(editPropertyType.Alias), tp)); var property = _content.getProperty(propertyType); if (property != null && tabPage != null) { @@ -246,9 +245,9 @@ namespace umbraco.controls } } - foreach (var type in DataTypes) + foreach (var property in DataTypes) { - type.Value.DataEditor.Save(); + property.Value.DataEditor.Save(); } if (!string.IsNullOrEmpty(NameTxt.Text)) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs index 9feee1ecd9..d078c60e7b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs @@ -32,7 +32,7 @@ namespace umbraco.dialogs cms.businesslogic.web.Document d = new cms.businesslogic.web.Document(nodeId); pageName = d.Text; - if (d.Level > 1 && !(new cms.businesslogic.web.Document(d.ParentId).PathPublished)) + if (d.Level > 1 && d.PathPublished == false) { TheForm.Visible = false; theEnd.Visible = true; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index abc9179108..0ee05709e7 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -1,27 +1,12 @@ using System; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Web; -using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; -using System.Reflection; using umbraco.BusinessLogic.Actions; -using umbraco.cms.businesslogic.language; -using umbraco.cms.helpers; using umbraco.IO; -using umbraco.uicontrols; using umbraco.uicontrols.DatePicker; using umbraco.BusinessLogic; -using umbraco.presentation.preview; using umbraco.cms.businesslogic.web; using umbraco.presentation; -using umbraco.cms.businesslogic.skinning; -using System.Collections.Generic; using System.Linq; using Image = System.Web.UI.WebControls.Image; @@ -297,7 +282,7 @@ namespace umbraco.cms.presentation //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). foreach (var item in cControl.DataTypes) { - _document.Content.SetValue(item.Key, item.Value.Data.Value); + _document.getProperty(item.Key).Value = item.Value.Data.Value; } // Run Handler @@ -326,7 +311,7 @@ namespace umbraco.cms.presentation { if (Page.IsValid) { - if (_document.Level == 1 || new cms.businesslogic.web.Document(_document.Parent.Id).PathPublished) + if (_document.Level == 1 || _document.PathPublished) { Trace.Warn("before d.publish"); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs index 27e5d38e54..aadd17841b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs @@ -1,16 +1,7 @@ using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Web; -using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; - using System.Xml; -using umbraco.cms.helpers; using umbraco.cms.businesslogic.datatype.controls; using System.Collections.Generic; using System.Linq; @@ -120,6 +111,16 @@ namespace umbraco.cms.presentation tp.ErrorControl.Visible = false; } } + + //The value of the properties has been set on IData through IDataEditor in the ContentControl + //so we need to 'retrieve' that value and set it on the property of the new IContent object. + //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property + //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). + foreach (var item in tmp.DataTypes) + { + _media.getProperty(item.Key).Value = item.Value.Data.Value; + } + _media.Save(); this.updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString(); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs index af928011d7..f682431a92 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs @@ -157,6 +157,7 @@ namespace umbraco.cms.presentation.members // Groups foreach (ListItem li in _memberGroups.Items) + { if (("," + _memberGroups.Value + ",").IndexOf("," + li.Value + ",") > -1) { if (!Roles.IsUserInRole(_document.LoginName, li.Value)) @@ -166,6 +167,17 @@ namespace umbraco.cms.presentation.members { Roles.RemoveUserFromRole(_document.LoginName, li.Value); } + } + + //The value of the properties has been set on IData through IDataEditor in the ContentControl + //so we need to 'retrieve' that value and set it on the property of the new IContent object. + //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property + //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). + foreach (var item in tmp.DataTypes) + { + _document.getProperty(item.Key).Value = item.Value.Data.Value; + } + // refresh cache _document.XmlGenerate(new System.Xml.XmlDocument()); _document.Save(); diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index a083d4f1d7..2fcf7cce96 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -282,13 +282,10 @@ namespace umbraco.cms.businesslogic /// The property with the given alias public virtual Property getProperty(string alias) { - ContentType ct = this.ContentType; - if (ct == null) - return null; - propertytype.PropertyType pt = ct.getPropertyType(alias); - if (pt == null) - return null; - return getProperty(pt); + EnsureProperties(); + + var prop = m_LoadedProperties.SingleOrDefault(x => x.PropertyType.Alias == alias); + return prop; } /// @@ -300,11 +297,8 @@ namespace umbraco.cms.businesslogic { EnsureProperties(); - var prop = m_LoadedProperties - .Where(x => x.PropertyType.Id == pt.Id) - .SingleOrDefault(); + var prop = m_LoadedProperties.SingleOrDefault(x => x.PropertyType.Id == pt.Id); return prop; - } /// diff --git a/src/umbraco.cms/businesslogic/datatype/DataTypeDefinition.cs b/src/umbraco.cms/businesslogic/datatype/DataTypeDefinition.cs index 9081532ce6..a782e61a7f 100644 --- a/src/umbraco.cms/businesslogic/datatype/DataTypeDefinition.cs +++ b/src/umbraco.cms/businesslogic/datatype/DataTypeDefinition.cs @@ -22,8 +22,10 @@ namespace umbraco.cms.businesslogic.datatype #region Private fields private Guid _controlId; - private static Guid _objectType = new Guid("30a2a501-1978-4ddb-a57b-f7efed43ba3c"); - #endregion + private static Guid _objectType = new Guid("30a2a501-1978-4ddb-a57b-f7efed43ba3c"); + private string _dbType; + + #endregion #region Constructors @@ -74,6 +76,10 @@ namespace umbraco.cms.businesslogic.datatype _controlId = value.Id; } } + internal string DbType + { + get { return _dbType; } + } #endregion #region Public methods @@ -330,6 +336,7 @@ namespace umbraco.cms.businesslogic.datatype if (dr.Read()) { _controlId = dr.GetGuid("controlId"); + _dbType = dr.GetString("dbType"); } else throw new ArgumentException("No dataType with id = " + this.Id.ToString() + " found"); diff --git a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs index d450c5d0df..ece234542e 100644 --- a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs +++ b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; using umbraco.DataLayer; @@ -101,7 +102,6 @@ namespace umbraco.cms.businesslogic.datatype } } - #region IData Members /// diff --git a/src/umbraco.cms/businesslogic/media/Media.cs b/src/umbraco.cms/businesslogic/media/Media.cs index 5086077faf..6d9c1a777f 100644 --- a/src/umbraco.cms/businesslogic/media/Media.cs +++ b/src/umbraco.cms/businesslogic/media/Media.cs @@ -1,14 +1,11 @@ using System; -using System.IO; -using umbraco.BusinessLogic.Actions; +using Umbraco.Core; +using Umbraco.Core.Models.Rdbms; using umbraco.DataLayer; using System.Collections; using System.Collections.Generic; -using umbraco.IO; using System.Xml; using System.Linq; -using umbraco.interfaces; -using umbraco.cms.businesslogic.datatype.controls; namespace umbraco.cms.businesslogic.media { @@ -202,6 +199,55 @@ namespace umbraco.cms.businesslogic.media if (!e.Cancel) { + var db = ApplicationContext.Current.DatabaseContext.Database; + using (var transaction = db.GetTransaction()) + { + foreach (var property in GenericProperties) + { + var poco = new PropertyDataDto + { + Id = property.Id, + PropertyTypeId = property.PropertyType.Id, + NodeId = Id, + VersionId = property.VersionId + }; + if (property.Value != null) + { + string dbType = property.PropertyType.DataTypeDefinition.DbType; + if (dbType.Equals("dataInt")) + { + int value = 0; + if (int.TryParse(property.Value.ToString(), out value)) + { + poco.Integer = value; + } + } + else if (dbType.Equals("dataDate")) + { + poco.Date = DateTime.Parse(property.Value.ToString()); + } + else if (dbType.Equals("dataNvarchar")) + { + poco.VarChar = property.Value.ToString(); + } + else + { + poco.Text = property.Value.ToString(); + } + } + bool isNew = db.IsNew(poco); + if (isNew) + { + db.Insert(poco); + } + else + { + db.Update(poco); + } + } + transaction.Complete(); + } + this.VersionDate = DateTime.Now; base.Save(); diff --git a/src/umbraco.cms/businesslogic/media/MediaType.cs b/src/umbraco.cms/businesslogic/media/MediaType.cs index 18365af868..f771f2a338 100644 --- a/src/umbraco.cms/businesslogic/media/MediaType.cs +++ b/src/umbraco.cms/businesslogic/media/MediaType.cs @@ -2,6 +2,7 @@ using System; using System.Data; using System.Runtime.CompilerServices; using System.Collections.Generic; +using Umbraco.Core.Persistence.Caching; using umbraco.DataLayer; using System.Linq; @@ -140,6 +141,9 @@ namespace umbraco.cms.businesslogic.media if (!e.Cancel) { + //Ensure that MediaTypes are reloaded from db by clearing cache + InMemoryCacheProvider.Current.Clear(); + base.Save(); FireBeforeSave(e); diff --git a/src/umbraco.cms/businesslogic/member/Member.cs b/src/umbraco.cms/businesslogic/member/Member.cs index e94ee3e642..f9ca2f18df 100644 --- a/src/umbraco.cms/businesslogic/member/Member.cs +++ b/src/umbraco.cms/businesslogic/member/Member.cs @@ -6,6 +6,8 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using System.Web; using System.Xml; +using Umbraco.Core; +using Umbraco.Core.Models.Rdbms; using umbraco.cms.businesslogic.cache; using umbraco.BusinessLogic; using umbraco.DataLayer; @@ -571,6 +573,55 @@ namespace umbraco.cms.businesslogic.member if (!e.Cancel) { + var db = ApplicationContext.Current.DatabaseContext.Database; + using (var transaction = db.GetTransaction()) + { + foreach (var property in GenericProperties) + { + var poco = new PropertyDataDto + { + Id = property.Id, + PropertyTypeId = property.PropertyType.Id, + NodeId = Id, + VersionId = property.VersionId + }; + if (property.Value != null) + { + string dbType = property.PropertyType.DataTypeDefinition.DbType; + if (dbType.Equals("dataInt")) + { + int value = 0; + if (int.TryParse(property.Value.ToString(), out value)) + { + poco.Integer = value; + } + } + else if (dbType.Equals("dataDate")) + { + poco.Date = DateTime.Parse(property.Value.ToString()); + } + else if (dbType.Equals("dataNvarchar")) + { + poco.VarChar = property.Value.ToString(); + } + else + { + poco.Text = property.Value.ToString(); + } + } + bool isNew = db.IsNew(poco); + if (isNew) + { + db.Insert(poco); + } + else + { + db.Update(poco); + } + } + transaction.Complete(); + } + // re-generate xml XmlDocument xd = new XmlDocument(); XmlGenerate(xd); diff --git a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs index 9c6c61c710..2de760e13a 100644 --- a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs +++ b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs @@ -36,8 +36,6 @@ namespace umbraco.cms.businesslogic.propertytype private int _propertyTypeGroup; private string _validationRegExp = ""; - private Umbraco.Core.Models.PropertyType _propertyType; - #endregion protected static ISqlHelper SqlHelper @@ -73,24 +71,6 @@ namespace umbraco.cms.businesslogic.propertytype } } - internal PropertyType(Umbraco.Core.Models.PropertyType propertyType) - { - _propertyType = propertyType; - - //_contenttypeid - //_propertyTypeGroup - //_tabId - - _mandatory = propertyType.Mandatory; - _sortOrder = propertyType.SortOrder; - _alias = propertyType.Alias; - _name = propertyType.Name; - _validationRegExp = propertyType.ValidationRegExp; - _DataTypeId = propertyType.DataTypeId; - _description = propertyType.Description; - - } - #endregion #region Properties diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index b6fce2f123..968e823391 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -605,19 +605,12 @@ namespace umbraco.cms.businesslogic.web /// /// Gets a value indicating whether the document and all its parents are published. /// - public bool PathPublished + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentService.IsPublishable()", false)] + public bool PathPublished { get { - // get all nodes in the path to the document, and get all matching published documents - // the difference should be zero if everything is published - // test nodeObjectType to make sure we only count _content_ nodes - int x = SqlHelper.ExecuteScalar(@"select count(node.id) - count(doc.nodeid) -from umbracoNode as node -left join cmsDocument as doc on (node.id=doc.nodeId and doc.published=1) -where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'") + @" -and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); - return (x == 0); + return ApplicationContext.Current.Services.ContentService.IsPublishable(Content); } } @@ -873,10 +866,9 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); if (!e.Cancel) { - //NOTE This seems to currently override the data set in the content control foreach (var property in GenericProperties) { - //Content.SetValue(property.PropertyType.Alias, property.Value); + Content.SetValue(property.PropertyType.Alias, property.Value); } ApplicationContext.Current.Services.ContentService.Save(Content); @@ -1225,20 +1217,6 @@ and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"); #endregion - #region Public Methods - Overides Content for legacy api refactor - public override Property getProperty(string alias) - { - var prop = Content.Properties.FirstOrDefault(x => x.Alias == alias); - return new Property(prop); - } - - public override Property getProperty(propertytype.PropertyType pt) - { - var prop = Content.Properties.FirstOrDefault(x => x.Alias == pt.Alias); - return new Property(prop); - } - #endregion - #region Protected Methods [Obsolete("Deprecated", false)] protected override void setupNode() diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index ecbd84112b..d652643700 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -4,6 +4,7 @@ using System.Text; using System.Xml; using System.Linq; using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Services; using umbraco.BusinessLogic; using umbraco.DataLayer; @@ -461,6 +462,9 @@ namespace umbraco.cms.businesslogic.web if (!e.Cancel) { + //Ensure that MediaTypes are reloaded from db by clearing cache + InMemoryCacheProvider.Current.Clear(); + base.Save(); FireAfterSave(e); } From d8da990080537b4b5e0c9709952789918530400d Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 18 Dec 2012 13:55:19 -0100 Subject: [PATCH 16/35] Refactoring legacy Media to use new Public API. --- src/umbraco.cms/businesslogic/CMSNode.cs | 2 +- src/umbraco.cms/businesslogic/ContentType.cs | 2 +- .../businesslogic/Property/Property.cs | 5 +- src/umbraco.cms/businesslogic/media/Media.cs | 182 +++++++++++------- src/umbraco.cms/businesslogic/web/Document.cs | 4 +- .../businesslogic/web/DocumentType.cs | 2 +- 6 files changed, 123 insertions(+), 74 deletions(-) diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index 2ccd66749f..f06e757bd6 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -1072,7 +1072,7 @@ order by level,sortOrder"; _isTrashed = dr.GetBoolean("trashed"); } - internal protected void PopulateCMSNodeFromContent(IContent content, Guid objectType) + internal protected void PopulateCMSNodeFromContentBase(IContentBase content, Guid objectType) { _uniqueID = content.Key; _nodeObjectType = objectType; diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index aeedc4983e..5a7a203f77 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -957,7 +957,7 @@ namespace umbraco.cms.businesslogic #region Protected Methods - internal protected void PopulateContentTypeFromContentType(IContentType contentType, Guid objectType) + internal protected void PopulateContentTypeFromContentTypeBase(IContentTypeBase contentType, Guid objectType) { _alias = contentType.Alias; _iconurl = contentType.Icon; diff --git a/src/umbraco.cms/businesslogic/Property/Property.cs b/src/umbraco.cms/businesslogic/Property/Property.cs index 6a8f9f92fd..8404081677 100644 --- a/src/umbraco.cms/businesslogic/Property/Property.cs +++ b/src/umbraco.cms/businesslogic/Property/Property.cs @@ -57,11 +57,10 @@ namespace umbraco.cms.businesslogic.property _property = property; _propertyType = property.PropertyType; - var dataTypeDefinition = DataTypeDefinition.GetDataTypeDefinition(property.PropertyType.DataTypeId); - _data = dataTypeDefinition.DataType.Data; - //Just to ensure that there is a PropertyType available _pt = PropertyType.GetPropertyType(property.PropertyTypeId); + _data = _pt.DataTypeDefinition.DataType.Data; + _data.PropertyId = Id; } public Guid VersionId diff --git a/src/umbraco.cms/businesslogic/media/Media.cs b/src/umbraco.cms/businesslogic/media/Media.cs index 6d9c1a777f..b4946301b7 100644 --- a/src/umbraco.cms/businesslogic/media/Media.cs +++ b/src/umbraco.cms/businesslogic/media/Media.cs @@ -1,5 +1,6 @@ using System; using Umbraco.Core; +using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; using umbraco.DataLayer; using System.Collections; @@ -14,9 +15,12 @@ namespace umbraco.cms.businesslogic.media /// /// By inheriting the Content class it has a generic datafields which enables custumization /// - public class Media : Content + [Obsolete("Deprecated, Use Umbraco.Core.Models.Media", false)] + public class Media : Content { #region Constants and static members + + private IMedia _media; private const string m_SQLOptimizedMany = @" select count(children.id) as children, cmsContentType.isContainer, umbracoNode.id, umbracoNode.uniqueId, umbracoNode.level, umbracoNode.parentId, umbracoNode.path, umbracoNode.sortOrder, umbracoNode.createDate, umbracoNode.nodeUser, umbracoNode.text, @@ -48,6 +52,11 @@ namespace umbraco.cms.businesslogic.media public Media(int id, bool noSetup) : base(id, noSetup) { } public Media(Guid id, bool noSetup) : base(id, noSetup) { } + + internal Media(IMedia media) : base(media) + { + SetupNode(media); + } #endregion @@ -65,16 +74,22 @@ namespace umbraco.cms.businesslogic.media /// The user creating the media /// The id of the folder under which the media is created /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.CreateMedia()", false)] public static Media MakeNew(string Name, MediaType dct, BusinessLogic.User u, int ParentId) { - Guid newId = Guid.NewGuid(); + var media = ApplicationContext.Current.Services.MediaService.CreateMedia(ParentId, dct.Alias, u.Id); + media.Name = Name; + ApplicationContext.Current.Services.MediaService.Save(media); + var tmp = new Media(media); + + /*Guid newId = Guid.NewGuid(); // Updated to match level from base node CMSNode n = new CMSNode(ParentId); int newLevel = n.Level; newLevel++; CMSNode.MakeNew(ParentId, _objectType, u.Id, newLevel, Name, newId); Media tmp = new Media(newId); - tmp.CreateContent(dct); + tmp.CreateContent(dct);*/ NewEventArgs e = new NewEventArgs(); tmp.OnNew(e); @@ -86,9 +101,13 @@ namespace umbraco.cms.businesslogic.media /// Retrieve a list of all toplevel medias and folders /// /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.GetRootMedia()", false)] public static Media[] GetRootMedias() { - Guid[] topNodeIds = CMSNode.TopMostNodeIds(_objectType); + var children = ApplicationContext.Current.Services.MediaService.GetRootMedia(); + return children.Select(x => new Media(x)).ToArray(); + + /*Guid[] topNodeIds = CMSNode.TopMostNodeIds(_objectType); Media[] retval = new Media[topNodeIds.Length]; for (int i = 0; i < topNodeIds.Length; i++) @@ -96,13 +115,16 @@ namespace umbraco.cms.businesslogic.media Media d = new Media(topNodeIds[i]); retval[i] = d; } - return retval; + return retval;*/ } + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.GetChildren()", false)] public static List GetChildrenForTree(int nodeId) { + var children = ApplicationContext.Current.Services.MediaService.GetChildren(nodeId); + return children.Select(x => new Media(x)).ToList(); - List tmp = new List(); + /*List tmp = new List(); using (IRecordsReader dr = SqlHelper.ExecuteReader( string.Format(m_SQLOptimizedMany.Trim() @@ -120,12 +142,16 @@ namespace umbraco.cms.businesslogic.media } } - return tmp; + return tmp;*/ } + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.GetMediaOfMediaType()", false)] public static IEnumerable GetMediaOfMediaType(int mediaTypeId) { - var tmp = new List(); + var children = ApplicationContext.Current.Services.MediaService.GetMediaOfMediaType(mediaTypeId); + return children.Select(x => new Media(x)).ToList(); + + /*var tmp = new List(); using (IRecordsReader dr = SqlHelper.ExecuteReader( string.Format(m_SQLOptimizedMany.Trim(), "cmsContent.contentType = @contentTypeId", "umbracoNode.sortOrder"), @@ -140,7 +166,7 @@ namespace umbraco.cms.businesslogic.media } } - return tmp.ToArray(); + return tmp.ToArray();*/ } /// @@ -149,10 +175,13 @@ namespace umbraco.cms.businesslogic.media /// Use with care. /// /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.DeleteMediaOfType()", false)] public static void DeleteFromType(MediaType dt) { + ApplicationContext.Current.Services.MediaService.DeleteMediaOfType(dt.Id); + //get all document for the document type and order by level (top level first) - var medias = Media.GetMediaOfMediaType(dt.Id) + /*var medias = Media.GetMediaOfMediaType(dt.Id) .OrderByDescending(x => x.Level); foreach (Media media in medias) @@ -168,7 +197,7 @@ namespace umbraco.cms.businesslogic.media } media.DeletePermanently(); - } + }*/ } #endregion @@ -177,12 +206,16 @@ namespace umbraco.cms.businesslogic.media /// /// Retrieve a list of all medias underneath the current /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.GetChildren()", false)] public new Media[] Children { get - { + { //return refactored optimized method - return Media.GetChildrenForTree(this.Id).ToArray(); + //return Media.GetChildrenForTree(this.Id).ToArray(); + + var children = ApplicationContext.Current.Services.MediaService.GetChildren(Id); + return children.Select(x => new Media(x)).ToArray(); } } #endregion @@ -192,6 +225,7 @@ namespace umbraco.cms.businesslogic.media /// /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.Save()", false)] public override void Save() { SaveEventArgs e = new SaveEventArgs(); @@ -199,56 +233,12 @@ namespace umbraco.cms.businesslogic.media if (!e.Cancel) { - var db = ApplicationContext.Current.DatabaseContext.Database; - using (var transaction = db.GetTransaction()) + foreach (var property in GenericProperties) { - foreach (var property in GenericProperties) - { - var poco = new PropertyDataDto - { - Id = property.Id, - PropertyTypeId = property.PropertyType.Id, - NodeId = Id, - VersionId = property.VersionId - }; - if (property.Value != null) - { - string dbType = property.PropertyType.DataTypeDefinition.DbType; - if (dbType.Equals("dataInt")) - { - int value = 0; - if (int.TryParse(property.Value.ToString(), out value)) - { - poco.Integer = value; - } - } - else if (dbType.Equals("dataDate")) - { - poco.Date = DateTime.Parse(property.Value.ToString()); - } - else if (dbType.Equals("dataNvarchar")) - { - poco.VarChar = property.Value.ToString(); - } - else - { - poco.Text = property.Value.ToString(); - } - } - bool isNew = db.IsNew(poco); - if (isNew) - { - db.Insert(poco); - } - else - { - db.Update(poco); - } - } - transaction.Complete(); + _media.SetValue(property.PropertyType.Alias, property.Value); } - this.VersionDate = DateTime.Now; + ApplicationContext.Current.Services.MediaService.Save(_media); base.Save(); @@ -269,6 +259,7 @@ namespace umbraco.cms.businesslogic.media /// /// Moves the media to the trash /// + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.MoveToRecycleBin()", false)] public override void delete() { MoveToTrash(); @@ -278,6 +269,7 @@ namespace umbraco.cms.businesslogic.media /// With either move the media to the trash or permanently remove it from the database. /// /// flag to set whether or not to completely remove it from the database or just send to trash + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.Delete() or Umbraco.Core.Services.MediaService.MoveToRecycleBin()", false)] public void delete(bool deletePermanently) { if (!deletePermanently) @@ -290,9 +282,13 @@ namespace umbraco.cms.businesslogic.media } } + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.GetDescendants()", false)] public override IEnumerable GetDescendants() { - var tmp = new List(); + var descendants = ApplicationContext.Current.Services.MediaService.GetDescendants(Id); + return descendants.Select(x => new Media(x)); + + /*var tmp = new List(); using (IRecordsReader dr = SqlHelper.ExecuteReader( string.Format(m_SQLOptimizedMany.Trim(), "umbracoNode.path LIKE '%," + this.Id + ",%'", "umbracoNode.level"), SqlHelper.CreateParameter("@nodeObjectType", Media._objectType))) @@ -305,12 +301,31 @@ namespace umbraco.cms.businesslogic.media } } - return tmp.ToArray(); + return tmp.ToArray();*/ } #endregion #region Protected methods + protected override void setupNode() + { + if (Id == -1) + { + base.setupNode(); + return; + } + + var media = Version == Guid.Empty + ? ApplicationContext.Current.Services.MediaService.GetById(Id) + : ApplicationContext.Current.Services.MediaService.GetByVersion(Version); + + if (media == null) + throw new ArgumentException(string.Format("No Media exists with id '{0}'", Id)); + + SetupNode(media); + } + + [Obsolete("Deprecated, This method is no longer used")] protected void PopulateMediaFromReader(IRecordsReader dr) { var hc = dr.GetInt("children") > 0; @@ -334,6 +349,19 @@ namespace umbraco.cms.businesslogic.media #endregion #region Private methods + private void SetupNode(IMedia media) + { + _media = media; + + //Setting private properties from IContentBase replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() + base.PopulateCMSNodeFromContentBase(_media, _objectType); + + //If the version is empty we update with the latest version from the current IContent. + if (Version == Guid.Empty) + Version = _media.Version; + } + + [Obsolete("Deprecated, This method is no longer needed", false)] private void SetupMediaForTree(Guid uniqueId, int level, int parentId, int user, string path, string text, DateTime createDate, string icon, bool hasChildren, string contentTypeAlias, string contentTypeThumb, string contentTypeDesc, int? masterContentType, int contentTypeId, bool isContainer) @@ -347,6 +375,7 @@ namespace umbraco.cms.businesslogic.media /// Used internally to permanently delete the data from the database /// /// returns true if deletion isn't cancelled + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.Delete()", false)] private bool DeletePermanently() { DeleteEventArgs e = new DeleteEventArgs(); @@ -355,13 +384,23 @@ namespace umbraco.cms.businesslogic.media if (!e.Cancel) { - foreach (Media m in Children.ToList()) + /*foreach (Media m in Children.ToList()) { m.DeletePermanently(); - } + } */ // Remove all files - DeleteAssociatedMediaFiles(); + //DeleteAssociatedMediaFiles(); + + if (_media != null) + { + ApplicationContext.Current.Services.MediaService.Delete(_media); + } + else + { + var media = ApplicationContext.Current.Services.MediaService.GetById(Id); + ApplicationContext.Current.Services.MediaService.Delete(media); + } base.delete(); @@ -374,6 +413,7 @@ namespace umbraco.cms.businesslogic.media /// Used internally to move the node to the recyle bin /// /// Returns true if the move was not cancelled + [Obsolete("Deprecated, Use Umbraco.Core.Services.MediaService.MoveToRecycleBin()", false)] private bool MoveToTrash() { MoveToTrashEventArgs e = new MoveToTrashEventArgs(); @@ -381,7 +421,17 @@ namespace umbraco.cms.businesslogic.media if (!e.Cancel) { - Move((int)RecycleBin.RecycleBinType.Media); + if (_media != null) + { + ApplicationContext.Current.Services.MediaService.MoveToRecycleBin(_media); + } + else + { + var media = ApplicationContext.Current.Services.MediaService.GetById(Id); + ApplicationContext.Current.Services.MediaService.MoveToRecycleBin(media); + } + + //Move((int)RecycleBin.RecycleBinType.Media); //TODO: Now that we've moved it to trash, we need to move the actual files so they are no longer accessible //from the original URL. diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 968e823391..59d7e61ce3 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -1234,8 +1234,8 @@ namespace umbraco.cms.businesslogic.web private void setupNode(IContent content) { Content = content; - //Setting private properties from IContent replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() - base.PopulateCMSNodeFromContent(Content, _objectType); + //Setting private properties from IContentBase replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() + base.PopulateCMSNodeFromContentBase(Content, _objectType); //If the version is empty we update with the latest version from the current IContent. if (Version == Guid.Empty) diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index d652643700..eb5fe1c6ea 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -501,7 +501,7 @@ namespace umbraco.cms.businesslogic.web if(_contentType.DefaultTemplate != null) _defaultTemplate = _contentType.DefaultTemplate.Id; - base.PopulateContentTypeFromContentType(_contentType, _objectType); + base.PopulateContentTypeFromContentTypeBase(_contentType, _objectType); base.PopulateCMSNodeFromContentType(_contentType, _objectType); /*base.setupNode(); From 25354389789b2a34f1764d513852abac595a0c1d Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 18 Dec 2012 14:50:26 -0100 Subject: [PATCH 17/35] Starting refactor of DocumentType, MediaType and the base ContentType class. --- src/umbraco.cms/businesslogic/CMSNode.cs | 3 +- src/umbraco.cms/businesslogic/ContentType.cs | 14 ++-- .../businesslogic/media/MediaType.cs | 38 +++++++++- src/umbraco.cms/businesslogic/web/Document.cs | 6 +- .../businesslogic/web/DocumentType.cs | 76 +++++++------------ 5 files changed, 74 insertions(+), 63 deletions(-) diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index f06e757bd6..e16a4cd49b 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -30,6 +30,7 @@ namespace umbraco.cms.businesslogic /// The child classes are required to implement an identifier (Guid) which is used as the objecttype identifier, for /// distinguishing the different types of CMSNodes (ex. Documents/Medias/Stylesheets/documenttypes and so forth). /// + [Obsolete("Deprecated, This class will eventually be phased out", false)] public class CMSNode : BusinessLogic.console.IconI { #region Private Members @@ -1086,7 +1087,7 @@ order by level,sortOrder"; _isTrashed = content.Trashed; } - internal protected void PopulateCMSNodeFromContentType(IContentType contentType, Guid objectType) + internal protected void PopulateCMSNodeFromContentTypeBase(IContentTypeBase contentType, Guid objectType) { _uniqueID = contentType.Key; _nodeObjectType = objectType; diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 5a7a203f77..64fe8daede 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -26,6 +26,7 @@ namespace umbraco.cms.businesslogic /// Besides data definition, the ContentType also defines the sorting and grouping (in tabs) of Properties/Datafields /// on the Content and which Content (by ContentType) can be created as child to the Content of the ContentType. /// + [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType or Umbraco.Core.Models.MediaType", false)] public class ContentType : CMSNode { @@ -72,6 +73,10 @@ namespace umbraco.cms.businesslogic _isContainerContentType = isContainer.Value; } + internal ContentType(IContentTypeComposition contentType) : base(contentType) + { + } + #endregion #region Constants and static members @@ -1003,15 +1008,6 @@ namespace umbraco.cms.businesslogic } } - /// - /// Set up the internal data of the ContentType - /// - [Obsolete("Use the overriden setupNode method instead. This method now calls that method")] - protected void setupContentType() - { - setupNode(); - } - /// /// Flushes the cache. /// diff --git a/src/umbraco.cms/businesslogic/media/MediaType.cs b/src/umbraco.cms/businesslogic/media/MediaType.cs index f771f2a338..6454de5e8f 100644 --- a/src/umbraco.cms/businesslogic/media/MediaType.cs +++ b/src/umbraco.cms/businesslogic/media/MediaType.cs @@ -1,7 +1,7 @@ using System; -using System.Data; -using System.Runtime.CompilerServices; using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.Models; using Umbraco.Core.Persistence.Caching; using umbraco.DataLayer; using System.Linq; @@ -14,9 +14,9 @@ namespace umbraco.cms.businesslogic.media /// /// Due to the inheritance of the ContentType class,it enables definition of generic datafields on a Media. /// + [Obsolete("Deprecated, Use Umbraco.Core.Models.MediaType", false)] public class MediaType : ContentType { - #region Constructors /// @@ -33,6 +33,12 @@ namespace umbraco.cms.businesslogic.media public MediaType(int id, bool noSetup) : base(id, noSetup) { } + internal MediaType(IMediaType mediaType) + : base(mediaType) + { + SetupNode(mediaType); + } + #endregion #region Constants and static members @@ -41,6 +47,12 @@ namespace umbraco.cms.businesslogic.media #endregion + #region Private Members + + private IMediaType _mediaType; + + #endregion + #region Static Methods /// /// Retrieve a MediaType by it's alias @@ -170,6 +182,26 @@ namespace umbraco.cms.businesslogic.media } #endregion + #region Protected Methods + + protected override void setupNode() + { + var mediaType = ApplicationContext.Current.Services.ContentTypeService.GetMediaType(Id); + SetupNode(mediaType); + } + + #endregion + + #region Private Methods + private void SetupNode(IMediaType mediaType) + { + _mediaType = mediaType; + + base.PopulateContentTypeFromContentTypeBase(_mediaType, _objectType); + base.PopulateCMSNodeFromContentTypeBase(_mediaType, _objectType); + } + #endregion + #region Events /// diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 59d7e61ce3..104db5b13d 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -102,7 +102,7 @@ namespace umbraco.cms.businesslogic.web internal Document(IContent content) : base(content) { - setupNode(content); + SetupNode(content); } #endregion @@ -1228,10 +1228,10 @@ namespace umbraco.cms.businesslogic.web if(content == null) throw new ArgumentException(string.Format("No Document exists with id '{0}'", Id)); - setupNode(content); + SetupNode(content); } - private void setupNode(IContent content) + private void SetupNode(IContent content) { Content = content; //Setting private properties from IContentBase replacing CMSNode.setupNode() / CMSNode.PopulateCMSNodeFromReader() diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index eb5fe1c6ea..81128cda23 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -5,7 +5,6 @@ using System.Xml; using System.Linq; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Caching; -using Umbraco.Core.Services; using umbraco.BusinessLogic; using umbraco.DataLayer; using System.Collections.Generic; @@ -17,6 +16,7 @@ namespace umbraco.cms.businesslogic.web /// /// Summary description for DocumentType. /// + [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType", false)] public class DocumentType : ContentType { #region Constructors @@ -27,6 +27,11 @@ namespace umbraco.cms.businesslogic.web public DocumentType(int id, bool noSetup) : base(id, noSetup) { } + internal DocumentType(IContentType contentType) : base(contentType) + { + SetupNode(contentType); + } + #endregion #region Constants and Static members @@ -60,6 +65,7 @@ namespace umbraco.cms.businesslogic.web /// Generates the complete (simplified) XML DTD /// /// The DTD as a string + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.GetDtd()", false)] public static string GenerateDtd() { StringBuilder dtd = new StringBuilder(); @@ -74,6 +80,7 @@ namespace umbraco.cms.businesslogic.web return dtd.ToString(); } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.GetContentTypesDtd()", false)] public static string GenerateXmlDocumentType() { StringBuilder dtd = new StringBuilder(); @@ -114,19 +121,14 @@ namespace umbraco.cms.businesslogic.web return dtd.ToString(); } - + + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.GetContentType()", false)] public new static DocumentType GetByAlias(string Alias) { try { var contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(Alias); return new DocumentType(contentType.Id); - - /*return - new DocumentType( - SqlHelper.ExecuteScalar(@"SELECT nodeid from cmsContentType INNER JOIN umbracoNode on cmsContentType.nodeId = umbracoNode.id WHERE nodeObjectType=@nodeObjectType AND alias=@alias", - SqlHelper.CreateParameter("@nodeObjectType", DocumentType._objectType), - SqlHelper.CreateParameter("@alias", Alias)));*/ } catch { @@ -134,16 +136,9 @@ namespace umbraco.cms.businesslogic.web } } + [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType and Umbraco.Core.Services.ContentTypeService.Save()", false)] public static DocumentType MakeNew(User u, string Text) { - /*int ParentId = -1; - int level = 1; - Guid uniqueId = Guid.NewGuid(); - CMSNode n = MakeNew(ParentId, _objectType, u.Id, level, Text, uniqueId); - - Create(n.Id, Text, ""); - DocumentType newDt = new DocumentType(n.Id);*/ - var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text}; ApplicationContext.Current.Services.ContentTypeService.Save(contentType); var newDt = new DocumentType(contentType.Id); @@ -164,6 +159,7 @@ namespace umbraco.cms.businesslogic.web } } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.GetAllContentTypes()", false)] public static List GetAllAsList() { var contentTypes = ApplicationContext.Current.Services.ContentTypeService.GetAllContentTypes(); @@ -204,14 +200,14 @@ namespace umbraco.cms.businesslogic.web #endregion #region Public Properties + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.HasChildren()", false)] public override bool HasChildren { get { - if (!_hasChildrenInitialized) + if (_hasChildrenInitialized == false) { HasChildren = ApplicationContext.Current.Services.ContentTypeService.HasChildren(Id); - //HasChildren = SqlHelper.ExecuteScalar("select count(childContentTypeId) as tmp from cmsContentType2ContentType where parentContentTypeId = @id", SqlHelper.CreateParameter("@id", Id)) > 0; } return _hasChildren; } @@ -474,6 +470,7 @@ namespace umbraco.cms.businesslogic.web #region Protected Methods + [Obsolete("Depreated, No longer needed nor used")] protected void PopulateDocumentTypeNodeFromReader(IRecordsReader dr) { if (!dr.IsNull("templateNodeId")) @@ -491,42 +488,27 @@ namespace umbraco.cms.businesslogic.web protected override void setupNode() { - _contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(Id); - - foreach (var template in _contentType.AllowedTemplates) - { - _templateIds.Add(template.Id); - } - - if(_contentType.DefaultTemplate != null) - _defaultTemplate = _contentType.DefaultTemplate.Id; - - base.PopulateContentTypeFromContentTypeBase(_contentType, _objectType); - base.PopulateCMSNodeFromContentType(_contentType, _objectType); - - /*base.setupNode(); - - using (IRecordsReader dr = SqlHelper.ExecuteReader("Select templateNodeId, IsDefault from cmsDocumentType where contentTypeNodeId = @id", - SqlHelper.CreateParameter("@id", Id))) - { - while (dr.Read()) - { - PopulateDocumentTypeNodeFromReader(dr); - } - }*/ - + var contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(Id); + SetupNode(contentType); } #endregion #region Private Methods - - [Obsolete("Use the overridden setupNode instead. This method now calls the setupNode method")] - private void setupDocumentType() + private void SetupNode(IContentType contentType) { - setupNode(); - } + _contentType = contentType; + foreach (var template in _contentType.AllowedTemplates) + { + _templateIds.Add(template.Id); + } + if (_contentType.DefaultTemplate != null) + _defaultTemplate = _contentType.DefaultTemplate.Id; + + base.PopulateContentTypeFromContentTypeBase(_contentType, _objectType); + base.PopulateCMSNodeFromContentTypeBase(_contentType, _objectType); + } #endregion #region Events From 3742a0b7319fb3988bce7d693823b3276c424707 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 19 Dec 2012 08:50:35 -0100 Subject: [PATCH 18/35] Refactoring legacy MediaType class to use new public api. Adding remove Template method to new ContenType class. --- src/Umbraco.Core/Models/ContentType.cs | 18 ++++++ src/Umbraco.Core/Models/IContentType.cs | 7 +++ src/Umbraco.Core/Models/Rdbms/ContentDto.cs | 2 +- .../Models/Rdbms/ContentVersionDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/DocumentDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/NodeDto.cs | 2 +- .../umbraco/Trees/loadMediaTypes.cs | 22 +------ .../umbraco/create/media.ascx.cs | 7 +-- src/umbraco.cms/businesslogic/CMSNode.cs | 2 - src/umbraco.cms/businesslogic/ContentType.cs | 20 +++---- .../businesslogic/media/MediaType.cs | 59 ++++--------------- .../businesslogic/template/Template.cs | 7 +-- .../businesslogic/web/DocumentType.cs | 8 ++- 13 files changed, 57 insertions(+), 101 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 158ec4055b..e82f27c3b2 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -76,6 +76,24 @@ namespace Umbraco.Core.Models } } + /// + /// Removes a template from the list of allowed templates + /// + /// to remove + /// True if template was removed, otherwise False + public bool RemoveTemplate(ITemplate template) + { + if (DefaultTemplateId == template.Id) + DefaultTemplateId = default(int); + + var templates = AllowedTemplates.ToList(); + var remove = templates.FirstOrDefault(x => x.Id == template.Id); + var result = templates.Remove(remove); + AllowedTemplates = templates; + + return result; + } + /// /// Indicates whether a specific property on the current entity is dirty. /// diff --git a/src/Umbraco.Core/Models/IContentType.cs b/src/Umbraco.Core/Models/IContentType.cs index 5e89279755..3e61b98510 100644 --- a/src/Umbraco.Core/Models/IContentType.cs +++ b/src/Umbraco.Core/Models/IContentType.cs @@ -22,5 +22,12 @@ namespace Umbraco.Core.Models /// /// Default void SetDefaultTemplate(ITemplate template); + + /// + /// Removes a template from the list of allowed templates + /// + /// to remove + /// True if template was removed, otherwise False + bool RemoveTemplate(ITemplate template); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs index fbed397c80..fde47f410e 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("cmsContent")] [PrimaryKey("pk")] [ExplicitColumns] - public class ContentDto + internal class ContentDto { [Column("pk")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs index a7ae66df23..e63d4e27da 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("cmsContentVersion")] [PrimaryKey("id")] [ExplicitColumns] - public class ContentVersionDto + internal class ContentVersionDto { [Column("id")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs index 9b3bf5c0dd..612084812e 100644 --- a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("cmsDocument")] [PrimaryKey("versionId", autoIncrement = false)] [ExplicitColumns] - public class DocumentDto + internal class DocumentDto { [Column("nodeId")] [ForeignKey(typeof(ContentDto), Column = "nodeId")] diff --git a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs index 6b7a97891b..abf1f01ca1 100644 --- a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Rdbms [TableName("umbracoNode")] [PrimaryKey("id")] [ExplicitColumns] - public class NodeDto + internal class NodeDto { [Column("id")] [PrimaryKeyColumn(Name = "PK_structure", IdentitySeed = 1045)] diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadMediaTypes.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadMediaTypes.cs index f5af115068..670f180228 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadMediaTypes.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadMediaTypes.cs @@ -1,27 +1,7 @@ using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.IO; using System.Text; -using System.Web; -using System.Xml; -using System.Configuration; -using umbraco.BasePages; -using umbraco.BusinessLogic; using umbraco.businesslogic; -using umbraco.cms.businesslogic; -using umbraco.cms.businesslogic.cache; -using umbraco.cms.businesslogic.contentitem; -using umbraco.cms.businesslogic.datatype; -using umbraco.cms.businesslogic.language; using umbraco.cms.businesslogic.media; -using umbraco.cms.businesslogic.member; -using umbraco.cms.businesslogic.property; -using umbraco.cms.businesslogic.web; -using umbraco.interfaces; -using umbraco.DataLayer; -using umbraco.BusinessLogic.Utils; using umbraco.cms.presentation.Trees; namespace umbraco @@ -49,7 +29,7 @@ function openMediaType(id) { public override void Render(ref XmlTree tree) { - foreach (MediaType dt in MediaType.GetAll) + foreach (var dt in MediaType.GetAllAsList()) { XmlTreeNode xNode = XmlTreeNode.Create(this); xNode.NodeID = dt.Id.ToString(); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/media.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/media.ascx.cs index 2ae91676a5..d6b615316a 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/media.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/create/media.ascx.cs @@ -1,12 +1,7 @@ namespace umbraco.cms.presentation.create.controls { using System; - using System.Data; - using System.Drawing; - using System.Web; using System.Web.UI.WebControls; - using System.Web.UI.HtmlControls; - using umbraco.cms.helpers; using umbraco.BasePages; /// @@ -28,7 +23,7 @@ namespace umbraco.cms.presentation.create.controls allowedIds = c.ContentType.AllowedChildContentTypeIDs; } - foreach(cms.businesslogic.ContentType dt in cms.businesslogic.media.MediaType.GetAll) + foreach (var dt in cms.businesslogic.media.MediaType.GetAllAsList()) { ListItem li = new ListItem(); li.Text = dt.Text; diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index e16a4cd49b..af8ffb06ab 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Data; - using System.Xml; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 64fe8daede..533baf6407 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -29,7 +29,6 @@ namespace umbraco.cms.businesslogic [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType or Umbraco.Core.Models.MediaType", false)] public class ContentType : CMSNode { - #region Constructors /// @@ -67,8 +66,10 @@ namespace umbraco.cms.businesslogic _alias = alias; _iconurl = icon; _thumbnail = thumbnail; + if (masterContentType.HasValue) MasterContentType = masterContentType.Value; + if (isContainer.HasValue) _isContainerContentType = isContainer.Value; } @@ -299,6 +300,9 @@ namespace umbraco.cms.businesslogic } } + /// + /// Gets or sets the 'allow at root' boolean + /// public bool AllowAtRoot { get { return _allowAtRoot; } @@ -311,6 +315,7 @@ namespace umbraco.cms.businesslogic SqlHelper.CreateParameter("@id", Id)); } } + /// /// Gets or sets the description. /// @@ -373,16 +378,6 @@ namespace umbraco.cms.businesslogic } } - ///// - ///// Gets or sets a value indicating whether [optimized mode]. - ///// - ///// true if [optimized mode]; otherwise, false. - //public bool OptimizedMode - //{ - // get { return _optimizedMode; } - // set { _optimizedMode = value; } - //} - /// /// Human readable name/label /// @@ -962,7 +957,7 @@ namespace umbraco.cms.businesslogic #region Protected Methods - internal protected void PopulateContentTypeFromContentTypeBase(IContentTypeBase contentType, Guid objectType) + internal protected void PopulateContentTypeFromContentTypeBase(IContentTypeBase contentType) { _alias = contentType.Alias; _iconurl = contentType.Icon; @@ -1047,7 +1042,6 @@ namespace umbraco.cms.businesslogic #endregion #region Private Methods - /// /// The cache key used to cache the properties for the content type /// diff --git a/src/umbraco.cms/businesslogic/media/MediaType.cs b/src/umbraco.cms/businesslogic/media/MediaType.cs index 6454de5e8f..fe229009f9 100644 --- a/src/umbraco.cms/businesslogic/media/MediaType.cs +++ b/src/umbraco.cms/businesslogic/media/MediaType.cs @@ -59,17 +59,11 @@ namespace umbraco.cms.businesslogic.media /// /// The alias of the MediaType /// The MediaType with the alias + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.GetMediaType()", false)] public static new MediaType GetByAlias(string Alias) { - using (IRecordsReader dr = SqlHelper.ExecuteReader(@"SELECT nodeid from cmsContentType INNER JOIN umbracoNode on cmsContentType.nodeId = umbracoNode.id WHERE nodeObjectType=@nodeObjectType AND alias=@alias", - SqlHelper.CreateParameter("@nodeObjectType", MediaType._objectType), - SqlHelper.CreateParameter("@alias", Alias))) - { - if(dr.Read()) - return new MediaType(dr.GetInt("nodeid")); - else - return null; - } + var mediaType = ApplicationContext.Current.Services.ContentTypeService.GetMediaType(Alias); + return new MediaType(mediaType); } /// @@ -84,38 +78,11 @@ namespace umbraco.cms.businesslogic.media } } + [Obsolete("Deprecated, Use Umbraco.Core.Services.ContentTypeService.GetMediaType()", false)] public static IEnumerable GetAllAsList() { - - var mediaTypes = new List(); - - using (IRecordsReader dr = - SqlHelper.ExecuteReader(m_SQLOptimizedGetAll.Trim(), SqlHelper.CreateParameter("@nodeObjectType", MediaType._objectType))) - { - while (dr.Read()) - { - //check if the document id has already been added - if (mediaTypes.Where(x => x.Id == dr.Get("id")).Count() == 0) - { - //create the DocumentType object without setting up - MediaType dt = new MediaType(dr.Get("id"), true); - //populate it's CMSNode properties - dt.PopulateCMSNodeFromReader(dr); - //populate it's ContentType properties - dt.PopulateContentTypeNodeFromReader(dr); - - mediaTypes.Add(dt); - } - else - { - //we've already created the document type with this id, so we'll add the rest of it's templates to itself - var dt = mediaTypes.Where(x => x.Id == dr.Get("id")).Single(); - } - } - } - - return mediaTypes.OrderBy(x => x.Text).ToList(); - + var mediaTypes = ApplicationContext.Current.Services.ContentTypeService.GetAllMediaTypes(); + return mediaTypes.OrderBy(x => x.Name).Select(x => new MediaType(x)); } /// @@ -124,17 +91,13 @@ namespace umbraco.cms.businesslogic.media /// The Umbraco user context /// The name of the MediaType /// The new MediaType + [Obsolete("Deprecated, Use Umbraco.Core.Models.MediaType and Umbraco.Core.Services.ContentTypeService.Save()", false)] public static MediaType MakeNew(BusinessLogic.User u, string Text) { + var mediaType = new Umbraco.Core.Models.MediaType(-1) { Name = Text, Alias = Text, CreatorId = u.Id}; + ApplicationContext.Current.Services.ContentTypeService.Save(mediaType, u.Id); + var mt = new MediaType(mediaType.Id); - int ParentId = -1; - int level = 1; - Guid uniqueId = Guid.NewGuid(); - CMSNode n = CMSNode.MakeNew(ParentId, _objectType, u.Id, level, Text, uniqueId); - - ContentType.Create(n.Id, Text, ""); - - MediaType mt = new MediaType(n.Id); NewEventArgs e = new NewEventArgs(); mt.OnNew(e); @@ -197,7 +160,7 @@ namespace umbraco.cms.businesslogic.media { _mediaType = mediaType; - base.PopulateContentTypeFromContentTypeBase(_mediaType, _objectType); + base.PopulateContentTypeFromContentTypeBase(_mediaType); base.PopulateCMSNodeFromContentTypeBase(_mediaType, _objectType); } #endregion diff --git a/src/umbraco.cms/businesslogic/template/Template.cs b/src/umbraco.cms/businesslogic/template/Template.cs index 6dd45b2296..c9c30d1622 100644 --- a/src/umbraco.cms/businesslogic/template/Template.cs +++ b/src/umbraco.cms/businesslogic/template/Template.cs @@ -18,10 +18,10 @@ namespace umbraco.cms.businesslogic.template /// /// Summary description for Template. /// + //[Obsolete("Deprecated, This class will eventually be phased out - Use Umbraco.Core.Models.Template", false)] public class Template : CMSNode { - - + #region Private members private string _OutputContentType; @@ -388,8 +388,7 @@ namespace umbraco.cms.businesslogic.template { return MakeNew(Name, u, master, null); } - - + private static Template MakeNew(string name, BusinessLogic.User u, string design) { return MakeNew(name, u, null, design); diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index 81128cda23..109834f055 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -19,6 +19,8 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType", false)] public class DocumentType : ContentType { + //MCH: Templates is still on the refactoring todo-list, so its currenly using db to get/set/remove templates. + #region Constructors public DocumentType(int id) : base(id) { } @@ -139,8 +141,8 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType and Umbraco.Core.Services.ContentTypeService.Save()", false)] public static DocumentType MakeNew(User u, string Text) { - var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text}; - ApplicationContext.Current.Services.ContentTypeService.Save(contentType); + var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text, CreatorId = u.Id}; + ApplicationContext.Current.Services.ContentTypeService.Save(contentType, u.Id); var newDt = new DocumentType(contentType.Id); //event @@ -506,7 +508,7 @@ namespace umbraco.cms.businesslogic.web if (_contentType.DefaultTemplate != null) _defaultTemplate = _contentType.DefaultTemplate.Id; - base.PopulateContentTypeFromContentTypeBase(_contentType, _objectType); + base.PopulateContentTypeFromContentTypeBase(_contentType); base.PopulateCMSNodeFromContentTypeBase(_contentType, _objectType); } #endregion From 2952990ad4bcd9d1a80e99867c8af175c4a88770 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 19 Dec 2012 10:13:56 -0100 Subject: [PATCH 19/35] Refactoring the legacy base ContentType class to better allow the usage of both new and old api. A few of the shared properties are now saved by the new api for DocumentType and MediaType, whereas the MemberType still uses the old style. --- src/Umbraco.Core/Models/ContentTypeBase.cs | 2 +- src/umbraco.cms/businesslogic/ContentType.cs | 229 +++++++++++++----- .../businesslogic/media/MediaType.cs | 6 +- .../businesslogic/member/MemberType.cs | 180 +++++++------- .../businesslogic/web/DocumentType.cs | 4 +- 5 files changed, 267 insertions(+), 154 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index ae0e587eb9..03fca722ea 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -130,7 +130,7 @@ namespace Umbraco.Core.Models get { return _alias; } set { - _alias = value; + _alias = value.ToUmbracoAlias(StringAliasCaseType.CamelCase, true); OnPropertyChanged(AliasSelector); } } diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 533baf6407..0633c050fb 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.Threading; using System.Runtime.CompilerServices; using System.Linq; +using Umbraco.Core; using Umbraco.Core.Models; using umbraco.cms.businesslogic.cache; using umbraco.cms.businesslogic.propertytype; using umbraco.cms.businesslogic.web; using umbraco.DataLayer; -using umbraco.BusinessLogic; using DataTypeDefinition = umbraco.cms.businesslogic.datatype.DataTypeDefinition; using Language = umbraco.cms.businesslogic.language.Language; using PropertyType = umbraco.cms.businesslogic.propertytype.PropertyType; @@ -76,6 +75,7 @@ namespace umbraco.cms.businesslogic internal ContentType(IContentTypeComposition contentType) : base(contentType) { + _contentType = contentType; } #endregion @@ -279,10 +279,74 @@ namespace umbraco.cms.businesslogic private static readonly object propertyTypesCacheSyncLock = new object(); + private IContentTypeComposition _contentType; + #endregion #region Public Properties + /// + /// The Alias of the ContentType, is used for import/export and more human readable initialization see: GetByAlias + /// method. + /// + public string Alias + { + get { return _alias; } + set + { + _alias = helpers.Casing.SafeAliasWithForcingCheck(value); + + // validate if alias is empty + if (String.IsNullOrEmpty(_alias)) + { + throw new ArgumentOutOfRangeException("An Alias cannot be empty"); + } + + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) + { + SqlHelper.ExecuteNonQuery("update cmsContentType set alias = @alias where nodeId = @id", + SqlHelper.CreateParameter("@alias", _alias), + SqlHelper.CreateParameter("@id", Id)); + } + else + { + _contentType.Alias = _alias; + } + + // Remove from cache + FlushFromCache(Id); + } + } + + /// + /// A Content object is often (always) represented in the treeview in the Umbraco console, the ContentType defines + /// which Icon the Content of this type is representated with. + /// + public string IconUrl + { + get { return _iconurl; } + set + { + _iconurl = value; + + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) + { + SqlHelper.ExecuteNonQuery("update cmsContentType set icon='" + value + "' where nodeid = " + Id); + } + else + { + _contentType.Icon = _iconurl; + } + + // Remove from cache + FlushFromCache(Id); + } + } + /// /// Get or Sets the Container status of the Content Type. A Container Content Type doesn't show its children in the tree, /// but instead adds a tab when edited showing its children in a grid @@ -293,10 +357,20 @@ namespace umbraco.cms.businesslogic set { _isContainerContentType = value; - SqlHelper.ExecuteNonQuery( + + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) + { + SqlHelper.ExecuteNonQuery( "update cmsContentType set isContainer = @isContainer where nodeId = @id", SqlHelper.CreateParameter("@isContainer", value), SqlHelper.CreateParameter("@id", Id)); + } + else + { + _contentType.IsContainer = _isContainerContentType; + } } } @@ -309,10 +383,20 @@ namespace umbraco.cms.businesslogic set { _allowAtRoot = value; - SqlHelper.ExecuteNonQuery( + + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) + { + SqlHelper.ExecuteNonQuery( "update cmsContentType set allowAtRoot = @allowAtRoot where nodeId = @id", SqlHelper.CreateParameter("@allowAtRoot", value), SqlHelper.CreateParameter("@id", Id)); + } + else + { + _contentType.AllowedAsRoot = _allowAtRoot; + } } } @@ -350,10 +434,20 @@ namespace umbraco.cms.businesslogic set { _description = value; - SqlHelper.ExecuteNonQuery( + + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) + { + SqlHelper.ExecuteNonQuery( "update cmsContentType set description = @description where nodeId = @id", SqlHelper.CreateParameter("@description", value), SqlHelper.CreateParameter("@id", Id)); + } + else + { + _contentType.Description = _description; + } FlushFromCache(Id); } @@ -369,10 +463,20 @@ namespace umbraco.cms.businesslogic set { _thumbnail = value; - SqlHelper.ExecuteNonQuery( + + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) + { + SqlHelper.ExecuteNonQuery( "update cmsContentType set thumbnail = @thumbnail where nodeId = @id", SqlHelper.CreateParameter("@thumbnail", value), SqlHelper.CreateParameter("@id", Id)); + } + else + { + _contentType.Thumbnail = _thumbnail; + } FlushFromCache(Id); } @@ -410,6 +514,11 @@ namespace umbraco.cms.businesslogic { base.Text = value; + if (_contentType != null) + { + _contentType.Name = value; + } + // Remove from cache FlushFromCache(Id); } @@ -466,50 +575,6 @@ namespace umbraco.cms.businesslogic } } - /// - /// The Alias of the ContentType, is used for import/export and more human readable initialization see: GetByAlias - /// method. - /// - public string Alias - { - get { return _alias; } - set - { - _alias = helpers.Casing.SafeAliasWithForcingCheck(value); - - // validate if alias is empty - if (String.IsNullOrEmpty(_alias)) - { - throw new ArgumentOutOfRangeException("An Alias cannot be empty"); - } - - SqlHelper.ExecuteNonQuery( - "update cmsContentType set alias = @alias where nodeId = @id", - SqlHelper.CreateParameter("@alias", _alias), - SqlHelper.CreateParameter("@id", Id)); - - // Remove from cache - FlushFromCache(Id); - } - } - - /// - /// A Content object is often (always) represented in the treeview in the Umbraco console, the ContentType defines - /// which Icon the Content of this type is representated with. - /// - public string IconUrl - { - get { return _iconurl; } - set - { - _iconurl = value; - SqlHelper.ExecuteNonQuery("update cmsContentType set icon='" + value + "' where nodeid = " + Id); - // Remove from cache - FlushFromCache(Id); - } - } - - public List MasterContentTypes { get @@ -703,13 +768,31 @@ namespace umbraco.cms.businesslogic { m_AllowedChildContentTypeIDs = value.ToList(); - SqlHelper.ExecuteNonQuery( - "delete from cmsContentTypeAllowedContentType where id=" + Id); - foreach (int i in value) + //This switches between using new vs. legacy api. + //Note that this is currently only done to support both DocumentType and MediaType, which use the new api and MemberType that doesn't. + if (_contentType == null) { SqlHelper.ExecuteNonQuery( - "insert into cmsContentTypeAllowedContentType (id,AllowedId) values (" + - Id + "," + i + ")"); + "delete from cmsContentTypeAllowedContentType where id=" + Id); + foreach (int i in value) + { + SqlHelper.ExecuteNonQuery( + "insert into cmsContentTypeAllowedContentType (id,AllowedId) values (" + + Id + "," + i + ")"); + } + } + else + { + var list = new List(); + int sort = 0; + foreach (var i in value) + { + int id = i; + list.Add(new ContentTypeSort{Id = new Lazy(() => id), SortOrder = sort}); + sort++; + } + + _contentType.AllowedContentTypes = list; } } } @@ -894,11 +977,6 @@ namespace umbraco.cms.businesslogic // NH 22-08-08, Get from the property type stack to ensure support of master document types object o = this.PropertyTypes.Find(pt => pt.Alias == alias); - //object o = SqlHelper.ExecuteScalar( - // "Select id from cmsPropertyType where contentTypeId=@contentTypeId And Alias=@alias", - // SqlHelper.CreateParameter("@contentTypeId", this.Id), - // SqlHelper.CreateParameter("@alias", alias)); - if (o == null) { return null; @@ -907,12 +985,6 @@ namespace umbraco.cms.businesslogic { return (PropertyType)o; } - - //int propertyTypeId; - //if (!int.TryParse(o.ToString(), out propertyTypeId)) - // return null; - - //return PropertyType.GetPropertyType(propertyTypeId); } /// @@ -957,7 +1029,7 @@ namespace umbraco.cms.businesslogic #region Protected Methods - internal protected void PopulateContentTypeFromContentTypeBase(IContentTypeBase contentType) + internal protected void PopulateContentTypeFromContentTypeBase(IContentTypeComposition contentType) { _alias = contentType.Alias; _iconurl = contentType.Icon; @@ -965,6 +1037,9 @@ namespace umbraco.cms.businesslogic _allowAtRoot = contentType.AllowedAsRoot; _thumbnail = contentType.Thumbnail; _description = contentType.Description; + + if (_contentType == null) + _contentType = contentType; } protected void PopulateContentTypeNodeFromReader(IRecordsReader dr) @@ -987,6 +1062,26 @@ namespace umbraco.cms.businesslogic { base.setupNode(); + //Try to load the ContentType/MediaType through the new public api + if (nodeObjectType == new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB")) + { + var contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(Id); + if (contentType != null) + { + PopulateContentTypeFromContentTypeBase(contentType); + return; + } + } + else if (nodeObjectType == new Guid("4EA4382B-2F5A-4C2B-9587-AE9B3CF3602E")) + { + var mediaType = ApplicationContext.Current.Services.ContentTypeService.GetMediaType(Id); + if (mediaType != null) + { + PopulateContentTypeFromContentTypeBase(mediaType); + return; + } + } + // TODO: Load master content types using (IRecordsReader dr = SqlHelper.ExecuteReader("Select allowAtRoot, isContainer, Alias,icon,thumbnail,description from cmsContentType where nodeid=" + Id) diff --git a/src/umbraco.cms/businesslogic/media/MediaType.cs b/src/umbraco.cms/businesslogic/media/MediaType.cs index fe229009f9..a25834698c 100644 --- a/src/umbraco.cms/businesslogic/media/MediaType.cs +++ b/src/umbraco.cms/businesslogic/media/MediaType.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Caching; -using umbraco.DataLayer; using System.Linq; - namespace umbraco.cms.businesslogic.media { /// @@ -94,7 +92,7 @@ namespace umbraco.cms.businesslogic.media [Obsolete("Deprecated, Use Umbraco.Core.Models.MediaType and Umbraco.Core.Services.ContentTypeService.Save()", false)] public static MediaType MakeNew(BusinessLogic.User u, string Text) { - var mediaType = new Umbraco.Core.Models.MediaType(-1) { Name = Text, Alias = Text, CreatorId = u.Id}; + var mediaType = new Umbraco.Core.Models.MediaType(-1) { Name = Text, Alias = Text, CreatorId = u.Id, Thumbnail = "folder.png", Icon = "folder.gif" }; ApplicationContext.Current.Services.ContentTypeService.Save(mediaType, u.Id); var mt = new MediaType(mediaType.Id); @@ -119,6 +117,8 @@ namespace umbraco.cms.businesslogic.media //Ensure that MediaTypes are reloaded from db by clearing cache InMemoryCacheProvider.Current.Clear(); + ApplicationContext.Current.Services.ContentTypeService.Save(_mediaType); + base.Save(); FireBeforeSave(e); diff --git a/src/umbraco.cms/businesslogic/member/MemberType.cs b/src/umbraco.cms/businesslogic/member/MemberType.cs index 30b04b5b23..c6ba370986 100644 --- a/src/umbraco.cms/businesslogic/member/MemberType.cs +++ b/src/umbraco.cms/businesslogic/member/MemberType.cs @@ -1,5 +1,4 @@ using System; -using System.Data; using System.Xml; using umbraco.cms.businesslogic.propertytype; using System.Linq; @@ -12,10 +11,16 @@ namespace umbraco.cms.businesslogic.member /// Due to the inheritance of the ContentType class, it enables definition of generic datafields on a Members. /// public class MemberType : ContentType - { - private static Guid _objectType = new Guid("9b5416fb-e72f-45a9-a07b-5a9a2709ce43"); + { + #region Private Members + + private static Guid _objectType = new Guid("9b5416fb-e72f-45a9-a07b-5a9a2709ce43"); + + #endregion - /// + #region Constructors + + /// /// Initializes a new instance of the MemberType class. /// /// MemberType id @@ -27,56 +32,11 @@ namespace umbraco.cms.businesslogic.member /// MemberType id public MemberType(Guid id) : base(id) { } - /// - /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility - /// - public override void Save() - { - SaveEventArgs e = new SaveEventArgs(); - FireBeforeSave(e); + #endregion - if(!e.Cancel){ - FireAfterSave(e); - } - } + #region Public Methods - /// - /// Create a new MemberType - /// - /// The name of the MemberType - /// Creator of the MemberType - public static MemberType MakeNew(User u,string Text) - { - int ParentId= -1; - int level = 1; - Guid uniqueId = Guid.NewGuid(); - CMSNode n = CMSNode.MakeNew(ParentId, _objectType, u.Id, level,Text, uniqueId); - - ContentType.Create(n.Id, Text,""); - MemberType mt = new MemberType(n.Id); - mt.IconUrl = "member.gif"; - NewEventArgs e = new NewEventArgs(); - mt.OnNew(e); - - return mt; - } - - /// - /// Retrieve a list of all MemberTypes - /// - public new static MemberType[] GetAll - { - get - { - Guid[] Ids = CMSNode.getAllUniquesFromObjectType(_objectType); - - MemberType[] retVal = new MemberType[Ids.Length]; - for (int i = 0; i < Ids.Length; i++) retVal[i] = new MemberType(Ids[i]); - return retVal; - } - } - - /// + /// /// Get an true/false if the Member can edit the given data defined in the propertytype /// /// Propertytype to edit @@ -90,29 +50,7 @@ namespace umbraco.cms.businesslogic.member } return false; } - - /// - /// Get a MemberType by it's alias - /// - /// The alias of the MemberType - /// The MemberType with the given Alias - public new static MemberType GetByAlias(string Alias) - { - try - { - return - new MemberType( - SqlHelper.ExecuteScalar(@"SELECT nodeid from cmsContentType INNER JOIN umbracoNode on cmsContentType.nodeId = umbracoNode.id WHERE nodeObjectType=@nodeObjectType AND alias=@alias", - SqlHelper.CreateParameter("@nodeObjectType", MemberType._objectType), - SqlHelper.CreateParameter("@alias", Alias))); - } - catch - { - return null; - } - } - - + /// /// Get an true/false if the given data defined in the propertytype, should be visible on the members profile page /// @@ -142,13 +80,7 @@ namespace umbraco.cms.businesslogic.member SqlHelper.ExecuteNonQuery("insert into cmsMemberType (NodeId, propertytypeid, memberCanEdit,viewOnProfile) values (" + this.Id + "," + pt.Id + ", " + tmpval + ",0)"); } - - private bool propertyTypeRegistered(PropertyType pt) - { - return (SqlHelper.ExecuteScalar("Select count(pk) as tmp from cmsMemberType where NodeId = " + this.Id + " And propertytypeId = " + pt.Id) > 0); - } - - + /// /// Set if the data should be displayed on members of this type's profilepage /// @@ -190,6 +122,20 @@ namespace umbraco.cms.businesslogic.member FireAfterDelete(e); } } + + /// + /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility + /// + public override void Save() + { + SaveEventArgs e = new SaveEventArgs(); + FireBeforeSave(e); + + if (!e.Cancel) + { + FireAfterSave(e); + } + } public XmlElement ToXml(XmlDocument xd) { @@ -235,6 +181,76 @@ namespace umbraco.cms.businesslogic.member return root; } + #endregion + + #region Public Static Methods + /// + /// Get a MemberType by it's alias + /// + /// The alias of the MemberType + /// The MemberType with the given Alias + public new static MemberType GetByAlias(string Alias) + { + try + { + return + new MemberType( + SqlHelper.ExecuteScalar(@"SELECT nodeid from cmsContentType INNER JOIN umbracoNode on cmsContentType.nodeId = umbracoNode.id WHERE nodeObjectType=@nodeObjectType AND alias=@alias", + SqlHelper.CreateParameter("@nodeObjectType", MemberType._objectType), + SqlHelper.CreateParameter("@alias", Alias))); + } + catch + { + return null; + } + } + + /// + /// Create a new MemberType + /// + /// The name of the MemberType + /// Creator of the MemberType + public static MemberType MakeNew(User u, string Text) + { + int ParentId = -1; + int level = 1; + Guid uniqueId = Guid.NewGuid(); + CMSNode n = CMSNode.MakeNew(ParentId, _objectType, u.Id, level, Text, uniqueId); + + ContentType.Create(n.Id, Text, ""); + MemberType mt = new MemberType(n.Id); + mt.IconUrl = "member.gif"; + NewEventArgs e = new NewEventArgs(); + mt.OnNew(e); + + return mt; + } + + /// + /// Retrieve a list of all MemberTypes + /// + public new static MemberType[] GetAll + { + get + { + Guid[] Ids = CMSNode.getAllUniquesFromObjectType(_objectType); + + MemberType[] retVal = new MemberType[Ids.Length]; + for (int i = 0; i < Ids.Length; i++) retVal[i] = new MemberType(Ids[i]); + return retVal; + } + } + #endregion + + #region Private Methods + + private bool propertyTypeRegistered(PropertyType pt) + { + return (SqlHelper.ExecuteScalar("Select count(pk) as tmp from cmsMemberType where NodeId = " + this.Id + " And propertytypeId = " + pt.Id) > 0); + } + + #endregion + #region Events /// diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index 109834f055..581cf50110 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -141,7 +141,7 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Deprecated, Use Umbraco.Core.Models.ContentType and Umbraco.Core.Services.ContentTypeService.Save()", false)] public static DocumentType MakeNew(User u, string Text) { - var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text, CreatorId = u.Id}; + var contentType = new Umbraco.Core.Models.ContentType(-1) { Name = Text, Alias = Text, CreatorId = u.Id, Thumbnail = "folder.png", Icon = "folder.gif" }; ApplicationContext.Current.Services.ContentTypeService.Save(contentType, u.Id); var newDt = new DocumentType(contentType.Id); @@ -463,6 +463,8 @@ namespace umbraco.cms.businesslogic.web //Ensure that MediaTypes are reloaded from db by clearing cache InMemoryCacheProvider.Current.Clear(); + ApplicationContext.Current.Services.ContentTypeService.Save(_contentType); + base.Save(); FireAfterSave(e); } From 271794ca400cf7530580f182b2c9b647f159cfe2 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 19 Dec 2012 10:35:01 -0100 Subject: [PATCH 20/35] Updates the Database step in the installer to not use the legacy sql install utility. --- .../install/steps/Definitions/Database.cs | 14 ++++++-------- .../ApplicationTreeRegistrar.cs | 2 -- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs index 9293d0e84b..a11e3be5da 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs @@ -1,11 +1,7 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; +using Umbraco.Core.Configuration; using umbraco.cms.businesslogic.installer; using umbraco.IO; -using umbraco.DataLayer.Utility.Installer; -using umbraco.DataLayer; namespace umbraco.presentation.install.steps.Definitions { @@ -41,9 +37,11 @@ namespace umbraco.presentation.install.steps.Definitions bool retval = false; try { - IInstallerUtility m_Installer = BusinessLogic.Application.SqlHelper.Utility.CreateInstaller(); - retval = m_Installer.IsLatestVersion; - m_Installer = null; + var configuredVersion = new Version(Umbraco.Core.Configuration.GlobalSettings.ConfigurationStatus); + var targetVersion = UmbracoVersion.Current; + + retval = targetVersion > configuredVersion; + } catch { // this step might fail due to missing connectionstring return false; diff --git a/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs b/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs index 07175dcc96..15067ca655 100644 --- a/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs +++ b/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs @@ -90,8 +90,6 @@ namespace umbraco.BusinessLogic } }, true); - - //SqlHelper.ExecuteNonQuery("DELETE FROM umbracoAppTree"); } } } \ No newline at end of file From 9af1f5842c05006e28aefbf26bf7cf7011074183 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 19 Dec 2012 12:14:49 -0100 Subject: [PATCH 21/35] Updating ApplicationTreeRegistrar to check for table before looping through it. Updating schema creation to not include the umbracoApp and umbracoAppTree tables. --- .../Initial/DatabaseSchemaCreation.cs | 4 +- .../Persistence/PetaPocoExtensions.cs | 5 ++ src/umbraco.businesslogic/Application.cs | 34 ----------- src/umbraco.businesslogic/ApplicationTree.cs | 57 ------------------- .../ApplicationTreeRegistrar.cs | 56 +++++++----------- 5 files changed, 29 insertions(+), 127 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index 5f39881e92..4e2f60eb3c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -72,8 +72,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.CreateTable(); _database.CreateTable(); - _database.CreateTable(); - _database.CreateTable(); + //_database.CreateTable(); + //_database.CreateTable(); _database.CreateTable(); _database.CreateTable(); diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index e154cb3fbc..aed50a889e 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -127,6 +127,11 @@ namespace Umbraco.Core.Persistence return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName); } + public static bool TableExist(this UmbracoDatabase db, string tableName) + { + return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName); + } + public static void CreateDatabaseSchema(this Database db) { NewTable += PetaPocoExtensions_NewTable; diff --git a/src/umbraco.businesslogic/Application.cs b/src/umbraco.businesslogic/Application.cs index 89a0d1ed1e..e452771fcc 100644 --- a/src/umbraco.businesslogic/Application.cs +++ b/src/umbraco.businesslogic/Application.cs @@ -1,8 +1,5 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; using System.IO; using System.Linq; using System.Web; @@ -195,15 +192,6 @@ namespace umbraco.BusinessLogic if (!exist) { - // SqlHelper.ExecuteNonQuery(@" - // insert into umbracoApp - // (appAlias,appIcon,appName, sortOrder) - // values (@alias,@icon,@name,@sortOrder)", - // SqlHelper.CreateParameter("@alias", alias), - // SqlHelper.CreateParameter("@icon", icon), - // SqlHelper.CreateParameter("@name", name), - // SqlHelper.CreateParameter("@sortOrder", sortOrder)); - LoadXml(doc => { doc.Root.Add(new XElement("add", @@ -215,16 +203,6 @@ namespace umbraco.BusinessLogic } } - //public static void MakeNew(IApplication Iapp, bool installAppTrees) { - - // MakeNew(Iapp.Name, Iapp.Alias, Iapp.Icon); - - // if (installAppTrees) { - - // } - //} - - /// /// Gets the application by its alias. /// @@ -250,9 +228,6 @@ namespace umbraco.BusinessLogic t.Delete(); } - //SqlHelper.ExecuteNonQuery("delete from umbracoApp where appAlias = @appAlias", - // SqlHelper.CreateParameter("@appAlias", this._alias)); - LoadXml(doc => { doc.Root.Elements("add").Where(x => x.Attribute("alias") != null && x.Attribute("alias").Value == this.alias).Remove(); @@ -299,15 +274,6 @@ namespace umbraco.BusinessLogic { var tmp = new List(); - //using (IRecordsReader dr = - // SqlHelper.ExecuteReader("Select appAlias, appIcon, appName from umbracoApp")) - //{ - // while (dr.Read()) - // { - // tmp.Add(new Application(dr.GetString("appName"), dr.GetString("appAlias"), dr.GetString("appIcon"))); - // } - //} - LoadXml(doc => { diff --git a/src/umbraco.businesslogic/ApplicationTree.cs b/src/umbraco.businesslogic/ApplicationTree.cs index d5a4ff4ffa..07f05cfe71 100644 --- a/src/umbraco.businesslogic/ApplicationTree.cs +++ b/src/umbraco.businesslogic/ApplicationTree.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Web; using System.Xml.Linq; using umbraco.DataLayer; @@ -240,24 +239,6 @@ namespace umbraco.BusinessLogic /// The action. public static void MakeNew(bool silent, bool initialize, byte sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string assemblyName, string type, string action) { - - // SqlHelper.ExecuteNonQuery(@"insert into umbracoAppTree(treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, - // treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType, action) - // values(@treeSilent, @treeInitialize, @treeSortOrder, @appAlias, @treeAlias, @treeTitle, @treeIconClosed, @treeIconOpen, @treeHandlerAssembly, @treeHandlerType, @action)" - // , - // SqlHelper.CreateParameter("@treeSilent", silent), - // SqlHelper.CreateParameter("@treeInitialize", initialize), - // SqlHelper.CreateParameter("@treeSortOrder", sortOrder), - // SqlHelper.CreateParameter("@treeAlias", alias), - // SqlHelper.CreateParameter("@appAlias", applicationAlias), - // SqlHelper.CreateParameter("@treeTitle", title), - // SqlHelper.CreateParameter("@treeIconClosed", iconClosed), - // SqlHelper.CreateParameter("@treeIconOpen", iconOpened), - // SqlHelper.CreateParameter("@treeHandlerAssembly", assemblyName), - // SqlHelper.CreateParameter("@treeHandlerType", type), - // SqlHelper.CreateParameter("@action", action) - // ); - LoadXml(doc => { doc.Root.Add(new XElement("add", @@ -280,22 +261,6 @@ namespace umbraco.BusinessLogic /// public void Save() { - // SqlHelper.ExecuteNonQuery(@"Update umbracoAppTree set treeSilent = @treeSilent, treeInitialize = @treeInitialize, treeSortOrder = @treeSortOrder, treeTitle = @treeTitle, - // treeIconClosed = @treeIconClosed, treeIconOpen = @treeIconOpen, treeHandlerAssembly = @treeHandlerAssembly, treeHandlerType = @treeHandlerType, action = @action - // where treeAlias = @treeAlias AND appAlias = @appAlias", - // SqlHelper.CreateParameter("@treeSilent", this.Silent), - // SqlHelper.CreateParameter("@treeInitialize", this.Initialize), - // SqlHelper.CreateParameter("@treeSortOrder", this.SortOrder), - // SqlHelper.CreateParameter("@treeTitle", this.Title), - // SqlHelper.CreateParameter("@treeIconClosed", this.IconClosed), - // SqlHelper.CreateParameter("@treeIconOpen", this.IconOpened), - // SqlHelper.CreateParameter("@treeHandlerAssembly", this.AssemblyName), - // SqlHelper.CreateParameter("@treeHandlerType", this.Type), - // SqlHelper.CreateParameter("@treeAlias", this.Alias), - // SqlHelper.CreateParameter("@appAlias", this.ApplicationAlias), - // SqlHelper.CreateParameter("@action", this.Action) - // ); - LoadXml(doc => { var el = doc.Root.Elements("add").SingleOrDefault(x => x.Attribute("alias").Value == this.Alias && x.Attribute("application").Value == this.ApplicationAlias); @@ -417,28 +382,6 @@ namespace umbraco.BusinessLogic { var list = new List(); - // using (IRecordsReader dr = SqlHelper.ExecuteReader(@"Select treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, - // treeIconOpen, treeHandlerAssembly, treeHandlerType, action from umbracoAppTree order by treeSortOrder")) - // { - // while (dr.Read()) - // { - - // list.Add(new ApplicationTree( - // dr.GetBoolean("treeSilent"), - // dr.GetBoolean("treeInitialize"), - // dr.GetByte("treeSortOrder"), - // dr.GetString("appAlias"), - // dr.GetString("treeAlias"), - // dr.GetString("treeTitle"), - // dr.GetString("treeIconClosed"), - // dr.GetString("treeIconOpen"), - // dr.GetString("treeHandlerAssembly"), - // dr.GetString("treeHandlerType"), - // dr.GetString("action"))); - - // } - // } - LoadXml(doc => { foreach (var addElement in doc.Root.Elements("add").OrderBy(x => diff --git a/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs b/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs index 15067ca655..16e98ba493 100644 --- a/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs +++ b/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs @@ -2,8 +2,8 @@ using System.Linq; using System.Xml.Linq; using Umbraco.Core; -using umbraco.BusinessLogic.Utils; -using umbraco.DataLayer; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence; using umbraco.businesslogic; using umbraco.interfaces; @@ -11,23 +11,6 @@ namespace umbraco.BusinessLogic { public class ApplicationTreeRegistrar : IApplicationStartupHandler { - private ISqlHelper _sqlHelper; - protected ISqlHelper SqlHelper - { - get - { - if (_sqlHelper == null) - { - try - { - _sqlHelper = DataLayerHelper.CreateSqlHelper(GlobalSettings.DbDSN); - } - catch { } - } - return _sqlHelper; - } - } - public ApplicationTreeRegistrar() { //don't do anything if the application is not configured! @@ -70,23 +53,28 @@ namespace umbraco.BusinessLogic new XAttribute("action", attr.Action))); } - var dbTrees = SqlHelper.ExecuteReader("SELECT * FROM umbracoAppTree WHERE treeAlias NOT IN (" + inString + ")"); - while (dbTrees.Read()) + var db = ApplicationContext.Current.DatabaseContext.Database; + var exist = db.TableExist("umbracoAppTree"); + if (exist) { - var action = dbTrees.GetString("action"); + var appTrees = db.Fetch("WHERE treeAlias NOT IN (" + inString + ")"); + foreach (var appTree in appTrees) + { + var action = appTree.Action; - doc.Root.Add(new XElement("add", - new XAttribute("silent", dbTrees.GetBoolean("treeSilent")), - new XAttribute("initialize", dbTrees.GetBoolean("treeInitialize")), - new XAttribute("sortOrder", dbTrees.GetByte("treeSortOrder")), - new XAttribute("alias", dbTrees.GetString("treeAlias")), - new XAttribute("application", dbTrees.GetString("appAlias")), - new XAttribute("title", dbTrees.GetString("treeTitle")), - new XAttribute("iconClosed", dbTrees.GetString("treeIconClosed")), - new XAttribute("iconOpen", dbTrees.GetString("treeIconOpen")), - new XAttribute("assembly", dbTrees.GetString("treeHandlerAssembly")), - new XAttribute("type", dbTrees.GetString("treeHandlerType")), - new XAttribute("action", string.IsNullOrEmpty(action) ? "" : action))); + doc.Root.Add(new XElement("add", + new XAttribute("silent", appTree.Silent), + new XAttribute("initialize", appTree.Initialize), + new XAttribute("sortOrder", appTree.SortOrder), + new XAttribute("alias", appTree.Alias), + new XAttribute("application", appTree.AppAlias), + new XAttribute("title", appTree.Title), + new XAttribute("iconClosed", appTree.IconClosed), + new XAttribute("iconOpen", appTree.IconOpen), + new XAttribute("assembly", appTree.HandlerAssembly), + new XAttribute("type", appTree.HandlerType), + new XAttribute("action", string.IsNullOrEmpty(action) ? "" : action))); + } } }, true); From 9f2d41286cf89ed0cbab3fccf57bd5b3dfb45efe Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 20 Dec 2012 14:29:08 -0100 Subject: [PATCH 22/35] Fixing MasterContentType for DocumentTypes. Adding ParentId "listener" to the repositories that uses ParentId, so we can ensure that the path is updated correctly. Fixing how AllowedTemplates are saved upon creation of a new DocumentType. Ensuring DocumentType.Save is called when creting a new DocumentType. Fixing Publish/RePublish of Content with previously published children. Removing UpdateDocumentCache in the save event of editContent.aspx.cs as its now handled in the new api. Rewiring template methods on DocumentType class to use the new api. --- .../Repositories/ContentRepository.cs | 2 +- .../Repositories/ContentTypeRepository.cs | 8 +++ .../DataTypeDefinitionRepository.cs | 7 +++ .../Repositories/MediaRepository.cs | 7 +++ .../Repositories/MediaTypeRepository.cs | 7 +++ .../Repositories/TemplateRepository.cs | 7 +++ src/Umbraco.Core/Services/ContentService.cs | 39 ++++-------- .../config/ClientDependency.config | 26 +++----- .../umbraco/create/nodetypeTasks.cs | 2 + .../umbraco/editContent.aspx.cs | 1 - src/umbraco.cms/businesslogic/ContentType.cs | 2 + .../businesslogic/media/MediaType.cs | 4 +- src/umbraco.cms/businesslogic/web/Document.cs | 2 +- .../businesslogic/web/DocumentType.cs | 61 ++++++++++++++----- 14 files changed, 109 insertions(+), 66 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index d947c1c0fa..93d72d07f5 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -298,7 +298,7 @@ namespace Umbraco.Core.Persistence.Repositories } //If Published state has changed then previous versions should have their publish state reset - if (shouldCreateNewVersion && entity.Published) + if (((ICanBeDirty)entity).IsPropertyDirty("Published")) { var publishedDocs = Database.Fetch("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true }); foreach (var doc in publishedDocs) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs index 87e982fd2b..59f9347476 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs @@ -144,6 +144,7 @@ namespace Umbraco.Core.Persistence.Repositories string.Format("DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id"), string.Format("DELETE FROM cmsTagRelationship WHERE nodeId = @Id"), string.Format("DELETE FROM cmsContentTypeAllowedContentType WHERE Id = @Id"), + string.Format("DELETE FROM cmsContentTypeAllowedContentType WHERE AllowedId = @Id"), string.Format("DELETE FROM cmsContentType2ContentType WHERE parentContentTypeId = @Id"), string.Format("DELETE FROM cmsContentType2ContentType WHERE childContentTypeId = @Id"), string.Format("DELETE FROM cmsPropertyType WHERE contentTypeId = @Id"), @@ -191,6 +192,13 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date ((ContentType)entity).UpdatingEntity(); + //Look up parent to get and set the correct Path if ParentId has changed + if (((ICanBeDirty)entity).IsPropertyDirty("ParentId")) + { + var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + } + var factory = new ContentTypeFactory(NodeObjectTypeId); var dto = factory.BuildDto(entity); diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index 5ef72413be..6212cf880e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -153,6 +153,13 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date and Version Guid ((DataTypeDefinition)entity).UpdatingEntity(); + //Look up parent to get and set the correct Path if ParentId has changed + if (((ICanBeDirty)entity).IsPropertyDirty("ParentId")) + { + var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + } + var factory = new DataTypeDefinitionFactory(NodeObjectTypeId); //Look up DataTypeDefinition entry to get Primary for updating the DTO var dataTypeDto = Database.SingleOrDefault("WHERE nodeId = @Id", new { Id = entity.Id }); diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 288ccd43e5..2c244def9a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -234,6 +234,13 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date ((Models.Media)entity).UpdatingEntity(); + //Look up parent to get and set the correct Path if ParentId has changed + if (((ICanBeDirty)entity).IsPropertyDirty("ParentId")) + { + var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + } + var factory = new MediaFactory(NodeObjectTypeId, entity.Id); //Look up Content entry to get Primary for updating the DTO var contentDto = Database.SingleOrDefault("WHERE nodeId = @Id", new { Id = entity.Id }); diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs index 50477a679e..fb0682511c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs @@ -160,6 +160,13 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date ((MediaType)entity).UpdatingEntity(); + //Look up parent to get and set the correct Path if ParentId has changed + if (((ICanBeDirty)entity).IsPropertyDirty("ParentId")) + { + var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + } + var factory = new MediaTypeFactory(NodeObjectTypeId); var dto = factory.BuildDto(entity); diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs index fb8307d940..0bd21368f0 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs @@ -226,6 +226,13 @@ namespace Umbraco.Core.Persistence.Repositories } } + //Look up parent to get and set the correct Path if ParentId has changed + if (((ICanBeDirty)entity).IsPropertyDirty("ParentId")) + { + var parent = Database.First("WHERE id = @ParentId", new { ParentId = ((Template)entity).ParentId }); + entity.Path = string.Concat(parent.Path, ",", entity.Id); + } + //Get TemplateDto from db to get the Primary key of the entity var templateDto = Database.SingleOrDefault("WHERE nodeId = @Id", new { Id = entity.Id }); //Save updated entity to db diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 95d4c14dc2..683680cb7c 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -539,17 +539,7 @@ namespace Umbraco.Core.Services { //TODO Refactor this so omitCacheRefresh isn't exposed in the public method, but only in an internal one as its purely there for legacy reasons. - //Look for children and unpublish them if any exists, otherwise just unpublish the passed in Content. - var children = GetChildrenDeep(content.Id); - var hasChildren = children.Any(); - - if (hasChildren) - children.Add(content); - - var unpublished = hasChildren - ? _publishingStrategy.UnPublish(children, userId) - : _publishingStrategy.UnPublish(content, userId); - + var unpublished = _publishingStrategy.UnPublish(content, userId); if (unpublished) { var uow = _uowProvider.GetUnitOfWork(); @@ -557,24 +547,8 @@ namespace Umbraco.Core.Services { repository.AddOrUpdate(content); - if (hasChildren) - { - foreach (var child in children) - { - SetWriter(child, userId); - repository.AddOrUpdate(child); - } - } - - //Remove 'published' xml from the cmsContentXml table for the unpublished content and its (possible) children + //Remove 'published' xml from the cmsContentXml table for the unpublished content uow.Database.Delete("WHERE nodeId = @Id", new {Id = content.Id}); - if (hasChildren) - { - foreach (var child in children) - { - uow.Database.Delete("WHERE nodeId = @Id", new {Id = child.Id}); - } - } uow.Commit(); } @@ -653,6 +627,15 @@ namespace Umbraco.Core.Services if (omitCacheRefresh == false) _publishingStrategy.PublishingFinalized(content); + if (HasChildren(content.Id)) + { + var children = GetChildrenDeep(content.Id); + var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id)); + + if (omitCacheRefresh == false) + _publishingStrategy.PublishingFinalized(shouldBeRepublished, false); + } + if (Saved != null) Saved(content, e); diff --git a/src/Umbraco.Web.UI/config/ClientDependency.config b/src/Umbraco.Web.UI/config/ClientDependency.config index f7fdad504a..d6edcff895 100644 --- a/src/Umbraco.Web.UI/config/ClientDependency.config +++ b/src/Umbraco.Web.UI/config/ClientDependency.config @@ -10,14 +10,14 @@ NOTES: * Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config * A new version will invalidate both client and server cache and create new persisted files --> - + - - - - + + + + @@ -26,8 +26,8 @@ NOTES: - - + + @@ -41,20 +41,12 @@ NOTES: --> - + - +