Renormalize

This commit is contained in:
Stephan
2018-07-31 14:14:52 +02:00
parent 309ca0a765
commit f35c63fa40
7 changed files with 2387 additions and 2387 deletions

View File

@@ -1,145 +1,145 @@
Umbraco.Sys.registerNamespace("Umbraco.Dialogs");
(function ($) {
// register AssignDomain dialog
Umbraco.Dialogs.AssignDomain2 = base2.Base.extend({
_opts: null,
_isRepeated: function (element) {
var inputs = $('form input.domain');
var elementName = element.attr('name');
var repeated = false;
inputs.each(function() {
var input = $(this);
if (input.attr('name') != elementName && input.val() == element.val())
repeated = true;
});
return repeated;
},
// constructor
constructor: function (opts) {
// merge options with default
this._opts = $.extend({
invalidDomain: 'Invalid domain.',
duplicateDomain: 'Domain has already been assigned.'
}, opts);
},
// public methods/variables
languages: null,
language: null,
domains: null,
addDomain: function () {
this.domains.push({
Name: "",
Lang: ""
});
},
init: function () {
var self = this;
self.domains = ko.observableArray(self._opts.domains);
self.languages = self._opts.languages;
self.language = self._opts.language;
self.removeDomain = function() { self.domains.remove(this); };
ko.applyBindings(self);
$.validator.addMethod("domain", function (value, element, param) {
// beware! encode('test') == 'test-'
// read eg https://rt.cpan.org/Public/Bug/Display.html?id=94347
value = punycode.encode(value);
// that regex is best-effort and certainly not exact
var re = /^(http[s]?:\/\/)?([-\w]+(\.[-\w]+)*)(:\d+)?(\/[-\w]*|-)?$/gi;
var isopt = this.optional(element);
var retest = re.test(value);
var ret = isopt || retest;
return ret;
}, self._opts.invalidDomain);
function getDuplicateMessage(val, el) {
var other = $(el).nextAll('input').val();
var msg = self._opts.duplicateDomain
if (other != "" && other != "!!!")
msg = msg + ' (' + other + ')';
return msg;
}
$.validator.addMethod("duplicate", function (value, element, param) {
return $(element).nextAll('input').val() == "" && !self._isRepeated($(element));
}, getDuplicateMessage);
$.validator.addClassRules({
domain: { domain: true },
duplicate: { duplicate: true }
});
$('form').validate({
debug: true,
focusCleanup: true,
onkeyup: false
});
$('form input.domain').on('focus', function(event) {
if (event.type != 'focusin') return;
$(this).nextAll('input').val("");
});
// force validation *now*
$('form').valid();
$('#btnSave').click(function () {
if (!$('form').valid())
return false;
var mask = $('#komask');
var masked = mask.parent();
mask.height(masked.height());
mask.width(masked.width());
mask.show();
var data = { nodeId: self._opts.nodeId, language: self.language ? self.language : 0, domains: self.domains };
$.post(self._opts.restServiceLocation + 'PostSaveLanguageAndDomains', ko.toJSON(data), function (json) {
mask.hide();
if (json.Valid) {
UmbClientMgr.closeModalWindow();
}
else {
var inputs = $('form input.domain');
inputs.each(function() { $(this).nextAll('input').val(""); });
for (var i = 0; i < json.Domains.length; i++) {
var d = json.Domains[i];
if (d.Duplicate)
inputs.each(function() {
var input = $(this);
if (input.val() == d.Name)
input.nextAll('input').val(d.Other ? d.Other : "!!!");
});
}
$('form').valid();
}
})
.fail(function (xhr, textStatus, errorThrown) {
mask.css('opacity', 1).css('color', "#ff0000").html(xhr.responseText);
});
return false;
});
}
});
// set defaults for jQuery ajax calls
$.ajaxSetup({
dataType: 'json',
cache: false,
contentType: 'application/json; charset=utf-8'
});
})(jQuery);
Umbraco.Sys.registerNamespace("Umbraco.Dialogs");
(function ($) {
// register AssignDomain dialog
Umbraco.Dialogs.AssignDomain2 = base2.Base.extend({
_opts: null,
_isRepeated: function (element) {
var inputs = $('form input.domain');
var elementName = element.attr('name');
var repeated = false;
inputs.each(function() {
var input = $(this);
if (input.attr('name') != elementName && input.val() == element.val())
repeated = true;
});
return repeated;
},
// constructor
constructor: function (opts) {
// merge options with default
this._opts = $.extend({
invalidDomain: 'Invalid domain.',
duplicateDomain: 'Domain has already been assigned.'
}, opts);
},
// public methods/variables
languages: null,
language: null,
domains: null,
addDomain: function () {
this.domains.push({
Name: "",
Lang: ""
});
},
init: function () {
var self = this;
self.domains = ko.observableArray(self._opts.domains);
self.languages = self._opts.languages;
self.language = self._opts.language;
self.removeDomain = function() { self.domains.remove(this); };
ko.applyBindings(self);
$.validator.addMethod("domain", function (value, element, param) {
// beware! encode('test') == 'test-'
// read eg https://rt.cpan.org/Public/Bug/Display.html?id=94347
value = punycode.encode(value);
// that regex is best-effort and certainly not exact
var re = /^(http[s]?:\/\/)?([-\w]+(\.[-\w]+)*)(:\d+)?(\/[-\w]*|-)?$/gi;
var isopt = this.optional(element);
var retest = re.test(value);
var ret = isopt || retest;
return ret;
}, self._opts.invalidDomain);
function getDuplicateMessage(val, el) {
var other = $(el).nextAll('input').val();
var msg = self._opts.duplicateDomain
if (other != "" && other != "!!!")
msg = msg + ' (' + other + ')';
return msg;
}
$.validator.addMethod("duplicate", function (value, element, param) {
return $(element).nextAll('input').val() == "" && !self._isRepeated($(element));
}, getDuplicateMessage);
$.validator.addClassRules({
domain: { domain: true },
duplicate: { duplicate: true }
});
$('form').validate({
debug: true,
focusCleanup: true,
onkeyup: false
});
$('form input.domain').on('focus', function(event) {
if (event.type != 'focusin') return;
$(this).nextAll('input').val("");
});
// force validation *now*
$('form').valid();
$('#btnSave').click(function () {
if (!$('form').valid())
return false;
var mask = $('#komask');
var masked = mask.parent();
mask.height(masked.height());
mask.width(masked.width());
mask.show();
var data = { nodeId: self._opts.nodeId, language: self.language ? self.language : 0, domains: self.domains };
$.post(self._opts.restServiceLocation + 'PostSaveLanguageAndDomains', ko.toJSON(data), function (json) {
mask.hide();
if (json.Valid) {
UmbClientMgr.closeModalWindow();
}
else {
var inputs = $('form input.domain');
inputs.each(function() { $(this).nextAll('input').val(""); });
for (var i = 0; i < json.Domains.length; i++) {
var d = json.Domains[i];
if (d.Duplicate)
inputs.each(function() {
var input = $(this);
if (input.val() == d.Name)
input.nextAll('input').val(d.Other ? d.Other : "!!!");
});
}
$('form').valid();
}
})
.fail(function (xhr, textStatus, errorThrown) {
mask.css('opacity', 1).css('color', "#ff0000").html(xhr.responseText);
});
return false;
});
}
});
// set defaults for jQuery ajax calls
$.ajaxSetup({
dataType: 'json',
cache: false,
contentType: 'application/json; charset=utf-8'
});
})(jQuery);

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +1,79 @@
using System;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Xml;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// Extension methods for UrlHelper
/// </summary>
public static class UrlHelperExtensions
{
/// <summary>
/// Utility method for checking for valid proxy urls or redirect urls to prevent Open Redirect security issues
/// </summary>
/// <param name="urlHelper"></param>
/// <param name="url">The url to validate</param>
/// <param name="callerUrl">The url of the current local domain (to ensure we can validate if the requested url is local without dependency on the request)</param>
/// <returns>True if it's an allowed url</returns>
public static bool ValidateProxyUrl(this UrlHelper urlHelper, string url, string callerUrl)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
{
return false;
}
if (url.StartsWith("//"))
return false;
Uri requestUri;
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out requestUri))
{
if (string.IsNullOrEmpty(callerUrl) == false)
{
Uri localUri;
if (Uri.TryCreate(callerUrl, UriKind.RelativeOrAbsolute, out localUri))
{
// check for local urls
//Cannot start with // since that is not a local url
if (requestUri.OriginalString.StartsWith("//") == false
//cannot be non-absolute and also contain the char : since that will indicate a protocol
&& (requestUri.IsAbsoluteUri == false && requestUri.OriginalString.Contains(":") == false)
//needs to be non-absolute or the hosts must match the current request
&& (requestUri.IsAbsoluteUri == false || requestUri.Host == localUri.Host))
{
return true;
}
}
else
{
return false;
}
}
//we cannot continue if the url is not absolute
if (requestUri.IsAbsoluteUri == false)
{
return false;
}
// check for valid proxy urls
var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
if (feedProxyXml != null &&
feedProxyXml.SelectSingleNode(string.Concat("//allow[@host = '", requestUri.Host, "']")) != null)
{
return true;
}
}
else
{
return false;
}
return false;
}
}
}
using System;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Xml;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// Extension methods for UrlHelper
/// </summary>
public static class UrlHelperExtensions
{
/// <summary>
/// Utility method for checking for valid proxy urls or redirect urls to prevent Open Redirect security issues
/// </summary>
/// <param name="urlHelper"></param>
/// <param name="url">The url to validate</param>
/// <param name="callerUrl">The url of the current local domain (to ensure we can validate if the requested url is local without dependency on the request)</param>
/// <returns>True if it's an allowed url</returns>
public static bool ValidateProxyUrl(this UrlHelper urlHelper, string url, string callerUrl)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
{
return false;
}
if (url.StartsWith("//"))
return false;
Uri requestUri;
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out requestUri))
{
if (string.IsNullOrEmpty(callerUrl) == false)
{
Uri localUri;
if (Uri.TryCreate(callerUrl, UriKind.RelativeOrAbsolute, out localUri))
{
// check for local urls
//Cannot start with // since that is not a local url
if (requestUri.OriginalString.StartsWith("//") == false
//cannot be non-absolute and also contain the char : since that will indicate a protocol
&& (requestUri.IsAbsoluteUri == false && requestUri.OriginalString.Contains(":") == false)
//needs to be non-absolute or the hosts must match the current request
&& (requestUri.IsAbsoluteUri == false || requestUri.Host == localUri.Host))
{
return true;
}
}
else
{
return false;
}
}
//we cannot continue if the url is not absolute
if (requestUri.IsAbsoluteUri == false)
{
return false;
}
// check for valid proxy urls
var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
if (feedProxyXml != null &&
feedProxyXml.SelectSingleNode(string.Concat("//allow[@host = '", requestUri.Host, "']")) != null)
{
return true;
}
}
else
{
return false;
}
return false;
}
}
}

