Compare commits

..

26 Commits

Author SHA1 Message Date
mikkelhm bfd201efcc Bump version to 7.6-Beta5 2017-03-23 15:46:18 +01:00
Shannon 2ae236e98d Adds xml transform for partial view tree types 2017-03-23 18:48:41 +11:00
Shannon 802fb95784 Fixes issue with renaming PartialViewMacro and PartialViewTree controller names - this also fixes an issue that we were looking up these types over and over again and now we just do it once. 2017-03-23 18:44:28 +11:00
Shannon 0297fdb32f Fixes a bunch of the JS unit tests 2017-03-23 13:19:37 +11:00
Shannon Deminick 5bede4bf9f Merge pull request #1816 from umbraco/temp-u4-9664
u4-9664 - Enables HasAccess on the MediaTreeController to use a udi for checkin…
2017-03-23 12:54:11 +11:00
Shannon d37106576d Adds null checks to the ContentTreeController too 2017-03-23 12:53:48 +11:00
Shannon ed0f0f7942 Merge remote-tracking branch 'origin/dev-v7' into dev-v7.6
# Conflicts:
#	src/Umbraco.Core/Configuration/CoreDebug.cs
#	src/Umbraco.Core/Publishing/PublishingStrategy.cs
#	src/Umbraco.Core/Umbraco.Core.csproj
2017-03-23 12:24:16 +11:00
Shannon Deminick 3d81c73495 Merge pull request #1814 from umbraco/temp-u4-9658
U4-9658 - detect umbraco.config rogue content types, and fix
2017-03-23 12:16:10 +11:00
Shannon e7a540e717 Proper Exception handling 2017-03-23 12:15:14 +11:00
Shannon Deminick bb886c237e Merge pull request #1815 from umbraco/temp-u4-9610
U4-9610 - fix nullref in BulkPublishController
2017-03-23 11:28:03 +11:00
Shannon 6c1e271fa8 Fixes styling and fixing error message quotes to make it more clear 2017-03-23 11:27:46 +11:00
Shannon Deminick 4c1b807e4f Merge pull request #1812 from umbraco/temp-u4-6811
U4-6811 - fix preview set deletion
2017-03-23 11:06:33 +11:00
Shannon 3b22c0cdd7 Catches correct expected exception type, we'll log for other non expected errors. 2017-03-23 11:06:06 +11:00
mikkelhm 31d8f49d3b Enables HasAccess on the MediaTreeController to use a udi for checking access 2017-03-22 20:25:15 +01:00
Stephan 631404743f U4-9610 - fix nullref in BulkPublishController 2017-03-22 14:44:39 +01:00
Stephan d5c9639170 U4-9658 - detect umbraco.config rogue content types, and fix 2017-03-22 13:58:40 +01:00
Stephan 94b7c36d62 U4-6811 - fix preview set deletion 2017-03-22 12:16:33 +01:00
Claus 532b177d2e Merge pull request #1793 from Phosworks/U4-8418
Fixes jquery selector bug, http://issues.umbraco.org/issue/U4-8418
2017-03-20 14:43:43 +01:00
Shannon 3d6f91cbef Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2017-03-18 15:47:56 +11:00
Shannon fffd508bb2 missing null check 2017-03-18 15:44:57 +11:00
Stephan 333b35d8b9 U4-9606 - hard cap of 8 minidump files 2017-03-16 15:51:19 +01:00
Claus 890673a197 Merge pull request #1797 from umbraco/temp-u4-9606
U4-9606 - New DumpOnTimeoutThreadAbort debug option
2017-03-16 15:38:01 +01:00
Stephan 27539d4aad U4-9606 - always minidump on Monitor.ReliableEnter exceptions 2017-03-16 14:04:28 +01:00
Stephan f7f23015d0 U4-9606 - missing file 2017-03-15 09:39:35 +01:00
Stephan e432b7061d U4-9606 - New DumpOnTimeoutThreadAbort debug option 2017-03-14 19:02:33 +01:00
Wincent fc92d40b3a Fixes jquery selector bug, http://issues.umbraco.org/issue/U4-8418 2017-03-13 11:25:02 +01:00
24 changed files with 364 additions and 99 deletions
+17 -7
View File
@@ -34,10 +34,15 @@
xdt:Transform="SetAttributes()" />
<add application="settings" alias="templates" title="Templates" type="Umbraco.Web.Trees.TemplatesTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="1"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTree, umbraco" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
xdt:Transform="SetAttributes()" />
<add application="settings" alias="partialViews" type="Umbraco.Web.Trees.PartialViewsTree, umbraco"
xdt:Locator="Match(application,alias,type)"
xdt:Transform="Remove()" />
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTreeController, umbraco" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="InsertIfMissing" />
<add application="settings" alias="scripts" title="Scripts" type="umbraco.loadScripts, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
@@ -84,9 +89,14 @@
<add application="developer" alias="xslt" title="XSLT Files" type="umbraco.loadXslt, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="5"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco"
xdt:Locator="Match(application,alias,type)"
xdt:Transform="Remove()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTreeController, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
xdt:Locator="Match(application,alias)"
xdt:Transform="InsertIfMissing" />
<add application="developer" alias="python"
xdt:Locator="Match(application,alias)"
xdt:Transform="Remove" />
+1 -1
View File
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.6.0
beta04
beta05
+1 -1
View File
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.6.0")]
[assembly: AssemblyInformationalVersion("7.6.0-beta04")]
[assembly: AssemblyInformationalVersion("7.6.0-beta05")]
@@ -18,10 +18,14 @@ namespace Umbraco.Core.Configuration
{
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase);
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings["Umbraco.CoreDebug.DumpOnTimeoutThreadAbort"], StringComparison.OrdinalIgnoreCase);
}
// when true, Scope logs the stack trace for any scope that gets disposed without being completed.
// this helps troubleshooting rogue scopes that we forget to complete
public bool LogUncompletedScopes { get; private set; }
// when true, the Logger creates a minidump of w3wp in ~/App_Data/MiniDump whenever it logs
// an error due to a ThreadAbortException that is due to a timeout.
public bool DumpOnTimeoutThreadAbort { get; private set; }
}
}
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "beta04"; } }
public static string CurrentComment { get { return "beta05"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+135
View File
@@ -0,0 +1,135 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Umbraco.Core.IO;
namespace Umbraco.Core.Diagnostics
{
// taken from https://blogs.msdn.microsoft.com/dondu/2010/10/24/writing-minidumps-in-c/
// and https://blogs.msdn.microsoft.com/dondu/2010/10/31/writing-minidumps-from-exceptions-in-c/
// which itself got it from http://blog.kalmbach-software.de/2008/12/13/writing-minidumps-in-c/
internal static class MiniDump
{
private static readonly object LockO = new object();
[Flags]
public enum Option : uint
{
// From dbghelp.h:
Normal = 0x00000000,
WithDataSegs = 0x00000001,
WithFullMemory = 0x00000002,
WithHandleData = 0x00000004,
FilterMemory = 0x00000008,
ScanMemory = 0x00000010,
WithUnloadedModules = 0x00000020,
WithIndirectlyReferencedMemory = 0x00000040,
FilterModulePaths = 0x00000080,
WithProcessThreadData = 0x00000100,
WithPrivateReadWriteMemory = 0x00000200,
WithoutOptionalData = 0x00000400,
WithFullMemoryInfo = 0x00000800,
WithThreadInfo = 0x00001000,
WithCodeSegs = 0x00002000,
WithoutAuxiliaryState = 0x00004000,
WithFullAuxiliaryState = 0x00008000,
WithPrivateWriteCopyMemory = 0x00010000,
IgnoreInaccessibleMemory = 0x00020000,
ValidTypeFlags = 0x0003ffff,
}
//typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
// DWORD ThreadId;
// PEXCEPTION_POINTERS ExceptionPointers;
// BOOL ClientPointers;
//} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
[StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64!
public struct MiniDumpExceptionInformation
{
public uint ThreadId;
public IntPtr ExceptionPointers;
[MarshalAs(UnmanagedType.Bool)]
public bool ClientPointers;
}
//BOOL
//WINAPI
//MiniDumpWriteDump(
// __in HANDLE hProcess,
// __in DWORD ProcessId,
// __in HANDLE hFile,
// __in MINIDUMP_TYPE DumpType,
// __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
// __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
// __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam
// );
// Overload requiring MiniDumpExceptionInformation
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);
// Overload supporting MiniDumpExceptionInformation == NULL
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);
[DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
private static extern uint GetCurrentThreadId();
private static bool Write(SafeHandle fileHandle, Option options, bool withException = false)
{
var currentProcess = Process.GetCurrentProcess();
var currentProcessHandle = currentProcess.Handle;
var currentProcessId = (uint)currentProcess.Id;
MiniDumpExceptionInformation exp;
exp.ThreadId = GetCurrentThreadId();
exp.ClientPointers = false;
exp.ExceptionPointers = IntPtr.Zero;
if (withException)
exp.ExceptionPointers = Marshal.GetExceptionPointers();
var bRet = exp.ExceptionPointers == IntPtr.Zero
? MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
: MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) options, ref exp, IntPtr.Zero, IntPtr.Zero);
return bRet;
}
public static bool Dump(Option options = Option.WithFullMemory, bool withException = false)
{
lock (LockO)
{
// work around "stack trace is not available while minidump debugging",
// by making sure a local var (that we can inspect) contains the stack trace.
// getting the call stack before it is unwound would require a special exception
// filter everywhere in our code = not!
var stacktrace = withException ? Environment.StackTrace : string.Empty;
var filepath = IOHelper.MapPath("~/App_Data/MiniDump");
if (Directory.Exists(filepath) == false)
Directory.CreateDirectory(filepath);
var filename = Path.Combine(filepath, string.Format("{0:yyyyMMddTHHmmss}.{1}.dmp", DateTime.UtcNow, Guid.NewGuid().ToString("N").Substring(0, 4)));
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
{
return Write(stream.SafeFileHandle, options, withException);
}
}
}
public static bool OkToDump()
{
lock (LockO)
{
var filepath = IOHelper.MapPath("~/App_Data/MiniDump");
if (Directory.Exists(filepath) == false) return true;
var count = Directory.GetFiles(filepath, "*.dmp").Length;
return count < 8;
}
}
}
}
+39 -5
View File
@@ -7,6 +7,8 @@ using System.Threading;
using System.Web;
using log4net;
using log4net.Config;
using Umbraco.Core.Configuration;
using Umbraco.Core.Diagnostics;
namespace Umbraco.Core.Logging
{
@@ -57,23 +59,55 @@ namespace Umbraco.Core.Logging
internal ILog LoggerFor(object getTypeFromInstance)
{
if (getTypeFromInstance == null) throw new ArgumentNullException("getTypeFromInstance");
return LogManager.GetLogger(getTypeFromInstance.GetType());
}
public void Error(Type callingType, string message, Exception exception)
{
var logger = LogManager.GetLogger(callingType);
if (logger == null) return;
var dump = false;
if (IsTimeoutThreadAbortException(exception))
{
message += "\r\nThe thread has been aborted, because the request has timed out.";
// dump if configured, or if stacktrace contains Monitor.ReliableEnter
dump = UmbracoConfig.For.CoreDebug().DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception);
// dump if it is ok to dump (might have a cap on number of dump...)
dump &= MiniDump.OkToDump();
}
logger.Error(message, exception);
if (dump)
{
try
{
var dumped = MiniDump.Dump(withException: true);
message += dumped
? "\r\nA minidump was created in App_Data/MiniDump"
: "\r\nFailed to create a minidump";
}
catch (Exception e)
{
message += string.Format("\r\nFailed to create a minidump ({0}: {1})", e.GetType().FullName, e.Message);
}
}
logger.Error(message, exception);
}
private static bool IsMonitorEnterThreadAbortException(Exception exception)
{
var abort = exception as ThreadAbortException;
if (abort == null) return false;
var stacktrace = abort.StackTrace;
return stacktrace.Contains("System.Threading.Monitor.ReliableEnter");
}
private static bool IsTimeoutThreadAbortException(Exception exception)
{
var abort = exception as ThreadAbortException;
@@ -105,7 +139,7 @@ namespace Umbraco.Core.Logging
if (showHttpTrace && HttpContext.Current != null)
{
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
}
}
var logger = LogManager.GetLogger(callingType);
if (logger == null || logger.IsWarnEnabled == false) return;
@@ -122,7 +156,7 @@ namespace Umbraco.Core.Logging
var logger = LogManager.GetLogger(callingType);
if (logger == null || logger.IsWarnEnabled == false) return;
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
logger.WarnFormat((message) + ". Exception: " + e, executedParams);
logger.WarnFormat((message) + ". Exception: " + e, executedParams);
}
/// <summary>
+54 -4
View File
@@ -1,5 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Models
{
@@ -84,16 +86,64 @@ namespace Umbraco.Core.Models
public string Type { get; set; }
private Type _runtimeType;
/// <summary>
/// Returns the CLR type based on it's assembly name stored in the config
/// </summary>
/// <returns></returns>
public Type GetRuntimeType()
{
return _runtimeType ?? (_runtimeType = System.Type.GetType(Type));
}
if (_runtimeType != null)
return _runtimeType;
_runtimeType = TryGetType(Type);
return _runtimeType;
}
/// <summary>
/// Used to try to get and cache the tree type
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
internal static Type TryGetType(string type)
{
try
{
return ResolvedTypes.GetOrAdd(type, s =>
{
var result = System.Type.GetType(type);
if (result != null)
{
return result;
}
//we need to implement a bit of a hack here due to some trees being renamed and backwards compat
var parts = type.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 2)
{
if (parts[1].Trim() == "umbraco" && parts[0].StartsWith("Umbraco.Web.Trees") && parts[0].EndsWith("Controller") == false)
{
//if it's one of our controllers but it's not suffixed with "Controller" then add it and try again
var tempType = parts[0] + "Controller, umbraco";
result = System.Type.GetType(tempType);
if (result != null)
{
return result;
}
}
}
throw new InvalidOperationException("Could not resolve type");
});
}
catch (InvalidOperationException)
{
//swallow, this is our own exception, couldn't find the type
return null;
}
}
private static readonly ConcurrentDictionary<string, Type> ResolvedTypes = new ConcurrentDictionary<string, Type>();
}
}
@@ -179,7 +179,7 @@ namespace Umbraco.Core.Models.PublishedContent
}
if (contentType == null)
throw new Exception(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
throw new InvalidOperationException(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
itemType.ToString().ToLower(), alias));
return new PublishedContentType(contentType);
+4 -3
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
@@ -12,7 +13,8 @@ namespace Umbraco.Core.Publishing
{
public PublishStatus(IContent content, PublishStatusType statusType, EventMessages eventMessages)
: base(content, statusType, eventMessages)
{
{
InvalidProperties = Enumerable.Empty<Property>();
}
/// <summary>
@@ -20,8 +22,7 @@ namespace Umbraco.Core.Publishing
/// </summary>
public PublishStatus(IContent content, EventMessages eventMessages)
: this(content, PublishStatusType.Success, eventMessages)
{
}
{ }
public IContent ContentItem
{
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Publishing
/// </summary>
/// <param name="uow"></param>
/// <param name="content"><see cref="IContent"/> to publish</param>
/// <param name="userId">Id of the User issueing the publish operation</param>
/// <param name="userId">Id of the User issueing the publish operation</param>
Attempt<PublishStatus> IPublishingStrategy2.Publish(IScopeUnitOfWork uow, IContent content, int userId)
{
var evtMsgs = _eventMessagesFactory.Get();
@@ -124,26 +124,26 @@ namespace Umbraco.Core.Publishing
/// By default this is set to true which means that it will publish any content item in the list that is completely unpublished and
/// not visible on the front-end. If set to false, this will only publish content that is live on the front-end but has new versions
/// that have yet to be published.
/// </param>
/// </param>
/// <returns></returns>
/// <remarks>
///
///
/// This method becomes complex once we start to be able to cancel events or stop publishing a content item in any way because if a
/// content item is not published then it's children shouldn't be published either. This rule will apply for the following conditions:
/// * If a document fails to be published, do not proceed to publish it's children if:
/// ** The document does not have a publish version
/// ** The document does have a published version but the includeUnpublishedDocuments = false
///
///
/// In order to do this, we will order the content by level and begin by publishing each item at that level, then proceed to the next
/// level and so on. If we detect that the above rule applies when the document publishing is cancelled we'll add it to the list of
/// level and so on. If we detect that the above rule applies when the document publishing is cancelled we'll add it to the list of
/// parentsIdsCancelled so that it's children don't get published.
///
///
/// Its important to note that all 'root' documents included in the list *will* be published regardless of the rules mentioned
/// above (unless it is invalid)!! By 'root' documents we are referring to documents in the list with the minimum value for their 'level'.
/// In most cases the 'root' documents will only be one document since under normal circumstance we only publish one document and
/// above (unless it is invalid)!! By 'root' documents we are referring to documents in the list with the minimum value for their 'level'.
/// In most cases the 'root' documents will only be one document since under normal circumstance we only publish one document and
/// its children. The reason we have to do this is because if a user is publishing a document and it's children, it is implied that
/// the user definitely wants to publish it even if it has never been published before.
///
///
/// </remarks>
IEnumerable<Attempt<PublishStatus>> IPublishingStrategy2.PublishWithChildren(IScopeUnitOfWork uow,
IEnumerable<IContent> content, int userId, bool includeUnpublishedDocuments)
@@ -157,7 +157,7 @@ namespace Umbraco.Core.Publishing
//group by levels and iterate over the sorted ascending level.
//TODO: This will cause all queries to execute, they will not be lazy but I'm not really sure being lazy actually made
// much difference because we iterate over them all anyways?? Morten?
// much difference because we iterate over them all anyways?? Morten?
// Because we're grouping I think this will execute all the queries anyways so need to fetch it all first.
var fetchedContent = content.ToArray();
@@ -174,7 +174,7 @@ namespace Umbraco.Core.Publishing
var levelGroups = fetchedContent.GroupBy(x => x.Level);
foreach (var level in levelGroups.OrderBy(x => x.Key))
{
//set the first level flag, used to ensure that all documents at the first level will
//set the first level flag, used to ensure that all documents at the first level will
//be published regardless of the rules mentioned in the remarks.
if (!firstLevel.HasValue)
{
@@ -224,7 +224,10 @@ namespace Umbraco.Core.Publishing
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published because some of it's content is not passing validation rules.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid, evtMsgs)));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid, evtMsgs)
{
InvalidProperties = ((ContentBase)item).LastInvalidProperties
}));
//Does this document apply to our rule to cancel it's children being published?
CheckCancellingOfChildPublishing(item, parentsIdsCancelled, includeUnpublishedDocuments);
@@ -296,11 +299,11 @@ namespace Umbraco.Core.Publishing
/// <param name="includeUnpublishedDocuments"></param>
/// <remarks>
/// See remarks on method: PublishWithChildrenInternal
/// </remarks>
/// </remarks>
private void CheckCancellingOfChildPublishing(IContent content, List<int> parentsIdsCancelled, bool includeUnpublishedDocuments)
{
//Does this document apply to our rule to cancel it's children being published?
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
// any document that fails to publish...
var hasPublishedVersion = ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
@@ -358,9 +358,8 @@ namespace Umbraco.Core.Services
{
var applicationAlias = (string)addElement.Attribute("application");
var type = (string)addElement.Attribute("type");
var assembly = (string)addElement.Attribute("assembly");
var clrType = Type.GetType(type);
var clrType = ApplicationTree.TryGetType(type);
if (clrType == null)
{
_logger.Warn<ApplicationTreeService>("The tree definition: " + addElement.ToString() + " could not be resolved to a .Net object type");
+2 -1
View File
@@ -199,6 +199,7 @@
<Compile Include="Configuration\BaseRest\ExtensionElementCollection.cs" />
<Compile Include="Configuration\BaseRest\MethodElement.cs" />
<Compile Include="Configuration\ContentXmlStorage.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\Dashboard\AccessElement.cs" />
<Compile Include="Configuration\Dashboard\AccessItem.cs" />
<Compile Include="Configuration\Dashboard\AccessType.cs" />
@@ -219,7 +220,6 @@
<Compile Include="Configuration\Dashboard\SectionElement.cs" />
<Compile Include="Configuration\Dashboard\TabCollection.cs" />
<Compile Include="Configuration\Dashboard\TabElement.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\FileSystemProviderElement.cs" />
<Compile Include="Configuration\FileSystemProviderElementCollection.cs" />
<Compile Include="Configuration\FileSystemProvidersSection.cs" />
@@ -323,6 +323,7 @@
<Compile Include="DateTimeExtensions.cs" />
<Compile Include="DecimalExtensions.cs" />
<Compile Include="DelegateExtensions.cs" />
<Compile Include="Diagnostics\MiniDump.cs" />
<Compile Include="Deploy\ArtifactBase.cs" />
<Compile Include="Deploy\ArtifactDependency.cs" />
<Compile Include="Deploy\ArtifactDependencyCollection.cs" />
@@ -163,13 +163,13 @@ angular.module('umbraco.directives')
}
// ignore clicks on dialog from old dialog service
var oldDialog = $(el).parents("#old-dialog-service");
var oldDialog = $(event.target).parents("#old-dialog-service");
if (oldDialog.length === 1) {
return;
}
// ignore clicks in tinyMCE dropdown(floatpanel)
var floatpanel = $(el).parents(".mce-floatpanel");
var floatpanel = $(event.target).closest(".mce-floatpanel");
if (floatpanel.length === 1) {
return;
}
@@ -50,6 +50,10 @@ angular.module('umbraco.mocks').
.whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetByIds'))
.respond(returnEntitybyIds);
$httpBackend
.whenPOST(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetByIds'))
.respond(returnEntitybyIds);
$httpBackend
.whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetAncestors'))
.respond(returnEntitybyIds);
@@ -80,7 +80,7 @@
<div id="feedbackMsg" data-bind="visible: processStatus() == 'complete'">
<div data-bind="css: { success: isSuccessful(), error: !isSuccessful() }">
<div data-bind="css: { 'text-success': isSuccessful(), 'text-error': !isSuccessful() }">
<span data-bind="text: resultMessage, visible: resultMessages().length == 0"></span>
<ul data-bind="foreach: resultMessages, visible: resultMessages().length > 1">
<li data-bind="text: message"></li>
@@ -4,6 +4,7 @@ using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
@@ -315,9 +316,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
private void InitializeNode()
{
InitializeNode(_xmlNode, UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema, _isPreviewing,
out _id, out _key, out _template, out _sortOrder, out _name, out _writerName,
out _urlName, out _creatorName, out _creatorId, out _writerId, out _docTypeAlias, out _docTypeId, out _path,
InitializeNode(_xmlNode, UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema, _isPreviewing,
out _id, out _key, out _template, out _sortOrder, out _name, out _writerName,
out _urlName, out _creatorName, out _creatorId, out _writerId, out _docTypeAlias, out _docTypeId, out _path,
out _version, out _createDate, out _updateDate, out _level, out _isDraft, out _contentType, out _properties,
PublishedContentType.Get);
@@ -345,7 +346,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
//return if this is null
if (xmlNode == null)
{
{
return;
}
@@ -407,8 +408,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
//dictionary to store the property node data
var propertyNodes = new Dictionary<string, XmlNode>();
var propertyNodes = new Dictionary<string, XmlNode>();
foreach (XmlNode n in xmlNode.ChildNodes)
{
var e = n as XmlElement;
@@ -432,7 +433,22 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
//lookup the content type and create the properties collection
contentType = getPublishedContentType(PublishedItemType.Content, docTypeAlias);
try
{
contentType = getPublishedContentType(PublishedItemType.Content, docTypeAlias);
}
catch (InvalidOperationException e)
{
content.Instance.RefreshContentFromDatabase();
throw new InvalidOperationException(
string.Format("{0}. This usually indicates that the content cache is corrupt; the content cache has been rebuilt in an attempt to self-fix the issue.",
//keep the original message but don't use this as an inner exception because we want the above message to be displayed, if we use the inner exception
//we can keep the stack trace but the header message will be the original message and the one we really want to display will be hidden below the fold.
e.Message));
}
properties = new Dictionary<string, IPublishedProperty>(StringComparer.OrdinalIgnoreCase);
//fill in the property collection
@@ -207,7 +207,11 @@ namespace Umbraco.Web.Trees
return false;
}
IContent content = Services.ContentService.GetById(entity.Id);
var content = Services.ContentService.GetById(entity.Id);
if (content == null)
{
return false;
}
return Security.CurrentUser.HasPathAccess(content);
}
@@ -308,7 +308,7 @@ namespace Umbraco.Web.Trees
{
IUmbracoEntity entity;
Guid idGuid = Guid.Empty;
Guid idGuid;
int idInt;
Udi idUdi;
+9 -3
View File
@@ -76,7 +76,7 @@ namespace Umbraco.Web.Trees
entity,
Constants.ObjectTypes.MediaGuid,
parentId,
queryStrings,
queryStrings,
entity.HasChildren && (isContainer == false));
node.AdditionalData.Add("contentType", entity.ContentTypeAlias);
@@ -130,7 +130,7 @@ namespace Umbraco.Web.Trees
menu.Items.Add<ActionRefresh>(ui.Text("actions", ActionRefresh.Instance.Alias), true);
//if the media item is in the recycle bin, don't have a default menu, just show the regular menu
if (item.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString()))
if (item.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString()))
{
menu.DefaultMenuAlias = null;
}
@@ -151,7 +151,13 @@ namespace Umbraco.Web.Trees
/// <returns></returns>
protected override bool HasPathAccess(string id, FormDataCollection queryStrings)
{
var media = Services.MediaService.GetById(int.Parse(id));
var entity = GetEntityFromId(id);
if (entity == null)
{
return false;
}
var media = Services.MediaService.GetById(entity.Id);
if (media == null)
{
return false;
@@ -46,16 +46,16 @@ namespace Umbraco.Web.WebServices
/*var result = ((ContentService) Services.ContentService)
.PublishWithChildrenInternal(content, UmbracoUser.Id, includeUnpublished)
.ToArray();*/
var result = doc.PublishWithSubs(UmbracoUser.Id, includeUnpublished);
var result = doc.PublishWithSubs(UmbracoUser.Id, includeUnpublished).ToArray();
return Json(new
{
success = result.All(x => x.Success),
message = GetMessageForStatuses(result.Select(x => x.Result), content)
message = GetMessageForStatuses(result.Select(x => x.Result).ToArray(), content)
});
}
}
private string GetMessageForStatuses(IEnumerable<PublishStatus> statuses, IContent doc)
private string GetMessageForStatuses(PublishStatus[] statuses, IContent doc)
{
//if all are successful then just say it was successful
if (statuses.All(x => ((int) x.StatusType) < 10))
@@ -91,12 +91,12 @@ namespace Umbraco.Web.WebServices
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);
string.Format("'{0}' ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser);
case PublishStatusType.FailedContentInvalid:
return ui.Text("publish", "contentPublishedFailedInvalid",
new []{
string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id),
string.Join(",", status.InvalidProperties.Select(x => x.Alias))
string.Format("'{0}' ({1})", status.ContentItem.Name, status.ContentItem.Id),
string.Format("'{0}'", string.Join(", ", status.InvalidProperties.Select(x => x.Alias)))
},
UmbracoUser);
default:
@@ -99,7 +99,7 @@ namespace umbraco.presentation.preview
//Inject preview xml
parentId = document.Level == 1 ? -1 : document.ParentId;
var previewXml = document.ToPreviewXml(XmlContent);
if (document.ContentEntity.Published == false
if (document.ContentEntity.Published == false
&& ApplicationContext.Current.Services.ContentService.HasPublishedVersion(document.Id))
previewXml.Attributes.Append(XmlContent.CreateAttribute("isDraft"));
XmlContent = content.GetAddOrUpdateXmlNode(XmlContent, document.Id, document.Level, parentId, previewXml);
@@ -187,13 +187,9 @@ namespace umbraco.presentation.preview
private static void CleanPreviewDirectory(int userId, DirectoryInfo dir)
{
foreach (FileInfo file in dir.GetFiles(userId + "_*.config"))
{
DeletePreviewFile(userId, file);
}
// also delete any files accessed more than 10 minutes ago
var now = DateTime.Now;
foreach (FileInfo file in dir.GetFiles("*.config"))
foreach (var file in dir.GetFiles("*.config"))
{
if ((now - file.LastAccessTime).TotalMinutes > 10)
DeletePreviewFile(userId, file);
@@ -206,6 +202,12 @@ namespace umbraco.presentation.preview
{
file.Delete();
}
catch (IOException)
{
// for *some* reason deleting the file can fail,
// and it will work later on (long-lasting locks, etc),
// so just ignore the exception
}
catch (Exception ex)
{
LogHelper.Error<PreviewContent>(string.Format("Couldn't delete preview set: {0} - User {1}", file.Name, userId), ex);
@@ -302,7 +302,11 @@ namespace umbraco.cms.businesslogic.packager
XmlHelper.SetAttribute(Source, xmlDef, "enableSkins", package.EnableSkins.ToString());
XmlHelper.SetAttribute(Source, xmlDef, "skinRepoGuid", package.SkinRepoGuid.ToString());
XmlHelper.SetAttribute(Source, xmlDef, "iconUrl", package.IconUrl);
XmlHelper.SetAttribute(Source, xmlDef, "umbVersion", package.UmbracoVersion.ToString(3));
if (package.UmbracoVersion != null)
{
XmlHelper.SetAttribute(Source, xmlDef, "umbVersion", package.UmbracoVersion.ToString(3));
}
var licenseNode = xmlDef.SelectSingleNode("license");
if (licenseNode == null)
+22 -30
View File
@@ -874,18 +874,15 @@ namespace umbraco.cms.businesslogic.web
[Obsolete("Don't use! Only used internally to support the legacy events", false)]
internal IEnumerable<Attempt<PublishStatus>> PublishWithSubs(int userId, bool includeUnpublished)
{
PublishEventArgs e = new PublishEventArgs();
var e = new PublishEventArgs();
FireBeforePublish(e);
IEnumerable<Attempt<PublishStatus>> publishedResults = Enumerable.Empty<Attempt<PublishStatus>>();
if (e.Cancel) return Enumerable.Empty<Attempt<PublishStatus>>();
if (!e.Cancel)
{
publishedResults = ApplicationContext.Current.Services.ContentService
.PublishWithChildrenWithStatus(ContentEntity, userId, includeUnpublished);
var publishedResults = ApplicationContext.Current.Services.ContentService
.PublishWithChildrenWithStatus(ContentEntity, userId, includeUnpublished);
FireAfterPublish(e);
}
FireAfterPublish(e);
return publishedResults;
}
@@ -893,7 +890,6 @@ namespace umbraco.cms.businesslogic.web
[Obsolete("Don't use! Only used internally to support the legacy events", false)]
internal Attempt<PublishStatus> SaveAndPublish(int userId)
{
var result = Attempt.Fail(new PublishStatus(ContentEntity, PublishStatusType.FailedCancelledByEvent, new EventMessages()));
foreach (var property in GenericProperties)
{
ContentEntity.SetValue(property.PropertyType.Alias, property.Value);
@@ -901,32 +897,28 @@ namespace umbraco.cms.businesslogic.web
var saveArgs = new SaveEventArgs();
FireBeforeSave(saveArgs);
if (saveArgs.Cancel) return Attempt.Fail(new PublishStatus(ContentEntity, PublishStatusType.FailedCancelledByEvent, new EventMessages()));
if (!saveArgs.Cancel)
{
var publishArgs = new PublishEventArgs();
FireBeforePublish(publishArgs);
var publishArgs = new PublishEventArgs();
FireBeforePublish(publishArgs);
if (publishArgs.Cancel) return Attempt.Fail(new PublishStatus(ContentEntity, PublishStatusType.FailedCancelledByEvent, new EventMessages()));
if (!publishArgs.Cancel)
{
//NOTE: The 'false' parameter will cause the PublishingStrategy events to fire which will ensure that the cache is refreshed.
result = ApplicationContext.Current.Services.ContentService
.SaveAndPublishWithStatus(ContentEntity, userId);
base.VersionDate = ContentEntity.UpdateDate;
this.UpdateDate = ContentEntity.UpdateDate;
//NOTE: The 'false' parameter will cause the PublishingStrategy events to fire which will ensure that the cache is refreshed.
var result = ApplicationContext.Current.Services.ContentService
.SaveAndPublishWithStatus(ContentEntity, userId);
VersionDate = ContentEntity.UpdateDate;
UpdateDate = ContentEntity.UpdateDate;
//NOTE: This is just going to call the CMSNode Save which will launch into the CMSNode.BeforeSave and CMSNode.AfterSave evenths
// which actually do dick all and there's no point in even having them there but just in case for some insane reason someone
// has bound to those events, I suppose we'll need to keep this here.
base.Save();
//NOTE: This is just going to call the CMSNode Save which will launch into the CMSNode.BeforeSave and CMSNode.AfterSave evenths
// which actually do dick all and there's no point in even having them there but just in case for some insane reason someone
// has bound to those events, I suppose we'll need to keep this here.
base.Save();
//Launch the After Save event since we're doing 2 things in one operation: Saving and publishing.
FireAfterSave(saveArgs);
//Launch the After Save event since we're doing 2 things in one operation: Saving and publishing.
FireAfterSave(saveArgs);
//Now we need to fire the After publish event
FireAfterPublish(publishArgs);
}
}
//Now we need to fire the After publish event
FireAfterPublish(publishArgs);
return result;
}