diff --git a/.hgtags b/.hgtags index 6a3fe90af2..e6189102f5 100644 --- a/.hgtags +++ b/.hgtags @@ -24,3 +24,4 @@ f6da531fbb4c251ff61d314e2a7effb13c71e74a Release-4.10.0 54cde33b809dcb3a1f7e7ae0d5375f6dd0d89c8d Release-4.11.2.2 ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta 56015ac26f5ab60e3c61b1d09075297b660afa07 Release-6.0.0-RC +1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0 diff --git a/build/Build.bat b/build/Build.bat index fa786d3c85..51196d6527 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -1,6 +1,6 @@ @ECHO OFF SET release=6.0.0 -SET comment=RC +SET comment= SET version=%release% IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%) diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 5d7845bb68..7e6e2d53b5 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -201,6 +201,7 @@ namespace Umbraco.Core.Configuration } } + /// /// Saves a setting into the configuration file. /// diff --git a/src/Umbraco.Core/Configuration/InfrastructureSettings/Infrastructure.cs b/src/Umbraco.Core/Configuration/InfrastructureSettings/Infrastructure.cs new file mode 100644 index 0000000000..8a8f4454bc --- /dev/null +++ b/src/Umbraco.Core/Configuration/InfrastructureSettings/Infrastructure.cs @@ -0,0 +1,190 @@ +using System.Configuration; + +namespace Umbraco.Core.Configuration.InfrastructureSettings +{ + public class Infrastructure : ConfigurationSection + { + private const string InfrastructureSectionName = "umbraco/infrastructure"; + + public static Infrastructure Instance + { + get { return (Infrastructure) ConfigurationManager.GetSection(InfrastructureSectionName); } + } + + #region RepositoriesSection Property + + internal const string RepositoriesPropertyName = "repositories"; + + [ConfigurationProperty(RepositoriesPropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)] + public Repositories Repositories + { + get { return ((Repositories)base[RepositoriesPropertyName]); } + set { base[RepositoriesPropertyName] = value; } + } + + #endregion + + #region PublishingStrategy Property + + internal const string PublishingStrategyPropertyName = "publishingStrategy"; + + [ConfigurationProperty(PublishingStrategyPropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)] + public PublishingProvider PublishingStrategy + { + get { return ((PublishingProvider)base[PublishingStrategyPropertyName]); } + set { base[PublishingStrategyPropertyName] = value; } + } + + #endregion + } + + public class Repositories : ConfigurationElement + { + [ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)] + public RepositoryElementCollection Repository + { + get { return ((RepositoryElementCollection)(base[""])); } + } + } + + [ConfigurationCollection(typeof(Repository), CollectionType = ConfigurationElementCollectionType.BasicMapAlternate, AddItemName = RepositoryPropertyName)] + public class RepositoryElementCollection : ConfigurationElementCollection + { + internal const string RepositoryPropertyName = "repository"; + + public override ConfigurationElementCollectionType CollectionType + { + get + { + return ConfigurationElementCollectionType.BasicMapAlternate; + } + } + + protected override string ElementName + { + get + { + return RepositoryPropertyName; + } + } + + protected override bool IsElementName(string elementName) + { + return elementName == RepositoryPropertyName; + } + + protected override object GetElementKey(ConfigurationElement element) + { + return ((Repository)element).InterfaceShortTypeName; + } + + protected override ConfigurationElement CreateNewElement() + { + return new Repository(); + } + + #region Indexer + + public Repository this[int index] + { + get { return (Repository)base.BaseGet(index); } + } + + public Repository this[string interfaceShortTypeName] + { + get { return (Repository)base.BaseGet(interfaceShortTypeName); } + } + + #endregion + + #region Add + + public void Add(Repository repository) + { + BaseAdd(repository); + } + + #endregion + + #region Remove + + public void Remove(Repository repository) + { + BaseRemove(repository); + } + + #endregion + + #region GetItem + + public Repository GetItemAt(int index) + { + return (Repository)BaseGet(index); + } + + public Repository GetItemByKey(string interfaceShortTypeName) + { + return (Repository)BaseGet(interfaceShortTypeName); + } + + #endregion + + public bool ContainsKey(string interfaceShortName) + { + bool result = false; + object[] keys = this.BaseGetAllKeys(); + foreach (object key in keys) + { + if ((string)key == interfaceShortName) + { + result = true; + break; + + } + } + return result; + } + } + + public class Repository : ConfigurationElement + { + internal const string InterfaceShortTypeNamePropertyName = "interfaceShortTypeName"; + + [ConfigurationPropertyAttribute(InterfaceShortTypeNamePropertyName, IsRequired = true, IsKey = true, IsDefaultCollection = false)] + public string InterfaceShortTypeName + { + get { return (string) base[InterfaceShortTypeNamePropertyName]; } + set { base[InterfaceShortTypeNamePropertyName] = value; } + } + + internal const string RepositoryFullTypeNamePropertyName = "repositoryFullTypeName"; + + [ConfigurationPropertyAttribute(RepositoryFullTypeNamePropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)] + public string RepositoryFullTypeName + { + get { return (string)base[RepositoryFullTypeNamePropertyName]; } + set { base[RepositoryFullTypeNamePropertyName] = value; } + } + + internal const string CacheProviderFullTypeNamePropertyName = "cacheProviderFullTypeName"; + + [ConfigurationPropertyAttribute(CacheProviderFullTypeNamePropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)] + public string CacheProviderFullTypeName + { + get { return (string)base[CacheProviderFullTypeNamePropertyName]; } + set { base[CacheProviderFullTypeNamePropertyName] = value; } + } + } + + public class PublishingProvider : ConfigurationElement + { + internal const string TypePropertyName = "type"; + + [ConfigurationPropertyAttribute(TypePropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)] + public string Type + { + get { return (string)base[TypePropertyName]; } + set { base[TypePropertyName] = value; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 60bf0ee45a..8e7387ba2e 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration /// Gets the version comment (like beta or RC). /// /// The version comment. - public static string CurrentComment { get { return "RC"; } } + public static string CurrentComment { get { return ""; } } // 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 diff --git a/src/Umbraco.Core/Persistence/DatabaseFactory.cs b/src/Umbraco.Core/Persistence/DatabaseFactory.cs new file mode 100644 index 0000000000..6ce5bd6ac4 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseFactory.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading; +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence +{ + /// + /// Provides access to the PetaPoco database as Singleton, so the database is created once in app lifecycle. + /// This is necessary for transactions to work properly + /// + public sealed class DatabaseFactory + { + #region Singleton + + private static readonly Database _database = new Database(GlobalSettings.DbDsn); + private static readonly Lazy lazy = new Lazy(() => new DatabaseFactory()); + + public static DatabaseFactory Current { get { return lazy.Value; } } + + private DatabaseFactory() + { + } + + #endregion + + /// + /// Returns an instance of the PetaPoco database + /// + public Database Database + { + get { return _database; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs index 886b9007da..0eeacc7bfb 100644 --- a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs @@ -78,7 +78,9 @@ namespace Umbraco.Core.Persistence.Factories } else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Date && property.Value != null && string.IsNullOrWhiteSpace(property.Value.ToString()) == false) { - dto.Date = DateTime.Parse(property.Value.ToString()); + DateTime date; + if(DateTime.TryParse(property.Value.ToString(), out date)) + dto.Date = date; } else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Ntext && property.Value != null) { diff --git a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs new file mode 100644 index 0000000000..6f43b8e304 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs @@ -0,0 +1,86 @@ +using System; +using System.Reflection; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Persistence.Mappers +{ + internal class ModelDtoMapper : IMapper + { + public void GetTableInfo(Type t, TableInfo ti) + { } + + public bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn) + { + if (pi.DeclaringType == typeof(Content) || pi.DeclaringType == typeof(IContent)) + { + switch (pi.Name) + { + case "Trashed": + columnName = "[umbracoNode].[trashed]"; + return true; + case "ParentId": + columnName = "[umbracoNode].[parentID]"; + return true; + case "UserId": + columnName = "[umbracoNode].[nodeUser]"; + return true; + case "Level": + columnName = "[umbracoNode].[level]"; + return true; + case "Path": + columnName = "[umbracoNode].[path]"; + return true; + case "SortOrder": + columnName = "[umbracoNode].[sortOrder]"; + return true; + case "NodeId": + columnName = "[umbracoNode].[id]"; + return true; + case "Published": + columnName = "[cmsDocument].[published]"; + return true; + case "Key": + columnName = "[umbracoNode].[uniqueID]"; + return true; + case "CreateDate": + columnName = "[umbracoNode].[createDate]"; + return true; + case "Name": + columnName = "[umbracoNode].[text]"; + return true; + } + } + + if (pi.DeclaringType == typeof(ContentType) || pi.DeclaringType == typeof(IContentType)) + { + switch (pi.Name) + { + case "Alias": + columnName = "[cmsContentType].[alias]"; + return true; + case "Icon": + columnName = "[cmsContentType].[icon]"; + return true; + case "Thumbnail": + columnName = "[cmsContentType].[thumbnail]"; + return true; + case "Description": + columnName = "[cmsContentType].[description]"; + return true; + } + } + + return true; + } + + public Func GetFromDbConverter(PropertyInfo pi, Type sourceType) + { + return null; + } + + public Func GetToDbConverter(Type sourceType) + { + return null; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index 74721961dd..2eb5896374 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -43,7 +43,7 @@ namespace Umbraco.Core.Persistence.Migrations /// True if migrations were applied, otherwise False public bool Execute(Database database, DatabaseProviders databaseProvider, bool isUpgrade = true) { - LogHelper.Info("Initializing database migration"); + LogHelper.Info("Initializing database migrations"); var foundMigrations = MigrationResolver.Current.Migrations; @@ -61,10 +61,12 @@ namespace Umbraco.Core.Persistence.Migrations if (isUpgrade) { migration.GetUpExpressions(context); + LogHelper.Info(string.Format("Added UPGRADE migration '{0}' to context", migration.GetType().Name)); } else { migration.GetDownExpressions(context); + LogHelper.Info(string.Format("Added DOWNGRADE migration '{0}' to context", migration.GetType().Name)); } } diff --git a/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs new file mode 100644 index 0000000000..4a97dc571c --- /dev/null +++ b/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs @@ -0,0 +1,572 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using Umbraco.Core.Persistence.Mappers; + +namespace Umbraco.Core.Persistence.Querying +{ + internal class ExpressionHelper + { + private string selectExpression = string.Empty; + private string whereExpression; + private string groupBy = string.Empty; + private string havingExpression; + private string orderBy = string.Empty; + + IList updateFields = new List(); + IList insertFields = new List(); + + private string sep = string.Empty; + private bool useFieldName = false; + private Database.PocoData pd; + + public ExpressionHelper() + { + Database.Mapper = new ModelDtoMapper(); + pd = new Database.PocoData(typeof(T)); + } + + protected internal virtual string Visit(Expression exp) + { + + if (exp == null) return string.Empty; + switch (exp.NodeType) + { + case ExpressionType.Lambda: + return VisitLambda(exp as LambdaExpression); + case ExpressionType.MemberAccess: + return VisitMemberAccess(exp as MemberExpression); + case ExpressionType.Constant: + return VisitConstant(exp as ConstantExpression); + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.Divide: + case ExpressionType.Modulo: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.Equal: + case ExpressionType.NotEqual: + case ExpressionType.Coalesce: + case ExpressionType.ArrayIndex: + case ExpressionType.RightShift: + case ExpressionType.LeftShift: + case ExpressionType.ExclusiveOr: + return "(" + VisitBinary(exp as BinaryExpression) + ")"; + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.ArrayLength: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + return VisitUnary(exp as UnaryExpression); + case ExpressionType.Parameter: + return VisitParameter(exp as ParameterExpression); + case ExpressionType.Call: + return VisitMethodCall(exp as MethodCallExpression); + case ExpressionType.New: + return VisitNew(exp as NewExpression); + case ExpressionType.NewArrayInit: + case ExpressionType.NewArrayBounds: + return VisitNewArray(exp as NewArrayExpression); + default: + return exp.ToString(); + } + } + + protected virtual string VisitLambda(LambdaExpression lambda) + { + if (lambda.Body.NodeType == ExpressionType.MemberAccess && sep == " ") + { + MemberExpression m = lambda.Body as MemberExpression; + + if (m.Expression != null) + { + string r = VisitMemberAccess(m); + return string.Format("{0}={1}", r, GetQuotedTrueValue()); + } + + } + return Visit(lambda.Body); + } + + protected virtual string VisitBinary(BinaryExpression b) + { + string left, right; + var operand = BindOperant(b.NodeType); //sep= " " ?? + if (operand == "AND" || operand == "OR") + { + MemberExpression m = b.Left as MemberExpression; + if (m != null && m.Expression != null) + { + string r = VisitMemberAccess(m); + left = string.Format("{0}={1}", r, GetQuotedTrueValue()); + } + else + { + left = Visit(b.Left); + } + m = b.Right as MemberExpression; + if (m != null && m.Expression != null) + { + string r = VisitMemberAccess(m); + right = string.Format("{0}={1}", r, GetQuotedTrueValue()); + } + else + { + right = Visit(b.Right); + } + } + else + { + left = Visit(b.Left); + right = Visit(b.Right); + } + + if (operand == "=" && right == "null") operand = "is"; + else if (operand == "<>" && right == "null") operand = "is not"; + else if (operand == "=" || operand == "<>") + { + if (IsTrueExpression(right)) right = GetQuotedTrueValue(); + else if (IsFalseExpression(right)) right = GetQuotedFalseValue(); + + if (IsTrueExpression(left)) left = GetQuotedTrueValue(); + else if (IsFalseExpression(left)) left = GetQuotedFalseValue(); + + } + + switch (operand) + { + case "MOD": + case "COALESCE": + return string.Format("{0}({1},{2})", operand, left, right); + default: + return left + sep + operand + sep + right; + } + } + + protected virtual string VisitMemberAccess(MemberExpression m) + { + if (m.Expression != null && + m.Expression.NodeType == ExpressionType.Parameter + && m.Expression.Type == typeof(T)) + { + string field = GetFieldName(pd, m.Member.Name); + return field; + } + + if (m.Expression != null && m.Expression.NodeType != ExpressionType.Constant) + { + Database.Mapper = new ModelDtoMapper(); + var def = new Database.PocoData(m.Expression.Type); + string field = GetFieldName(def, m.Member.Name); + return field; + } + + + var member = Expression.Convert(m, typeof(object)); + var lambda = Expression.Lambda>(member); + var getter = lambda.Compile(); + object o = getter(); + return GetQuotedValue(o, o != null ? o.GetType() : null); + + } + + protected virtual string VisitNew(NewExpression nex) + { + // TODO : check ! + var member = Expression.Convert(nex, typeof(object)); + var lambda = Expression.Lambda>(member); + try + { + var getter = lambda.Compile(); + object o = getter(); + return GetQuotedValue(o, o.GetType()); + } + catch (System.InvalidOperationException) + { // FieldName ? + List exprs = VisitExpressionList(nex.Arguments); + var r = new StringBuilder(); + foreach (Object e in exprs) + { + r.AppendFormat("{0}{1}", + r.Length > 0 ? "," : "", + e); + } + return r.ToString(); + } + + } + + protected virtual string VisitParameter(ParameterExpression p) + { + return p.Name; + } + + protected virtual string VisitConstant(ConstantExpression c) + { + if (c.Value == null) + return "null"; + else if (c.Value.GetType() == typeof(bool)) + { + object o = GetQuotedValue(c.Value, c.Value.GetType()); + return string.Format("({0}={1})", GetQuotedTrueValue(), o); + } + else + return GetQuotedValue(c.Value, c.Value.GetType()); + } + + protected virtual string VisitUnary(UnaryExpression u) + { + switch (u.NodeType) + { + case ExpressionType.Not: + string o = Visit(u.Operand); + if (IsFieldName(o)) o = o + "=" + GetQuotedValue(true, typeof(bool)); + return "NOT (" + o + ")"; + default: + return Visit(u.Operand); + } + + } + + protected virtual string VisitMethodCall(MethodCallExpression m) + { + List args = this.VisitExpressionList(m.Arguments); + + Object r; + if (m.Object != null) + r = Visit(m.Object); + else + { + r = args[0]; + args.RemoveAt(0); + } + + switch (m.Method.Name) + { + case "ToUpper": + return string.Format("upper({0})", r); + case "ToLower": + return string.Format("lower({0})", r); + case "StartsWith": + return string.Format("upper({0}) starting with {1} ", r, args[0].ToString().ToUpper()); + case "EndsWith": + return string.Format("upper({0}) like '%{1}'", r, RemoveQuote(args[0].ToString()).ToUpper()); + case "Contains": + return string.Format("upper({0}) like '%{1}%'", r, RemoveQuote(args[0].ToString()).ToUpper()); + case "Substring": + var startIndex = Int32.Parse(args[0].ToString()) + 1; + if (args.Count == 2) + { + var length = Int32.Parse(args[1].ToString()); + return string.Format("substring({0} from {1} for {2})", + r, + startIndex, + length); + } + else + return string.Format("substring({0} from {1})", + r, + startIndex); + case "Round": + case "Floor": + case "Ceiling": + case "Coalesce": + case "Abs": + case "Sum": + return string.Format("{0}({1}{2})", + m.Method.Name, + r, + args.Count == 1 ? string.Format(",{0}", args[0]) : ""); + case "Concat": + var s = new StringBuilder(); + foreach (Object e in args) + { + s.AppendFormat(" || {0}", e); + } + return string.Format("{0}{1}", r, s.ToString()); + + case "In": + + var member = Expression.Convert(m.Arguments[1], typeof(object)); + var lambda = Expression.Lambda>(member); + var getter = lambda.Compile(); + + var inArgs = getter() as object[]; + + var sIn = new StringBuilder(); + foreach (Object e in inArgs) + { + if (e.GetType().ToString() != "System.Collections.Generic.List`1[System.Object]") + { + sIn.AppendFormat("{0}{1}", + sIn.Length > 0 ? "," : "", + GetQuotedValue(e, e.GetType())); + } + else + { + var listArgs = e as IList; + foreach (Object el in listArgs) + { + sIn.AppendFormat("{0}{1}", + sIn.Length > 0 ? "," : "", + GetQuotedValue(el, el.GetType())); + } + } + } + + return string.Format("{0} {1} ({2})", r, m.Method.Name, sIn.ToString()); + case "Desc": + return string.Format("{0} DESC", r); + case "Alias": + case "As": + return string.Format("{0} As {1}", r, + GetQuotedColumnName(RemoveQuoteFromAlias(RemoveQuote(args[0].ToString())))); + case "ToString": + return r.ToString(); + default: + var s2 = new StringBuilder(); + foreach (Object e in args) + { + s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType())); + } + return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString()); + } + } + + protected virtual List VisitExpressionList(ReadOnlyCollection original) + { + var list = new List(); + for (int i = 0, n = original.Count; i < n; i++) + { + if (original[i].NodeType == ExpressionType.NewArrayInit || + original[i].NodeType == ExpressionType.NewArrayBounds) + { + + list.AddRange(VisitNewArrayFromExpressionList(original[i] as NewArrayExpression)); + } + else + list.Add(Visit(original[i])); + + } + return list; + } + + protected virtual string VisitNewArray(NewArrayExpression na) + { + + List exprs = VisitExpressionList(na.Expressions); + var r = new StringBuilder(); + foreach (Object e in exprs) + { + r.Append(r.Length > 0 ? "," + e : e); + } + + return r.ToString(); + } + + protected virtual List VisitNewArrayFromExpressionList(NewArrayExpression na) + { + + List exprs = VisitExpressionList(na.Expressions); + return exprs; + } + + + protected virtual string BindOperant(ExpressionType e) + { + + switch (e) + { + case ExpressionType.Equal: + return "="; + case ExpressionType.NotEqual: + return "<>"; + case ExpressionType.GreaterThan: + return ">"; + case ExpressionType.GreaterThanOrEqual: + return ">="; + case ExpressionType.LessThan: + return "<"; + case ExpressionType.LessThanOrEqual: + return "<="; + case ExpressionType.AndAlso: + return "AND"; + case ExpressionType.OrElse: + return "OR"; + case ExpressionType.Add: + return "+"; + case ExpressionType.Subtract: + return "-"; + case ExpressionType.Multiply: + return "*"; + case ExpressionType.Divide: + return "/"; + case ExpressionType.Modulo: + return "MOD"; + case ExpressionType.Coalesce: + return "COALESCE"; + default: + return e.ToString(); + } + } + + public virtual string GetQuotedTableName(string tableName) + { + return string.Format("\"{0}\"", tableName); + } + + public virtual string GetQuotedColumnName(string columnName) + { + return string.Format("\"{0}\"", columnName); + } + + public virtual string GetQuotedName(string name) + { + return string.Format("\"{0}\"", name); + } + + private string GetQuotedTrueValue() + { + return GetQuotedValue(true, typeof(bool)); + } + + private string GetQuotedFalseValue() + { + return GetQuotedValue(false, typeof(bool)); + } + + public virtual string GetQuotedValue(object value, Type fieldType) + { + if (value == null) return "NULL"; + + if (!fieldType.UnderlyingSystemType.IsValueType && fieldType != typeof(string)) + { + //if (TypeSerializer.CanCreateFromString(fieldType)) + //{ + // return "'" + EscapeParam(TypeSerializer.SerializeToString(value)) + "'"; + //} + + throw new NotSupportedException( + string.Format("Property of type: {0} is not supported", fieldType.FullName)); + } + + if (fieldType == typeof(int)) + return ((int)value).ToString(CultureInfo.InvariantCulture); + + if (fieldType == typeof(float)) + return ((float)value).ToString(CultureInfo.InvariantCulture); + + if (fieldType == typeof(double)) + return ((double)value).ToString(CultureInfo.InvariantCulture); + + if (fieldType == typeof(decimal)) + return ((decimal)value).ToString(CultureInfo.InvariantCulture); + + return ShouldQuoteValue(fieldType) + ? "'" + EscapeParam(value) + "'" + : value.ToString(); + } + + public virtual string EscapeParam(object paramValue) + { + return paramValue.ToString().Replace("'", "''"); + } + + public virtual bool ShouldQuoteValue(Type fieldType) + { + return true; + } + + protected virtual string GetFieldName(Database.PocoData pocoData, string name) + { + var column = pocoData.Columns.FirstOrDefault(x => x.Value.PropertyInfo.Name == name); + return column.Value.ColumnName; + } + + protected virtual string GetFieldName(string name) + { + + if (useFieldName) + { + //FieldDefinition fd = modelDef.FieldDefinitions.FirstOrDefault(x => x.Name == name); + //string fn = fd != default(FieldDefinition) ? fd.FieldName : name; + //return OrmLiteConfig.DialectProvider.GetQuotedColumnName(fn); + return "[" + name + "]"; + } + else + { + return name; + } + } + + protected string RemoveQuote(string exp) + { + + if (exp.StartsWith("'") && exp.EndsWith("'")) + { + exp = exp.Remove(0, 1); + exp = exp.Remove(exp.Length - 1, 1); + } + return exp; + } + + protected string RemoveQuoteFromAlias(string exp) + { + + if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'")) + && + (exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'"))) + { + exp = exp.Remove(0, 1); + exp = exp.Remove(exp.Length - 1, 1); + } + return exp; + } + + private string GetTrueExpression() + { + object o = GetQuotedTrueValue(); + return string.Format("({0}={1})", o, o); + } + + private string GetFalseExpression() + { + + return string.Format("({0}={1})", + GetQuotedTrueValue(), + GetQuotedFalseValue()); + } + + private bool IsTrueExpression(string exp) + { + return (exp == GetTrueExpression()); + } + + private bool IsFalseExpression(string exp) + { + return (exp == GetFalseExpression()); + } + + protected bool IsFieldName(string quotedExp) + { + return true; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index b284a4550a..660589dbbe 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -42,6 +42,7 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false) .Where(GetBaseWhereClause(), new { Id = id }) + .Where(x => x.Newest) .OrderByDescending(x => x.VersionDate); var dto = Database.Fetch(sql).FirstOrDefault(); @@ -49,21 +50,8 @@ namespace Umbraco.Core.Persistence.Repositories if (dto == null) return null; - //Get the ContentType that this Content is based on - var contentType = _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId); + var content = CreateContentFromDto(dto, dto.ContentVersionDto.VersionId); - var factory = new ContentFactory(contentType, NodeObjectTypeId, id); - var content = factory.BuildEntity(dto); - - //Check if template id is set on DocumentDto, and get ITemplate if it is. - if (dto.TemplateId.HasValue && dto.TemplateId.Value > 0) - { - content.Template = _templateRepository.Get(dto.TemplateId.Value); - } - - content.Properties = GetPropertyCollection(id, dto.ContentVersionDto.VersionId, contentType); - - ((ICanBeDirty)content).ResetDirtyProperties(); return content; } @@ -167,15 +155,9 @@ namespace Umbraco.Core.Persistence.Repositories if (dto == null) return null; + + var content = CreateContentFromDto(dto, versionId); - var contentType = _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId); - - var factory = new ContentFactory(contentType, NodeObjectTypeId, dto.NodeId); - var content = factory.BuildEntity(dto); - - content.Properties = GetPropertyCollection(dto.NodeId, versionId, contentType); - - ((ICanBeDirty)content).ResetDirtyProperties(); return content; } @@ -430,6 +412,31 @@ namespace Umbraco.Core.Persistence.Repositories #endregion + /// + /// Private method to create a content object from a DocumentDto, which is used by Get and GetByVersion. + /// + /// + /// + /// + private IContent CreateContentFromDto(DocumentDto dto, Guid versionId) + { + var contentType = _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId); + + var factory = new ContentFactory(contentType, NodeObjectTypeId, dto.NodeId); + var content = factory.BuildEntity(dto); + + //Check if template id is set on DocumentDto, and get ITemplate if it is. + if (dto.TemplateId.HasValue && dto.TemplateId.Value > 0) + { + content.Template = _templateRepository.Get(dto.TemplateId.Value); + } + + content.Properties = GetPropertyCollection(dto.NodeId, versionId, contentType); + + ((ICanBeDirty)content).ResetDirtyProperties(); + return content; + } + private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType) { var sql = new Sql(); diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index ed438d6967..4b8beb1de4 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1054,6 +1054,22 @@ namespace Umbraco.Core.Services return SaveAndPublishDo(content, omitCacheRefresh, userId, raiseEvents); } + /// + /// Gets a collection of descendants by the first Parent. + /// + /// item to retrieve Descendants from + /// An Enumerable list of objects + internal IEnumerable GetPublishedDescendants(IContent content) + { + using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork())) + { + var query = Query.Builder.Where(x => x.Id != content.Id && x.Path.StartsWith(content.Path) && x.Published == true && x.Trashed == false); + var contents = repository.GetByQuery(query); + + return contents; + } + } + #endregion #region Private Methods @@ -1243,6 +1259,9 @@ namespace Umbraco.Core.Services return false; } + //Has this content item previously been published? If so, we don't need to refresh the children + var previouslyPublished = HasPublishedVersion(content.Id); + //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) { @@ -1279,11 +1298,35 @@ namespace Umbraco.Core.Services if (published) { var xml = content.ToXml(); - var poco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) }; - var exists = uow.Database.FirstOrDefault("WHERE nodeId = @Id", new { Id = content.Id }) != null; - int result = exists - ? uow.Database.Update(poco) - : Convert.ToInt32(uow.Database.Insert(poco)); + //Content Xml + var contentPoco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) }; + var contentExists = uow.Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0; + int contentResult = contentExists + ? uow.Database.Update(contentPoco) + : Convert.ToInt32(uow.Database.Insert(contentPoco)); + //Preview Xml + var previewPoco = new PreviewXmlDto + { + NodeId = content.Id, + Timestamp = DateTime.Now, + VersionId = content.Version, + Xml = xml.ToString(SaveOptions.None) + }; + var previewExists = + uow.Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", + new {Id = content.Id, Version = content.Version}) != 0; + int previewResult = previewExists + ? uow.Database.Update( + "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version", + new + { + Xml = previewPoco.Xml, + Timestamp = previewPoco.Timestamp, + Id = previewPoco.NodeId, + Version = previewPoco.VersionId + }) + : Convert.ToInt32(uow.Database.Insert(previewPoco)); + } } @@ -1294,13 +1337,12 @@ namespace Umbraco.Core.Services 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 (omitCacheRefresh == false && HasChildren(content.Id)) + //We need to check if children and their publish state to ensure that we 'republish' content that was previously published + if (omitCacheRefresh == false && previouslyPublished == false && HasChildren(content.Id)) { - var children = GetDescendants(content); - var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id)); + var descendants = GetPublishedDescendants(content); - _publishingStrategy.PublishingFinalized(shouldBeRepublished, false); + _publishingStrategy.PublishingFinalized(descendants, false); } Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId, content.Id); @@ -1334,6 +1376,30 @@ namespace Umbraco.Core.Services repository.AddOrUpdate(content); uow.Commit(); + + //Preview Xml + var xml = content.ToXml(); + var previewPoco = new PreviewXmlDto + { + NodeId = content.Id, + Timestamp = DateTime.Now, + VersionId = content.Version, + Xml = xml.ToString(SaveOptions.None) + }; + var previewExists = + uow.Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", + new { Id = content.Id, Version = content.Version }) != 0; + int previewResult = previewExists + ? uow.Database.Update( + "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version", + new + { + Xml = previewPoco.Xml, + Timestamp = previewPoco.Timestamp, + Id = previewPoco.NodeId, + Version = previewPoco.VersionId + }) + : Convert.ToInt32(uow.Database.Insert(previewPoco)); } if(raiseEvents) diff --git a/src/Umbraco.Tests/Configurations/RepositorySettingsTests.cs b/src/Umbraco.Tests/Configurations/RepositorySettingsTests.cs new file mode 100644 index 0000000000..c25bd853b5 --- /dev/null +++ b/src/Umbraco.Tests/Configurations/RepositorySettingsTests.cs @@ -0,0 +1,32 @@ +using System.Configuration; +using NUnit.Framework; +using Umbraco.Core.Configuration.InfrastructureSettings; + +namespace Umbraco.Tests.Configurations +{ + [TestFixture] + public class RepositorySettingsTests + { + [Test] + public void Can_Get_Repository_From_Config() + { + Infrastructure infrastructure = Infrastructure.Instance; + Repositories repositories = infrastructure.Repositories; + Repository repository = repositories.Repository["IContentRepository"]; + + Assert.That(repository, Is.Not.Null); + Assert.AreEqual(repository.InterfaceShortTypeName, "IContentRepository"); + Assert.AreEqual(repository.RepositoryFullTypeName, "Umbraco.Core.Persistence.Repositories.ContentRepository, Umbraco.Core"); + Assert.AreEqual(repository.CacheProviderFullTypeName, "Umbraco.Core.Persistence.Caching.RuntimeCacheProvider, Umbraco.Core"); + } + + [Test] + public void Can_Get_PublishingStrategy_From_Config() + { + Infrastructure infrastructure = Infrastructure.Instance; + PublishingProvider strategy = infrastructure.PublishingStrategy; + + Assert.That(strategy.Type, Is.EqualTo("Umbraco.Web.Publishing.PublishingStrategy, Umbraco.Web")); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/DatabaseFactoryTests.cs b/src/Umbraco.Tests/Persistence/DatabaseFactoryTests.cs new file mode 100644 index 0000000000..4a3337f1b2 --- /dev/null +++ b/src/Umbraco.Tests/Persistence/DatabaseFactoryTests.cs @@ -0,0 +1,18 @@ +using NUnit.Framework; +using Umbraco.Core.Persistence; + +namespace Umbraco.Tests.Persistence +{ + [TestFixture] + public class DatabaseFactoryTests + { + [Test] + public void Can_Verify_Single_Database_Instance() + { + var db1 = DatabaseFactory.Current.Database; + var db2 = DatabaseFactory.Current.Database; + + Assert.AreSame(db1, db2); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs b/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs index 46bc9099ac..282d93bd1c 100644 --- a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs @@ -1,6 +1,7 @@ using System; using NUnit.Framework; using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; using Umbraco.Tests.TestHelpers; @@ -78,5 +79,35 @@ namespace Umbraco.Tests.Persistence.Querying Assert.That(strResult, Is.EqualTo(expectedResult)); Console.WriteLine(strResult); } + + [Test] + public void Can_Build_PublishedDescendants_Query_For_IContent() + { + // Arrange + var path = "-1,1046,1076,1089"; + var id = 1046; + var nodeObjectTypeId = new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"); + + var sql = new Sql(); + sql.Select("*") + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == nodeObjectTypeId); + + var query = Query.Builder.Where(x => x.Path.StartsWith(path) && x.Id != id && x.Published == true && x.Trashed == false); + + // Act + var translator = new SqlTranslator(sql, query); + var result = translator.Translate(); + var strResult = result.SQL; + + // Assert + Console.WriteLine(strResult); + } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index bc59b85d18..6a942594ae 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; @@ -8,6 +9,8 @@ using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; +using umbraco.editorControls.tinyMCE3; +using umbraco.interfaces; namespace Umbraco.Tests.Persistence.Repositories { @@ -17,6 +20,20 @@ namespace Umbraco.Tests.Persistence.Repositories [SetUp] public override void Initialize() { + //NOTE The DataTypesResolver is only necessary because we are using the Save method in the ContentService + //this ensures its reset + PluginManager.Current = new PluginManager(); + + //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver + PluginManager.Current.AssembliesToScan = new[] + { + typeof(IDataType).Assembly, + typeof(tinyMCE3dataType).Assembly + }; + + DataTypesResolver.Current = new DataTypesResolver( + () => PluginManager.Current.ResolveDataTypes()); + base.Initialize(); CreateTestData(); @@ -25,6 +42,9 @@ namespace Umbraco.Tests.Persistence.Repositories [TearDown] public override void TearDown() { + //reset the app context + DataTypesResolver.Reset(); + base.TearDown(); } diff --git a/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs index 8730dc3aad..73249bc3a1 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Persistence.Querying; @@ -8,6 +9,8 @@ using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; +using umbraco.editorControls.tinyMCE3; +using umbraco.interfaces; namespace Umbraco.Tests.Persistence.Repositories { @@ -17,6 +20,20 @@ namespace Umbraco.Tests.Persistence.Repositories [SetUp] public override void Initialize() { + //NOTE The DataTypesResolver is only necessary because we are using the Save method in the ContentService + //this ensures its reset + PluginManager.Current = new PluginManager(); + + //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver + PluginManager.Current.AssembliesToScan = new[] + { + typeof(IDataType).Assembly, + typeof(tinyMCE3dataType).Assembly + }; + + DataTypesResolver.Current = new DataTypesResolver( + () => PluginManager.Current.ResolveDataTypes()); + base.Initialize(); CreateTestData(); @@ -237,6 +254,9 @@ namespace Umbraco.Tests.Persistence.Repositories [TearDown] public override void TearDown() { + //reset the app context + DataTypesResolver.Reset(); + base.TearDown(); } diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 23321bf363..ae44930f53 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -69,7 +69,11 @@ namespace Umbraco.Tests.Routing } //test all template name styles to match the ActionName - [TestCase("home-page")] + [TestCase("home-\\234^^*32page")] + [TestCase("home-page")] + [TestCase("home-\\234^^*32page")] + [TestCase("home-page")] + [TestCase("home-page")] [TestCase("Home-Page")] [TestCase("HomePage")] [TestCase("homePage")] @@ -90,7 +94,9 @@ namespace Umbraco.Tests.Routing handler.GetHandlerForRoute(routingContext.UmbracoContext.HttpContext.Request.RequestContext, docRequest); Assert.AreEqual("CustomDocument", routeData.Values["controller"].ToString()); - Assert.AreEqual("HomePage", routeData.Values["action"].ToString()); + Assert.AreEqual( + global::umbraco.cms.helpers.Casing.SafeAlias(templateName), + routeData.Values["action"].ToString()); } diff --git a/src/Umbraco.Web.UI/config/trees.config b/src/Umbraco.Web.UI/config/trees.config index 34558bbdaf..6834440077 100644 --- a/src/Umbraco.Web.UI/config/trees.config +++ b/src/Umbraco.Web.UI/config/trees.config @@ -20,7 +20,6 @@ - diff --git a/src/Umbraco.Web.UI/install/default.aspx b/src/Umbraco.Web.UI/install/default.aspx index 2d0acda187..9e5f9056da 100644 --- a/src/Umbraco.Web.UI/install/default.aspx +++ b/src/Umbraco.Web.UI/install/default.aspx @@ -11,7 +11,7 @@ - + " /> @@ -40,7 +40,11 @@
- + + + + +
diff --git a/src/Umbraco.Web.UI/install/steps/theend.ascx b/src/Umbraco.Web.UI/install/steps/theend.ascx index 61c6fd86cb..f9c6f30107 100644 --- a/src/Umbraco.Web.UI/install/steps/theend.ascx +++ b/src/Umbraco.Web.UI/install/steps/theend.ascx @@ -12,6 +12,9 @@ jQuery(document).ready(function () { function (data) { jQuery("#ajax-developervids").html(data); }); + + umbraco.presentation.webservices.CheckForUpgrade.InstallStatus(true, navigator.userAgent, ""); + }); diff --git a/src/Umbraco.Web.UI/install/steps/welcome.ascx b/src/Umbraco.Web.UI/install/steps/welcome.ascx index 18f24a143d..a0ce00d7f1 100644 --- a/src/Umbraco.Web.UI/install/steps/welcome.ascx +++ b/src/Umbraco.Web.UI/install/steps/welcome.ascx @@ -47,4 +47,9 @@ Let's get started! - \ No newline at end of file + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml index c41f2631a0..b5c96e1b58 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml @@ -1,4 +1,4 @@ - + umbraco @@ -15,8 +15,6 @@ 無効 ごみ箱を空にする ドキュメントタイプの書出 - .NETの書き出し - .NETの書き出し ドキュメントタイプの読込 パッケージの読み込み ライブ編集 @@ -25,6 +23,7 @@ メール通知 一般公開 公開 + 公開を止める 最新の情報に更新 サイトのリフレッシュ アクセス権 @@ -38,6 +37,7 @@ ドメインの割り当て + 適当でないホスト名 ドメイン ドメイン '%0%' が新たに割り当てられました ドメイン '%0%' は削除されました @@ -71,6 +71,7 @@ 保存及び公開 保存して承認に送る プレビュー + テンプレートが指定されていないのでプレビューは無効になっています スタイルの選択 スタイルの表示 表の挿入 @@ -90,6 +91,7 @@ このページは公開されていません 公開日時 メディアタイプ + メディアの項目へのリンク メンバーグループ 役割 メンバータイプ @@ -324,6 +326,7 @@ ようこそ... はい + フォルダー 背景色 @@ -482,6 +485,7 @@ Runwayをインストールして作られた新しいウェブサイトがど 現在のノードは、ドキュメントタイプの設定により選択されたノードの子になることはできません。 ノードは、自分のサブページには移動できません 子ドキュメントで権限がないので、その操作はできません。 + コピーしたものを元と関係づける %0% への通知を編集 @@ -586,8 +590,13 @@ Runwayをインストールして作られた新しいウェブサイトがど + + + 非公開の子ページも含めます 公開を進めています - 少々お待ちください... %1% ページ中 %0% ページが公開されました... @@ -648,6 +657,9 @@ Runwayをインストールして作られた新しいウェブサイトがど タブ タブの名前 タブ + マスターコンテンツタイプが有効 + このコンテンツタイプの使用 + マスターコンテンツタイプについては、マスターコンテンツタイプからのタブは表示されず、マスターコンテンツタイプでのみ編集することができます。 ソートが完了しました。 @@ -682,6 +694,7 @@ Runwayをインストールして作られた新しいウェブサイトがど テンプレートを保存しました ユーザーの保存時にエラーが発生しました (ログを確認してください) ユーザーを保存しました + ユーザータイプを保存しました ファイルは未保存です ファイルを保存できません。アクセス権を確認してください。 ファイルを保存しました @@ -700,6 +713,11 @@ Runwayをインストールして作られた新しいウェブサイトがど XSLTを保存できません。アクセス権を確認してください。 XSLTを保存しました XSLTにエラーはありません + コンテンツは公開されていません + 部分ビュー保存しました + 部分ビューをエラーなしで保存しました! + 部分ビューは保存されていません + ファイルを保存するときにエラーが発生しました。 CSSシンタックスを使用 例: h1, .redHeader, .blueTex @@ -727,6 +745,7 @@ Runwayをインストールして作られた新しいウェブサイトがど フィールドの選択 改行コードの変換 改行コードをhtmlタグ &lt;br&gt; に変換する + カスタムフィールド 日付のみ表示 日付の形式 HTMLエンコード @@ -740,6 +759,7 @@ Runwayをインストールして作られた新しいウェブサイトがど 再帰的 段落タグの消去 段落タグ &lt;P&gt; を消去します + 標準フィールド 大文字変換 URLエンコード 文字列をURLで使用可能な文字列に変換する @@ -833,6 +853,8 @@ Runwayをインストールして作られた新しいウェブサイトがど 管理者 フィールドのカテゴリー パスワードの変更 + 新パスワード + 新パスワードの確認 Umbracoの管理画面にアクセスするためのパスワードを変更するには、以下のフォームに新しいパスワード入力して「パスワードの変更」ボタンをクリックしてください。 コンテントチャンネル ログオン後ライブ編集にリダイレクト @@ -851,6 +873,8 @@ Runwayをインストールして作られた新しいウェブサイトがど 新しいパスワードの確認 新しいパスワードの入力 パスワードは空白にできません! + 現在のパスワード + 現在のパスワードが正しくない 新しいパスワードと確認のパスワードが一致しません。再度入力してください! 確認のパスワードは新しいパスワードと一致しません! 子ノードのアクセス権を置き換える @@ -864,4 +888,4 @@ Runwayをインストールして作られた新しいウェブサイトがど ユーザーの種類 投稿者 - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml index 189c352d63..f46a3f340c 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml @@ -501,13 +501,13 @@