View File

@@ -1,193 +1,193 @@
using System;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Management.Instrumentation;
using System.Web.Mvc;
using System.Web.Routing;
using ClientDependency.Core.Config;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Exceptions;
using Umbraco.Web.Composing;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
using Umbraco.Web.WebServices;
namespace Umbraco.Web
{
/// <summary>
/// Extension methods for UrlHelper
/// </summary>
public static class UrlHelperExtensions
{
/// <summary>
/// Returns the base path (not including the 'action') of the MVC controller "ExamineManagementController"
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string GetExamineManagementServicePath(this UrlHelper url)
{
// TODO: Possibly remove this method, I think it's unused...
var result = url.GetUmbracoApiService<ExamineManagementController>("GetIndexerDetails");
return result.TrimEnd("GetIndexerDetails").EnsureEndsWith('/');
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService<T>(this UrlHelper url, string actionName, RouteValueDictionary routeVals = null)
where T : UmbracoApiController
{
return url.GetUmbracoApiService(actionName, typeof(T), routeVals);
}
/// <summary>
/// Return the Base Url (not including the action) for a Web Api service
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <returns></returns>
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, string actionName)
where T : UmbracoApiController
{
return url.GetUmbracoApiService<T>(actionName).TrimEnd(actionName);
}
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
}
return url.GetUmbracoApiService<T>(method.Name).TrimEnd(method.Name);
}
public static string GetUmbracoApiService<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
}
var parameters = Core.ExpressionHelper.GetMethodParams(methodSelector);
var routeVals = new RouteValueDictionary(parameters);
return url.GetUmbracoApiService<T>(method.Name, routeVals);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="apiControllerType"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, RouteValueDictionary routeVals = null)
{
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
if (apiControllerType == null) throw new ArgumentNullException(nameof(apiControllerType));
var area = "";
var apiController = Current.UmbracoApiControllerTypes
.SingleOrDefault(x => x == apiControllerType);
if (apiController == null)
throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName);
var metaData = PluginController.GetMetadata(apiController);
if (!metaData.AreaName.IsNullOrWhiteSpace())
{
//set the area to the plugin area
area = metaData.AreaName;
}
return url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area, routeVals);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
{
return url.GetUmbracoApiService(actionName, controllerName, "", routeVals);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="area"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, string area, RouteValueDictionary routeVals = null)
{
if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullOrEmptyException(nameof(controllerName));
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
if (routeVals == null)
{
routeVals = new RouteValueDictionary(new {httproute = "", area = area});
}
else
{
var requiredRouteVals = new RouteValueDictionary(new { httproute = "", area = area });
requiredRouteVals.MergeLeft(routeVals);
//copy it back now
routeVals = requiredRouteVals;
}
return url.Action(actionName, controllerName, routeVals);
}
/// <summary>
/// Return the Url for an action with a cache-busting hash appended
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUrlWithCacheBust(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
{
var applicationJs = url.Action(actionName, controllerName, routeVals);
applicationJs = applicationJs + "?umb__rnd=" + GetCacheBustHash();
return applicationJs;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string GetCacheBustHash()
{
//make a hash of umbraco and client dependency version
//in case the user bypasses the installer and just bumps the web.config or clientdep config
//if in debug mode, always burst the cache
if (GlobalSettings.DebugMode)
{
return DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture).GenerateHash();
}
var version = Current.RuntimeState.SemanticVersion.ToSemanticString();
return $"{version}.{ClientDependencySettings.Instance.Version}".GenerateHash();
}
}
}
using System;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Management.Instrumentation;
using System.Web.Mvc;
using System.Web.Routing;
using ClientDependency.Core.Config;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Exceptions;
using Umbraco.Web.Composing;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
using Umbraco.Web.WebServices;
namespace Umbraco.Web
{
/// <summary>
/// Extension methods for UrlHelper
/// </summary>
public static class UrlHelperExtensions
{
/// <summary>
/// Returns the base path (not including the 'action') of the MVC controller "ExamineManagementController"
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string GetExamineManagementServicePath(this UrlHelper url)
{
// TODO: Possibly remove this method, I think it's unused...
var result = url.GetUmbracoApiService<ExamineManagementController>("GetIndexerDetails");
return result.TrimEnd("GetIndexerDetails").EnsureEndsWith('/');
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService<T>(this UrlHelper url, string actionName, RouteValueDictionary routeVals = null)
where T : UmbracoApiController
{
return url.GetUmbracoApiService(actionName, typeof(T), routeVals);
}
/// <summary>
/// Return the Base Url (not including the action) for a Web Api service
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <returns></returns>
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, string actionName)
where T : UmbracoApiController
{
return url.GetUmbracoApiService<T>(actionName).TrimEnd(actionName);
}
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
}
return url.GetUmbracoApiService<T>(method.Name).TrimEnd(method.Name);
}
public static string GetUmbracoApiService<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
}
var parameters = Core.ExpressionHelper.GetMethodParams(methodSelector);
var routeVals = new RouteValueDictionary(parameters);
return url.GetUmbracoApiService<T>(method.Name, routeVals);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="apiControllerType"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, RouteValueDictionary routeVals = null)
{
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
if (apiControllerType == null) throw new ArgumentNullException(nameof(apiControllerType));
var area = "";
var apiController = Current.UmbracoApiControllerTypes
.SingleOrDefault(x => x == apiControllerType);
if (apiController == null)
throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName);
var metaData = PluginController.GetMetadata(apiController);
if (!metaData.AreaName.IsNullOrWhiteSpace())
{
//set the area to the plugin area
area = metaData.AreaName;
}
return url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area, routeVals);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
{
return url.GetUmbracoApiService(actionName, controllerName, "", routeVals);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="area"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, string area, RouteValueDictionary routeVals = null)
{
if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullOrEmptyException(nameof(controllerName));
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
if (routeVals == null)
{
routeVals = new RouteValueDictionary(new {httproute = "", area = area});
}
else
{
var requiredRouteVals = new RouteValueDictionary(new { httproute = "", area = area });
requiredRouteVals.MergeLeft(routeVals);
//copy it back now
routeVals = requiredRouteVals;
}
return url.Action(actionName, controllerName, routeVals);
}
/// <summary>
/// Return the Url for an action with a cache-busting hash appended
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="routeVals"></param>
/// <returns></returns>
public static string GetUrlWithCacheBust(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
{
var applicationJs = url.Action(actionName, controllerName, routeVals);
applicationJs = applicationJs + "?umb__rnd=" + GetCacheBustHash();
return applicationJs;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string GetCacheBustHash()
{
//make a hash of umbraco and client dependency version
//in case the user bypasses the installer and just bumps the web.config or clientdep config
//if in debug mode, always burst the cache
if (GlobalSettings.DebugMode)
{
return DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture).GenerateHash();
}
var version = Current.RuntimeState.SemanticVersion.ToSemanticString();
return $"{version}.{ClientDependencySettings.Instance.Version}".GenerateHash();
}
}
}

