diff --git a/src/Umbraco.Core/Publishing/ScheduledPublisher.cs b/src/Umbraco.Core/Publishing/ScheduledPublisher.cs
new file mode 100644
index 0000000000..acc21c6c95
--- /dev/null
+++ b/src/Umbraco.Core/Publishing/ScheduledPublisher.cs
@@ -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
+{
+ ///
+ /// Used to perform scheduled publishing/unpublishing
+ ///
+ internal class ScheduledPublisher
+ {
+ private readonly IContentService _contentService;
+ private readonly ILogger _logger;
+
+ public ScheduledPublisher(IContentService contentService, ILogger logger)
+ {
+ _contentService = contentService;
+ _logger = logger;
+ }
+
+ ///
+ /// Processes scheduled operations
+ ///
+ ///
+ /// Returns the number of items successfully completed
+ ///
+ public int CheckPendingAndProcess()
+ {
+ var counter = 0;
+ var contentForRelease = _contentService.GetContentForRelease().ToArray();
+ if (contentForRelease.Length > 0)
+ _logger.Debug($"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($"Result of publish attempt: {result.Result.StatusType}");
+ if (result.Success == false)
+ {
+ if (result.Exception != null)
+ {
+ _logger.Error("Could not published the document (" + d.Id + ") based on it's scheduled release, status result: " + result.Result.StatusType, result.Exception);
+ }
+ else
+ {
+ _logger.Warn("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($"Error publishing node {d.Id}", ee);
+ throw;
+ }
+ }
+
+ var contentForExpiration = _contentService.GetContentForExpiration().ToArray();
+ if (contentForExpiration.Length > 0)
+ _logger.Debug($"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($"Error unpublishing node {d.Id}", ee);
+ throw;
+ }
+ }
+
+ return counter;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index e2095c737b..8da2b86518 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -1264,6 +1264,7 @@
+
diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
index 748e90469d..794a3d4d66 100644
--- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
+++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.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();
- //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?
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index a7adf07049..ef61c17c57 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -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;
diff --git a/src/Umbraco.Web/Editors/CurrentUserController.cs b/src/Umbraco.Web/Editors/CurrentUserController.cs
index 1dc431b069..f97f389c9d 100644
--- a/src/Umbraco.Web/Editors/CurrentUserController.cs
+++ b/src/Umbraco.Web/Editors/CurrentUserController.cs
@@ -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 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());
}
///
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index f5f18e995e..ce8fd3341f 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -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
{
-
///
/// Configures this controller with a custom action selector
///
@@ -56,6 +50,12 @@ namespace Umbraco.Web.Editors
}
private readonly UmbracoTreeSearcher _treeSearcher = new UmbracoTreeSearcher();
+ private readonly SearchableTreeCollection _searchableTreeCollection;
+
+ public EntityController(SearchableTreeCollection searchableTreeCollection)
+ {
+ _searchableTreeCollection = searchableTreeCollection;
+ }
///
/// Returns an Umbraco alias given a string
@@ -65,7 +65,7 @@ namespace Umbraco.Web.Editors
///
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.
- ///
+ ///
[HttpGet]
public IDictionary 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(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 GetResultForChildren(int id, UmbracoEntityTypes entityType)
diff --git a/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs b/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs
index 50fe829e1a..fe835e950c 100644
--- a/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs
+++ b/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs
@@ -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;
///
/// HtmlHelper extensions for the back office
///
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);
- }
-
///
/// Outputs a script tag containing the bare minimum (non secure) server vars for use with the angular app
///
///
///
- ///
///
/// 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.
///
- 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 = @"