Merge with 6.0.0
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Release\SQLCE4Umbraco.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version(6, 0, 0);
|
||||
private static readonly Version Version = new Version("6.0.0");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
public static string CurrentComment { get { return "RC"; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -7,10 +7,13 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Services;
|
||||
using MigrationsVersionFourNineZero = Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -40,7 +43,7 @@ namespace Umbraco.Core
|
||||
|
||||
//create database and service contexts for the app context
|
||||
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName);
|
||||
UmbracoDatabase.Mapper = new PetaPocoMapper();
|
||||
Database.Mapper = new PetaPocoMapper();
|
||||
var dbContext = new DatabaseContext(dbFactory);
|
||||
var serviceContext = new ServiceContext(
|
||||
new PetaPocoUnitOfWorkProvider(dbFactory),
|
||||
@@ -132,12 +135,33 @@ namespace Umbraco.Core
|
||||
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
|
||||
PluginManager.Current.ResolveMacroPropertyTypes());
|
||||
|
||||
//TODO: Y U NO WORK?
|
||||
//MigrationResolver.Current = new MigrationResolver(
|
||||
// PluginManager.Current.ResolveMigrationTypes());
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(new List<Type>
|
||||
{
|
||||
typeof (MigrationsVersionFourNineZero.RemoveUmbracoAppConstraints),
|
||||
typeof (DeleteAppTables),
|
||||
typeof (EnsureAppsTreesUpdated),
|
||||
typeof (MoveMasterContentTypeData),
|
||||
typeof (NewCmsContentType2ContentTypeTable),
|
||||
typeof (RemoveMasterContentTypeColumn),
|
||||
typeof (RenameCmsTabTable),
|
||||
typeof (RenameTabIdColumn),
|
||||
typeof (UpdateCmsContentTypeAllowedContentTypeTable),
|
||||
typeof (UpdateCmsContentTypeTable),
|
||||
typeof (UpdateCmsContentVersionTable),
|
||||
typeof (UpdateCmsPropertyTypeGroupTable)
|
||||
});
|
||||
|
||||
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
||||
//add the internal ones, these are not public currently so need to add them manually
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<DatePickerPropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<TinyMcePropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<YesNoPropertyEditorValueConverter>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -158,7 +159,7 @@ namespace Umbraco.Core
|
||||
var builder = new StringBuilder();
|
||||
foreach (var i in d)
|
||||
{
|
||||
builder.Append(String.Format("{0}={1}&", i.Key, i.Value));
|
||||
builder.Append(String.Format("{0}={1}&", HttpUtility.UrlEncode(i.Key), i.Value == null ? string.Empty : HttpUtility.UrlEncode(i.Value.ToString())));
|
||||
}
|
||||
return builder.ToString().TrimEnd('&');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Dynamic;
|
||||
using System.Reflection;
|
||||
@@ -11,7 +12,8 @@ using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
public class DynamicXml : DynamicObject, IEnumerable<DynamicXml>, IEnumerable<XElement>
|
||||
[TypeConverter(typeof(DynamicXmlConverter))]
|
||||
public class DynamicXml : DynamicObject, IEnumerable<DynamicXml>, IEnumerable<XElement>
|
||||
{
|
||||
public XElement BaseElement { get; set; }
|
||||
|
||||
@@ -213,6 +215,16 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the string version of Xml
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToXml();
|
||||
}
|
||||
|
||||
public IHtmlString ToHtml()
|
||||
{
|
||||
return new HtmlString(this.ToXml());
|
||||
|
||||
59
src/Umbraco.Core/Dynamics/DynamicXmlConverter.cs
Normal file
59
src/Umbraco.Core/Dynamics/DynamicXmlConverter.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom type converter for DynamicXml
|
||||
/// </summary>
|
||||
public class DynamicXmlConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
var convertableTypes = new[] {typeof(string), typeof(XElement), typeof(XmlElement), typeof(XmlDocument)};
|
||||
|
||||
return convertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, sourceType))
|
||||
|| base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
public override object ConvertTo(
|
||||
ITypeDescriptorContext context,
|
||||
CultureInfo culture,
|
||||
object value,
|
||||
Type destinationType)
|
||||
{
|
||||
var dxml = value as DynamicXml;
|
||||
if (dxml == null)
|
||||
return null;
|
||||
//string
|
||||
if (TypeHelper.IsTypeAssignableFrom<string>(destinationType))
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
//XElement
|
||||
if (TypeHelper.IsTypeAssignableFrom<XElement>(destinationType))
|
||||
{
|
||||
return dxml.BaseElement;
|
||||
}
|
||||
//XmlElement
|
||||
if (TypeHelper.IsTypeAssignableFrom<XmlElement>(destinationType))
|
||||
{
|
||||
var xDoc = new XmlDocument();
|
||||
xDoc.LoadXml(dxml.ToString());
|
||||
return xDoc.DocumentElement;
|
||||
}
|
||||
//XmlDocument
|
||||
if (TypeHelper.IsTypeAssignableFrom<XmlDocument>(destinationType))
|
||||
{
|
||||
var xDoc = new XmlDocument();
|
||||
xDoc.LoadXml(dxml.ToString());
|
||||
return xDoc;
|
||||
}
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/Umbraco.Core/Events/MigrationEventArgs.cs
Normal file
66
src/Umbraco.Core/Events/MigrationEventArgs.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
public class MigrationEventArgs : CancellableObjectEventArgs<IEnumerable<IMigration>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor accepting multiple migrations that are used in the migration runner
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="targetVersion"></param>
|
||||
/// <param name="canCancel"></param>
|
||||
/// <param name="configuredVersion"></param>
|
||||
public MigrationEventArgs(IEnumerable<IMigration> eventObject, Version configuredVersion, Version targetVersion, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{
|
||||
ConfiguredVersion = configuredVersion;
|
||||
TargetVersion = targetVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor accepting multiple migrations that are used in the migration runner
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="migrationContext"></param>
|
||||
/// <param name="targetVersion"></param>
|
||||
/// <param name="canCancel"></param>
|
||||
/// <param name="configuredVersion"></param>
|
||||
internal MigrationEventArgs(IEnumerable<IMigration> eventObject, MigrationContext migrationContext, Version configuredVersion, Version targetVersion, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{
|
||||
MigrationContext = migrationContext;
|
||||
ConfiguredVersion = configuredVersion;
|
||||
TargetVersion = targetVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor accepting multiple migrations that are used in the migration runner
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="configuredVersion"></param>
|
||||
/// <param name="targetVersion"></param>
|
||||
public MigrationEventArgs(IEnumerable<IMigration> eventObject, Version configuredVersion, Version targetVersion)
|
||||
: base(eventObject)
|
||||
{
|
||||
ConfiguredVersion = configuredVersion;
|
||||
TargetVersion = targetVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all migrations that were used in the migration runner
|
||||
/// </summary>
|
||||
public IEnumerable<IMigration> Migrations
|
||||
{
|
||||
get { return EventObject; }
|
||||
}
|
||||
|
||||
public Version ConfiguredVersion { get; private set; }
|
||||
|
||||
public Version TargetVersion { get; private set; }
|
||||
|
||||
internal MigrationContext MigrationContext { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using System.IO;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
public static class FileSystemExtensions
|
||||
{
|
||||
[UmbracoExperimentalFeature("", "Will be declared public after 4.10")]
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal static long GetSize(this IFileSystem fs, string path)
|
||||
{
|
||||
var s = fs.OpenFile(path);
|
||||
@@ -15,10 +16,22 @@ namespace Umbraco.Core.IO
|
||||
return size;
|
||||
}
|
||||
|
||||
[UmbracoExperimentalFeature("", "Will be declared public after 4.10")]
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal static void CopyFile(this IFileSystem fs, string path, string newPath)
|
||||
{
|
||||
fs.AddFile(newPath, fs.OpenFile(path));
|
||||
}
|
||||
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal static string GetExtension(this IFileSystem fs, string path)
|
||||
{
|
||||
return Path.GetExtension(fs.GetFullPath(path));
|
||||
}
|
||||
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal static string GetFileName(this IFileSystem fs, string path)
|
||||
{
|
||||
return Path.GetFileName(fs.GetFullPath(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ namespace Umbraco.Core.IO
|
||||
///
|
||||
/// This abstract class just wraps the 'real' IFileSystem object passed in to its constructor.
|
||||
/// </remarks>
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal abstract class FileSystemWrapper : IFileSystem
|
||||
public abstract class FileSystemWrapper : IFileSystem
|
||||
{
|
||||
private readonly IFileSystem _wrapped;
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal interface IFileSystem
|
||||
public interface IFileSystem
|
||||
{
|
||||
IEnumerable<string> GetDirectories(string path);
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ namespace Umbraco.Core.IO
|
||||
/// A custom file system provider for media
|
||||
/// </summary>
|
||||
[FileSystemProvider("media")]
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class MediaFileSystem : FileSystemWrapper
|
||||
public class MediaFileSystem : FileSystemWrapper
|
||||
{
|
||||
public MediaFileSystem(IFileSystem wrapped)
|
||||
: base(wrapped)
|
||||
|
||||
@@ -10,16 +10,19 @@ using Umbraco.Core.Publishing;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class PhysicalFileSystem : IFileSystem
|
||||
public class PhysicalFileSystem : IFileSystem
|
||||
{
|
||||
private readonly string _rootPath;
|
||||
internal string RootPath { get; private set; }
|
||||
private readonly string _rootUrl;
|
||||
|
||||
public PhysicalFileSystem(string virtualRoot)
|
||||
{
|
||||
_rootPath = System.Web.Hosting.HostingEnvironment.MapPath(virtualRoot);
|
||||
_rootUrl = VirtualPathUtility.ToAbsolute(virtualRoot);
|
||||
if (virtualRoot == null) throw new ArgumentNullException("virtualRoot");
|
||||
if (!virtualRoot.StartsWith("~/"))
|
||||
throw new ArgumentException("The virtualRoot argument must be a virtual path and start with '~/'");
|
||||
|
||||
RootPath = IOHelper.MapPath(virtualRoot);
|
||||
_rootUrl = IOHelper.ResolveUrl(virtualRoot);
|
||||
}
|
||||
|
||||
public PhysicalFileSystem(string rootPath, string rootUrl)
|
||||
@@ -30,7 +33,10 @@ namespace Umbraco.Core.IO
|
||||
if (string.IsNullOrEmpty(rootUrl))
|
||||
throw new ArgumentException("The argument 'rootUrl' cannot be null or empty.");
|
||||
|
||||
_rootPath = rootPath;
|
||||
if (rootPath.StartsWith("~/"))
|
||||
throw new ArgumentException("The rootPath argument cannot be a virtual path and cannot start with '~/'");
|
||||
|
||||
RootPath = rootPath;
|
||||
_rootUrl = rootUrl;
|
||||
}
|
||||
|
||||
@@ -141,7 +147,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
LogHelper.Info<PublishingStrategy>(string.Format("DeleteFile failed with FileNotFoundException: {0}", ex.InnerException));
|
||||
LogHelper.Info<PhysicalFileSystem>(string.Format("DeleteFile failed with FileNotFoundException: {0}", ex.InnerException));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,17 +156,12 @@ namespace Umbraco.Core.IO
|
||||
return File.Exists(GetFullPath(path));
|
||||
}
|
||||
|
||||
public string GetExtension(string path)
|
||||
{
|
||||
return Path.GetExtension(GetFullPath(path));
|
||||
}
|
||||
|
||||
public string GetRelativePath(string fullPathOrUrl)
|
||||
{
|
||||
var relativePath = fullPathOrUrl
|
||||
.TrimStart(_rootUrl)
|
||||
.Replace('/', Path.DirectorySeparatorChar)
|
||||
.TrimStart(_rootPath)
|
||||
.TrimStart(RootPath)
|
||||
.TrimStart(Path.DirectorySeparatorChar);
|
||||
|
||||
return relativePath;
|
||||
@@ -168,8 +169,8 @@ namespace Umbraco.Core.IO
|
||||
|
||||
public string GetFullPath(string path)
|
||||
{
|
||||
return !path.StartsWith(_rootPath)
|
||||
? Path.Combine(_rootPath, path)
|
||||
return !path.StartsWith(RootPath)
|
||||
? Path.Combine(RootPath, path)
|
||||
: path;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,25 +19,28 @@ namespace Umbraco.Core.Models
|
||||
private DateTime? _releaseDate;
|
||||
private DateTime? _expireDate;
|
||||
private int _writer;
|
||||
private string _nodeName;
|
||||
private string _nodeName;//NOTE Once localization is introduced this will be the non-localized Node Name.
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating a Content object
|
||||
/// </summary>
|
||||
/// <param name="parentId">Id of the Parent content</param>
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
public Content(int parentId, IContentType contentType)
|
||||
: this(parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
}
|
||||
|
||||
public Content(IContent parent, IContentType contentType)
|
||||
: this(parent, contentType, new PropertyCollection())
|
||||
public Content(string name, IContent parent, IContentType contentType)
|
||||
: this(name, parent, contentType, new PropertyCollection())
|
||||
{
|
||||
}
|
||||
|
||||
public Content(IContent parent, IContentType contentType, PropertyCollection properties)
|
||||
: base(parent, contentType, properties)
|
||||
/// <summary>
|
||||
/// Constructor for creating a Content object
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
/// <param name="properties">Collection of properties</param>
|
||||
public Content(string name, IContent parent, IContentType contentType, PropertyCollection properties)
|
||||
: base(name, parent, contentType, properties)
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
@@ -47,11 +50,23 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Constructor for creating a Content object
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="parentId">Id of the Parent content</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
public Content(string name, int parentId, IContentType contentType)
|
||||
: this(name, parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating a Content object
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="parentId">Id of the Parent content</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
/// <param name="properties">Collection of properties</param>
|
||||
public Content(int parentId, IContentType contentType, PropertyCollection properties)
|
||||
: base(parentId, contentType, properties)
|
||||
public Content(string name, int parentId, IContentType contentType, PropertyCollection properties)
|
||||
: base(name, parentId, contentType, properties)
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
@@ -189,6 +204,12 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of the Node (non-localized).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This Property is kept internal until localization is introduced.
|
||||
/// </remarks>
|
||||
internal string NodeName
|
||||
{
|
||||
get { return _nodeName; }
|
||||
@@ -246,20 +267,20 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Changes the Published state of the content object
|
||||
/// </summary>
|
||||
/// <param name="isPublished">Boolean indicating whether content is published (true) or unpublished (false)</param>
|
||||
public void ChangePublishedState(bool isPublished)
|
||||
public void ChangePublishedState(PublishedState state)
|
||||
{
|
||||
Published = isPublished;
|
||||
//NOTE Should this be checked against the Expire/Release dates?
|
||||
//TODO possibly create new (unpublished version)?
|
||||
Published = state == PublishedState.Published;
|
||||
PublishedState = state;
|
||||
}
|
||||
|
||||
internal PublishedState PublishedState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Trashed state of the content object
|
||||
/// </summary>
|
||||
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
|
||||
/// <param name="parentId"> </param>
|
||||
public void ChangeTrashedState(bool isTrashed, int parentId = -1)
|
||||
public override void ChangeTrashedState(bool isTrashed, int parentId = -1)
|
||||
{
|
||||
Trashed = isTrashed;
|
||||
|
||||
@@ -276,7 +297,7 @@ namespace Umbraco.Core.Models
|
||||
//If the content is trashed and is published it should be marked as unpublished
|
||||
if (isTrashed && Published)
|
||||
{
|
||||
ChangePublishedState(false);
|
||||
ChangePublishedState(PublishedState.Unpublished);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
@@ -16,7 +17,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
protected IContentTypeComposition ContentTypeBase;
|
||||
private Lazy<int> _parentId;
|
||||
private string _name;
|
||||
private string _name;//NOTE Once localization is introduced this will be the localized Name of the Content/Media.
|
||||
private int _sortOrder;
|
||||
private int _level;
|
||||
private string _path;
|
||||
@@ -25,34 +26,50 @@ namespace Umbraco.Core.Models
|
||||
private int _contentTypeId;
|
||||
private PropertyCollection _properties;
|
||||
|
||||
protected ContentBase(int parentId, IContentTypeComposition contentType, PropertyCollection properties)
|
||||
/// <summary>
|
||||
/// Protected constructor for ContentBase (Base for Content and Media)
|
||||
/// </summary>
|
||||
/// <param name="name">Localized Name of the entity</param>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="properties"></param>
|
||||
protected ContentBase(string name, int parentId, IContentTypeComposition contentType, PropertyCollection properties)
|
||||
{
|
||||
Mandate.ParameterCondition(parentId != 0, "parentId");
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
Mandate.ParameterNotNull(properties, "properties");
|
||||
|
||||
_parentId = new Lazy<int>(() => parentId);
|
||||
|
||||
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
|
||||
ContentTypeBase = contentType;
|
||||
Version = Guid.NewGuid();
|
||||
|
||||
_parentId = new Lazy<int>(() => parentId);
|
||||
_name = name;
|
||||
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
|
||||
_properties = properties;
|
||||
_properties.EnsurePropertyTypes(PropertyTypes);
|
||||
Version = Guid.NewGuid();
|
||||
}
|
||||
|
||||
protected ContentBase(IContentBase parent, IContentTypeComposition contentType, PropertyCollection properties)
|
||||
/// <summary>
|
||||
/// Protected constructor for ContentBase (Base for Content and Media)
|
||||
/// </summary>
|
||||
/// <param name="name">Localized Name of the entity</param>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="properties"></param>
|
||||
protected ContentBase(string name, IContentBase parent, IContentTypeComposition contentType, PropertyCollection properties)
|
||||
{
|
||||
Mandate.ParameterNotNull(parent, "parent");
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
Mandate.ParameterNotNull(properties, "properties");
|
||||
|
||||
_parentId = new Lazy<int>(() => parent.Id);
|
||||
ContentTypeBase = contentType;
|
||||
Version = Guid.NewGuid();
|
||||
|
||||
_parentId = new Lazy<int>(() => parent.Id);
|
||||
_name = name;
|
||||
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
|
||||
ContentTypeBase = contentType;
|
||||
_properties = properties;
|
||||
_properties.EnsurePropertyTypes(PropertyTypes);
|
||||
Version = Guid.NewGuid();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentBase, string>(x => x.Name);
|
||||
@@ -256,11 +273,110 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a Property
|
||||
/// Sets the <see cref="System.Object"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetValue(string propertyTypeAlias, object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
SetValueOnProperty(propertyTypeAlias, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// .NET magic to call one of the 'SetPropertyValue' handlers with matching signature
|
||||
((dynamic)this).SetPropertyValue(propertyTypeAlias, (dynamic)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.String"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, string value)
|
||||
{
|
||||
SetValueOnProperty(propertyTypeAlias, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.Int32"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, int value)
|
||||
{
|
||||
SetValueOnProperty(propertyTypeAlias, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.Int64"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, long value)
|
||||
{
|
||||
string val = value.ToString();
|
||||
SetValueOnProperty(propertyTypeAlias, val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.Boolean"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, bool value)
|
||||
{
|
||||
int val = Convert.ToInt32(value);
|
||||
SetValueOnProperty(propertyTypeAlias, val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.DateTime"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, DateTime value)
|
||||
{
|
||||
SetValueOnProperty(propertyTypeAlias, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.Web.HttpPostedFile"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, HttpPostedFile value)
|
||||
{
|
||||
ContentExtensions.SetValue(this, propertyTypeAlias, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.Web.HttpPostedFileBase"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, HttpPostedFileBase value)
|
||||
{
|
||||
ContentExtensions.SetValue(this, propertyTypeAlias, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="System.Web.HttpPostedFileWrapper"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
public virtual void SetPropertyValue(string propertyTypeAlias, HttpPostedFileWrapper value)
|
||||
{
|
||||
ContentExtensions.SetValue(this, propertyTypeAlias, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private method to set the value of a property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <param name="value"></param>
|
||||
private void SetValueOnProperty(string propertyTypeAlias, object value)
|
||||
{
|
||||
if (Properties.Contains(propertyTypeAlias))
|
||||
{
|
||||
@@ -284,5 +400,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
return Properties.Any(property => !property.IsValid()) == false;
|
||||
}
|
||||
|
||||
public abstract void ChangeTrashedState(bool isTrashed, int parentId = -1);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
@@ -53,13 +54,14 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Sets and uploads the file from a HttpPostedFileBase object as the property value
|
||||
/// </summary>
|
||||
/// <param name="media"><see cref="IMedia"/> to add property value to</param>
|
||||
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
|
||||
/// <param name="value">The <see cref="HttpPostedFileBase"/> containing the file that will be uploaded</param>
|
||||
public static void SetValue(this IMedia media, string propertyTypeAlias, HttpPostedFileBase value)
|
||||
public static void SetPropertyValue(this IMedia media, string propertyTypeAlias, HttpPostedFileBase value)
|
||||
{
|
||||
var name =
|
||||
IOHelper.SafeFileName(
|
||||
@@ -77,7 +79,7 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="media"><see cref="IMedia"/> to add property value to</param>
|
||||
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
|
||||
/// <param name="value">The <see cref="HttpPostedFile"/> containing the file that will be uploaded</param>
|
||||
public static void SetValue(this IMedia media, string propertyTypeAlias, HttpPostedFile value)
|
||||
public static void SetPropertyValue(this IMedia media, string propertyTypeAlias, HttpPostedFile value)
|
||||
{
|
||||
var name =
|
||||
IOHelper.SafeFileName(
|
||||
@@ -95,19 +97,19 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="media"><see cref="IMedia"/> to add property value to</param>
|
||||
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
|
||||
/// <param name="value">The <see cref="HttpPostedFileWrapper"/> containing the file that will be uploaded</param>
|
||||
public static void SetValue(this IMedia media, string propertyTypeAlias, HttpPostedFileWrapper value)
|
||||
public static void SetPropertyValue(this IMedia media, string propertyTypeAlias, HttpPostedFileWrapper value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value.FileName) == false)
|
||||
SetFileOnContent(media, propertyTypeAlias, value.FileName, value.InputStream);
|
||||
}
|
||||
|
||||
*/
|
||||
/// <summary>
|
||||
/// Sets and uploads the file from a HttpPostedFileBase object as the property value
|
||||
/// </summary>
|
||||
/// <param name="content"><see cref="IContent"/> to add property value to</param>
|
||||
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
|
||||
/// <param name="value">The <see cref="HttpPostedFileBase"/> containing the file that will be uploaded</param>
|
||||
public static void SetValue(this IContent content, string propertyTypeAlias, HttpPostedFileBase value)
|
||||
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value)
|
||||
{
|
||||
var name =
|
||||
IOHelper.SafeFileName(
|
||||
@@ -125,7 +127,7 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="content"><see cref="IContent"/> to add property value to</param>
|
||||
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
|
||||
/// <param name="value">The <see cref="HttpPostedFile"/> containing the file that will be uploaded</param>
|
||||
public static void SetValue(this IContent content, string propertyTypeAlias, HttpPostedFile value)
|
||||
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFile value)
|
||||
{
|
||||
var name =
|
||||
IOHelper.SafeFileName(
|
||||
@@ -143,7 +145,7 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="content"><see cref="IContent"/> to add property value to</param>
|
||||
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
|
||||
/// <param name="value">The <see cref="HttpPostedFileWrapper"/> containing the file that will be uploaded</param>
|
||||
public static void SetValue(this IContent content, string propertyTypeAlias, HttpPostedFileWrapper value)
|
||||
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileWrapper value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value.FileName) == false)
|
||||
SetFileOnContent(content, propertyTypeAlias, value.FileName, value.InputStream);
|
||||
@@ -174,10 +176,10 @@ namespace Umbraco.Core.Models
|
||||
|
||||
//Look up Prevalues for this upload datatype - if it is an upload datatype
|
||||
var uploadFieldId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
|
||||
if (property.PropertyType.DataTypeControlId == uploadFieldId)
|
||||
if (property.PropertyType.DataTypeId == uploadFieldId)
|
||||
{
|
||||
//Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
|
||||
var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeId);
|
||||
var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId);
|
||||
var thumbnailSizes = values.FirstOrDefault();
|
||||
//Additional thumbnails configured as prevalues on the DataType
|
||||
if (thumbnailSizes != null)
|
||||
@@ -208,8 +210,8 @@ namespace Umbraco.Core.Models
|
||||
//Only add dimensions to web images
|
||||
if (supportsResizing)
|
||||
{
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", GetDimensions(fs, fileName).Item1);
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", GetDimensions(fs, fileName).Item2);
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", GetDimensions(fs, fileName).Item1.ToString(CultureInfo.InvariantCulture));
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", GetDimensions(fs, fileName).Item2.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -217,7 +219,7 @@ namespace Umbraco.Core.Models
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", string.Empty);
|
||||
}
|
||||
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "lengthFieldAlias", fs.GetSize(fileName));
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "lengthFieldAlias", fs.GetSize(fileName).ToString(CultureInfo.InvariantCulture));
|
||||
SetPropertyValue(content, uploadFieldConfigNode, "extensionFieldAlias", extension);
|
||||
}
|
||||
}
|
||||
@@ -226,7 +228,7 @@ namespace Umbraco.Core.Models
|
||||
property.Value = fs.GetUrl(fileName);
|
||||
}
|
||||
|
||||
private static void SetPropertyValue(IContentBase content, XmlNode uploadFieldConfigNode, string propertyAlias, object propertyValue)
|
||||
private static void SetPropertyValue(IContentBase content, XmlNode uploadFieldConfigNode, string propertyAlias, string propertyValue)
|
||||
{
|
||||
XmlNode propertyNode = uploadFieldConfigNode.SelectSingleNode(propertyAlias);
|
||||
if (propertyNode != null && string.IsNullOrEmpty(propertyNode.FirstChild.Value) == false)
|
||||
@@ -403,9 +405,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
||||
//var nodeName = content.ContentType.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true);
|
||||
var nodeName = content.ContentType.Alias;
|
||||
|
||||
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : content.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
||||
var x = content.ToXml(nodeName);
|
||||
x.Add(new XAttribute("nodeType", content.ContentType.Id));
|
||||
x.Add(new XAttribute("creatorName", content.GetCreatorProfile().Name));
|
||||
@@ -458,7 +458,8 @@ namespace Umbraco.Core.Models
|
||||
new XAttribute("nodeName", contentBase.Name),
|
||||
new XAttribute("urlName", niceUrl),//Format Url ?
|
||||
new XAttribute("path", contentBase.Path),
|
||||
new XAttribute("isDoc", ""));
|
||||
new XAttribute("isDoc", ""),
|
||||
UmbracoSettings.UseLegacyXmlSchema ? new XAttribute("nodeTypeAlias", content.ContentType.Alias) : null);
|
||||
|
||||
foreach (var property in contentBase.Properties)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,12 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="template">Default <see cref="ITemplate"/></param>
|
||||
public void SetDefaultTemplate(ITemplate template)
|
||||
{
|
||||
if (template == null)
|
||||
{
|
||||
DefaultTemplateId = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
DefaultTemplateId = template.Id;
|
||||
if(_allowedTemplates.Any(x => x != null && x.Id == template.Id) == false)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
@@ -29,6 +30,7 @@ namespace Umbraco.Core.Models
|
||||
private bool _isContainer;
|
||||
private bool _trashed;
|
||||
private PropertyGroupCollection _propertyGroups;
|
||||
private PropertyTypeCollection _propertyTypes;
|
||||
private IEnumerable<ContentTypeSort> _allowedContentTypes;
|
||||
|
||||
protected ContentTypeBase(int parentId)
|
||||
@@ -38,6 +40,7 @@ namespace Umbraco.Core.Models
|
||||
_parentId = new Lazy<int>(() => parentId);
|
||||
_allowedContentTypes = new List<ContentTypeSort>();
|
||||
_propertyGroups = new PropertyGroupCollection();
|
||||
_propertyTypes = new PropertyTypeCollection();
|
||||
}
|
||||
|
||||
protected ContentTypeBase(IContentTypeBase parent)
|
||||
@@ -47,6 +50,7 @@ namespace Umbraco.Core.Models
|
||||
_parentId = new Lazy<int>(() => parent.Id);
|
||||
_allowedContentTypes = new List<ContentTypeSort>();
|
||||
_propertyGroups = new PropertyGroupCollection();
|
||||
_propertyTypes = new PropertyTypeCollection();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, string>(x => x.Name);
|
||||
@@ -64,12 +68,18 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.Trashed);
|
||||
private static readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<ContentTypeSort>>(x => x.AllowedContentTypes);
|
||||
private static readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, PropertyGroupCollection>(x => x.PropertyGroups);
|
||||
private static readonly PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<PropertyType>>(x => x.PropertyTypes);
|
||||
|
||||
protected void PropertyGroupsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(PropertyGroupCollectionSelector);
|
||||
}
|
||||
|
||||
protected void PropertyTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(PropertyTypeCollectionSelector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Id of the Parent entity
|
||||
/// </summary>
|
||||
@@ -144,7 +154,12 @@ namespace Umbraco.Core.Models
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
_alias = value;
|
||||
//Ensures a valid ContentType alias
|
||||
//Would have liked to use .ToUmbracoAlias() but that would break casing upon saving older/upgraded ContentTypes
|
||||
var result = Regex.Replace(value, @"[^a-zA-Z0-9\s\.-]+", "", RegexOptions.Compiled);
|
||||
result = result.Replace(" ", "");
|
||||
|
||||
_alias = result;
|
||||
OnPropertyChanged(AliasSelector);
|
||||
}
|
||||
}
|
||||
@@ -301,7 +316,16 @@ namespace Umbraco.Core.Models
|
||||
[IgnoreDataMember]
|
||||
public virtual IEnumerable<PropertyType> PropertyTypes
|
||||
{
|
||||
get { return PropertyGroups.SelectMany(x => x.PropertyTypes); }
|
||||
get
|
||||
{
|
||||
var types = _propertyTypes.Union(PropertyGroups.SelectMany(x => x.PropertyTypes));
|
||||
return types;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_propertyTypes = new PropertyTypeCollection(value);
|
||||
_propertyTypes.CollectionChanged += PropertyTypesChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -69,14 +69,6 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Changes the Published state of the content object
|
||||
/// </summary>
|
||||
/// <param name="isPublished">Boolean indicating whether content is published (true) or unpublished (false)</param>
|
||||
void ChangePublishedState(bool isPublished);
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Trashed state of the content object
|
||||
/// </summary>
|
||||
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
|
||||
/// <param name="parentId"> </param>
|
||||
void ChangeTrashedState(bool isTrashed, int parentId = -1);
|
||||
void ChangePublishedState(PublishedState state);
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ namespace Umbraco.Core.Models
|
||||
TPassType GetValue<TPassType>(string propertyTypeAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a Property
|
||||
/// Sets the <see cref="System.Object"/> value of a Property
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
|
||||
/// <param name="value">Value to set for the Property</param>
|
||||
@@ -77,5 +77,12 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <returns>True if content is valid otherwise false</returns>
|
||||
bool IsValid();
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Trashed state of the content object
|
||||
/// </summary>
|
||||
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
|
||||
/// <param name="parentId"> </param>
|
||||
void ChangeTrashedState(bool isTrashed, int parentId = -1);
|
||||
}
|
||||
}
|
||||
@@ -15,20 +15,23 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Constructor for creating a Media object
|
||||
/// </summary>
|
||||
/// <param name="parentId"> </param>
|
||||
/// <param name="name">ame of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> object</param>
|
||||
/// <param name="contentType">MediaType for the current Media object</param>
|
||||
public Media(int parentId, IMediaType contentType)
|
||||
: this(parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
}
|
||||
|
||||
public Media(IMedia parent, IMediaType contentType)
|
||||
: this(parent, contentType, new PropertyCollection())
|
||||
public Media(string name, IMedia parent, IMediaType contentType)
|
||||
: this(name, parent, contentType, new PropertyCollection())
|
||||
{
|
||||
}
|
||||
|
||||
public Media(IMedia parent, IMediaType contentType, PropertyCollection properties)
|
||||
: base(parent, contentType, properties)
|
||||
/// <summary>
|
||||
/// Constructor for creating a Media object
|
||||
/// </summary>
|
||||
/// <param name="name">ame of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> object</param>
|
||||
/// <param name="contentType">MediaType for the current Media object</param>
|
||||
/// <param name="properties">Collection of properties</param>
|
||||
public Media(string name, IMedia parent, IMediaType contentType, PropertyCollection properties)
|
||||
: base(name, parent, contentType, properties)
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
_contentType = contentType;
|
||||
@@ -37,10 +40,23 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Constructor for creating a Media object
|
||||
/// </summary>
|
||||
/// <param name="parentId"> </param>
|
||||
/// <param name="name">ame of the Media object</param>
|
||||
/// <param name="parentId">Id of the Parent IMedia</param>
|
||||
/// <param name="contentType">MediaType for the current Media object</param>
|
||||
public Media(string name, int parentId, IMediaType contentType)
|
||||
: this(name, parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating a Media object
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of the Parent IMedia</param>
|
||||
/// <param name="contentType">MediaType for the current Media object</param>
|
||||
/// <param name="properties">Collection of properties</param>
|
||||
public Media(int parentId, IMediaType contentType, PropertyCollection properties) : base(parentId, contentType, properties)
|
||||
public Media(string name, int parentId, IMediaType contentType, PropertyCollection properties)
|
||||
: base(name, parentId, contentType, properties)
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
_contentType = contentType;
|
||||
@@ -95,7 +111,7 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
|
||||
/// <param name="parentId"> </param>
|
||||
internal void ChangeTrashedState(bool isTrashed, int parentId = -1)
|
||||
public override void ChangeTrashedState(bool isTrashed, int parentId = -1)
|
||||
{
|
||||
Trashed = isTrashed;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -13,7 +14,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml of the property and its value</returns>
|
||||
public static XElement ToXml(this Property property)
|
||||
{
|
||||
string nodeName = property.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true);
|
||||
string nodeName = UmbracoSettings.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
|
||||
|
||||
var xd = new XmlDocument();
|
||||
XmlNode xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, "");
|
||||
|
||||
@@ -17,8 +17,9 @@ namespace Umbraco.Core.Models
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private string _description;
|
||||
private int _dataTypeId;
|
||||
private Guid _dataTypeControlId;
|
||||
private int _dataTypeDefinitionId;
|
||||
private int _propertyGroupId;
|
||||
private Guid _dataTypeId;
|
||||
private DataTypeDatabaseType _dataTypeDatabaseType;
|
||||
private bool _mandatory;
|
||||
private string _helpText;
|
||||
@@ -28,9 +29,9 @@ namespace Umbraco.Core.Models
|
||||
public PropertyType(IDataTypeDefinition dataTypeDefinition)
|
||||
{
|
||||
if(dataTypeDefinition.HasIdentity)
|
||||
DataTypeId = dataTypeDefinition.Id;
|
||||
DataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
|
||||
DataTypeControlId = dataTypeDefinition.ControlId;
|
||||
DataTypeId = dataTypeDefinition.ControlId;
|
||||
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
|
||||
EnsureSerializationService();
|
||||
@@ -38,7 +39,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
internal PropertyType(Guid dataTypeControlId, DataTypeDatabaseType dataTypeDatabaseType)
|
||||
{
|
||||
DataTypeControlId = dataTypeControlId;
|
||||
DataTypeId = dataTypeControlId;
|
||||
DataTypeDatabaseType = dataTypeDatabaseType;
|
||||
|
||||
EnsureSerializationService();
|
||||
@@ -53,13 +54,14 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Alias);
|
||||
private static readonly PropertyInfo DescriptionSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Description);
|
||||
private static readonly PropertyInfo DataTypeIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.DataTypeId);
|
||||
private static readonly PropertyInfo DataTypeControlIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, Guid>(x => x.DataTypeControlId);
|
||||
private static readonly PropertyInfo DataTypeDefinitionIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.DataTypeDefinitionId);
|
||||
private static readonly PropertyInfo DataTypeControlIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, Guid>(x => x.DataTypeId);
|
||||
private static readonly PropertyInfo DataTypeDatabaseTypeSelector = ExpressionHelper.GetPropertyInfo<PropertyType, DataTypeDatabaseType>(x => x.DataTypeDatabaseType);
|
||||
private static readonly PropertyInfo MandatorySelector = ExpressionHelper.GetPropertyInfo<PropertyType, bool>(x => x.Mandatory);
|
||||
private static readonly PropertyInfo HelpTextSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.HelpText);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo ValidationRegExpSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.ValidationRegExp);
|
||||
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.PropertyGroupId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets of Sets the Name of the PropertyType
|
||||
@@ -108,13 +110,13 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <remarks>This is actually the Id of the <see cref="IDataTypeDefinition"/></remarks>
|
||||
[DataMember]
|
||||
public int DataTypeId
|
||||
public int DataTypeDefinitionId
|
||||
{
|
||||
get { return _dataTypeId; }
|
||||
get { return _dataTypeDefinitionId; }
|
||||
set
|
||||
{
|
||||
_dataTypeId = value;
|
||||
OnPropertyChanged(DataTypeIdSelector);
|
||||
_dataTypeDefinitionId = value;
|
||||
OnPropertyChanged(DataTypeDefinitionIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,12 +125,12 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <remarks>This is the Id of the actual DataType control</remarks>
|
||||
[DataMember]
|
||||
internal Guid DataTypeControlId
|
||||
public Guid DataTypeId
|
||||
{
|
||||
get { return _dataTypeControlId; }
|
||||
set
|
||||
get { return _dataTypeId; }
|
||||
internal set
|
||||
{
|
||||
_dataTypeControlId = value;
|
||||
_dataTypeId = value;
|
||||
OnPropertyChanged(DataTypeControlIdSelector);
|
||||
}
|
||||
}
|
||||
@@ -147,6 +149,20 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets the PropertyGroup's Id for which this PropertyType belongs
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal int PropertyGroupId
|
||||
{
|
||||
get { return _propertyGroupId; }
|
||||
set
|
||||
{
|
||||
_propertyGroupId = value;
|
||||
OnPropertyChanged(PropertyGroupIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets of Sets the Boolean indicating whether a value for this PropertyType is required
|
||||
/// </summary>
|
||||
@@ -280,7 +296,7 @@ namespace Umbraco.Core.Models
|
||||
return argument == type;
|
||||
}*/
|
||||
|
||||
if (DataTypeControlId != Guid.Empty)
|
||||
if (DataTypeId != Guid.Empty)
|
||||
{
|
||||
//Find DataType by Id
|
||||
//IDataType dataType = DataTypesResolver.Current.GetById(DataTypeControlId);
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Umbraco.Core.Models
|
||||
internal static IDataType DataType(this PropertyType propertyType, int propertyId)
|
||||
{
|
||||
Mandate.ParameterNotNull(propertyType, "propertyType");
|
||||
var dataType = ApplicationContext.Current.Services.DataTypeService.GetDataTypeById(propertyType.DataTypeControlId);
|
||||
dataType.DataTypeDefinitionId = propertyType.DataTypeId;
|
||||
var dataType = ApplicationContext.Current.Services.DataTypeService.GetDataTypeById(propertyType.DataTypeId);
|
||||
dataType.DataTypeDefinitionId = propertyType.DataTypeDefinitionId;
|
||||
dataType.Data.PropertyId = propertyId;
|
||||
return dataType;
|
||||
}
|
||||
|
||||
9
src/Umbraco.Core/Models/PublishedState.cs
Normal file
9
src/Umbraco.Core/Models/PublishedState.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public enum PublishedState
|
||||
{
|
||||
Published,
|
||||
Unpublished,
|
||||
Saved
|
||||
}
|
||||
}
|
||||
@@ -43,11 +43,6 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[Constraint(Default = "0")]
|
||||
public bool AllowAtRoot { get; set; }
|
||||
|
||||
[Column("masterContentType")]
|
||||
[Constraint(Default = "0")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public int MasterContentType { get; set; }//TODO Delete once "masterContentType" has been removed from the Core
|
||||
|
||||
[ResultColumn]
|
||||
public NodeDto NodeDto { get; set; }
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
public int ContentTypeNodeId { get; set; }
|
||||
|
||||
[Column("templateNodeId")]
|
||||
/*[ForeignKey(typeof(TemplateDto))]*/
|
||||
[ForeignKey(typeof(TemplateDto), Column = "nodeId")]
|
||||
public int TemplateNodeId { get; set; }
|
||||
|
||||
[Column("IsDefault")]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Caching;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Caching
|
||||
@@ -23,9 +24,10 @@ namespace Umbraco.Core.Persistence.Caching
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly ObjectCache _memoryCache = new MemoryCache("in-memory");
|
||||
//TODO Save this in cache as well, so its not limited to a single server usage
|
||||
private ConcurrentDictionary<string, string> _keyTracker = new ConcurrentDictionary<string, string>();
|
||||
private ObjectCache _memoryCache = new MemoryCache("in-memory");
|
||||
private static readonly ReaderWriterLockSlim ClearLock = new ReaderWriterLockSlim();
|
||||
|
||||
public IEntity GetById(Type type, Guid id)
|
||||
{
|
||||
@@ -77,6 +79,16 @@ namespace Umbraco.Core.Persistence.Caching
|
||||
_keyTracker.TryRemove(key, out throwaway);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
using (new ReadLock(ClearLock))
|
||||
{
|
||||
_keyTracker.Clear();
|
||||
_memoryCache.DisposeIfDisposable();
|
||||
_memoryCache = new MemoryCache("in-memory");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetCompositeId(Type type, Guid id)
|
||||
{
|
||||
return string.Format("{0}-{1}", type.Name, id.ToString());
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public IContent BuildEntity(DocumentDto dto)
|
||||
{
|
||||
return new Content(dto.ContentVersionDto.ContentDto.NodeDto.ParentId, _contentType)
|
||||
return new Content(dto.Text, dto.ContentVersionDto.ContentDto.NodeDto.ParentId, _contentType)
|
||||
{
|
||||
Id = _id,
|
||||
Key =
|
||||
@@ -57,20 +57,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public DocumentDto BuildDto(IContent entity)
|
||||
{
|
||||
//NOTE Currently doesn't add Alias and templateId (legacy stuff that eventually will go away)
|
||||
//NOTE Currently doesn't add Alias (legacy that eventually will go away)
|
||||
var documentDto = new DocumentDto
|
||||
{
|
||||
Newest = true,
|
||||
NodeId = entity.Id,
|
||||
Published = entity.Published,
|
||||
Text = entity.Name,
|
||||
UpdateDate = entity.UpdateDate,
|
||||
WriterUserId = entity.WriterId,
|
||||
VersionId = entity.Version,
|
||||
ExpiresDate = null,
|
||||
ReleaseDate = null,
|
||||
ContentVersionDto = BuildContentVersionDto(entity)
|
||||
};
|
||||
{
|
||||
Newest = true,
|
||||
NodeId = entity.Id,
|
||||
Published = entity.Published,
|
||||
Text = entity.Name,
|
||||
UpdateDate = entity.UpdateDate,
|
||||
WriterUserId = entity.WriterId,
|
||||
VersionId = entity.Version,
|
||||
ExpiresDate = null,
|
||||
ReleaseDate = null,
|
||||
ContentVersionDto = BuildContentVersionDto(entity)
|
||||
};
|
||||
|
||||
if (entity.Template != null && entity.Template.Id > 0)
|
||||
documentDto.TemplateId = entity.Template.Id;
|
||||
|
||||
if (entity.ExpireDate.HasValue)
|
||||
documentDto.ExpiresDate = entity.ExpireDate.Value;
|
||||
|
||||
@@ -29,14 +29,13 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public IMedia BuildEntity(ContentVersionDto dto)
|
||||
{
|
||||
return new Models.Media(dto.ContentDto.NodeDto.ParentId, _contentType)
|
||||
return new Models.Media(dto.ContentDto.NodeDto.Text, dto.ContentDto.NodeDto.ParentId, _contentType)
|
||||
{
|
||||
Id = _id,
|
||||
Key =
|
||||
dto.ContentDto.NodeDto.UniqueId.HasValue
|
||||
? dto.ContentDto.NodeDto.UniqueId.Value
|
||||
: _id.ToGuid(),
|
||||
Name = dto.ContentDto.NodeDto.Text,
|
||||
Path = dto.ContentDto.NodeDto.Path,
|
||||
CreatorId = dto.ContentDto.NodeDto.UserId.Value,
|
||||
Level = dto.ContentDto.NodeDto.Level,
|
||||
|
||||
@@ -32,13 +32,19 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public IEnumerable<Property> BuildEntity(IEnumerable<PropertyDataDto> dtos)
|
||||
{
|
||||
var properties = new List<Property>();
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var propertyType = _contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Id == dto.PropertyTypeId);
|
||||
var property = propertyType.CreatePropertyFromRawValue(dto.GetValue, dto.VersionId.Value, dto.Id);
|
||||
property.ResetDirtyProperties();
|
||||
properties.Add(property);
|
||||
if (_contentType.CompositionPropertyTypes.Any(x => x.Id == dto.PropertyTypeId))
|
||||
{
|
||||
var propertyType = _contentType.CompositionPropertyTypes.First(x => x.Id == dto.PropertyTypeId);
|
||||
var property = propertyType.CreatePropertyFromRawValue(dto.GetValue, dto.VersionId.Value, dto.Id);
|
||||
|
||||
property.ResetDirtyProperties();
|
||||
properties.Add(property);
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
@@ -95,10 +101,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
var properties = new List<Property>();
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var propertyType = _mediaType.PropertyTypes.FirstOrDefault(x => x.Id == dto.PropertyTypeId);
|
||||
var property = propertyType.CreatePropertyFromRawValue(dto.GetValue, dto.VersionId.Value, dto.Id);
|
||||
property.ResetDirtyProperties();
|
||||
properties.Add(property);
|
||||
if (_mediaType.CompositionPropertyTypes.Any(x => x.Id == dto.PropertyTypeId))
|
||||
{
|
||||
var propertyType = _mediaType.CompositionPropertyTypes.First(x => x.Id == dto.PropertyTypeId);
|
||||
var property = propertyType.CreatePropertyFromRawValue(dto.GetValue, dto.VersionId.Value, dto.Id);
|
||||
|
||||
property.ResetDirtyProperties();
|
||||
properties.Add(property);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@@ -28,19 +28,22 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
group.SortOrder = groupDto.SortOrder;
|
||||
group.PropertyTypes = new PropertyTypeCollection();
|
||||
|
||||
foreach (var typeDto in groupDto.PropertyTypeDtos)
|
||||
//Because we are likely to have a group with no PropertyTypes we need to ensure that these are excluded
|
||||
var typeDtos = groupDto.PropertyTypeDtos.Where(x => x.Id > 0);
|
||||
foreach (var typeDto in typeDtos)
|
||||
{
|
||||
group.PropertyTypes.Add(new PropertyType(typeDto.DataTypeDto.ControlId,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeId = typeDto.DataTypeId,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
Id = typeDto.Id,
|
||||
Name = typeDto.Name,
|
||||
HelpText = typeDto.HelpText,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder
|
||||
SortOrder = typeDto.SortOrder,
|
||||
PropertyGroupId = groupDto.Id
|
||||
});
|
||||
|
||||
}
|
||||
@@ -53,7 +56,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public IEnumerable<PropertyTypeGroupDto> BuildDto(IEnumerable<PropertyGroup> entity)
|
||||
{
|
||||
return entity.Select(propertyGroup => BuildGroupDto(propertyGroup)).ToList();
|
||||
return entity.Select(BuildGroupDto).ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -82,15 +85,17 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
Alias = propertyType.Alias,
|
||||
ContentTypeId = _id,
|
||||
DataTypeId = propertyType.DataTypeId,
|
||||
DataTypeId = propertyType.DataTypeDefinitionId,
|
||||
Description = propertyType.Description,
|
||||
HelpText = propertyType.HelpText,
|
||||
Mandatory = propertyType.Mandatory,
|
||||
Name = propertyType.Name,
|
||||
SortOrder = propertyType.SortOrder,
|
||||
PropertyTypeGroupId = tabId
|
||||
SortOrder = propertyType.SortOrder
|
||||
};
|
||||
|
||||
if (tabId != default(int))
|
||||
propertyTypeDto.PropertyTypeGroupId = tabId;
|
||||
|
||||
if (propertyType.HasIdentity)
|
||||
propertyTypeDto.Id = propertyType.Id;
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.DataTypeId, dto => dto.DataTypeId);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.DataTypeDefinitionId, dto => dto.DataTypeId);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.HelpText, dto => dto.HelpText);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Mandatory, dto => dto.Mandatory);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.ValidationRegExp, dto => dto.ValidationRegExp);
|
||||
CacheMap<PropertyType, DataTypeDto>(src => src.DataTypeControlId, dto => dto.ControlId);
|
||||
CacheMap<PropertyType, DataTypeDto>(src => src.DataTypeId, dto => dto.ControlId);
|
||||
CacheMap<PropertyType, DataTypeDto>(src => src.DataTypeDatabaseType, dto => dto.DbType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
ICollection<IMigrationExpression> Expressions { get; set; }
|
||||
DatabaseProviders CurrentDatabaseProvider { get; }
|
||||
Database Database { get; }
|
||||
}
|
||||
}
|
||||
@@ -11,61 +11,61 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
public abstract class MigrationBase : IMigration
|
||||
{
|
||||
internal IMigrationContext _context;
|
||||
internal IMigrationContext Context;
|
||||
|
||||
public abstract void Up();
|
||||
public abstract void Down();
|
||||
|
||||
public virtual void GetUpExpressions(IMigrationContext context)
|
||||
{
|
||||
_context = context;
|
||||
Context = context;
|
||||
Up();
|
||||
}
|
||||
|
||||
public virtual void GetDownExpressions(IMigrationContext context)
|
||||
{
|
||||
_context = context;
|
||||
Context = context;
|
||||
Down();
|
||||
}
|
||||
|
||||
public IAlterSyntaxBuilder Alter
|
||||
{
|
||||
get { return new AlterSyntaxBuilder(_context); }
|
||||
get { return new AlterSyntaxBuilder(Context); }
|
||||
}
|
||||
|
||||
public ICreateBuilder Create
|
||||
{
|
||||
get { return new CreateBuilder(_context); }
|
||||
get { return new CreateBuilder(Context); }
|
||||
}
|
||||
|
||||
public IDeleteBuilder Delete
|
||||
{
|
||||
get { return new DeleteBuilder(_context); }
|
||||
get { return new DeleteBuilder(Context); }
|
||||
}
|
||||
|
||||
public IExecuteBuilder Execute
|
||||
{
|
||||
get { return new ExecuteBuilder(_context); }
|
||||
get { return new ExecuteBuilder(Context); }
|
||||
}
|
||||
|
||||
public IInsertBuilder Insert
|
||||
{
|
||||
get { return new InsertBuilder(_context); }
|
||||
get { return new InsertBuilder(Context); }
|
||||
}
|
||||
|
||||
public IRenameBuilder Rename
|
||||
{
|
||||
get { return new RenameBuilder(_context); }
|
||||
get { return new RenameBuilder(Context); }
|
||||
}
|
||||
|
||||
public IUpdateBuilder Update
|
||||
{
|
||||
get { return new UpdateBuilder(_context); }
|
||||
get { return new UpdateBuilder(Context); }
|
||||
}
|
||||
|
||||
public IIfDatabaseBuilder IfDatabase(params DatabaseProviders[] databaseProviders)
|
||||
{
|
||||
return new IfDatabaseBuilder(_context, databaseProviders);
|
||||
return new IfDatabaseBuilder(Context, databaseProviders);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,17 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
internal class MigrationContext : IMigrationContext
|
||||
{
|
||||
public MigrationContext(DatabaseProviders databaseProvider)
|
||||
public MigrationContext(DatabaseProviders databaseProvider, Database database)
|
||||
{
|
||||
Expressions = new Collection<IMigrationExpression>();
|
||||
CurrentDatabaseProvider = databaseProvider;
|
||||
Database = database;
|
||||
}
|
||||
|
||||
public ICollection<IMigrationExpression> Expressions { get; set; }
|
||||
|
||||
public DatabaseProviders CurrentDatabaseProvider { get; private set; }
|
||||
|
||||
public Database Database { get; private set; }
|
||||
}
|
||||
}
|
||||
32
src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs
Normal file
32
src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IMigrations
|
||||
/// </summary>
|
||||
internal class MigrationResolver : ManyObjectsResolverBase<MigrationResolver, IMigration>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="migrations"></param>
|
||||
/// <remarks>
|
||||
/// Use transient objects as we don't want these as singletons and take up memory that is not required
|
||||
/// </remarks>
|
||||
public MigrationResolver(IEnumerable<Type> migrations)
|
||||
: base(migrations, ObjectLifetimeScope.Transient)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the migrations
|
||||
/// </summary>
|
||||
public IEnumerable<IMigration> Migrations
|
||||
{
|
||||
get { return Values; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Represents the Migration Runner, which is used to apply migrations to
|
||||
/// the umbraco database.
|
||||
/// </summary>
|
||||
@@ -44,13 +45,17 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
LogHelper.Info<MigrationRunner>("Initializing database migration");
|
||||
|
||||
var foundMigrations = PluginManager.Current.FindMigrations();
|
||||
var foundMigrations = MigrationResolver.Current.Migrations;
|
||||
|
||||
var migrations = isUpgrade
|
||||
? OrderedUpgradeMigrations(foundMigrations)
|
||||
: OrderedDowngradeMigrations(foundMigrations);
|
||||
? OrderedUpgradeMigrations(foundMigrations).ToList()
|
||||
: OrderedDowngradeMigrations(foundMigrations).ToList();
|
||||
|
||||
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _configuredVersion, _targetVersion, true), this))
|
||||
return false;
|
||||
|
||||
//Loop through migrations to generate sql
|
||||
var context = new MigrationContext(databaseProvider);
|
||||
var context = new MigrationContext(databaseProvider, database);
|
||||
foreach (MigrationBase migration in migrations)
|
||||
{
|
||||
if (isUpgrade)
|
||||
@@ -84,6 +89,8 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
transaction.Complete();
|
||||
}
|
||||
|
||||
Migrated.RaiseEvent(new MigrationEventArgs(migrations, context, _configuredVersion, _targetVersion, false), this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -114,5 +121,15 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
select migration);
|
||||
return migrations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Migration
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<MigrationRunner, MigrationEventArgs> Migrating;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Migration
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<MigrationRunner, MigrationEventArgs> Migrated;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
internal static class PluginManagerExtension
|
||||
{
|
||||
public static IEnumerable<IMigration> FindMigrations(this PluginManager resolver)
|
||||
{
|
||||
var types = resolver.ResolveTypesWithAttribute<IMigration, MigrationAttribute>();
|
||||
return resolver.CreateInstances<IMigration>(types);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,20 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute
|
||||
public class ExecuteBuilder : IExecuteBuilder
|
||||
{
|
||||
private readonly IMigrationContext _context;
|
||||
private readonly DatabaseProviders[] _databaseProviders;
|
||||
|
||||
public ExecuteBuilder(IMigrationContext context)
|
||||
public ExecuteBuilder(IMigrationContext context, params DatabaseProviders[] databaseProviders)
|
||||
{
|
||||
_context = context;
|
||||
_databaseProviders = databaseProviders;
|
||||
}
|
||||
|
||||
public void Sql(string sqlStatement)
|
||||
{
|
||||
var expression = new ExecuteSqlStatementExpression {SqlStatement = sqlStatement};
|
||||
var expression = _databaseProviders == null
|
||||
? new ExecuteSqlStatementExpression {SqlStatement = sqlStatement}
|
||||
: new ExecuteSqlStatementExpression(_context.CurrentDatabaseProvider,
|
||||
_databaseProviders) {SqlStatement = sqlStatement};
|
||||
_context.Expressions.Add(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
return SqlStatement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Rename;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Update;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase
|
||||
{
|
||||
public interface IIfDatabaseBuilder : IFluentSyntax
|
||||
{
|
||||
ICreateBuilder Create { get; }
|
||||
IExecuteBuilder Execute { get; }
|
||||
IDeleteBuilder Delete { get; }
|
||||
IRenameBuilder Rename { get; }
|
||||
IUpdateBuilder Update { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Rename;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Update;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase
|
||||
{
|
||||
@@ -20,6 +22,11 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase
|
||||
get { return new CreateBuilder(_context, _databaseProviders); }
|
||||
}
|
||||
|
||||
public IExecuteBuilder Execute
|
||||
{
|
||||
get { return new ExecuteBuilder(_context, _databaseProviders); }
|
||||
}
|
||||
|
||||
public IDeleteBuilder Delete
|
||||
{
|
||||
get { return new DeleteBuilder(_context, _databaseProviders); }
|
||||
@@ -29,5 +36,10 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase
|
||||
{
|
||||
get { return new RenameBuilder(_context, _databaseProviders); }
|
||||
}
|
||||
|
||||
public IUpdateBuilder Update
|
||||
{
|
||||
get { return new UpdateBuilder(_context, _databaseProviders); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
var updateItems = new List<string>();
|
||||
var whereClauses = new List<string>();
|
||||
|
||||
|
||||
@@ -5,15 +5,19 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update
|
||||
public class UpdateBuilder : IUpdateBuilder
|
||||
{
|
||||
private readonly IMigrationContext _context;
|
||||
private readonly DatabaseProviders[] _databaseProviders;
|
||||
|
||||
public UpdateBuilder(IMigrationContext context)
|
||||
public UpdateBuilder(IMigrationContext context, params DatabaseProviders[] databaseProviders)
|
||||
{
|
||||
_context = context;
|
||||
_databaseProviders = databaseProviders;
|
||||
}
|
||||
|
||||
public IUpdateSetSyntax Table(string tableName)
|
||||
{
|
||||
var expression = new UpdateDataExpression { TableName = tableName };
|
||||
var expression = _databaseProviders == null
|
||||
? new UpdateDataExpression { TableName = tableName }
|
||||
: new UpdateDataExpression(_context.CurrentDatabaseProvider, _databaseProviders) { TableName = tableName };
|
||||
_context.Expressions.Add(expression);
|
||||
return new UpdateDataBuilder(expression, _context);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Data;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourEightZero
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero
|
||||
{
|
||||
[MigrationAttribute("4.8.0", 0, GlobalSettings.UmbracoMigrationName)]
|
||||
public class RemoveUmbracoAppConstraints : MigrationBase
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 10, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 10, GlobalSettings.UmbracoMigrationName)]
|
||||
public class DeleteAppTables : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 9, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 9, GlobalSettings.UmbracoMigrationName)]
|
||||
public class EnsureAppsTreesUpdated : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -0,0 +1,29 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 5, GlobalSettings.UmbracoMigrationName)]
|
||||
public class MoveMasterContentTypeData : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
{
|
||||
//Reading entries from the cmsContentType table in order to update the parentID on the umbracoNode table.
|
||||
//NOTE This is primarily done because of a shortcoming in sql ce, which has really bad support for updates (can't use FROM or subqueries with multiple results).
|
||||
if (base.Context != null && base.Context.Database != null)
|
||||
{
|
||||
var list = base.Context.Database.Fetch<dynamic>("SELECT nodeId, masterContentType FROM cmsContentType WHERE not masterContentType is null AND masterContentType != 0");
|
||||
foreach (var item in list)
|
||||
{
|
||||
Update.Table("umbracoNode").Set(new { parentID = item.masterContentType }).Where(new { id = item.nodeId });
|
||||
}
|
||||
}
|
||||
|
||||
Execute.Sql(
|
||||
"INSERT INTO cmsContentType2ContentType (parentContentTypeId, childContentTypeId) SELECT masterContentType, nodeId FROM cmsContentType WHERE not masterContentType is null and masterContentType != 0");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 4, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 4, GlobalSettings.UmbracoMigrationName)]
|
||||
public class NewCmsContentType2ContentTypeTable : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 6, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 6, GlobalSettings.UmbracoMigrationName)]
|
||||
public class RemoveMasterContentTypeColumn : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 0, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 0, GlobalSettings.UmbracoMigrationName)]
|
||||
public class RenameCmsTabTable : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Data;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 7, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 7, GlobalSettings.UmbracoMigrationName)]
|
||||
public class RenameTabIdColumn : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 3, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 3, GlobalSettings.UmbracoMigrationName)]
|
||||
public class UpdateCmsContentTypeAllowedContentTypeTable : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 2, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 2, GlobalSettings.UmbracoMigrationName)]
|
||||
public class UpdateCmsContentTypeTable : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,8 +1,8 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 8, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 8, GlobalSettings.UmbracoMigrationName)]
|
||||
public class UpdateCmsContentVersionTable : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Data;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 1, GlobalSettings.UmbracoMigrationName)]
|
||||
[Migration("6.0.0", 1, GlobalSettings.UmbracoMigrationName)]
|
||||
public class UpdateCmsPropertyTypeGroupTable : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
@@ -1,18 +0,0 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth
|
||||
{
|
||||
[MigrationAttribute("6.0.0", 5, GlobalSettings.UmbracoMigrationName)]
|
||||
public class MoveMasterContentTypeData : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Sql(
|
||||
"INSERT INTO cmsContentType2ContentType (parentContentTypeId, childContentTypeId) SELECT masterContentType, nodeId FROM cmsContentType WHERE not masterContentType is null and masterContentType != 0");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,7 +424,14 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
else if (t == typeof(string))
|
||||
{
|
||||
p.Size = Math.Max((item as string).Length + 1, 4000); // Help query plan caching by using common size
|
||||
// out of memory exception occurs if trying to save more than 4000 characters to SQL Server CE NText column. Set before attempting to set Size, or Size will always max out at 4000
|
||||
if ((item as string).Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter")
|
||||
p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null);
|
||||
|
||||
p.Size = (item as string).Length + 1;
|
||||
if(p.Size < 4000)
|
||||
p.Size = Math.Max((item as string).Length + 1, 4000); // Help query plan caching by using common size
|
||||
|
||||
p.Value = item;
|
||||
}
|
||||
else if (t == typeof(AnsiString))
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Umbraco.Core.Persistence
|
||||
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName))));
|
||||
|
||||
//Special case for MySql
|
||||
if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("MySql"))
|
||||
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
|
||||
{
|
||||
db.Update<UserDto>("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" });
|
||||
}
|
||||
|
||||
@@ -150,21 +150,18 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
|
||||
protected virtual string VisitMemberAccess(MemberExpression m)
|
||||
{
|
||||
if (m.Expression != null &&
|
||||
m.Expression.NodeType == ExpressionType.Parameter
|
||||
&& m.Expression.Type == typeof(T))
|
||||
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Parameter && m.Expression.Type == typeof(T))
|
||||
{
|
||||
var field = _mapper.Map(m.Member.Name);
|
||||
return field;
|
||||
}
|
||||
|
||||
if (m.Expression != null && m.Expression.NodeType != ExpressionType.Constant)
|
||||
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
|
||||
{
|
||||
var field = _mapper.Map(m.Member.Name);
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var member = Expression.Convert(m, typeof(object));
|
||||
var lambda = Expression.Lambda<Func<object>>(member);
|
||||
var getter = lambda.Compile();
|
||||
@@ -190,9 +187,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
var r = new StringBuilder();
|
||||
foreach (Object e in exprs)
|
||||
{
|
||||
r.AppendFormat("{0}{1}",
|
||||
r.Length > 0 ? "," : "",
|
||||
e);
|
||||
r.AppendFormat("{0}{1}", r.Length > 0 ? "," : "", e);
|
||||
}
|
||||
return r.ToString();
|
||||
}
|
||||
|
||||
@@ -159,13 +159,12 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
return field;
|
||||
}
|
||||
|
||||
if (m.Expression != null && m.Expression.NodeType != ExpressionType.Constant)
|
||||
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
|
||||
{
|
||||
string field = GetFieldName(pd, m.Member.Name);
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
var member = Expression.Convert(m, typeof(object));
|
||||
var lambda = Expression.Lambda<Func<object>>(member);
|
||||
var getter = lambda.Compile();
|
||||
|
||||
@@ -40,11 +40,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override IContent PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where(GetBaseWhereClause(), new { Id = id })
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto = Database.Query<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
var dto = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var content = factory.BuildEntity(dto);
|
||||
|
||||
//Check if template id is set on DocumentDto, and get ITemplate if it is.
|
||||
if (dto.TemplateId.HasValue)
|
||||
if (dto.TemplateId.HasValue && dto.TemplateId.Value > 0)
|
||||
{
|
||||
content.Template = _templateRepository.Get(dto.TemplateId.Value);
|
||||
}
|
||||
@@ -163,7 +163,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
sql.Where("cmsContentVersion.VersionId = @VersionId", new { VersionId = versionId });
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto = Database.Query<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
var dto = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
@@ -262,8 +262,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IContent entity)
|
||||
{
|
||||
var publishedState = ((Content) entity).PublishedState;
|
||||
//A new version should only be created if published state (or language) has changed
|
||||
bool shouldCreateNewVersion = ((ICanBeDirty)entity).IsPropertyDirty("Published") || ((ICanBeDirty)entity).IsPropertyDirty("Language");
|
||||
bool shouldCreateNewVersion = (((ICanBeDirty)entity).IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished) || ((ICanBeDirty)entity).IsPropertyDirty("Language");
|
||||
if (shouldCreateNewVersion)
|
||||
{
|
||||
//Updates Modified date and Version Guid
|
||||
@@ -274,11 +275,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
entity.UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
//Look up parent to get and set the correct Path if ParentId has changed
|
||||
//Look up parent to get and set the correct Path and update SortOrder if ParentId has changed
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("ParentId"))
|
||||
{
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.SortOrder = maxSortOrder;
|
||||
}
|
||||
|
||||
var factory = new ContentFactory(NodeObjectTypeId, entity.Id);
|
||||
@@ -299,8 +303,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Update(newContentDto);
|
||||
}
|
||||
|
||||
//If Published state has changed then 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 state has been changed to unpublished the previous versions publish state should also be reset.
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
|
||||
{
|
||||
var publishedDocs = Database.Fetch<DocumentDto>("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true });
|
||||
foreach (var doc in publishedDocs)
|
||||
@@ -365,6 +370,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
foreach (var property in entity.Properties)
|
||||
{
|
||||
if(keyDictionary.ContainsKey(property.PropertyTypeId) == false) continue;
|
||||
|
||||
property.Id = keyDictionary[property.PropertyTypeId];
|
||||
}
|
||||
}
|
||||
@@ -379,7 +386,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//Loop through properties to check if the content contains images/files that should be deleted
|
||||
foreach (var property in entity.Properties)
|
||||
{
|
||||
if (property.PropertyType.DataTypeControlId == uploadFieldId &&
|
||||
if (property.PropertyType.DataTypeId == uploadFieldId &&
|
||||
string.IsNullOrEmpty(property.Value.ToString()) == false
|
||||
&& fs.FileExists(IOHelper.MapPath(property.Value.ToString())))
|
||||
{
|
||||
@@ -413,7 +420,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
sql.Where<ContentVersionDto>(x => x.Language == language);
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto = Database.Query<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
var dto = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
@@ -40,7 +40,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.RightJoin<PropertyTypeDto>()
|
||||
.On<PropertyTypeGroupDto, PropertyTypeDto>(left => left.Id, right => right.PropertyTypeGroupId)
|
||||
.InnerJoin<DataTypeDto>()
|
||||
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId);
|
||||
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.OrderBy<PropertyTypeDto>(x => x.PropertyTypeGroupId);
|
||||
|
||||
var translator = new SqlTranslator<PropertyType>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
@@ -130,7 +131,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Update the current PropertyType with correct ControlId and DatabaseType
|
||||
var dataTypeDto = Database.FirstOrDefault<DataTypeDto>("WHERE nodeId = @Id", new { Id = propertyTypeDto.DataTypeId });
|
||||
propertyType.DataTypeControlId = dataTypeDto.ControlId;
|
||||
propertyType.DataTypeId = dataTypeDto.ControlId;
|
||||
propertyType.DataTypeDatabaseType = dataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true);
|
||||
}
|
||||
}
|
||||
@@ -168,11 +169,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("PropertyGroups") || entity.PropertyGroups.Any(x => x.IsDirty()))
|
||||
{
|
||||
//Delete PropertyTypes by excepting entries from db with entries from collections
|
||||
var dbPropertyTypes = Database.Fetch<PropertyTypeDto>("WHERE contentTypeId = @Id", new { Id = entity.Id }).Select(x => x.Alias);
|
||||
var entityPropertyTypes = entity.PropertyTypes.Select(x => x.Alias);
|
||||
var aliases = dbPropertyTypes.Except(entityPropertyTypes);
|
||||
var dbPropertyTypes = Database.Fetch<PropertyTypeDto>("WHERE contentTypeId = @Id", new { Id = entity.Id });
|
||||
var dbPropertyTypeAlias = dbPropertyTypes.Select(x => x.Alias.ToLowerInvariant());
|
||||
var entityPropertyTypes = entity.PropertyTypes.Select(x => x.Alias.ToLowerInvariant());
|
||||
var aliases = dbPropertyTypeAlias.Except(entityPropertyTypes);
|
||||
foreach (var alias in aliases)
|
||||
{
|
||||
//Before a PropertyType can be deleted, all Properties based on that PropertyType should be deleted.
|
||||
var propertyType = dbPropertyTypes.FirstOrDefault(x => x.Alias.ToLowerInvariant() == alias);
|
||||
if (propertyType != null)
|
||||
{
|
||||
Database.Delete<PropertyDataDto>("WHERE propertytypeid = @Id", new { Id = propertyType.Id });
|
||||
}
|
||||
|
||||
Database.Delete<PropertyTypeDto>("WHERE contentTypeId = @Id AND Alias = @Alias", new { Id = entity.Id, Alias = alias });
|
||||
}
|
||||
//Delete Tabs/Groups by excepting entries from db with entries from collections
|
||||
@@ -184,7 +193,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Delete<PropertyTypeGroupDto>("WHERE contenttypeNodeId = @Id AND text = @Name", new { Id = entity.Id, Name = tabName });
|
||||
}
|
||||
|
||||
//Run through all groups and types to insert or update entries
|
||||
//Run through all groups to insert or update entries
|
||||
foreach (var propertyGroup in entity.PropertyGroups)
|
||||
{
|
||||
var tabDto = propertyFactory.BuildGroupDto(propertyGroup);
|
||||
@@ -193,19 +202,17 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
: Convert.ToInt32(Database.Insert(tabDto));
|
||||
if (!propertyGroup.HasIdentity)
|
||||
propertyGroup.Id = groupPrimaryKey;//Set Id on new PropertyGroup
|
||||
}
|
||||
|
||||
//This should indicate that neither group nor property types has been touched, but this implies a deeper 'Dirty'-lookup
|
||||
//if(!propertyGroup.IsDirty()) continue;
|
||||
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(propertyGroup.Id, propertyType);
|
||||
int typePrimaryKey = propertyType.HasIdentity
|
||||
? Database.Update(propertyTypeDto)
|
||||
: Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
if (!propertyType.HasIdentity)
|
||||
propertyType.Id = typePrimaryKey;//Set Id on new PropertyType
|
||||
}
|
||||
//Run through all PropertyTypes to insert or update entries
|
||||
foreach (var propertyType in entity.PropertyTypes)
|
||||
{
|
||||
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(propertyType.PropertyGroupId, propertyType);
|
||||
int typePrimaryKey = propertyType.HasIdentity
|
||||
? Database.Update(propertyTypeDto)
|
||||
: Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
if (!propertyType.HasIdentity)
|
||||
propertyType.Id = typePrimaryKey;//Set Id on new PropertyType
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,11 +233,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyTypeGroupDto>()
|
||||
.RightJoin<PropertyTypeDto>()
|
||||
.LeftJoin<PropertyTypeDto>()
|
||||
.On<PropertyTypeGroupDto, PropertyTypeDto>(left => left.Id, right => right.PropertyTypeGroupId)
|
||||
.InnerJoin<DataTypeDto>()
|
||||
.LeftJoin<DataTypeDto>()
|
||||
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.Where<PropertyTypeDto>(x => x.ContentTypeId == id);
|
||||
.Where<PropertyTypeGroupDto>(x => x.ContentTypeNodeId == id)
|
||||
.OrderBy<PropertyTypeGroupDto>(x => x.Id);
|
||||
|
||||
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
|
||||
|
||||
@@ -238,5 +246,36 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var propertyGroups = propertyFactory.BuildEntity(dtos);
|
||||
return new PropertyGroupCollection(propertyGroups);
|
||||
}
|
||||
|
||||
protected PropertyTypeCollection GetPropertyTypeCollection(int id)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyTypeDto>()
|
||||
.InnerJoin<DataTypeDto>()
|
||||
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.Where<PropertyTypeDto>(x => x.ContentTypeId == id);
|
||||
|
||||
var dtos = Database.Fetch<PropertyTypeDto, DataTypeDto>(sql);
|
||||
|
||||
//TODO Move this to a PropertyTypeFactory
|
||||
var list = (from dto in dtos
|
||||
where (dto.PropertyTypeGroupId > 0) == false
|
||||
select
|
||||
new PropertyType(dto.DataTypeDto.ControlId,
|
||||
dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
DataTypeDefinitionId = dto.DataTypeId,
|
||||
Description = dto.Description,
|
||||
Id = dto.Id,
|
||||
Name = dto.Name,
|
||||
HelpText = dto.HelpText,
|
||||
Mandatory = dto.Mandatory,
|
||||
SortOrder = dto.SortOrder
|
||||
});
|
||||
|
||||
return new PropertyTypeCollection(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var contentTypeSql = GetBaseQuery(false);
|
||||
contentTypeSql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
|
||||
var dto = Database.Query<DocumentTypeDto, ContentTypeDto, NodeDto>(contentTypeSql).FirstOrDefault();
|
||||
// The SQL will contain one record for each allowed template, so order to put the default one
|
||||
// at the top to populate the default template property correctly.
|
||||
contentTypeSql.OrderByDescending<DocumentTypeDto>(x => x.IsDefault);
|
||||
|
||||
var dto = Database.Fetch<DocumentTypeDto, ContentTypeDto, NodeDto>(contentTypeSql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
@@ -47,12 +51,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
contentType.AllowedContentTypes = GetAllowedContentTypeIds(id);
|
||||
contentType.PropertyGroups = GetPropertyGroupCollection(id);
|
||||
((ContentType)contentType).PropertyTypes = GetPropertyTypeCollection(id);
|
||||
|
||||
var templates = Database.Fetch<DocumentTypeDto>("WHERE contentTypeNodeId = @Id", new { Id = id });
|
||||
if(templates.Any())
|
||||
{
|
||||
contentType.AllowedTemplates =
|
||||
templates.Select(template => _templateRepository.Get(template.TemplateNodeId));
|
||||
contentType.AllowedTemplates = templates.Select(template => _templateRepository.Get(template.TemplateNodeId)).ToList();
|
||||
}
|
||||
|
||||
var list = Database.Fetch<ContentType2ContentTypeDto>("WHERE childContentTypeId = @Id", new { Id = id});
|
||||
@@ -114,16 +118,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
//TODO Investigate the proper usage of IsDefault on cmsDocumentType
|
||||
var sql = new Sql();
|
||||
sql.Select(isCount ? "COUNT(*)" : "*")
|
||||
.From<DocumentTypeDto>()
|
||||
.RightJoin<ContentTypeDto>()
|
||||
.On<ContentTypeDto, DocumentTypeDto>(left => left.NodeId, right => right.ContentTypeNodeId)
|
||||
.InnerJoin<NodeDto>()
|
||||
.On<ContentTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<DocumentTypeDto>(x => x.IsDefault == true);
|
||||
.From<DocumentTypeDto>()
|
||||
.RightJoin<ContentTypeDto>()
|
||||
.On<ContentTypeDto, DocumentTypeDto>(left => left.NodeId, right => right.ContentTypeNodeId)
|
||||
.InnerJoin<NodeDto>()
|
||||
.On<ContentTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
|
||||
return sql;
|
||||
}
|
||||
@@ -170,9 +172,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
PersistNewBaseContentType(dto.ContentTypeDto, entity);
|
||||
//Inserts data into the cmsDocumentType table
|
||||
dto.ContentTypeNodeId = entity.Id;
|
||||
Database.Insert(dto);
|
||||
//Inserts data into the cmsDocumentType table if a template exists
|
||||
if (dto.TemplateNodeId > 0)
|
||||
{
|
||||
dto.ContentTypeNodeId = entity.Id;
|
||||
Database.Insert(dto);
|
||||
}
|
||||
|
||||
//Insert allowed Templates not including the default one, as that has already been inserted
|
||||
foreach (var template in entity.AllowedTemplates.Where(x => x != null && x.Id != dto.TemplateNodeId))
|
||||
@@ -203,8 +208,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Look up DocumentType entries for updating - this could possibly be a "remove all, insert all"-approach
|
||||
Database.Delete<DocumentTypeDto>("WHERE contentTypeNodeId = @Id", new { Id = entity.Id});
|
||||
|
||||
Database.Insert(dto);
|
||||
//Insert the updated DocumentTypeDto if a template exists
|
||||
if (dto.TemplateNodeId > 0)
|
||||
{
|
||||
Database.Insert(dto);
|
||||
}
|
||||
|
||||
//Insert allowed Templates not including the default one, as that has already been inserted
|
||||
foreach (var template in entity.AllowedTemplates.Where(x => x != null && x.Id != dto.TemplateNodeId))
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var dataTypeSql = GetBaseQuery(false);
|
||||
dataTypeSql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
|
||||
var dataTypeDto = Database.Query<DataTypeDto, NodeDto>(dataTypeSql).FirstOrDefault();
|
||||
var dataTypeDto = Database.Fetch<DataTypeDto, NodeDto>(dataTypeSql).FirstOrDefault();
|
||||
|
||||
if (dataTypeDto == null)
|
||||
return null;
|
||||
|
||||
@@ -35,8 +35,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override IDictionaryItem PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where(GetBaseWhereClause(), new {Id = id})
|
||||
.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
var dto = Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql).FirstOrDefault();
|
||||
if (dto == null)
|
||||
@@ -83,6 +84,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
sql.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
var dtos = Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql);
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
private void EnsureDependencies()
|
||||
{
|
||||
_fileSystem = FileSystemProviderManager.Current.GetFileSystemProvider("macros");
|
||||
{
|
||||
_fileSystem = new PhysicalFileSystem("~/App_Data/Macros");
|
||||
var serviceStackSerializer = new ServiceStackJsonSerializer();
|
||||
_serializationService = new SerializationService(serviceStackSerializer);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto = Database.Query<ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
var dto = Database.Fetch<ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
@@ -145,7 +145,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
sql.Where("cmsContentVersion.VersionId = @VersionId", new { VersionId = versionId });
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto = Database.Query<ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
var dto = Database.Fetch<ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
@@ -240,11 +240,14 @@ 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
|
||||
//Look up parent to get and set the correct Path and update SortOrder if ParentId has changed
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("ParentId"))
|
||||
{
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.SortOrder = maxSortOrder;
|
||||
}
|
||||
|
||||
var factory = new MediaFactory(NodeObjectTypeId, entity.Id);
|
||||
@@ -307,7 +310,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//Loop through properties to check if the media item contains images/file that should be deleted
|
||||
foreach (var property in entity.Properties)
|
||||
{
|
||||
if (property.PropertyType.DataTypeControlId == uploadFieldId &&
|
||||
if (property.PropertyType.DataTypeId == uploadFieldId &&
|
||||
string.IsNullOrEmpty(property.Value.ToString()) == false
|
||||
&& fs.FileExists(IOHelper.MapPath(property.Value.ToString())))
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var contentTypeSql = GetBaseQuery(false);
|
||||
contentTypeSql.Where(GetBaseWhereClause(), new { Id = id});
|
||||
|
||||
var dto = Database.Query<ContentTypeDto, NodeDto>(contentTypeSql).FirstOrDefault();
|
||||
var dto = Database.Fetch<ContentTypeDto, NodeDto>(contentTypeSql).FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
@@ -43,6 +43,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
contentType.AllowedContentTypes = GetAllowedContentTypeIds(id);
|
||||
contentType.PropertyGroups = GetPropertyGroupCollection(id);
|
||||
((MediaType)contentType).PropertyTypes = GetPropertyTypeCollection(id);
|
||||
|
||||
var list = Database.Fetch<ContentType2ContentTypeDto>("WHERE childContentTypeId = @Id", new{ Id = id});
|
||||
foreach (var contentTypeDto in list)
|
||||
|
||||
@@ -14,8 +14,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
internal class ScriptRepository : FileRepository<string, Script>, IScriptRepository
|
||||
{
|
||||
internal ScriptRepository(IUnitOfWork work, IFileSystem fileSystem)
|
||||
: base(work, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptRepository(IUnitOfWork work)
|
||||
: base(work, FileSystemProviderManager.Current.GetFileSystemProvider("scripts"))
|
||||
: this(work, new PhysicalFileSystem(SystemDirectories.Scripts))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
internal class StylesheetRepository : FileRepository<string, Stylesheet>, IStylesheetRepository
|
||||
{
|
||||
internal StylesheetRepository(IUnitOfWork work, IFileSystem fileSystem)
|
||||
: base(work, fileSystem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public StylesheetRepository(IUnitOfWork work)
|
||||
: base(work, FileSystemProviderManager.Current.GetFileSystemProvider("stylesheets"))
|
||||
: this(work, new PhysicalFileSystem(SystemDirectories.Css))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -23,20 +23,20 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
private IFileSystem _masterpagesFileSystem;
|
||||
private IFileSystem _viewsFileSystem;
|
||||
|
||||
public TemplateRepository(IDatabaseUnitOfWork work)
|
||||
: base(work)
|
||||
public TemplateRepository(IDatabaseUnitOfWork work)
|
||||
: base(work)
|
||||
{
|
||||
EnsureDepedencies();
|
||||
}
|
||||
|
||||
public TemplateRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
: base(work, cache)
|
||||
public TemplateRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
: base(work, cache)
|
||||
{
|
||||
EnsureDepedencies();
|
||||
}
|
||||
|
||||
internal TemplateRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem)
|
||||
: base(work, cache)
|
||||
internal TemplateRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem)
|
||||
: base(work, cache)
|
||||
{
|
||||
_masterpagesFileSystem = masterpageFileSystem;
|
||||
_viewsFileSystem = viewFileSystem;
|
||||
@@ -44,8 +44,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
private void EnsureDepedencies()
|
||||
{
|
||||
_masterpagesFileSystem = FileSystemProviderManager.Current.GetFileSystemProvider("masterpages");
|
||||
_viewsFileSystem = FileSystemProviderManager.Current.GetFileSystemProvider("views");
|
||||
_masterpagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages);
|
||||
_viewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,ITemplate>
|
||||
@@ -74,17 +74,20 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
template.MasterTemplateId = dto.Master.Value;
|
||||
}
|
||||
|
||||
if(_viewsFileSystem.FileExists(csViewName))
|
||||
if (_viewsFileSystem.FileExists(csViewName))
|
||||
{
|
||||
PopulateViewTemplate(template, csViewName);
|
||||
}
|
||||
else if(_viewsFileSystem.FileExists(vbViewName))
|
||||
else if (_viewsFileSystem.FileExists(vbViewName))
|
||||
{
|
||||
PopulateViewTemplate(template, vbViewName);
|
||||
}
|
||||
else
|
||||
{
|
||||
PopulateMasterpageTemplate(template, masterpageName);
|
||||
if (_masterpagesFileSystem.FileExists(masterpageName))
|
||||
{
|
||||
PopulateMasterpageTemplate(template, masterpageName);
|
||||
}
|
||||
}
|
||||
|
||||
return template;
|
||||
@@ -164,9 +167,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistNewItem(ITemplate entity)
|
||||
{
|
||||
using(var stream = new MemoryStream(Encoding.UTF8.GetBytes(entity.Content)))
|
||||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(entity.Content)))
|
||||
{
|
||||
if(entity.GetTypeOfRenderingEngine() == RenderingEngine.Mvc)
|
||||
if (entity.GetTypeOfRenderingEngine() == RenderingEngine.Mvc)
|
||||
{
|
||||
_viewsFileSystem.AddFile(entity.Name, stream, true);
|
||||
}
|
||||
@@ -337,7 +340,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public IEnumerable<ITemplate> GetAll(params string[] aliases)
|
||||
{
|
||||
if(aliases.Any())
|
||||
if (aliases.Any())
|
||||
{
|
||||
foreach (var id in aliases)
|
||||
{
|
||||
@@ -352,7 +355,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
yield return Get(nodeDto.NodeId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
@@ -23,9 +25,16 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public virtual IEnumerable<TEntity> GetAllVersions(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<ContentVersionDto>()
|
||||
.InnerJoin<ContentDto>()
|
||||
.On<ContentVersionDto, ContentDto>(left => left.NodeId, right => right.NodeId)
|
||||
.InnerJoin<NodeDto>()
|
||||
.On<ContentDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<NodeDto>(x => x.NodeId == id)
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dtos = Database.Fetch<ContentVersionDto, ContentDto, NodeDto>(sql);
|
||||
foreach (var dto in dtos)
|
||||
|
||||
@@ -41,11 +41,21 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
public override bool DoesTableExist(Database db, string tableName)
|
||||
{
|
||||
db.OpenSharedConnection();
|
||||
var result =
|
||||
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
|
||||
"WHERE TABLE_NAME = @TableName AND " +
|
||||
"TABLE_SCHEMA = @TableSchema", new { TableName = tableName, TableSchema = db.Connection.Database });
|
||||
long result;
|
||||
try
|
||||
{
|
||||
db.OpenSharedConnection();
|
||||
result =
|
||||
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
|
||||
"WHERE TABLE_NAME = @TableName AND " +
|
||||
"TABLE_SCHEMA = @TableSchema",
|
||||
new {TableName = tableName, TableSchema = db.Connection.Database});
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
db.CloseSharedConnection();
|
||||
}
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
{
|
||||
@@ -14,10 +15,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// </remarks>
|
||||
public class UmbracoDatabase : Database
|
||||
{
|
||||
|
||||
|
||||
|
||||
private readonly Guid _instanceId = Guid.NewGuid();
|
||||
private readonly Guid _instanceId = Guid.NewGuid();
|
||||
/// <summary>
|
||||
/// Used for testing
|
||||
/// </summary>
|
||||
@@ -41,5 +39,11 @@ namespace Umbraco.Core.Persistence
|
||||
public UmbracoDatabase(string connectionStringName) : base(connectionStringName)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnException(Exception x)
|
||||
{
|
||||
LogHelper.Info<UmbracoDatabase>(x.StackTrace);
|
||||
base.OnException(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ using System.Xml.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using umbraco.interfaces;
|
||||
using File = System.IO.File;
|
||||
@@ -458,6 +459,15 @@ namespace Umbraco.Core
|
||||
return ResolveTypes<IMacroPropertyType>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available IMigrations in application
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveMigrationTypes()
|
||||
{
|
||||
return ResolveTypes<IMigration>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets which assemblies to scan when type finding, generally used for unit testing, if not explicitly set
|
||||
/// this will search all assemblies known to have plugins and exclude ones known to not have them.
|
||||
|
||||
@@ -38,4 +38,5 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("Umbraco.Core")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Web")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Web.UI")]
|
||||
[assembly: InternalsVisibleTo("UmbracoExamine")]
|
||||
[assembly: InternalsVisibleTo("UmbracoExamine")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")]
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Core.Publishing
|
||||
return false;
|
||||
}
|
||||
|
||||
content.ChangePublishedState(true);
|
||||
content.ChangePublishedState(PublishedState.Published);
|
||||
|
||||
LogHelper.Info<PublishingStrategy>(
|
||||
string.Format("Content '{0}' with Id '{1}' has been published.",
|
||||
@@ -106,7 +106,7 @@ namespace Umbraco.Core.Publishing
|
||||
continue;
|
||||
}
|
||||
|
||||
item.ChangePublishedState(true);
|
||||
item.ChangePublishedState(PublishedState.Published);
|
||||
|
||||
LogHelper.Info<PublishingStrategy>(
|
||||
string.Format("Content '{0}' with Id '{1}' has been published.",
|
||||
@@ -138,8 +138,8 @@ namespace Umbraco.Core.Publishing
|
||||
"Content '{0}' with Id '{1}' had its release date removed, because it was unpublished.",
|
||||
content.Name, content.Id));
|
||||
}
|
||||
|
||||
content.ChangePublishedState(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Unpublished);
|
||||
|
||||
LogHelper.Info<PublishingStrategy>(
|
||||
string.Format("Content '{0}' with Id '{1}' has been unpublished.",
|
||||
@@ -173,7 +173,7 @@ namespace Umbraco.Core.Publishing
|
||||
item.Name, item.Id));
|
||||
}
|
||||
|
||||
item.ChangePublishedState(false);
|
||||
item.ChangePublishedState(PublishedState.Unpublished);
|
||||
|
||||
LogHelper.Info<PublishingStrategy>(
|
||||
string.Format("Content '{0}' with Id '{1}' has been unpublished.",
|
||||
|
||||
@@ -59,15 +59,16 @@ namespace Umbraco.Core.Services
|
||||
_repositoryFactory = repositoryFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// </summary>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent CreateContent(int parentId, string contentTypeAlias, int userId = -1)
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = -1)
|
||||
{
|
||||
IContentType contentType = null;
|
||||
IContent content = null;
|
||||
@@ -89,7 +90,7 @@ namespace Umbraco.Core.Services
|
||||
contentTypeAlias));
|
||||
}
|
||||
|
||||
content = new Content(parentId, contentType);
|
||||
content = new Content(name, parentId, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
return content;
|
||||
@@ -245,7 +246,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path));
|
||||
var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path) && x.Id != content.Id);
|
||||
var contents = repository.GetByQuery(query);
|
||||
|
||||
return contents;
|
||||
@@ -375,63 +376,10 @@ namespace Umbraco.Core.Services
|
||||
/// Re-Publishes all Content
|
||||
/// </summary>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this RePublish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
public bool RePublishAll(int userId = -1, bool omitCacheRefresh = false)
|
||||
public bool RePublishAll(int userId = -1)
|
||||
{
|
||||
//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.
|
||||
var list = new List<IContent>();
|
||||
var updated = new List<IContent>();
|
||||
|
||||
//Consider creating a Path query instead of recursive method:
|
||||
//var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
||||
|
||||
var rootContent = GetRootContent();
|
||||
foreach (var content in rootContent)
|
||||
{
|
||||
if (content.IsValid())
|
||||
{
|
||||
list.Add(content);
|
||||
list.AddRange(GetChildrenDeep(content.Id));
|
||||
}
|
||||
}
|
||||
|
||||
//Publish and then update the database with new status
|
||||
var published = _publishingStrategy.PublishWithChildren(list, userId);
|
||||
if (published)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
//Only loop through content where the Published property has been updated
|
||||
foreach (var item in list.Where(x => ((ICanBeDirty) x).IsPropertyDirty("Published")))
|
||||
{
|
||||
SetWriter(item, userId);
|
||||
repository.AddOrUpdate(item);
|
||||
updated.Add(item);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var c in updated)
|
||||
{
|
||||
var xml = c.ToXml();
|
||||
var poco = new ContentXmlDto {NodeId = c.Id, Xml = xml.ToString(SaveOptions.None)};
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = c.Id}) !=
|
||||
null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
//Updating content to published state is finished, so we fire event through PublishingStrategy to have cache updated
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(updated, true);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "RePublish All performed by user", userId == -1 ? 0 : userId, -1);
|
||||
|
||||
return published;
|
||||
return RePublishAllDo(false, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -439,12 +387,10 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
public bool Publish(IContent content, int userId = -1, bool omitCacheRefresh = false)
|
||||
public bool Publish(IContent content, int userId = -1)
|
||||
{
|
||||
//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.
|
||||
return SaveAndPublish(content, userId, omitCacheRefresh);
|
||||
return SaveAndPublishDo(content, false, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -452,76 +398,10 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
public bool PublishWithChildren(IContent content, int userId = -1, bool omitCacheRefresh = false)
|
||||
public bool PublishWithChildren(IContent content, int userId = -1)
|
||||
{
|
||||
//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 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"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;
|
||||
}
|
||||
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (!content.IsValid())
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format("Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Consider creating a Path query instead of recursive method:
|
||||
//var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path));
|
||||
|
||||
var updated = new List<IContent>();
|
||||
var list = new List<IContent>();
|
||||
list.Add(content);
|
||||
list.AddRange(GetChildrenDeep(content.Id));
|
||||
|
||||
//Publish and then update the database with new status
|
||||
var published = _publishingStrategy.PublishWithChildren(list, userId);
|
||||
if (published)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
//Only loop through content where the Published property has been updated
|
||||
foreach (var item in list.Where(x => ((ICanBeDirty) x).IsPropertyDirty("Published")))
|
||||
{
|
||||
SetWriter(item, userId);
|
||||
repository.AddOrUpdate(item);
|
||||
updated.Add(item);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var c in updated)
|
||||
{
|
||||
var xml = c.ToXml();
|
||||
var poco = new ContentXmlDto {NodeId = c.Id, Xml = xml.ToString(SaveOptions.None)};
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = c.Id}) !=
|
||||
null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
//Save xml to db and call following method to fire event:
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(updated, false);
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId == -1 ? 0 : userId,
|
||||
content.Id);
|
||||
}
|
||||
|
||||
return published;
|
||||
return PublishWithChildrenDo(content, false, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -529,33 +409,10 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if unpublishing succeeded, otherwise False</returns>
|
||||
public bool UnPublish(IContent content, int userId = -1, bool omitCacheRefresh = false)
|
||||
public bool UnPublish(IContent content, int userId = -1)
|
||||
{
|
||||
//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.
|
||||
|
||||
var unpublished = _publishingStrategy.UnPublish(content, userId);
|
||||
if (unpublished)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(content);
|
||||
|
||||
//Remove 'published' xml from the cmsContentXml table for the unpublished content
|
||||
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new {Id = content.Id});
|
||||
|
||||
uow.Commit();
|
||||
}
|
||||
//Delete xml from db? and call following method to fire event through PublishingStrategy to update cache
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.UnPublishingFinalized(content);
|
||||
|
||||
Audit.Add(AuditTypes.UnPublish, "UnPublish performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
}
|
||||
|
||||
return unpublished;
|
||||
return UnPublishDo(content, false, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -563,76 +420,10 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
public bool SaveAndPublish(IContent content, int userId = -1, bool omitCacheRefresh = false)
|
||||
public bool SaveAndPublish(IContent content, int userId = -1)
|
||||
{
|
||||
//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.
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
return false;
|
||||
|
||||
//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 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (!content.IsValid())
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Publish and then update the database with new status
|
||||
bool published = _publishingStrategy.Publish(content, userId);
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
//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);
|
||||
|
||||
uow.Commit();
|
||||
|
||||
if (published)
|
||||
{
|
||||
var xml = content.ToXml();
|
||||
var poco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = content.Id}) != null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
//Save xml to db and call following method to fire event through PublishingStrategy to update cache
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(content);
|
||||
|
||||
//We need to check if children and their publish state to ensure that we republish content that was previously published
|
||||
if (HasChildren(content.Id))
|
||||
{
|
||||
var children = GetChildrenDeep(content.Id);
|
||||
var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id));
|
||||
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(shouldBeRepublished, false);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
|
||||
return published;
|
||||
return SaveAndPublishDo(content, false, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -642,25 +433,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId">Optional Id of the User saving the Content</param>
|
||||
public void Save(IContent content, int userId = -1)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
SetWriter(content, userId);
|
||||
|
||||
//Only change the publish state if the "previous" version was actually published
|
||||
if (content.Published)
|
||||
content.ChangePublishedState(false);
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Content performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
Save(content, true, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -690,7 +463,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//Only change the publish state if the "previous" version was actually published
|
||||
if (content.Published)
|
||||
content.ChangePublishedState(false);
|
||||
content.ChangePublishedState(PublishedState.Saved);
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
@@ -893,52 +666,90 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an <see cref="IContent"/> object to a new location by changing its parent id.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the <see cref="IContent"/> object is already published it will be
|
||||
/// published after being moved to its new location. Otherwise it'll just
|
||||
/// be saved with a new parent id.
|
||||
/// </remarks>
|
||||
/// <param name="content">The <see cref="IContent"/> to move</param>
|
||||
/// <param name="parentId">Id of the Content's new Parent</param>
|
||||
/// <param name="userId">Optional Id of the User moving the Content</param>
|
||||
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
|
||||
|
||||
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IContent>(content, parentId), this))
|
||||
return;
|
||||
|
||||
SetWriter(content, userId);
|
||||
/// Moves an <see cref="IContent"/> object to a new location by changing its parent id.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the <see cref="IContent"/> object is already published it will be
|
||||
/// published after being moved to its new location. Otherwise it'll just
|
||||
/// be saved with a new parent id.
|
||||
/// </remarks>
|
||||
/// <param name="content">The <see cref="IContent"/> to move</param>
|
||||
/// <param name="parentId">Id of the Content's new Parent</param>
|
||||
/// <param name="userId">Optional Id of the User moving the Content</param>
|
||||
public void Move(IContent content, int parentId, int userId = -1)
|
||||
{
|
||||
//This ensures that the correct method is called if this method is used to Move to recycle bin.
|
||||
if (parentId == -20)
|
||||
{
|
||||
MoveToRecycleBin(content, userId);
|
||||
return;
|
||||
}
|
||||
|
||||
//If Content is being moved away from Recycle Bin, its state should be un-trashed
|
||||
if (content.Trashed && parentId != -20)
|
||||
{
|
||||
content.ChangeTrashedState(false, parentId);
|
||||
}
|
||||
else
|
||||
{
|
||||
content.ParentId = parentId;
|
||||
}
|
||||
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IContent>(content, parentId), this))
|
||||
return;
|
||||
|
||||
//If Content is published, it should be (re)published from its new location
|
||||
if (content.Published)
|
||||
{
|
||||
SaveAndPublish(content, userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Save(content, userId);
|
||||
}
|
||||
SetWriter(content, userId);
|
||||
var parent = GetById(parentId);
|
||||
content.Path = string.Concat(parent.Path, ",", content.Id);
|
||||
content.Level = parent.Level + 1;
|
||||
|
||||
Moved.RaiseEvent(new MoveEventArgs<IContent>(content, false, parentId), this);
|
||||
//If Content is being moved away from Recycle Bin, its state should be un-trashed
|
||||
if (content.Trashed && parentId != -20)
|
||||
{
|
||||
content.ChangeTrashedState(false, parentId);
|
||||
}
|
||||
else
|
||||
{
|
||||
content.ParentId = parentId;
|
||||
}
|
||||
|
||||
//If Content is published, it should be (re)published from its new location
|
||||
if (content.Published)
|
||||
{
|
||||
//If Content is Publishable its saved and published
|
||||
//otherwise we save the content without changing the publish state, and generate new xml because the Path, Level and Parent has changed.
|
||||
if (IsPublishable(content))
|
||||
{
|
||||
SaveAndPublish(content, userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Save(content, false, userId);
|
||||
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var xml = content.ToXml();
|
||||
var poco = new ContentXmlDto {NodeId = content.Id, Xml = xml.ToString(SaveOptions.None)};
|
||||
var exists =
|
||||
uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = content.Id}) !=
|
||||
null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Save(content, userId);
|
||||
}
|
||||
|
||||
//Ensure that Path and Level is updated on children
|
||||
var children = GetChildren(content.Id);
|
||||
if (children.Any())
|
||||
{
|
||||
foreach (var child in children)
|
||||
{
|
||||
Move(child, content.Id, userId);
|
||||
}
|
||||
}
|
||||
|
||||
Moved.RaiseEvent(new MoveEventArgs<IContent>(content, false, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.Move, "Move Content performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Empties the Recycle Bin by deleting all <see cref="IContent"/> that resides in the bin
|
||||
/// </summary>
|
||||
public void EmptyRecycleBin()
|
||||
@@ -982,7 +793,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
// A copy should never be set to published
|
||||
// automatically even if the original was
|
||||
this.UnPublish(copy);
|
||||
this.UnPublish(copy, userId);
|
||||
|
||||
if (Copying.IsRaisedEventCancelled(new CopyEventArgs<IContent>(content, copy, parentId), this))
|
||||
return null;
|
||||
@@ -996,13 +807,13 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
var uploadFieldId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
|
||||
if (content.Properties.Any(x => x.PropertyType.DataTypeControlId == uploadFieldId))
|
||||
if (content.Properties.Any(x => x.PropertyType.DataTypeId == uploadFieldId))
|
||||
{
|
||||
bool isUpdated = false;
|
||||
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
|
||||
|
||||
//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
|
||||
foreach (var property in content.Properties.Where(x => x.PropertyType.DataTypeId == uploadFieldId
|
||||
&& string.IsNullOrEmpty(x.Value.ToString()) == false))
|
||||
{
|
||||
if (fs.FileExists(IOHelper.MapPath(property.Value.ToString())))
|
||||
@@ -1133,10 +944,344 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to Re-Publishes all Content for legacy purposes.
|
||||
/// </summary>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this RePublish method. By default this method will not update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
internal bool RePublishAll(bool omitCacheRefresh = true, int userId = -1)
|
||||
{
|
||||
return RePublishAllDo(omitCacheRefresh, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method that Publishes a single <see cref="IContent"/> object for legacy purposes.
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will not update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
internal bool Publish(IContent content, bool omitCacheRefresh = true, int userId = -1)
|
||||
{
|
||||
return SaveAndPublishDo(content, omitCacheRefresh, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method that Publishes a <see cref="IContent"/> object and all its children for legacy purposes.
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will not update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
internal bool PublishWithChildren(IContent content, bool omitCacheRefresh = true, int userId = -1)
|
||||
{
|
||||
return PublishWithChildrenDo(content, omitCacheRefresh, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method that UnPublishes a single <see cref="IContent"/> object for legacy purposes.
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will not update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if unpublishing succeeded, otherwise False</returns>
|
||||
internal bool UnPublish(IContent content, bool omitCacheRefresh = true, int userId = -1)
|
||||
{
|
||||
return UnPublishDo(content, omitCacheRefresh, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves and Publishes a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will not update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
internal bool SaveAndPublish(IContent content, bool omitCacheRefresh = true, int userId = -1)
|
||||
{
|
||||
return SaveAndPublishDo(content, omitCacheRefresh, userId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Re-Publishes all Content
|
||||
/// </summary>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this RePublish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
private bool RePublishAllDo(bool omitCacheRefresh = false, int userId = -1)
|
||||
{
|
||||
var list = new List<IContent>();
|
||||
var updated = new List<IContent>();
|
||||
|
||||
//Consider creating a Path query instead of recursive method:
|
||||
//var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
||||
|
||||
var rootContent = GetRootContent();
|
||||
foreach (var content in rootContent)
|
||||
{
|
||||
if (content.IsValid())
|
||||
{
|
||||
list.Add(content);
|
||||
list.AddRange(GetChildrenDeep(content.Id));
|
||||
}
|
||||
}
|
||||
|
||||
//Publish and then update the database with new status
|
||||
var published = _publishingStrategy.PublishWithChildren(list, userId);
|
||||
if (published)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
//Only loop through content where the Published property has been updated
|
||||
foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published")))
|
||||
{
|
||||
SetWriter(item, userId);
|
||||
repository.AddOrUpdate(item);
|
||||
updated.Add(item);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var c in updated)
|
||||
{
|
||||
var xml = c.ToXml();
|
||||
var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = c.Id }) !=
|
||||
null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
//Updating content to published state is finished, so we fire event through PublishingStrategy to have cache updated
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(updated, true);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "RePublish All performed by user", userId == -1 ? 0 : userId, -1);
|
||||
|
||||
return published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes a <see cref="IContent"/> object and all its children
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
private bool PublishWithChildrenDo(IContent content, bool omitCacheRefresh = false, int userId = -1)
|
||||
{
|
||||
//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 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"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;
|
||||
}
|
||||
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (!content.IsValid())
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format("Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Consider creating a Path query instead of recursive method:
|
||||
//var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path));
|
||||
|
||||
var updated = new List<IContent>();
|
||||
var list = new List<IContent>();
|
||||
list.Add(content);
|
||||
list.AddRange(GetChildrenDeep(content.Id));
|
||||
|
||||
//Publish and then update the database with new status
|
||||
var published = _publishingStrategy.PublishWithChildren(list, userId);
|
||||
if (published)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
//Only loop through content where the Published property has been updated
|
||||
foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published")))
|
||||
{
|
||||
SetWriter(item, userId);
|
||||
repository.AddOrUpdate(item);
|
||||
updated.Add(item);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var c in updated)
|
||||
{
|
||||
var xml = c.ToXml();
|
||||
var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = c.Id }) !=
|
||||
null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
//Save xml to db and call following method to fire event:
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(updated, false);
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId == -1 ? 0 : userId,
|
||||
content.Id);
|
||||
}
|
||||
|
||||
return published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UnPublishes a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if unpublishing succeeded, otherwise False</returns>
|
||||
private bool UnPublishDo(IContent content, bool omitCacheRefresh = false, int userId = -1)
|
||||
{
|
||||
var unpublished = _publishingStrategy.UnPublish(content, userId);
|
||||
if (unpublished)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(content);
|
||||
|
||||
//Remove 'published' xml from the cmsContentXml table for the unpublished content
|
||||
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = content.Id });
|
||||
|
||||
uow.Commit();
|
||||
}
|
||||
//Delete xml from db? and call following method to fire event through PublishingStrategy to update cache
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.UnPublishingFinalized(content);
|
||||
|
||||
Audit.Add(AuditTypes.UnPublish, "UnPublish performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
}
|
||||
|
||||
return unpublished;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves and Publishes a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
private bool SaveAndPublishDo(IContent content, bool omitCacheRefresh = false, int userId = -1)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
return false;
|
||||
|
||||
//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 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (!content.IsValid())
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Publish and then update the database with new status
|
||||
bool published = _publishingStrategy.Publish(content, userId);
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
//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);
|
||||
|
||||
uow.Commit();
|
||||
|
||||
if (published)
|
||||
{
|
||||
var xml = content.ToXml();
|
||||
var poco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = content.Id }) != null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
//Save xml to db and call following method to fire event through PublishingStrategy to update cache
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(content);
|
||||
|
||||
//We need to check if children and their publish state to ensure that we republish content that was previously published
|
||||
if (HasChildren(content.Id))
|
||||
{
|
||||
var children = GetChildrenDeep(content.Id);
|
||||
var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id));
|
||||
|
||||
if (omitCacheRefresh == false)
|
||||
_publishingStrategy.PublishingFinalized(shouldBeRepublished, false);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
|
||||
return published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to save</param>
|
||||
/// <param name="changeState">Boolean indicating whether or not to change the Published state upon saving</param>
|
||||
/// <param name="userId">Optional Id of the User saving the Content</param>
|
||||
private void Save(IContent content, bool changeState, int userId = -1)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
SetWriter(content, userId);
|
||||
|
||||
//Only change the publish state if the "previous" version was actually published
|
||||
if (changeState && content.Published)
|
||||
content.ChangePublishedState(PublishedState.Saved);
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Content performed by user", userId == -1 ? 0 : userId, content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flat list of decendents of content from parent id
|
||||
/// </summary>
|
||||
@@ -1189,7 +1334,7 @@ namespace Umbraco.Core.Services
|
||||
if (checkCurrent == false && id == content.Id) continue;
|
||||
|
||||
//Check if the content for the current id is published - escape the loop if we encounter content that isn't published
|
||||
var hasPublishedVersion = ApplicationContext.Current.Services.ContentService.GetById(id).Published;
|
||||
var hasPublishedVersion = HasPublishedVersion(id);
|
||||
if (hasPublishedVersion == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Umbraco.Core.Services
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
|
||||
{
|
||||
//Find ContentTypes using this IDataTypeDefinition on a PropertyType
|
||||
var query = Query<PropertyType>.Builder.Where(x => x.DataTypeId == dataTypeDefinition.Id);
|
||||
var query = Query<PropertyType>.Builder.Where(x => x.DataTypeDefinitionId == dataTypeDefinition.Id);
|
||||
var contentTypes = repository.GetByQuery(query);
|
||||
|
||||
//Loop through the list of results and remove the PropertyTypes that references the DataTypeDefinition that is being deleted
|
||||
@@ -163,7 +163,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
foreach (var group in contentType.PropertyGroups)
|
||||
{
|
||||
var types = @group.PropertyTypes.Where(x => x.DataTypeId == dataTypeDefinition.Id);
|
||||
var types = @group.PropertyTypes.Where(x => x.DataTypeDefinitionId == dataTypeDefinition.Id);
|
||||
foreach (var propertyType in types)
|
||||
{
|
||||
@group.PropertyTypes.Remove(propertyType);
|
||||
|
||||
@@ -13,11 +13,12 @@ namespace Umbraco.Core.Services
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContent(int parentId, string contentTypeAlias, int userId = -1);
|
||||
IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IContent"/> object by Id
|
||||
@@ -209,45 +210,40 @@ namespace Umbraco.Core.Services
|
||||
/// Re-Publishes all Content
|
||||
/// </summary>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this RePublish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
bool RePublishAll(int userId = -1, bool omitCacheRefresh = false);
|
||||
bool RePublishAll(int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Publishes a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
bool Publish(IContent content, int userId = -1, bool omitCacheRefresh = false);
|
||||
bool Publish(IContent content, int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Publishes a <see cref="IContent"/> object and all its children
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
bool PublishWithChildren(IContent content, int userId = -1, bool omitCacheRefresh = false);
|
||||
bool PublishWithChildren(IContent content, int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// UnPublishes a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if unpublishing succeeded, otherwise False</returns>
|
||||
bool UnPublish(IContent content, int userId = -1, bool omitCacheRefresh = false);
|
||||
bool UnPublish(IContent content, int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Saves and Publishes a single <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
bool SaveAndPublish(IContent content, int userId = -1, bool omitCacheRefresh = false);
|
||||
bool SaveAndPublish(IContent content, int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes an <see cref="IContent"/> object.
|
||||
|
||||
@@ -13,11 +13,12 @@ namespace Umbraco.Core.Services
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMedia(int parentId, string mediaTypeAlias, int userId = -1);
|
||||
IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMedia"/> object by Id
|
||||
|
||||
@@ -44,11 +44,12 @@ namespace Umbraco.Core.Services
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(int parentId, string mediaTypeAlias, int userId = -1)
|
||||
public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = -1)
|
||||
{
|
||||
IMediaType mediaType = null;
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
@@ -68,7 +69,7 @@ namespace Umbraco.Core.Services
|
||||
mediaTypeAlias));
|
||||
}
|
||||
|
||||
var media = new Models.Media(parentId, mediaType);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
return media;
|
||||
@@ -262,12 +263,29 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId">Id of the User moving the Media</param>
|
||||
public void Move(IMedia media, int parentId, int userId = -1)
|
||||
{
|
||||
//This ensures that the correct method is called if this method is used to Move to recycle bin.
|
||||
if (parentId == -21)
|
||||
{
|
||||
MoveToRecycleBin(media, userId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, parentId), this))
|
||||
return;
|
||||
|
||||
media.ParentId = parentId;
|
||||
Save(media, userId);
|
||||
|
||||
//Ensure that Path and Level is updated on children
|
||||
var children = GetChildren(media.Id);
|
||||
if (children.Any())
|
||||
{
|
||||
var parentPath = media.Path;
|
||||
var parentLevel = media.Level;
|
||||
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
|
||||
Save(updatedDescendents, userId);
|
||||
}
|
||||
|
||||
Moved.RaiseEvent(new MoveEventArgs<IMedia>(media, false, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.Move, "Move Media performed by user", userId == -1 ? 0 : userId, media.Id);
|
||||
@@ -280,14 +298,20 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId">Id of the User deleting the Media</param>
|
||||
public void MoveToRecycleBin(IMedia media, int userId = -1)
|
||||
{
|
||||
//TODO If media item has children those should also be moved to the recycle bin as well
|
||||
if (Trashing.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, -21), this))
|
||||
if (Trashing.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, -21), this))
|
||||
return;
|
||||
|
||||
//Move children to Recycle Bin before the 'possible parent' is moved there
|
||||
var children = GetChildren(media.Id);
|
||||
foreach (var child in children)
|
||||
{
|
||||
MoveToRecycleBin(child, userId);
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
((Core.Models.Media)media).ChangeTrashedState(true);
|
||||
media.ChangeTrashedState(true);
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
}
|
||||
@@ -499,6 +523,32 @@ namespace Umbraco.Core.Services
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Path and Level on a collection of <see cref="IMedia"/> objects
|
||||
/// based on the Parent's Path and Level.
|
||||
/// </summary>
|
||||
/// <param name="children">Collection of <see cref="IMedia"/> objects to update</param>
|
||||
/// <param name="parentPath">Path of the Parent media</param>
|
||||
/// <param name="parentLevel">Level of the Parent media</param>
|
||||
/// <returns>Collection of updated <see cref="IMedia"/> objects</returns>
|
||||
private List<IMedia> UpdatePathAndLevelOnChildren(IEnumerable<IMedia> children, string parentPath, int parentLevel)
|
||||
{
|
||||
var list = new List<IMedia>();
|
||||
foreach (var child in children)
|
||||
{
|
||||
child.Path = string.Concat(parentPath, ",", child.Id);
|
||||
child.Level = parentLevel + 1;
|
||||
list.Add(child);
|
||||
|
||||
var grandkids = GetChildren(child.Id);
|
||||
if (grandkids.Any())
|
||||
{
|
||||
list.AddRange(UpdatePathAndLevelOnChildren(grandkids, child.Path, child.Level));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates a media object with the User (id), who created the content.
|
||||
/// </summary>
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Configuration;
|
||||
using System.Web.Security;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -20,47 +21,57 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
public static class StringExtensions
|
||||
{
|
||||
//this is from SqlMetal and just makes it a bit of fun to allow pluralisation
|
||||
public static string MakePluralName(this string name)
|
||||
{
|
||||
if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
name = name + "es";
|
||||
return name;
|
||||
}
|
||||
if ((name.EndsWith("y", StringComparison.OrdinalIgnoreCase) && (name.Length > 1)) && !IsVowel(name[name.Length - 2]))
|
||||
{
|
||||
name = name.Remove(name.Length - 1, 1);
|
||||
name = name + "ies";
|
||||
return name;
|
||||
}
|
||||
if (!name.EndsWith("s", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
name = name + "s";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
public static string EncryptWithMachineKey(this string toEncrypt)
|
||||
{
|
||||
var output = FormsAuthentication.Encrypt(new FormsAuthenticationTicket(0, "temp", DateTime.Now, DateTime.MaxValue, false, toEncrypt));
|
||||
return output;
|
||||
}
|
||||
public static string DecryptWithMachineKey(this string encrypted)
|
||||
{
|
||||
var output = FormsAuthentication.Decrypt(encrypted);
|
||||
return output.UserData;
|
||||
}
|
||||
//this is from SqlMetal and just makes it a bit of fun to allow pluralisation
|
||||
public static string MakePluralName(this string name)
|
||||
{
|
||||
if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
name = name + "es";
|
||||
return name;
|
||||
}
|
||||
if ((name.EndsWith("y", StringComparison.OrdinalIgnoreCase) && (name.Length > 1)) && !IsVowel(name[name.Length - 2]))
|
||||
{
|
||||
name = name.Remove(name.Length - 1, 1);
|
||||
name = name + "ies";
|
||||
return name;
|
||||
}
|
||||
if (!name.EndsWith("s", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
name = name + "s";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static bool IsVowel(this char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'O':
|
||||
case 'U':
|
||||
case 'Y':
|
||||
case 'A':
|
||||
case 'E':
|
||||
case 'I':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'y':
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool IsVowel(this char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'O':
|
||||
case 'U':
|
||||
case 'Y':
|
||||
case 'A':
|
||||
case 'E':
|
||||
case 'I':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'y':
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trims the specified value from a string; accepts a string input whereas the in-built implementation only accepts char or char[].
|
||||
@@ -74,49 +85,49 @@ namespace Umbraco.Core
|
||||
return value.TrimEnd(forRemoving).TrimStart(forRemoving);
|
||||
}
|
||||
|
||||
public static string EncodeJsString(this string s)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var c in s)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\"':
|
||||
sb.Append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.Append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
sb.Append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
sb.Append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
sb.Append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
sb.Append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
sb.Append("\\t");
|
||||
break;
|
||||
default:
|
||||
int i = (int)c;
|
||||
if (i < 32 || i > 127)
|
||||
{
|
||||
sb.AppendFormat("\\u{0:X04}", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
public static string EncodeJsString(this string s)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var c in s)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\"':
|
||||
sb.Append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.Append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
sb.Append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
sb.Append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
sb.Append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
sb.Append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
sb.Append("\\t");
|
||||
break;
|
||||
default:
|
||||
int i = (int)c;
|
||||
if (i < 32 || i > 127)
|
||||
{
|
||||
sb.AppendFormat("\\u{0:X04}", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string TrimEnd(this string value, string forRemoving)
|
||||
{
|
||||
@@ -144,25 +155,25 @@ namespace Umbraco.Core
|
||||
return toStartWith + input.TrimStart(toStartWith.ToArray()); // Ensure each char is removed first from input, e.g. ~/ plus /Path will equal ~/Path not ~//Path
|
||||
}
|
||||
|
||||
public static string EnsureStartsWith(this string input, char value)
|
||||
{
|
||||
return input.StartsWith(value.ToString()) ? input : value + input;
|
||||
}
|
||||
public static string EnsureStartsWith(this string input, char value)
|
||||
{
|
||||
return input.StartsWith(value.ToString()) ? input : value + input;
|
||||
}
|
||||
|
||||
public static string EnsureEndsWith(this string input, char value)
|
||||
{
|
||||
return input.EndsWith(value.ToString()) ? input : input + value;
|
||||
}
|
||||
public static string EnsureEndsWith(this string input, char value)
|
||||
{
|
||||
return input.EndsWith(value.ToString()) ? input : input + value;
|
||||
}
|
||||
|
||||
public static bool IsLowerCase(this char ch)
|
||||
{
|
||||
return ch.ToString(CultureInfo.InvariantCulture) == ch.ToString(CultureInfo.InvariantCulture).ToLower();
|
||||
}
|
||||
|
||||
public static bool IsUpperCase(this char ch)
|
||||
{
|
||||
return ch.ToString(CultureInfo.InvariantCulture) == ch.ToString(CultureInfo.InvariantCulture).ToUpper();
|
||||
}
|
||||
public static bool IsUpperCase(this char ch)
|
||||
{
|
||||
return ch.ToString(CultureInfo.InvariantCulture) == ch.ToString(CultureInfo.InvariantCulture).ToUpper();
|
||||
}
|
||||
|
||||
/// <summary>Is null or white space.</summary>
|
||||
/// <param name="str">The str.</param>
|
||||
@@ -479,10 +490,10 @@ namespace Umbraco.Core
|
||||
return String.Equals(compare, compareTo, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public static bool InvariantStartsWith(this string compare, string compareTo)
|
||||
{
|
||||
return compare.StartsWith(compareTo, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
public static bool InvariantStartsWith(this string compare, string compareTo)
|
||||
{
|
||||
return compare.StartsWith(compareTo, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public static bool InvariantContains(this string compare, string compareTo)
|
||||
{
|
||||
@@ -697,7 +708,7 @@ namespace Umbraco.Core
|
||||
.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
||||
return currentFolder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Truncates the specified text string.
|
||||
@@ -760,5 +771,54 @@ namespace Umbraco.Core
|
||||
|
||||
return newUrl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An extention method to ensure that an Alias string doesn't contains any illegal characters
|
||||
/// which is defined in a private constant 'ValidCharacters' in this class.
|
||||
/// Conventions over configuration, baby. You can't touch this - MC Hammer!
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Copied and cleaned up a bit from umbraco.cms.helpers.Casing.
|
||||
/// </remarks>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <returns>An alias guaranteed not to contain illegal characters</returns>
|
||||
public static string ToSafeAlias(this string alias)
|
||||
{
|
||||
const string validAliasCharacters = "_-abcdefghijklmnopqrstuvwxyz1234567890";
|
||||
const string invalidFirstCharacters = "01234567890";
|
||||
var safeString = new StringBuilder();
|
||||
int aliasLength = alias.Length;
|
||||
for (int i = 0; i < aliasLength; i++)
|
||||
{
|
||||
string currentChar = alias.Substring(i, 1);
|
||||
if (validAliasCharacters.Contains(currentChar.ToLower()))
|
||||
{
|
||||
// check for camel (if previous character is a space, we'll upper case the current one
|
||||
if (safeString.Length == 0 && invalidFirstCharacters.Contains(currentChar.ToLower()))
|
||||
{
|
||||
currentChar = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i < aliasLength - 1 && i > 0 && alias.Substring(i - 1, 1) == " ")
|
||||
currentChar = currentChar.ToUpper();
|
||||
|
||||
safeString.Append(currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return safeString.ToString();
|
||||
}
|
||||
|
||||
public static string ToSafeAliasWithForcingCheck(this string alias)
|
||||
{
|
||||
if (UmbracoSettings.ForceSafeAliases)
|
||||
{
|
||||
return alias.ToSafeAlias();
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Release\Umbraco.Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
@@ -118,6 +119,7 @@
|
||||
<Compile Include="Dictionary\CultureDictionaryFactoryResolver.cs" />
|
||||
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
|
||||
<Compile Include="Dynamics\DynamicInstanceHelper.cs" />
|
||||
<Compile Include="Dynamics\DynamicXmlConverter.cs" />
|
||||
<Compile Include="Events\CancellableEventArgs.cs" />
|
||||
<Compile Include="Events\ContentCacheEventArgs.cs" />
|
||||
<Compile Include="Events\CopyEventArgs.cs" />
|
||||
@@ -125,6 +127,7 @@
|
||||
<Compile Include="Events\CancellableObjectEventArgs.cs" />
|
||||
<Compile Include="Events\DeleteRevisionsEventArgs.cs" />
|
||||
<Compile Include="Events\EventExtensions.cs" />
|
||||
<Compile Include="Events\MigrationEventArgs.cs" />
|
||||
<Compile Include="Events\PublishEventArgs.cs" />
|
||||
<Compile Include="Events\TypedEventHandler.cs" />
|
||||
<Compile Include="Events\MoveEventArgs.cs" />
|
||||
@@ -181,6 +184,7 @@
|
||||
<Compile Include="Models\PropertyExtensions.cs" />
|
||||
<Compile Include="Models\PropertyTypeExtensions.cs" />
|
||||
<Compile Include="Models\PublishedItemType.cs" />
|
||||
<Compile Include="Models\PublishedState.cs" />
|
||||
<Compile Include="Models\Rdbms\ContentType2ContentTypeDto.cs" />
|
||||
<Compile Include="Models\Rdbms\PropertyTypeGroupDto.cs" />
|
||||
<Compile Include="Models\Relation.cs" />
|
||||
@@ -265,8 +269,8 @@
|
||||
<Compile Include="Persistence\Migrations\MigrationBase.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationContext.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationExpressionBase.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationResolver.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationRunner.cs" />
|
||||
<Compile Include="Persistence\Migrations\PluginManagerExtension.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Alter\AlterSyntaxBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Alter\Column\AlterColumnBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Alter\Column\IAlterColumnOptionForeignKeyCascadeSyntax.cs" />
|
||||
@@ -372,18 +376,18 @@
|
||||
<Compile Include="Persistence\Migrations\Syntax\Update\IUpdateWhereSyntax.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Update\UpdateBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Update\UpdateDataBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionFourEightZero\RemoveUmbracoAppConstraints.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\DeleteAppTables.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\EnsureAppsTreesUpdated.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\MoveMasterContentTypeData.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\NewCmsContentType2ContentTypeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\RemoveMasterContentTypeColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\RenameTabIdColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\UpdateCmsContentTypeAllowedContentTypeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\UpdateCmsContentTypeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\UpdateCmsContentVersionTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\UpdateCmsPropertyTypeGroupTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixth\RenameCmsTabTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionFourNineZero\RemoveUmbracoAppConstraints.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\DeleteAppTables.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\EnsureAppsTreesUpdated.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\MoveMasterContentTypeData.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\NewCmsContentType2ContentTypeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\RemoveMasterContentTypeColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\RenameTabIdColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\UpdateCmsContentTypeAllowedContentTypeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\UpdateCmsContentTypeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\UpdateCmsContentVersionTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\UpdateCmsPropertyTypeGroupTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\RenameCmsTabTable.cs" />
|
||||
<Compile Include="Persistence\PetaPocoExtensions.cs" />
|
||||
<Compile Include="Persistence\PetaPocoSqlExtensions.cs" />
|
||||
<Compile Include="Persistence\Querying\PocoToSqlExpressionHelper.cs" />
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Umbraco.Core
|
||||
/// <param name="text">The text.</param>
|
||||
/// <param name="xmlDoc">The XML doc.</param>
|
||||
/// <returns></returns>
|
||||
internal static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
|
||||
public static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
|
||||
{
|
||||
xmlDoc.LoadXml(text);
|
||||
return xmlDoc.FirstChild;
|
||||
@@ -80,7 +80,7 @@ namespace Umbraco.Core
|
||||
/// <param name="name">The node name.</param>
|
||||
/// <param name="value">The node value.</param>
|
||||
/// <returns>A XmlNode</returns>
|
||||
public static XmlNode AddCDataNode(XmlDocument xd, string name, string value)
|
||||
public static XmlNode AddCDataNode(XmlDocument xd, string name, string value)
|
||||
{
|
||||
var temp = xd.CreateNode(XmlNodeType.Element, name, "");
|
||||
temp.AppendChild(xd.CreateCDataSection(value));
|
||||
@@ -92,7 +92,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="n">The XmlNode.</param>
|
||||
/// <returns>the value as a string</returns>
|
||||
internal static string GetNodeValue(XmlNode n)
|
||||
public static string GetNodeValue(XmlNode n)
|
||||
{
|
||||
var value = string.Empty;
|
||||
if (n == null || n.FirstChild == null)
|
||||
@@ -108,7 +108,7 @@ namespace Umbraco.Core
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified string appears to be XML; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
internal static bool CouldItBeXml(string xml)
|
||||
public static bool CouldItBeXml(string xml)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(xml))
|
||||
{
|
||||
@@ -131,7 +131,7 @@ namespace Umbraco.Core
|
||||
/// <param name="rootName">Name of the root.</param>
|
||||
/// <param name="elementName">Name of the element.</param>
|
||||
/// <returns>Returns an <c>System.Xml.XmlDocument</c> representation of the delimited string data.</returns>
|
||||
internal static XmlDocument Split(string data, string[] separator, string rootName, string elementName)
|
||||
public static XmlDocument Split(string data, string[] separator, string rootName, string elementName)
|
||||
{
|
||||
return Split(new XmlDocument(), data, separator, rootName, elementName);
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace Umbraco.Core
|
||||
/// <param name="rootName">Name of the root node.</param>
|
||||
/// <param name="elementName">Name of the element node.</param>
|
||||
/// <returns>Returns an <c>System.Xml.XmlDocument</c> representation of the delimited string data.</returns>
|
||||
internal static XmlDocument Split(XmlDocument xml, string data, string[] separator, string rootName, string elementName)
|
||||
public static XmlDocument Split(XmlDocument xml, string data, string[] separator, string rootName, string elementName)
|
||||
{
|
||||
// load new XML document.
|
||||
xml.LoadXml(string.Concat("<", rootName, "/>"));
|
||||
@@ -174,7 +174,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="tag"></param>
|
||||
/// <returns></returns>
|
||||
internal static Dictionary<string, string> GetAttributesFromElement(string tag)
|
||||
public static Dictionary<string, string> GetAttributesFromElement(string tag)
|
||||
{
|
||||
var m =
|
||||
Regex.Matches(tag, "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"",
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Umbraco.Tests.BusinessLogic
|
||||
private void ClearDatabase()
|
||||
{
|
||||
var databaseSettings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName];
|
||||
var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString) as SqlCEHelper;
|
||||
var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString, false) as SqlCEHelper;
|
||||
|
||||
if (dataHelper == null)
|
||||
throw new InvalidOperationException("The sql helper for unit tests must be of type SqlCEHelper, check the ensure the connection string used for this test is set to use SQLCE");
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Tests.BusinessLogic
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", TestHelper.CurrentAssemblyDirectory);
|
||||
|
||||
var databaseSettings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName];
|
||||
var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString) as SqlCEHelper;
|
||||
var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString, false) as SqlCEHelper;
|
||||
|
||||
var installer = dataHelper.Utility.CreateInstaller();
|
||||
if (installer.CanConnect)
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace Umbraco.Tests.ContentStores
|
||||
PublishedMediaTests.DoTearDown();
|
||||
}
|
||||
|
||||
[Ignore]
|
||||
[Test]
|
||||
public void Get_Root_Docs()
|
||||
{
|
||||
@@ -47,6 +48,7 @@ namespace Umbraco.Tests.ContentStores
|
||||
|
||||
}
|
||||
|
||||
[Ignore]
|
||||
[Test]
|
||||
public void Get_Item_Without_Examine()
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Umbraco.Tests
|
||||
ConfigurationManager.AppSettings.Set("umbracoReservedUrls", "");
|
||||
}
|
||||
|
||||
[Ignore]
|
||||
[Test]
|
||||
public void Is_Version_From_Assembly_Correct()
|
||||
{
|
||||
|
||||
@@ -110,6 +110,7 @@ namespace Umbraco.Tests.IO
|
||||
_fileSystem.DeleteDirectory("test", true);
|
||||
}
|
||||
|
||||
[Ignore]
|
||||
[Test]
|
||||
public void Can_Get_File_Dates()
|
||||
{
|
||||
|
||||
@@ -13,6 +13,13 @@ namespace Umbraco.Tests.IO
|
||||
public class IOHelperTest
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void IOHelper_ResolveUrl()
|
||||
{
|
||||
var result = IOHelper.ResolveUrl("~/Scripts");
|
||||
Assert.AreEqual("/Scripts", result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for MapPath verifying that HttpContext method (which includes vdirs) matches non-HttpContext method
|
||||
///</summary>
|
||||
|
||||
@@ -3,6 +3,8 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
using umbraco.BusinessLogic;
|
||||
using umbraco.cms.businesslogic.datatype;
|
||||
using umbraco.cms.businesslogic.media;
|
||||
|
||||
namespace Umbraco.Tests.LegacyApi
|
||||
@@ -37,6 +39,49 @@ namespace Umbraco.Tests.LegacyApi
|
||||
Assert.That(updated.AllowedChildContentTypeIDs.Any(x => x == 1045), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Set_Tab_On_PropertyType()
|
||||
{
|
||||
var UPLOAD_DATATYPE_ID = -90;
|
||||
var CROP_DATATYPE_ID = 1043;
|
||||
var LABEL_DATATYPE_ID = -92;
|
||||
var mediaTypeName = "ImageWide";
|
||||
|
||||
MediaType mediaType = MediaType.MakeNew(new User(0), mediaTypeName);
|
||||
|
||||
int imageTab = mediaType.AddVirtualTab("Image");
|
||||
int cropTab = mediaType.AddVirtualTab("Crop");
|
||||
|
||||
mediaType.AddPropertyType(new DataTypeDefinition(UPLOAD_DATATYPE_ID), "umbracoFile", "Upload image");
|
||||
mediaType.AddPropertyType(new DataTypeDefinition(LABEL_DATATYPE_ID), "umbracoWidth", "Width");
|
||||
mediaType.AddPropertyType(new DataTypeDefinition(LABEL_DATATYPE_ID), "umbracoHeight", "Height");
|
||||
mediaType.AddPropertyType(new DataTypeDefinition(LABEL_DATATYPE_ID), "umbracoBytes", "Size");
|
||||
mediaType.AddPropertyType(new DataTypeDefinition(LABEL_DATATYPE_ID), "umbracoExtension", "Type");
|
||||
mediaType.AddPropertyType(new DataTypeDefinition(CROP_DATATYPE_ID), "wideImage", "Wide image");
|
||||
|
||||
mediaType.SetTabOnPropertyType(mediaType.getPropertyType("umbracoFile"), imageTab);
|
||||
mediaType.SetTabOnPropertyType(mediaType.getPropertyType("umbracoWidth"), imageTab);
|
||||
mediaType.SetTabOnPropertyType(mediaType.getPropertyType("umbracoHeight"), imageTab);
|
||||
mediaType.SetTabOnPropertyType(mediaType.getPropertyType("umbracoBytes"), imageTab);
|
||||
mediaType.SetTabOnPropertyType(mediaType.getPropertyType("umbracoExtension"), imageTab);
|
||||
mediaType.SetTabOnPropertyType(mediaType.getPropertyType("wideImage"), cropTab);
|
||||
|
||||
mediaType.Text = mediaTypeName;
|
||||
mediaType.IconUrl = "mediaPhoto.gif";
|
||||
mediaType.Save();
|
||||
|
||||
Assert.That(mediaType.getVirtualTabs.Count(), Is.EqualTo(2));
|
||||
Assert.That(mediaType.getVirtualTabs.Any(x => x.Caption.Equals("Image")), Is.True);
|
||||
Assert.That(mediaType.getVirtualTabs.Any(x => x.Caption.Equals("Crop")), Is.True);
|
||||
|
||||
var updated = new MediaType(mediaType.Id);
|
||||
Assert.That(updated.getVirtualTabs.Count(), Is.EqualTo(2));
|
||||
Assert.That(updated.getVirtualTabs.Any(x => x.Caption.Equals("Image")), Is.True);
|
||||
Assert.That(updated.getVirtualTabs.Any(x => x.Caption.Equals("Crop")), Is.True);
|
||||
Assert.That(updated.ContentTypeItem.PropertyGroups.Count(), Is.EqualTo(2));
|
||||
Assert.That(updated.ContentTypeItem.PropertyTypes.Count(), Is.EqualTo(6));
|
||||
}
|
||||
|
||||
public void CreateTestData()
|
||||
{
|
||||
//Create and Save ContentType "video" -> 1045
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.Migrations
|
||||
public void Can_Get_Up_Migration_From_MigrationStub()
|
||||
{
|
||||
// Arrange
|
||||
var context = new MigrationContext(DatabaseProviders.SqlServerCE);
|
||||
var context = new MigrationContext(DatabaseProviders.SqlServerCE, null);
|
||||
var stub = new AlterUserTableMigrationStub();
|
||||
|
||||
// Act
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
@@ -19,31 +20,25 @@ namespace Umbraco.Tests.Migrations
|
||||
{
|
||||
TestHelper.SetupLog4NetForTests();
|
||||
|
||||
//this ensures its reset
|
||||
PluginManager.Current = new PluginManager(false);
|
||||
MigrationResolver.Current = new MigrationResolver(new List<Type>
|
||||
{
|
||||
typeof (AlterUserTableMigrationStub),
|
||||
typeof(Dummy),
|
||||
typeof (FourNineMigration),
|
||||
typeof (FourTenMigration),
|
||||
typeof (FourElevenMigration),
|
||||
typeof (FourElevenMigration)
|
||||
});
|
||||
|
||||
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
|
||||
PluginManager.Current.AssembliesToScan = new[]
|
||||
{
|
||||
typeof (FourNineMigration).Assembly
|
||||
};
|
||||
Resolution.Freeze();
|
||||
|
||||
SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Find_Migrations_In_Current_Assembly()
|
||||
{
|
||||
var foundTypes = PluginManager.Current.ResolveMigrationTypes();
|
||||
|
||||
Assert.That(foundTypes.Any(), Is.True);
|
||||
Assert.That(foundTypes.Count(), Is.EqualTo(4));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Find_Migrations_With_Targtet_Version_Six()
|
||||
{
|
||||
var foundMigrations = PluginManager.Current.FindMigrations();
|
||||
var foundMigrations = MigrationResolver.Current.Migrations;
|
||||
var targetVersion = new Version("6.0.0");
|
||||
var list = new List<IMigration>();
|
||||
|
||||
@@ -61,7 +56,7 @@ namespace Umbraco.Tests.Migrations
|
||||
|
||||
Assert.That(list.Count, Is.EqualTo(3));
|
||||
|
||||
var context = new MigrationContext(DatabaseProviders.SqlServerCE);
|
||||
var context = new MigrationContext(DatabaseProviders.SqlServerCE, null);
|
||||
foreach (MigrationBase migration in list)
|
||||
{
|
||||
migration.GetUpExpressions(context);
|
||||
@@ -78,8 +73,9 @@ namespace Umbraco.Tests.Migrations
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
PluginManager.Current = null;
|
||||
{
|
||||
MigrationResolver.Reset();
|
||||
Resolution.IsFrozen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
|
||||
namespace Umbraco.Tests.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for TypeInheritanceTest and CodeFirstTests
|
||||
/// </summary>
|
||||
internal static class PluginManagerExtensions
|
||||
{
|
||||
public static IEnumerable<Type> ResolveMigrationTypes(this PluginManager resolver)
|
||||
{
|
||||
return resolver.ResolveTypesWithAttribute<IMigration, MigrationAttribute>();
|
||||
}
|
||||
|
||||
public static IEnumerable<IMigration> FindMigrations(this PluginManager resolver)
|
||||
{
|
||||
var types = resolver.ResolveTypesWithAttribute<IMigration, MigrationAttribute>();
|
||||
return resolver.CreateInstances<IMigration>(types);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -86,23 +86,47 @@ namespace Umbraco.Tests.Migrations.SqlScripts {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to /*******************************************************************************************
|
||||
/// Looks up a localized string similar to -- Script Date: 10-01-2013 11:50 - Generated by ExportSqlCe version 3.5.2.18
|
||||
///-- Database information:
|
||||
///-- Locale Identifier: 1030
|
||||
///-- Encryption Mode:
|
||||
///-- Case Sensitive: False
|
||||
///-- Database: C:\Temp\Playground\Umb4110Starterkit\Umb4110Starterkit\App_Data\Umbraco.sdf
|
||||
///-- ServerVersion: 4.0.8876.1
|
||||
///-- DatabaseSize: 1114112
|
||||
///-- Created: 10-01-2013 11:39
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
/// Umbraco database installation script for SQL Server CE 4
|
||||
///-- User Table information:
|
||||
///-- Number of tables: 43
|
||||
///-- cmsContent: 12 row(s)
|
||||
///-- cmsContentType: 10 row(s)
|
||||
///-- cmsContentTypeAllowedContentType: 8 row(s [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SqlCe_SchemaAndData_4110 {
|
||||
get {
|
||||
return ResourceManager.GetString("SqlCe_SchemaAndData_4110", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CREATE TABLE [umbracoRelation]
|
||||
///(
|
||||
///[id] [int] NOT NULL IDENTITY(1, 1),
|
||||
///[parentId] [int] NOT NULL,
|
||||
///[childId] [int] NOT NULL,
|
||||
///[relType] [int] NOT NULL,
|
||||
///[datetime] [datetime] NOT NULL CONSTRAINT [DF_umbracoRelation_datetime] DEFAULT (getdate()),
|
||||
///[comment] [nvarchar] (1000) NOT NULL
|
||||
///)
|
||||
///
|
||||
///IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
|
||||
///
|
||||
/// Database version: 4.8.0.1
|
||||
///
|
||||
/// Please increment this version number if ANY change is made to this script,
|
||||
/// so compatibility with scripts for other database systems can be verified easily.
|
||||
/// The first 3 digits depict the Umbraco [rest of string was truncated]";.
|
||||
///;
|
||||
///ALTER TABLE [umbracoRelation] ADD CONSTRAINT [PK_umbracoRelation] PRIMARY KEY ([id])
|
||||
///;
|
||||
///CREATE TABLE [cmsDocument]
|
||||
///(
|
||||
///[nodeId] [int] NOT NULL,
|
||||
///[published] [bit] NOT NULL,
|
||||
///[documentUser] [int] NOT [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SqlCeTotal_480 {
|
||||
get {
|
||||
|
||||
@@ -124,6 +124,9 @@
|
||||
<data name="SqlCeTotal_480" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>sqlcetotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="SqlCe_SchemaAndData_4110" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>sqlce-schemaanddata-4110.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
|
||||
</data>
|
||||
<data name="SqlServerTotal_480" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>sqlservertotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
|
||||
@@ -18,38 +21,38 @@ namespace Umbraco.Tests.Migrations
|
||||
{
|
||||
TestHelper.SetupLog4NetForTests();
|
||||
|
||||
//this ensures its reset
|
||||
PluginManager.Current = new PluginManager(false);
|
||||
MigrationResolver.Current = new MigrationResolver(new List<Type>
|
||||
{
|
||||
typeof (Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero.RemoveUmbracoAppConstraints),
|
||||
typeof (DeleteAppTables),
|
||||
typeof (EnsureAppsTreesUpdated),
|
||||
typeof (MoveMasterContentTypeData),
|
||||
typeof (NewCmsContentType2ContentTypeTable),
|
||||
typeof (RemoveMasterContentTypeColumn),
|
||||
typeof (RenameCmsTabTable),
|
||||
typeof (RenameTabIdColumn),
|
||||
typeof (UpdateCmsContentTypeAllowedContentTypeTable),
|
||||
typeof (UpdateCmsContentTypeTable),
|
||||
typeof (UpdateCmsContentVersionTable),
|
||||
typeof (UpdateCmsPropertyTypeGroupTable)
|
||||
});
|
||||
|
||||
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
|
||||
PluginManager.Current.AssembliesToScan = new[]
|
||||
{
|
||||
typeof (MigrationRunner).Assembly
|
||||
};
|
||||
Resolution.Freeze();
|
||||
|
||||
SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Find_Migrations_In_Current_Assembly()
|
||||
{
|
||||
var foundTypes = PluginManager.Current.ResolveMigrationTypes();
|
||||
|
||||
Assert.That(foundTypes.Any(), Is.True);
|
||||
Assert.That(foundTypes.Count(), Is.GreaterThanOrEqualTo(11));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Can_Find_Targetted_Migrations()
|
||||
{
|
||||
var configuredVersion = new Version("4.11.0");
|
||||
var targetVersion = new Version("6.0.0");
|
||||
var foundMigrations = PluginManager.Current.FindMigrations();
|
||||
var foundMigrations = MigrationResolver.Current.Migrations;
|
||||
|
||||
var migrationRunner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
|
||||
var migrations = migrationRunner.OrderedUpgradeMigrations(foundMigrations);
|
||||
|
||||
var context = new MigrationContext(DatabaseProviders.SqlServerCE);
|
||||
var context = new MigrationContext(DatabaseProviders.SqlServerCE, null);
|
||||
foreach (MigrationBase migration in migrations)
|
||||
{
|
||||
migration.GetUpExpressions(context);
|
||||
@@ -66,7 +69,8 @@ namespace Umbraco.Tests.Migrations
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
PluginManager.Current = null;
|
||||
MigrationResolver.Reset();
|
||||
Resolution.IsFrozen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.Strategies.Migrations;
|
||||
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
|
||||
|
||||
namespace Umbraco.Tests.Migrations.Upgrades
|
||||
@@ -15,7 +19,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
public abstract class BaseUpgradeTest
|
||||
{
|
||||
/// <summary>Regular expression that finds multiline block comments.</summary>
|
||||
private static readonly Regex m_findComments = new Regex(@"\/\*.*?\*\/", RegexOptions.Singleline | RegexOptions.Compiled);
|
||||
private static readonly Regex FindComments = new Regex(@"\/\*.*?\*\/", RegexOptions.Singleline | RegexOptions.Compiled);
|
||||
|
||||
[SetUp]
|
||||
public virtual void Initialize()
|
||||
@@ -27,15 +31,24 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", Path);
|
||||
|
||||
UmbracoSettings.UseLegacyXmlSchema = false;
|
||||
|
||||
MigrationResolver.Current = new MigrationResolver(new List<Type>
|
||||
{
|
||||
typeof (Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero.RemoveUmbracoAppConstraints),
|
||||
typeof (DeleteAppTables),
|
||||
typeof (EnsureAppsTreesUpdated),
|
||||
typeof (MoveMasterContentTypeData),
|
||||
typeof (NewCmsContentType2ContentTypeTable),
|
||||
typeof (RemoveMasterContentTypeColumn),
|
||||
typeof (RenameCmsTabTable),
|
||||
typeof (RenameTabIdColumn),
|
||||
typeof (UpdateCmsContentTypeAllowedContentTypeTable),
|
||||
typeof (UpdateCmsContentTypeTable),
|
||||
typeof (UpdateCmsContentVersionTable),
|
||||
typeof (UpdateCmsPropertyTypeGroupTable)
|
||||
});
|
||||
|
||||
//this ensures its reset
|
||||
PluginManager.Current = new PluginManager(false);
|
||||
|
||||
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
|
||||
PluginManager.Current.AssembliesToScan = new[]
|
||||
{
|
||||
typeof (MigrationRunner).Assembly
|
||||
};
|
||||
Resolution.Freeze();
|
||||
|
||||
DatabaseSpecificSetUp();
|
||||
|
||||
@@ -43,7 +56,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Upgrade_From_470_To_600()
|
||||
public virtual void Can_Upgrade_From_470_To_600()
|
||||
{
|
||||
var configuredVersion = new Version("4.7.0");
|
||||
var targetVersion = new Version("6.0.0");
|
||||
@@ -53,13 +66,13 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
//Create db schema and data from old Total.sql file for Sql Ce
|
||||
string statements = GetDatabaseSpecificSqlScript();
|
||||
// replace block comments by whitespace
|
||||
statements = m_findComments.Replace(statements, " ");
|
||||
statements = FindComments.Replace(statements, " ");
|
||||
// execute all non-empty statements
|
||||
foreach (string statement in statements.Split(";".ToCharArray()))
|
||||
{
|
||||
string rawStatement = statement.Trim();
|
||||
string rawStatement = statement.Replace("GO", "").Trim();
|
||||
if (rawStatement.Length > 0)
|
||||
db.Execute(rawStatement);
|
||||
db.Execute(new Sql(rawStatement));
|
||||
}
|
||||
|
||||
//Setup the MigrationRunner
|
||||
@@ -82,6 +95,8 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
{
|
||||
PluginManager.Current = null;
|
||||
SyntaxConfig.SqlSyntaxProvider = null;
|
||||
MigrationResolver.Reset();
|
||||
Resolution.IsFrozen = false;
|
||||
|
||||
TestHelper.CleanContentDirectories();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user