View File

@@ -1,154 +1,154 @@
using System;
using Umbraco.Core.Security;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using umbraco;
using umbraco.cms.businesslogic;
using umbraco.cms.presentation.Trees;
using umbraco.controls.Tree;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Security;
using Umbraco.Web.WebServices;
namespace umbraco.controls.Tree
{
/// <summary>
/// Client side ajax utlities for the tree
/// </summary>
[ScriptService]
[WebService]
public class CustomTreeService : UmbracoWebService
{
/// <summary>
/// Returns some info about the node such as path and id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public NodeInfo GetNodeInfo(int id)
{
Authorize();
//var node = new CMSNode(id);
var node = Services.EntityService.Get(id);
return new NodeInfo()
{
Id = node.Id,
Path = node.Path,
PathAsNames = string.Join("->",
GetPathNames(node.Path.Split(',')
.Select(x => int.Parse(x))
.ToArray()))
};
}
/// <summary>
/// returns the node names for each id passed in
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
private string[] GetPathNames(int[] ids)
{
return ids
.Where(x => x != -1)
//.Select(x => new CMSNode(x).Text).ToArray();
.Select(x => Services.EntityService.Get(x).Name).ToArray();
}
/// <summary>
/// Returns a key/value object with: json, app, js as the keys
/// </summary>
/// <returns></returns>
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Dictionary<string, string> GetInitAppTreeData(string app, string treeType, bool showContextMenu, bool isDialog, TreeDialogModes dialogMode, string functionToCall, string nodeKey)
{
Authorize();
var treeCtl = new TreeControl()
{
ShowContextMenu = showContextMenu,
IsDialog = isDialog,
DialogMode = dialogMode,
App = app,
TreeType = string.IsNullOrEmpty(treeType) ? "" : treeType, //don't set the tree type unless explicitly set
NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey,
//StartNodeID = -1, //TODO: set this based on parameters!
FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall
};
var returnVal = new Dictionary<string, string>();
if (string.IsNullOrEmpty(treeType))
{
//if there's not tree type specified, then render out the tree as per normal with the normal
//way of doing things
returnVal.Add("json", treeCtl.GetJSONInitNode());
}
else
{
//since 4.5.1 has a bug in it, it ignores if the treeType is specified and will always only render
//the whole APP not just a specific tree.
//this is a work around for this bug until it is fixed (which should be fixed in 4.5.2
//get the tree that we need to render
var tree = TreeDefinitionCollection.Instance.FindTree(treeType).CreateInstance();
tree.ShowContextMenu = showContextMenu;
tree.IsDialog = isDialog;
tree.DialogMode = dialogMode;
tree.NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey;
tree.FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall;
//now render it's start node
var xTree = new XmlTree();
//we're going to hijack the node name here to make it say content/media
var node = tree.RootNode;
if (node.Text.Equals("[FilteredContentTree]")) node.Text = Services.TextService.Localize("content");
else if (node.Text.Equals("[FilteredMediaTree]")) node.Text = Services.TextService.Localize("media");
xTree.Add(node);
returnVal.Add("json", xTree.ToString());
}
returnVal.Add("app", app);
returnVal.Add("js", treeCtl.JSCurrApp);
return returnVal;
}
internal void Authorize()
{
if (ValidateCurrentUser() == false)
throw new Exception("Client authorization failed. User is not logged in");
}
/// <summary>
/// Validates the currently logged in user and ensures they are not timed out
/// </summary>
/// <returns></returns>
private bool ValidateCurrentUser()
{
var identity = Context.GetCurrentIdentity(
//DO NOT AUTO-AUTH UNLESS THE CURRENT HANDLER IS WEBFORMS!
// Without this check, anything that is using this legacy API, like ui.Text will
// automatically log the back office user in even if it is a front-end request (if there is
// a back office user logged in. This can cause problems becaues the identity is changing mid
// request. For example: http://issues.umbraco.org/issue/U4-4010
HttpContext.Current.CurrentHandler is Page);
if (identity != null)
{
return true;
}
return false;
}
}
}
using System;
using Umbraco.Core.Security;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using umbraco;
using umbraco.cms.businesslogic;
using umbraco.cms.presentation.Trees;
using umbraco.controls.Tree;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Security;
using Umbraco.Web.WebServices;
namespace umbraco.controls.Tree
{
/// <summary>
/// Client side ajax utlities for the tree
/// </summary>
[ScriptService]
[WebService]
public class CustomTreeService : UmbracoWebService
{
/// <summary>
/// Returns some info about the node such as path and id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public NodeInfo GetNodeInfo(int id)
{
Authorize();
//var node = new CMSNode(id);
var node = Services.EntityService.Get(id);
return new NodeInfo()
{
Id = node.Id,
Path = node.Path,
PathAsNames = string.Join("->",
GetPathNames(node.Path.Split(',')
.Select(x => int.Parse(x))
.ToArray()))
};
}
/// <summary>
/// returns the node names for each id passed in
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
private string[] GetPathNames(int[] ids)
{
return ids
.Where(x => x != -1)
//.Select(x => new CMSNode(x).Text).ToArray();
.Select(x => Services.EntityService.Get(x).Name).ToArray();
}
/// <summary>
/// Returns a key/value object with: json, app, js as the keys
/// </summary>
/// <returns></returns>
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Dictionary<string, string> GetInitAppTreeData(string app, string treeType, bool showContextMenu, bool isDialog, TreeDialogModes dialogMode, string functionToCall, string nodeKey)
{
Authorize();
var treeCtl = new TreeControl()
{
ShowContextMenu = showContextMenu,
IsDialog = isDialog,
DialogMode = dialogMode,
App = app,
TreeType = string.IsNullOrEmpty(treeType) ? "" : treeType, //don't set the tree type unless explicitly set
NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey,
//StartNodeID = -1, //TODO: set this based on parameters!
FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall
};
var returnVal = new Dictionary<string, string>();
if (string.IsNullOrEmpty(treeType))
{
//if there's not tree type specified, then render out the tree as per normal with the normal
//way of doing things
returnVal.Add("json", treeCtl.GetJSONInitNode());
}
else
{
//since 4.5.1 has a bug in it, it ignores if the treeType is specified and will always only render
//the whole APP not just a specific tree.
//this is a work around for this bug until it is fixed (which should be fixed in 4.5.2
//get the tree that we need to render
var tree = TreeDefinitionCollection.Instance.FindTree(treeType).CreateInstance();
tree.ShowContextMenu = showContextMenu;
tree.IsDialog = isDialog;
tree.DialogMode = dialogMode;
tree.NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey;
tree.FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall;
//now render it's start node
var xTree = new XmlTree();
//we're going to hijack the node name here to make it say content/media
var node = tree.RootNode;
if (node.Text.Equals("[FilteredContentTree]")) node.Text = Services.TextService.Localize("content");
else if (node.Text.Equals("[FilteredMediaTree]")) node.Text = Services.TextService.Localize("media");
xTree.Add(node);
returnVal.Add("json", xTree.ToString());
}
returnVal.Add("app", app);
returnVal.Add("js", treeCtl.JSCurrApp);
return returnVal;
}
internal void Authorize()
{
if (ValidateCurrentUser() == false)
throw new Exception("Client authorization failed. User is not logged in");
}
/// <summary>
/// Validates the currently logged in user and ensures they are not timed out
/// </summary>
/// <returns></returns>
private bool ValidateCurrentUser()
{
var identity = Context.GetCurrentIdentity(
//DO NOT AUTO-AUTH UNLESS THE CURRENT HANDLER IS WEBFORMS!
// Without this check, anything that is using this legacy API, like ui.Text will
// automatically log the back office user in even if it is a front-end request (if there is
// a back office user logged in. This can cause problems becaues the identity is changing mid
// request. For example: http://issues.umbraco.org/issue/U4-4010
HttpContext.Current.CurrentHandler is Page);
if (identity != null)
{
return true;
}
return false;
}
}
}