您好!这是一封自动发送的邮件,告诉您任务'%1%'已在'%2%'被用户'%3%'执行

-

Update summary:

+

更新概况:

%6%
@@ -515,14 +515,14 @@ -

Have a nice day!

- Cheers from the umbraco robot +

祝您愉快!

+ 该信息由系统自动发送

]]> 在 %2%,[%0%] 关于 %1% 的通告已执行。 diff --git a/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx b/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx index 973bdc1028..d70e8c59c4 100644 --- a/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx +++ b/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx @@ -1,11 +1,13 @@ -<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Dashboard.ascx.cs" Inherits="Our.Umbraco.uGoLive.Web.Umbraco.Plugins.uGoLive.Dashboard" %> +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Dashboard.ascx.cs" Inherits="Our.Umbraco.uGoLive.Web.Umbraco.Plugins.uGoLive.Dashboard" %> <%@ Import Namespace="umbraco.IO" %> <%@ Import Namespace="Our.Umbraco.uGoLive.Web" %> - - - - - +<%@ Register Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" TagPrefix="cdf" %> + + + + + + -
+
diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index ed93abcc08..84702aff98 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -274,7 +274,7 @@ namespace Umbraco.Web.Mvc //the template Alias should always be already saved with a safe name. //if there are hyphens in the name and there is a hijacked route, then the Action will need to be attributed // with the action name attribute. - var templateName = publishedContentRequest.Template.Split('.')[0]; + var templateName = global::umbraco.cms.helpers.Casing.SafeAlias(publishedContentRequest.Template.Alias.Split('.')[0]); def.ActionName = templateName; } diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs index 42c2237380..c2cb1294a9 100644 --- a/src/Umbraco.Web/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs @@ -30,4 +30,6 @@ using System.Security; [assembly: InternalsVisibleTo("Umbraco.Tests")] [assembly: InternalsVisibleTo("umbraco.MacroEngines")] [assembly: InternalsVisibleTo("Umbraco.Web.UI")] -[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")] \ No newline at end of file +[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")] +[assembly: InternalsVisibleTo("umbraco.webservices")] + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 496050690d..b7a3014326 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1915,7 +1915,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + @@ -2042,7 +2044,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + diff --git a/src/Umbraco.Web/Web References/org.umbraco.update/Reference.cs b/src/Umbraco.Web/Web References/org.umbraco.update/Reference.cs index 87a309f714..c6a3c0dc17 100644 --- a/src/Umbraco.Web/Web References/org.umbraco.update/Reference.cs +++ b/src/Umbraco.Web/Web References/org.umbraco.update/Reference.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.544 +// Runtime Version:4.0.30319.18033 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -9,27 +9,28 @@ //------------------------------------------------------------------------------ // -// This source code was auto-generated by Microsoft.VSDesigner, Version 4.0.30319.544. +// This source code was auto-generated by Microsoft.VSDesigner, Version 4.0.30319.18033. // #pragma warning disable 1591 -namespace umbraco.presentation.org.umbraco.update -{ +namespace umbraco.presentation.org.umbraco.update { using System; using System.Web.Services; using System.Diagnostics; using System.Web.Services.Protocols; - using System.ComponentModel; using System.Xml.Serialization; + using System.ComponentModel; /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.17929")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="CheckForUpgradeSoap", Namespace="http://update.umbraco.org/")] public partial class CheckForUpgrade : System.Web.Services.Protocols.SoapHttpClientProtocol { + private System.Threading.SendOrPostCallback InstallOperationCompleted; + private System.Threading.SendOrPostCallback CheckUpgradeOperationCompleted; private bool useDefaultCredentialsSetExplicitly; @@ -70,34 +71,85 @@ namespace umbraco.presentation.org.umbraco.update } } + /// + public event InstallCompletedEventHandler InstallCompleted; + /// public event CheckUpgradeCompletedEventHandler CheckUpgradeCompleted; + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://update.umbraco.org/Install", RequestNamespace="http://update.umbraco.org/", ResponseNamespace="http://update.umbraco.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public void Install(System.Guid installId, bool isUpgrade, bool installCompleted, System.DateTime timestamp, int versionMajor, int versionMinor, int versionPatch, string versionComment, string error, string userAgent, string dbProvider) { + this.Invoke("Install", new object[] { + installId, + isUpgrade, + installCompleted, + timestamp, + versionMajor, + versionMinor, + versionPatch, + versionComment, + error, + userAgent, + dbProvider}); + } + + /// + public void InstallAsync(System.Guid installId, bool isUpgrade, bool installCompleted, System.DateTime timestamp, int versionMajor, int versionMinor, int versionPatch, string versionComment, string error, string userAgent, string dbProvider) { + this.InstallAsync(installId, isUpgrade, installCompleted, timestamp, versionMajor, versionMinor, versionPatch, versionComment, error, userAgent, dbProvider, null); + } + + /// + public void InstallAsync(System.Guid installId, bool isUpgrade, bool installCompleted, System.DateTime timestamp, int versionMajor, int versionMinor, int versionPatch, string versionComment, string error, string userAgent, string dbProvider, object userState) { + if ((this.InstallOperationCompleted == null)) { + this.InstallOperationCompleted = new System.Threading.SendOrPostCallback(this.OnInstallOperationCompleted); + } + this.InvokeAsync("Install", new object[] { + installId, + isUpgrade, + installCompleted, + timestamp, + versionMajor, + versionMinor, + versionPatch, + versionComment, + error, + userAgent, + dbProvider}, this.InstallOperationCompleted, userState); + } + + private void OnInstallOperationCompleted(object arg) { + if ((this.InstallCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.InstallCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://update.umbraco.org/CheckUpgrade", RequestNamespace="http://update.umbraco.org/", ResponseNamespace="http://update.umbraco.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] - public UpgradeResult CheckUpgrade(int VersionMajor, int VersionMinor, int VersionPatch, string versionComment) { + public UpgradeResult CheckUpgrade(int versionMajor, int versionMinor, int versionPatch, string versionComment) { object[] results = this.Invoke("CheckUpgrade", new object[] { - VersionMajor, - VersionMinor, - VersionPatch, + versionMajor, + versionMinor, + versionPatch, versionComment}); return ((UpgradeResult)(results[0])); } /// - public void CheckUpgradeAsync(int VersionMajor, int VersionMinor, int VersionPatch, string versionComment) { - this.CheckUpgradeAsync(VersionMajor, VersionMinor, VersionPatch, versionComment, null); + public void CheckUpgradeAsync(int versionMajor, int versionMinor, int versionPatch, string versionComment) { + this.CheckUpgradeAsync(versionMajor, versionMinor, versionPatch, versionComment, null); } /// - public void CheckUpgradeAsync(int VersionMajor, int VersionMinor, int VersionPatch, string versionComment, object userState) { + public void CheckUpgradeAsync(int versionMajor, int versionMinor, int versionPatch, string versionComment, object userState) { if ((this.CheckUpgradeOperationCompleted == null)) { this.CheckUpgradeOperationCompleted = new System.Threading.SendOrPostCallback(this.OnCheckUpgradeOperationCompleted); } this.InvokeAsync("CheckUpgrade", new object[] { - VersionMajor, - VersionMinor, - VersionPatch, + versionMajor, + versionMinor, + versionPatch, versionComment}, this.CheckUpgradeOperationCompleted, userState); } @@ -128,28 +180,18 @@ namespace umbraco.presentation.org.umbraco.update } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.450")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18033")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://update.umbraco.org/")] public partial class UpgradeResult { - private UpgradeType upgradeTypeField; - private string commentField; - private string upgradeUrlField; + private UpgradeType upgradeTypeField; - /// - public UpgradeType UpgradeType { - get { - return this.upgradeTypeField; - } - set { - this.upgradeTypeField = value; - } - } + private string upgradeUrlField; /// public string Comment { @@ -161,6 +203,16 @@ namespace umbraco.presentation.org.umbraco.update } } + /// + public UpgradeType UpgradeType { + get { + return this.upgradeTypeField; + } + set { + this.upgradeTypeField = value; + } + } + /// public string UpgradeUrl { get { @@ -173,7 +225,7 @@ namespace umbraco.presentation.org.umbraco.update } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.450")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18033")] [System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://update.umbraco.org/")] public enum UpgradeType { @@ -201,11 +253,15 @@ namespace umbraco.presentation.org.umbraco.update } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.17929")] + public delegate void InstallCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.17929")] public delegate void CheckUpgradeCompletedEventHandler(object sender, CheckUpgradeCompletedEventArgs e); /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.17929")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class CheckUpgradeCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { diff --git a/src/Umbraco.Web/Web References/org.umbraco.update/Reference.map b/src/Umbraco.Web/Web References/org.umbraco.update/Reference.map index a0cba8d88b..dc2f3d1d64 100644 --- a/src/Umbraco.Web/Web References/org.umbraco.update/Reference.map +++ b/src/Umbraco.Web/Web References/org.umbraco.update/Reference.map @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/Web References/org.umbraco.update/checkforupgrade.wsdl b/src/Umbraco.Web/Web References/org.umbraco.update/checkforupgrade.wsdl index 9661c33653..5c700af0bb 100644 --- a/src/Umbraco.Web/Web References/org.umbraco.update/checkforupgrade.wsdl +++ b/src/Umbraco.Web/Web References/org.umbraco.update/checkforupgrade.wsdl @@ -1,13 +1,34 @@ - + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -21,8 +42,8 @@ - + @@ -38,7 +59,20 @@ + + + + + + + + + + + + + @@ -46,6 +80,10 @@ + + + + @@ -53,6 +91,15 @@ + + + + + + + + + @@ -65,6 +112,15 @@ + + + + + + + + + diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index 70d1a2d3e6..8d8dfa0ef2 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -580,40 +580,42 @@ namespace umbraco ThreadPool.QueueUserWorkItem(delegate { UpdateDocumentCache(documentId); }); } - - [Obsolete("Method obsolete in version 4.1 and later, please use ClearDocumentCache", true)] /// /// Clears the document cache async. /// /// The document id. + [Obsolete("Method obsolete in version 4.1 and later, please use ClearDocumentCache", true)] public virtual void ClearDocumentCacheAsync(int documentId) { ThreadPool.QueueUserWorkItem(delegate { ClearDocumentCache(documentId); }); } + public virtual void ClearDocumentCache(int documentId) + { + // Get the document + var d = new Document(documentId); + ClearDocumentCache(d); + } /// /// Clears the document cache and removes the document from the xml db cache. /// This means the node gets unpublished from the website. /// - /// The document id. - public virtual void ClearDocumentCache(int documentId) + /// The document + internal void ClearDocumentCache(Document doc) { - // Get the document - var d = new Document(documentId); - var e = new DocumentCacheEventArgs(); - FireBeforeClearDocumentCache(d, e); + FireBeforeClearDocumentCache(doc, e); if (!e.Cancel) { XmlNode x; // remove from xml db cache - d.XmlRemoveFromDB(); + doc.XmlRemoveFromDB(); // Check if node present, before cloning - x = XmlContentInternal.GetElementById(d.Id.ToString()); + x = XmlContentInternal.GetElementById(doc.Id.ToString()); if (x == null) return; @@ -626,7 +628,7 @@ namespace umbraco XmlDocument xmlContentCopy = CloneXmlDoc(XmlContentInternal); // Find the document in the xml cache - x = xmlContentCopy.GetElementById(d.Id.ToString()); + x = xmlContentCopy.GetElementById(doc.Id.ToString()); if (x != null) { // The document already exists in cache, so repopulate it @@ -639,17 +641,17 @@ namespace umbraco if (x != null) { // Run Handler - Action.RunActionHandlers(d, ActionUnPublish.Instance); + Action.RunActionHandlers(doc, ActionUnPublish.Instance); } // update sitemapprovider if (SiteMap.Provider is UmbracoSiteMapProvider) { var prov = (UmbracoSiteMapProvider)SiteMap.Provider; - prov.RemoveNode(d.Id); + prov.RemoveNode(doc.Id); } - FireAfterClearDocumentCache(d, e); + FireAfterClearDocumentCache(doc, e); } } diff --git a/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs index 1bd81f7df3..479cb474c6 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs @@ -9,7 +9,7 @@ using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Collections.Specialized; -using umbraco.IO; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; using System.Collections.Generic; @@ -36,7 +36,7 @@ namespace umbraco.presentation.install private void loadContent(InstallerStep currentStep) { PlaceHolderStep.Controls.Clear(); - PlaceHolderStep.Controls.Add(new System.Web.UI.UserControl().LoadControl(IOHelper.ResolveUrl(currentStep.UserControl))); + PlaceHolderStep.Controls.Add(LoadControl(IOHelper.ResolveUrl(currentStep.UserControl))); step.Value = currentStep.Alias; currentStepClass = currentStep.Alias; } diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs index f5a695e8cf..54bdc0c721 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs @@ -1,8 +1,9 @@ using System; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; -using umbraco.IO; + namespace umbraco.presentation.install.steps.Definitions { @@ -26,10 +27,7 @@ namespace umbraco.presentation.install.steps.Definitions public override bool MoveToNextStepAutomaticly { - get - { - return true; - } + get { return true; } } //here we determine if the installer should skip this step... @@ -49,7 +47,7 @@ namespace umbraco.presentation.install.steps.Definitions var configuredVersion = new Version(Umbraco.Core.Configuration.GlobalSettings.ConfigurationStatus); var targetVersion = UmbracoVersion.Current; - + return targetVersion < configuredVersion; } } diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs index ef3827225f..f0f6887ed3 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; namespace umbraco.presentation.install.steps.Definitions @@ -20,7 +21,7 @@ namespace umbraco.presentation.install.steps.Definitions public override string UserControl { - get { return IO.SystemDirectories.Install + "/steps/validatepermissions.ascx"; } + get { return SystemDirectories.Install + "/steps/validatepermissions.ascx"; } } public override bool HideFromNavigation { diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/theend.ascx b/src/Umbraco.Web/umbraco.presentation/install/steps/theend.ascx index 61c6fd86cb..f9c6f30107 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/theend.ascx +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/theend.ascx @@ -12,6 +12,9 @@ jQuery(document).ready(function () { function (data) { jQuery("#ajax-developervids").html(data); }); + + umbraco.presentation.webservices.CheckForUpgrade.InstallStatus(true, navigator.userAgent, ""); + }); diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/welcome.ascx b/src/Umbraco.Web/umbraco.presentation/install/steps/welcome.ascx index 18f24a143d..a0ce00d7f1 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/welcome.ascx +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/welcome.ascx @@ -47,4 +47,9 @@ Let's get started! -
\ No newline at end of file +
+ \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index 1c64fbc96a..2d45157eb3 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -188,9 +188,7 @@ namespace umbraco /// /// The Id of the Document to be unpublished public static void UnPublishSingleNode(int DocumentId) - { - - //PPH Added dispatcher support + { if (UmbracoSettings.UseDistributedCalls) dispatcher.Remove( new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), @@ -199,6 +197,21 @@ namespace umbraco content.Instance.ClearDocumentCache(DocumentId); } + /// + /// Unpublish a node, by removing it from the runtime xml index. Note, prior to this the Document should be + /// marked unpublished by setting the publish property on the document object to false + /// + /// The Document to be unpublished + internal static void UnPublishSingleNode(Document document) + { + if (UmbracoSettings.UseDistributedCalls) + dispatcher.Remove( + new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), + document.Id); + else + content.Instance.ClearDocumentCache(document); + } + /// /// Publishes a Document by adding it to the runtime xml index. Note, prior to this the Document should be /// marked published by calling Publish(User u) on the document object. diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index d42f8f2a60..4c63531890 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -311,7 +311,7 @@ namespace umbraco Model.CacheIdentifier = GetCacheIdentifier(Model, pageElements, pageId); - if (Model.CacheDuration > 0) + if (!UmbracoContext.Current.InPreviewMode && Model.CacheDuration > 0) { if (cacheMacroAsString(Model)) { diff --git a/src/Umbraco.Web/umbraco.presentation/publishingService.cs b/src/Umbraco.Web/umbraco.presentation/publishingService.cs index 1f7c6c7c2c..f1d30e7005 100644 --- a/src/Umbraco.Web/umbraco.presentation/publishingService.cs +++ b/src/Umbraco.Web/umbraco.presentation/publishingService.cs @@ -38,7 +38,7 @@ namespace umbraco.presentation d.ReleaseDate = DateTime.MinValue; //new DateTime(1, 1, 1); // Causes release date to be null d.Publish(d.User); - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); } catch(Exception ee) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs index 18b0e22a72..fd353d09cc 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs @@ -132,7 +132,7 @@ namespace umbraco.presentation.LiveEditing.Modules.CreateModule DocumentType typeToCreate = new DocumentType(Convert.ToInt32(m_AllowedDocTypesDropdown.SelectedValue)); Document newDoc = Document.MakeNew(m_NameTextBox.Text, typeToCreate, new global::umbraco.BusinessLogic.User(userid), (int)UmbracoContext.Current.PageId); newDoc.Publish(new global::umbraco.BusinessLogic.User(userid)); - library.UpdateDocumentCache(newDoc.Id); + library.UpdateDocumentCache(newDoc); Page.Response.Redirect(library.NiceUrl(newDoc.Id), false); break; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs index aa5e64c9ea..d2f8d32404 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs @@ -35,7 +35,7 @@ namespace umbraco.cms.presentation.Trees public BaseContentTree(string application) : base(application) { } - private User m_user; + private User _user; /// /// Returns the current User. This ensures that we don't instantiate a new User object @@ -45,7 +45,7 @@ namespace umbraco.cms.presentation.Trees { get { - return (m_user == null ? (m_user = UmbracoEnsuredPage.CurrentUser) : m_user); + return (_user == null ? (_user = UmbracoEnsuredPage.CurrentUser) : _user); } } @@ -113,7 +113,7 @@ function openContent(id) { node.OpenIcon = dd.ContentTypeIcon; } - if (dd.HasPublishedVersion() == false) + if (!dd.Published) node.Style.DimNode(); if (dd.HasPendingChanges()) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs index 94c88425ac..d58e002785 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs @@ -39,7 +39,7 @@ namespace umbraco.presentation.actions confirm.Visible = false; d.Publish(getUser()); - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); deleted.Text = ui.Text("editContentPublishedHeader") + " ('" + d.Text + "') " + ui.Text("editContentPublishedText") + "

