Compare commits

..

66 Commits

Author SHA1 Message Date
Sebastiaan Janssen 92ef071883 Don't do a ToString() in a IsNullOrEmpty.. 2014-05-28 16:37:16 +02:00
Sebastiaan Janssen b42d0bc17e Bump version and fix dashboard 2014-05-28 16:04:11 +02:00
Sebastiaan Janssen 020a416dc5 en_us lang also updated like en 2014-05-28 13:15:20 +02:00
Sebastiaan Janssen d491c133a7 Merge pull request #391 from danlister/patch-1
Updated en.xml to fix some minor spelling mistakes
2014-05-28 13:13:01 +02:00
Sebastiaan Janssen b68dd6b35c U4-5006 Typo: "struture" in the Copy and Move dialogs 2014-05-28 13:12:10 +02:00
Sebastiaan Janssen ba9d023cc0 Additional fix for U4-4950 U7.1.3 multiple media picker 2014-05-28 13:10:17 +02:00
Sebastiaan Janssen eb6fe1e4d3 Fix unit test that was failing after moving from yepnope to LazyLoad.js 2014-05-28 13:06:23 +02:00
Stephan c972ae566e Merge remote-tracking branch 'origin/6.2.1' into 7.1.4
Conflicts:
	src/Umbraco.Core/Dynamics/PropertyResult.cs
	src/Umbraco.Core/Models/IPublishedProperty.cs
	src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs
	src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs
2014-05-28 11:45:45 +02:00
Stephan 320b53ae3c U4-4773 - bring back IPublishedContentProperty Alias and Version (compat) 2014-05-28 11:36:31 +02:00
Sebastiaan Janssen 84f94d6471 U4-4752 No "change password" dialog available in 7.x backoffice 2014-05-28 11:17:33 +02:00
Morten Christensen f758eb6a62 Extra open namespace for hackers 2014-05-28 10:54:52 +02:00
Shannon 7ec4d3f26d Fixes: U4-4950 U7.1.3 multiple media picker 2014-05-28 13:33:03 +10:00
Shannon 2a0d2bdb86 Fixes: U4-4945 Slider type stops working on ajax load in 7.1.3 2014-05-28 13:25:47 +10:00
Shannon 24d3e465ea Merge remote-tracking branch 'origin/6.2.1' into 7.1.4 2014-05-28 12:42:43 +10:00
Shannon d987dfb5a2 Fixes: U4-4141 7.0.2 "Save and send for approval" fails for a writer user on a newly created unsaved content page 2014-05-28 12:40:43 +10:00
Shannon 2ede32fe70 minor change, using non obsolete user id 2014-05-28 12:39:12 +10:00
Shannon fce8c9d3ec Fixes: U4-4141 7.0.2 "Save and send for approval" fails for a writer user on a newly created unsaved content page 2014-05-28 12:38:11 +10:00
Shannon f5194efb6e Fixes: U4-4999 Image cropper - Image file duplicated each time the page (content) is saved/published 2014-05-28 12:29:41 +10:00
Dan Lister 1b360226d6 Updated en.xml to fix some minor spelling mistakes 2014-05-27 12:01:41 +01:00
Sebastiaan Janssen 524d6fb76a U4-4914 Add icon for 'Import Document Type' action menu 2014-05-27 12:12:34 +02:00
Sebastiaan Janssen 7185a6dba5 Merge pull request #383 from imulus/colorpicker-toggle
Allow colors to be toggled on/off in Color Picker - U4-4935
2014-05-27 11:53:55 +02:00
Sebastiaan Janssen 2496a8e77e Merge branch '6.2.1' of https://github.com/umbraco/Umbraco-CMS into 7.1.4
Conflicts:
	src/Umbraco.Web/Models/PublishedContentBase.cs
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
2014-05-27 11:49:31 +02:00
Sebastiaan Janssen 13e8e972eb U4-4956 UserService.SavePassword method always throws a not supported exception 2014-05-27 11:43:50 +02:00
Stephan d631039c0d U4-4928 - issue with missing media content properties 2014-05-26 18:07:20 +02:00
Stephan b1e879bf68 U4-4928 - issue with missing media content properties 2014-05-26 15:59:28 +02:00
Stephan 95b9a46b88 U4-4928 - issue with missing media content properties 2014-05-26 15:02:05 +02:00
Shannon 766ca78725 Merge remote-tracking branch 'origin/6.2.1' into 7.1.4 2014-05-23 10:00:34 +10:00
Shannon 3ca4fb76b2 Merge branch 'darrenferguson-7.1.2' into 7.1.4 2014-05-23 09:52:11 +10:00
Shannon 0a76757cea Merge branch '7.1.2' of https://github.com/darrenferguson/Umbraco-CMS into darrenferguson-7.1.2 2014-05-23 09:51:48 +10:00
Sebastiaan Janssen 8fb446960c U4-4927 Image Cropper Crop URL is wrong in 6.2.0
Reverts part of 067268a96e which was refactored wrong
2014-05-22 19:39:25 +02:00
Stephan 1cf40aca07 U4-4922 - add details to error message 2014-05-22 18:32:20 +02:00
Shannon aadcdc9c15 ensures session id is set on user data on login. 2014-05-22 13:17:15 +10:00
Shannon e04eed41e7 Merge remote-tracking branch 'origin/6.2.1' into 7.1.4
Conflicts:
	src/Umbraco.Core/Models/DeepCloneHelper.cs
	src/Umbraco.Core/Models/PreValue.cs
	src/Umbraco.Core/Models/PreValueCollection.cs
	src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs
2014-05-22 13:01:23 +10:00
Shannon 62887607ff fixes csrf with mediauploader.ashx 2014-05-22 12:44:04 +10:00
Shandem 54a639ffcd Merge pull request #387 from lars-erik/Fix-U4-4264
Fixes U4-4264 (dictionary tree collapses) while we wait for angularification.
2014-05-22 10:47:47 +10:00
Shannon 9f16bee040 Fixes: U4-4952 RTE: macro editing - parameter dialog blank 2014-05-21 15:27:10 +10:00
Stephan 976d1b1ff6 Merge pull request #385 from zpqrtbnk/7.1.4
U4-4618 - public PublishedContentModel & Factory
2014-05-20 15:41:41 +02:00
Lars-Erik Aabech 8a4e39a999 Fixes U4-4264 while we wait for angularification. 2014-05-20 15:05:45 +02:00
Stephan f325794523 U4-4949 - fix issue with domains 2014-05-20 09:32:26 +02:00
Stephan 0b3733f992 Merge remote-tracking branch 'origin/7.1.4' into 7.1.4 2014-05-20 09:28:03 +02:00
Stephan 2926a79c3f U4-4949 - fix issue with domains 2014-05-20 09:24:40 +02:00
Stephan ef7a6f19ba Fix the build 2014-05-20 08:57:27 +02:00
Stephan 95a4bb9ba6 refactor PublishedContentModelFactory 2014-05-19 13:15:47 +02:00
Stephan 32b7871eaf Rename PublishedContentModelFactoryImpl 2014-05-19 13:01:49 +02:00
Sebastiaan Janssen 3ec6d2b82f U4-4861 6.2.0 Nuget package copies wrong files 2014-05-19 10:08:26 +02:00
Stephan cd03e80410 Optimize PublishedContentModelFactoryImpl 2014-05-18 21:57:59 +02:00
Stephan 9ed3561b56 Fix the build 2014-05-18 21:41:34 +02:00
Stephan 28da44f0de Refactor PublishedContentModelFactory 2014-05-18 21:31:53 +02:00
Stephan f8d7aeec80 Merge branch '7.1.4' into HEAD 2014-05-18 21:29:37 +02:00
Stephan dacec47cd9 Fix the build 2014-05-18 21:27:41 +02:00
Stephan 57f06ba447 U4-4618 - public PublishedContentModel & Factory 2014-05-18 19:57:39 +02:00
Stephan 82c1c95e35 Detached PublishedProperty - refactor 2014-05-18 19:06:28 +02:00
Tom Fulton fa6c215849 Merge branch '7.1.4' into colorpicker-toggle 2014-05-17 15:06:15 -06:00
Tom Fulton b656db3af3 Allow colors to be toggled on/off in Color Picker - U4-4935 2014-05-16 21:59:34 -06:00
Sebastiaan Janssen d697c590e7 U4-4930 NuGet update fails to copy new Umbraco binaries 2014-05-16 18:54:49 +02:00
Sebastiaan Janssen a55cd67fd6 U4-4650 Pluralization of document type aliases doesn't always work 2014-05-16 14:33:25 +02:00
Sebastiaan Janssen afa81be102 Fixes U4-4650 Pluralization of document type aliases doesn't always work 2014-05-16 14:23:40 +02:00
Stephan ddd0e8abb5 Bugfix media cache property alias case sensitivity 2014-05-16 10:10:55 +02:00
Stephan e07f573683 Fix the build 2014-05-16 09:57:21 +02:00
Shannon 1f88960b3f Fixes: U4-4926 Pre-values need to be cloned in/out of the cache
Conflicts:
	src/Umbraco.Core/Models/PreValue.cs
	src/Umbraco.Core/Models/PreValueCollection.cs
