Port 7.7 - WIP
This commit is contained in:
89
src/Umbraco.Core/Publishing/ScheduledPublisher.cs
Normal file
89
src/Umbraco.Core/Publishing/ScheduledPublisher.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Publishing
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to perform scheduled publishing/unpublishing
|
||||
/// </summary>
|
||||
internal class ScheduledPublisher
|
||||
{
|
||||
private readonly IContentService _contentService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ScheduledPublisher(IContentService contentService, ILogger logger)
|
||||
{
|
||||
_contentService = contentService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes scheduled operations
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Returns the number of items successfully completed
|
||||
/// </returns>
|
||||
public int CheckPendingAndProcess()
|
||||
{
|
||||
var counter = 0;
|
||||
var contentForRelease = _contentService.GetContentForRelease().ToArray();
|
||||
if (contentForRelease.Length > 0)
|
||||
_logger.Debug<ScheduledPublisher>($"There's {contentForRelease.Length} item(s) of content to be published");
|
||||
foreach (var d in contentForRelease)
|
||||
{
|
||||
try
|
||||
{
|
||||
d.ReleaseDate = null;
|
||||
var result = _contentService.SaveAndPublishWithStatus(d, d.GetWriterProfile().Id);
|
||||
_logger.Debug<ContentService>($"Result of publish attempt: {result.Result.StatusType}");
|
||||
if (result.Success == false)
|
||||
{
|
||||
if (result.Exception != null)
|
||||
{
|
||||
_logger.Error<ScheduledPublisher>("Could not published the document (" + d.Id + ") based on it's scheduled release, status result: " + result.Result.StatusType, result.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn<ScheduledPublisher>("Could not published the document (" + d.Id + ") based on it's scheduled release. Status result: " + result.Result.StatusType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
_logger.Error<ScheduledPublisher>($"Error publishing node {d.Id}", ee);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
var contentForExpiration = _contentService.GetContentForExpiration().ToArray();
|
||||
if (contentForExpiration.Length > 0)
|
||||
_logger.Debug<ScheduledPublisher>($"There's {contentForExpiration.Length} item(s) of content to be unpublished");
|
||||
foreach (var d in contentForExpiration)
|
||||
{
|
||||
try
|
||||
{
|
||||
d.ExpireDate = null;
|
||||
var result = _contentService.UnPublish(d, d.GetWriterProfile().Id);
|
||||
if (result)
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
_logger.Error<ScheduledPublisher>($"Error unpublishing node {d.Id}", ee);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1264,6 +1264,7 @@
|
||||
<Compile Include="PropertyEditors\ValueConverters\UploadPropertyConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\YesNoValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueValidatorAttribute.cs" />
|
||||
<Compile Include="Publishing\ScheduledPublisher.cs" />
|
||||
<Compile Include="ReadLock.cs" />
|
||||
<Compile Include="RenderingEngine.cs" />
|
||||
<Compile Include="RuntimeLevel.cs" />
|
||||
|
||||
@@ -3,6 +3,7 @@ using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Web.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
@@ -50,15 +51,13 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
var dataTypeCache = CacheHelper.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>();
|
||||
|
||||
//clears the prevalue cache
|
||||
if (dataTypeCache)
|
||||
foreach (var payload in payloads)
|
||||
dataTypeCache.Result.ClearCacheByKeySearch(CacheKeys.DataTypePreValuesCacheKey + "_" + payload.Id);
|
||||
|
||||
foreach (var payload in payloads)
|
||||
{
|
||||
{
|
||||
if (dataTypeCache)
|
||||
dataTypeCache.Result.ClearCacheByKeySearch(CacheKeys.DataTypePreValuesCacheKey + "_" + payload.Id);
|
||||
|
||||
_idkMap.ClearCache(payload.Id);
|
||||
#error also nested content see 7.7
|
||||
NestedContentHelper.ClearCache(payload.Id); // fixme refactor nested content
|
||||
}
|
||||
|
||||
// fixme - not sure I like these?
|
||||
|
||||
@@ -9,7 +9,6 @@ using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.ModelBinding;
|
||||
using AutoMapper;
|
||||
using umbraco.BusinessLogic.Actions;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using Umbraco.Core.Services;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
@@ -8,7 +10,6 @@ using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
@@ -66,7 +67,7 @@ namespace Umbraco.Web.Editors
|
||||
public async Task<HttpResponseMessage> PostSetAvatar()
|
||||
{
|
||||
//borrow the logic from the user controller
|
||||
return await UsersController.PostSetAvatarInternal(Request, Services.UserService, ApplicationContext.ApplicationCache.StaticCache, Security.GetUserId());
|
||||
return await UsersController.PostSetAvatarInternal(Request, Services.UserService, Current.ApplicationCache.StaticCache, Security.GetUserId());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Web.Http;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
@@ -16,8 +13,6 @@ using System.Net.Http;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using Examine;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using System.Web.Http.Controllers;
|
||||
using Umbraco.Core.Xml;
|
||||
@@ -36,7 +31,6 @@ namespace Umbraco.Web.Editors
|
||||
[PluginController("UmbracoApi")]
|
||||
public class EntityController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Configures this controller with a custom action selector
|
||||
/// </summary>
|
||||
@@ -56,6 +50,12 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
private readonly UmbracoTreeSearcher _treeSearcher = new UmbracoTreeSearcher();
|
||||
private readonly SearchableTreeCollection _searchableTreeCollection;
|
||||
|
||||
public EntityController(SearchableTreeCollection searchableTreeCollection)
|
||||
{
|
||||
_searchableTreeCollection = searchableTreeCollection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an Umbraco alias given a string
|
||||
@@ -65,7 +65,7 @@ namespace Umbraco.Web.Editors
|
||||
/// <returns></returns>
|
||||
public dynamic GetSafeAlias(string value, bool camelCase = true)
|
||||
{
|
||||
var returnValue = (string.IsNullOrWhiteSpace(value)) ? string.Empty : value.ToSafeAlias(camelCase);
|
||||
var returnValue = string.IsNullOrWhiteSpace(value) ? string.Empty : value.ToSafeAlias(camelCase);
|
||||
dynamic returnObj = new System.Dynamic.ExpandoObject();
|
||||
returnObj.alias = returnValue;
|
||||
returnObj.original = value;
|
||||
@@ -107,7 +107,7 @@ namespace Umbraco.Web.Editors
|
||||
///
|
||||
/// The reason a user is allowed to search individual entity types that they are not allowed to edit is because those search
|
||||
/// methods might be used in things like pickers in the content editor.
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
[HttpGet]
|
||||
public IDictionary<string, TreeSearchResult> SearchAll(string query)
|
||||
{
|
||||
@@ -115,17 +115,17 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
if (string.IsNullOrEmpty(query))
|
||||
return result;
|
||||
|
||||
|
||||
var allowedSections = Security.CurrentUser.AllowedSections.ToArray();
|
||||
var searchableTrees = SearchableTreeResolver.Current.GetSearchableTrees();
|
||||
|
||||
var searchableTrees = _searchableTreeCollection.AsReadOnlyDictionary();
|
||||
|
||||
foreach (var searchableTree in searchableTrees)
|
||||
{
|
||||
if (allowedSections.Contains(searchableTree.Value.AppAlias))
|
||||
{
|
||||
var tree = Services.ApplicationTreeService.GetByAlias(searchableTree.Key);
|
||||
if (tree == null) continue; //shouldn't occur
|
||||
#error why cannot we use a collectino?
|
||||
|
||||
var searchableTreeAttribute = searchableTree.Value.SearchableTree.GetType().GetCustomAttribute<SearchableTreeAttribute>(false);
|
||||
var treeAttribute = tree.GetTreeAttribute();
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Umbraco.Web.Editors
|
||||
JsFormatterMethod = searchableTreeAttribute == null ? "" : searchableTreeAttribute.MethodName
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ namespace Umbraco.Web.Editors
|
||||
return _treeSearcher.ExamineSearch(Umbraco, query, entityType, 200, 0, out total, searchFrom);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private IEnumerable<EntityBasic> GetResultForChildren(int id, UmbracoEntityTypes entityType)
|
||||
|
||||
@@ -1,40 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using ClientDependency.Core.Config;
|
||||
using Microsoft.Owin.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
using Umbraco.Core.Configuration;
|
||||
using Core.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// HtmlHelper extensions for the back office
|
||||
/// </summary>
|
||||
public static class HtmlHelperBackOfficeExtensions
|
||||
{
|
||||
[Obsolete("Use the overload with all required parameters instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static IHtmlString BareMinimumServerVariablesScript(this HtmlHelper html, UrlHelper uri, string externalLoginsUrl)
|
||||
{
|
||||
return html.BareMinimumServerVariablesScript(uri, ApplicationContext.Current, externalLoginsUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a script tag containing the bare minimum (non secure) server vars for use with the angular app
|
||||
/// </summary>
|
||||
/// <param name="html"></param>
|
||||
/// <param name="uri"></param>
|
||||
/// <param name="appCtx"></param>
|
||||
/// <param name="externalLoginsUrl">
|
||||
/// The post url used to sign in with external logins - this can change depending on for what service the external login is service.
|
||||
/// Example: normal back office login or authenticating upgrade login
|
||||
@@ -44,9 +32,9 @@ namespace Umbraco.Web
|
||||
/// These are the bare minimal server variables that are required for the application to start without being authenticated,
|
||||
/// we will load the rest of the server vars after the user is authenticated.
|
||||
/// </remarks>
|
||||
public static IHtmlString BareMinimumServerVariablesScript(this HtmlHelper html, UrlHelper uri, ApplicationContext appCtx, string externalLoginsUrl)
|
||||
public static IHtmlString BareMinimumServerVariablesScript(this HtmlHelper html, UrlHelper uri, string externalLoginsUrl)
|
||||
{
|
||||
var serverVars = new BackOfficeServerVariables(uri, appCtx, UmbracoConfig.For.UmbracoSettings());
|
||||
var serverVars = new BackOfficeServerVariables(uri, Current.RuntimeState);
|
||||
var minVars = serverVars.BareMinimumServerVariables();
|
||||
|
||||
var str = @"<script type=""text/javascript"">
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Web.Configuration;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.Install.Models;
|
||||
@@ -16,26 +13,15 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
PerformsAppRestart = true)]
|
||||
internal class ConfigureMachineKey : InstallSetupStep<bool?>
|
||||
{
|
||||
private readonly ApplicationContext _appContext;
|
||||
|
||||
public ConfigureMachineKey(ApplicationContext appContext)
|
||||
{
|
||||
if (appContext == null) throw new ArgumentNullException("appContext");
|
||||
_appContext = appContext;
|
||||
}
|
||||
|
||||
public override string View
|
||||
{
|
||||
get { return HasMachineKey() == false ? base.View : ""; }
|
||||
}
|
||||
public override string View => HasMachineKey() == false ? base.View : "";
|
||||
|
||||
/// <summary>
|
||||
/// Don't display the view or execute if a machine key already exists
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool HasMachineKey()
|
||||
private static bool HasMachineKey()
|
||||
{
|
||||
var section = (MachineKeySection)WebConfigurationManager.GetSection("system.web/machineKey");
|
||||
var section = (MachineKeySection) WebConfigurationManager.GetSection("system.web/machineKey");
|
||||
return section.ElementInformation.Source != null;
|
||||
}
|
||||
|
||||
@@ -49,7 +35,7 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
if (model.HasValue && model.Value == false) return null;
|
||||
|
||||
//install the machine key
|
||||
var fileName = IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root));
|
||||
var fileName = IOHelper.MapPath($"{SystemDirectories.Root}/web.config");
|
||||
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
|
||||
|
||||
var systemWeb = xml.Root.DescendantsAndSelf("system.web").Single();
|
||||
|
||||
@@ -1,52 +1,44 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
internal class DetachedPublishedProperty : IPublishedProperty
|
||||
{
|
||||
private readonly PublishedPropertyType _propertyType;
|
||||
private readonly object _rawValue;
|
||||
private readonly Lazy<object> _sourceValue;
|
||||
private readonly object _sourceValue;
|
||||
private readonly Lazy<object> _objectValue;
|
||||
private readonly Lazy<object> _xpathValue;
|
||||
private readonly bool _isPreview;
|
||||
|
||||
public DetachedPublishedProperty(PublishedPropertyType propertyType, object value)
|
||||
: this(propertyType, value, false)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
public DetachedPublishedProperty(PublishedPropertyType propertyType, object value, bool isPreview)
|
||||
{
|
||||
_propertyType = propertyType;
|
||||
_isPreview = isPreview;
|
||||
|
||||
_rawValue = value;
|
||||
_sourceValue = value;
|
||||
|
||||
_sourceValue = new Lazy<object>(() => _propertyType.ConvertDataToSource(_rawValue, _isPreview));
|
||||
_objectValue = new Lazy<object>(() => _propertyType.ConvertSourceToObject(_sourceValue.Value, _isPreview));
|
||||
_xpathValue = new Lazy<object>(() => _propertyType.ConvertSourceToXPath(_sourceValue.Value, _isPreview));
|
||||
IPropertySet propertySet = null; // fixme!! nested content needs complete refactoring!
|
||||
|
||||
var interValue = new Lazy<object>(() => _propertyType.ConvertSourceToInter(propertySet, _sourceValue, _isPreview));
|
||||
_objectValue = new Lazy<object>(() => _propertyType.ConvertInterToObject(propertySet, PropertyCacheLevel.None, interValue.Value, _isPreview));
|
||||
_xpathValue = new Lazy<object>(() => _propertyType.ConvertInterToXPath(propertySet, PropertyCacheLevel.None, interValue.Value, _isPreview));
|
||||
}
|
||||
|
||||
public string PropertyTypeAlias
|
||||
{
|
||||
get
|
||||
{
|
||||
return _propertyType.PropertyTypeAlias;
|
||||
}
|
||||
}
|
||||
public string PropertyTypeAlias => _propertyType.PropertyTypeAlias;
|
||||
|
||||
public bool HasValue
|
||||
{
|
||||
get { return DataValue != null && DataValue.ToString().Trim().Length > 0; }
|
||||
}
|
||||
public bool HasValue => SourceValue != null && SourceValue.ToString().Trim().Length > 0;
|
||||
|
||||
public object DataValue { get { return _rawValue; } }
|
||||
public object SourceValue => _sourceValue;
|
||||
|
||||
public object Value { get { return _objectValue.Value; } }
|
||||
public object Value => _objectValue.Value;
|
||||
|
||||
public object XPathValue { get { return _xpathValue.Value; } }
|
||||
public object XPathValue => _xpathValue.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements an Application Event Handler for managing redirect urls tracking.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>when content is renamed or moved, we want to create a permanent 301 redirect from it's old url</para>
|
||||
/// <para>not managing domains because we don't know how to do it - changing domains => must create a higher level strategy using rewriting rules probably</para>
|
||||
/// <para>recycle bin = moving to and from does nothing: to = the node is gone, where would we redirect? from = same</para>
|
||||
/// </remarks>
|
||||
public class RedirectTrackingEventHandler : ApplicationEventHandler
|
||||
{
|
||||
private const string ContextKey1 = "Umbraco.Web.Routing.RedirectTrackingEventHandler.1";
|
||||
private const string ContextKey2 = "Umbraco.Web.Routing.RedirectTrackingEventHandler.2";
|
||||
private const string ContextKey3 = "Umbraco.Web.Routing.RedirectTrackingEventHandler.3";
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking)
|
||||
{
|
||||
ContentFinderResolver.Current.RemoveType<ContentFinderByRedirectUrl>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if any of these dlls are loaded we don't want to run our finder
|
||||
var dlls = new[]
|
||||
{
|
||||
"InfoCaster.Umbraco.UrlTracker",
|
||||
"SEOChecker",
|
||||
"Simple301",
|
||||
"Terabyte.Umbraco.Modules.PermanentRedirect",
|
||||
"CMUmbracoTools",
|
||||
"PWUrlRedirect"
|
||||
};
|
||||
|
||||
// assuming all assemblies have been loaded already
|
||||
// check if any of them matches one of the above dlls
|
||||
var found = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Select(x => x.FullName.Split(',')[0])
|
||||
.Any(x => dlls.Contains(x));
|
||||
if (found)
|
||||
ContentFinderResolver.Current.RemoveType<ContentFinderByRedirectUrl>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
// don't let the event handlers kick in if Redirect Tracking is turned off in the config
|
||||
if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking) return;
|
||||
|
||||
// events are weird
|
||||
// on 'published' we 'could' get the old or the new route depending on event handlers order
|
||||
// so it is not reliable. getting the old route in 'publishing' to be sure and storing in http
|
||||
// context. then for the same reason, we have to process these old items only when the cache
|
||||
// is ready
|
||||
// when moving, the moved node is also published, which is causing all sorts of troubles with
|
||||
// descendants, so when moving, we lock events so that neither 'published' nor 'publishing'
|
||||
// are processed more than once
|
||||
//
|
||||
// this is all verrrry weird but it seems to work
|
||||
|
||||
ContentService.Publishing += ContentService_Publishing;
|
||||
ContentService.Published += ContentService_Published;
|
||||
ContentService.Moving += ContentService_Moving;
|
||||
ContentService.Moved += ContentService_Moved;
|
||||
PageCacheRefresher.CacheUpdated += PageCacheRefresher_CacheUpdated;
|
||||
|
||||
// kill all redirects once a content is deleted
|
||||
//ContentService.Deleted += ContentService_Deleted;
|
||||
// BUT, doing it here would prevent content deletion due to FK
|
||||
// so the rows are actually deleted by the ContentRepository (see GetDeleteClauses)
|
||||
|
||||
// rolled back items have to be published, so publishing will take care of that
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks a documents URLs during publishing in the current request
|
||||
/// </summary>
|
||||
private static Dictionary<int, Tuple<Guid, string>> OldRoutes
|
||||
{
|
||||
get
|
||||
{
|
||||
var oldRoutes = RequestCache.GetCacheItem<Dictionary<int, Tuple<Guid, string>>>(
|
||||
ContextKey3,
|
||||
() => new Dictionary<int, Tuple<Guid, string>>());
|
||||
return oldRoutes;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool LockedEvents
|
||||
{
|
||||
get
|
||||
{
|
||||
return Moving && RequestCache.GetCacheItem(ContextKey2) != null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Moving && value)
|
||||
{
|
||||
//this forces true into the cache
|
||||
RequestCache.GetCacheItem(ContextKey2, () => true);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestCache.ClearCacheItem(ContextKey2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Moving
|
||||
{
|
||||
get { return RequestCache.GetCacheItem(ContextKey1) != null; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
//this forces true into the cache
|
||||
RequestCache.GetCacheItem(ContextKey1, () => true);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestCache.ClearCacheItem(ContextKey1);
|
||||
RequestCache.ClearCacheItem(ContextKey2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Before the items are published, we need to get it's current URL before it changes
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
private static void ContentService_Publishing(IPublishingStrategy sender, PublishEventArgs<IContent> args)
|
||||
{
|
||||
if (LockedEvents) return;
|
||||
|
||||
var contentCache = GetPublishedCache();
|
||||
if (contentCache == null) return;
|
||||
|
||||
// prepare entities
|
||||
var entities = PrepareEntities(args.PublishedEntities);
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
// for each entity, we want to save the 'old route' of any impacted entity.
|
||||
//
|
||||
// previously, we'd save the routes of all descendants - super safe but has an
|
||||
// impact on perfs - assuming that the descendant routes will NOT change if the
|
||||
// entity's segment does not change (else... outside of the scope of the simple,
|
||||
// built -in, tracker) then we can compare the entity's old and new segments
|
||||
// and avoid processing the descendants
|
||||
|
||||
var process = true;
|
||||
if (Moving == false) // always process descendants when moving
|
||||
{
|
||||
// SD: in 7.5.0 we re-lookup the entity that is published, which gets its
|
||||
// current state in the DB, which we use to get the 'old' segment. In the
|
||||
// future this will certainly cause some problems, to fix this we'd need to
|
||||
// change the IUrlSegmentProvider to support being able to determine if a
|
||||
// segment is going to change for an entity. See notes in IUrlSegmentProvider.
|
||||
|
||||
var oldEntity = ApplicationContext.Current.Services.ContentService.GetById(entity.Id);
|
||||
if (oldEntity == null) continue;
|
||||
var oldSegment = oldEntity.GetUrlSegment();
|
||||
var newSegment = entity.GetUrlSegment();
|
||||
process = oldSegment != newSegment;
|
||||
}
|
||||
|
||||
// skip if no segment change
|
||||
if (process == false) continue;
|
||||
|
||||
// else save routes for all descendants
|
||||
var entityContent = contentCache.GetById(entity.Id);
|
||||
if (entityContent == null) continue;
|
||||
foreach (var x in entityContent.DescendantsOrSelf())
|
||||
{
|
||||
var route = contentCache.GetRouteById(x.Id);
|
||||
if (IsNotRoute(route)) continue;
|
||||
var wk = UnwrapToKey(x);
|
||||
if (wk == null) continue;
|
||||
|
||||
OldRoutes[x.Id] = Tuple.Create(wk.Key, route);
|
||||
}
|
||||
}
|
||||
|
||||
LockedEvents = true; // we only want to see the "first batch"
|
||||
}
|
||||
|
||||
private static IEnumerable<IContent> PrepareEntities(IEnumerable<IContent> eventEntities)
|
||||
{
|
||||
// prepare entities
|
||||
// - exclude entities without an identity (new entities)
|
||||
// - exclude duplicates (in case publishing a parent and its children)
|
||||
|
||||
var entities = new List<IContent>();
|
||||
foreach (var e in eventEntities.Where(x => x.HasIdentity).OrderBy(x => x.Level))
|
||||
{
|
||||
var pathIds = e.Path.Split(',').Select(int.Parse);
|
||||
if (entities.Any(x => pathIds.Contains(x.Id))) continue;
|
||||
entities.Add(e);
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
private static IPublishedContentWithKey UnwrapToKey(IPublishedContent content)
|
||||
{
|
||||
if (content == null) return null;
|
||||
var withKey = content as IPublishedContentWithKey;
|
||||
if (withKey != null) return withKey;
|
||||
|
||||
var extended = content as PublishedContentExtended;
|
||||
while (extended != null)
|
||||
extended = (content = extended.Unwrap()) as PublishedContentExtended;
|
||||
|
||||
withKey = content as IPublishedContentWithKey;
|
||||
return withKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executed when the cache updates, which means we can know what the new URL is for a given document
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="cacheRefresherEventArgs"></param>
|
||||
private void PageCacheRefresher_CacheUpdated(PageCacheRefresher sender, CacheRefresherEventArgs cacheRefresherEventArgs)
|
||||
{
|
||||
// only on master / single, not on slaves!
|
||||
if (IsSlaveServer) return;
|
||||
|
||||
// simply getting OldRoutes will register it in the request cache,
|
||||
// so whatever we do with it, try/finally it to ensure it's cleared
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var oldRoute in OldRoutes)
|
||||
{
|
||||
// assuming we cannot have 'CacheUpdated' for only part of the infos else we'd need
|
||||
// to set a flag in 'Published' to indicate which entities have been refreshed ok
|
||||
CreateRedirect(oldRoute.Key, oldRoute.Value.Item1, oldRoute.Value.Item2);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
OldRoutes.Clear();
|
||||
RequestCache.ClearCacheItem(ContextKey3);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ContentService_Published(IPublishingStrategy sender, PublishEventArgs<IContent> e)
|
||||
{
|
||||
// look note in CacheUpdated
|
||||
// we might want to set a flag on the entities we are seeing here
|
||||
}
|
||||
|
||||
private static void ContentService_Moving(IContentService sender, MoveEventArgs<IContent> e)
|
||||
{
|
||||
Moving = true;
|
||||
}
|
||||
|
||||
private static void ContentService_Moved(IContentService sender, MoveEventArgs<IContent> e)
|
||||
{
|
||||
Moving = false;
|
||||
LockedEvents = false;
|
||||
}
|
||||
|
||||
private static void CreateRedirect(int contentId, Guid contentKey, string oldRoute)
|
||||
{
|
||||
|
||||
var contentCache = GetPublishedCache();
|
||||
if (contentCache == null) return;
|
||||
|
||||
var newRoute = contentCache.GetRouteById(contentId);
|
||||
if (IsNotRoute(newRoute) || oldRoute == newRoute) return;
|
||||
var redirectUrlService = ApplicationContext.Current.Services.RedirectUrlService;
|
||||
redirectUrlService.Register(oldRoute, contentKey);
|
||||
}
|
||||
|
||||
private static bool IsNotRoute(string route)
|
||||
{
|
||||
// null if content not found
|
||||
return route == null;
|
||||
}
|
||||
|
||||
// gets a value indicating whether server is 'slave'
|
||||
private static bool IsSlaveServer
|
||||
{
|
||||
get
|
||||
{
|
||||
var serverRole = ApplicationContext.Current.GetCurrentServerRole();
|
||||
return serverRole != ServerRole.Master && serverRole != ServerRole.Single;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current request cache to persist the values between handlers
|
||||
/// </summary>
|
||||
private static ContextualPublishedContentCache GetPublishedCache()
|
||||
{
|
||||
return UmbracoContext.Current == null ? null : UmbracoContext.Current.ContentCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current request cache to persist the values between handlers
|
||||
/// </summary>
|
||||
private static ICacheProvider RequestCache
|
||||
{
|
||||
get { return ApplicationContext.Current.ApplicationCache.RequestCache; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.HealthChecks;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
@@ -13,39 +11,48 @@ namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
internal class HealthCheckNotifier : RecurringTaskBase
|
||||
{
|
||||
private readonly ApplicationContext _appContext;
|
||||
private readonly IHealthCheckResolver _healthCheckResolver;
|
||||
private readonly IRuntimeState _runtimeState;
|
||||
private readonly HealthCheckCollection _healthChecks;
|
||||
private readonly HealthCheckNotificationMethodCollection _notifications;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ProfilingLogger _proflog;
|
||||
|
||||
public HealthCheckNotifier(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
ApplicationContext appContext)
|
||||
public HealthCheckNotifier(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
|
||||
IRuntimeState runtimeState,
|
||||
ILogger logger, ProfilingLogger proflog)
|
||||
: base(runner, delayMilliseconds, periodMilliseconds)
|
||||
{
|
||||
_appContext = appContext;
|
||||
_healthCheckResolver = HealthCheckResolver.Current;
|
||||
_healthChecks = healthChecks;
|
||||
_notifications = notifications;
|
||||
_runtimeState = runtimeState;
|
||||
_logger = logger;
|
||||
_proflog = proflog;
|
||||
}
|
||||
|
||||
public override async Task<bool> PerformRunAsync(CancellationToken token)
|
||||
{
|
||||
if (_appContext == null) return true; // repeat...
|
||||
if (_runtimeState.Level != RuntimeLevel.Run)
|
||||
return true; // repeat...
|
||||
|
||||
switch (_appContext.GetCurrentServerRole())
|
||||
switch (_runtimeState.ServerRole)
|
||||
{
|
||||
case ServerRole.Slave:
|
||||
LogHelper.Debug<HealthCheckNotifier>("Does not run on slave servers.");
|
||||
_logger.Debug<HealthCheckNotifier>("Does not run on slave servers.");
|
||||
return true; // DO repeat, server role can change
|
||||
case ServerRole.Unknown:
|
||||
LogHelper.Debug<HealthCheckNotifier>("Does not run on servers with unknown role.");
|
||||
_logger.Debug<HealthCheckNotifier>("Does not run on servers with unknown role.");
|
||||
return true; // DO repeat, server role can change
|
||||
}
|
||||
|
||||
// ensure we do not run if not main domain, but do NOT lock it
|
||||
if (_appContext.MainDom.IsMainDom == false)
|
||||
if (_runtimeState.IsMainDom == false)
|
||||
{
|
||||
LogHelper.Debug<HealthCheckNotifier>("Does not run if not MainDom.");
|
||||
_logger.Debug<HealthCheckNotifier>("Does not run if not MainDom.");
|
||||
return false; // do NOT repeat, going down
|
||||
}
|
||||
|
||||
using (_appContext.ProfilingLogger.DebugDuration<KeepAlive>("Health checks executing", "Health checks complete"))
|
||||
using (_proflog.DebugDuration<KeepAlive>("Health checks executing", "Health checks complete"))
|
||||
{
|
||||
var healthCheckConfig = UmbracoConfig.For.HealthCheck();
|
||||
|
||||
@@ -58,26 +65,20 @@ namespace Umbraco.Web.Scheduling
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
var checks = _healthCheckResolver.HealthChecks
|
||||
var checks = _healthChecks
|
||||
.Where(x => disabledCheckIds.Contains(x.Id) == false);
|
||||
|
||||
var results = new HealthCheckResults(checks);
|
||||
results.LogResults();
|
||||
|
||||
// Send using registered notification methods
|
||||
var registeredNotificationMethods = HealthCheckNotificationMethodResolver.Current.NotificationMethods;
|
||||
foreach (var notificationMethod in registeredNotificationMethods)
|
||||
{
|
||||
await notificationMethod.SendAsync(results);
|
||||
}
|
||||
foreach (var notificationMethod in _notifications)
|
||||
await notificationMethod.SendAsync(results, token);
|
||||
}
|
||||
|
||||
return true; // repeat
|
||||
}
|
||||
|
||||
public override bool IsAsync
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
public override bool IsAsync => true;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,27 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using umbraco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
internal class ScheduledPublishing : RecurringTaskBase
|
||||
{
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IScopeProvider _scopeProvider;
|
||||
private readonly IContentService _contentService;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ProfilingLogger _proflog;
|
||||
|
||||
public ScheduledPublishing(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
IRuntimeState runtime, IUserService userService, IScopeProvider scopeProvider, ILogger logger, ProfilingLogger proflog)
|
||||
IRuntimeState runtime, IContentService contentService, ILogger logger)
|
||||
: base(runner, delayMilliseconds, periodMilliseconds)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_userService = userService;
|
||||
_scopeProvider = scopeProvider;
|
||||
_contentService = contentService;
|
||||
_logger = logger;
|
||||
_proflog = proflog;
|
||||
}
|
||||
|
||||
public override async Task<bool> PerformRunAsync(CancellationToken token)
|
||||
@@ -55,38 +43,19 @@ namespace Umbraco.Web.Scheduling
|
||||
return false; // do NOT repeat, going down
|
||||
}
|
||||
|
||||
UmbracoContext tempContext = null;
|
||||
try
|
||||
{
|
||||
// DO not run publishing if content is re-loading
|
||||
if (content.Instance.isInitializing == false)
|
||||
if (_runtime.Level != RuntimeLevel.Run)
|
||||
{
|
||||
//TODO: We should remove this in v8, this is a backwards compat hack
|
||||
// see notes in CacheRefresherEventHandler
|
||||
// because notifications will not be sent if there is no UmbracoContext
|
||||
// see NotificationServiceExtensions
|
||||
var httpContext = new HttpContextWrapper(new HttpContext(new SimpleWorkerRequest("temp.aspx", "", new StringWriter())));
|
||||
tempContext = UmbracoContext.EnsureContext(
|
||||
httpContext,
|
||||
_appContext,
|
||||
new WebSecurity(httpContext, _appContext),
|
||||
_settings,
|
||||
UrlProviderResolver.Current.Providers,
|
||||
true);
|
||||
|
||||
var publisher = new ScheduledPublisher(_appContext.Services.ContentService);
|
||||
var publisher = new ScheduledPublisher(_contentService, _logger);
|
||||
var count = publisher.CheckPendingAndProcess();
|
||||
_logger.Warn<ScheduledPublishing>("No url for service (yet), skip.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error<ScheduledPublishing>("Could not acquire application url", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tempContext != null)
|
||||
tempContext.Dispose(); // nulls the ThreadStatic context
|
||||
_logger.Error<ScheduledPublishing>("Failed.", e);
|
||||
}
|
||||
|
||||
return true; // repeat
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.HealthChecks;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Scheduling
|
||||
@@ -22,35 +25,45 @@ namespace Umbraco.Web.Scheduling
|
||||
internal sealed class SchedulerComponent : UmbracoComponentBase, IUmbracoCoreComponent
|
||||
{
|
||||
private IRuntimeState _runtime;
|
||||
private IUserService _userService;
|
||||
private IContentService _contentService;
|
||||
private IAuditService _auditService;
|
||||
private ILogger _logger;
|
||||
private ProfilingLogger _proflog;
|
||||
private IScopeProvider _scopeProvider;
|
||||
private HealthCheckCollection _healthChecks;
|
||||
private HealthCheckNotificationMethodCollection _notifications;
|
||||
|
||||
private BackgroundTaskRunner<IBackgroundTask> _keepAliveRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _tasksRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _scrubberRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _healthCheckRunner;
|
||||
|
||||
private bool _started;
|
||||
private object _locker = new object();
|
||||
private IBackgroundTask[] _tasks;
|
||||
|
||||
public void Initialize(IRuntimeState runtime, IUserService userService, IAuditService auditService, IScopeProvider scopeProvider, ILogger logger, ProfilingLogger proflog)
|
||||
public void Initialize(IRuntimeState runtime,
|
||||
IContentService contentService, IAuditService auditService,
|
||||
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
|
||||
IScopeProvider scopeProvider, ILogger logger, ProfilingLogger proflog)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_userService = userService;
|
||||
_contentService = contentService;
|
||||
_auditService = auditService;
|
||||
_scopeProvider = scopeProvider;
|
||||
_logger = logger;
|
||||
_proflog = proflog;
|
||||
|
||||
_healthChecks = healthChecks;
|
||||
_notifications = notifications;
|
||||
|
||||
// backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly
|
||||
_keepAliveRunner = new BackgroundTaskRunner<IBackgroundTask>("KeepAlive", logger);
|
||||
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", logger);
|
||||
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", logger);
|
||||
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", logger);
|
||||
_healthCheckRunner = new BackgroundTaskRunner<IBackgroundTask>("HealthCheckNotifier", logger);
|
||||
|
||||
// we will start the whole process when a successful request is made
|
||||
UmbracoModule.RouteAttempt += UmbracoModuleRouteAttempt;
|
||||
@@ -62,12 +75,12 @@ namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
case EnsureRoutableOutcome.IsRoutable:
|
||||
case EnsureRoutableOutcome.NotDocumentRequest:
|
||||
RegisterBackgroundTasks(e);
|
||||
RegisterBackgroundTasks();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterBackgroundTasks(UmbracoRequestEventArgs e)
|
||||
private void RegisterBackgroundTasks()
|
||||
{
|
||||
// remove handler, we're done
|
||||
UmbracoModule.RouteAttempt -= UmbracoModuleRouteAttempt;
|
||||
@@ -77,30 +90,78 @@ namespace Umbraco.Web.Scheduling
|
||||
_logger.Debug<SchedulerComponent>(() => "Initializing the scheduler");
|
||||
var settings = UmbracoConfig.For.UmbracoSettings();
|
||||
|
||||
var tasks = new List<IBackgroundTask>
|
||||
{
|
||||
new KeepAlive(_keepAliveRunner, 60000, 300000, _runtime, _logger, _proflog),
|
||||
new ScheduledPublishing(_publishingRunner, 60000, 60000, _runtime, _userService, _scopeProvider, _logger, _proflog),
|
||||
new ScheduledTasks(_tasksRunner, 60000, 60000, _runtime, settings, _logger, _proflog),
|
||||
new LogScrubber(_scrubberRunner, 60000, LogScrubber.GetLogScrubbingInterval(settings, _logger), _runtime, _auditService, settings, _scopeProvider, _logger, _proflog)
|
||||
};
|
||||
var tasks = new List<IBackgroundTask>();
|
||||
|
||||
// ping/keepalive
|
||||
// on all servers
|
||||
_keepAliveRunner.TryAdd(tasks[0]);
|
||||
tasks.Add(RegisterKeepAlive());
|
||||
tasks.Add(RegisterScheduledPublishing());
|
||||
tasks.Add(RegisterTaskRunner(settings));
|
||||
tasks.Add(RegisterLogScrubber(settings));
|
||||
|
||||
// scheduled publishing/unpublishing
|
||||
// install on all, will only run on non-slaves servers
|
||||
_publishingRunner.TryAdd(tasks[1]);
|
||||
|
||||
_tasksRunner.TryAdd(tasks[2]);
|
||||
|
||||
// log scrubbing
|
||||
// install on all, will only run on non-slaves servers
|
||||
_scrubberRunner.TryAdd(tasks[3]);
|
||||
var healthCheckConfig = UmbracoConfig.For.HealthCheck();
|
||||
if (healthCheckConfig.NotificationSettings.Enabled)
|
||||
tasks.Add(RegisterHealthCheckNotifier(healthCheckConfig, _healthChecks, _notifications, _logger, _proflog));
|
||||
|
||||
return tasks.ToArray();
|
||||
});
|
||||
}
|
||||
|
||||
private IBackgroundTask RegisterKeepAlive()
|
||||
{
|
||||
// ping/keepalive
|
||||
// on all servers
|
||||
var task = new KeepAlive(_keepAliveRunner, 60000, 300000, _runtime, _logger, _proflog);
|
||||
_keepAliveRunner.TryAdd(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
private IBackgroundTask RegisterScheduledPublishing()
|
||||
{
|
||||
// scheduled publishing/unpublishing
|
||||
// install on all, will only run on non-slaves servers
|
||||
var task = new ScheduledPublishing(_publishingRunner, 60000, 60000, _runtime, _contentService, _logger);
|
||||
_publishingRunner.TryAdd(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
private IBackgroundTask RegisterTaskRunner(IUmbracoSettingsSection settings)
|
||||
{
|
||||
var task = new ScheduledTasks(_tasksRunner, 60000, 60000, _runtime, settings, _logger, _proflog);
|
||||
_tasksRunner.TryAdd(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
private IBackgroundTask RegisterHealthCheckNotifier(IHealthChecks healthCheckConfig,
|
||||
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
|
||||
ILogger logger, ProfilingLogger proflog)
|
||||
{
|
||||
// If first run time not set, start with just small delay after application start
|
||||
int delayInMilliseconds;
|
||||
if (string.IsNullOrEmpty(healthCheckConfig.NotificationSettings.FirstRunTime))
|
||||
{
|
||||
delayInMilliseconds = 60000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise start at scheduled time
|
||||
delayInMilliseconds = DateTime.Now.PeriodicMinutesFrom(healthCheckConfig.NotificationSettings.FirstRunTime) * 60 * 1000;
|
||||
if (delayInMilliseconds < 60000)
|
||||
{
|
||||
delayInMilliseconds = 60000;
|
||||
}
|
||||
}
|
||||
|
||||
var periodInMilliseconds = healthCheckConfig.NotificationSettings.PeriodInHours * 60 * 60 * 1000;
|
||||
var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _runtime, logger, proflog);
|
||||
return task;
|
||||
}
|
||||
|
||||
private IBackgroundTask RegisterLogScrubber(IUmbracoSettingsSection settings)
|
||||
{
|
||||
// log scrubbing
|
||||
// install on all, will only run on non-slaves servers
|
||||
var task = new LogScrubber(_scrubberRunner, 60000, LogScrubber.GetLogScrubbingInterval(settings, _logger), _runtime, _auditService, settings, _scopeProvider, _logger, _proflog);
|
||||
_scrubberRunner.TryAdd(task);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using Umbraco.Web.Trees;
|
||||
|
||||
namespace Umbraco.Web.Search
|
||||
{
|
||||
internal class SearchableTreeCollection : BuilderCollectionBase<ISearchableTree>
|
||||
public class SearchableTreeCollection : BuilderCollectionBase<ISearchableTree>
|
||||
{
|
||||
private readonly Dictionary<string, SearchableApplicationTree> _dictionary;
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Trees;
|
||||
|
||||
namespace Umbraco.Web.Search
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return the collection of searchable trees
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This collection has a request scoped lifetime therefore any instance of ISearchableTree needs to support being a request scoped lifetime
|
||||
/// </remarks>
|
||||
public class SearchableTreeResolver : LazyManyObjectsResolverBase<SearchableTreeResolver, ISearchableTree>
|
||||
{
|
||||
private readonly IApplicationTreeService _treeService;
|
||||
|
||||
public SearchableTreeResolver(IServiceProvider serviceProvider, ILogger logger, IApplicationTreeService treeService, Func<IEnumerable<Type>> searchableTrees)
|
||||
: base(serviceProvider, logger, searchableTrees, ObjectLifetimeScope.HttpRequest)
|
||||
{
|
||||
_treeService = treeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the a dictionary of tree alias with it's affiliated <see cref="ISearchableTree"/>
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, SearchableApplicationTree> GetSearchableTrees()
|
||||
{
|
||||
var appTrees = _treeService.GetAll().ToArray();
|
||||
var collection = new SearchableTreeCollection();
|
||||
var searchableTrees = Values.ToArray();
|
||||
foreach (var searchableTree in searchableTrees)
|
||||
{
|
||||
var found = appTrees.FirstOrDefault(x => x.Alias == searchableTree.TreeAlias);
|
||||
if (found != null)
|
||||
{
|
||||
collection.Add(new SearchableApplicationTree(found.ApplicationAlias, found.Alias, searchableTree));
|
||||
}
|
||||
}
|
||||
return collection.AsReadOnlyDictionary();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Web;
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Web.Http;
|
||||
using umbraco;
|
||||
using umbraco.businesslogic.Actions;
|
||||
using umbraco.BusinessLogic.Actions;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -75,22 +67,20 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
return nodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
var intId = id.TryConvertTo<int>();
|
||||
//Get the content type
|
||||
var ct = Services.ContentTypeService.GetContentType(intId.Result);
|
||||
if (ct == null) return nodes;
|
||||
|
||||
var blueprintsForDocType = entities.Where(x => ct.Alias == ((UmbracoEntity) x).ContentTypeAlias);
|
||||
nodes.AddRange(blueprintsForDocType
|
||||
.Select(entity =>
|
||||
{
|
||||
var treeNode = CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprintGuid, id, queryStrings, "icon-blueprint", false);
|
||||
treeNode.Path = string.Format("-1,{0},{1}", ct.Id, entity.Id);
|
||||
return treeNode;
|
||||
}));
|
||||
}
|
||||
var intId = id.TryConvertTo<int>();
|
||||
//Get the content type
|
||||
var ct = Services.ContentTypeService.Get(intId.Result);
|
||||
if (ct == null) return nodes;
|
||||
|
||||
var blueprintsForDocType = entities.Where(x => ct.Alias == ((UmbracoEntity) x).ContentTypeAlias);
|
||||
nodes.AddRange(blueprintsForDocType
|
||||
.Select(entity =>
|
||||
{
|
||||
var treeNode = CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprintGuid, id, queryStrings, "icon-blueprint", false);
|
||||
treeNode.Path = $"-1,{ct.Id},{entity.Id}";
|
||||
return treeNode;
|
||||
}));
|
||||
|
||||
return nodes;
|
||||
}
|
||||
@@ -109,16 +99,16 @@ namespace Umbraco.Web.Trees
|
||||
//only refresh & create if it's a content type
|
||||
if (cte != null)
|
||||
{
|
||||
var ct = Services.ContentTypeService.GetContentType(cte.Id);
|
||||
var createItem = menu.Items.Add<ActionCreateBlueprintFromContent>(Services.TextService.Localize(string.Format("actions/{0}", ActionCreateBlueprintFromContent.Instance.Alias)));
|
||||
var ct = Services.ContentTypeService.Get(cte.Id);
|
||||
var createItem = menu.Items.Add<ActionCreateBlueprintFromContent>(Services.TextService.Localize($"actions/{ActionCreateBlueprintFromContent.Instance.Alias}"));
|
||||
createItem.NavigateToRoute("/settings/contentBlueprints/edit/-1?create=true&doctype=" + ct.Alias);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http.Formatting;
|
||||
@@ -11,7 +12,6 @@ using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using umbraco.businesslogic.Actions;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// This attribute is used purely to maintain some compatibility with legacy webform tree pickers
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This allows us to attribute new trees with their legacy counterparts and when a legacy tree is loaded this will indicate
|
||||
/// on the new tree which legacy tree to load (it won't actually render using the new tree)
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
[Obsolete("Remove this in v8, it should no longer be necessary!")]
|
||||
internal sealed class LegacyBaseTreeAttribute : Attribute
|
||||
{
|
||||
public Type BaseTreeType { get; private set; }
|
||||
|
||||
public LegacyBaseTreeAttribute(Type baseTreeType)
|
||||
{
|
||||
if (!TypeHelper.IsTypeAssignableFrom<BaseTree>(baseTreeType))
|
||||
{
|
||||
throw new InvalidOperationException("The type for baseTreeType must be assignable from " + typeof(BaseTree));
|
||||
}
|
||||
|
||||
BaseTreeType = baseTreeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ namespace Umbraco.Web.Trees
|
||||
[Tree(Constants.Applications.Developer, Constants.Trees.Packages, null, sortOrder: 0)]
|
||||
[PluginController("UmbracoTrees")]
|
||||
[CoreTree]
|
||||
[LegacyBaseTree(typeof(loadPackager))]
|
||||
public class PackagesTreeController : TreeController
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Formatting;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Net.Http.Formatting;
|
||||
using umbraco;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
@@ -10,22 +9,9 @@ namespace Umbraco.Web.Trees
|
||||
[UmbracoTreeAuthorize(Constants.Trees.Users)]
|
||||
[Tree(Constants.Applications.Users, Constants.Trees.Users, null, sortOrder: 0)]
|
||||
[PluginController("UmbracoTrees")]
|
||||
[LegacyBaseTree(typeof(loadUsers))]
|
||||
[CoreTree]
|
||||
public class UserTreeController : TreeController
|
||||
{
|
||||
public UserTreeController()
|
||||
{
|
||||
}
|
||||
|
||||
public UserTreeController(UmbracoContext umbracoContext) : base(umbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
public UserTreeController(UmbracoContext umbracoContext, UmbracoHelper umbracoHelper) : base(umbracoContext, umbracoHelper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a root model for a tree
|
||||
/// </summary>
|
||||
|
||||
@@ -194,6 +194,8 @@
|
||||
<Compile Include="HealthCheck\StatusResultType.cs" />
|
||||
<Compile Include="HealthCheck\Checks\DataIntegrity\XmlDataIntegrityHealthCheck.cs" />
|
||||
<Compile Include="Media\ImageUrlProviderCollection.cs" />
|
||||
<Compile Include="Models\ContentEditing\AssignedContentPermissions.cs" />
|
||||
<Compile Include="Models\ContentEditing\AssignedUserGroupPermissions.cs" />
|
||||
<Compile Include="Models\ContentEditing\CodeFileDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\ContentRedirectUrl.cs" />
|
||||
<Compile Include="Media\ImageUrlProviderCollectionBuilder.cs" />
|
||||
@@ -203,8 +205,18 @@
|
||||
<Compile Include="Editors\IEditorValidator.cs" />
|
||||
<Compile Include="Editors\EditorModelEventManager.cs" />
|
||||
<Compile Include="HtmlHelperBackOfficeExtensions.cs" />
|
||||
<Compile Include="Models\ContentEditing\Permission.cs" />
|
||||
<Compile Include="Models\ContentEditing\SnippetDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\TemplateDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\TreeSearchResult.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserGroupBasic.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserGroupDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserGroupPermissionsSave.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserGroupSave.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserInvite.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserProfile.cs" />
|
||||
<Compile Include="Models\ContentEditing\UserSave.cs" />
|
||||
<Compile Include="Models\DetachedPublishedContent.cs" />
|
||||
<Compile Include="Models\DetachedPublishedProperty.cs" />
|
||||
<Compile Include="Models\Mapping\ActionButtonsResolver.cs" />
|
||||
@@ -297,7 +309,6 @@
|
||||
<Compile Include="Routing\ContentFinderCollectionBuilder.cs" />
|
||||
<Compile Include="Routing\Domain.cs" />
|
||||
<Compile Include="Routing\IContentLastChanceFinder.cs" />
|
||||
<Compile Include="Routing\RedirectTrackingEventHandler.cs" />
|
||||
<Compile Include="Routing\UrlProviderCollection.cs" />
|
||||
<Compile Include="Routing\UrlProviderCollectionBuilder.cs" />
|
||||
<Compile Include="Scheduling\HealthCheckNotifier.cs" />
|
||||
@@ -305,7 +316,6 @@
|
||||
<Compile Include="Search\SearchableTreeAttribute.cs" />
|
||||
<Compile Include="Search\SearchableTreeCollection.cs" />
|
||||
<Compile Include="Search\SearchableTreeCollectionBuilder.cs" />
|
||||
<Compile Include="Search\SearchableTreeResolver.cs" />
|
||||
<Compile Include="Search\UmbracoTreeSearcher.cs" />
|
||||
<Compile Include="SignalR\IPreviewHub.cs" />
|
||||
<Compile Include="SignalR\PreviewHub.cs" />
|
||||
@@ -560,7 +570,6 @@
|
||||
<Compile Include="Install\Controllers\InstallApiController.cs" />
|
||||
<Compile Include="Install\Controllers\InstallController.cs" />
|
||||
<Compile Include="Install\InstallAuthorizeAttribute.cs" />
|
||||
<Compile Include="Models\ContentEditing\EntityTypeSearchResult.cs" />
|
||||
<Compile Include="Models\ContentEditing\ListViewAwareContentItemDisplayBase.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyTypeValidation.cs" />
|
||||
<Compile Include="Models\ImageCropData.cs" />
|
||||
@@ -703,7 +712,6 @@
|
||||
<Compile Include="Trees\DataTypeTreeController.cs" />
|
||||
<Compile Include="Trees\FileSystemTreeController.cs" />
|
||||
<Compile Include="Trees\LanguageTreeController.cs" />
|
||||
<Compile Include="Trees\LegacyBaseTreeAttribute.cs" />
|
||||
<Compile Include="Trees\MemberTreeController.cs" />
|
||||
<Compile Include="Trees\MenuRenderingEventArgs.cs" />
|
||||
<Compile Include="Models\Trees\CreateChildEntity.cs" />
|
||||
@@ -717,18 +725,15 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\create.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\create\script.ascx.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\Language.ascx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\create\PartialViewTasksBase.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\xslt.ascx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Packages\Installer.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\cruds.aspx.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\Trees\loadPackager.cs" />
|
||||
<Compile Include="UmbracoComponentRenderer.cs" />
|
||||
<Compile Include="Web References\org.umbraco.our\Reference.cs">
|
||||
@@ -902,7 +907,6 @@
|
||||
<Compile Include="UI\Bundles\JsUmbracoApplicationUI.cs" />
|
||||
<Compile Include="UI\Bundles\JsUmbracoTree.cs" />
|
||||
<Compile Include="UI\CdfLogger.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\controls\PasswordChanger.ascx.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\controls\Tree\TreeControl.ascx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
@@ -922,7 +926,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\AssignDomain2.aspx.designer.cs">
|
||||
<DependentUpon>AssignDomain2.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\EditUser.aspx.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\editstylesheet.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
@@ -1106,8 +1109,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\ping.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\create\PartialViewMacrosTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\PartialViewTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Macros\editMacro.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
@@ -1126,7 +1127,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\masterpages\umbracoDialog.master.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\editTemplate.aspx.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\modals\ShowUmbracoTags.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
@@ -1252,11 +1252,8 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\create\dictionaryTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\macroTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\MemberGroupTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\ScriptTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\stylesheetPropertyTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\StylesheetTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\templateTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\userTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\create\XsltTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\dashboard\FeedProxy.aspx.cs">
|
||||
<DependentUpon>FeedProxy.aspx</DependentUpon>
|
||||
@@ -1345,12 +1342,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Macros\assemblyBrowser.aspx.designer.cs">
|
||||
<DependentUpon>assemblyBrowser.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\autoDoc.aspx.cs">
|
||||
<DependentUpon>autoDoc.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\autoDoc.aspx.designer.cs">
|
||||
<DependentUpon>autoDoc.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Packages\editPackage.aspx.cs">
|
||||
<DependentUpon>editPackage.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -1376,12 +1367,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Xslt\xsltInsertValueOf.aspx.designer.cs">
|
||||
<DependentUpon>xsltInsertValueOf.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\about.aspx.cs">
|
||||
<DependentUpon>about.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\about.aspx.designer.cs">
|
||||
<DependentUpon>about.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\exportDocumenttype.aspx.cs">
|
||||
<DependentUpon>exportDocumenttype.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -1438,9 +1423,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\editLanguage.aspx.designer.cs">
|
||||
<DependentUpon>editLanguage.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\scripts\editScript.aspx.cs">
|
||||
<DependentUpon>editScript.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\Trees\ITreeService.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -1497,29 +1479,6 @@
|
||||
<DependentUpon>XmlTree.xsd</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\urlRewriter\UrlRewriterFormWriter.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\users\EditUserType.aspx.cs">
|
||||
<DependentUpon>EditUserType.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\EditUserType.aspx.designer.cs">
|
||||
<DependentUpon>EditUserType.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\NodePermissions.ascx.cs">
|
||||
<DependentUpon>NodePermissions.ascx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\NodePermissions.ascx.designer.cs">
|
||||
<DependentUpon>NodePermissions.ascx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\PermissionEditor.aspx.cs">
|
||||
<DependentUpon>PermissionEditor.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\PermissionEditor.aspx.designer.cs">
|
||||
<DependentUpon>PermissionEditor.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\PermissionsHandler.asmx.cs">
|
||||
<DependentUpon>PermissionsHandler.asmx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\users\UserPermissions.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\users\UserTypeTasks.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\webservices\ajaxHelpers.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\webservices\CacheRefresher.asmx.cs">
|
||||
<DependentUpon>CacheRefresher.asmx</DependentUpon>
|
||||
@@ -1533,9 +1492,6 @@
|
||||
<DependentUpon>codeEditorSave.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\webservices\Developer.asmx.cs">
|
||||
<DependentUpon>Developer.asmx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\webservices\legacyAjaxCalls.asmx.cs">
|
||||
<DependentUpon>legacyAjaxCalls.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
@@ -1544,9 +1500,6 @@
|
||||
<DependentUpon>nodeSorter.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\webservices\templates.asmx.cs">
|
||||
<DependentUpon>templates.asmx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\Web\UI\ContentPage.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
@@ -1595,32 +1548,22 @@
|
||||
<EmbeddedResource Include="UI\JavaScript\Main.js" />
|
||||
<EmbeddedResource Include="UI\JavaScript\JsInitialize.js" />
|
||||
<EmbeddedResource Include="UI\JavaScript\ServerVariables.js" />
|
||||
<EmbeddedResource Include="_Legacy\Packager\FileResources\PackageFiles.resx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WebReferences Include="Web References\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="umbraco.presentation\umbraco\users\NodePermissions.ascx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\users\PermissionEditor.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\users\PermissionsHandler.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\CheckForUpgrade.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\settings\DictionaryItemList.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\settings\scripts\editScript.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\translation\default.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\translation\preview.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\translation\xml.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Macros\assemblyBrowser.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\autoDoc.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Xslt\getXsltStatus.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Xslt\xsltChooseExtension.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Xslt\xsltInsertValueOf.aspx" />
|
||||
@@ -1628,18 +1571,13 @@
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\settings\editLanguage.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\users\EditUserType.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<!--<Content Include="umbraco.presentation\umbraco\users\PermissionEditor.aspx" />-->
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\CacheRefresher.asmx">
|
||||
<SubType>Form</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\codeEditorSave.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\Developer.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\legacyAjaxCalls.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\nodeSorter.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\webservices\templates.asmx" />
|
||||
<Content Include="PublishedCache\NuCache\notes.txt" />
|
||||
<Content Include="umbraco.presentation\umbraco\controls\Tree\CustomTreeService.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\RelationTypes\EditRelationType.aspx">
|
||||
@@ -1680,9 +1618,6 @@
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Packages\editPackage.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\dialogs\about.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\dialogs\exportDocumenttype.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\dialogs\importDocumenttype.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\dialogs\notifications.aspx">
|
||||
|
||||
Reference in New Issue
Block a user