" + ui.Text("view") + " " + d.Text + ""; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs index afe99ac4d2..c1089d77be 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs @@ -84,7 +84,7 @@ namespace umbraco.presentation.channels if (publish) { doc.Publish(new User(username)); - library.UpdateDocumentCache(doc.Id); + library.UpdateDocumentCache(doc); } return true; } @@ -403,7 +403,7 @@ namespace umbraco.presentation.channels if (publish) { doc.Publish(new User(username)); - library.UpdateDocumentCache(doc.Id); + library.UpdateDocumentCache(doc); } return doc.Id.ToString(); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs index 549ce2657c..f6a54a1d0e 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -545,10 +545,14 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); var gpw = (GenericProperties.GenericPropertyWrapper)sender; var alias = gpw.PropertyType.Alias; - gpw.GenricPropertyControl.PropertyType.delete(); //We have to ensure that the property type is removed from the underlying IContentType object - cType.ContentTypeItem.RemovePropertyType(alias); - cType.Save(); + if (cType.ContentTypeItem != null) + { + cType.ContentTypeItem.RemovePropertyType(alias); + cType.Save(); + } + + gpw.GenricPropertyControl.PropertyType.delete(); cType = ContentType.GetContentType(cType.Id); this.bindDataGenericProperties(true); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs index d8b99c6bba..bfe92ef3c6 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs @@ -93,7 +93,7 @@ namespace umbraco.dialogs { if (doc.Published) { - library.UpdateDocumentCache(doc.Id); + library.UpdateDocumentCache(doc); } } @@ -117,7 +117,7 @@ namespace umbraco.dialogs { if (d.PublishWithResult(base.getUser())) { - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); feedbackMsg.type = umbraco.uicontrols.Feedback.feedbacktype.success; feedbackMsg.Text = ui.Text("publish", "nodePublish", d.Text, base.getUser()) + "