View File

@@ -1,83 +1,83 @@
using System;
using System.Text;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web.UI.Pages;
using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web.Editors;
using Umbraco.Web.WebServices;
using Umbraco.Web._Legacy.Actions;
namespace umbraco.dialogs
{
public partial class AssignDomain2 : UmbracoEnsuredPage
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var nodeId = GetNodeId();
CheckPathAndPermissions(nodeId, UmbracoObjectTypes.Document, ActionAssignDomain.Instance);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var nodeId = GetNodeId();
var node = Services.ContentService.GetById(nodeId);
if (node == null)
{
feedback.Text = Services.TextService.Localize("assignDomain/invalidNode");
pane_language.Visible = false;
pane_domains.Visible = false;
p_buttons.Visible = false;
return;
}
pane_language.Title = Services.TextService.Localize("assignDomain/setLanguage");
pane_domains.Title = Services.TextService.Localize("assignDomain/setDomains");
prop_language.Text = Services.TextService.Localize("assignDomain/language");
var nodeDomains = Services.DomainService.GetAssignedDomains(nodeId, true).ToArray();
var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
var sb = new StringBuilder();
sb.Append("languages: [");
var i = 0;
foreach (var language in Current.Services.LocalizationService.GetAllLanguages())
sb.AppendFormat("{0}{{ \"Id\": {1}, \"Code\": \"{2}\" }}", (i++ == 0 ? "" : ","), language.Id, language.IsoCode);
sb.Append("]\r\n");
sb.AppendFormat(",language: {0}", wildcard == null ? "undefined" : wildcard.LanguageId.ToString());
sb.Append(",domains: [");
i = 0;
foreach (var domain in nodeDomains.Where(d => d.IsWildcard == false))
sb.AppendFormat("{0}{{ \"Name\": \"{1}\", \"Lang\": \"{2}\" }}", (i++ == 0 ? "" :","), domain.DomainName, domain.LanguageId);
sb.Append("]\r\n");
data.Text = sb.ToString();
}
protected int GetNodeId()
{
int nodeId;
if (int.TryParse(Request.QueryString["id"], out nodeId) == false)
nodeId = -1;
return nodeId;
}
protected string GetRestServicePath()
{
const string action = "ListDomains";
var path = Url.GetUmbracoApiService<ContentController>(action);
return path.TrimEnd(action).EnsureEndsWith('/');
}
}
}
using System;
using System.Text;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web.UI.Pages;
using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web.Editors;
using Umbraco.Web.WebServices;
using Umbraco.Web._Legacy.Actions;
namespace umbraco.dialogs
{
public partial class AssignDomain2 : UmbracoEnsuredPage
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var nodeId = GetNodeId();
CheckPathAndPermissions(nodeId, UmbracoObjectTypes.Document, ActionAssignDomain.Instance);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var nodeId = GetNodeId();
var node = Services.ContentService.GetById(nodeId);
if (node == null)
{
feedback.Text = Services.TextService.Localize("assignDomain/invalidNode");
pane_language.Visible = false;
pane_domains.Visible = false;
p_buttons.Visible = false;
return;
}
pane_language.Title = Services.TextService.Localize("assignDomain/setLanguage");
pane_domains.Title = Services.TextService.Localize("assignDomain/setDomains");
prop_language.Text = Services.TextService.Localize("assignDomain/language");
var nodeDomains = Services.DomainService.GetAssignedDomains(nodeId, true).ToArray();
var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
var sb = new StringBuilder();
sb.Append("languages: [");
var i = 0;
foreach (var language in Current.Services.LocalizationService.GetAllLanguages())
sb.AppendFormat("{0}{{ \"Id\": {1}, \"Code\": \"{2}\" }}", (i++ == 0 ? "" : ","), language.Id, language.IsoCode);
sb.Append("]\r\n");
sb.AppendFormat(",language: {0}", wildcard == null ? "undefined" : wildcard.LanguageId.ToString());
sb.Append(",domains: [");
i = 0;
foreach (var domain in nodeDomains.Where(d => d.IsWildcard == false))
sb.AppendFormat("{0}{{ \"Name\": \"{1}\", \"Lang\": \"{2}\" }}", (i++ == 0 ? "" :","), domain.DomainName, domain.LanguageId);
sb.Append("]\r\n");
data.Text = sb.ToString();
}
protected int GetNodeId()
{
int nodeId;
if (int.TryParse(Request.QueryString["id"], out nodeId) == false)
nodeId = -1;
return nodeId;
}
protected string GetRestServicePath()
{
const string action = "ListDomains";
var path = Url.GetUmbracoApiService<ContentController>(action);
return path.TrimEnd(action).EnsureEndsWith('/');
}
}
}

