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()
{