2014-05-16 12:09:47 +10:00
Shannon d8edf67b82 Fixes: U4-4842 Unable to edit "name" and "alias" to MediaType property 2014-05-16 12:09:08 +10:00
Shannon 365a8e85e9 Fixes: U4-2356 2014-05-15 16:13:54 +10:00
Shannon 5f9dddafd8 fixed an upgrade script when upgrading from old 4.x versions 2014-05-15 14:11:43 +10:00
Shannon 836297df58 Fixes error message on publishing when it fails due to any of these statuses: FailedHasExpired, FailedAwaitingRelease, FailedIsTrashed 2014-05-15 13:35:52 +10:00
Darren Ferguson a2a81222e6 Adding extension methods to PartialViewMacroModel to allow: Model.GetParameterValue<DateTime>("datey")
Model.GetParameterValue<int>("booly", 8) //optional default value if parsing can't happen
Model.GetParameterValue("booly",8) // can be used like this as type is implied by default value argument
2014-05-14 11:33:40 +01:00
Darren Ferguson 5abbca0f5d Adding extension methods to PartialViewMacroModel to allow: Model.GetParameterValue<DateTime>("datey")
Model.GetParameterValue<int>("booly", 8) //optional default value if parsing can't happen
Model.GetParameterValue("booly",8) // can be used like this as type is implied by default value argument
2014-05-14 11:32:39 +01:00
85 changed files with 483 additions and 407 deletions
+1 -1
View File
@@ -1 +1 @@
7.1.3
7.1.4
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.1.3");
private static readonly Version Version = new Version("7.1.4");
/// <summary>
/// Gets the current version of Umbraco.
+1 -2
View File
@@ -329,9 +329,8 @@ namespace Umbraco.Core
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
typeof (DefaultUrlSegmentProvider));
// keep it internal for now
// by default, no factory is activated
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
// new PublishedContentModelFactoryImpl());
}
}
}
@@ -117,13 +117,12 @@ namespace Umbraco.Core.Dynamics
}
catch (Exception ex)
{
var sb = new StringBuilder("An error occurred finding an executing an extension method for type ");
sb.Append(typeof (T));
sb.Append("Types searched for extension methods were ");
foreach(var t in findExtensionMethodsOnTypes)
{
sb.Append(t + ",");
}
var sb = new StringBuilder();
sb.AppendFormat("An error occurred finding and executing extension method \"{0}\" ", binder.Name);
sb.AppendFormat("for type \"{0}\". ", typeof (T));
sb.Append("Types searched for extension methods were ");
sb.Append(string.Join(", ", findExtensionMethodsOnTypes));
sb.Append(".");
LogHelper.Error<DynamicInstanceHelper>(sb.ToString(), ex);
var mresult = new TryInvokeMemberResult(null, TryInvokeMemberSuccessReason.FoundExtensionMethod);
return Attempt<TryInvokeMemberResult>.Fail(mresult, ex);
@@ -171,7 +170,7 @@ namespace Umbraco.Core.Dynamics
}
else
{
throw new MissingMethodException();
throw new MissingMethodException(typeof(T).FullName, name);
}
return result;
}
@@ -3,7 +3,7 @@
/// <summary>
/// Provides the model creation service.
/// </summary>
internal interface IPublishedContentModelFactory
public interface IPublishedContentModelFactory
{
/// <summary>
/// Creates a strongly-typed model representing a published content.
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Models.PublishedContent
// a model, and then that model has to inherit from PublishedContentExtended,
// => implements the internal IPublishedContentExtended.
var model = PublishedContentModelFactory.CreateModel(content);
var model = content.CreateModel();
var extended = model == content // == means the factory did not create a model
? new PublishedContentExtended(content) // so we have to extend
: model; // else we can use what the factory returned
@@ -0,0 +1,20 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides strongly typed published content models services.
/// </summary>
internal static class PublishedContentExtensionsForModels
{
/// <summary>
/// Creates a strongly typed published content model for an internal published content.
/// </summary>
/// <param name="content">The internal published content.</param>
/// <returns>The strongly typed published content model.</returns>
public static IPublishedContent CreateModel(this IPublishedContent content)
{
return PublishedContentModelFactoryResolver.Current.HasValue
? PublishedContentModelFactoryResolver.Current.Factory.CreateModel(content)
: content;
}
}
}
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// </summary>
/// <remarks>Every strongly-typed published content class should inherit from <c>PublishedContentModel</c>
/// (or inherit from a class that inherits from... etc.) so they are picked by the factory.</remarks>
internal abstract class PublishedContentModel : PublishedContentExtended
public abstract class PublishedContentModel : PublishedContentExtended
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModel"/> class with
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// <remarks>By default, the name of the class is assumed to be the content type alias. The
/// <c>PublishedContentModelAttribute</c> can be used to indicate a different alias.</remarks>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal sealed class PublishedContentModelAttribute : Attribute
public sealed class PublishedContentModelAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModelAttribute"/> class with a content type alias.
@@ -1,20 +1,86 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides strongly typed published content models services.
/// </summary>
internal static class PublishedContentModelFactory
{
/// <summary>
/// Creates a strongly typed published content model for an internal published content.
/// </summary>
/// <param name="content">The internal published content.</param>
/// <returns>The strongly typed published content model.</returns>
public static IPublishedContent CreateModel(IPublishedContent content)
{
return PublishedContentModelFactoryResolver.Current.HasValue
? PublishedContentModelFactoryResolver.Current.Factory.CreateModel(content)
: content;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Implements a strongly typed content model factory
/// </summary>
public class PublishedContentModelFactory : IPublishedContentModelFactory
{
//private readonly Dictionary<string, ConstructorInfo> _constructors
// = new Dictionary<string, ConstructorInfo>();
private readonly Dictionary<string, Func<IPublishedContent, IPublishedContent>> _constructors;
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModelFactory"/> class with types.
/// </summary>
/// <param name="types">The model types.</param>
/// <remarks>
/// <para>Types must implement <c>IPublishedContent</c> and have a unique constructor that
/// accepts one IPublishedContent as a parameter.</para>
/// <para>To activate,</para>
/// <code>
/// var types = PluginManager.Current.ResolveTypes{PublishedContentModel}();
/// var factory = new PublishedContentModelFactoryImpl(types);
/// PublishedContentModelFactoryResolver.Current.SetFactory(factory);
/// </code>
/// </remarks>
public PublishedContentModelFactory(IEnumerable<Type> types)
{
var ctorArgTypes = new[] { typeof(IPublishedContent) };
var constructors = new Dictionary<string, Func<IPublishedContent, IPublishedContent>>();
foreach (var type in types)
{
var constructor = type.GetConstructor(ctorArgTypes);
if (constructor == null)
throw new InvalidOperationException(string.Format("Type {0} is missing a public constructor with one argument of type IPublishedContent.", type.FullName));
var attribute = type.GetCustomAttribute<PublishedContentModelAttribute>(false);
var typeName = attribute == null ? type.Name : attribute.ContentTypeAlias;
typeName = typeName.ToLowerInvariant();
if (constructors.ContainsKey(typeName))
throw new InvalidOperationException(string.Format("More that one type want to be a model for content type {0}.", typeName));
// should work everywhere, but slow
//_constructors[typeName] = constructor;
// much faster with a dynamic method but potential MediumTrust issues
// here http://stackoverflow.com/questions/16363838/how-do-you-call-a-constructor-via-an-expression-tree-on-an-existing-object
// fast enough and works in MediumTrust
// read http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/
var exprArg = Expression.Parameter(typeof(IPublishedContent), "content");
var exprNew = Expression.New(constructor, exprArg);
var expr = Expression.Lambda<Func<IPublishedContent, IPublishedContent>>(exprNew, exprArg);
var func = expr.Compile();
constructors[typeName] = func;
}
_constructors = constructors.Count > 0 ? constructors : null;
}
public IPublishedContent CreateModel(IPublishedContent content)
{
// fail fast
if (_constructors == null)
return content;
// be case-insensitive
var contentTypeAlias = content.DocumentTypeAlias.ToLowerInvariant();
//ConstructorInfo constructor;
//return _constructors.TryGetValue(contentTypeAlias, out constructor)
// ? (IPublishedContent) constructor.Invoke(new object[] { content })
// : content;
Func<IPublishedContent, IPublishedContent> constructor;
return _constructors.TryGetValue(contentTypeAlias, out constructor)
? constructor(content)
: content;
}
}
}
@@ -1,67 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Implements a strongly typed content model factory
/// </summary>
internal class PublishedContentModelFactoryImpl : IPublishedContentModelFactory
{
//private readonly Dictionary<string, ConstructorInfo> _constructors
// = new Dictionary<string, ConstructorInfo>();
private readonly Dictionary<string, Func<IPublishedContent, IPublishedContent>> _constructors
= new Dictionary<string, Func<IPublishedContent, IPublishedContent>>();
public PublishedContentModelFactoryImpl()
{
var types = PluginManager.Current.ResolveTypes<PublishedContentModel>();
var ctorArgTypes = new[] { typeof(IPublishedContent) };
foreach (var type in types)
{
var constructor = type.GetConstructor(ctorArgTypes);
if (constructor == null)
throw new InvalidOperationException(string.Format("Type {0} is missing a public constructor with one argument of type IPublishedContent.", type.FullName));
var attribute = type.GetCustomAttribute<PublishedContentModelAttribute>(false);
var typeName = attribute == null ? type.Name : attribute.ContentTypeAlias;
typeName = typeName.ToLowerInvariant();
if (_constructors.ContainsKey(typeName))
throw new InvalidOperationException(string.Format("More that one type want to be a model for content type {0}.", typeName));
// should work everywhere, but slow
//_constructors[typeName] = constructor;
// much faster with a dynamic method but potential MediumTrust issues
// here http://stackoverflow.com/questions/16363838/how-do-you-call-a-constructor-via-an-expression-tree-on-an-existing-object
// fast enough and works in MediumTrust
// read http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/
var exprArg = Expression.Parameter(typeof(IPublishedContent), "content");
var exprNew = Expression.New(constructor, exprArg);
var expr = Expression.Lambda<Func<IPublishedContent, IPublishedContent>>(exprNew, exprArg);
var func = expr.Compile();
_constructors[typeName] = func;
}
}
public IPublishedContent CreateModel(IPublishedContent content)
{
// be case-insensitive
var contentTypeAlias = content.DocumentTypeAlias.ToLowerInvariant();
//ConstructorInfo constructor;
//return _constructors.TryGetValue(contentTypeAlias, out constructor)
// ? (IPublishedContent) constructor.Invoke(new object[] { content })
// : content;
Func<IPublishedContent, IPublishedContent> constructor;
return _constructors.TryGetValue(contentTypeAlias, out constructor)
? constructor(content)
: content;
}
}
}
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// <summary>
/// Resolves the IPublishedContentModelFactory object.
/// </summary>
internal class PublishedContentModelFactoryResolver : SingleObjectResolverBase<PublishedContentModelFactoryResolver, IPublishedContentModelFactory>
public class PublishedContentModelFactoryResolver : SingleObjectResolverBase<PublishedContentModelFactoryResolver, IPublishedContentModelFactory>
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModelFactoryResolver"/>.
@@ -44,6 +44,11 @@ namespace Umbraco.Core.Models.PublishedContent
InitializeIndexes();
}
// create detached content type - ie does not match anything in the DB
internal PublishedContentType(string alias, IEnumerable<PublishedPropertyType> propertyTypes)
: this (0, alias, propertyTypes)
{ }
private void InitializeIndexes()
{
for (var i = 0; i < _propertyTypes.Length; i++)
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms
internal class DataTypePreValueDto
{
[Column("id")]
[PrimaryKeyColumn(IdentitySeed = 5)]
[PrimaryKeyColumn(IdentitySeed = 6)]
public int Id { get; set; }
[Column("datatypeNodeId")]
@@ -248,6 +248,9 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
{
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = 3, Alias = "", SortOrder = 0, DataTypeNodeId = -87, Value = ",code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,umbracoembed,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|" });
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = 4, Alias = "group", SortOrder = 0, DataTypeNodeId = 1041, Value = "default" });
//default's for MultipleMediaPickerAlias picker
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = 5, Alias = "multiPicker", SortOrder = 0, DataTypeNodeId = 1045, Value = "1" });
}
private void CreateUmbracoRelationTypeData()
@@ -1,5 +1,7 @@
using System.Data;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero
{
@@ -18,9 +20,18 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero
}
else
{
//These are the old aliases
Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app");
Delete.ForeignKey("FK_umbracoUser2app_umbracoUser").OnTable("umbracoUser2app");
//These are the old aliases, before removing them, check they exist
var constraints = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoApp")))
{
Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app");
}
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoUser")))
{
Delete.ForeignKey("FK_umbracoUser2app_umbracoUser").OnTable("umbracoUser2app");
}
}
}
@@ -22,6 +22,7 @@ using System.Security.Permissions;
[assembly: InternalsVisibleTo("umbraco")]
[assembly: InternalsVisibleTo("Umbraco.Tests")]
[assembly: InternalsVisibleTo("Umbraco.Extensions")]
[assembly: InternalsVisibleTo("businesslogic")]
[assembly: InternalsVisibleTo("cms")]
[assembly: InternalsVisibleTo("umbraco.editorControls")]
+2 -2
View File
@@ -1224,8 +1224,8 @@ namespace Umbraco.Core.Services
if (SendingToPublish.IsRaisedEventCancelled(new SendToPublishEventArgs<IContent>(content), this))
return false;
//TODO: Do some stuff here.. ... what is it supposed to do ?
// pretty sure all that legacy stuff did was raise an event? and we no longer have IActionHandlers so no worries there.
//Save before raising event
Save(content, userId);
SentToPublish.RaiseEvent(new SendToPublishEventArgs<IContent>(content, false), this);
+5 -6
View File
@@ -207,10 +207,11 @@ namespace Umbraco.Core.Services
if (user == null) throw new ArgumentNullException("user");
var provider = MembershipProviderExtensions.GetUsersMembershipProvider();
if (provider.IsUmbracoMembershipProvider())
{
provider.ChangePassword(user.Username, "", password);
}
if (provider.IsUmbracoMembershipProvider() == false)
throw new NotSupportedException("When using a non-Umbraco membership provider you must change the user password by using the MembershipProvider.ChangePassword method");
provider.ChangePassword(user.Username, "", password);
//go re-fetch the member and update the properties that may have changed
var result = GetByUsername(user.Username);
@@ -221,8 +222,6 @@ namespace Umbraco.Core.Services
user.LastPasswordChangeDate = result.LastPasswordChangeDate;
user.UpdateDate = user.UpdateDate;
}
throw new NotSupportedException("When using a non-Umbraco membership provider you must change the user password by using the MembershipProvider.ChangePassword method");
}
/// <summary>
+2 -2
View File
@@ -352,7 +352,7 @@
<Compile Include="Models\PropertyTagBehavior.cs" />
<Compile Include="Models\PublishedContent\IPublishedContentExtended.cs" />
<Compile Include="Models\PublishedContent\PublishedPropertyBase.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModelFactoryImpl.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModelFactory.cs" />
<Compile Include="Models\PublishedContent\IPublishedContentModelFactory.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModel.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModelFactoryResolver.cs" />
@@ -441,7 +441,7 @@
<Compile Include="Models\Macro.cs" />
<Compile Include="Models\PublishedContent\PublishedContentExtended.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModelAttribute.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModelFactory.cs" />
<Compile Include="Models\PublishedContent\PublishedContentExtensionsForModels.cs" />
<Compile Include="Models\MacroProperty.cs" />
<Compile Include="Models\MacroPropertyCollection.cs" />
<Compile Include="Models\MacroPropertyTypeBaseTypes.cs" />
@@ -26,27 +26,13 @@ namespace Umbraco.Tests.AngularIntegration
{
var result = JsInitialization.ParseMain(new[] {"[World]", "Hello" });
Assert.AreEqual(@"
yepnope({
load: [
'lib/jquery/jquery-2.0.3.min.js',
'lib/angular/1.1.5/angular.min.js',
'lib/underscore/underscore.js',
],
complete: function () {
yepnope({
load: [World],
complete: function () {
Assert.AreEqual(@"LazyLoad.js([World], function () {
//we need to set the legacy UmbClientMgr path
UmbClientMgr.setUmbracoPath('Hello');
//we need to set the legacy UmbClientMgr path
UmbClientMgr.setUmbracoPath('Hello');
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
});
}
});
}
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
});
});", result);
}
}
@@ -44,8 +44,9 @@ namespace Umbraco.Tests.PublishedContent
{
PropertyValueConvertersResolver.Current =
new PropertyValueConvertersResolver();
var types = PluginManager.Current.ResolveTypes<PublishedContentModel>();
PublishedContentModelFactoryResolver.Current =
new PublishedContentModelFactoryResolver(new PublishedContentModelFactoryImpl());
new PublishedContentModelFactoryResolver(new PublishedContentModelFactory(types));
base.FreezeResolution();
}
@@ -32,7 +32,7 @@ namespace Umbraco.Tests.PublishedContent
public void Add(SolidPublishedContent content)
{
_content[content.Id] = PublishedContentModelFactory.CreateModel(content);
_content[content.Id] = content.CreateModel();
}
public void Clear()
@@ -63,8 +63,9 @@ namespace Umbraco.Tests.PublishedContent
protected override void FreezeResolution()
{
var types = PluginManager.Current.ResolveTypes<PublishedContentModel>();
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver(
new PublishedContentModelFactoryImpl());
new PublishedContentModelFactory(types));
base.FreezeResolution();
}
@@ -221,7 +222,7 @@ namespace Umbraco.Tests.PublishedContent
var doc = GetNode(1173);
var items = doc.Children
.Select(PublishedContentModelFactory.CreateModel) // linq, returns IEnumerable<IPublishedContent>
.Select(x => x.CreateModel()) // linq, returns IEnumerable<IPublishedContent>
// only way around this is to make sure every IEnumerable<T> extension
// explicitely returns a PublishedContentSet, not an IEnumerable<T>
@@ -38,10 +38,42 @@ angular.module('umbraco.services')
for (var i = 0; i < dialogs.length; i++) {
var dialog = dialogs[i];
dialog.close(args);
dialogs.splice(i, 1);
}
}
/** Internal method that closes the dialog properly and cleans up resources */
function closeDialog(dialog) {
if (dialog.element) {
dialog.element.modal('hide');
//this is not entirely enough since the damn webforms scriploader still complains
if (dialog.iframe) {
dialog.element.find("iframe").attr("src", "about:blank");
$timeout(function () {
//we need to do more than just remove the element, this will not destroy the
// scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont
// take care of this ourselves we have memory leaks.
dialog.element.remove();
//SD: No idea why this is required but was there before - pretty sure it's not required
$("#" + dialog.element.attr("id")).remove();
dialog.scope.$destroy();
}, 1000);
} else {
//we need to do more than just remove the element, this will not destroy the
// scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont
// take care of this ourselves we have memory leaks.
dialog.element.remove();
//SD: No idea why this is required but was there before - pretty sure it's not required
$("#" + dialog.element.attr("id")).remove();
dialog.scope.$destroy();
}
}
//remove 'this' dialog from the dialogs array
dialogs = _.reject(dialogs, function (i) { return i === dialog; });
}
/** Internal method that handles opening all dialogs */
function openDialog(options) {
var defaults = {
@@ -55,13 +87,19 @@ angular.module('umbraco.services')
template: "views/common/notfound.html",
callback: undefined,
closeCallback: undefined,
element: undefined,
//this allows us to pass in data to the dialog if required which can be used to configure the dialog
//and re-use it for different purposes. It will set on to the $scope.dialogData if it is defined.
element: undefined,
// It will set this value as a property on the dialog controller's scope as dialogData,
// used to pass in custom data to the dialog controller's $scope. Though this is near identical to
// the dialogOptions property that is also set the the dialog controller's $scope object.
// So there's basically 2 ways of doing the same thing which we're now stuck with and in fact
// dialogData has another specially attached property called .selection which gets used.
dialogData: undefined
};
var dialog = angular.extend(defaults, options);
//NOTE: People should NOT pass in a scope object that is legacy functoinality and causes problems. We will ALWAYS
// destroy the scope when the dialog is closed regardless if it is in use elsewhere which is why it shouldn't be done.
var scope = options.scope || $rootScope.$new();
//Modal dom obj and unique id
@@ -94,28 +132,7 @@ angular.module('umbraco.services')
dialog.closeCallback(data);
}
if (dialog.element) {
dialog.element.modal('hide');
//this is not entirely enough since the damn
//webforms scriploader still complains
if (dialog.iframe) {
dialog.element.find("iframe").attr("src", "about:blank");
$timeout(function () {
//we need to do more than just remove the element, this will not destroy the
// scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont
// take care of this ourselves we have memory leaks.
dialog.element.remove();
dialog.scope.$destroy();
}, 1000);
} else {
//we need to do more than just remove the element, this will not destroy the
// scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont
// take care of this ourselves we have memory leaks.
dialog.element.remove();
dialog.scope.$destroy();
}
}
closeDialog(dialog);
};
//if iframe is enabled, inject that instead of a template
@@ -183,15 +200,9 @@ angular.module('umbraco.services')
}
};
//NOTE: Same as 'close' without the callbacks
scope.hide = function () {
dialog.element.modal('hide');
dialog.element.remove();
$("#" + dialog.element.attr("id")).remove();
//we need to do more than just remove the element, this will not destroy the
// scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont
// take care of this ourselves we have memory leaks.
dialog.scope.$destroy();
closeDialog(dialog);
};
//basic events for submitting and closing
@@ -200,19 +211,16 @@ angular.module('umbraco.services')
dialog.callback(data);
}
dialog.element.modal('hide');
dialog.element.remove();
$("#" + dialog.element.attr("id")).remove();
//we need to do more than just remove the element, this will not destroy the
// scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont
// take care of this ourselves we have memory leaks.
dialog.scope.$destroy();
closeDialog(dialog);
};
scope.close = function (data) {
dialog.close(data);
};
//NOTE: This can ONLY ever be used to show the dialog if dialog.show is false (autoshow).
// You CANNOT call show() after you call hide(). hide = close, they are the same thing and once
// a dialog is closed it's resources are disposed of.
scope.show = function () {
dialog.element.modal('show');
};
@@ -226,6 +234,7 @@ angular.module('umbraco.services')
}
};
//NOTE: Same as 'close' without the callbacks
scope.dismiss = scope.hide;
// Emit modal events
@@ -274,7 +283,6 @@ angular.module('umbraco.services')
* @param {String} options.animation animation csss class, by default set to "fade"
* @param {String} options.modalClass modal css class, by default "umb-modal"
* @param {Bool} options.show show the modal instantly
* @param {Object} options.scope scope to attach the modal to, by default rootScope.new()
* @param {Bool} options.iframe load template in an iframe, only needed for serverside templates
* @param {Int} options.width set a width on the modal, only needed for iframes
* @param {Bool} options.inline strips the modal from any animation and wrappers, used when you want to inject a dialog into an existing container
@@ -321,7 +329,6 @@ angular.module('umbraco.services')
* @description
* Opens a media picker in a modal, the callback returns an array of selected media items
* @param {Object} options mediapicker dialog options object
* @param {$scope} options.scope dialog scope
* @param {Boolean} options.onlyImages Only display files that have an image file-extension
* @param {Function} options.callback callback function
* @returns {Object} modal object
@@ -341,8 +348,7 @@ angular.module('umbraco.services')
* @description
* Opens a content picker tree in a modal, the callback returns an array of selected documents
* @param {Object} options content picker dialog options object
* @param {$scope} options.scope dialog scope
* @param {$scope} options.multipicker should the picker return one or multiple items
* @param {Boolean} options.multipicker should the picker return one or multiple items
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -360,7 +366,6 @@ angular.module('umbraco.services')
* @description
* Opens a link picker tree in a modal, the callback returns a single link
* @param {Object} options content picker dialog options object
* @param {$scope} options.scope dialog scope
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -378,7 +383,6 @@ angular.module('umbraco.services')
* @description
* Opens a mcaro picker in a modal, the callback returns a object representing the macro and it's parameters
* @param {Object} options macropicker dialog options object
* @param {$scope} options.scope dialog scope
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -397,8 +401,7 @@ angular.module('umbraco.services')
* @description
* Opens a member picker in a modal, the callback returns a object representing the selected member
* @param {Object} options member picker dialog options object
* @param {$scope} options.scope dialog scope
* @param {$scope} options.multiPicker should the tree pick one or multiple members before returning
* @param {Boolean} options.multiPicker should the tree pick one or multiple members before returning
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -416,8 +419,7 @@ angular.module('umbraco.services')
* @description
* Opens a member group picker in a modal, the callback returns a object representing the selected member
* @param {Object} options member group picker dialog options object
* @param {$scope} options.scope dialog scope
* @param {$scope} options.multiPicker should the tree pick one or multiple members before returning
* @param {Boolean} options.multiPicker should the tree pick one or multiple members before returning
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -435,7 +437,6 @@ angular.module('umbraco.services')
* @description
* Opens a icon picker in a modal, the callback returns a object representing the selected icon
* @param {Object} options iconpicker dialog options object
* @param {$scope} options.scope dialog scope
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -453,10 +454,9 @@ angular.module('umbraco.services')
* @description
* Opens a tree picker in a modal, the callback returns a object representing the selected tree item
* @param {Object} options iconpicker dialog options object
* @param {$scope} options.scope dialog scope
* @param {$scope} options.section tree section to display
* @param {$scope} options.treeAlias specific tree to display
* @param {$scope} options.multiPicker should the tree pick one or multiple items before returning
* @param {String} options.section tree section to display
* @param {String} options.treeAlias specific tree to display
* @param {Boolean} options.multiPicker should the tree pick one or multiple items before returning
* @param {Function} options.callback callback function
* @returns {Object} modal object
*/
@@ -474,7 +474,6 @@ angular.module('umbraco.services')
* @description
* Opens a dialog with a chosen property editor in, a value can be passed to the modal, and this value is returned in the callback
* @param {Object} options mediapicker dialog options object
* @param {$scope} options.scope dialog scope
* @param {Function} options.callback callback function
* @param {String} editor editor to use to edit a given value and return on callback
* @param {Object} value value sent to the property editor
@@ -400,7 +400,6 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
}
var dialog = self.showDialog({
scope: args.scope,
node: args.node,
action: found,
section: appState.getSectionState("currentSection")
@@ -569,12 +568,11 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
* into #dialog div.umb-panel-body
* the path to the dialog view is determined by:
* "views/" + current tree + "/" + action alias + ".html"
* The dialog controller will get passed a scope object that is created here. This scope
* object may be injected as part of the args object, if one is not found then a new scope
* is created. Regardless of whether a scope is created or re-used, a few properties and methods
* will be added to it so that they can be used in any dialog controller:
* The dialog controller will get passed a scope object that is created here with the properties:
* scope.currentNode = the selected tree node
* scope.currentAction = the selected menu item
* so that the dialog controllers can use these properties
*
* @param {Object} args arguments passed to the function
* @param {Scope} args.scope current scope passed to the dialog
* @param {Object} args.action the clicked action containing `name` and `alias`
@@ -598,8 +596,11 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
setMode("dialog");
//set up the scope object and assign properties
var dialogScope = args.scope || $rootScope.$new();
//NOTE: Set up the scope object and assign properties, this is legacy functionality but we have to live with it now.
// we should be passing in currentNode and currentAction using 'dialogData' for the dialog, not attaching it to a scope.
// This scope instance will be destroyed by the dialog so it cannot be a scope that exists outside of the dialog.
// If a scope instance has been passed in, we'll have to create a child scope of it, otherwise a new root scope.
var dialogScope = args.scope ? args.scope.$new() : $rootScope.$new();
dialogScope.currentNode = args.node;
dialogScope.currentAction = args.action;
@@ -657,14 +658,19 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
var dialog = dialogService.open(
{
container: $("#dialog div.umb-modalcolumn-body"),
//The ONLY reason we're passing in scope to the dialogService (which is legacy functionality) is
// for backwards compatibility since many dialogs require $scope.currentNode or $scope.currentAction
// to exist
scope: dialogScope,
currentNode: args.node,
currentAction: args.action,
inline: true,
show: true,
iframe: iframe,
modalClass: "umb-dialog",
template: templateUrl
template: templateUrl,
//These will show up on the dialog controller's $scope under dialogOptions
currentNode: args.node,
currentAction: args.action,
});
//save the currently assigned dialog so it can be removed before a new one is created
@@ -61,7 +61,7 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
tooltip: 'Embed',
onclick: function () {
dialogService.embedDialog({
scope: $scope, callback: function (data) {
callback: function (data) {
editor.insertContent(data);
}
});
@@ -80,7 +80,7 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
* @param {Object} editor the TinyMCE editor instance
* @param {Object} $scope the current controller scope
*/
createMediaPicker: function (editor, $scope) {
createMediaPicker: function (editor) {
editor.addButton('umbmediapicker', {
icon: 'custom icon-picture',
tooltip: 'Media Picker',
@@ -103,7 +103,7 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
currentTarget: currentTarget,
onlyImages: true,
showDetails: true,
scope: $scope, callback: function (img) {
callback: function (img) {
if (img) {
@@ -139,49 +139,6 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
});
},
/**
* @ngdoc method
* @name umbraco.services.tinyMceService#createLinkPicker
* @methodOf umbraco.services.tinyMceService
*
* @description
* Creates the umbrco insert link tinymce plugin
*
* @param {Object} editor the TinyMCE editor instance
* @param {Object} $scope the current controller scope
*/
createLinkPicker: function (editor, $scope) {
/*
editor.addButton('link', {
icon: 'custom icon-link',
tooltip: 'Link Picker',
onclick: function () {
dialogService.linkPicker({
scope: $scope, callback: function (link) {
if (link) {
var data = {
title: "Some description",
href: "",
id: '__mcenew'
};
editor.execCommand("mceInsertLink", false, {
href: "wat",
title: "muh",
target: null,
"class": null
});
//editor.insertContent(editor.dom.createHTML('a', data));
}
}
});
}
});*/
},
/**
* @ngdoc method
* @name umbraco.services.tinyMceService#createUmbracoMacro
@@ -496,7 +453,6 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
}
dialogService.macroPicker({
scope: $scope,
dialogData : dialogData,
callback: function(data) {
@@ -107,9 +107,6 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams,
//this reacts to the options item in the tree
//todo, migrate to nav service
$scope.searchShowMenu = function (ev, args) {
$scope.currentNode = args.node;
args.scope = $scope;
//always skip default
args.skipDefault = true;
navigationService.showMenu(ev, args);
@@ -26,8 +26,10 @@ function SearchController($scope, searchService, $log, $location, navigationServ
iterateResults(false);
break;
case 13:
$location.path($scope.selectedItem.editorPath);
navigationService.hideSearch();
if ($scope.selectedItem) {
$location.path($scope.selectedItem.editorPath);
navigationService.hideSearch();
}
break;
}
};
@@ -4,7 +4,7 @@ function ContentEditDialogController($scope) {
$scope.model.defaultButton = null;
$scope.model.subButtons = [];
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
if(dialogOptions.entity){
$scope.model.entity = dialogOptions.entity;
$scope.loaded = true;
@@ -1,7 +1,7 @@
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Dialogs.ContentPickerController",
function ($scope, eventsService, entityResource, searchService, $log) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
$scope.results = [];
@@ -1,7 +1,7 @@
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController",
function ($scope, eventsService, dialogService, entityResource, contentResource, mediaHelper, $log) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
$scope.target = {};
@@ -3,7 +3,7 @@ angular.module("umbraco")
.controller("Umbraco.Dialogs.MediaPickerController",
function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, eventsService, treeService, $cookies) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.onlyImages = dialogOptions.onlyImages;
$scope.showDetails = dialogOptions.showDetails;
@@ -1,7 +1,7 @@
//used for the member picker dialog
angular.module("umbraco").controller("Umbraco.Dialogs.MemberGroupPickerController",
function($scope, eventsService, entityResource, searchService, $log) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
$scope.results = [];
$scope.dialogData = [];
@@ -1,7 +1,7 @@
//used for the member picker dialog
angular.module("umbraco").controller("Umbraco.Dialogs.MemberPickerController",
function($scope, eventsService, entityResource, searchService, $log) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
$scope.results = [];
@@ -2,7 +2,7 @@
angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
function ($scope, entityResource, eventsService, $log, searchService) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
$scope.section = dialogOptions.section;
$scope.treeAlias = dialogOptions.treeAlias;
@@ -22,7 +22,7 @@ angular.module("umbraco")
var pendingChangeEvent = eventsService.on("valFormManager.pendingChanges", function (e, args) {
//one time listener, remove the event
pendingChangeEvent();
$scope.hide();
$scope.close();
});
//perform the path change, if it is successful then the promise will resolve otherwise it will fail
@@ -31,7 +31,7 @@ angular.module("umbraco")
$scope.gotoHistory = function (link) {
$location.path(link);
$scope.hide();
$scope.close();
};
//Manually update the remaining timeout seconds
@@ -2,7 +2,7 @@ angular.module("umbraco")
.controller("Umbraco.Editors.Content.CopyController",
function ($scope, eventsService, contentResource, navigationService, appState, treeService) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.relateToOriginal = false;
$scope.dialogTreeEventHandler = $({});
@@ -1,7 +1,7 @@
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController",
function ($scope, eventsService, contentResource, navigationService, appState, treeService) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
var node = dialogOptions.currentNode;
@@ -4,7 +4,7 @@
<ng-form name="copyForm">
<p class="abstract" ng-hide="success">
Choose where to copy <strong>{{currentNode.name}}</strong> to in the tree struture below
Choose where to copy <strong>{{currentNode.name}}</strong> to in the tree structure below
</p>
<div class="alert alert-error" ng-show="error">
@@ -3,7 +3,7 @@
<div class="umb-pane">
<p class="abstract" ng-hide="success">
Choose where to move <strong>{{currentNode.name}}</strong> to in the tree struture below
Choose where to move <strong>{{currentNode.name}}</strong> to in the tree structure below
</p>
<div class="alert alert-error" ng-show="error">
@@ -22,7 +22,7 @@ function startupLatestEditsController($scope) {
angular.module("umbraco").controller("Umbraco.Dashboard.StartupLatestEditsController", startupLatestEditsController);
function MediaFolderBrowserDashboardController($rootScope, $scope, assetsService, $routeParams, $timeout, $element, $location, umbRequestHelper,navigationService, mediaResource, $cookies) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.filesUploading = [];
$scope.options = {
@@ -1,7 +1,7 @@
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController",
function ($scope, eventsService, mediaResource, appState, treeService, navigationService) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.dialogTreeEventHandler = $({});
var node = dialogOptions.currentNode;
@@ -3,7 +3,7 @@
<div class="umb-pane">
<p class="abstract" ng-hide="success">
Choose where to move <strong>{{currentNode.name}}</strong> to in the tree struture below
Choose where to move <strong>{{currentNode.name}}</strong> to in the tree structure below
</p>
<div class="alert alert-error" ng-show="error">
@@ -29,7 +29,6 @@ angular.module('umbraco')
var d = dialogService.treePicker({
section: $scope.cfg.type,
treeAlias: $scope.cfg.type,
scope: $scope,
multiPicker: $scope.cfg.multiPicker,
callback: populate});
};
@@ -30,7 +30,6 @@ angular.module('umbraco')
var d = dialogService.treePicker({
section: $scope.cfg.type,
treeAlias: $scope.cfg.type,
scope: $scope,
multiPicker: $scope.cfg.multiPicker,
callback: populate});
};
@@ -31,7 +31,6 @@ angular.module('umbraco')
var d = dialogService.treePicker({
section: $scope.model.value.type,
treeAlias: $scope.model.value.type,
scope: $scope,
multiPicker: false,
callback: populate});
};
@@ -1,6 +1,11 @@
function ColorPickerController($scope) {
$scope.selectItem = function (color) {
$scope.model.value = color;
$scope.toggleItem = function (color) {
if ($scope.model.value == color) {
$scope.model.value = "";
}
else {
$scope.model.value = color;
}
};
$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;
}
@@ -6,7 +6,7 @@
<ul class="thumbnails color-picker">
<li ng-repeat="(key, val) in model.config.items" ng-class="{active: model.value === val}">
<a ng-click="selectItem(val)" class="thumbnail" hex-bg-color="{{val}}">
<a ng-click="toggleItem(val)" class="thumbnail" hex-bg-color="{{val}}">
</a>
</li>
@@ -25,6 +25,9 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
/** this method is used to initialize the data and to re-initialize it if the server value is changed */
function initialize(index) {
clearFiles();
if (!index) {
index = 1;
}
@@ -116,9 +119,6 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
initialize($scope.rebuildInput.index + 1);
}
//if (newVal !== "{clearFiles: true}" && newVal !== $scope.originalValue && !newVal.startsWith("{selectedFiles:")) {
// initialize($scope.rebuildInput.index + 1);
//}
}
});
};
@@ -12,7 +12,7 @@ angular.module("umbraco")
})
.controller("Umbraco.PropertyEditors.FolderBrowserController",
function ($rootScope, $scope, assetsService, $routeParams, $timeout, $element, $location, $log, umbRequestHelper, mediaResource, imageHelper, navigationService, editorState) {
var dialogOptions = $scope.$parent.dialogOptions;
var dialogOptions = $scope.dialogOptions;
$scope.creating = $routeParams.create;
@@ -33,7 +33,7 @@ angular.module("umbraco")
google.maps.event.addListener(map, 'click', function (event) {
dialogService.mediaPicker({
scope: $scope, callback: function (data) {
callback: function (data) {
var image = data.selection[0].src;
var latLng = event.latLng;
@@ -7,15 +7,15 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.GridController",
//we most likely will need some iframe-motherpage interop here
$scope.openMediaPicker =function(){
var d = dialogService.mediaPicker({scope: $scope, callback: renderImages});
var d = dialogService.mediaPicker({callback: renderImages});
};
$scope.openPropertyDialog =function(){
var d = dialogService.property({scope: $scope, callback: renderProperty});
var d = dialogService.property({callback: renderProperty});
};
$scope.openMacroDialog =function(){
var d = dialogService.macroPicker({scope: $scope, callback: renderMacro});
var d = dialogService.macroPicker({callback: renderMacro});
};
function renderProperty(data){
@@ -26,8 +26,8 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.GridController",
// $scope.currentElement.html( macroFactory.renderMacro(data.macro, -1) );
}
function renderImages(data){
var list = $("<ul class='thumbnails'></ul>")
function renderImages(data) {
var list = $("<ul class='thumbnails'></ul>");
$.each(data.selection, function(i, image) {
list.append( $("<li class='span2'><img class='thumbnail' src='" + image.src + "'></li>") );
});
@@ -88,6 +88,13 @@ angular.module('umbraco')
}
});
//here we declare a special method which will be called whenever the value has changed from the server
$scope.model.onValueChanged = function (newVal, oldVal) {
//clear current uploaded files
fileManager.setFiles($scope.model.alias, []);
};
var unsubscribe = $scope.$on("formSubmitting", function () {
$scope.done();
});
@@ -43,7 +43,6 @@ angular.module('umbraco')
}
dialogService.macroPicker({
scope: $scope,
dialogData : dialogData,
callback: function(data) {
@@ -28,7 +28,6 @@ angular.module('umbraco')
$scope.openMemberGroupPicker =function(){
var d = dialogService.memberGroupPicker(
{
scope: $scope,
multiPicker: $scope.cfg.multiPicker,
filter: $scope.cfg.filter,
filterCssClass: "not-allowed",
@@ -22,7 +22,6 @@ angular.module('umbraco')
$scope.openMemberPicker =function(){
var d = dialogService.memberPicker(
{
scope: $scope,
multiPicker: $scope.cfg.multiPicker,
filter: $scope.cfg.filter,
filterCssClass: "not-allowed",
@@ -17,14 +17,14 @@
$scope.internal = function ($event) {
$scope.currentEditLink = null;
var d = dialogService.contentPicker({ scope: $scope, multipicker: false, callback: select });
var d = dialogService.contentPicker({ multipicker: false, callback: select });
$event.preventDefault();
};
$scope.selectInternal = function ($event, link) {
$scope.currentEditLink = link;
var d = dialogService.contentPicker({ scope: $scope, multipicker: false, callback: select });
var d = dialogService.contentPicker({ multipicker: false, callback: select });
$event.preventDefault();
};
@@ -182,9 +182,6 @@ angular.module("umbraco")
//Create the embedded plugin
tinyMceService.createInsertEmbeddedMedia(editor, $scope);
//Create the insert link plugin
tinyMceService.createLinkPicker(editor, $scope);
//Create the insert macro plugin
tinyMceService.createInsertMacro(editor, $scope);
};
@@ -71,6 +71,12 @@
//initiate slider, add event handler and get the instance reference (stored in data)
var slider = $element.find('.slider-item').slider({
max: $scope.model.config.maxVal,
min: $scope.model.config.minVal,
orientation: $scope.model.config.orientation,
selection: "after",
step: $scope.model.config.step,
tooltip: "show",
//set the slider val - we cannot do this with data- attributes when using ranges
value: sliderVal
}).on('slideStop', function () {
@@ -1,11 +1,5 @@
<div ng-controller="Umbraco.PropertyEditors.SliderController">
<input type="text" name="slider" class="slider-item"
data-slider-min="{{ model.config.minVal }}"
data-slider-max="{{ model.config.maxVal }}"
data-slider-step="{{ model.config.step }}"
data-slider-orientation="{{ model.config.orientation }}"
data-slider-selection="after"
data-slider-tooltip="show" />
<input type="text" name="slider" class="slider-item" />
</div>
+2 -2
View File
@@ -2530,9 +2530,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7130</DevelopmentServerPort>
<DevelopmentServerPort>7140</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7130</IISUrl>
<IISUrl>http://localhost:7140</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -53,8 +53,13 @@
<control showOnce="true" addPanel="true" panelCaption="">
views/dashboard/default/startupdashboardintro.html
</control>
</tab>
</tab>
<tab caption="Change password">
<control showOnce="false" addPanel="false" panelCaption="">
views/dashboard/ChangePassword.html
</control>
</tab>
</section>
<section alias="StartupMemberDashboardSection">
+14 -14
View File
@@ -212,16 +212,16 @@
<key alias="recycleBinIsEmpty">The recycle bin is now empty</key>
<key alias="recycleBinWarning">When items are deleted from the recycle bin, they will be gone forever</key>
<key alias="regexSearchError"><![CDATA[<a target='_blank' href='http://regexlib.com'>regexlib.com</a>'s webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]></key>
<key alias="regexSearchHelp">Search for a regular expression to add validation to a form field. Exemple: 'email, 'zip-code' 'url'</key>
<key alias="regexSearchHelp">Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url'</key>
<key alias="removeMacro">Remove Macro</key>
<key alias="requiredField">Required Field</key>
<key alias="sitereindexed">Site is reindexed</key>
<key alias="siterepublished">The website cache has been refreshed. All publish content is now uptodate. While all unpublished content is still unpublished</key>
<key alias="siterepublished">The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished</key>
<key alias="siterepublishHelp">The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished.</key>
<key alias="tableColumns">Number of columns</key>
<key alias="tableRows">Number of rows</key>
<key alias="templateContentAreaHelp"><![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]></key>
by referring this ID using a <code>&lt;asp:content /&gt;</code> element.]]></key>
<key alias="templateContentPlaceHolderHelp"><![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]></key>
<key alias="thumbnailimageclickfororiginal">Click on the image to see full size</key>
@@ -243,7 +243,7 @@
<key alias="filter">Type to filter...</key>
</area>
<area alias="editcontenttype">
<key alias="allowedchildnodetypes">Allowed child nodetypes</key>
<key alias="allowedchildnodetypes">Allowed child node types</key>
<key alias="create">Create</key>
<key alias="deletetab">Delete tab</key>
<key alias="description">Description</key>
@@ -267,7 +267,7 @@
</area>
<area alias="errorHandling">
<key alias="errorButDataWasSaved">Your data has been saved, but before you can publish this page there are some errors you need to fix first:</key>
<key alias="errorChangingProviderPassword">The current MemberShip Provider does not support changing password (EnablePasswordRetrieval need to be true)</key>
<key alias="errorChangingProviderPassword">The current membership provider does not support changing password (EnablePasswordRetrieval need to be true)</key>
<key alias="errorExistsWithoutTab">%0% already exists</key>
<key alias="errorHeader">There were errors:</key>
<key alias="errorHeaderWithoutTab">There were errors:</key>
@@ -279,9 +279,9 @@
<key alias="errorRegExpWithoutTab">%0% is not in a correct format</key>
</area>
<area alias="errors">
<key alias="dissallowedMediaType">The specified file type has been dissallowed by the administrator</key>
<key alias="dissallowedMediaType">The specified file type has been disallowed by the administrator</key>
<key alias="codemirroriewarning">NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough.</key>
<key alias="contentTypeAliasAndNameNotNull">Please fill both alias and name on the new propertytype!</key>
<key alias="contentTypeAliasAndNameNotNull">Please fill both alias and name on the new property type!</key>
<key alias="filePermissionsError">There is a problem with read/write access to a specific file or folder</key>
<key alias="missingTitle">Please enter a title</key>
<key alias="missingType">Please choose a type</key>
@@ -653,7 +653,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="paAdvancedNoGroups"><![CDATA[You need to create a membergroup before you can use <br />role-based authentication.]]></key>
<key alias="paErrorPage">Error Page</key>
<key alias="paErrorPageHelp">Used when people are logged on, but do not have access</key>
<key alias="paHowWould">Choose how to restict access to this page</key>
<key alias="paHowWould">Choose how to restrict access to this page</key>
<key alias="paIsProtected">%0% is now protected</key>
<key alias="paIsRemoved">Protection removed from %0%</key>
<key alias="paLoginPage">Login Page</key>
@@ -737,7 +737,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="dictionary editor egenskab">Dictionary Key</key>
<key alias="importDocumentTypeHelp">To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen)</key>
<key alias="newtabname">New Tab Title</key>
<key alias="nodetype">Nodetype</key>
<key alias="nodetype">Node type</key>
<key alias="objecttype">Type</key>
<key alias="stylesheet">Stylesheet</key>
<key alias="script">Script</key>
@@ -835,8 +835,8 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="casing">Casing</key>
<key alias="encoding">Encoding</key>
<key alias="chooseField">Choose field</key>
<key alias="convertLineBreaks">Convert Linebreaks</key>
<key alias="convertLineBreaksHelp">Replaces linebreaks with html-tag &amp;lt;br&amp;gt;</key>
<key alias="convertLineBreaks">Convert line breaks</key>
<key alias="convertLineBreaksHelp">Replaces line breaks with html-tag &amp;lt;br&amp;gt;</key>
<key alias="customFields">Custom Fields</key>
<key alias="dateOnly">Yes, Date only</key>
<key alias="formatAsDate">Format as date</key>
@@ -857,7 +857,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="urlEncodeHelp">Will format special characters in URLs</key>
<key alias="usedIfAllEmpty">Will only be used when the field values above are empty</key>
<key alias="usedIfEmpty">This field will only be used if the primary field is empty</key>
<key alias="withTime">Yes, with time. Seperator: </key>
<key alias="withTime">Yes, with time. Separator: </key>
</area>
<area alias="translation">
<key alias="assignedTasks">Tasks assigned to you</key>
@@ -971,7 +971,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsDifferent">There was a difference between the new password and the confirmed password. Please try again!</key>
<key alias="passwordMismatch">The confirmed password doesn't match the new password!</key>
<key alias="permissionReplaceChildren">Replace child node permssions</key>
<key alias="permissionReplaceChildren">Replace child node permissions</key>
<key alias="permissionSelectedPages">You are currently modifying permissions for the pages:</key>
<key alias="permissionSelectPages">Select pages to modify their permissions</key>
<key alias="searchAllChildren">Search all children</key>
@@ -985,4 +985,4 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="yourHistory" version="7.0">Your recent history</key>
<key alias="sessionExpires" version="7.0">Session expires in</key>
</area>
</language>
</language>
@@ -218,7 +218,7 @@
<key alias="recycleBinIsEmpty">The recycle bin is now empty</key>
<key alias="recycleBinWarning">When items are deleted from the recycle bin, they will be gone forever</key>
<key alias="regexSearchError"><![CDATA[<a target='_blank' href='http://regexlib.com'>regexlib.com</a>'s webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]></key>
<key alias="regexSearchHelp">Search for a regular expression to add validation to a form field. Exemple: 'email, 'zip-code' 'url'</key>
<key alias="regexSearchHelp">Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url'</key>
<key alias="removeMacro">Remove Macro</key>
<key alias="requiredField">Required Field</key>
<key alias="sitereindexed">Site is reindexed</key>
@@ -227,7 +227,7 @@
<key alias="tableColumns">Number of columns</key>
<key alias="tableRows">Number of rows</key>
<key alias="templateContentAreaHelp"><![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]></key>
by referring this ID using a <code>&lt;asp:content /&gt;</code> element.]]></key>
<key alias="templateContentPlaceHolderHelp"><![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]></key>
<key alias="thumbnailimageclickfororiginal">Click on the image to see full size</key>
@@ -286,7 +286,7 @@
<key alias="errorRegExpWithoutTab">%0% is not in a correct format</key>
</area>
<area alias="errors">
<key alias="dissallowedMediaType">The specified file type has been dissallowed by the administrator</key>
<key alias="dissallowedMediaType">The specified file type has been disallowed by the administrator</key>
<key alias="codemirroriewarning">NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough.</key>
<key alias="contentTypeAliasAndNameNotNull">Please fill both alias and name on the new propertytype!</key>
<key alias="filePermissionsError">There is a problem with read/write access to a specific file or folder</key>
@@ -544,11 +544,11 @@ To manage your website, simply open the umbraco back office and start adding con
<area alias="login">
<key alias="greeting0">Happy super sunday</key>
<key alias="greeting1">Happy manic monday </key>
<key alias="greeting2">Happy tremendous tuesday</key>
<key alias="greeting2">Happy tubular tuesday</key>
<key alias="greeting3">Happy wonderful wednesday</key>
<key alias="greeting4">Happy thunder thursday</key>
<key alias="greeting5">Happy friendly friday</key>
<key alias="greeting6">Happy shiny saturday</key>
<key alias="greeting5">Happy funky friday</key>
<key alias="greeting6">Happy caturday</key>
<key alias="instruction">log in below</key>
<key alias="timeout">Session timed out</key>
@@ -664,7 +664,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="paAdvancedNoGroups"><![CDATA[You need to create a membergroup before you can use <br />role-based authentication.]]></key>
<key alias="paErrorPage">Error Page</key>
<key alias="paErrorPageHelp">Used when people are logged on, but do not have access</key>
<key alias="paHowWould">Choose how to restict access to this page</key>
<key alias="paHowWould">Choose how to restrict access to this page</key>
<key alias="paIsProtected">%0% is now protected</key>
<key alias="paIsRemoved">Protection removed from %0%</key>
<key alias="paLoginPage">Login Page</key>
@@ -869,7 +869,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="urlEncodeHelp">Will format special characters in URLs</key>
<key alias="usedIfAllEmpty">Will only be used when the field values above are empty</key>
<key alias="usedIfEmpty">This field will only be used if the primary field is empty</key>
<key alias="withTime">Yes, with time. Seperator: </key>
<key alias="withTime">Yes, with time. Separator: </key>
</area>
<area alias="translation">
<key alias="assignedTasks">Tasks assigned to you</key>
@@ -983,7 +983,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsDifferent">There was a difference between the new password and the confirmed password. Please try again!</key>
<key alias="passwordMismatch">The confirmed password doesn't match the new password!</key>
<key alias="permissionReplaceChildren">Replace child node permssions</key>
<key alias="permissionReplaceChildren">Replace child node permissions</key>
<key alias="permissionSelectedPages">You are currently modifying permissions for the pages:</key>
<key alias="permissionSelectPages">Select pages to modify their permissions</key>
<key alias="searchAllChildren">Search all children</key>
@@ -179,6 +179,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
instructions +
"<form action=\"" + self._opts.umbracoPath + "/webservices/MediaUploader.ashx?format=json&action=upload&parentNodeId=" + this._parentId + "\" method=\"post\" enctype=\"multipart/form-data\">" +
"<input id='fileupload' type='file' name='file' multiple>" +
"<input type='hidden' name='__reqver' value='" + self._opts.reqver + "' />" +
"<input type='hidden' name='name' />" +
"<input type='hidden' name='replaceExisting' />" +
"</form>" +
+3 -3
View File
@@ -269,16 +269,16 @@ namespace Umbraco.Web.Editors
if (contentItem.Action == ContentSaveAction.Save || contentItem.Action == ContentSaveAction.SaveNew)
{
//save the item
Services.ContentService.Save(contentItem.PersistedContent, (int)Security.CurrentUser.Id);
Services.ContentService.Save(contentItem.PersistedContent, Security.CurrentUser.Id);
}
else if (contentItem.Action == ContentSaveAction.SendPublish || contentItem.Action == ContentSaveAction.SendPublishNew)
{
Services.ContentService.SendToPublication(contentItem.PersistedContent, UmbracoUser.Id);
Services.ContentService.SendToPublication(contentItem.PersistedContent, Security.CurrentUser.Id);
}
else
{
//publish the item and check if it worked, if not we will show a diff msg below
publishStatus = Services.ContentService.SaveAndPublishWithStatus(contentItem.PersistedContent, (int)Security.CurrentUser.Id);
publishStatus = Services.ContentService.SaveAndPublishWithStatus(contentItem.PersistedContent, Security.CurrentUser.Id);
}
+16 -3
View File
@@ -10,21 +10,33 @@ namespace Umbraco.Web.Models
{
private readonly Dictionary<string, IPublishedProperty> _properties;
/// <summary>
/// Initialized a new instance of the <see cref="DetachedContent"/> class with properties.
/// </summary>
/// <param name="properties">The properties</param>
/// <remarks>Properties must be detached or nested properties ie their property type must be detached or nested.
/// Such a detached content can be part of a published property value.</remarks>
public DetachedContent(IEnumerable<IPublishedProperty> properties)
{
_properties = properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
}
// don't uncomment until you know what you are doing
/*
public DetachedContent(IPublishedContent content)
{
_properties = content.Properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
}
*/
// don't uncomment until you know what you are doing
// at the moment, I don't fully
/*
public DetachedContent(IContent content, bool isPreviewing)
{
var publishedContentType = PublishedContentType.Get(PublishedItemType.Content, content.ContentType.Alias);
_properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, content.Properties,
(t, v) => PublishedProperty.GetDetached(t, v, isPreviewing))
(t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing))
.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
}
@@ -32,7 +44,7 @@ namespace Umbraco.Web.Models
{
var publishedContentType = PublishedContentType.Get(PublishedItemType.Media, media.ContentType.Alias);
_properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, media.Properties,
(t, v) => PublishedProperty.GetDetached(t, v, isPreviewing))
(t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing))
.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
}
@@ -40,9 +52,10 @@ namespace Umbraco.Web.Models
{
var publishedContentType = PublishedContentType.Get(PublishedItemType.Member, member.ContentType.Alias);
_properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, member.Properties,
(t, v) => PublishedProperty.GetDetached(t, v, isPreviewing))
(t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing))
.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
}
*/
public ICollection<IPublishedProperty> Properties
{
@@ -0,0 +1,38 @@
using Umbraco.Core;
namespace Umbraco.Web.Models
{
/// <summary>
/// Extension methods for the PartialViewMacroModel object
/// </summary>
public static class PartialViewMacroModelExtensions
{
/// <summary>
/// Attempt to get a Marco parameter from a PartialViewMacroModel and return a default value otherwise
/// </summary>
/// <param name="partialViewMacroModel"></param>
/// <param name="parameterAlias"></param>
/// <param name="defaultValue"></param>
/// <returns>Parameter value if available, the default value that was passed otherwise.</returns>
public static T GetParameterValue<T>(this PartialViewMacroModel partialViewMacroModel, string parameterAlias, T defaultValue)
{
if (partialViewMacroModel.MacroParameters.ContainsKey(parameterAlias) == false || string.IsNullOrEmpty(partialViewMacroModel.MacroParameters[parameterAlias].ToString()))
return defaultValue;
var attempt = partialViewMacroModel.MacroParameters[parameterAlias].TryConvertTo(typeof(T));
return attempt.Success ? (T) attempt.Result : defaultValue;
}
/// <summary>
/// Attempt to get a Marco parameter from a PartialViewMacroModel
/// </summary>
/// <param name="partialViewMacroModel"></param>
/// <param name="parameterAlias"></param>
/// <returns>Parameter value if available, the default value for the type otherwise.</returns>
public static T GetParameterValue<T>(this PartialViewMacroModel partialViewMacroModel, string parameterAlias)
{
return partialViewMacroModel.GetParameterValue(parameterAlias, default(T));
}
}
}
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Media;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Editors;
@@ -50,11 +51,22 @@ namespace Umbraco.Web.PropertyEditors
JObject oldJson = null;
//get the old src path
if (currentValue != null)
if (currentValue != null && string.IsNullOrEmpty(currentValue.ToString()) == false)
{
oldJson = currentValue as JObject;
try
{
oldJson = JObject.Parse(currentValue.ToString());
}
catch (Exception ex)
{
//for some reason the value is invalid so continue as if there was no value there
LogHelper.WarnWithException<ImageCropperPropertyValueEditor>("Could not parse current db value to a JObject", ex);
}
if (oldJson != null && oldJson["src"] != null)
{
oldFile = oldJson["src"].Value<string>();
}
}
//get the new src path
@@ -62,7 +74,9 @@ namespace Umbraco.Web.PropertyEditors
{
newJson = editorValue.Value as JObject;
if (newJson != null && newJson["src"] != null)
{
newFile = newJson["src"].Value<string>();
}
}
//compare old and new src path
@@ -72,7 +86,7 @@ namespace Umbraco.Web.PropertyEditors
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
//if we have an existing file, delete it
if (!string.IsNullOrEmpty(oldFile))
if (string.IsNullOrEmpty(oldFile) == false)
fs.DeleteFile(fs.GetRelativePath(oldFile), true);
else
oldFile = string.Empty;
@@ -242,13 +242,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
return xmlNode == null
? null
: PublishedContentModelFactory.CreateModel(new XmlPublishedContent(xmlNode, isPreviewing));
: (new XmlPublishedContent(xmlNode, isPreviewing)).CreateModel();
}
private static IEnumerable<IPublishedContent> ConvertToDocuments(XmlNodeList xmlNodes, bool isPreviewing)
{
return xmlNodes.Cast<XmlNode>()
.Select(xmlNode => PublishedContentModelFactory.CreateModel(new XmlPublishedContent(xmlNode, isPreviewing)));
.Select(xmlNode => (new XmlPublishedContent(xmlNode, isPreviewing)).CreateModel());
}
#endregion
@@ -255,7 +255,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
d => GetChildrenMedia(d.Id),
GetProperty,
true);
return PublishedContentModelFactory.CreateModel(content);
return content.CreateModel();
}
internal IPublishedContent ConvertFromXPathNavigator(XPathNavigator xpath)
@@ -314,7 +314,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
d => GetChildrenMedia(d.Id, xpath),
GetProperty,
false);
return PublishedContentModelFactory.CreateModel(content);
return content.CreateModel();
}
/// <summary>
@@ -514,47 +514,36 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
_contentType = PublishedContentType.Get(PublishedItemType.Media, _documentTypeAlias);
_properties = new Collection<IPublishedProperty>();
//handle content type properties
//make sure we create them even if there's no value
foreach (var propertyType in _contentType.PropertyTypes)
{
var alias = propertyType.PropertyTypeAlias;
_keysAdded.Add(alias);
string value;
const bool isPreviewing = false; // false :: never preview a media
var property = valueDictionary.TryGetValue(alias, out value) == false
? new XmlPublishedProperty(propertyType, isPreviewing)
: new XmlPublishedProperty(propertyType, isPreviewing, value);
_properties.Add(property);
}
//loop through remaining values that haven't been applied
foreach (var i in valueDictionary.Where(x => !_keysAdded.Contains(x.Key)))
foreach (var i in valueDictionary.Where(x =>
_keysAdded.Contains(x.Key) == false // not already processed
&& IgnoredKeys.Contains(x.Key) == false)) // not ignorable
{
IPublishedProperty property = null;
// must ignore those
if (IgnoredKeys.Contains(i.Key)) continue;
if (i.Key.InvariantStartsWith("__"))
{
{
// no type for that one, dunno how to convert
property = new PropertyResult(i.Key, i.Value, PropertyResultType.CustomProperty);
}
IPublishedProperty property = new PropertyResult(i.Key, i.Value, PropertyResultType.CustomProperty);
_properties.Add(property);
}
else
{
// use property type to ensure proper conversion
var propertyType = _contentType.GetPropertyType(i.Key);
// note: this is where U4-4144 and -3665 were born
//
// because propertyType is null, the XmlPublishedProperty ctor will throw
// it's null because i.Key is not a valid property alias for the type...
// the alias is case insensitive (verified) so it means it really is not
// a correct alias.
//
// in every cases this is after a ConvertFromXPathNavigator, so it means
// that we get some properties from the XML that are not valid properties.
// no idea which property. could come from the cache in library, could come
// from so many places really.
// workaround: just ignore that property
if (propertyType == null)
{
LogHelper.Warn<PublishedMediaCache>("Dropping property \"" + i.Key + "\" because it does not belong to the content type.");
continue;
}
property = new XmlPublishedProperty(propertyType, false, i.Value); // false :: never preview a media
// this is a property that does not correspond to anything, ignore and log
LogHelper.Warn<PublishedMediaCache>("Dropping property \"" + i.Key + "\" because it does not belong to the content type.");
}
_properties.Add(property);
}
}
@@ -338,7 +338,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
if (parent == null) return;
if (parent.Name == "node" || (parent.Attributes != null && parent.Attributes.GetNamedItem("isDoc") != null))
_parent = PublishedContentModelFactory.CreateModel(new XmlPublishedContent(parent, _isPreviewing, true));
_parent = (new XmlPublishedContent(parent, _isPreviewing, true)).CreateModel();
}
private void Initialize()
@@ -439,8 +439,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
expr.AddSort("@sortOrder", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Number);
var iterator = nav.Select(expr);
while (iterator.MoveNext())
_children.Add(PublishedContentModelFactory.CreateModel(
new XmlPublishedContent(((IHasXmlNode)iterator.Current).GetNode(), _isPreviewing, true)));
_children.Add(
(new XmlPublishedContent(((IHasXmlNode)iterator.Current).GetNode(), _isPreviewing, true)).CreateModel());
// warn: this is not thread-safe
_childrenInitialized = true;
-6
View File
@@ -159,12 +159,6 @@ namespace Umbraco.Web.Routing
.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash));
if (domainAndUri != null) return domainAndUri;
// look for the first domain that the current url would be the base of
// ie current is www.example.com, look for domain www.example.com/foo/bar
domainAndUri = domainsAndUris
.FirstOrDefault(d => currentWithSlash.IsBaseOf(d.Uri.EndPathWithSlash()));
if (domainAndUri != null) return domainAndUri;
// if none matches, then try to run the filter to pick a domain
if (filter != null)
{
+1 -1
View File
@@ -107,7 +107,7 @@ namespace Umbraco.Web.Security
/// <returns>returns the number of seconds until their session times out</returns>
public FormsAuthenticationTicket PerformLogin(IUser user)
{
var ticket = _httpContext.CreateUmbracoAuthTicket(new UserData()
var ticket = _httpContext.CreateUmbracoAuthTicket(new UserData(Guid.NewGuid().ToString("N"))
{
Id = user.Id,
AllowedApplications = user.AllowedSections.ToArray(),
+4 -2
View File
@@ -4,6 +4,7 @@ using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using ClientDependency.Core;
using Umbraco.Core;
using Umbraco.Web.UI.Bundles;
using umbraco.BasePages;
using Umbraco.Core.IO;
@@ -138,10 +139,11 @@ namespace Umbraco.Web.UI.Controls
Page.ClientScript.RegisterStartupScript(typeof(FolderBrowser),
"RegisterFolderBrowsers",
string.Format("$(function () {{ $(\".umbFolderBrowser\").folderBrowser({{ umbracoPath : '{0}', basePath : '{1}' }}); " +
string.Format("$(function () {{ $(\".umbFolderBrowser\").folderBrowser({{ umbracoPath : '{0}', basePath : '{1}', reqver : '{2}' }}); " +
"$(\".umbFolderBrowser #filterTerm\").keypress(function(event) {{ return event.keyCode != 13; }});}});",
IOHelper.ResolveUrl(SystemDirectories.Umbraco),
IOHelper.ResolveUrl(SystemDirectories.Base)),
IOHelper.ResolveUrl(SystemDirectories.Base),
UmbracoEnsuredPage.umbracoUserContextID.EncryptWithMachineKey() ),
true);
}
+1
View File
@@ -353,6 +353,7 @@
<Compile Include="Models\ImageCropData.cs" />
<Compile Include="Models\ImageCropRatioMode.cs" />
<Compile Include="Models\IRenderModel.cs" />
<Compile Include="Models\PartialViewMacroModelExtensions.cs" />
<Compile Include="Models\PostRedirectModel.cs" />
<Compile Include="Models\PublishedProperty.cs" />
<Compile Include="Mvc\RedirectToUmbracoUrlResult.cs" />
+2 -1
View File
@@ -437,8 +437,9 @@ namespace Umbraco.Web
//currently assigned node. The PublishedContentRequest will be null if:
// * we are rendering a partial view or child action
// * we are rendering a view from a custom route
if (UmbracoContext.PublishedContentRequest == null
if ((UmbracoContext.PublishedContentRequest == null
|| UmbracoContext.PublishedContentRequest.PublishedContent.Id != currentPage.Id)
&& currentPage.Id > 0) // in case we're rendering a detached content (id == 0)
{
item.NodeId = currentPage.Id.ToString();
}
@@ -87,7 +87,7 @@ namespace Umbraco.Web.WebServices
case PublishStatusType.FailedHasExpired:
case PublishStatusType.FailedAwaitingRelease:
case PublishStatusType.FailedIsTrashed:
return ""; //we will not notify about this type of failure... or should we ?
return "Cannot publish document with a status of " + status.StatusType;
case PublishStatusType.FailedCancelledByEvent:
return ui.Text("publish", "contentPublishedFailedByEvent",
string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser);
@@ -70,6 +70,7 @@ namespace umbraco.presentation.actions
case PublishStatusType.FailedHasExpired:
case PublishStatusType.FailedAwaitingRelease:
case PublishStatusType.FailedIsTrashed:
return "Cannot publish document with a status of " + status.StatusType;
case PublishStatusType.FailedContentInvalid:
return ui.Text("publish", "contentPublishedFailedInvalid",
new[]
@@ -67,15 +67,22 @@ namespace umbraco.settings
if (!IsPostBack)
{
var path = BuildPath(currentItem);
ClientTools
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadDictionary>().Tree.Alias)
.SyncTree(helper.Request("id"), false);
.SyncTree(path, false);
}
Panel1.Controls.Add(p);
}
private string BuildPath(cms.businesslogic.Dictionary.DictionaryItem current)
{
var parentPath = current.IsTopMostItem() ? "" : BuildPath(current.Parent) + ",";
return parentPath + current.id;
}
void save_Click(object sender, EventArgs e)
{
foreach (TextBox t in languageFields)
@@ -258,10 +258,32 @@ namespace umbraco.presentation.umbraco.webservices
else
{
var usr = User.GetCurrent();
if (BasePage.ValidateUserContextID(BasePage.umbracoUserContextID) && usr != null)
{
isValid = true;
AuthenticatedUser = usr;
//The user is valid based on their cookies, but is the request valid? We need to validate
// against CSRF here. We'll do this by ensuring that the request contains a token which will
// be equal to the decrypted version of the current user's user context id.
var token = context.Request["__reqver"];
if (token.IsNullOrWhiteSpace() == false)
{
//try decrypting it
try
{
var decrypted = token.DecryptWithMachineKey();
//now check if it matches
if (decrypted == BasePage.umbracoUserContextID)
{
isValid = true;
AuthenticatedUser = usr;
}
}
catch
{
//couldn't decrypt, so it's invalid
}
}
}
}
+1 -1
View File
@@ -65,7 +65,7 @@ namespace umbraco.BusinessLogic.Actions
{
get
{
return "upload-alt";
return "page-up";
}
}
@@ -748,7 +748,7 @@ namespace umbraco.cms.businesslogic.web
#region Public Methods
/// <summary>
/// Executes handlers and events for the Send To Publication action.
/// Saves and executes handlers and events for the Send To Publication action.
/// </summary>
/// <param name="u">The User</param>
public bool SendToPublication(User u)
@@ -33,9 +33,12 @@ namespace umbraco.editorControls.imagecropper
//This get's the IFileSystem's path based on the URL (i.e. /media/blah/blah.jpg )
Path = _fs.GetRelativePath(relativePath);
image = Image.FromStream(_fs.OpenFile(Path));
Name = _fs.GetFileName(Path);
var fileName = _fs.GetFileName(Path);
Name = fileName.Substring(0, fileName.LastIndexOf('.'));
DateStamp = _fs.GetLastModified(Path).Date;
Width = image.Width;
Height = image.Height;
@@ -75,12 +78,10 @@ namespace umbraco.editorControls.imagecropper
{
crop = preset.Fit(this);
}
var tmpName = Name.Substring(0, Name.LastIndexOf('.'));
ImageTransform.Execute(
Path,
String.Format("{0}_{1}", tmpName, preset.Name),
String.Format("{0}_{1}", Name, preset.Name),
crop.X,
crop.Y,
crop.X2 - crop.X,