Compare commits

...

29 Commits

Author SHA1 Message Date
Sebastiaan Janssen ea32776174 Bump version 2014-05-28 17:07:51 +02:00
Stephan 320b53ae3c U4-4773 - bring back IPublishedContentProperty Alias and Version (compat) 2014-05-28 11:36:31 +02: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
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 95b9a46b88 U4-4928 - issue with missing media content properties 2014-05-26 15:02:05 +02: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
Shannon 62887607ff fixes csrf with mediauploader.ashx 2014-05-22 12:44:04 +10:00
Stephan f325794523 U4-4949 - fix issue with domains 2014-05-20 09:32:26 +02:00
Sebastiaan Janssen 3ec6d2b82f U4-4861 6.2.0 Nuget package copies wrong files 2014-05-19 10:08:26 +02: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
Shannon 78613823ae Fixes: U4-4853 Richtext Editor doesn't render macros after upgrade to Umbraco 6.2.0 2014-05-13 15:22:16 +10:00
Shannon 937e840104 Fixes: U4-4873 RuntimeCacheRefresher does not remove items when media or content requires cache refreshing & U4-4871 Synced media indexes between load balanced servers do not sync all properties 2014-05-13 10:40:56 +10:00
Shannon 313d77eb91 Fixes: U4-4789 PluginCache doesn't update with code defined PropertyEditors in package and publicizes a couple things 2014-05-12 17:19:17 +10:00
Stephan 4e5019d5af U4-4851 - Umbraco.Field legacy names 2014-05-11 21:33:56 +02:00
Shannon da0b935604 Fixes merge 2014-05-09 16:08:05 +10:00
Shannon b91a06ab98 Fixes: U4-4849 Cannot change a users language/sections in the back office 2014-05-09 16:00:30 +10:00
Shannon d61fb5d94d Fixes user cloning issues with allowed sections 2014-05-09 15:59:30 +10:00
Shannon 3b424274ee ensure properties reset on deep clone of ContentType (this is just a fail safe check) 2014-05-09 15:57:17 +10:00
Shannon b763c2ab2f Fixes deep clone of User object 2014-05-09 15:56:45 +10:00
55 changed files with 754 additions and 277 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
@ECHO OFF
SET release=6.2.0
SET release=6.2.1
SET comment=
SET version=%release%
+1
View File
@@ -69,5 +69,6 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
</files>
</package>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UmbracoVersion>6.2.0</UmbracoVersion>
<UmbracoVersion>6.2.1</UmbracoVersion>
</PropertyGroup>
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
<PropertyGroup>
+24
View File
@@ -0,0 +1,24 @@
param($rootPath, $toolsPath, $package, $project)
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
$projectDestinationPath = Split-Path $project.FullName -Parent
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# After backing up, remove all dlls from bin folder in case dll files are included in the VS project
# See: http://issues.umbraco.org/issue/U4-4930
$umbracoBinFolder = Join-Path $projectDestinationPath "bin"
if(Test-Path $umbracoBinFolder) {
$umbracoBinBackupPath = Join-Path $backupPath "bin"
New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
Remove-Item $umbracoBinFolder\*.dll -Force -Confirm:$false
}
}
+16 -6
View File
@@ -3,9 +3,11 @@ param($rootPath, $toolsPath, $package, $project)
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
# Create backup folder if it doesn't exist yet
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# Create a backup of original web.config
$projectDestinationPath = Split-Path $project.FullName -Parent
@@ -19,18 +21,26 @@ if ($project) {
# Copy umbraco and umbraco_files from package to project folder
# This is only done when these folders already exist because we
# only want to do this for upgrades
$umbracoFolder = Join-Path $projectDestinationPath "Umbraco\"
$umbracoFolder = Join-Path $projectDestinationPath "Umbraco"
if(Test-Path $umbracoFolder) {
$umbracoFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco"
Copy-Item $umbracoFolder $backupPath -Force
robocopy $umbracoFolderSource $umbracoFolder /e /xf UI.xml
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
}
$umbracoClientFolder = Join-Path $projectDestinationPath "Umbraco_Client"
if(Test-Path $umbracoClientFolder) {
$umbracoClientFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco_Client"
Copy-Item $umbracoClientFolder $backupPath -Force
robocopy $umbracoFolderSource $umbracoClientFolder /e
$umbracoClientBackupPath = Join-Path $backupPath "Umbraco_Client"
New-Item -ItemType Directory -Force -Path $umbracoClientBackupPath
robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log
robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log
}
# Open readme.txt file
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("6.2.0");
private static readonly Version Version = new Version("6.2.1");
/// <summary>
/// Gets the current version of Umbraco.
@@ -37,6 +37,9 @@ namespace Umbraco.Core.Dynamics
public object Value { get { return _source == null ? _value : _source.Value; } }
public object XPathValue { get { return Value == null ? null : Value.ToString(); } }
public string Alias { get { return PropertyTypeAlias; }}
public Guid Version { get { return Guid.Empty; }}
// implements IHtmlString.ToHtmlString
public string ToHtmlString()
{
-20
View File
@@ -133,26 +133,6 @@ namespace Umbraco.Core.Models
Key = Guid.NewGuid();
}
/// <summary>
/// Method to call when Entity is being updated
/// </summary>
/// <remarks>Modified Date is set and a new Version guid is set</remarks>
internal override void UpdatingEntity()
{
base.UpdatingEntity();
}
public override object DeepClone()
{
var clone = (ContentType)base.DeepClone();
var propertyGroups = PropertyGroups.Select(x => (PropertyGroup)x.DeepClone()).ToList();
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
//set the property types that are not part of a group
clone.PropertyTypes = PropertyTypeCollection
.Where(x => x.PropertyGroupId == null)
.Select(x => (PropertyType)x.DeepClone()).ToList();
return clone;
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
+31 -1
View File
@@ -351,7 +351,9 @@ namespace Umbraco.Core.Models
/// <summary>
/// List of PropertyGroups available on this ContentType
/// </summary>
/// <remarks>A PropertyGroup corresponds to a Tab in the UI</remarks>
/// <remarks>
/// A PropertyGroup corresponds to a Tab in the UI
/// </remarks>
[DataMember]
public virtual PropertyGroupCollection PropertyGroups
{
@@ -367,7 +369,13 @@ namespace Umbraco.Core.Models
/// List of PropertyTypes available on this ContentType.
/// This list aggregates PropertyTypes across the PropertyGroups.
/// </summary>
/// <remarks>
/// Marked as DoNotClone because the result of this property is not the natural result of the data, it is
/// a union of data so when auto-cloning if the setter is used it will be setting the unnatural result of the
/// data. We manually clone this instead.
/// </remarks>
[IgnoreDataMember]
[DoNotClone]
public virtual IEnumerable<PropertyType> PropertyTypes
{
get
@@ -383,6 +391,14 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Returns the property type collection containing types that are non-groups - used for tests
/// </summary>
internal IEnumerable<PropertyType> NonGroupedPropertyTypes
{
get { return _propertyTypes; }
}
/// <summary>
/// A boolean flag indicating if a property type has been removed from this instance.
/// </summary>
/// <remarks>
@@ -579,5 +595,19 @@ namespace Umbraco.Core.Models
propertyType.ResetDirtyProperties();
}
}
public override object DeepClone()
{
var clone = (ContentTypeBase)base.DeepClone();
//need to manually wire up the event handlers for the property type collections - we've ensured
// its ignored from the auto-clone process because its return values are unions, not raw and
// we end up with duplicates, see: http://issues.umbraco.org/issue/U4-4842
clone._propertyTypes = (PropertyTypeCollection)_propertyTypes.DeepClone();
clone._propertyTypes.CollectionChanged += clone.PropertyTypesChanged;
return clone;
}
}
}
+23 -1
View File
@@ -2,9 +2,29 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used to attribute properties that have a setter and are a reference type
/// that should be ignored for cloning when using the DeepCloneHelper
/// </summary>
/// <remarks>
///
/// This attribute must be used:
/// * when the property is backed by a field but the result of the property is the un-natural data stored in the field
///
/// This attribute should not be used:
/// * when the property is virtual
/// * when the setter performs additional required logic other than just setting the underlying field
///
/// </remarks>
internal class DoNotCloneAttribute : Attribute
{
}
public static class DeepCloneHelper
{
/// <summary>
@@ -25,8 +45,10 @@ namespace Umbraco.Core.Models
var refProperties = inputType.GetProperties()
.Where(x =>
//is not attributed with the ignore clone attribute
Attribute.GetCustomAttribute(x, typeof(DoNotCloneAttribute)) == null
//reference type but not string
x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
&& x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
//settable
&& x.CanWrite
//non-indexed
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Models.EntityBase
/// <summary>
/// Tracks the properties that have changed
/// </summary>
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
private IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
/// <summary>
/// Tracks the properties that we're changed before the last commit (or last call to ResetDirtyProperties)
@@ -86,7 +86,9 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
public void ForgetPreviouslyDirtyProperties()
{
_lastPropertyChangedInfo.Clear();
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
_lastPropertyChangedInfo = new Dictionary<string, bool>();
}
/// <summary>
@@ -119,7 +121,9 @@ namespace Umbraco.Core.Models.EntityBase
_lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
}
_propertyChangedInfo.Clear();
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
_propertyChangedInfo = new Dictionary<string, bool>();
}
/// <summary>
@@ -1,3 +1,5 @@
using System;
namespace Umbraco.Core.Models
{
/// <summary>
@@ -56,5 +58,8 @@ namespace Umbraco.Core.Models
/// <para>It has been fully prepared and processed by the appropriate converter.</para>
/// </remarks>
object XPathValue { get; }
string Alias { get; }
Guid Version { get; }
}
}
+35 -15
View File
@@ -59,9 +59,9 @@ namespace Umbraco.Core.Models.Membership
private IUserType _userType;
private string _name;
private Type _userTypeKey;
private readonly List<string> _addedSections;
private readonly List<string> _removedSections;
private readonly ObservableCollection<string> _sectionCollection;
private List<string> _addedSections;
private List<string> _removedSections;
private ObservableCollection<string> _sectionCollection;
private int _sessionTimeout;
private int _startContentId;
private int _startMediaId;
@@ -244,7 +244,10 @@ namespace Umbraco.Core.Models.Membership
public void RemoveAllowedSection(string sectionAlias)
{
_sectionCollection.Remove(sectionAlias);
if (_sectionCollection.Contains(sectionAlias))
{
_sectionCollection.Remove(sectionAlias);
}
}
public void AddAllowedSection(string sectionAlias)
@@ -423,24 +426,41 @@ namespace Umbraco.Core.Models.Membership
if (e.Action == NotifyCollectionChangedAction.Add)
{
//remove from the removed/added sections (since people could add/remove all they want in one request)
_removedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
_addedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
var item = e.NewItems.Cast<string>().First();
//add to the added sections
_addedSections.Add(e.NewItems.Cast<string>().First());
if (_addedSections.Contains(item) == false)
{
_addedSections.Add(item);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
//remove from the removed/added sections (since people could add/remove all they want in one request)
_removedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
_addedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
var item = e.OldItems.Cast<string>().First();
if (_removedSections.Contains(item) == false)
{
_removedSections.Add(item);
}
//add to the added sections
_removedSections.Add(e.OldItems.Cast<string>().First());
}
}
public override object DeepClone()
{
var clone = (User)base.DeepClone();
//need to create new collections otherwise they'll get copied by ref
clone._addedSections = new List<string>();
clone._removedSections = new List<string>();
clone._sectionCollection = new ObservableCollection<string>(_sectionCollection.ToList());
//re-create the event handler
clone._sectionCollection.CollectionChanged += clone.SectionCollectionChanged;
clone.ResetDirtyProperties(false);
return clone;
}
/// <summary>
/// Internal class used to wrap the user in a profile
/// </summary>
+20 -1
View File
@@ -3,8 +3,15 @@
/// <summary>
/// Represents a stored pre-value field value
/// </summary>
public class PreValue
public class PreValue : IDeepCloneable
{
public PreValue(int id, string value, int sortOrder)
{
Id = id;
Value = value;
SortOrder = sortOrder;
}
public PreValue(int id, string value)
{
Value = value;
@@ -25,5 +32,17 @@
/// The database id for the pre-value field value
/// </summary>
public int Id { get; private set; }
/// <summary>
/// The sort order stored for the pre-value field value
/// </summary>
public int SortOrder { get; private set; }
public virtual object DeepClone()
{
//Memberwise clone on PreValue will work since it doesn't have any deep elements
var clone = (PreValue)MemberwiseClone();
return clone;
}
}
}
+17 -1
View File
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Models
/// Most legacy property editors won't support the dictionary format but new property editors should always use the dictionary format.
/// In order to get overrideable pre-values working we need a dictionary since we'll have to reference a pre-value by a key.
/// </remarks>
public class PreValueCollection
public class PreValueCollection : IDeepCloneable
{
private IDictionary<string, PreValue> _preValuesAsDictionary;
private IEnumerable<PreValue> _preValuesAsArray;
@@ -82,5 +82,21 @@ namespace Umbraco.Core.Models
}
return result;
}
public object DeepClone()
{
var clone = (PreValueCollection) MemberwiseClone();
if (_preValuesAsArray != null)
{
clone._preValuesAsArray = _preValuesAsArray.Select(x => (PreValue)x.DeepClone()).ToArray();
}
if (_preValuesAsDictionary != null)
{
clone._preValuesAsDictionary = _preValuesAsDictionary.ToDictionary(x => x.Key, x => (PreValue)x.Value.DeepClone());
}
return clone;
}
}
}
@@ -27,5 +27,8 @@ namespace Umbraco.Core.Models.PublishedContent
public abstract object DataValue { get; }
public abstract object Value { get; }
public abstract object XPathValue { get; }
public string Alias { get { return PropertyTypeAlias; } }
public Guid Version { get { return Guid.Empty; } }
}
}
@@ -49,6 +49,7 @@ namespace Umbraco.Core.ObjectResolution
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list
/// <remarks>If <paramref name="scope"/> is per HttpRequest then there must be a current HttpContext.</remarks>
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
/// </summary>
protected LazyManyObjectsResolverBase(IEnumerable<Lazy<Type>> lazyTypeList, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
: this(scope)
{
@@ -108,7 +109,7 @@ namespace Umbraco.Core.ObjectResolution
/// Gets a value indicating whether the resolver has resolved types to create instances from.
/// </summary>
/// <remarks>To be used in unit tests.</remarks>
internal bool HasResolvedTypes
public bool HasResolvedTypes
{
get
{
@@ -128,9 +128,9 @@ namespace Umbraco.Core.Persistence.Caching
public void Save(Type type, IEntity entity)
{
//IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259
entity = (IEntity)entity.DeepClone();
var clone = (IEntity)entity.DeepClone();
var key = GetCompositeId(type, entity.Id);
var key = GetCompositeId(type, clone.Id);
_keyTracker.TryAdd(key);
@@ -139,11 +139,11 @@ namespace Umbraco.Core.Persistence.Caching
if (_memoryCache != null)
{
_memoryCache.Set(key, entity, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) });
_memoryCache.Set(key, clone, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) });
}
else
{
HttpRuntime.Cache.Insert(key, entity, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
HttpRuntime.Cache.Insert(key, clone, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
}
}
@@ -74,7 +74,7 @@ namespace Umbraco.Core.Persistence.Factories
{
AppAlias = app
};
if (entity.Id != null)
if (entity.HasIdentity)
{
appDto.UserId = (int) entity.Id;
}
@@ -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");
}
}
}
@@ -295,8 +295,8 @@ AND umbracoNode.id <> @id",
var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeySearch<PreValueCollection>(GetPrefixedCacheKey(dataTypeId));
if (cached != null && cached.Any())
{
//return from the cache
return cached.First();
//return from the cache, ensure it's a cloned result
return (PreValueCollection)cached.First().DeepClone();
}
l.UpgradeToWriteLock();
@@ -158,7 +158,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
"UPDATE cmsDocument SET templateId = NULL WHERE nodeId = @Id",
"UPDATE cmsDocument SET templateId = NULL WHERE templateId = @Id",
"DELETE FROM cmsDocumentType WHERE templateNodeId = @Id",
"DELETE FROM cmsTemplate WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id"
@@ -211,9 +211,19 @@ namespace Umbraco.Core.Persistence.Repositories
var user = (User)entity;
if (user.IsPropertyDirty("AllowedSections"))
{
//now we need to delete any applications that have been removed
foreach (var section in user.RemovedSections)
{
//we need to manually delete thsi record because it has a composite key
Database.Delete<User2AppDto>("WHERE app=@Section AND " + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("user") + "=@UserId",
new { Section = section, UserId = (int)user.Id });
}
//for any that exist on the object, we need to determine if we need to update or insert
//NOTE: the User2AppDtos collection wil always be equal to the User.AllowedSections
foreach (var sectionDto in userDto.User2AppDtos)
{
//if something has been added then insert it
if (user.AddedSections.Contains(sectionDto.AppAlias))
{
//we need to insert since this was added
@@ -227,13 +237,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
//now we need to delete any applications that have been removed
foreach (var section in user.RemovedSections)
{
//we need to manually delete thsi record because it has a composite key
Database.Delete<User2AppDto>("WHERE app=@Section AND " + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("user") + "=@UserId",
new { Section = section, UserId = (int)user.Id });
}
}
((ICanBeDirty)entity).ResetDirtyProperties();
+28 -16
View File
@@ -43,9 +43,9 @@ namespace Umbraco.Core
/// file is cached temporarily until app startup completes.
/// </summary>
/// <param name="appContext"></param>
/// <param name="detectBinChanges"></param>
internal PluginManager(ApplicationContext appContext, bool detectBinChanges = true)
: this(detectBinChanges)
/// <param name="detectChanges"></param>
internal PluginManager(ApplicationContext appContext, bool detectChanges = true)
: this(detectChanges)
{
if (appContext == null) throw new ArgumentNullException("appContext");
_appContext = appContext;
@@ -54,11 +54,11 @@ namespace Umbraco.Core
/// <summary>
/// Creates a new PluginManager
/// </summary>
/// <param name="detectCodeChanges">
/// If true will detect changes in the /bin folder and therefor load plugins from the
/// <param name="detectChanges">
/// If true will detect changes in the /bin folder, app_code, etc... and therefor load plugins from the
/// cached plugins file if one is found. If false will never use the cache file for plugins
/// </param>
internal PluginManager(bool detectCodeChanges = true)
internal PluginManager(bool detectChanges = true)
{
_tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
//create the folder if it doesn't exist
@@ -67,29 +67,41 @@ namespace Umbraco.Core
Directory.CreateDirectory(_tempFolder);
}
var pluginListFile = GetPluginListFilePath();
//this is a check for legacy changes, before we didn't store the TypeResolutionKind in the file which was a mistake,
//so we need to detect if the old file is there without this attribute, if it is then we delete it
if (DetectLegacyPluginListFile())
{
var filePath = GetPluginListFilePath();
File.Delete(filePath);
File.Delete(pluginListFile);
}
if (detectCodeChanges)
if (detectChanges)
{
//first check if the cached hash is 0, if it is then we ne
//do the check if they've changed
HaveAssembliesChanged = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == 0;
RequiresRescanning = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == 0;
//if they have changed, we need to write the new file
if (HaveAssembliesChanged)
if (RequiresRescanning)
{
//if the hash has changed, clear out the persisted list no matter what, this will force
// rescanning of all plugin types including lazy ones.
// http://issues.umbraco.org/issue/U4-4789
File.Delete(pluginListFile);
WriteCachePluginsHash();
}
}
else
{
//if the hash has changed, clear out the persisted list no matter what, this will force
// rescanning of all plugin types including lazy ones.
// http://issues.umbraco.org/issue/U4-4789
File.Delete(pluginListFile);
//always set to true if we're not detecting (generally only for testing)
HaveAssembliesChanged = true;
RequiresRescanning = true;
}
}
@@ -129,9 +141,9 @@ namespace Umbraco.Core
/// <summary>
/// Returns a bool if the assemblies in the /bin have changed since they were last hashed.
/// Returns a bool if the assemblies in the /bin, app_code, global.asax, etc... have changed since they were last hashed.
/// </summary>
internal bool HaveAssembliesChanged { get; private set; }
internal bool RequiresRescanning { get; private set; }
/// <summary>
/// Returns the currently cached hash value of the scanned assemblies in the /bin folder. Returns 0
@@ -327,7 +339,7 @@ namespace Umbraco.Core
/// <remarks>
/// Generally only used for resetting cache, for example during the install process
/// </remarks>
internal void ClearPluginCache()
public void ClearPluginCache()
{
var path = GetPluginListFilePath();
if (File.Exists(path))
@@ -646,7 +658,7 @@ namespace Umbraco.Core
//we first need to look into our cache file (this has nothing to do with the 'cacheResult' parameter which caches in memory).
//if assemblies have not changed and the cache file actually exists, then proceed to try to lookup by the cache file.
if (HaveAssembliesChanged == false && File.Exists(GetPluginListFilePath()))
if (RequiresRescanning == false && File.Exists(GetPluginListFilePath()))
{
var fileCacheResult = TryGetCachedPluginsFromFile<T>(resolutionType);
+2 -2
View File
@@ -1263,8 +1263,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
@@ -205,10 +205,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);
@@ -219,8 +220,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>
+1 -1
View File
@@ -135,7 +135,7 @@ namespace Umbraco.Core
//this is from SqlMetal and just makes it a bit of fun to allow pluralisation
public static string MakePluralName(this string name)
{
if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)))
if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)))
{
name = name + "es";
return name;
+8
View File
@@ -224,6 +224,14 @@ namespace Umbraco.Tests.Models
{
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(content, null));
}
//need to ensure the event handlers are wired
var asDirty = (ICanBeDirty)clone;
Assert.IsFalse(asDirty.IsPropertyDirty("Properties"));
clone.Properties.Add(new Property(1, Guid.NewGuid(), new PropertyType(Guid.NewGuid(), DataTypeDatabaseType.Ntext) { Alias = "blah" }, "blah"));
Assert.IsTrue(asDirty.IsPropertyDirty("Properties"));
}
[Test]
+29 -2
View File
@@ -4,6 +4,7 @@ using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Serialization;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
namespace Umbraco.Tests.Models
@@ -11,6 +12,18 @@ namespace Umbraco.Tests.Models
[TestFixture]
public class ContentTypeTests
{
[SetUp]
public void Init()
{
TestHelper.EnsureUmbracoSettingsConfig();
}
[TearDown]
public void Dispose()
{
TestHelper.CleanUmbracoSettingsConfig();
}
[Test]
public void Can_Deep_Clone_Content_Type_Sort()
{
@@ -140,19 +153,22 @@ namespace Umbraco.Tests.Models
Assert.AreNotSame(clone.AllowedTemplates.ElementAt(index), contentType.AllowedTemplates.ElementAt(index));
Assert.AreEqual(clone.AllowedTemplates.ElementAt(index), contentType.AllowedTemplates.ElementAt(index));
}
Assert.AreNotSame(clone.PropertyGroups, contentType.PropertyGroups);
Assert.AreEqual(clone.PropertyGroups.Count, contentType.PropertyGroups.Count);
for (var index = 0; index < contentType.PropertyGroups.Count; index++)
{
Assert.AreNotSame(clone.PropertyGroups[index], contentType.PropertyGroups[index]);
Assert.AreEqual(clone.PropertyGroups[index], contentType.PropertyGroups[index]);
}
Assert.AreNotSame(clone.PropertyTypes, contentType.PropertyTypes);
Assert.AreEqual(clone.PropertyTypes.Count(), contentType.PropertyTypes.Count());
Assert.AreEqual(0, ((ContentTypeBase)clone).NonGroupedPropertyTypes.Count());
for (var index = 0; index < contentType.PropertyTypes.Count(); index++)
{
Assert.AreNotSame(clone.PropertyTypes.ElementAt(index), contentType.PropertyTypes.ElementAt(index));
Assert.AreEqual(clone.PropertyTypes.ElementAt(index), contentType.PropertyTypes.ElementAt(index));
}
Assert.AreEqual(clone.CreateDate, contentType.CreateDate);
Assert.AreEqual(clone.CreatorId, contentType.CreatorId);
Assert.AreEqual(clone.Key, contentType.Key);
@@ -167,13 +183,24 @@ namespace Umbraco.Tests.Models
Assert.AreEqual(clone.Thumbnail, contentType.Thumbnail);
Assert.AreEqual(clone.Icon, contentType.Icon);
Assert.AreEqual(clone.IsContainer, contentType.IsContainer);
//This double verifies by reflection
var allProps = clone.GetType().GetProperties();
foreach (var propertyInfo in allProps)
{
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(contentType, null));
}
//need to ensure the event handlers are wired
var asDirty = (ICanBeDirty)clone;
Assert.IsFalse(asDirty.IsPropertyDirty("PropertyTypes"));
clone.AddPropertyType(new PropertyType(Guid.NewGuid(), DataTypeDatabaseType.Nvarchar) { Alias = "blah" });
Assert.IsTrue(asDirty.IsPropertyDirty("PropertyTypes"));
Assert.IsFalse(asDirty.IsPropertyDirty("PropertyGroups"));
clone.AddPropertyGroup("hello");
Assert.IsTrue(asDirty.IsPropertyDirty("PropertyGroups"));
}
[Test]
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Models;
namespace Umbraco.Tests.Models
{
[TestFixture]
public class PreValueCollectionTests
{
[Test]
public void Can_Deep_Clone()
{
var d = new PreValueCollection(new Dictionary<string, PreValue>
{
{"blah1", new PreValue(1, "test1", 1)},
{"blah2", new PreValue(2, "test1", 3)},
{"blah3", new PreValue(3, "test1", 2)}
});
var a = new PreValueCollection(new[]
{
new PreValue(1, "test1", 1),
new PreValue(2, "test1", 3),
new PreValue(3, "test1", 2)
});
var clone1 = (PreValueCollection)d.DeepClone();
var clone2 = (PreValueCollection)a.DeepClone();
Action<PreValueCollection, PreValueCollection> assert = (orig, clone) =>
{
Assert.AreNotSame(orig, clone);
var oDic = orig.FormatAsDictionary();
var cDic = clone.FormatAsDictionary();
Assert.AreEqual(oDic.Keys.Count(), cDic.Keys.Count());
foreach (var k in oDic.Keys)
{
Assert.AreNotSame(oDic[k], cDic[k]);
Assert.AreEqual(oDic[k].Id, cDic[k].Id);
Assert.AreEqual(oDic[k].SortOrder, cDic[k].SortOrder);
Assert.AreEqual(oDic[k].Value, cDic[k].Value);
}
};
assert(d, clone1);
assert(a, clone2);
}
}
}
+15
View File
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Serialization;
@@ -39,6 +40,8 @@ namespace Umbraco.Tests.Models
Username = "username"
};
item.AddAllowedSection("test");
var clone = (User)item.DeepClone();
Assert.AreNotSame(clone, item);
@@ -46,6 +49,7 @@ namespace Umbraco.Tests.Models
Assert.AreNotSame(clone.UserType, item.UserType);
Assert.AreEqual(clone.UserType, item.UserType);
Assert.AreEqual(clone.AllowedSections.Count(), item.AllowedSections.Count());
//Verify normal properties with reflection
var allProps = clone.GetType().GetProperties();
@@ -53,6 +57,17 @@ namespace Umbraco.Tests.Models
{
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
}
//ensure internal collections are differet
Assert.AreNotSame(item.AddedSections, clone.AddedSections);
Assert.AreNotSame(item.RemovedSections, clone.RemovedSections);
//ensure event handlers are still wired on clone
clone.AddAllowedSection("blah");
Assert.AreEqual(1, clone.AddedSections.Count());
clone.RemoveAllowedSection("blah");
Assert.AreEqual(1, clone.RemovedSections.Count());
}
[Test]
@@ -3,6 +3,7 @@ using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
@@ -10,6 +11,7 @@ using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
namespace Umbraco.Tests.Persistence.Repositories
{
@@ -37,10 +39,13 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
// Act
var repository = RepositoryResolver.Current.ResolveByType<ITemplateRepository>(unitOfWork);
using (var repository = RepositoryResolver.Current.ResolveByType<ITemplateRepository>(unitOfWork))
{
// Assert
Assert.That(repository, Is.Not.Null);
}
// Assert
Assert.That(repository, Is.Not.Null);
}
[Test]
@@ -51,10 +56,13 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
// Act
var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem);
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
// Assert
Assert.That(repository, Is.Not.Null);
}
// Assert
Assert.That(repository, Is.Not.Null);
}
[Test]
@@ -63,16 +71,18 @@ namespace Umbraco.Tests.Persistence.Repositories
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem);
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
// Act
var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
// Act
var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
//Assert
Assert.That(repository.Get("test"), Is.Not.Null);
Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True);
//Assert
Assert.That(repository.Get("test"), Is.Not.Null);
Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True);
}
}
[Test]
@@ -81,22 +91,25 @@ namespace Umbraco.Tests.Persistence.Repositories
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem);
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
// Act
var template = new Template("test-updated-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
// Act
var template = new Template("test-updated-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
template.Content = @"<%@ Master Language=""VB"" %>";
repository.AddOrUpdate(template);
unitOfWork.Commit();
template.Content = @"<%@ Master Language=""VB"" %>";
repository.AddOrUpdate(template);
unitOfWork.Commit();
var updated = repository.Get("test");
var updated = repository.Get("test");
// Assert
Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True);
Assert.That(updated.Content, Is.EqualTo(@"<%@ Master Language=""VB"" %>"));
}
// Assert
Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True);
Assert.That(updated.Content, Is.EqualTo(@"<%@ Master Language=""VB"" %>"));
}
[Test]
@@ -105,19 +118,63 @@ namespace Umbraco.Tests.Persistence.Repositories
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem);
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
// Act
var templates = repository.Get("test");
repository.Delete(templates);
unitOfWork.Commit();
// Act
var templates = repository.Get("test");
repository.Delete(templates);
unitOfWork.Commit();
// Assert
Assert.IsNull(repository.Get("test"));
}
// Assert
Assert.IsNull(repository.Get("test"));
}
[Test]
public void Can_Perform_Delete_When_Assigned_To_Doc()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current);
var contentTypeRepository = new ContentTypeRepository(unitOfWork, NullCacheProvider.Current, templateRepository);
var contentRepo = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, CacheHelper.CreateDisabledCacheHelper());
using (contentRepo)
{
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");
var textpage = MockedContent.CreateSimpleContent(contentType);
contentTypeRepository.AddOrUpdate(contentType);
contentRepo.AddOrUpdate(textpage);
unitOfWork.Commit();
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" };
repository.AddOrUpdate(template);
unitOfWork.Commit();
textpage.Template = template;
contentRepo.AddOrUpdate(textpage);
unitOfWork.Commit();
// Act
var templates = repository.Get("test");
repository.Delete(templates);
unitOfWork.Commit();
// Assert
Assert.IsNull(repository.Get("test"));
}
}
}
[Test]
@@ -126,27 +183,30 @@ namespace Umbraco.Tests.Persistence.Repositories
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem);
var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" };
var child = new Template("test-child-masterpage.master", "child", "child") { Content = @"<%@ Master Language=""C#"" %>" };
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" };
var child = new Template("test-child-masterpage.master", "child", "child") { Content = @"<%@ Master Language=""C#"" %>" };
var baby = new Template("test-baby-masterpage.master", "baby", "baby") { Content = @"<%@ Master Language=""C#"" %>" };
child.MasterTemplateAlias = parent.Alias;
child.MasterTemplateId = new Lazy<int>(() => parent.Id);
baby.MasterTemplateAlias = child.Alias;
baby.MasterTemplateId = new Lazy<int>(() => child.Id);
repository.AddOrUpdate(parent);
repository.AddOrUpdate(child);
repository.AddOrUpdate(baby);
unitOfWork.Commit();
child.MasterTemplateAlias = parent.Alias;
child.MasterTemplateId = new Lazy<int>(() => parent.Id);
baby.MasterTemplateAlias = child.Alias;
baby.MasterTemplateId = new Lazy<int>(() => child.Id);
repository.AddOrUpdate(parent);
repository.AddOrUpdate(child);
repository.AddOrUpdate(baby);
unitOfWork.Commit();
// Act
var templates = repository.Get("parent");
repository.Delete(templates);
unitOfWork.Commit();
// Act
var templates = repository.Get("parent");
repository.Delete(templates);
unitOfWork.Commit();
// Assert
Assert.IsNull(repository.Get("test"));
// Assert
Assert.IsNull(repository.Get("test"));
}
}
[Test]
@@ -155,66 +215,69 @@ namespace Umbraco.Tests.Persistence.Repositories
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem);
using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem))
{
var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" };
var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" };
var child1 = new Template("test-child1-masterpage.master", "child1", "child1") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler1 = new Template("test-toddler1-masterpage.master", "toddler1", "toddler1") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler2 = new Template("test-toddler2-masterpage.master", "toddler2", "toddler2") { Content = @"<%@ Master Language=""C#"" %>" };
var baby1 = new Template("test-baby1-masterpage.master", "baby1", "baby1") { Content = @"<%@ Master Language=""C#"" %>" };
var child1 = new Template("test-child1-masterpage.master", "child1", "child1") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler1 = new Template("test-toddler1-masterpage.master", "toddler1", "toddler1") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler2 = new Template("test-toddler2-masterpage.master", "toddler2", "toddler2") { Content = @"<%@ Master Language=""C#"" %>" };
var baby1 = new Template("test-baby1-masterpage.master", "baby1", "baby1") { Content = @"<%@ Master Language=""C#"" %>" };
var child2 = new Template("test-child2-masterpage.master", "child2", "child2") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler3 = new Template("test-toddler3-masterpage.master", "toddler3", "toddler3") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler4 = new Template("test-toddler4-masterpage.master", "toddler4", "toddler4") { Content = @"<%@ Master Language=""C#"" %>" };
var baby2 = new Template("test-baby2-masterpage.master", "baby2", "baby2") { Content = @"<%@ Master Language=""C#"" %>" };
var child2 = new Template("test-child2-masterpage.master", "child2", "child2") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler3 = new Template("test-toddler3-masterpage.master", "toddler3", "toddler3") { Content = @"<%@ Master Language=""C#"" %>" };
var toddler4 = new Template("test-toddler4-masterpage.master", "toddler4", "toddler4") { Content = @"<%@ Master Language=""C#"" %>" };
var baby2 = new Template("test-baby2-masterpage.master", "baby2", "baby2") { Content = @"<%@ Master Language=""C#"" %>" };
child1.MasterTemplateAlias = parent.Alias;
child1.MasterTemplateId = new Lazy<int>(() => parent.Id);
child2.MasterTemplateAlias = parent.Alias;
child2.MasterTemplateId = new Lazy<int>(() => parent.Id);
child1.MasterTemplateAlias = parent.Alias;
child1.MasterTemplateId = new Lazy<int>(() => parent.Id);
child2.MasterTemplateAlias = parent.Alias;
child2.MasterTemplateId = new Lazy<int>(() => parent.Id);
toddler1.MasterTemplateAlias = child1.Alias;
toddler1.MasterTemplateId = new Lazy<int>(() => child1.Id);
toddler2.MasterTemplateAlias = child1.Alias;
toddler2.MasterTemplateId = new Lazy<int>(() => child1.Id);
toddler1.MasterTemplateAlias = child1.Alias;
toddler1.MasterTemplateId = new Lazy<int>(() => child1.Id);
toddler2.MasterTemplateAlias = child1.Alias;
toddler2.MasterTemplateId = new Lazy<int>(() => child1.Id);
toddler3.MasterTemplateAlias = child2.Alias;
toddler3.MasterTemplateId = new Lazy<int>(() => child2.Id);
toddler4.MasterTemplateAlias = child2.Alias;
toddler4.MasterTemplateId = new Lazy<int>(() => child2.Id);
toddler3.MasterTemplateAlias = child2.Alias;
toddler3.MasterTemplateId = new Lazy<int>(() => child2.Id);
toddler4.MasterTemplateAlias = child2.Alias;
toddler4.MasterTemplateId = new Lazy<int>(() => child2.Id);
baby1.MasterTemplateAlias = toddler2.Alias;
baby1.MasterTemplateId = new Lazy<int>(() => toddler2.Id);
baby1.MasterTemplateAlias = toddler2.Alias;
baby1.MasterTemplateId = new Lazy<int>(() => toddler2.Id);
baby2.MasterTemplateAlias = toddler4.Alias;
baby2.MasterTemplateId = new Lazy<int>(() => toddler4.Id);
baby2.MasterTemplateAlias = toddler4.Alias;
baby2.MasterTemplateId = new Lazy<int>(() => toddler4.Id);
repository.AddOrUpdate(parent);
repository.AddOrUpdate(child1);
repository.AddOrUpdate(child2);
repository.AddOrUpdate(toddler1);
repository.AddOrUpdate(toddler2);
repository.AddOrUpdate(toddler3);
repository.AddOrUpdate(toddler4);
repository.AddOrUpdate(baby1);
repository.AddOrUpdate(baby2);
unitOfWork.Commit();
repository.AddOrUpdate(parent);
repository.AddOrUpdate(child1);
repository.AddOrUpdate(child2);
repository.AddOrUpdate(toddler1);
repository.AddOrUpdate(toddler2);
repository.AddOrUpdate(toddler3);
repository.AddOrUpdate(toddler4);
repository.AddOrUpdate(baby1);
repository.AddOrUpdate(baby2);
unitOfWork.Commit();
// Act
var rootNode = repository.GetTemplateNode("parent");
// Act
var rootNode = repository.GetTemplateNode("parent");
// Assert
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "parent"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child1"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child2"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler1"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler2"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler3"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler4"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby1"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby2"));
// Assert
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "parent"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child1"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child2"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler1"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler2"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler3"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler4"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby1"));
Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby2"));
}
}
//[Test]
@@ -231,6 +231,9 @@ namespace Umbraco.Tests.PublishedContent
public object Value { get; set; }
public bool HasValue { get; set; }
public object XPathValue { get; set; }
public string Alias { get { return PropertyTypeAlias; } }
public Guid Version { get { return Guid.Empty; } }
}
[PublishedContentModel("ContentType2")]
@@ -387,6 +387,41 @@ namespace Umbraco.Tests.Services
Assert.That(user.DefaultPermissions, Is.EqualTo(userType.Permissions));
}
[Test]
public void Can_Add_And_Remove_Sections_From_User()
{
var userType = ServiceContext.UserService.GetUserTypeByAlias("admin");
var user1 = ServiceContext.UserService.CreateUserWithIdentity("test1", "test1@test.com", userType);
//adds some allowed sections
user1.AddAllowedSection("test1");
user1.AddAllowedSection("test2");
user1.AddAllowedSection("test3");
user1.AddAllowedSection("test4");
ServiceContext.UserService.Save(user1);
var result1 = ServiceContext.UserService.GetUserById((int)user1.Id);
Assert.AreEqual(4, result1.AllowedSections.Count());
//simulate clearing the sections
foreach (var s in user1.AllowedSections)
{
result1.RemoveAllowedSection(s);
}
//now just re-add a couple
result1.AddAllowedSection("test3");
result1.AddAllowedSection("test4");
ServiceContext.UserService.Save(result1);
//assert
//re-get
result1 = ServiceContext.UserService.GetUserById((int)user1.Id);
Assert.AreEqual(2, result1.AllowedSections.Count());
}
[Test]
public void Can_Remove_Section_From_All_Assigned_Users()
{
+1
View File
@@ -173,6 +173,7 @@
<Compile Include="Models\LanguageTests.cs" />
<Compile Include="Models\MemberGroupTests.cs" />
<Compile Include="Models\MemberTests.cs" />
<Compile Include="Models\PreValueCollectionTests.cs" />
<Compile Include="Models\PropertyGroupTests.cs" />
<Compile Include="Models\PropertyTypeTests.cs" />
<Compile Include="Models\RelationTests.cs" />
+2 -2
View File
@@ -2674,9 +2674,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>6200</DevelopmentServerPort>
<DevelopmentServerPort>6210</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:6200</IISUrl>
<IISUrl>http://localhost:6210</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -180,6 +180,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>" +
@@ -7,6 +7,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Caching;
using umbraco.interfaces;
using System.Linq;
@@ -155,6 +156,7 @@ namespace Umbraco.Web.Cache
payloads.ForEach(payload =>
{
//if there's no path, then just use id (this will occur on permanent deletion like emptying recycle bin)
if (payload.Path.IsNullOrWhiteSpace())
{
@@ -165,6 +167,12 @@ namespace Umbraco.Web.Cache
{
foreach (var idPart in payload.Path.Split(','))
{
int idPartAsInt;
if (int.TryParse(idPart, out idPartAsInt))
{
RuntimeCacheProvider.Current.Delete(typeof(IMedia), idPartAsInt);
}
ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(
string.Format("{0}_{1}_True", CacheKeys.MediaCacheKey, idPart));
@@ -3,22 +3,16 @@ using System.Web.Script.Serialization;
using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using System.Linq;
using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Sync;
namespace Umbraco.Web.Cache
{
/// <summary>
/// A cache refresher used for non-published content, this is primarily to notify Examine indexes to update
/// A cache refresher used for non-published content, this is primarily to notify Examine indexes to update and to refresh the RuntimeCacheRefresher
/// </summary>
public sealed class UnpublishedPageCacheRefresher : TypedCacheRefresherBase<UnpublishedPageCacheRefresher, IContent>, IJsonCacheRefresher
{
//NOTE: There is no functionality for this cache refresher, it is here simply to emit events on each server for which examine
// binds to. We could put the Examine index functionality in here but we've kept it all in the ExamineEvents class so that all of
// the logic is in one place. In the future we may put the examine logic in a cache refresher instead (that would make sense) but we'd
// want to get this done before making more cache refreshers:
// http://issues.umbraco.org/issue/U4-2633
protected override UnpublishedPageCacheRefresher Instance
{
get { return this; }
@@ -78,12 +72,48 @@ namespace Umbraco.Web.Cache
#endregion
public override void RefreshAll()
{
RuntimeCacheProvider.Current.Clear(typeof(IContent));
base.RefreshAll();
}
public override void Refresh(int id)
{
RuntimeCacheProvider.Current.Delete(typeof(IContent), id);
base.Refresh(id);
}
public override void Remove(int id)
{
RuntimeCacheProvider.Current.Delete(typeof(IContent), id);
base.Remove(id);
}
public override void Refresh(IContent instance)
{
RuntimeCacheProvider.Current.Delete(typeof(IContent), instance.Id);
base.Refresh(instance);
}
public override void Remove(IContent instance)
{
RuntimeCacheProvider.Current.Delete(typeof(IContent), instance.Id);
base.Remove(instance);
}
/// <summary>
/// Implement the IJsonCacheRefresher so that we can bulk delete the cache based on multiple IDs for when the recycle bin is emptied
/// </summary>
/// <param name="jsonPayload"></param>
public void Refresh(string jsonPayload)
{
foreach (var payload in DeserializeFromJsonPayload(jsonPayload))
{
RuntimeCacheProvider.Current.Delete(typeof(IContent), payload.Id);
}
OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
}
@@ -47,7 +47,7 @@ namespace Umbraco.Web.Models
var prop = GetProperty(Constants.Conventions.Media.File);
if (prop == null)
throw new NotSupportedException("Cannot resolve a Url for a media item when there is no 'umbracoFile' property defined.");
_url = prop.Value.ToString();
_url = prop.Value == null ? "" : prop.Value.ToString();
break;
default:
throw new NotSupportedException();
@@ -328,7 +328,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
//lets check if the alias does not exist on the document.
//NOTE: Examine will not index empty values and we do not output empty XML Elements to the cache - either of these situations
// would mean that the property is missing from the collection whether we are getting the value from Examine or from the library media cache.
if (dd.Properties.All(x => x.PropertyTypeAlias != alias))
if (dd.Properties.All(x => x.PropertyTypeAlias.InvariantEquals(alias) == false))
{
return null;
}
@@ -464,6 +464,10 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// I'm not sure that _properties contains all properties including those without a value,
// neither that GetProperty will return a property without a value vs. null... @zpqrtbnk
// List of properties that will appear in the XML and do not match
// anything in the ContentType, so they must be ignored.
private static readonly string[] IgnoredKeys = { "version", "isDoc", "key" };
public DictionaryPublishedContent(
IDictionary<string, string> valueDictionary,
Func<DictionaryPublishedContent, IPublishedContent> getParent,
@@ -509,47 +513,36 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
_contentType = PublishedContentType.Get(PublishedItemType.Media, _documentTypeAlias);
_properties = new Collection<IPublishedContentProperty>();
//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
{
IPublishedContentProperty property;
// must ignore that one
if (i.Key == "version" || i.Key == "isDoc") continue;
if (i.Key.InvariantStartsWith("__"))
{
// no type for tha tone, dunno how to convert
property = new PropertyResult(i.Key, i.Value, Guid.Empty, PropertyResultType.CustomProperty);
}
{
// no type for that one, dunno how to convert
IPublishedContentProperty property = new PropertyResult(i.Key, i.Value, Guid.Empty, 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);
}
}
-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)
{
+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);
}
@@ -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);
+19 -7
View File
@@ -78,26 +78,38 @@ namespace umbraco
else
{
//check for published content and get its value using that
if (publishedContent != null)
if (publishedContent != null && publishedContent.HasProperty(_fieldName))
{
var pval = publishedContent.GetPropertyValue(_fieldName);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
else if (elements[_fieldName] != null && string.IsNullOrEmpty(elements[_fieldName].ToString()) == false)
{
else
{
//get the vaue the legacy way (this will not parse locallinks, etc... since that is handled with ipublishedcontent)
_fieldContent = elements[_fieldName].ToString().Trim();
var elt = elements[_fieldName];
if (elt != null && string.IsNullOrEmpty(elt.ToString()) == false)
_fieldContent = elt.ToString().Trim();
}
//now we check if the value is still empty and if so we'll check useIfEmpty
if (string.IsNullOrEmpty(_fieldContent))
{
if (string.IsNullOrEmpty(helper.FindAttribute(attributes, "useIfEmpty")) == false)
var altFieldName = helper.FindAttribute(attributes, "useIfEmpty");
if (string.IsNullOrEmpty(altFieldName) == false)
{
if (elements[helper.FindAttribute(attributes, "useIfEmpty")] != null && string.IsNullOrEmpty(elements[helper.FindAttribute(attributes, "useIfEmpty")].ToString()) == false)
if (publishedContent != null && publishedContent.HasProperty(altFieldName))
{
_fieldContent = elements[helper.FindAttribute(attributes, "useIfEmpty")].ToString().Trim();
var pval = publishedContent.GetPropertyValue(altFieldName);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
else
{
//get the vaue the legacy way (this will not parse locallinks, etc... since that is handled with ipublishedcontent)
var elt = elements[altFieldName];
if (elt != null && string.IsNullOrEmpty(elt.ToString()) == false)
_fieldContent = elt.ToString().Trim();
}
}
}
@@ -354,6 +354,9 @@ namespace umbraco
}
catch (Exception e)
{
LogHelper.WarnWithException<macro>(
"Error loading partial view macro (View: " + Model.ScriptName + ")", true, e);
renderFailed = true;
Exceptions.Add(e);
macroControl = handleError(e);
@@ -1824,6 +1827,12 @@ namespace umbraco
public static string MacroContentByHttp(int PageID, Guid PageVersion, Hashtable attributes)
{
if (SystemUtilities.GetCurrentTrustLevel() != AspNetHostingPermissionLevel.Unrestricted)
{
return "<span style='color: red'>Cannot render macro content in the rich text editor when the application is running in a Partial Trust environment</span>";
}
string tempAlias = (attributes["macroalias"] != null)
? attributes["macroalias"].ToString()
: attributes["macroAlias"].ToString();
@@ -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[]
@@ -341,6 +341,11 @@ namespace umbraco.cms.presentation
case PublishStatusType.FailedHasExpired:
case PublishStatusType.FailedAwaitingRelease:
case PublishStatusType.FailedIsTrashed:
ClientTools.ShowSpeechBubble(
speechBubbleIcon.warning,
ui.Text("publish"),
"Cannot publish document with a status of " + status.StatusType);
break;
case PublishStatusType.FailedContentInvalid:
ClientTools.ShowSpeechBubble(
speechBubbleIcon.warning,
@@ -550,7 +550,13 @@ namespace umbraco.NodeFactory
{
if (HttpContext.Current.Items["pageID"] == null)
throw new InvalidOperationException("There is no current node.");
return (int)HttpContext.Current.Items["pageID"];
var intAttempt = HttpContext.Current.Items["pageID"].TryConvertTo<int>();
if (intAttempt == false)
{
throw new InvalidOperationException("The pageID value in the HttpContext.Items cannot be converted to an integer");
}
return intAttempt.Result;
}
}
}
@@ -489,10 +489,10 @@ namespace umbraco.cms.presentation.user
}
u.StartMediaId = mstartNode;
u.clearApplications();
u.ClearApplications();
foreach (ListItem li in lapps.Items)
{
if (li.Selected) u.addApplication(li.Value);
if (li.Selected) u.AddApplication(li.Value);
}
u.Save();
@@ -256,10 +256,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
}
}
}
}
@@ -875,7 +875,7 @@ namespace umbraco.MacroEngines
//this is from SqlMetal and just makes it a bit of fun to allow pluralisation
private static string MakePluralName(string name)
{
if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)))
if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)))
{
name = name + "es";
return name;
+26
View File
@@ -689,9 +689,22 @@ namespace umbraco.BusinessLogic
get { return _user.Id; }
}
/// <summary>
/// Clears the list of applications the user has access to, ensure to call Save afterwords
/// </summary>
public void ClearApplications()
{
if (_lazyId.HasValue) SetupUser(_lazyId.Value);
foreach (var s in _user.AllowedSections.ToArray())
{
_user.RemoveAllowedSection(s);
}
}
/// <summary>
/// Clears the list of applications the user has access to.
/// </summary>
[Obsolete("This method will implicitly cause a database save and will reset the current user's dirty property, do not use this method, use the ClearApplications method instead and then call Save() when you are done performing all user changes to persist the chagnes in one transaction")]
public void clearApplications()
{
if (_lazyId.HasValue) SetupUser(_lazyId.Value);
@@ -701,19 +714,32 @@ namespace umbraco.BusinessLogic
_user.RemoveAllowedSection(s);
}
//For backwards compatibility this requires an implicit save
ApplicationContext.Current.Services.UserService.Save(_user);
}
/// <summary>
/// Adds a application to the list of allowed applications, ensure to call Save() afterwords
/// </summary>
/// <param name="appAlias"></param>
public void AddApplication(string appAlias)
{
if (_lazyId.HasValue) SetupUser(_lazyId.Value);
_user.AddAllowedSection(appAlias);
}
/// <summary>
/// Adds a application to the list of allowed applications
/// </summary>
/// <param name="AppAlias">The app alias.</param>
[Obsolete("This method will implicitly cause a multiple database saves and will reset the current user's dirty property, do not use this method, use the AddApplication method instead and then call Save() when you are done performing all user changes to persist the chagnes in one transaction")]
public void addApplication(string AppAlias)
{
if (_lazyId.HasValue) SetupUser(_lazyId.Value);
_user.AddAllowedSection(AppAlias);
//For backwards compatibility this requires an implicit save
ApplicationContext.Current.Services.UserService.Save(_user);
}
@@ -750,7 +750,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)
@@ -32,9 +32,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;
@@ -74,12 +77,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,