" + ui.Text("closeThisWindow") + ""; } @@ -142,7 +142,7 @@ namespace umbraco.dialogs { // Needed for supporting distributed calls if (UmbracoSettings.UseDistributedCalls) - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); else documents.Add(d); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 08fa0f6ed8..d6ef34ee67 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -4,6 +4,7 @@ using System.Web.UI.WebControls; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Caching; +using Umbraco.Core.Services; using umbraco.BusinessLogic.Actions; using umbraco.IO; using umbraco.uicontrols.DatePicker; @@ -316,6 +317,8 @@ namespace umbraco.cms.presentation { if (_document.Level == 1 || _document.PathPublished) { + var previouslyPublished = _document.HasPublishedVersion(); + Trace.Warn("before d.publish"); if (_document.PublishWithResult(base.getUser())) @@ -330,15 +333,19 @@ namespace umbraco.cms.presentation _documentHasPublishedVersion = _document.HasPublishedVersion(); - var descendants = ApplicationContext.Current.Services.ContentService.GetDescendants(_document.Id); - var publishableDescendants = descendants.Where(descendant => descendant.HasPublishedVersion()).ToList(); - if(publishableDescendants.Any()) + if (previouslyPublished == false) { - foreach (var descendant in publishableDescendants) + var descendants = ((ContentService) ApplicationContext.Current.Services.ContentService) + .GetPublishedDescendants(_document.Content).ToList(); + + if (descendants.Any()) { - library.UpdateDocumentCache(descendant.Id); + foreach (var descendant in descendants) + { + library.UpdateDocumentCache(descendant.Id); + } + library.RefreshContent(); } - library.RefreshContent(); } } else diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs index 7deebd1613..8600c84c2d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Data; using System.Configuration; +using System.Globalization; using System.Linq; using System.Web; using System.Web.Security; @@ -53,13 +55,30 @@ namespace umbraco.presentation.preview // clone xml XmlContent = (XmlDocument)content.Instance.XmlContent.Clone(); - // inject current document xml - int parentId = documentObject.Level == 1 ? -1 : documentObject.Parent.Id; - XmlContent = content.AppendDocumentXml(documentObject.Id, documentObject.Level, parentId, documentObject.ToPreviewXml(XmlContent), XmlContent); + var previewNodes = new List(); + + var parentId = documentObject.Level == 1 ? -1 : documentObject.Parent.Id; + + while (parentId > 0 && XmlContent.GetElementById(parentId.ToString(CultureInfo.InvariantCulture)) == null) + { + var document = new Document(parentId); + previewNodes.Insert(0, document); + parentId = document.ParentId; + } + + previewNodes.Add(documentObject); + + foreach (var document in previewNodes) + { + //Inject preview xml + parentId = document.Level == 1 ? -1 : document.Parent.Id; + var previewXml = document.ToPreviewXml(XmlContent); + content.AppendDocumentXml(document.Id, document.Level, parentId, previewXml, XmlContent); + } if (includeSubs) { - foreach (CMSPreviewNode prevNode in documentObject.GetNodesForPreview(true)) + foreach (var prevNode in documentObject.GetNodesForPreview(true)) { XmlContent = content.AppendDocumentXml(prevNode.NodeId, prevNode.Level, prevNode.ParentId, XmlContent.ReadNode(XmlReader.Create(new StringReader(prevNode.Xml))), XmlContent); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs index 7c7b17c3a2..de897b6209 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs @@ -250,7 +250,7 @@ namespace umbraco } } - library.UpdateDocumentCache(document.Id); + library.UpdateDocumentCache(document); return document; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs index e2ee304244..018e6d9ff5 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs @@ -102,11 +102,11 @@ namespace umbraco.cms.presentation.user ///

