From e61b567ee1288fd43ee9ac47496169e07d54c2ab Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Mon, 27 May 2013 08:45:07 -0200 Subject: [PATCH] Fixes #U4-2270 and #U4-2269 --- src/Umbraco.Core/Services/ContentService.cs | 100 ++++++++++- src/Umbraco.Core/Services/IContentService.cs | 44 ++++- src/Umbraco.Core/Services/IMediaService.cs | 44 ++++- src/Umbraco.Core/Services/MediaService.cs | 164 +++++++++++++----- src/Umbraco.Core/Services/PackagingService.cs | 1 + .../Services/Importing/PackageImportTests.cs | 24 +++ 6 files changed, 328 insertions(+), 49 deletions(-) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 4ac8926ee4..0068c2e72a 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -56,8 +56,13 @@ namespace Umbraco.Core.Services /// /// Creates an object using the alias of the - /// that this Content is based on. + /// that this Content should based on. /// + /// + /// Note that using this method will simply return a new IContent without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects + /// that does not invoke a save operation against the database. + /// /// Name of the Content object /// Id of Parent for the new Content /// Alias of the @@ -66,7 +71,7 @@ namespace Umbraco.Core.Services public IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = 0) { var contentType = FindContentTypeByAlias(contentTypeAlias); - var content = new Content(name, parentId, contentType); ; + var content = new Content(name, parentId, contentType); if (Creating.IsRaisedEventCancelled(new NewEventArgs(content, contentTypeAlias, parentId), this)) { @@ -86,8 +91,13 @@ namespace Umbraco.Core.Services /// /// Creates an object using the alias of the - /// that this Content is based on. + /// that this Content should based on. /// + /// + /// Note that using this method will simply return a new IContent without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects + /// that does not invoke a save operation against the database. + /// /// Name of the Content object /// Parent object for the new Content /// Alias of the @@ -114,6 +124,86 @@ namespace Umbraco.Core.Services return content; } + /// + /// Creates and saves an object using the alias of the + /// that this Content should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Content object + /// Id of Parent for the new Content + /// Alias of the + /// Optional id of the user creating the content + /// + public IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0) + { + var contentType = FindContentTypeByAlias(contentTypeAlias); + var content = new Content(name, parentId, contentType); + + if (Creating.IsRaisedEventCancelled(new NewEventArgs(content, contentTypeAlias, parentId), this)) + { + content.WasCancelled = true; + return content; + } + + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateContentRepository(uow)) + { + content.CreatorId = userId; + content.WriterId = userId; + repository.AddOrUpdate(content); + uow.Commit(); + } + + Created.RaiseEvent(new NewEventArgs(content, false, contentTypeAlias, parentId), this); + + Audit.Add(AuditTypes.New, "", content.CreatorId, content.Id); + + return content; + } + + /// + /// Creates and saves an object using the alias of the + /// that this Content should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Content object + /// Parent object for the new Content + /// Alias of the + /// Optional id of the user creating the content + /// + public IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0) + { + var contentType = FindContentTypeByAlias(contentTypeAlias); + var content = new Content(name, parent, contentType); + + if (Creating.IsRaisedEventCancelled(new NewEventArgs(content, contentTypeAlias, parent), this)) + { + content.WasCancelled = true; + return content; + } + + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateContentRepository(uow)) + { + content.CreatorId = userId; + content.WriterId = userId; + repository.AddOrUpdate(content); + uow.Commit(); + } + + Created.RaiseEvent(new NewEventArgs(content, false, contentTypeAlias, parent), this); + + Audit.Add(AuditTypes.New, "", content.CreatorId, content.Id); + + return content; + } + /// /// Gets an object by Id /// @@ -1347,7 +1437,7 @@ namespace Umbraco.Core.Services using (new WriteLock(Locker)) { //Has this content item previously been published? If so, we don't need to refresh the children - var previouslyPublished = HasPublishedVersion(content.Id); + var previouslyPublished = content.HasIdentity && HasPublishedVersion(content.Id); var validForPublishing = CheckAndLogIsPublishable(content) && CheckAndLogIsValid(content); //Publish and then update the database with new status @@ -1559,7 +1649,7 @@ namespace Umbraco.Core.Services var query = Query.Builder.Where(x => x.Alias == contentTypeAlias); var types = repository.GetByQuery(query); - if (!types.Any()) + if (types.Any() == false) throw new Exception( string.Format("No ContentType matching the passed in Alias: '{0}' was found", contentTypeAlias)); diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 1aa3a2aeae..1c25bddcc4 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -11,8 +11,13 @@ namespace Umbraco.Core.Services { /// /// Creates an object using the alias of the - /// that this Content is based on. + /// that this Content should based on. /// + /// + /// Note that using this method will simply return a new IContent without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects + /// that does not invoke a save operation against the database. + /// /// Name of the Content object /// Id of Parent for the new Content /// Alias of the @@ -22,8 +27,13 @@ namespace Umbraco.Core.Services /// /// Creates an object using the alias of the - /// that this Content is based on. + /// that this Content should based on. /// + /// + /// Note that using this method will simply return a new IContent without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects + /// that does not invoke a save operation against the database. + /// /// Name of the Content object /// Parent object for the new Content /// Alias of the @@ -301,5 +311,35 @@ namespace Umbraco.Core.Services /// /// True if sorting succeeded, otherwise False bool Sort(SortedSet items, int userId = 0, bool raiseEvents = true); + + /// + /// Creates and saves an object using the alias of the + /// that this Content should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Content object + /// Parent object for the new Content + /// Alias of the + /// Optional id of the user creating the content + /// + IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0); + + /// + /// Creates and saves an object using the alias of the + /// that this Content should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Content object + /// Id of Parent for the new Content + /// Alias of the + /// Optional id of the user creating the content + /// + IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 31db004d84..84b886a9cd 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -11,8 +11,13 @@ namespace Umbraco.Core.Services { /// /// Creates an object using the alias of the - /// that this Media is based on. + /// that this Media should based on. /// + /// + /// Note that using this method will simply return a new IMedia without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new media objects + /// that does not invoke a save operation against the database. + /// /// Name of the Media object /// Id of Parent for the new Media item /// Alias of the @@ -22,8 +27,13 @@ namespace Umbraco.Core.Services /// /// Creates an object using the alias of the - /// that this Media is based on. + /// that this Media should based on. /// + /// + /// Note that using this method will simply return a new IMedia without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new media objects + /// that does not invoke a save operation against the database. + /// /// Name of the Media object /// Parent for the new Media item /// Alias of the @@ -194,5 +204,35 @@ namespace Umbraco.Core.Services /// /// True if sorting succeeded, otherwise False bool Sort(SortedSet items, int userId = 0, bool raiseEvents = true); + + /// + /// Creates an object using the alias of the + /// that this Media should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Media object + /// Parent for the new Media item + /// Alias of the + /// Optional id of the user creating the media item + /// + IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0); + + /// + /// Creates an object using the alias of the + /// that this Media should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Media object + /// Id of Parent for the new Media item + /// Alias of the + /// Optional id of the user creating the media item + /// + IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index bc0ab042d9..9f15f7f0cc 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -37,8 +37,13 @@ namespace Umbraco.Core.Services /// /// Creates an object using the alias of the - /// that this Media is based on. + /// that this Media should based on. /// + /// + /// Note that using this method will simply return a new IMedia without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new media objects + /// that does not invoke a save operation against the database. + /// /// Name of the Media object /// Id of Parent for the new Media item /// Alias of the @@ -46,25 +51,7 @@ namespace Umbraco.Core.Services /// public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0) { - IMediaType mediaType; - - var uow = _uowProvider.GetUnitOfWork(); - using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow)) - { - var query = Query.Builder.Where(x => x.Alias == mediaTypeAlias); - var mediaTypes = repository.GetByQuery(query); - - if (!mediaTypes.Any()) - throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found", - mediaTypeAlias)); - - mediaType = mediaTypes.First(); - - if (mediaType == null) - throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null", - mediaTypeAlias)); - } - + var mediaType = FindMediaTypeByAlias(mediaTypeAlias); var media = new Models.Media(name, parentId, mediaType); if (Creating.IsRaisedEventCancelled(new NewEventArgs(media, mediaTypeAlias, parentId), this)) @@ -84,8 +71,13 @@ namespace Umbraco.Core.Services /// /// Creates an object using the alias of the - /// that this Media is based on. + /// that this Media should based on. /// + /// + /// Note that using this method will simply return a new IMedia without any identity + /// as it has not yet been persisted. It is intended as a shortcut to creating new media objects + /// that does not invoke a save operation against the database. + /// /// Name of the Media object /// Parent for the new Media item /// Alias of the @@ -93,25 +85,7 @@ namespace Umbraco.Core.Services /// public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0) { - IMediaType mediaType; - - var uow = _uowProvider.GetUnitOfWork(); - using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow)) - { - var query = Query.Builder.Where(x => x.Alias == mediaTypeAlias); - var mediaTypes = repository.GetByQuery(query); - - if (!mediaTypes.Any()) - throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found", - mediaTypeAlias)); - - mediaType = mediaTypes.First(); - - if (mediaType == null) - throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null", - mediaTypeAlias)); - } - + var mediaType = FindMediaTypeByAlias(mediaTypeAlias); var media = new Models.Media(name, parent, mediaType); if (Creating.IsRaisedEventCancelled(new NewEventArgs(media, mediaTypeAlias, parent), this)) { @@ -128,6 +102,94 @@ namespace Umbraco.Core.Services return media; } + /// + /// Creates an object using the alias of the + /// that this Media should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Media object + /// Id of Parent for the new Media item + /// Alias of the + /// Optional id of the user creating the media item + /// + public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0) + { + var mediaType = FindMediaTypeByAlias(mediaTypeAlias); + var media = new Models.Media(name, parentId, mediaType); + if (Creating.IsRaisedEventCancelled(new NewEventArgs(media, mediaTypeAlias, parentId), this)) + { + media.WasCancelled = true; + return media; + } + + using (new WriteLock(Locker)) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMediaRepository(uow)) + { + media.CreatorId = userId; + repository.AddOrUpdate(media); + uow.Commit(); + + var xml = media.ToXml(); + CreateAndSaveMediaXml(xml, media.Id, uow.Database); + } + } + + Created.RaiseEvent(new NewEventArgs(media, false, mediaTypeAlias, parentId), this); + + Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id); + + return media; + } + + /// + /// Creates an object using the alias of the + /// that this Media should based on. + /// + /// + /// This method returns an object that has been persisted to the database + /// and therefor has an identity. + /// + /// Name of the Media object + /// Parent for the new Media item + /// Alias of the + /// Optional id of the user creating the media item + /// + public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0) + { + var mediaType = FindMediaTypeByAlias(mediaTypeAlias); + var media = new Models.Media(name, parent, mediaType); + if (Creating.IsRaisedEventCancelled(new NewEventArgs(media, mediaTypeAlias, parent), this)) + { + media.WasCancelled = true; + return media; + } + + using (new WriteLock(Locker)) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMediaRepository(uow)) + { + media.CreatorId = userId; + repository.AddOrUpdate(media); + uow.Commit(); + + var xml = media.ToXml(); + CreateAndSaveMediaXml(xml, media.Id, uow.Database); + } + } + + Created.RaiseEvent(new NewEventArgs(media, false, mediaTypeAlias, parent), this); + + Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id); + + return media; + } + /// /// Gets an object by Id /// @@ -732,6 +794,28 @@ namespace Umbraco.Core.Services int result = exists ? db.Update(poco) : Convert.ToInt32(db.Insert(poco)); } + private IMediaType FindMediaTypeByAlias(string mediaTypeAlias) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow)) + { + var query = Query.Builder.Where(x => x.Alias == mediaTypeAlias); + var mediaTypes = repository.GetByQuery(query); + + if (mediaTypes.Any() == false) + throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found", + mediaTypeAlias)); + + var mediaType = mediaTypes.First(); + + if (mediaType == null) + throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null", + mediaTypeAlias)); + + return mediaType; + } + } + #region Event Handlers /// diff --git a/src/Umbraco.Core/Services/PackagingService.cs b/src/Umbraco.Core/Services/PackagingService.cs index 7792a531bf..92140889b8 100644 --- a/src/Umbraco.Core/Services/PackagingService.cs +++ b/src/Umbraco.Core/Services/PackagingService.cs @@ -324,6 +324,7 @@ namespace Umbraco.Core.Services var template = _fileService.GetTemplate(alias); if (template != null) { + if(allowedTemplates.Any(x => x.Id == template.Id)) continue; allowedTemplates.Add(template); } else diff --git a/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs b/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs index 24ae92f4d5..cb82edacef 100644 --- a/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs +++ b/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs @@ -162,6 +162,30 @@ namespace Umbraco.Tests.Services.Importing Assert.That(contentMaster.PropertyGroups["SEO"].PropertyTypes.Any(x => x.PropertyGroupId.Value != propertyGroupId), Is.False); } + [Test] + public void PackagingService_Can_Import_StandardMvc_ContentTypes_And_Templates_Xml() + { + // Arrange + string strXml = ImportResources.StandardMvc_Package; + var xml = XElement.Parse(strXml); + var dataTypeElement = xml.Descendants("DataTypes").First(); + var templateElement = xml.Descendants("Templates").First(); + var docTypeElement = xml.Descendants("DocumentTypes").First(); + + // Act + var dataTypeDefinitions = ServiceContext.PackagingService.ImportDataTypeDefinitions(dataTypeElement); + var templates = ServiceContext.PackagingService.ImportTemplates(templateElement); + var contentTypes = ServiceContext.PackagingService.ImportContentTypes(docTypeElement); + var numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); + + //Assert - Re-Import contenttypes doesn't throw + Assert.DoesNotThrow(() => ServiceContext.PackagingService.ImportContentTypes(docTypeElement)); + Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes)); + Assert.That(dataTypeDefinitions, Is.Not.Null); + Assert.That(dataTypeDefinitions.Any(), Is.True); + Assert.That(templates.Any(), Is.True); + } + [Test] public void PackagingService_Can_Import_Content_Package_Xml() {