diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000000..c5560c3ce1
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,9 @@
+# The MIT License (MIT) #
+
+Copyright (c) 2013 Umbraco
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec
index 32dab6f4a3..996f05936a 100644
--- a/build/NuSpecs/UmbracoCms.Core.nuspec
+++ b/build/NuSpecs/UmbracoCms.Core.nuspec
@@ -19,22 +19,21 @@
-
+
-
+
+
+
-
-
-
diff --git a/build/NuSpecs/build/net40/UmbracoCms.props b/build/NuSpecs/build/net40/UmbracoCms.props
index 50c21a7c0d..5e11945a9d 100644
--- a/build/NuSpecs/build/net40/UmbracoCms.props
+++ b/build/NuSpecs/build/net40/UmbracoCms.props
@@ -5,5 +5,10 @@
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
+
+
+ AddUmbracoFilesToOutput;
+ $(CopyAllFilesToSingleFolderForPackageDependsOn);
+
\ No newline at end of file
diff --git a/build/NuSpecs/build/net45/UmbracoCms.props b/build/NuSpecs/build/net45/UmbracoCms.props
index 50c21a7c0d..5e11945a9d 100644
--- a/build/NuSpecs/build/net45/UmbracoCms.props
+++ b/build/NuSpecs/build/net45/UmbracoCms.props
@@ -5,5 +5,10 @@
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
+
+
+ AddUmbracoFilesToOutput;
+ $(CopyAllFilesToSingleFolderForPackageDependsOn);
+
\ No newline at end of file
diff --git a/build/NuSpecs/build/net451/UmbracoCms.props b/build/NuSpecs/build/net451/UmbracoCms.props
index 50c21a7c0d..5e11945a9d 100644
--- a/build/NuSpecs/build/net451/UmbracoCms.props
+++ b/build/NuSpecs/build/net451/UmbracoCms.props
@@ -5,5 +5,10 @@
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
+
+
+ AddUmbracoFilesToOutput;
+ $(CopyAllFilesToSingleFolderForPackageDependsOn);
+
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/CacheKeys.cs b/src/Umbraco.Core/Cache/CacheKeys.cs
index 1c89d7662f..54f9ab4832 100644
--- a/src/Umbraco.Core/Cache/CacheKeys.cs
+++ b/src/Umbraco.Core/Cache/CacheKeys.cs
@@ -31,6 +31,7 @@ namespace Umbraco.Core.Cache
public const string UserContextCacheKey = "UmbracoUserContext";
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
public const string UserCacheKey = "UmbracoUser";
+ public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
public const string ContentTypeCacheKey = "UmbracoContentType";
diff --git a/src/Umbraco.Core/Cache/RuntimeCacheProviderBase.cs b/src/Umbraco.Core/Cache/RuntimeCacheProviderBase.cs
index 9dddb4c576..d88a3922bb 100644
--- a/src/Umbraco.Core/Cache/RuntimeCacheProviderBase.cs
+++ b/src/Umbraco.Core/Cache/RuntimeCacheProviderBase.cs
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Cache
/// An abstract class for implementing a runtime cache provider
///
///
- /// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC...
+ /// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, REQUEST CACHE, ETC...
///
internal abstract class RuntimeCacheProviderBase : CacheProviderBase
{
diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index 41ceaf9b90..0e5c3340fa 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Models
private DateTime? _expireDate;
private int _writer;
private string _nodeName;//NOTE Once localization is introduced this will be the non-localized Node Name.
-
+ private bool _permissionsChanged;
///
/// Constructor for creating a Content object
///
@@ -82,6 +82,7 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo ExpireDateSelector = ExpressionHelper.GetPropertyInfo(x => x.ExpireDate);
private static readonly PropertyInfo WriterSelector = ExpressionHelper.GetPropertyInfo(x => x.WriterId);
private static readonly PropertyInfo NodeNameSelector = ExpressionHelper.GetPropertyInfo(x => x.NodeName);
+ private static readonly PropertyInfo PermissionsChangedSelector = ExpressionHelper.GetPropertyInfo(x => x.PermissionsChanged);
///
/// Gets or sets the template used by the Content.
@@ -243,6 +244,22 @@ namespace Umbraco.Core.Models
}
}
+ ///
+ /// Used internally to track if permissions have been changed during the saving process for this entity
+ ///
+ internal bool PermissionsChanged
+ {
+ get { return _permissionsChanged; }
+ set
+ {
+ SetPropertyValueAndDetectChanges(o =>
+ {
+ _permissionsChanged = value;
+ return _permissionsChanged;
+ }, _permissionsChanged, PermissionsChangedSelector);
+ }
+ }
+
///
/// Gets the ContentType used by this content object
///
diff --git a/src/Umbraco.Core/Models/Membership/IUser.cs b/src/Umbraco.Core/Models/Membership/IUser.cs
index 4960b1f2b9..268ed04219 100644
--- a/src/Umbraco.Core/Models/Membership/IUser.cs
+++ b/src/Umbraco.Core/Models/Membership/IUser.cs
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Models.Membership
bool NoConsole { get; set; }
IUserType UserType { get; }
- string Permissions { get; set; }
+ string DefaultPermissions { get; set; }
}
internal interface IUserProfile : IProfile
diff --git a/src/Umbraco.Core/Models/Membership/User.cs b/src/Umbraco.Core/Models/Membership/User.cs
index d6b71135ef..ddcc28cccb 100644
--- a/src/Umbraco.Core/Models/Membership/User.cs
+++ b/src/Umbraco.Core/Models/Membership/User.cs
@@ -91,7 +91,7 @@ namespace Umbraco.Core.Models.Membership
[DataMember]
public string Language { get; set; }
[DataMember]
- public string Permissions { get; set; }
+ public string DefaultPermissions { get; set; }
[DataMember]
public bool DefaultToLiveEditing { get; set; }
diff --git a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs
index 6d38db9739..0a046ca7a0 100644
--- a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Factories
Language = dto.UserLanguage,
DefaultToLiveEditing = dto.DefaultToLiveEditing,
NoConsole = dto.NoConsole,
- Permissions = dto.DefaultPermissions
+ DefaultPermissions = dto.DefaultPermissions
};
foreach (var app in dto.User2AppDtos)
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Persistence.Factories
UserLanguage = entity.Language,
UserName = entity.Name,
Type = short.Parse(entity.UserType.Id.ToString()),
- DefaultPermissions = entity.Permissions,
+ DefaultPermissions = entity.DefaultPermissions,
User2AppDtos = new List()
};
diff --git a/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs b/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs
index 1a7add097a..5e2947c3a7 100644
--- a/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Username, dto => dto.Login);
CacheMap(src => src.Password, dto => dto.Password);
CacheMap(src => src.Name, dto => dto.UserName);
- CacheMap(src => src.Permissions, dto => dto.DefaultPermissions);
+ CacheMap(src => src.DefaultPermissions, dto => dto.DefaultPermissions);
CacheMap(src => src.StartMediaId, dto => dto.MediaStartId);
CacheMap(src => src.StartContentId, dto => dto.ContentStartId);
CacheMap(src => src.DefaultToLiveEditing, dto => dto.DefaultToLiveEditing);
diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs
index 269fea5f9a..d8507ac681 100644
--- a/src/Umbraco.Core/Persistence/PetaPoco.cs
+++ b/src/Umbraco.Core/Persistence/PetaPoco.cs
@@ -384,7 +384,7 @@ namespace Umbraco.Core.Persistence
}
// Add a parameter to a DB command
- void AddParam(IDbCommand cmd, object item, string ParameterPrefix)
+ internal void AddParam(IDbCommand cmd, object item, string ParameterPrefix)
{
// Convert value to from poco type to db type
if (Database.Mapper != null && item!=null)
diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
index 85ab884857..6faf4d637a 100644
--- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
+++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Data;
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
@@ -28,6 +30,76 @@ namespace Umbraco.Core.Persistence
CreateTable(db, overwrite, tableType);
}
+ public static void BulkInsertRecords(this Database db, IEnumerable collection)
+ {
+ using (var tr = db.GetTransaction())
+ {
+ try
+ {
+ if (SqlSyntaxContext.SqlSyntaxProvider is SqlCeSyntaxProvider)
+ {
+ //SqlCe doesn't support bulk insert statements!
+
+ foreach (var poco in collection)
+ {
+ db.Insert(poco);
+ }
+
+ }
+ else
+ {
+ string sql;
+ using (var cmd = db.GenerateBulkInsertCommand(collection, db.Connection, out sql))
+ {
+ cmd.CommandText = sql;
+ cmd.ExecuteNonQuery();
+ }
+ }
+
+ tr.Complete();
+ }
+ catch
+ {
+ tr.Dispose();
+ throw;
+ }
+ }
+ }
+
+ internal static IDbCommand GenerateBulkInsertCommand(this Database db, IEnumerable collection, IDbConnection connection, out string sql)
+ {
+ var pd = Database.PocoData.ForType(typeof(T));
+ var tableName = db.EscapeTableName(pd.TableInfo.TableName);
+
+ //get all columns but not the primary key if it is auto-incremental
+ var cols = string.Join(", ", (
+ from c in pd.Columns
+ where c.Value.ResultColumn == false
+ select tableName + "." + db.EscapeSqlIdentifier(c.Key))
+ .ToArray());
+
+ var cmd = db.CreateCommand(connection, "");
+
+ var pocoValues = new List();
+ var index = 0;
+ foreach (var poco in collection)
+ {
+ var values = new List();
+ foreach (var i in pd.Columns)
+ {
+ //if (pd.TableInfo.AutoIncrement && i.Key == pd.TableInfo.PrimaryKey)
+ //{
+ // continue;
+ //}
+ values.Add(string.Format("{0}{1}", "@", index++));
+ db.AddParam(cmd, i.Value.GetValue(poco), "@");
+ }
+ pocoValues.Add("(" + string.Join(",", values.ToArray()) + ")");
+ }
+ sql = string.Format("INSERT INTO {0} ({1}) VALUES {2}", tableName, cols, string.Join(", ", pocoValues));
+ return cmd;
+ }
+
public static void CreateTable(this Database db, bool overwrite, Type modelType)
{
var tableDefinition = DefinitionFactory.GetTableDefinition(modelType);
@@ -67,7 +139,7 @@ namespace Umbraco.Core.Persistence
//Turn on identity insert if db provider is not mysql
if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName))));
-
+
//Call the NewTable-event to trigger the insert of base/default data
NewTable(tableName, db, e);
@@ -106,7 +178,7 @@ namespace Umbraco.Core.Persistence
public static void DropTable(this Database db)
where T : new()
{
- Type type = typeof (T);
+ Type type = typeof(T);
var tableNameAttribute = type.FirstAttribute();
if (tableNameAttribute == null)
throw new Exception(
@@ -184,5 +256,5 @@ namespace Umbraco.Core.Persistence
}
}
- internal class TableCreationEventArgs : System.ComponentModel.CancelEventArgs{}
+ internal class TableCreationEventArgs : System.ComponentModel.CancelEventArgs { }
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
index 2c92517b15..755fc5f04a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
@@ -206,7 +206,7 @@ namespace Umbraco.Core.Persistence.Repositories
nodeDto.Level = short.Parse(level.ToString(CultureInfo.InvariantCulture));
nodeDto.SortOrder = sortOrder;
var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto);
-
+
//Update with new correct path
nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId);
Database.Update(nodeDto);
@@ -217,6 +217,24 @@ namespace Umbraco.Core.Persistence.Repositories
entity.SortOrder = sortOrder;
entity.Level = level;
+
+ //Assign the same permissions to it as the parent node
+ // http://issues.umbraco.org/issue/U4-2161
+ var parentPermissions = GetPermissionsForEntity(entity.ParentId).ToArray();
+ //if there are parent permissions then assign them, otherwise leave null and permissions will become the
+ // user's default permissions.
+ if (parentPermissions.Any())
+ {
+ var userPermissions = parentPermissions.Select(
+ permissionDto => new KeyValuePair
" + ui.Text("closeThisWindow") + "";
feedback.type = uicontrols.Feedback.feedbacktype.success;
// refresh tree
- ClientTools.CopyNode(currContent.Id.ToString(), parentContent.Path);
+ ClientTools.CopyNode(currContent.Id.ToString(), newContent.Path);
}
}
}
diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config
index f76f93a114..023ebfc6b9 100644
--- a/src/umbraco.MacroEngines/packages.config
+++ b/src/umbraco.MacroEngines/packages.config
@@ -1,15 +1,15 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
index 07891470f2..d6fecdbaca 100644
--- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
+++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
@@ -49,9 +49,9 @@
False
..\packages\Examine.0.1.51.2941\lib\Examine.dll
-
+
False
- ..\packages\HtmlAgilityPack.1.4.5\lib\Net40\HtmlAgilityPack.dll
+ ..\packages\HtmlAgilityPack.1.4.6\lib\Net40\HtmlAgilityPack.dll
False
@@ -77,7 +77,7 @@
..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.dll
- ..\packages\Microsoft.AspNet.WebApi.Client.4.0.20710.0\lib\net40\System.Net.Http.Formatting.dll
+ ..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll
..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.WebRequest.dll
@@ -85,33 +85,33 @@
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll
- ..\packages\Microsoft.AspNet.WebApi.Core.4.0.20710.0\lib\net40\System.Web.Http.dll
+ ..\packages\Microsoft.AspNet.WebApi.Core.4.0.30506.0\lib\net40\System.Web.Http.dll
- ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.20710.0\lib\net40\System.Web.Http.WebHost.dll
+ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll
True
- ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll
+ ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll
True
- ..\packages\Microsoft.AspNet.Razor.2.0.20715.0\lib\net40\System.Web.Razor.dll
+ ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll
diff --git a/src/umbraco.businesslogic/User.cs b/src/umbraco.businesslogic/User.cs
index ae5c0202ab..5da83d2a6d 100644
--- a/src/umbraco.businesslogic/User.cs
+++ b/src/umbraco.businesslogic/User.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections;
+using System.Web.Caching;
using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using umbraco.DataLayer;
using System.Collections.Generic;
@@ -27,9 +29,6 @@ namespace umbraco.BusinessLogic
private bool _userDisabled;
private bool _defaultToLiveEditing;
- private Hashtable _cruds = new Hashtable();
- private bool _crudsInitialized = false;
-
private Hashtable _notifications = new Hashtable();
private bool _notificationsInitialized = false;
@@ -667,52 +666,56 @@ namespace umbraco.BusinessLogic
{
if (!_isInitialized)
setupUser(_id);
- string cruds = UserType.DefaultPermissions;
+ string defaultPermissions = UserType.DefaultPermissions;
- if (!_crudsInitialized)
- initCruds();
+ //get the cached permissions for the user
+ var cachedPermissions = ApplicationContext.Current.ApplicationCache.GetCacheItem(
+ string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, _id),
+ //Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will make this priority below average
+ CacheItemPriority.BelowNormal,
+ null,
+ //Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will only have this exist in cache for 20 minutes,
+ // then it will refresh from the database.
+ new TimeSpan(0, 20, 0),
+ () =>
+ {
+ var cruds = new Hashtable();
+ using (var dr = SqlHelper.ExecuteReader("select * from umbracoUser2NodePermission where userId = @userId order by nodeId", SqlHelper.CreateParameter("@userId", this.Id)))
+ {
+ while (dr.Read())
+ {
+ if (!cruds.ContainsKey(dr.GetInt("nodeId")))
+ {
+ cruds.Add(dr.GetInt("nodeId"), string.Empty);
+ }
+ cruds[dr.GetInt("nodeId")] += dr.GetString("permission");
+ }
+ }
+ return cruds;
+ });
// NH 4.7.1 changing default permission behavior to default to User Type permissions IF no specific permissions has been
// set for the current node
- int nodeId = Path.Contains(",") ? int.Parse(Path.Substring(Path.LastIndexOf(",")+1)) : int.Parse(Path);
- if (_cruds.ContainsKey(nodeId))
+ var nodeId = Path.Contains(",") ? int.Parse(Path.Substring(Path.LastIndexOf(",", StringComparison.Ordinal)+1)) : int.Parse(Path);
+ if (cachedPermissions.ContainsKey(nodeId))
{
- return _cruds[int.Parse(Path.Substring(Path.LastIndexOf(",")+1))].ToString();
+ return cachedPermissions[int.Parse(Path.Substring(Path.LastIndexOf(",", StringComparison.Ordinal) + 1))].ToString();
}
// exception to everything. If default cruds is empty and we're on root node; allow browse of root node
- if (String.IsNullOrEmpty(cruds) && Path == "-1")
- cruds = "F";
+ if (string.IsNullOrEmpty(defaultPermissions) && Path == "-1")
+ defaultPermissions = "F";
// else return default user type cruds
- return cruds;
+ return defaultPermissions;
}
///
/// Initializes the user node permissions
///
+ [Obsolete("This method doesn't do anything whatsoever and will be removed in future versions")]
public void initCruds()
- {
- if (!_isInitialized)
- setupUser(_id);
-
- // clear cruds
- System.Web.HttpContext.Current.Application.Lock();
- _cruds.Clear();
- System.Web.HttpContext.Current.Application.UnLock();
-
- using (IRecordsReader dr = SqlHelper.ExecuteReader("select * from umbracoUser2NodePermission where userId = @userId order by nodeId", SqlHelper.CreateParameter("@userId", this.Id)))
- {
- // int currentId = -1;
- while (dr.Read())
- {
- if (!_cruds.ContainsKey(dr.GetInt("nodeId")))
- _cruds.Add(dr.GetInt("nodeId"), String.Empty);
-
- _cruds[dr.GetInt("nodeId")] += dr.GetString("permission");
- }
- }
- _crudsInitialized = true;
+ {
}
///
@@ -904,7 +907,7 @@ namespace umbraco.BusinessLogic
public void FlushFromCache()
{
OnFlushingFromCache(EventArgs.Empty);
- ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("UmbracoUser{0}", Id.ToString()));
+ ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserCacheKey, Id.ToString()));
}
///
@@ -915,7 +918,7 @@ namespace umbraco.BusinessLogic
public static User GetUser(int id)
{
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
- string.Format("UmbracoUser{0}", id.ToString()), () =>
+ string.Format("{0}{1}", CacheKeys.UserCacheKey, id.ToString()), () =>
{
try
{
diff --git a/src/umbraco.businesslogic/packages.config b/src/umbraco.businesslogic/packages.config
index 9febdbd940..02e046e7cb 100644
--- a/src/umbraco.businesslogic/packages.config
+++ b/src/umbraco.businesslogic/packages.config
@@ -1,8 +1,8 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/umbraco.businesslogic/umbraco.businesslogic.csproj b/src/umbraco.businesslogic/umbraco.businesslogic.csproj
index 32127a6b3a..5eb81794fc 100644
--- a/src/umbraco.businesslogic/umbraco.businesslogic.csproj
+++ b/src/umbraco.businesslogic/umbraco.businesslogic.csproj
@@ -128,27 +128,27 @@
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll
True
- ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll
+ ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll
True
- ..\packages\Microsoft.AspNet.Razor.2.0.20715.0\lib\net40\System.Web.Razor.dll
+ ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll
True
- ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll
+ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll
System.XML
diff --git a/src/umbraco.cms/Actions/ActionNew.cs b/src/umbraco.cms/Actions/ActionNew.cs
index 303baa3e35..ff17c91a0b 100644
--- a/src/umbraco.cms/Actions/ActionNew.cs
+++ b/src/umbraco.cms/Actions/ActionNew.cs
@@ -10,7 +10,7 @@ namespace umbraco.BusinessLogic.Actions
public class ActionNew : IAction
{
//create singleton
- private static readonly ActionNew InternalInstance = new ActionNew();
+ private static readonly ActionNew InnerInstance = new ActionNew();
///
/// A public constructor exists ONLY for backwards compatibility in regards to 3rd party add-ons.
@@ -22,7 +22,7 @@ namespace umbraco.BusinessLogic.Actions
public static ActionNew Instance
{
- get { return InternalInstance; }
+ get { return InnerInstance; }
}
#region IAction Members
diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs
index 76455c1361..ba8a6ccc35 100644
--- a/src/umbraco.cms/businesslogic/CMSNode.cs
+++ b/src/umbraco.cms/businesslogic/CMSNode.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
+using System.Threading;
using System.Xml;
+using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Caching;
@@ -55,12 +57,13 @@ namespace umbraco.cms.businesslogic
#region Private static
- private static readonly string m_DefaultIconCssFile = IOHelper.MapPath(SystemDirectories.Umbraco_client + "/Tree/treeIcons.css");
- private static List m_DefaultIconClasses = new List();
+ private static readonly string DefaultIconCssFile = IOHelper.MapPath(SystemDirectories.Umbraco_client + "/Tree/treeIcons.css");
+ private static readonly List InternalDefaultIconClasses = new List();
+ private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
- private static void initializeIconClasses()
+ private static void InitializeIconClasses()
{
- StreamReader re = File.OpenText(m_DefaultIconCssFile);
+ StreamReader re = File.OpenText(DefaultIconCssFile);
string content = string.Empty;
string input = null;
while ((input = re.ReadLine()) != null)
@@ -70,20 +73,20 @@ namespace umbraco.cms.businesslogic
re.Close();
// parse the classes
- MatchCollection m = Regex.Matches(content, "([^{]*){([^}]*)}", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+ var m = Regex.Matches(content, "([^{]*){([^}]*)}", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match match in m)
{
- GroupCollection groups = match.Groups;
- string cssClass = groups[1].Value.Replace("\n", "").Replace("\r", "").Trim().Trim(Environment.NewLine.ToCharArray());
- if (!String.IsNullOrEmpty(cssClass))
+ var groups = match.Groups;
+ var cssClass = groups[1].Value.Replace("\n", "").Replace("\r", "").Trim().Trim(Environment.NewLine.ToCharArray());
+ if (string.IsNullOrEmpty(cssClass) == false)
{
- m_DefaultIconClasses.Add(cssClass);
+ InternalDefaultIconClasses.Add(cssClass);
}
}
}
- private const string m_SQLSingle = "SELECT id, createDate, trashed, parentId, nodeObjectType, nodeUser, level, path, sortOrder, uniqueID, text FROM umbracoNode WHERE id = @id";
- private const string m_SQLDescendants = @"
+ private const string SqlSingle = "SELECT id, createDate, trashed, parentId, nodeObjectType, nodeUser, level, path, sortOrder, uniqueID, text FROM umbracoNode WHERE id = @id";
+ private const string SqlDescendants = @"
SELECT id, createDate, trashed, parentId, nodeObjectType, nodeUser, level, path, sortOrder, uniqueID, text
FROM umbracoNode
WHERE path LIKE '%,{0},%'";
@@ -137,10 +140,16 @@ namespace umbraco.cms.businesslogic
{
get
{
- if (m_DefaultIconClasses.Count == 0)
- initializeIconClasses();
+ using (var l = new UpgradeableReadLock(Locker))
+ {
+ if (InternalDefaultIconClasses.Count == 0)
+ {
+ l.UpgradeToWriteLock();
+ InitializeIconClasses();
+ }
+ return InternalDefaultIconClasses;
+ }
- return m_DefaultIconClasses;
}
}
@@ -309,7 +318,7 @@ namespace umbraco.cms.businesslogic
return sortOrder;
}
-
+
///
/// Retrieve a list of the id's of all CMSNodes given the objecttype and the first letter of the name.
///
@@ -519,9 +528,9 @@ order by level,sortOrder";
SqlHelper.CreateParameter("@parentId", newParent.Id));
this.Parent = newParent;
- this.sortOrder = maxSortOrder + 1;
+ this.sortOrder = maxSortOrder + 1;
}
-
+
//detect if we have moved, then update the level and path
// issue: http://issues.umbraco.org/issue/U4-1579
if (this.Path != newParent.Path + "," + this.Id.ToString())
@@ -556,7 +565,7 @@ order by level,sortOrder";
//regenerate the xml for the newParent node
var parentDocument = new Document(newParent.Id);
parentDocument.XmlGenerate(new XmlDocument());
-
+
}
else if (!IsTrashed && newParent.nodeObjectType == Media._objectType)
{
@@ -661,7 +670,7 @@ order by level,sortOrder";
public virtual IEnumerable GetDescendants()
{
var descendants = new List();
- using (IRecordsReader dr = SqlHelper.ExecuteReader(string.Format(m_SQLDescendants, Id)))
+ using (IRecordsReader dr = SqlHelper.ExecuteReader(string.Format(SqlDescendants, Id)))
{
while (dr.Read())
{
@@ -998,7 +1007,7 @@ order by level,sortOrder";
///
protected virtual void setupNode()
{
- using (IRecordsReader dr = SqlHelper.ExecuteReader(m_SQLSingle,
+ using (IRecordsReader dr = SqlHelper.ExecuteReader(SqlSingle,
SqlHelper.CreateParameter("@id", this.Id)))
{
if (dr.Read())
@@ -1187,7 +1196,7 @@ order by level,sortOrder";
}
///
- /// Occurs after a node is saved.
+ /// Occurs after a node is saved.
///
public static event EventHandler AfterSave;
diff --git a/src/umbraco.cms/businesslogic/media/Media.cs b/src/umbraco.cms/businesslogic/media/Media.cs
index 252d8cd799..6dcff5792f 100644
--- a/src/umbraco.cms/businesslogic/media/Media.cs
+++ b/src/umbraco.cms/businesslogic/media/Media.cs
@@ -92,12 +92,11 @@ namespace umbraco.cms.businesslogic.media
return null;
}
- var media = ApplicationContext.Current.Services.MediaService.CreateMedia(Name, ParentId, dct.Alias, u.Id);
+ var media = ApplicationContext.Current.Services.MediaService.CreateMediaWithIdentity(Name, ParentId, dct.Alias, u.Id);
//The media object will only have the 'WasCancelled' flag set to 'True' if the 'Creating' event has been cancelled
if (((Entity)media).WasCancelled)
return null;
- ApplicationContext.Current.Services.MediaService.Save(media);
var tmp = new Media(media);
tmp.OnNew(e);
diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs
index 6be26cfa77..2df9e19f37 100644
--- a/src/umbraco.cms/businesslogic/web/Document.cs
+++ b/src/umbraco.cms/businesslogic/web/Document.cs
@@ -306,14 +306,11 @@ namespace umbraco.cms.businesslogic.web
}
//Create a new IContent object based on the passed in DocumentType's alias, set the name and save it
- IContent content = ApplicationContext.Current.Services.ContentService.CreateContent(Name, ParentId, dct.Alias, u.Id);
+ IContent content = ApplicationContext.Current.Services.ContentService.CreateContentWithIdentity(Name, ParentId, dct.Alias, u.Id);
//The content object will only have the 'WasCancelled' flag set to 'True' if the 'Creating' event has been cancelled, so we return null.
if (((Entity)content).WasCancelled)
return null;
- //don't raise events here (false), they will get raised with the d.Save() call.
- ApplicationContext.Current.Services.ContentService.Save(content, u.Id, false);
-
//read the whole object from the db
Document d = new Document(content);
diff --git a/src/umbraco.cms/businesslogic/web/Domain.cs b/src/umbraco.cms/businesslogic/web/Domain.cs
index 83bbb850ac..f5bcb46090 100644
--- a/src/umbraco.cms/businesslogic/web/Domain.cs
+++ b/src/umbraco.cms/businesslogic/web/Domain.cs
@@ -138,12 +138,12 @@ namespace umbraco.cms.businesslogic.web
#region Statics
- internal static List GetDomains()
+ public static IEnumerable GetDomains()
{
return GetDomains(false);
}
- internal static List GetDomains(bool includeWildcards)
+ internal static IEnumerable GetDomains(bool includeWildcards)
{
var domains = ApplicationContext.Current.ApplicationCache.GetCacheItem(
CacheKeys.DomainCacheKey,
@@ -177,7 +177,7 @@ namespace umbraco.cms.businesslogic.web
public static Domain GetDomain(string DomainName)
{
- return GetDomains().Find(delegate(Domain d) { return d.Name == DomainName; });
+ return GetDomains().FirstOrDefault(d => d.Name == DomainName);
}
public static int GetRootFromDomain(string DomainName)
@@ -189,7 +189,7 @@ namespace umbraco.cms.businesslogic.web
public static Domain[] GetDomainsById(int nodeId)
{
- return GetDomains().FindAll(delegate(Domain d) { return d._root == nodeId; }).ToArray();
+ return GetDomains().Where(d => d._root == nodeId).ToArray();
}
public static bool Exists(string DomainName)
diff --git a/src/umbraco.cms/packages.config b/src/umbraco.cms/packages.config
index 06959d20f2..3a63559557 100644
--- a/src/umbraco.cms/packages.config
+++ b/src/umbraco.cms/packages.config
@@ -1,7 +1,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj
index b0509a302b..3e2e8da4c2 100644
--- a/src/umbraco.cms/umbraco.cms.csproj
+++ b/src/umbraco.cms/umbraco.cms.csproj
@@ -106,13 +106,13 @@
false
-
+
False
- ..\packages\ClientDependency.1.7.0.2\lib\ClientDependency.Core.dll
+ ..\packages\ClientDependency.1.7.0.3\lib\ClientDependency.Core.dll
-
+
False
- ..\packages\HtmlAgilityPack.1.4.5\lib\Net40\HtmlAgilityPack.dll
+ ..\packages\HtmlAgilityPack.1.4.6\lib\Net40\HtmlAgilityPack.dll
False
diff --git a/src/umbraco.controls/DatePicker/DateTimePicker.cs b/src/umbraco.controls/DatePicker/DateTimePicker.cs
index 5c453649e1..4df20fbb9d 100644
--- a/src/umbraco.controls/DatePicker/DateTimePicker.cs
+++ b/src/umbraco.controls/DatePicker/DateTimePicker.cs
@@ -1,11 +1,7 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using ClientDependency.Core;
using System.Web.UI;
using System.Web.UI.WebControls;
-using umbraco.IO;
using System.Web.UI.HtmlControls;
namespace umbraco.uicontrols.DatePicker
diff --git a/src/umbraco.controls/packages.config b/src/umbraco.controls/packages.config
index babc1d8a83..d30bbbe9c0 100644
--- a/src/umbraco.controls/packages.config
+++ b/src/umbraco.controls/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/src/umbraco.controls/umbraco.controls.csproj b/src/umbraco.controls/umbraco.controls.csproj
index c8ec886edf..520d173367 100644
--- a/src/umbraco.controls/umbraco.controls.csproj
+++ b/src/umbraco.controls/umbraco.controls.csproj
@@ -68,9 +68,9 @@
false
-
+
False
- ..\packages\ClientDependency.1.7.0.2\lib\ClientDependency.Core.dll
+ ..\packages\ClientDependency.1.7.0.3\lib\ClientDependency.Core.dll
diff --git a/src/umbraco.datalayer/packages.config b/src/umbraco.datalayer/packages.config
index 87b5ad1860..02379f5503 100644
--- a/src/umbraco.datalayer/packages.config
+++ b/src/umbraco.datalayer/packages.config
@@ -2,5 +2,5 @@
-
+
\ No newline at end of file
diff --git a/src/umbraco.datalayer/umbraco.datalayer.csproj b/src/umbraco.datalayer/umbraco.datalayer.csproj
index 7e8b055cbd..253e058e2b 100644
--- a/src/umbraco.datalayer/umbraco.datalayer.csproj
+++ b/src/umbraco.datalayer/umbraco.datalayer.csproj
@@ -76,8 +76,9 @@
False
..\packages\Microsoft.ApplicationBlocks.Data.1.0.1559.20655\lib\Microsoft.ApplicationBlocks.Data.dll
-
- ..\packages\MySql.Data.6.6.4\lib\net40\MySql.Data.dll
+
+ False
+ ..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll
diff --git a/src/umbraco.editorControls/packages.config b/src/umbraco.editorControls/packages.config
index babc1d8a83..d30bbbe9c0 100644
--- a/src/umbraco.editorControls/packages.config
+++ b/src/umbraco.editorControls/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/src/umbraco.editorControls/tags/DataEditor.cs b/src/umbraco.editorControls/tags/DataEditor.cs
index 4281e1f12a..22c9fd423b 100644
--- a/src/umbraco.editorControls/tags/DataEditor.cs
+++ b/src/umbraco.editorControls/tags/DataEditor.cs
@@ -62,7 +62,6 @@ namespace umbraco.editorControls.tags
base.OnInit(e);
// register all dependencies - only registered once
- ClientDependencyLoader.Instance.RegisterDependency("ui/ui-lightness/jquery-ui.custom.css", "UmbracoClient", ClientDependencyType.Css);
ClientDependencyLoader.Instance.RegisterDependency("css/umbracoGui.css", "UmbracoRoot", ClientDependencyType.Css);
ClientDependencyLoader.Instance.RegisterDependency("tags/css/jquery.tagsinput.css", "UmbracoClient", ClientDependencyType.Css);
ClientDependencyLoader.Instance.RegisterDependency("tags/js/jquery.tagsinput.min.js", "UmbracoClient", ClientDependencyType.Javascript);
diff --git a/src/umbraco.editorControls/umbraco.editorControls.csproj b/src/umbraco.editorControls/umbraco.editorControls.csproj
index bd395aa192..c702e92e6a 100644
--- a/src/umbraco.editorControls/umbraco.editorControls.csproj
+++ b/src/umbraco.editorControls/umbraco.editorControls.csproj
@@ -114,9 +114,9 @@
{651E1350-91B6-44B7-BD60-7207006D7003}
Umbraco.Web
-
+
False
- ..\packages\ClientDependency.1.7.0.2\lib\ClientDependency.Core.dll
+ ..\packages\ClientDependency.1.7.0.3\lib\ClientDependency.Core.dll
System
diff --git a/src/umbraco.macroRenderings/packages.config b/src/umbraco.macroRenderings/packages.config
index 2a8355e1b9..c840bab970 100644
--- a/src/umbraco.macroRenderings/packages.config
+++ b/src/umbraco.macroRenderings/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj b/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj
index 4fb59d605d..7bb292dffd 100644
--- a/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj
+++ b/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj
@@ -106,9 +106,9 @@
false
-
+
False
- ..\packages\ClientDependency.1.7.0.2\lib\ClientDependency.Core.dll
+ ..\packages\ClientDependency.1.7.0.3\lib\ClientDependency.Core.dll
False
diff --git a/src/umbraco.sln b/src/umbraco.sln
index 00674dae46..40e367de59 100644
--- a/src/umbraco.sln
+++ b/src/umbraco.sln
@@ -83,6 +83,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UmbracoExamine.Azure", "Umb
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UmbracoExamine.PDF.Azure", "UmbracoExamine.PDF.Azure\UmbracoExamine.PDF.Azure.csproj", "{B555AAE6-0F56-442F-AC9F-EF497DB38DE7}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{227C3B55-80E5-4E7E-A802-BE16C5128B9D}"
+ ProjectSection(SolutionItems) = preProject
+ ..\build\NuSpecs\UmbracoCms.Core.nuspec = ..\build\NuSpecs\UmbracoCms.Core.nuspec
+ ..\build\NuSpecs\UmbracoCms.nuspec = ..\build\NuSpecs\UmbracoCms.nuspec
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -168,6 +174,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {227C3B55-80E5-4E7E-A802-BE16C5128B9D} = {2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}
{5D3B8245-ADA6-453F-A008-50ED04BFE770} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{07FBC26B-2927-4A22-8D96-D644C667FECC} = {DD32977B-EF54-475B-9A1B-B97A502C6E58}
{F30DDDB8-3994-4673-82AE-057123C6E1A8} = {DD32977B-EF54-475B-9A1B-B97A502C6E58}