/// Returns the current user permissions for the node specified /// - /// + /// /// - public List GetExistingNodePermission(int nodeID) + public List GetExistingNodePermission(int nodeId) { - string path = GetNodePath(nodeID); + var path = GetNodePath(nodeId); if (path != "") { //get the user and their permissions @@ -119,13 +119,13 @@ namespace umbraco.cms.presentation.user /// /// gets path attribute for node id passed /// - /// + /// /// - private string GetNodePath(int iNodeID) + private static string GetNodePath(int iNodeId) { - if (Document.IsDocument(iNodeID)) + if (Document.IsDocument(iNodeId)) { - Document doc = new Document(iNodeID); + var doc = new Document(iNodeId); return doc.Path; } @@ -135,14 +135,13 @@ namespace umbraco.cms.presentation.user /// /// Finds all child node IDs /// - /// - /// + /// /// - private List FindChildNodes(int nodeID) + private static IEnumerable FindChildNodes(int nodeId) { - Document[] docs = Document.GetChildrenForTree(nodeID); - List nodeIds = new List(); - foreach (Document doc in docs) + var docs = Document.GetChildrenForTree(nodeId); + var nodeIds = new List(); + foreach (var doc in docs) { nodeIds.Add(doc.Id); if (doc.HasChildren) @@ -153,16 +152,16 @@ namespace umbraco.cms.presentation.user return nodeIds; } - private void InsertPermissions(int[] nodeIDs, IAction permission) + private void InsertPermissions(IEnumerable nodeIDs, IAction permission) { foreach (int i in nodeIDs) InsertPermission(i, permission); } - private void InsertPermission(int nodeID, IAction permission) + private void InsertPermission(int nodeId, IAction permission) { //create a new CMSNode object but don't initialize (this prevents a db query) - CMSNode node = new CMSNode(nodeID, false); + var node = new CMSNode(nodeId, false); Permission.MakeNew(m_user, node, permission.Letter); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs index f06a7e43c7..f6aa1f337b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Web; using System.Web.Services; using System.Web.Script.Services; +using Umbraco.Core; using Umbraco.Core.Configuration; @@ -32,7 +33,54 @@ namespace umbraco.presentation.webservices return new UpgradeResult(result.UpgradeType.ToString(), result.Comment, result.UpgradeUrl); } + [WebMethod] + [ScriptMethod] + public void InstallStatus(bool isCompleted, string userAgent, string errorMsg) + { + bool isUpgrade = false; + // if it's an upgrade, you'll need to be logged in before we allow this call + if (!String.IsNullOrEmpty(Umbraco.Core.Configuration.GlobalSettings.ConfigurationStatus)) + { + isUpgrade = true; + legacyAjaxCalls.Authorize(); + } + + // Check for current install Id + Guid installId = Guid.NewGuid(); + BusinessLogic.StateHelper.Cookies.Cookie installCookie = + new BusinessLogic.StateHelper.Cookies.Cookie("umb_installId", 1); + if (!String.IsNullOrEmpty(installCookie.GetValue())) + { + if (Guid.TryParse(installCookie.GetValue(), out installId)) + { + // check that it's a valid Guid + if (installId == Guid.Empty) + installId = Guid.NewGuid(); + + } + } + installCookie.SetValue(installId.ToString()); + + string dbProvider = String.Empty; + if (!String.IsNullOrEmpty(Umbraco.Core.Configuration.GlobalSettings.ConfigurationStatus)) + dbProvider = ApplicationContext.Current.DatabaseContext.DatabaseProvider.ToString(); + + org.umbraco.update.CheckForUpgrade check = new global::umbraco.presentation.org.umbraco.update.CheckForUpgrade(); + check.Install(installId, + isUpgrade, + isCompleted, + DateTime.Now, + UmbracoVersion.Current.Major, + UmbracoVersion.Current.Minor, + UmbracoVersion.Current.Build, + UmbracoVersion.CurrentComment, + errorMsg, + userAgent, + dbProvider); + } } + + public class UpgradeResult { public string UpgradeType { get; set; } diff --git a/src/WebPi/parameters.xml b/src/WebPi/parameters.xml index 8efe1e9506..ae1b4135e9 100644 --- a/src/WebPi/parameters.xml +++ b/src/WebPi/parameters.xml @@ -105,7 +105,9 @@ - + + diff --git a/src/umbraco.cms/businesslogic/media/Media.cs b/src/umbraco.cms/businesslogic/media/Media.cs index 076fc37a3e..5a698c9a4f 100644 --- a/src/umbraco.cms/businesslogic/media/Media.cs +++ b/src/umbraco.cms/businesslogic/media/Media.cs @@ -232,9 +232,6 @@ namespace umbraco.cms.businesslogic.media foreach (var property in GenericProperties) { - if (property.Value == null) - continue; - MediaItem.SetValue(property.PropertyType.Alias, property.Value); } diff --git a/src/umbraco.cms/businesslogic/member/Member.cs b/src/umbraco.cms/businesslogic/member/Member.cs index b30a664991..94bebaf74a 100644 --- a/src/umbraco.cms/businesslogic/member/Member.cs +++ b/src/umbraco.cms/businesslogic/member/Member.cs @@ -598,7 +598,10 @@ namespace umbraco.cms.businesslogic.member } else if (dbType.Equals("Date")) { - poco.Date = DateTime.Parse(property.Value.ToString()); + DateTime date; + + if(DateTime.TryParse(property.Value.ToString(), out date)) + poco.Date = date; } else if (dbType.Equals("Nvarchar")) { diff --git a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs index d72a1d3eb3..97563546b9 100644 --- a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs +++ b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs @@ -378,10 +378,6 @@ namespace umbraco.cms.businesslogic.propertytype // flush cache FlushCache(); - // clean all properties on inherited document types (if this propertytype is removed from a master) - CleanPropertiesOnDeletion(_contenttypeid); - // DocumentType.GetAllAsList().FindAll(dt => dt.MasterContentType == _contenttypeid).ForEach(dt => cleanPropertiesOnDeletion(dt.Id)); - // Delete all properties of propertytype CleanPropertiesOnDeletion(_contenttypeid); @@ -413,15 +409,15 @@ namespace umbraco.cms.businesslogic.propertytype DocumentType.GetAllAsList().FindAll(dt => dt.MasterContentTypes.Contains(contentTypeId)).ForEach( dt => CleanPropertiesOnDeletion(dt.Id)); - // then remove from the current doc type - Content[] objs = Content.getContentOfContentType(new ContentType(contentTypeId)); - foreach (Content c in objs.ToList()) + //Initially Content.getContentOfContentType() was called, but because this doesn't include members we resort to sql lookups and deletes + var tmp = new List(); + IRecordsReader dr = SqlHelper.ExecuteReader("SELECT nodeId FROM cmsContent INNER JOIN umbracoNode ON cmsContent.nodeId = umbracoNode.id WHERE ContentType = " + contentTypeId + " ORDER BY umbracoNode.text "); + while (dr.Read()) tmp.Add(dr.GetInt("nodeId")); + dr.Close(); + + foreach (var contentId in tmp) { - Property prop = c.getProperty(this); - if (prop != null) - { - prop.delete(); - } + SqlHelper.ExecuteNonQuery("DELETE FROM cmsPropertyData WHERE PropertyTypeId =" + this.Id + " AND contentNodeId = " + contentId); } // invalidate content type cache diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 3855363702..c80264b0df 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -892,9 +892,6 @@ namespace umbraco.cms.businesslogic.web foreach (var property in GenericProperties) { - if (property.Value == null) - continue; - Content.SetValue(property.PropertyType.Alias, property.Value); } @@ -905,8 +902,6 @@ namespace umbraco.cms.businesslogic.web ApplicationContext.Current.Services.ContentService.Save(Content, userId); base.Save(); - // update preview xml - SaveXmlPreview(new XmlDocument()); FireAfterSave(e); } @@ -935,8 +930,6 @@ namespace umbraco.cms.businesslogic.web var result = ((ContentService)ApplicationContext.Current.Services.ContentService).SaveAndPublish(Content, true, u.Id); base.Save(); - // update preview xml - SaveXmlPreview(new XmlDocument()); FireAfterSave(e); diff --git a/src/umbraco.controls/UmbracoClientDependencyLoader.cs b/src/umbraco.controls/UmbracoClientDependencyLoader.cs index 54536fb9e2..06c369a5a1 100644 --- a/src/umbraco.controls/UmbracoClientDependencyLoader.cs +++ b/src/umbraco.controls/UmbracoClientDependencyLoader.cs @@ -5,7 +5,7 @@ using System.Text; using System.Web.UI; using ClientDependency.Core.Controls; using ClientDependency.Core.FileRegistration.Providers; -using umbraco.IO; +using Umbraco.Core.IO; namespace umbraco.uicontrols { @@ -22,7 +22,7 @@ namespace umbraco.uicontrols public UmbracoClientDependencyLoader() : base() { - this.AddPath("UmbracoClient", IOHelper.ResolveUrl( SystemDirectories.Umbraco_client )); + this.AddPath("UmbracoClient", IOHelper.ResolveUrl( SystemDirectories.UmbracoClient )); this.AddPath("UmbracoRoot", IOHelper.ResolveUrl( SystemDirectories.Umbraco )); this.ProviderName = LoaderControlProvider.DefaultName; @@ -32,7 +32,7 @@ namespace umbraco.uicontrols { if (ClientDependencyLoader.Instance == null) { - UmbracoClientDependencyLoader loader = new UmbracoClientDependencyLoader(); + var loader = new UmbracoClientDependencyLoader(); parent.Controls.Add(loader); isNew = true; return loader; diff --git a/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs b/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs index ad34baec5e..307af3cf60 100644 --- a/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs +++ b/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs @@ -259,45 +259,5 @@ namespace umbraco.DataLayer.Utility.Installer #endregion } - /// - /// A triple (Field, Table, Version) meaning: - /// if a SELECT statement of Field FROM Table succeeds, - /// the database version is at least Version. - /// - /// - /// This also supports checking for a value in a table. - /// - public struct VersionSpecs - { - /// The SQL statament to execute in order to test for the specified version - public readonly string Sql; - - /// An integer identifying the expected row count from the Sql statement - public readonly int ExpectedRows; - - /// The minimum version number of a database that contains the specified field. - public readonly DatabaseVersion Version; - - /// - /// Initializes a new instance of the struct. - /// - /// The sql statement to execute. - /// The version. - public VersionSpecs(string sql, DatabaseVersion version) - : this(sql, -1, version) - { } - - /// - /// Initializes a new instance of the struct. - /// - /// The sql statement to execute. - /// The expected row count. - /// The version. - public VersionSpecs(string sql, int expectedRows, DatabaseVersion version) - { - Sql = sql; - ExpectedRows = expectedRows; - Version = version; - } - } + } diff --git a/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs b/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs new file mode 100644 index 0000000000..c1237e1e97 --- /dev/null +++ b/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs @@ -0,0 +1,44 @@ +namespace umbraco.DataLayer.Utility.Installer +{ + /// + /// A triple (Field, Table, Version) meaning: + /// if a SELECT statement of Field FROM Table succeeds, + /// the database version is at least Version. + /// + /// + /// This also supports checking for a value in a table. + /// + public struct VersionSpecs + { + /// The SQL statament to execute in order to test for the specified version + public readonly string Sql; + + /// An integer identifying the expected row count from the Sql statement + public readonly int ExpectedRows; + + /// The minimum version number of a database that contains the specified field. + public readonly DatabaseVersion Version; + + /// + /// Initializes a new instance of the struct. + /// + /// The sql statement to execute. + /// The version. + public VersionSpecs(string sql, DatabaseVersion version) + : this(sql, -1, version) + { } + + /// + /// Initializes a new instance of the struct. + /// + /// The sql statement to execute. + /// The expected row count. + /// The version. + public VersionSpecs(string sql, int expectedRows, DatabaseVersion version) + { + Sql = sql; + ExpectedRows = expectedRows; + Version = version; + } + } +} \ No newline at end of file diff --git a/src/umbraco.datalayer/umbraco.datalayer.csproj b/src/umbraco.datalayer/umbraco.datalayer.csproj index c16bf518ae..9f91f604bd 100644 --- a/src/umbraco.datalayer/umbraco.datalayer.csproj +++ b/src/umbraco.datalayer/umbraco.datalayer.csproj @@ -124,6 +124,7 @@ + diff --git a/src/umbraco.editorControls/datepicker/DateData.cs b/src/umbraco.editorControls/datepicker/DateData.cs index ca34f5b343..fe1edc7be4 100644 --- a/src/umbraco.editorControls/datepicker/DateData.cs +++ b/src/umbraco.editorControls/datepicker/DateData.cs @@ -11,7 +11,7 @@ namespace umbraco.editorControls.datepicker public override System.Xml.XmlNode ToXMl(System.Xml.XmlDocument d) { - if (Value.ToString() != "") + if (Value != null && Value.ToString() != "") return d.CreateTextNode(((DateTime) Value).ToString("s")); else return d.CreateTextNode(""); diff --git a/src/umbraco.webservices/documents/documentService.cs b/src/umbraco.webservices/documents/documentService.cs index 6292c02d6b..634033cffd 100644 --- a/src/umbraco.webservices/documents/documentService.cs +++ b/src/umbraco.webservices/documents/documentService.cs @@ -246,13 +246,13 @@ namespace umbraco.webservices.documents case documentCarrier.EPublishAction.Publish: if (doc.PublishWithResult(user)) { - umbraco.library.UpdateDocumentCache(doc.Id); + umbraco.library.UpdateDocumentCache(doc); } break; case documentCarrier.EPublishAction.Unpublish: if (doc.PublishWithResult(user)) { - umbraco.library.UnPublishSingleNode(doc.Id); + umbraco.library.UnPublishSingleNode(doc); } break; case documentCarrier.EPublishAction.Ignore: @@ -260,14 +260,14 @@ namespace umbraco.webservices.documents { if (doc.PublishWithResult(user)) { - umbraco.library.UpdateDocumentCache(doc.Id); + umbraco.library.UpdateDocumentCache(doc); } } else { if (doc.PublishWithResult(user)) { - umbraco.library.UpdateDocumentCache(doc.Id); + umbraco.library.UpdateDocumentCache(doc); } } break;