View File

@@ -1,262 +1,262 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web._Legacy.Actions;
namespace umbraco.presentation.webservices
{
/// <summary>
/// Summary description for nodeSorter
/// </summary>
[WebService(Namespace = "http://umbraco.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class nodeSorter : UmbracoAuthorizedWebService
{
[WebMethod]
public SortNode GetNodes(string ParentId, string App)
{
if (AuthorizeRequest())
{
var nodes = new List<SortNode>();
// "hack for stylesheet"
if (App == "settings")
{
var stylesheet = Services.FileService.GetStylesheetByName(ParentId.EnsureEndsWith(".css"));
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + ParentId);
var sort = 0;
foreach (var child in stylesheet.Properties)
{
nodes.Add(new SortNode(child.Name.GetHashCode(), sort, child.Name, DateTime.Now));
sort++;
}
return new SortNode()
{
SortNodes = nodes.ToArray()
};
}
else
{
var asInt = int.Parse(ParentId);
var parent = new SortNode { Id = asInt };
var entityService = Services.EntityService;
// Root nodes?
if (asInt == -1)
{
if (App == "media")
{
var rootMedia = entityService.GetRootEntities(UmbracoObjectTypes.Media);
nodes.AddRange(rootMedia.Select(media => new SortNode(media.Id, media.SortOrder, media.Name, media.CreateDate)));
}
else
{
var rootContent = entityService.GetRootEntities(UmbracoObjectTypes.Document);
nodes.AddRange(rootContent.Select(content => new SortNode(content.Id, content.SortOrder, content.Name, content.CreateDate)));
}
}
else
{
var children = entityService.GetChildren(asInt);
nodes.AddRange(children.Select(child => new SortNode(child.Id, child.SortOrder, child.Name, child.CreateDate)));
}
parent.SortNodes = nodes.ToArray();
return parent;
}
}
throw new ArgumentException("User not logged in");
}
public void UpdateSortOrder(int ParentId, string SortOrder)
{
UpdateSortOrder(ParentId.ToString(), SortOrder);
}
[WebMethod]
public void UpdateSortOrder(string ParentId, string SortOrder)
{
if (AuthorizeRequest() == false) return;
if (SortOrder.Trim().Length <= 0) return;
var isContent = Context.Request.GetItemAsString("app") == "content" | Context.Request.GetItemAsString("app") == "";
var isMedia = Context.Request.GetItemAsString("app") == "media";
//ensure user is authorized for the app requested
if (isContent && AuthorizeRequest(Constants.Applications.Content.ToString()) == false) return;
if (isMedia && AuthorizeRequest(Constants.Applications.Media.ToString()) == false) return;
var ids = SortOrder.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (isContent)
{
SortContent(ids, int.Parse(ParentId));
}
else if (isMedia)
{
SortMedia(ids);
}
else
{
SortStylesheetProperties(ParentId, ids);
}
}
private void SortMedia(string[] ids)
{
var mediaService = Services.MediaService;
var sortedMedia = new List<IMedia>();
try
{
for (var i = 0; i < ids.Length; i++)
{
var id = int.Parse(ids[i]);
var m = mediaService.GetById(id);
sortedMedia.Add(m);
}
// Save Media with new sort order and update content xml in db accordingly
var sorted = mediaService.Sort(sortedMedia);
}
catch (Exception ex)
{
Current.Logger.Error<nodeSorter>("Could not update media sort order", ex);
}
}
private void SortStylesheetProperties(string stylesheetName, string[] names)
{
var stylesheet = Services.FileService.GetStylesheetByName(stylesheetName.EnsureEndsWith(".css"));
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + stylesheetName);
var currProps = stylesheet.Properties.ToArray();
//remove them all first
foreach (var prop in currProps)
{
stylesheet.RemoveProperty(prop.Name);
}
//re-add them in the right order
for (var i = 0; i < names.Length; i++)
{
var found = currProps.Single(x => x.Name == names[i]);
stylesheet.AddProperty(found);
}
Services.FileService.SaveStylesheet(stylesheet);
}
private void SortContent(string[] ids, int parentId)
{
var contentService = Services.ContentService;
try
{
// Save content with new sort order and update db+cache accordingly
var intIds = new List<int>();
foreach (var stringId in ids)
{
int intId;
if (int.TryParse(stringId, out intId))
intIds.Add(intId);
}
var sorted = contentService.Sort(intIds.ToArray());
// refresh sort order on cached xml
// but no... this is not distributed - solely relying on content service & events should be enough
//content.Instance.SortNodes(parentId);
//send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here
if (parentId > 0)
{
Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings);
}
}
catch (Exception ex)
{
Current.Logger.Error<nodeSorter>("Could not update content sort order", ex);
}
}
}
[Serializable]
public class SortNode
{
public SortNode()
{
}
private SortNode[] _sortNodes;
public SortNode[] SortNodes
{
get { return _sortNodes; }
set { _sortNodes = value; }
}
public int TotalNodes
{
get { return _sortNodes != null ? _sortNodes.Length : 0; }
set { int test = value; }
}
public SortNode(int Id, int SortOrder, string Name, DateTime CreateDate)
{
_id = Id;
_sortOrder = SortOrder;
_name = Name;
_createDate = CreateDate;
}
private DateTime _createDate;
public DateTime CreateDate
{
get { return _createDate; }
set { _createDate = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _sortOrder;
public int SortOrder
{
get { return _sortOrder; }
set { _sortOrder = value; }
}
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web._Legacy.Actions;
namespace umbraco.presentation.webservices
{
/// <summary>
/// Summary description for nodeSorter
/// </summary>
[WebService(Namespace = "http://umbraco.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class nodeSorter : UmbracoAuthorizedWebService
{
[WebMethod]
public SortNode GetNodes(string ParentId, string App)
{
if (AuthorizeRequest())
{
var nodes = new List<SortNode>();
// "hack for stylesheet"
if (App == "settings")
{
var stylesheet = Services.FileService.GetStylesheetByName(ParentId.EnsureEndsWith(".css"));
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + ParentId);
var sort = 0;
foreach (var child in stylesheet.Properties)
{
nodes.Add(new SortNode(child.Name.GetHashCode(), sort, child.Name, DateTime.Now));
sort++;
}
return new SortNode()
{
SortNodes = nodes.ToArray()
};
}
else
{
var asInt = int.Parse(ParentId);
var parent = new SortNode { Id = asInt };
var entityService = Services.EntityService;
// Root nodes?
if (asInt == -1)
{
if (App == "media")
{
var rootMedia = entityService.GetRootEntities(UmbracoObjectTypes.Media);
nodes.AddRange(rootMedia.Select(media => new SortNode(media.Id, media.SortOrder, media.Name, media.CreateDate)));
}
else
{
var rootContent = entityService.GetRootEntities(UmbracoObjectTypes.Document);
nodes.AddRange(rootContent.Select(content => new SortNode(content.Id, content.SortOrder, content.Name, content.CreateDate)));
}
}
else
{
var children = entityService.GetChildren(asInt);
nodes.AddRange(children.Select(child => new SortNode(child.Id, child.SortOrder, child.Name, child.CreateDate)));
}
parent.SortNodes = nodes.ToArray();
return parent;
}
}
throw new ArgumentException("User not logged in");
}
public void UpdateSortOrder(int ParentId, string SortOrder)
{
UpdateSortOrder(ParentId.ToString(), SortOrder);
}
[WebMethod]
public void UpdateSortOrder(string ParentId, string SortOrder)
{
if (AuthorizeRequest() == false) return;
if (SortOrder.Trim().Length <= 0) return;
var isContent = Context.Request.GetItemAsString("app") == "content" | Context.Request.GetItemAsString("app") == "";
var isMedia = Context.Request.GetItemAsString("app") == "media";
//ensure user is authorized for the app requested
if (isContent && AuthorizeRequest(Constants.Applications.Content.ToString()) == false) return;
if (isMedia && AuthorizeRequest(Constants.Applications.Media.ToString()) == false) return;
var ids = SortOrder.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (isContent)
{
SortContent(ids, int.Parse(ParentId));
}
else if (isMedia)
{
SortMedia(ids);
}
else
{
SortStylesheetProperties(ParentId, ids);
}
}
private void SortMedia(string[] ids)
{
var mediaService = Services.MediaService;
var sortedMedia = new List<IMedia>();
try
{
for (var i = 0; i < ids.Length; i++)
{
var id = int.Parse(ids[i]);
var m = mediaService.GetById(id);
sortedMedia.Add(m);
}
// Save Media with new sort order and update content xml in db accordingly
var sorted = mediaService.Sort(sortedMedia);
}
catch (Exception ex)
{
Current.Logger.Error<nodeSorter>("Could not update media sort order", ex);
}
}
private void SortStylesheetProperties(string stylesheetName, string[] names)
{
var stylesheet = Services.FileService.GetStylesheetByName(stylesheetName.EnsureEndsWith(".css"));
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + stylesheetName);
var currProps = stylesheet.Properties.ToArray();
//remove them all first
foreach (var prop in currProps)
{
stylesheet.RemoveProperty(prop.Name);
}
//re-add them in the right order
for (var i = 0; i < names.Length; i++)
{
var found = currProps.Single(x => x.Name == names[i]);
stylesheet.AddProperty(found);
}
Services.FileService.SaveStylesheet(stylesheet);
}
private void SortContent(string[] ids, int parentId)
{
var contentService = Services.ContentService;
try
{
// Save content with new sort order and update db+cache accordingly
var intIds = new List<int>();
foreach (var stringId in ids)
{
int intId;
if (int.TryParse(stringId, out intId))
intIds.Add(intId);
}
var sorted = contentService.Sort(intIds.ToArray());
// refresh sort order on cached xml
// but no... this is not distributed - solely relying on content service & events should be enough
//content.Instance.SortNodes(parentId);
//send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here
if (parentId > 0)
{
Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings);
}
}
catch (Exception ex)
{
Current.Logger.Error<nodeSorter>("Could not update content sort order", ex);
}
}
}
[Serializable]
public class SortNode
{
public SortNode()
{
}
private SortNode[] _sortNodes;
public SortNode[] SortNodes
{
get { return _sortNodes; }
set { _sortNodes = value; }
}
public int TotalNodes
{
get { return _sortNodes != null ? _sortNodes.Length : 0; }
set { int test = value; }
}
public SortNode(int Id, int SortOrder, string Name, DateTime CreateDate)
{
_id = Id;
_sortOrder = SortOrder;
_name = Name;
_createDate = CreateDate;
}
private DateTime _createDate;
public DateTime CreateDate
{
get { return _createDate; }
set { _createDate = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _sortOrder;
public int SortOrder
{
get { return _sortOrder; }
set { _sortOrder = value; }
}
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
}
}