Compare commits
109 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e1c45e981 | |||
| 4a7ee52d63 | |||
| b4d88b0361 | |||
| b41cf37dd5 | |||
| fc32100142 | |||
| 7ecbc3b391 | |||
| c3c44df52e | |||
| 13a86624ff | |||
| 2f61bc27c8 | |||
| e7d157a209 | |||
| d3ed90c23e | |||
| b916360771 | |||
| db4b93dbc3 | |||
| 40868ac361 | |||
| f399a9f52b | |||
| 562851b93e | |||
| e61b567ee1 | |||
| 4ce22b836e | |||
| f5bf05a6f5 | |||
| e50569597b | |||
| 071f3dcc01 | |||
| 6943a454f3 | |||
| 532f407260 | |||
| 834d04f8ed | |||
| f36ab37f6a | |||
| aeff33d0a6 | |||
| 5cfe9e57ce | |||
| 4863e657df | |||
| c0e1be4df9 | |||
| a93e562f14 | |||
| 822cac5d87 | |||
| d58487fafc | |||
| ea9653fa83 | |||
| 8cca1b77b3 | |||
| 53e4308c29 | |||
| 6f26f7b57c | |||
| bda2614290 | |||
| efc482511e | |||
| 40b90b8a58 | |||
| a009dfe2a1 | |||
| 41e87fca98 | |||
| f23c6c53cc | |||
| 0762decd92 | |||
| 0b58c1c03c | |||
| 38c6a21896 | |||
| 15bff44ec1 | |||
| a626efa9b6 | |||
| 54d2258634 | |||
| 25be0621b2 | |||
| cba09ed817 | |||
| d5d00553b4 | |||
| c52669fb05 | |||
| c4a071523e | |||
| ca99319ead | |||
| 81360f629e | |||
| aa36c66f39 | |||
| 09e31d6595 | |||
| f9fc2619fa | |||
| 5d8cfa5efb | |||
| 297f8e2a0b | |||
| 8ddfb5f6ad | |||
| 9387544865 | |||
| 66ddb21ef8 | |||
| 9d19ed9463 | |||
| df62697477 | |||
| f0cacf0d52 | |||
| d501fcb679 | |||
| f5994d8442 | |||
| 4295cba915 | |||
| 6d66fc6cb8 | |||
| 4484f83caa | |||
| 3ada1770eb | |||
| 0b6f05e630 | |||
| 2170380f7b | |||
| a8ab7e4c35 | |||
| c20c9c638f | |||
| 43b2a2185e | |||
| 2423bdd623 | |||
| bcb90d64a5 | |||
| 7d448d0959 | |||
| 53fe02db7e | |||
| a03dd7b11e | |||
| 6d994f48ac | |||
| f0e8252e38 | |||
| ad06aded1b | |||
| 0ca52fcc60 | |||
| c53342ba4c | |||
| 25eea8d599 | |||
| 22498649b1 | |||
| 25ce7baa7d | |||
| e885384678 | |||
| 528209f8da | |||
| 153fe248a7 | |||
| 7fc4822bbe | |||
| d65bee76b2 | |||
| 385d6396b0 | |||
| 46858af1ed | |||
| 34163625fe | |||
| e53b388a5e | |||
| 4fb4af0b4f | |||
| 461f032777 | |||
| ab37f9ae35 | |||
| a3347c0037 | |||
| f3835d1ca3 | |||
| d30c4791fe | |||
| 7ee9b9ebcc | |||
| b4caf109f7 | |||
| 0e8ffe528a | |||
| a8029d1dc5 |
@@ -27,5 +27,7 @@ ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
|
||||
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
|
||||
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
|
||||
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
|
||||
ce47176bc6b9298741783e20f1fe2672c811f744 release-4.11.7
|
||||
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
|
||||
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
|
||||
0dee9964687ea51ea797984cf7cce3655d6a6558 release-6.0.4
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
@ECHO OFF
|
||||
SET release=6.0.4
|
||||
SET release=6.0.6
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.dll" target="lib\umbraco.webservices.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.xml" target="lib\umbraco.webservices.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
|
||||
@@ -19,7 +19,41 @@ namespace Umbraco.Core
|
||||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Returns true if the assembly is the App_Code assembly
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAppCodeAssembly(this Assembly assembly)
|
||||
{
|
||||
if (assembly.FullName.StartsWith("App_Code"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly.Load("App_Code");
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
//this will occur if it cannot load the assembly
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the assembly is the compiled global asax.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsGlobalAsaxAssembly(this Assembly assembly)
|
||||
{
|
||||
//only way I can figure out how to test is by the name
|
||||
return assembly.FullName.StartsWith("App_global.asax");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file used to load the assembly
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("6.0.4");
|
||||
private static readonly Version Version = new Version("6.0.6");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -5,12 +5,11 @@ using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class FileSystemProviderAttribute : Attribute
|
||||
public class FileSystemProviderAttribute : Attribute
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
public string Alias { get; private set; }
|
||||
|
||||
public FileSystemProviderAttribute(string alias)
|
||||
{
|
||||
|
||||
+1
-2
@@ -6,8 +6,7 @@ using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProvider
|
||||
internal class FileSystemProviderConstants
|
||||
{
|
||||
public const string Media = "media";
|
||||
}
|
||||
@@ -9,9 +9,8 @@ using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProviderManager
|
||||
{
|
||||
public class FileSystemProviderManager
|
||||
{
|
||||
private readonly FileSystemProvidersSection _config;
|
||||
|
||||
@@ -28,7 +27,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
#region Constructors
|
||||
|
||||
public FileSystemProviderManager()
|
||||
internal FileSystemProviderManager()
|
||||
{
|
||||
_config = (FileSystemProvidersSection)ConfigurationManager.GetSection("FileSystemProviders");
|
||||
}
|
||||
@@ -48,7 +47,15 @@ namespace Umbraco.Core.IO
|
||||
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
|
||||
private readonly ConcurrentDictionary<Type, string> _wrappedProviderLookup = new ConcurrentDictionary<Type, string>();
|
||||
|
||||
public IFileSystem GetFileSystemProvider(string alias)
|
||||
/// <summary>
|
||||
/// Returns the underlying (non-typed) file system provider for the alias specified
|
||||
/// </summary>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// It is recommended to use the typed GetFileSystemProvider method instead to get a strongly typed provider instance.
|
||||
/// </remarks>
|
||||
public IFileSystem GetUnderlyingFileSystemProvider(string alias)
|
||||
{
|
||||
//either get the constructor info from cache or create it and add to cache
|
||||
var ctorInfo = _providerLookup.GetOrAdd(alias, s =>
|
||||
@@ -88,6 +95,11 @@ namespace Umbraco.Core.IO
|
||||
return fs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the strongly typed file system provider
|
||||
/// </summary>
|
||||
/// <typeparam name="TProviderTypeFilter"></typeparam>
|
||||
/// <returns></returns>
|
||||
public TProviderTypeFilter GetFileSystemProvider<TProviderTypeFilter>()
|
||||
where TProviderTypeFilter : FileSystemWrapper
|
||||
{
|
||||
@@ -111,7 +123,7 @@ namespace Umbraco.Core.IO
|
||||
return attr.Alias;
|
||||
});
|
||||
|
||||
var innerFs = GetFileSystemProvider(alias);
|
||||
var innerFs = GetUnderlyingFileSystemProvider(alias);
|
||||
var outputFs = Activator.CreateInstance(typeof (TProviderTypeFilter), innerFs);
|
||||
return (TProviderTypeFilter)outputFs;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace Umbraco.Core.Models
|
||||
/// <remarks>
|
||||
/// A replacement for INode which needs to occur since INode doesn't contain the document type alias
|
||||
/// and INode is poorly formatted with mutable properties (i.e. Lists instead of IEnumerable)
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
public interface IPublishedContent
|
||||
{
|
||||
int Id { get; }
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
@@ -16,7 +17,12 @@ namespace Umbraco.Core.Persistence
|
||||
private readonly string _connectionStringName;
|
||||
private readonly string _connectionString;
|
||||
private readonly string _providerName;
|
||||
private static volatile UmbracoDatabase _globalInstance = null;
|
||||
|
||||
//very important to have ThreadStatic:
|
||||
// see: http://issues.umbraco.org/issue/U4-2172
|
||||
[ThreadStatic]
|
||||
private static volatile UmbracoDatabase _nonHttpInstance;
|
||||
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
/// <summary>
|
||||
@@ -55,27 +61,27 @@ namespace Umbraco.Core.Persistence
|
||||
//no http context, create the singleton global object
|
||||
if (HttpContext.Current == null)
|
||||
{
|
||||
if (_globalInstance == null)
|
||||
if (_nonHttpInstance == null)
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
//double check
|
||||
if (_globalInstance == null)
|
||||
if (_nonHttpInstance == null)
|
||||
{
|
||||
_globalInstance = string.IsNullOrEmpty(_providerName) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
_nonHttpInstance = string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
: new UmbracoDatabase(_connectionStringName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _globalInstance;
|
||||
return _nonHttpInstance;
|
||||
}
|
||||
|
||||
//we have an http context, so only create one per request
|
||||
if (!HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)))
|
||||
if (HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)) == false)
|
||||
{
|
||||
HttpContext.Current.Items.Add(typeof (DefaultDatabaseFactory),
|
||||
string.IsNullOrEmpty(_providerName) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
: new UmbracoDatabase(_connectionStringName));
|
||||
}
|
||||
@@ -86,7 +92,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
if (HttpContext.Current == null)
|
||||
{
|
||||
_globalInstance.Dispose();
|
||||
_nonHttpInstance.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -455,9 +455,12 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
if (fieldType == typeof(decimal))
|
||||
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if(fieldType == typeof(DateTime))
|
||||
if (fieldType == typeof(DateTime))
|
||||
return "'" + EscapeParam(((DateTime)value).ToString(CultureInfo.InvariantCulture)) + "'";
|
||||
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
|
||||
@@ -29,11 +29,11 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("businesslogic")]
|
||||
[assembly: InternalsVisibleTo("cms")]
|
||||
[assembly: InternalsVisibleTo("umbraco.editorControls")]
|
||||
[assembly: InternalsVisibleTo("umbraco.webservices")]
|
||||
[assembly: InternalsVisibleTo("umbraco.datalayer")]
|
||||
[assembly: InternalsVisibleTo("umbraco.MacroEngines")]
|
||||
|
||||
[assembly: InternalsVisibleTo("umbraco.editorControls")]
|
||||
[assembly: InternalsVisibleTo("umbraco.webservices")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Tests")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Core")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Web")]
|
||||
|
||||
@@ -56,8 +56,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -66,7 +71,7 @@ namespace Umbraco.Core.Services
|
||||
public IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = 0)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parentId, contentType); ;
|
||||
var content = new Content(name, parentId, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
{
|
||||
@@ -86,8 +91,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -114,6 +124,86 @@ namespace Umbraco.Core.Services
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parentId, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
content.CreatorId = userId;
|
||||
content.WriterId = userId;
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", content.CreatorId, content.Id);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parent, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parent), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
content.CreatorId = userId;
|
||||
content.WriterId = userId;
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", content.CreatorId, content.Id);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IContent"/> object by Id
|
||||
/// </summary>
|
||||
@@ -1010,6 +1100,92 @@ namespace Umbraco.Core.Services
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using this method will ensure that the Published-state is maintained upon sorting
|
||||
/// so the cache is updated accordingly - as needed.
|
||||
/// </remarks>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
public bool Sort(SortedSet<IContent> items, int userId = 0, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(items), this))
|
||||
return false;
|
||||
}
|
||||
|
||||
var shouldBePublished = new List<IContent>();
|
||||
var shouldBeSaved = new List<IContent>();
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var content in items)
|
||||
{
|
||||
//If the current sort order equals that of the content
|
||||
//we don't need to update it, so just increment the sort order
|
||||
//and continue.
|
||||
if (content.SortOrder == i)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
content.SortOrder = i;
|
||||
content.WriterId = userId;
|
||||
i++;
|
||||
|
||||
if (content.Published)
|
||||
{
|
||||
var published = _publishingStrategy.Publish(content, userId);
|
||||
shouldBePublished.Add(content);
|
||||
}
|
||||
else
|
||||
shouldBeSaved.Add(content);
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var content in shouldBeSaved)
|
||||
{
|
||||
//Create and Save PreviewXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
}
|
||||
|
||||
foreach (var content in shouldBePublished)
|
||||
{
|
||||
//Create and Save PreviewXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
//Create and Save ContentXml DTO
|
||||
CreateAndSaveContentXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(items, false), this);
|
||||
|
||||
if(shouldBePublished.Any())
|
||||
_publishingStrategy.PublishingFinalized(shouldBePublished, false);
|
||||
|
||||
Audit.Add(AuditTypes.Sort, "Sorting content performed by user", userId, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
/// <summary>
|
||||
@@ -1096,9 +1272,11 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (!contentTypeIds.Any())
|
||||
{
|
||||
//since we're updating all records, it will be much faster to just clear the table first
|
||||
uow.Database.TruncateTable("cmsContentXml");
|
||||
|
||||
//Remove all Document records from the cmsContentXml table (DO NOT REMOVE Media/Members!)
|
||||
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsDocument ON cmsContentXml.nodeId = cmsDocument.nodeId)");
|
||||
|
||||
//get all content items that are published
|
||||
// Consider creating a Path query instead of recursive method:
|
||||
// var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
||||
@@ -1268,28 +1446,8 @@ namespace Umbraco.Core.Services
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
//Has this content item previously been published? If so, we don't need to refresh the children
|
||||
var previouslyPublished = HasPublishedVersion(content.Id);
|
||||
var validForPublishing = true;
|
||||
|
||||
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
|
||||
if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
||||
content.Name, content.Id));
|
||||
validForPublishing = false;
|
||||
}
|
||||
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (!content.IsValid())
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
validForPublishing = false;
|
||||
}
|
||||
var previouslyPublished = content.HasIdentity && HasPublishedVersion(content.Id);
|
||||
var validForPublishing = CheckAndLogIsPublishable(content) && CheckAndLogIsValid(content);
|
||||
|
||||
//Publish and then update the database with new status
|
||||
bool published = validForPublishing && _publishingStrategy.Publish(content, userId);
|
||||
@@ -1306,37 +1464,12 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var xml = content.ToXml();
|
||||
//Preview Xml
|
||||
var previewPoco = new PreviewXmlDto
|
||||
{
|
||||
NodeId = content.Id,
|
||||
Timestamp = DateTime.Now,
|
||||
VersionId = content.Version,
|
||||
Xml = xml.ToString(SaveOptions.None)
|
||||
};
|
||||
var previewExists =
|
||||
uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
|
||||
new { Id = content.Id, Version = content.Version }) != 0;
|
||||
int previewResult = previewExists
|
||||
? uow.Database.Update<PreviewXmlDto>(
|
||||
"SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version",
|
||||
new
|
||||
{
|
||||
Xml = previewPoco.Xml,
|
||||
Timestamp = previewPoco.Timestamp,
|
||||
Id = previewPoco.NodeId,
|
||||
Version = previewPoco.VersionId
|
||||
})
|
||||
: Convert.ToInt32(uow.Database.Insert(previewPoco));
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
|
||||
if (published)
|
||||
{
|
||||
//Content Xml
|
||||
var contentPoco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var contentExists = uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0;
|
||||
int contentResult = contentExists
|
||||
? uow.Database.Update(contentPoco)
|
||||
: Convert.ToInt32(uow.Database.Insert(contentPoco));
|
||||
|
||||
CreateAndSaveContentXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1456,6 +1589,68 @@ namespace Umbraco.Core.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckAndLogIsPublishable(IContent content)
|
||||
{
|
||||
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
|
||||
if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckAndLogIsValid(IContent content)
|
||||
{
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (content.IsValid() == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CreateAndSavePreviewXml(XElement xml, int id, Guid version, UmbracoDatabase db)
|
||||
{
|
||||
var previewPoco = new PreviewXmlDto
|
||||
{
|
||||
NodeId = id,
|
||||
Timestamp = DateTime.Now,
|
||||
VersionId = version,
|
||||
Xml = xml.ToString(SaveOptions.None)
|
||||
};
|
||||
var previewExists =
|
||||
db.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
|
||||
new { Id = id, Version = version }) != 0;
|
||||
int previewResult = previewExists
|
||||
? db.Update<PreviewXmlDto>(
|
||||
"SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version",
|
||||
new
|
||||
{
|
||||
Xml = previewPoco.Xml,
|
||||
Timestamp = previewPoco.Timestamp,
|
||||
Id = previewPoco.NodeId,
|
||||
Version = previewPoco.VersionId
|
||||
})
|
||||
: Convert.ToInt32(db.Insert(previewPoco));
|
||||
}
|
||||
|
||||
private void CreateAndSaveContentXml(XElement xml, int id, UmbracoDatabase db)
|
||||
{
|
||||
var contentPoco = new ContentXmlDto { NodeId = id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var contentExists = db.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = id }) != 0;
|
||||
int contentResult = contentExists ? db.Update(contentPoco) : Convert.ToInt32(db.Insert(contentPoco));
|
||||
}
|
||||
|
||||
private IContentType FindContentTypeByAlias(string contentTypeAlias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
@@ -1463,7 +1658,7 @@ namespace Umbraco.Core.Services
|
||||
var query = Query<IContentType>.Builder.Where(x => x.Alias == contentTypeAlias);
|
||||
var types = repository.GetByQuery(query);
|
||||
|
||||
if (!types.Any())
|
||||
if (types.Any() == false)
|
||||
throw new Exception(
|
||||
string.Format("No ContentType matching the passed in Alias: '{0}' was found",
|
||||
contentTypeAlias));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
@@ -12,8 +11,13 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -23,8 +27,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -288,5 +297,49 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content"><see cref="IContent"/> to check if anscestors are published</param>
|
||||
/// <returns>True if the Content can be published, otherwise False</returns>
|
||||
bool IsPublishable(IContent content);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using this method will ensure that the Published-state is maintained upon sorting
|
||||
/// so the cache is updated accordingly - as needed.
|
||||
/// </remarks>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
bool Sort(SortedSet<IContent> items, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,13 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -22,8 +27,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -184,5 +194,45 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="mediaPath">Path of the media item to retreive (for example: /media/1024/koala_403x328.jpg)</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia GetMediaByPath(string mediaPath);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IMedia"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
bool Sort(SortedSet<IMedia> items, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -46,25 +51,7 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
IMediaType mediaType;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (!mediaTypes.Any())
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
}
|
||||
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
@@ -84,8 +71,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -93,25 +85,7 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
IMediaType mediaType;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (!mediaTypes.Any())
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
}
|
||||
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
@@ -128,6 +102,94 @@ namespace Umbraco.Core.Services
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id);
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id);
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMedia"/> object by Id
|
||||
/// </summary>
|
||||
@@ -598,18 +660,14 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
var poco = new ContentXmlDto {NodeId = media.Id, Xml = xml.ToString(SaveOptions.None)};
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = media.Id}) != null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Media performed by user", media.CreatorId, media.Id);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Media performed by user", userId, media.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -626,6 +684,7 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
var mediaXml = new Dictionary<int, Lazy<XElement>>();
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
@@ -637,6 +696,11 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//commit the whole lot in one go
|
||||
uow.Commit();
|
||||
|
||||
foreach (var media in medias)
|
||||
{
|
||||
CreateAndSaveMediaXml(media.ToXml(), media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
if(raiseEvents)
|
||||
@@ -645,6 +709,67 @@ namespace Umbraco.Core.Services
|
||||
Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IMedia"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
public bool Sort(SortedSet<IMedia> items, int userId = 0, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(items), this))
|
||||
return false;
|
||||
}
|
||||
|
||||
var shouldBeCached = new List<IMedia>();
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var media in items)
|
||||
{
|
||||
//If the current sort order equals that of the media
|
||||
//we don't need to update it, so just increment the sort order
|
||||
//and continue.
|
||||
if (media.SortOrder == i)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
media.SortOrder = i;
|
||||
i++;
|
||||
|
||||
repository.AddOrUpdate(media);
|
||||
shouldBeCached.Add(media);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var content in shouldBeCached)
|
||||
{
|
||||
//Create and Save ContentXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSaveMediaXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(items, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Sort, "Sorting Media performed by user", userId, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Path and Level on a collection of <see cref="IMedia"/> objects
|
||||
/// based on the Parent's Path and Level.
|
||||
@@ -671,6 +796,35 @@ namespace Umbraco.Core.Services
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CreateAndSaveMediaXml(XElement xml, int id, UmbracoDatabase db)
|
||||
{
|
||||
var poco = new ContentXmlDto { NodeId = id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = db.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = id }) != null;
|
||||
int result = exists ? db.Update(poco) : Convert.ToInt32(db.Insert(poco));
|
||||
}
|
||||
|
||||
private IMediaType FindMediaTypeByAlias(string mediaTypeAlias)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (mediaTypes.Any() == false)
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
var mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -324,6 +324,7 @@ namespace Umbraco.Core.Services
|
||||
var template = _fileService.GetTemplate(alias);
|
||||
if (template != null)
|
||||
{
|
||||
if(allowedTemplates.Any(x => x.Id == template.Id)) continue;
|
||||
allowedTemplates.Add(template);
|
||||
}
|
||||
else
|
||||
|
||||
+179
-65
@@ -19,8 +19,6 @@ using Umbraco.Core.IO;
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
//TODO: Get the App_Code stuff in here from the old one
|
||||
|
||||
/// <summary>
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
@@ -143,7 +141,8 @@ namespace Umbraco.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
var foundAssembly = safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
var foundAssembly =
|
||||
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
if (foundAssembly != null)
|
||||
{
|
||||
binFolderAssemblies.Add(foundAssembly);
|
||||
@@ -236,7 +235,7 @@ namespace Umbraco.Core
|
||||
"umbraco.interfaces,",
|
||||
"umbraco.providers,",
|
||||
"Umbraco.Web.UI,",
|
||||
"umbraco.webservices",
|
||||
"umbraco.webservices",
|
||||
"Lucene.",
|
||||
"Examine,",
|
||||
"Examine.",
|
||||
@@ -248,36 +247,66 @@ namespace Umbraco.Core
|
||||
"CookComputing."
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<TAttribute>(typeof (T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach(var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface
|
||||
&& typeof (T).IsAssignableFrom(t)
|
||||
&& t.GetCustomAttributes<TAttribute>(false).Any()
|
||||
&& (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
|
||||
return l;
|
||||
|
||||
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
|
||||
//the additional filter will ensure that any found types also have the attribute applied.
|
||||
t => t.GetCustomAttributes<TAttribute>(false).Any());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -301,7 +330,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetAssignablesFromType<T>(assemblies, onlyConcreteClasses);
|
||||
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -328,32 +357,50 @@ namespace Umbraco.Core
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <param name="type">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(Type type, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
if (!TypeHelper.IsTypeAssignableFrom<Attribute>(type))
|
||||
throw new ArgumentException("The type specified: " + type + " is not an Attribute type");
|
||||
/// <summary>
|
||||
/// Finds any classes with the attribute.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(
|
||||
Type attributeType,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && t.GetCustomAttributes(type, false).Any() && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
|
||||
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
|
||||
|
||||
return l;
|
||||
}
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
|
||||
/// <summary>
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
//find all assembly references that are referencing the attribute type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain a class that has this attribute.
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
|
||||
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allTypes = GetTypesWithFormattedException(a).ToArray();
|
||||
|
||||
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
//the type must have this attribute
|
||||
&& t.GetCustomAttributes(attributeType, false).Any());
|
||||
|
||||
foundAssignableTypes.AddRange(types);
|
||||
}
|
||||
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
@@ -379,29 +426,96 @@ namespace Umbraco.Core
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of assignables of type T from a collection of assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetAssignablesFromType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
/// <summary>
|
||||
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
|
||||
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
|
||||
/// deriving from the base type.
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetClasses(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses,
|
||||
Func<Type, bool> additionalFilter = null)
|
||||
{
|
||||
return GetTypes(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
//the default filter will always return true.
|
||||
if (additionalFilter == null)
|
||||
{
|
||||
additionalFilter = type => true;
|
||||
}
|
||||
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
//find all assembly references that are referencing the current type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain sub type's of the one we're currently looking for
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(assignTypeFrom, assemblyList);
|
||||
|
||||
//get a list of non-referenced assemblies (we'll use this when we recurse below)
|
||||
var otherAssemblies = assemblyList.Where(x => referencedAssemblies.Contains(x) == false).ToArray();
|
||||
|
||||
//loop through the referenced assemblies
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allSubTypes = GetTypesWithFormattedException(a)
|
||||
.Where(assignTypeFrom.IsAssignableFrom)
|
||||
.ToArray();
|
||||
|
||||
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
|
||||
var filteredTypes = allSubTypes
|
||||
.Where(t => (TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
&& additionalFilter(t)))
|
||||
.ToArray();
|
||||
|
||||
//add the types to our list to return
|
||||
foundAssignableTypes.AddRange(filteredTypes);
|
||||
|
||||
//now we need to include types that may be inheriting from sub classes of the type being searched for
|
||||
//so we will search in assemblies that reference those types too.
|
||||
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
|
||||
{
|
||||
|
||||
//So that we are not scanning too much, we need to group the sub types:
|
||||
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
|
||||
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
|
||||
// * We should not search for sub types if the type is static since you cannot inherit from them.
|
||||
var subTypeList = subTypesInAssembly
|
||||
.Where(t => t.IsSealed == false && TypeHelper.IsStaticClass(t) == false)
|
||||
.ToArray();
|
||||
|
||||
var baseClassAttempt = TypeHelper.GetLowestBaseType(subTypeList);
|
||||
|
||||
//if there's a base class amongst the types then we'll only search for that type.
|
||||
//otherwise we'll have to search for all of them.
|
||||
var subTypesToSearch = new List<Type>();
|
||||
if (baseClassAttempt.Success)
|
||||
{
|
||||
subTypesToSearch.Add(baseClassAttempt.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
subTypesToSearch.AddRange(subTypeList);
|
||||
}
|
||||
|
||||
foreach (var typeToSearch in subTypesToSearch)
|
||||
{
|
||||
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
|
||||
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses);
|
||||
foundAssignableTypes.AddRange(foundTypes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypes(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
return l;
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
|
||||
@@ -420,7 +534,7 @@ namespace Umbraco.Core
|
||||
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
|
||||
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
|
||||
{
|
||||
sb.AppendLine("Exception: " + loaderException.ToString());
|
||||
sb.AppendLine("Exception: " + loaderException);
|
||||
}
|
||||
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -11,12 +12,113 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal static class TypeHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, Type>, bool> TypeCheckCache = new ConcurrentDictionary<Tuple<Type, Type>, bool>();
|
||||
private static readonly ConcurrentDictionary<Type, bool> ValueTypeCache = new ConcurrentDictionary<Type, bool>();
|
||||
private static readonly ConcurrentDictionary<Type, bool> ImplicitValueTypeCache = new ConcurrentDictionary<Type, bool>();
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache = new ConcurrentDictionary<Type, FieldInfo[]>();
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// If the assembly of the assignTypeFrom Type is in the App_Code assembly, then we return nothing since things cannot
|
||||
/// reference that assembly, same with the global.asax assembly.
|
||||
/// </remarks>
|
||||
public static Assembly[] GetReferencedAssemblies(Type assignTypeFrom, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
//check if it is the app_code assembly.
|
||||
//check if it is App_global.asax assembly
|
||||
if (assignTypeFrom.Assembly.IsAppCodeAssembly() || assignTypeFrom.Assembly.IsGlobalAsaxAssembly())
|
||||
{
|
||||
return Enumerable.Empty<Assembly>().ToArray();
|
||||
}
|
||||
|
||||
//find all assembly references that are referencing the current type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain sub type's of the one we're currently looking for
|
||||
return assemblies
|
||||
.Where(assembly =>
|
||||
assembly == assignTypeFrom.Assembly || HasReferenceToAssemblyWithName(assembly, assignTypeFrom.Assembly.GetName().Name))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks if the assembly has a reference with the same name as the expected assembly name.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <param name="expectedAssemblyName"></param>
|
||||
/// <returns></returns>
|
||||
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
|
||||
{
|
||||
return assembly
|
||||
.GetReferencedAssemblies()
|
||||
.Select(a => a.Name)
|
||||
.Contains(expectedAssemblyName, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the type is a class and is not static
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNonStaticClass(Type t)
|
||||
{
|
||||
return t.IsClass && IsStaticClass(t) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the type is a static class
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// In IL a static class is abstract and sealed
|
||||
/// see: http://stackoverflow.com/questions/1175888/determine-if-a-type-is-static
|
||||
/// </remarks>
|
||||
public static bool IsStaticClass(Type type)
|
||||
{
|
||||
return type.IsAbstract && type.IsSealed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a lowest base class amongst a collection of types
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The term 'lowest' refers to the most base class of the type collection.
|
||||
/// If a base type is not found amongst the type collection then an invalid attempt is returned.
|
||||
/// </remarks>
|
||||
public static Attempt<Type> GetLowestBaseType(params Type[] types)
|
||||
{
|
||||
if (types.Length == 0)
|
||||
{
|
||||
return Attempt<Type>.False;
|
||||
}
|
||||
if (types.Length == 1)
|
||||
{
|
||||
return new Attempt<Type>(true, types[0]);
|
||||
}
|
||||
|
||||
foreach (var curr in types)
|
||||
{
|
||||
var others = types.Except(new[] {curr});
|
||||
|
||||
//is the curr type a common denominator for all others ?
|
||||
var isBase = others.All(curr.IsAssignableFrom);
|
||||
|
||||
//if this type is the base for all others
|
||||
if (isBase)
|
||||
{
|
||||
return new Attempt<Type>(true, curr);
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<Type>.False;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the type <paramref name="implementation"/> is assignable from the specified implementation <typeparamref name="TContract"/>,
|
||||
/// and caches the result across the application using a <see cref="ConcurrentDictionary{TKey,TValue}"/>.
|
||||
@@ -28,8 +130,7 @@ namespace Umbraco.Core
|
||||
/// </returns>
|
||||
public static bool IsTypeAssignableFrom(Type contract, Type implementation)
|
||||
{
|
||||
// NOTE The use of a Tuple<,> here is because its Equals / GetHashCode implementation is literally 10.5x faster than KeyValuePair<,>
|
||||
return TypeCheckCache.GetOrAdd(new Tuple<Type, Type>(contract, implementation), x => x.Item1.IsAssignableFrom(x.Item2));
|
||||
return contract.IsAssignableFrom(implementation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,7 +150,7 @@ namespace Umbraco.Core
|
||||
/// <param name="implementation">The implementation.</param>
|
||||
public static bool IsValueType(Type implementation)
|
||||
{
|
||||
return ValueTypeCache.GetOrAdd(implementation, x => x.IsValueType || x.IsPrimitive);
|
||||
return implementation.IsValueType || implementation.IsPrimitive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -58,7 +159,7 @@ namespace Umbraco.Core
|
||||
/// <param name="implementation">The implementation.</param>
|
||||
public static bool IsImplicitValueType(Type implementation)
|
||||
{
|
||||
return ImplicitValueTypeCache.GetOrAdd(implementation, x => IsValueType(implementation) || implementation.IsEnum || implementation == typeof(string));
|
||||
return IsValueType(implementation) || implementation.IsEnum || implementation == typeof (string);
|
||||
}
|
||||
|
||||
public static bool IsTypeAssignableFrom<TContract>(object implementation)
|
||||
|
||||
@@ -675,7 +675,7 @@
|
||||
<Compile Include="IfExtensions.cs" />
|
||||
<Compile Include="PluginManager.cs" />
|
||||
<Compile Include="IO\FileSecurityException.cs" />
|
||||
<Compile Include="IO\FileSystemProvider.cs" />
|
||||
<Compile Include="IO\FileSystemProviderConstants.cs" />
|
||||
<Compile Include="IO\FileSystemProviderManager.cs" />
|
||||
<Compile Include="IO\IFileSystem.cs" />
|
||||
<Compile Include="IO\IOHelper.cs" />
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -27,6 +28,9 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal void StartApplication(object sender, EventArgs e)
|
||||
{
|
||||
//don't output the MVC version header (security)
|
||||
MvcHandler.DisableMvcResponseHeader = true;
|
||||
|
||||
//boot up the application
|
||||
GetBootManager()
|
||||
.Initialize()
|
||||
|
||||
@@ -17,7 +17,72 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public class XmlHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a specified string contains only xml whitespace characters.
|
||||
/// </summary>
|
||||
/// <param name="s">The string.</param>
|
||||
/// <returns><c>true</c> if the string contains only xml whitespace characters.</returns>
|
||||
/// <remarks>As per XML 1.1 specs, space, \t, \r and \n.</remarks>
|
||||
public static bool IsXmlWhitespace(string s)
|
||||
{
|
||||
// as per xml 1.1 specs - anything else is significant whitespace
|
||||
s = s.Trim(' ', '\t', '\r', '\n');
|
||||
return s.Length == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <c>XPathDocument</c> from an xml string.
|
||||
/// </summary>
|
||||
/// <param name="xml">The xml string.</param>
|
||||
/// <returns>An <c>XPathDocument</c> created from the xml string.</returns>
|
||||
public static XPathDocument CreateXPathDocument(string xml)
|
||||
{
|
||||
return new XPathDocument(new XmlTextReader(new StringReader(xml)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to create a new <c>XPathDocument</c> from an xml string.
|
||||
/// </summary>
|
||||
/// <param name="xml">The xml string.</param>
|
||||
/// <param name="doc">The XPath document.</param>
|
||||
/// <returns>A value indicating whether it has been possible to create the document.</returns>
|
||||
public static bool TryCreateXPathDocument(string xml, out XPathDocument doc)
|
||||
{
|
||||
try
|
||||
{
|
||||
doc = new XPathDocument(new XmlTextReader(new StringReader(xml)));
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
doc = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to create a new <c>XPathDocument</c> from a property value.
|
||||
/// </summary>
|
||||
/// <param name="alias">The alias of the property.</param>
|
||||
/// <param name="value">The value of the property.</param>
|
||||
/// <param name="doc">The XPath document.</param>
|
||||
/// <returns>A value indicating whether it has been possible to create the document.</returns>
|
||||
public static bool TryCreateXPathDocumentFromPropertyValue(string alias, object value, out XPathDocument doc)
|
||||
{
|
||||
// In addition, DynamicNode strips dashes in elements or attributes
|
||||
// names but really, this is ugly enough, and using dashes should be
|
||||
// illegal in content type or property aliases anyway.
|
||||
|
||||
doc = null;
|
||||
var xml = value as string;
|
||||
if (xml == null) return false;
|
||||
xml = xml.Trim();
|
||||
if (xml.StartsWith("<") == false || xml.EndsWith(">") == false || xml.Contains('/') == false) return false;
|
||||
if (UmbracoSettings.NotDynamicXmlDocumentElements.Any(x => x.InvariantEquals(alias))) return false;
|
||||
return TryCreateXPathDocument(xml, out doc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the children of the parentNode that match the xpath selector
|
||||
/// </summary>
|
||||
/// <param name="parentNode"></param>
|
||||
@@ -72,7 +137,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string StripDashesInElementOrAttributeNames(string xml)
|
||||
{
|
||||
using (var outputms = new MemoryStream())
|
||||
@@ -126,6 +191,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Imports a XML node from text.
|
||||
/// </summary>
|
||||
@@ -222,11 +288,11 @@ namespace Umbraco.Core
|
||||
/// </returns>
|
||||
public static bool CouldItBeXml(string xml)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(xml))
|
||||
if (string.IsNullOrEmpty(xml) == false)
|
||||
{
|
||||
xml = xml.Trim();
|
||||
|
||||
if (xml.StartsWith("<") && xml.EndsWith(">"))
|
||||
if (xml.StartsWith("<") && xml.EndsWith(">") && xml.Contains("/"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,34 @@ using umbraco.BusinessLogic;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[TestFixture]
|
||||
public class EnumerableExtensionsTests
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void Flatten_List()
|
||||
{
|
||||
var hierarchy = new TestItem()
|
||||
{
|
||||
Children = new List<TestItem>()
|
||||
[Test]
|
||||
public void Flatten_List_2()
|
||||
{
|
||||
var hierarchy = new TestItem()
|
||||
{
|
||||
Children = new List<TestItem>()
|
||||
{
|
||||
new TestItem(),
|
||||
new TestItem(),
|
||||
new TestItem()
|
||||
}
|
||||
};
|
||||
|
||||
var flattened = hierarchy.Children.FlattenList(x => x.Children);
|
||||
|
||||
Assert.AreEqual(3, flattened.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Flatten_List()
|
||||
{
|
||||
var hierarchy = new TestItem()
|
||||
{
|
||||
Children = new List<TestItem>()
|
||||
{
|
||||
new TestItem()
|
||||
{
|
||||
@@ -65,12 +83,12 @@ namespace Umbraco.Tests
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var flattened = hierarchy.Children.FlattenList(x => x.Children);
|
||||
var flattened = hierarchy.Children.FlattenList(x => x.Children);
|
||||
|
||||
Assert.AreEqual(10, flattened.Count());
|
||||
}
|
||||
}
|
||||
|
||||
private class TestItem
|
||||
{
|
||||
@@ -78,7 +96,7 @@ namespace Umbraco.Tests
|
||||
{
|
||||
Children = Enumerable.Empty<TestItem>();
|
||||
}
|
||||
public IEnumerable<TestItem> Children { get; set; }
|
||||
public IEnumerable<TestItem> Children { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Umbraco.Tests.IO
|
||||
[Test]
|
||||
public void Can_Get_Base_File_System()
|
||||
{
|
||||
var fs = FileSystemProviderManager.Current.GetFileSystemProvider(FileSystemProvider.Media);
|
||||
var fs = FileSystemProviderManager.Current.GetUnderlyingFileSystemProvider(FileSystemProviderConstants.Media);
|
||||
|
||||
Assert.NotNull(fs);
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ namespace Umbraco.Tests
|
||||
public void Resolves_DataTypes()
|
||||
{
|
||||
var types = PluginManager.Current.ResolveDataTypes();
|
||||
Assert.AreEqual(37, types.Count());
|
||||
Assert.AreEqual(38, types.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -317,7 +317,7 @@ namespace Umbraco.Tests
|
||||
public void Resolves_RestExtensions()
|
||||
{
|
||||
var types = PluginManager.Current.ResolveRestExtensions();
|
||||
Assert.AreEqual(2, types.Count());
|
||||
Assert.AreEqual(3, types.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
//need to specify a custom callback for unit tests
|
||||
PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
|
||||
{
|
||||
if (propertyAlias == "content")
|
||||
if (propertyAlias.InvariantEquals("content"))
|
||||
{
|
||||
//return the rte type id
|
||||
return Guid.Parse("5e9b75ae-face-41c8-b47e-5f4b0fd82f83");
|
||||
|
||||
@@ -222,6 +222,10 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var propVal2 = doc.GetPropertyValue<IHtmlString>("content");
|
||||
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal2.GetType()));
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
|
||||
|
||||
var propVal3 = doc.GetPropertyValue("Content");
|
||||
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal3.GetType()));
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal3.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
@@ -218,6 +219,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
|
||||
public class PublishedContentWrapper : IPublishedContent, IOwnerCollectionAware<IPublishedContent>
|
||||
{
|
||||
protected IPublishedContent WrappedContent { get; private set; }
|
||||
|
||||
@@ -162,6 +162,30 @@ namespace Umbraco.Tests.Services.Importing
|
||||
Assert.That(contentMaster.PropertyGroups["SEO"].PropertyTypes.Any(x => x.PropertyGroupId.Value != propertyGroupId), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackagingService_Can_Import_StandardMvc_ContentTypes_And_Templates_Xml()
|
||||
{
|
||||
// Arrange
|
||||
string strXml = ImportResources.StandardMvc_Package;
|
||||
var xml = XElement.Parse(strXml);
|
||||
var dataTypeElement = xml.Descendants("DataTypes").First();
|
||||
var templateElement = xml.Descendants("Templates").First();
|
||||
var docTypeElement = xml.Descendants("DocumentTypes").First();
|
||||
|
||||
// Act
|
||||
var dataTypeDefinitions = ServiceContext.PackagingService.ImportDataTypeDefinitions(dataTypeElement);
|
||||
var templates = ServiceContext.PackagingService.ImportTemplates(templateElement);
|
||||
var contentTypes = ServiceContext.PackagingService.ImportContentTypes(docTypeElement);
|
||||
var numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count();
|
||||
|
||||
//Assert - Re-Import contenttypes doesn't throw
|
||||
Assert.DoesNotThrow(() => ServiceContext.PackagingService.ImportContentTypes(docTypeElement));
|
||||
Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes));
|
||||
Assert.That(dataTypeDefinitions, Is.Not.Null);
|
||||
Assert.That(dataTypeDefinitions.Any(), Is.True);
|
||||
Assert.That(templates.Any(), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackagingService_Can_Import_Content_Package_Xml()
|
||||
{
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Compilation;
|
||||
using NUnit.Framework;
|
||||
using SqlCE4Umbraco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Tests;
|
||||
using Umbraco.Tests.PartialTrust;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.BaseRest;
|
||||
using umbraco;
|
||||
using umbraco.DataLayer;
|
||||
using umbraco.MacroEngines;
|
||||
using umbraco.businesslogic;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.editorControls.tags;
|
||||
using umbraco.interfaces;
|
||||
using umbraco.uicontrols;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Full Trust benchmark tests for typefinder and the old typefinder
|
||||
|
||||
/// <summary>
|
||||
/// Tests for typefinder
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TypeFinderTests
|
||||
@@ -50,45 +62,578 @@ namespace Umbraco.Tests
|
||||
typeof(System.Web.Mvc.ActionResult).Assembly,
|
||||
typeof(TypeFinder).Assembly,
|
||||
typeof(ISqlHelper).Assembly,
|
||||
typeof(ICultureDictionary).Assembly
|
||||
typeof(ICultureDictionary).Assembly,
|
||||
typeof(Tag).Assembly,
|
||||
typeof(UmbracoExamine.BaseUmbracoIndexer).Assembly
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class MyTestAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract class TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[MyTestAttribute]
|
||||
public class BenchmarkTestEditor : TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[MyTestAttribute]
|
||||
public class MyOtherTestEditor : TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Type_With_Attribute()
|
||||
public void Find_Class_Of_Type_With_Attribute()
|
||||
{
|
||||
|
||||
var typesFound = TypeFinder.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies);
|
||||
|
||||
Assert.AreEqual(2, typesFound.Count());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void Find_Classes_Of_Type()
|
||||
{
|
||||
var typesFound = TypeFinder.FindClassesOfType<IApplicationStartupHandler>(_assemblies);
|
||||
var originalTypesFound = TypeFinderOriginal.FindClassesOfType<IApplicationStartupHandler>(_assemblies);
|
||||
|
||||
Assert.AreEqual(originalTypesFound.Count(), typesFound.Count());
|
||||
Assert.AreEqual(6, typesFound.Count());
|
||||
Assert.AreEqual(6, originalTypesFound.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Find_Classes_With_Attribute()
|
||||
{
|
||||
var typesFound = TypeFinder.FindClassesWithAttribute<RestExtensionAttribute>(_assemblies);
|
||||
Assert.AreEqual(1, typesFound.Count());
|
||||
}
|
||||
|
||||
[Ignore]
|
||||
[Test]
|
||||
public void Benchmark_Original_Finder()
|
||||
{
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting test", "Finished test"))
|
||||
{
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting FindClassesOfType", "Finished FindClassesOfType"))
|
||||
{
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Assert.Greater(TypeFinderOriginal.FindClassesOfType<DisposableObject>(_assemblies).Count(), 0);
|
||||
}
|
||||
}
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting FindClassesOfTypeWithAttribute", "Finished FindClassesOfTypeWithAttribute"))
|
||||
{
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Assert.Greater(TypeFinderOriginal.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies).Count(), 0);
|
||||
}
|
||||
}
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting FindClassesWithAttribute", "Finished FindClassesWithAttribute"))
|
||||
{
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Assert.Greater(TypeFinderOriginal.FindClassesWithAttribute<XsltExtensionAttribute>(_assemblies).Count(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Ignore]
|
||||
[Test]
|
||||
public void Benchmark_New_Finder()
|
||||
{
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting test", "Finished test"))
|
||||
{
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting FindClassesOfType", "Finished FindClassesOfType"))
|
||||
{
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Assert.Greater(TypeFinder.FindClassesOfType<DisposableObject>(_assemblies).Count(), 0);
|
||||
}
|
||||
}
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting FindClassesOfTypeWithAttribute", "Finished FindClassesOfTypeWithAttribute"))
|
||||
{
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Assert.Greater(TypeFinder.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies).Count(), 0);
|
||||
}
|
||||
}
|
||||
using (DisposableTimer.TraceDuration<TypeFinderTests>("Starting FindClassesWithAttribute", "Finished FindClassesWithAttribute"))
|
||||
{
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Assert.Greater(TypeFinder.FindClassesWithAttribute<XsltExtensionAttribute>(_assemblies).Count(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MyTag : ITag
|
||||
{
|
||||
public int Id { get; private set; }
|
||||
public string TagCaption { get; private set; }
|
||||
public string Group { get; private set; }
|
||||
}
|
||||
|
||||
public class MySuperTag : MyTag
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class MyTestAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract class TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[MyTestAttribute]
|
||||
public class BenchmarkTestEditor : TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[MyTestAttribute]
|
||||
public class MyOtherTestEditor : TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//USED FOR THE ABOVE TESTS
|
||||
// see this issue for details: http://issues.umbraco.org/issue/U4-1187
|
||||
internal static class TypeFinderOriginal
|
||||
{
|
||||
|
||||
private static readonly ConcurrentBag<Assembly> LocalFilteredAssemblyCache = new ConcurrentBag<Assembly>();
|
||||
private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
|
||||
private static ReadOnlyCollection<Assembly> _allAssemblies = null;
|
||||
private static ReadOnlyCollection<Assembly> _binFolderAssemblies = null;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// lazily load a reference to all assemblies and only local assemblies.
|
||||
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
|
||||
/// loaded in the CLR, not all assemblies.
|
||||
/// See these threads:
|
||||
/// http://issues.umbraco.org/issue/U5-198
|
||||
/// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
|
||||
/// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
|
||||
/// </remarks>
|
||||
internal static IEnumerable<Assembly> GetAllAssemblies()
|
||||
{
|
||||
if (_allAssemblies == null)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
List<Assembly> assemblies = null;
|
||||
try
|
||||
{
|
||||
var isHosted = HttpContext.Current != null;
|
||||
|
||||
try
|
||||
{
|
||||
if (isHosted)
|
||||
{
|
||||
assemblies = new List<Assembly>(BuildManager.GetReferencedAssemblies().Cast<Assembly>());
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
if (!(e.InnerException is SecurityException))
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
if (assemblies == null)
|
||||
{
|
||||
//NOTE: we cannot use AppDomain.CurrentDomain.GetAssemblies() because this only returns assemblies that have
|
||||
// already been loaded in to the app domain, instead we will look directly into the bin folder and load each one.
|
||||
var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
|
||||
var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
|
||||
assemblies = new List<Assembly>();
|
||||
foreach (var a in binAssemblyFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
var assName = AssemblyName.GetAssemblyName(a);
|
||||
var ass = Assembly.Load(assName);
|
||||
assemblies.Add(ass);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is SecurityException || e is BadImageFormatException)
|
||||
{
|
||||
//swallow these exceptions
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
|
||||
if (!assemblies.Any())
|
||||
{
|
||||
assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().ToList());
|
||||
}
|
||||
|
||||
//here we are trying to get the App_Code assembly
|
||||
var fileExtensions = new[] { ".cs", ".vb" }; //only vb and cs files are supported
|
||||
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
|
||||
//check if the folder exists and if there are any files in it with the supported file extensions
|
||||
if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
|
||||
{
|
||||
var appCodeAssembly = Assembly.Load("App_Code");
|
||||
if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
|
||||
assemblies.Add(appCodeAssembly);
|
||||
}
|
||||
|
||||
//now set the _allAssemblies
|
||||
_allAssemblies = new ReadOnlyCollection<Assembly>(assemblies);
|
||||
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
if (!(e.InnerException is SecurityException))
|
||||
throw;
|
||||
|
||||
_binFolderAssemblies = _allAssemblies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _allAssemblies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only assemblies found in the bin folder that have been loaded into the app domain.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
|
||||
/// </remarks>
|
||||
internal static IEnumerable<Assembly> GetBinAssemblies()
|
||||
{
|
||||
|
||||
if (_binFolderAssemblies == null)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var assemblies = GetAssembliesWithKnownExclusions().ToArray();
|
||||
var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
|
||||
var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
|
||||
var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
|
||||
var safeDomainAssemblies = new List<Assembly>();
|
||||
var binFolderAssemblies = new List<Assembly>();
|
||||
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
//do a test to see if its queryable in med trust
|
||||
var assemblyFile = a.GetAssemblyFile();
|
||||
safeDomainAssemblies.Add(a);
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
//we will just ignore this because this will fail
|
||||
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
|
||||
//an assembly that is ok.
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var assemblyName in domainAssemblyNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
var foundAssembly = safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
if (foundAssembly != null)
|
||||
{
|
||||
binFolderAssemblies.Add(foundAssembly);
|
||||
}
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
//we will just ignore this because if we are trying to do a call to:
|
||||
// AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
|
||||
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
|
||||
//an assembly that is ok.
|
||||
}
|
||||
}
|
||||
|
||||
_binFolderAssemblies = new ReadOnlyCollection<Assembly>(binFolderAssemblies);
|
||||
}
|
||||
}
|
||||
return _binFolderAssemblies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
|
||||
/// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
|
||||
/// cached for perforance reasons.
|
||||
/// </summary>
|
||||
/// <param name="excludeFromResults"></param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Assembly> GetAssembliesWithKnownExclusions(
|
||||
IEnumerable<Assembly> excludeFromResults = null)
|
||||
{
|
||||
if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
|
||||
using (new WriteLock(LocalFilteredAssemblyCacheLocker))
|
||||
{
|
||||
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
|
||||
assemblies.ForEach(LocalFilteredAssemblyCache.Add);
|
||||
}
|
||||
return LocalFilteredAssemblyCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
|
||||
/// </summary>
|
||||
/// <param name="excludeFromResults"></param>
|
||||
/// <param name="exclusionFilter"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Assembly> GetFilteredAssemblies(
|
||||
IEnumerable<Assembly> excludeFromResults = null,
|
||||
string[] exclusionFilter = null)
|
||||
{
|
||||
if (excludeFromResults == null)
|
||||
excludeFromResults = new List<Assembly>();
|
||||
if (exclusionFilter == null)
|
||||
exclusionFilter = new string[] { };
|
||||
|
||||
return GetAllAssemblies()
|
||||
.Where(x => !excludeFromResults.Contains(x)
|
||||
&& !x.GlobalAssemblyCache
|
||||
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
|
||||
/// </remarks>
|
||||
internal static readonly string[] KnownAssemblyExclusionFilter = new[]
|
||||
{
|
||||
"mscorlib,",
|
||||
"System.",
|
||||
"Antlr3.",
|
||||
"Autofac.",
|
||||
"Autofac,",
|
||||
"Castle.",
|
||||
"ClientDependency.",
|
||||
"DataAnnotationsExtensions.",
|
||||
"DataAnnotationsExtensions,",
|
||||
"Dynamic,",
|
||||
"HtmlDiff,",
|
||||
"Iesi.Collections,",
|
||||
"log4net,",
|
||||
"Microsoft.",
|
||||
"Newtonsoft.",
|
||||
"NHibernate.",
|
||||
"NHibernate,",
|
||||
"NuGet.",
|
||||
"RouteDebugger,",
|
||||
"SqlCE4Umbraco,",
|
||||
"umbraco.datalayer,",
|
||||
"umbraco.interfaces,",
|
||||
"umbraco.providers,",
|
||||
"Umbraco.Web.UI,",
|
||||
"umbraco.webservices",
|
||||
"Lucene.",
|
||||
"Examine,",
|
||||
"Examine.",
|
||||
"ServiceStack.",
|
||||
"MySql.",
|
||||
"HtmlAgilityPack.",
|
||||
"TidyNet.",
|
||||
"ICSharpCode.",
|
||||
"CookComputing."
|
||||
};
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface
|
||||
&& typeof(T).IsAssignableFrom(t)
|
||||
&& t.GetCustomAttributes<TAttribute>(false).Any()
|
||||
&& (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches all filtered local assemblies specified for classes of the type passed in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>()
|
||||
{
|
||||
return FindClassesOfType<T>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetAssignablesFromType<T>(assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
return FindClassesOfType<T>(assemblies, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <param name="type">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(Type type, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
if (!TypeHelper.IsTypeAssignableFrom<Attribute>(type))
|
||||
throw new ArgumentException("The type specified: " + type + " is not an Attribute type");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && t.GetCustomAttributes(type, false).Any() && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute<T>(assemblies, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute in filtered local assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>()
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
|
||||
}
|
||||
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of assignables of type T from a collection of assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetAssignablesFromType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
return GetTypes(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypes(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
|
||||
{
|
||||
//if the assembly is dynamic, do not try to scan it
|
||||
if (a.IsDynamic)
|
||||
return Enumerable.Empty<Type>();
|
||||
|
||||
try
|
||||
{
|
||||
return a.GetExportedTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
|
||||
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
|
||||
{
|
||||
sb.AppendLine("Exception: " + loaderException.ToString());
|
||||
}
|
||||
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Odbc;
|
||||
using System.Data.OleDb;
|
||||
using System.Data.SqlClient;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Tests.PartialTrust;
|
||||
using Umbraco.Web;
|
||||
using UmbracoExamine;
|
||||
using umbraco;
|
||||
using umbraco.presentation;
|
||||
using umbraco.presentation.nodeFactory;
|
||||
using umbraco.presentation.umbraco.Search;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for TypeHelper
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TypeHelperTests : AbstractPartialTrustFixture<TypeHelperTests>
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void Is_Static_Class()
|
||||
{
|
||||
Assert.IsTrue(TypeHelper.IsStaticClass(typeof(TypeHelper)));
|
||||
Assert.IsFalse(TypeHelper.IsStaticClass(typeof(TypeHelperTests)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Find_Common_Base_Class()
|
||||
{
|
||||
var t1 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
|
||||
typeof (OdbcCommand),
|
||||
typeof (SqlCommand));
|
||||
Assert.IsFalse(t1.Success);
|
||||
|
||||
var t2 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
|
||||
typeof (OdbcCommand),
|
||||
typeof (SqlCommand),
|
||||
typeof (Component));
|
||||
Assert.IsTrue(t2.Success);
|
||||
Assert.AreEqual(typeof(Component), t2.Result);
|
||||
|
||||
var t3 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
|
||||
typeof (OdbcCommand),
|
||||
typeof (SqlCommand),
|
||||
typeof (Component),
|
||||
typeof (Component).BaseType);
|
||||
Assert.IsTrue(t3.Success);
|
||||
Assert.AreEqual(typeof(MarshalByRefObject), t3.Result);
|
||||
|
||||
var t4 = TypeHelper.GetLowestBaseType(typeof(OleDbCommand),
|
||||
typeof(OdbcCommand),
|
||||
typeof(SqlCommand),
|
||||
typeof(Component),
|
||||
typeof(Component).BaseType,
|
||||
typeof(int));
|
||||
Assert.IsFalse(t4.Success);
|
||||
|
||||
var t5 = TypeHelper.GetLowestBaseType(typeof(UmbracoEventManager));
|
||||
Assert.IsTrue(t5.Success);
|
||||
Assert.AreEqual(typeof(UmbracoEventManager), t5.Result);
|
||||
|
||||
var t6 = TypeHelper.GetLowestBaseType(typeof (IApplicationEventHandler),
|
||||
typeof (LegacyScheduledTasks),
|
||||
typeof(CacheHelperExtensions.CacheHelperApplicationEventListener));
|
||||
Assert.IsTrue(t6.Success);
|
||||
Assert.AreEqual(typeof(IApplicationEventHandler), t6.Result);
|
||||
|
||||
}
|
||||
|
||||
public override void TestSetup()
|
||||
{
|
||||
}
|
||||
|
||||
public override void TestTearDown()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,6 +306,7 @@
|
||||
<Compile Include="TestHelpers\Entities\MockedEntity.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedMedia.cs" />
|
||||
<Compile Include="TestHelpers\ExamineHelpers\IndexInitializer.cs" />
|
||||
<Compile Include="TypeHelperTests.cs" />
|
||||
<Compile Include="UriUtilityTests.cs" />
|
||||
<Compile Include="Resolvers\MacroFieldEditorsResolverTests.cs" />
|
||||
<Compile Include="MacroEngineFactoryTests.cs" />
|
||||
|
||||
@@ -236,10 +236,6 @@
|
||||
<Project>{511F6D8D-7717-440A-9A57-A507E9A8B27F}</Project>
|
||||
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\umbraco.webservices\umbraco.webservices.csproj">
|
||||
<Project>{CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}</Project>
|
||||
<Name>umbraco.webservices</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Umbraco.Web\Umbraco.Web.csproj">
|
||||
<Project>{651E1350-91B6-44B7-BD60-7207006D7003}</Project>
|
||||
<Name>Umbraco.Web</Name>
|
||||
@@ -327,6 +323,13 @@
|
||||
<Compile Include="Umbraco\Developer\Packages\StarterKits.aspx.designer.cs">
|
||||
<DependentUpon>StarterKits.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\Developer\Python\EditPython.aspx.cs">
|
||||
<DependentUpon>editPython.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\Developer\Python\EditPython.aspx.designer.cs">
|
||||
<DependentUpon>editPython.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\Dialogs\EditMacro.aspx.cs">
|
||||
<DependentUpon>EditMacro.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -374,6 +377,20 @@
|
||||
<Compile Include="Umbraco\Settings\EditTemplate.aspx.designer.cs">
|
||||
<DependentUpon>editTemplate.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\settings\Stylesheet\editstylesheet.aspx.cs">
|
||||
<DependentUpon>editstylesheet.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\settings\Stylesheet\editstylesheet.aspx.designer.cs">
|
||||
<DependentUpon>editstylesheet.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\settings\Stylesheet\Property\EditStyleSheetProperty.aspx.cs">
|
||||
<DependentUpon>EditStyleSheetProperty.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\settings\Stylesheet\Property\EditStyleSheetProperty.aspx.designer.cs">
|
||||
<DependentUpon>EditStyleSheetProperty.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Umbraco\Settings\Views\EditView.aspx.cs">
|
||||
<DependentUpon>EditView.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -518,13 +535,6 @@
|
||||
<Content Include="Umbraco\Plugins\UGoLive\throbber.gif" />
|
||||
<Content Include="Umbraco\Plugins\UGoLive\tick.png" />
|
||||
<Content Include="Umbraco\Settings\Views\EditView.aspx" />
|
||||
<Content Include="Umbraco\Webservices\Api\DocumentService.asmx" />
|
||||
<Content Include="Umbraco\Webservices\Api\FileService.asmx" />
|
||||
<Content Include="Umbraco\Webservices\Api\MaintanceService.asmx" />
|
||||
<Content Include="Umbraco\Webservices\Api\MediaService.asmx" />
|
||||
<Content Include="Umbraco\Webservices\Api\MemberService.asmx" />
|
||||
<Content Include="Umbraco\Webservices\Api\StylesheetService.asmx" />
|
||||
<Content Include="Umbraco\Webservices\Api\TemplateService.asmx" />
|
||||
<Content Include="Umbraco_Client\CodeMirror\Js\Lib\codemirror.css" />
|
||||
<Content Include="Umbraco_Client\CodeMirror\Js\Lib\codemirror.js" />
|
||||
<Content Include="Umbraco_Client\CodeMirror\Js\Lib\Util\closetag.js" />
|
||||
@@ -693,7 +703,13 @@
|
||||
<Content Include="umbraco_Client\Editors\DirectoryBrowser.css" />
|
||||
<Content Include="Umbraco_Client\Dialogs\EditMacro.js" />
|
||||
<Content Include="Umbraco_Client\Dialogs\UmbracoField.js" />
|
||||
<Content Include="Umbraco_Client\Editors\EditMacroScripts.js" />
|
||||
<Content Include="Umbraco_Client\Editors\EditXslt.css" />
|
||||
<Content Include="Umbraco_Client\Editors\EditXslt.js" />
|
||||
<Content Include="Umbraco_Client\Editors\EditScript.js" />
|
||||
<Content Include="Umbraco_Client\Editors\EditMacro.css" />
|
||||
<Content Include="Umbraco_Client\Editors\EditStyleSheet.js" />
|
||||
<Content Include="Umbraco_Client\Editors\EditTemplate.js" />
|
||||
<Content Include="Umbraco_Client\Editors\EditView.js" />
|
||||
<Content Include="Umbraco_Client\FileUploader\Js\jquery.fileUploader.js" />
|
||||
<Content Include="Umbraco_Client\FolderBrowser\Css\folderbrowser.css" />
|
||||
@@ -1882,7 +1898,9 @@
|
||||
<Content Include="Config\feedProxy.config" />
|
||||
<Content Include="Umbraco_Client\ui\ui-lightness\jquery-ui.custom.css" />
|
||||
<Content Include="Config\applications.config" />
|
||||
<Content Include="Config\trees.config" />
|
||||
<Content Include="Config\trees.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<None Include="Config\applications.Release.config">
|
||||
<DependentUpon>applications.config</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
|
||||
@@ -10,7 +10,7 @@ NOTES:
|
||||
* Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config
|
||||
* A new version will invalidate both client and server cache and create new persisted files
|
||||
-->
|
||||
<clientDependency version="2" fileDependencyExtensions=".js,.css">
|
||||
<clientDependency version="5" fileDependencyExtensions=".js,.css">
|
||||
|
||||
<fileRegistration defaultProvider="LoaderControlProvider">
|
||||
<providers>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Web.UI.Umbraco.Developer.Python
|
||||
{
|
||||
public partial class EditPython : global::umbraco.cms.presentation.developer.editPython
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Umbraco.Web.UI.Umbraco.Developer.Python {
|
||||
|
||||
|
||||
public partial class EditPython {
|
||||
|
||||
/// <summary>
|
||||
/// JsInclude2 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::ClientDependency.Core.Controls.JsInclude JsInclude2;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,35 @@
|
||||
<%@ Page ValidateRequest="false" Language="c#" MasterPageFile="../../masterpages/umbracoPage.Master"
|
||||
CodeBehind="editPython.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.developer.editPython" %>
|
||||
CodeBehind="editPython.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Developer.Python.EditPython" %>
|
||||
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
|
||||
<asp:Content ID="DocTypeContent" ContentPlaceHolderID="DocType" runat="server">
|
||||
<!DOCTYPE html>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="cp0" runat="server" ContentPlaceHolderID="head">
|
||||
|
||||
<umb:JsInclude ID="JsInclude2" runat="server" FilePath="Editors/EditMacroScripts.js" PathNameAlias="UmbracoClient" />
|
||||
|
||||
<script type="text/javascript">
|
||||
function closeErrorDiv() {
|
||||
jQuery('#errorDiv').hide();
|
||||
}
|
||||
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
var editor = new Umbraco.Editors.EditMacroScripts({
|
||||
nameTxtBox: $('#<%= pythonFileName.ClientID %>'),
|
||||
originalFileName: '<%= pythonFileName.Text %>',
|
||||
saveButton: $("#<%= ((Control)SaveButton).ClientID %>"),
|
||||
editorSourceElement: $('#<%= pythonFileName.ClientID %>'),
|
||||
skipTestingCheckBox: $("#<%= SkipTesting.ClientID %>"),
|
||||
});
|
||||
editor.init();
|
||||
|
||||
function doSubmit() {
|
||||
closeErrorDiv();
|
||||
|
||||
var codeVal = jQuery('#<%= pythonSource.ClientID %>').val();
|
||||
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
|
||||
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveDLRScript(jQuery('#<%= pythonFileName.ClientID %>').val(), '<%= pythonFileName.Text %>', codeVal, document.getElementById('<%= SkipTesting.ClientID %>').checked, submitSucces, submitFailure);
|
||||
}
|
||||
|
||||
function submitSucces(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', 'Saving scripting file failed', '');
|
||||
jQuery('#errorDiv').html('<p><a href="#" style="position: absolute; right: 10px; top: 10px;" onclick=\'closeErrorDiv()\'>Hide Errors</a><strong>Error occured</strong></p><p>' + t + '</p>');
|
||||
jQuery('#errorDiv').slideDown('fast');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', 'Scripting file saved', '')
|
||||
}
|
||||
}
|
||||
|
||||
function submitFailure(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('warning', 'Scripting file could not be saved', '')
|
||||
}
|
||||
|
||||
|
||||
function showError() {
|
||||
var id = "#errorDiv";
|
||||
if (jQuery(id).is(":visible")) {
|
||||
jQuery(id).hide();
|
||||
}
|
||||
}
|
||||
//bind save shortcut
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="cp1" runat="server" ContentPlaceHolderID="body">
|
||||
@@ -69,9 +50,4 @@
|
||||
OffSetY="55" runat="server" />
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
@@ -9,54 +9,30 @@
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server" ID="cp2">
|
||||
<style type="text/css">
|
||||
#errorDiv
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
#errorDiv a
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
.propertyItemheader
|
||||
{
|
||||
width: 200px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<umb:JsInclude ID="JsInclude2" runat="server" FilePath="Editors/EditXslt.js" PathNameAlias="UmbracoClient" />
|
||||
<umb:CssInclude ID="CssInclude1" runat="server" FilePath="Editors/EditXslt.css" PathNameAlias="UmbracoClient" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var xsltSnippet = "";
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
var editor = new Umbraco.Editors.EditXslt({
|
||||
nameTxtBox: $('#<%= xsltFileName.ClientID %>'),
|
||||
originalFileName: '<%= xsltFileName.Text %>',
|
||||
saveButton: $("#<%= ((Control)SaveButton).ClientID %>"),
|
||||
editorSourceElement: $('#<%= editorSource.ClientID %>'),
|
||||
skipTestingCheckBox: $("#<%= SkipTesting.ClientID %>"),
|
||||
});
|
||||
editor.init();
|
||||
|
||||
function closeErrorDiv() {
|
||||
jQuery('#errorDiv').hide();
|
||||
}
|
||||
|
||||
function doSubmit() {
|
||||
closeErrorDiv();
|
||||
|
||||
var codeVal = jQuery('#<%= editorSource.ClientID %>').val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveXslt(jQuery('#<%= xsltFileName.ClientID %>').val(), '<%= xsltFileName.Text %>', codeVal, document.getElementById('<%= SkipTesting.ClientID %>').checked, submitSucces, submitFailure);
|
||||
}
|
||||
|
||||
function submitSucces(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', 'Saving Xslt file failed', '');
|
||||
jQuery('#errorDiv').html('<p><a href="#" onclick=\'closeErrorDiv()\'>Hide Errors</a><strong>Error occured</strong></p><p>' + t + '</p>');
|
||||
jQuery('#errorDiv').slideDown('fast');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', 'Xslt file saved', '')
|
||||
}
|
||||
}
|
||||
function submitFailure(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('warning', 'Xslt file could not be saved', '')
|
||||
}
|
||||
//bind save shortcut
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
//TODO: Move these to EditXslt.js one day
|
||||
var xsltSnippet = "";
|
||||
function xsltVisualize() {
|
||||
|
||||
xsltSnippet = UmbEditor.IsSimpleEditor
|
||||
@@ -71,7 +47,6 @@
|
||||
}
|
||||
|
||||
UmbClientMgr.openModalWindow('<%= umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) %>/developer/xslt/xsltVisualize.aspx', 'Visualize XSLT', true, 550, 650);
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -92,15 +67,9 @@
|
||||
<div id="errorDiv" style="display: none;" class="error">
|
||||
test</div>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:CodeArea ID="editorSource" CodeBase="XML" ClientSaveMethod="doSubmit" runat="server"
|
||||
AutoResize="true" OffSetX="47" OffSetY="55" />
|
||||
<cc1:CodeArea ID="editorSource" CodeBase="XML" runat="server" AutoResize="true" OffSetX="47" OffSetY="55" />
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ContentPlaceHolderID="footer" runat="server">
|
||||
<asp:Literal ID="editorJs" runat="server"></asp:Literal>
|
||||
|
||||
@@ -34,7 +34,7 @@ UmbracoSpeechBubble.prototype.ShowMessage = function (icon, header, message, don
|
||||
if (!dontAutoHide) {
|
||||
jQuery("#" + this.id).fadeIn("slow").animate({ opacity: 1.0 }, 5000).fadeOut("fast");
|
||||
} else {
|
||||
speechBubble.jQuery(".speechClose").show();
|
||||
jQuery(".speechClose").show();
|
||||
jQuery("#" + this.id).fadeIn("slow");
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<body>
|
||||
<form id="Form1" method="post" runat="server">
|
||||
<cc1:UmbracoPanel Style="text-align: left;" ID="Panel1" runat="server" Height="347px"
|
||||
Width="340px" Text="Umbraco 4 login" AutoResize="false">
|
||||
Width="340px" Text="Umbraco login" AutoResize="false">
|
||||
<div style="padding: 70px 0px 0px 0px;">
|
||||
<p style="margin: 0px; padding: 5px 0px 20px 0px; color: #999">
|
||||
<asp:Literal ID="TopText" runat="server"></asp:Literal>
|
||||
|
||||
@@ -11,5 +11,14 @@ namespace Umbraco.Web.UI.Umbraco.Settings {
|
||||
|
||||
|
||||
public partial class EditTemplate {
|
||||
|
||||
/// <summary>
|
||||
/// JsInclude1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::ClientDependency.Core.Controls.JsInclude JsInclude1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,162 +11,91 @@
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
|
||||
<umb:CssInclude ID="CssInclude1" runat="server" FilePath="splitbutton/splitbutton.css" PathNameAlias="UmbracoClient" />
|
||||
<umb:JsInclude ID="JsInclude" runat="server" FilePath="splitbutton/jquery.splitbutton.js" PathNameAlias="UmbracoClient" />
|
||||
|
||||
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="Editors/EditTemplate.js" PathNameAlias="UmbracoClient" />
|
||||
<script type="text/javascript">
|
||||
//this needs to be a global object for the doSubmit() to work
|
||||
var editor;
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
//macro split button
|
||||
jQuery('#sbMacro').splitbutton({menu:'#macroMenu'});
|
||||
jQuery("#splitButtonMacro").appendTo("#splitButtonMacroPlaceHolder");
|
||||
|
||||
////razor macro split button
|
||||
jQuery('#sb').splitbutton({menu:'#codeTemplateMenu'});
|
||||
jQuery("#splitButton").appendTo("#splitButtonPlaceHolder");
|
||||
|
||||
jQuery(".macro").click(function(){
|
||||
var alias = jQuery(this).attr("rel");
|
||||
if(jQuery(this).attr("params") == "1")
|
||||
{
|
||||
openMacroModal(alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
insertMacro(alias);
|
||||
//create the editor
|
||||
editor = new Umbraco.Editors.EditTemplate({
|
||||
umbracoPath: '<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>',
|
||||
editorClientId: '<%= editorSource.ClientID %>',
|
||||
useMasterPages: <%=umbraco.UmbracoSettings.UseAspNetMasterPages.ToString().ToLower()%>,
|
||||
templateId: <%= Request.QueryString["templateID"] %>,
|
||||
masterTemplateId: jQuery('#<%= MasterTemplate.ClientID %>').val(),
|
||||
treeSyncPath: '<%=TemplateTreeSyncPath%>',
|
||||
text: {
|
||||
templateErrorHeader: "<%= umbraco.ui.Text("speechBubbles", "templateErrorHeader") %>",
|
||||
templateSavedHeader: "<%= umbraco.ui.Text("speechBubbles", "templateSavedHeader") %>",
|
||||
templateErrorText: "<%= umbraco.ui.Text("speechBubbles", "templateErrorText") %>",
|
||||
templateSavedText: "<%= umbraco.ui.Text("speechBubbles", "templateSavedText") %>"
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(".codeTemplate").click(function(){
|
||||
insertCodeBlockFromTemplate(jQuery(this).attr("rel"));
|
||||
});
|
||||
|
||||
editor.init();
|
||||
});
|
||||
|
||||
|
||||
function doSubmit() {
|
||||
var codeVal = UmbEditor.GetCode();
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveTemplate(jQuery('#<%= NameTxt.ClientID %>').val(), jQuery('#<%= AliasTxt.ClientID %>').val(), codeVal, '<%= Request.QueryString["templateID"] %>', jQuery('#<%= MasterTemplate.ClientID %>').val(), submitSucces, submitFailure);
|
||||
}
|
||||
|
||||
function submitSucces(t)
|
||||
{
|
||||
if(t != 'true')
|
||||
{
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "templateErrorHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "templateErrorText") %>');
|
||||
}
|
||||
else
|
||||
{
|
||||
top.UmbSpeechBubble.ShowMessage('save', '<%= umbraco.ui.Text("speechBubbles", "templateSavedHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "templateSavedText") %>')
|
||||
}
|
||||
}
|
||||
function submitFailure(t)
|
||||
{
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "templateErrorHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "templateErrorText") %>')
|
||||
//this is called when the save button is clicked or invoked
|
||||
editor.save(jQuery('#<%= NameTxt.ClientID %>').val(), jQuery('#<%= AliasTxt.ClientID %>').val(), UmbEditor.GetCode());
|
||||
}
|
||||
|
||||
//TODO: the below should be refactored into being part of the EditTemplate.js class but have left it here for now since i don't have time.
|
||||
|
||||
function umbracoTemplateInsertMasterPageContentContainer() {
|
||||
var master = document.getElementById('<%= MasterTemplate.ClientID %>')[document.getElementById('<%= MasterTemplate.ClientID %>').selectedIndex].value;
|
||||
if (master == "") master = 0;
|
||||
umbraco.presentation.webservices.legacyAjaxCalls.TemplateMasterPageContentContainer(<%=Request["templateID"] %>, master, umbracoTemplateInsertMasterPageContentContainerDo);
|
||||
}
|
||||
|
||||
function umbracoTemplateInsertMasterPageContentContainerDo(result) {
|
||||
UmbEditor.Insert(result + '\n', '\n</asp\:Content>\n', '<%= editorSource.ClientID%>');
|
||||
}
|
||||
|
||||
function changeMasterPageFile(){
|
||||
|
||||
function umbracoTemplateInsertMasterPageContentContainerDo(result) {
|
||||
UmbEditor.Insert(result + '\n', '\n</asp\:Content>\n', '<%= editorSource.ClientID%>');
|
||||
}
|
||||
|
||||
function changeMasterPageFile() {
|
||||
var editor = document.getElementById("<%= editorSource.ClientID %>");
|
||||
var templateDropDown = document.getElementById("<%= MasterTemplate.ClientID %>");
|
||||
|
||||
|
||||
var templateCode = UmbEditor.GetCode();
|
||||
var selectedTemplate = templateDropDown.options[templateDropDown.selectedIndex].id;
|
||||
var masterTemplate = "<%= umbraco.IO.SystemDirectories.Masterpages%>/" + selectedTemplate + ".master";
|
||||
|
||||
if(selectedTemplate == "")
|
||||
masterTemplate = "<%= umbraco.IO.SystemDirectories.Umbraco%>/masterpages/default.master";
|
||||
|
||||
var regex = /MasterPageFile=[~a-z0-9/._"-]+/im;
|
||||
|
||||
if (templateCode.match(regex)) {
|
||||
templateCode = templateCode.replace(regex, 'MasterPageFile="' + masterTemplate + '"');
|
||||
|
||||
UmbEditor.SetCode(templateCode);
|
||||
|
||||
} else {
|
||||
//todo, spot if a directive is there, and if not suggest that the user inserts it..
|
||||
alert("Master directive not found...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function insertContentElement(id){
|
||||
|
||||
//nasty hack to avoid asp.net freaking out because of the markup...
|
||||
var cp = 'asp:Content ContentPlaceHolderId="' + id + '"';
|
||||
cp += ' runat="server"';
|
||||
cp += '>\n\t<!-- Insert "' + id + '" markup here -->';
|
||||
|
||||
UmbEditor.Insert('\n<' + cp, '\n</asp:Content' + '>\n', '<%= editorSource.ClientID %>');
|
||||
}
|
||||
|
||||
function insertPlaceHolderElement(id){
|
||||
|
||||
var cp = 'asp:ContentPlaceHolder Id="' + id + '"';
|
||||
cp += ' runat="server"';
|
||||
cp += '>\n\t<!-- Insert default "' + id + '" markup here -->';
|
||||
if (selectedTemplate == "")
|
||||
masterTemplate = "<%= umbraco.IO.SystemDirectories.Umbraco%>/masterpages/default.master";
|
||||
|
||||
UmbEditor.Insert('\n<' + cp, '\n</asp:ContentPlaceHolder' + '>\n', '<%= editorSource.ClientID %>');
|
||||
}
|
||||
|
||||
function insertCodeBlock()
|
||||
{
|
||||
var snip = umbracoInsertSnippet();
|
||||
UmbEditor.Insert(snip.BeginTag, snip.EndTag, '<%= editorSource.ClientID %>');
|
||||
}
|
||||
var regex = /MasterPageFile=[~a-z0-9/._"-]+/im;
|
||||
|
||||
function umbracoInsertSnippet() {
|
||||
var snip = new UmbracoCodeSnippet();
|
||||
var cp = 'umbraco:Macro runat="server" language="cshtml"';
|
||||
snip.BeginTag = '\n<' + cp + '>\n';
|
||||
snip.EndTag = '\n<' + '/umbraco:Macro' + '>\n';
|
||||
snip.TargetId = "<%= editorSource.ClientID %>";
|
||||
return snip;
|
||||
}
|
||||
if (templateCode.match(regex)) {
|
||||
templateCode = templateCode.replace(regex, 'MasterPageFile="' + masterTemplate + '"');
|
||||
|
||||
function insertCodeBlockFromTemplate(templateId)
|
||||
{
|
||||
|
||||
jQuery.ajax({
|
||||
type: "POST",
|
||||
url: "../webservices/templates.asmx/GetCodeSnippet",
|
||||
data: "{templateId: '" + templateId + "'}",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function(msg) {
|
||||
|
||||
var cp = 'umbraco:Macro runat="server" language="cshtml"';
|
||||
UmbEditor.Insert('\n<' + cp +'>\n' + msg.d,'\n</umbraco:Macro' + '>\n', '<%= editorSource.ClientID %>');
|
||||
UmbEditor.SetCode(templateCode);
|
||||
|
||||
}
|
||||
});
|
||||
else {
|
||||
//todo, spot if a directive is there, and if not suggest that the user inserts it..
|
||||
alert("Master directive not found...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
function insertContentElement(id) {
|
||||
|
||||
function insertMacro(alias)
|
||||
{
|
||||
<%if (umbraco.UmbracoSettings.UseAspNetMasterPages) { %>
|
||||
var macroElement = "umbraco:Macro";
|
||||
<%}else{ %>
|
||||
var macroElement = "?UMBRACO_MACRO";
|
||||
<%}%>
|
||||
//nasty hack to avoid asp.net freaking out because of the markup...
|
||||
var cp = 'asp:Content ContentPlaceHolderId="' + id + '"';
|
||||
cp += ' runat="server"';
|
||||
cp += '>\n\t<!-- Insert "' + id + '" markup here -->';
|
||||
|
||||
var cp = macroElement + ' Alias="'+ alias +'" runat="server"';
|
||||
UmbEditor.Insert('<' + cp +' />','', '<%= editorSource.ClientID %>');
|
||||
}
|
||||
function openMacroModal(alias)
|
||||
{
|
||||
var t = "";
|
||||
if(alias != null && alias != ""){
|
||||
t = "&alias="+alias;
|
||||
}
|
||||
UmbClientMgr.openModalWindow('<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>/dialogs/editMacro.aspx?renderingEngine=Webforms&objectId=<%= editorSource.ClientID %>' + t, 'Insert Macro', true, 470, 530, 0, 0, '', '');
|
||||
UmbEditor.Insert('\n<' + cp, '\n</asp:Content' + '>\n', '<%= editorSource.ClientID %>');
|
||||
}
|
||||
|
||||
function insertPlaceHolderElement(id) {
|
||||
|
||||
var cp = 'asp:ContentPlaceHolder Id="' + id + '"';
|
||||
cp += ' runat="server"';
|
||||
cp += '>\n\t<!-- Insert default "' + id + '" markup here -->';
|
||||
|
||||
UmbEditor.Insert('\n<' + cp, '\n</asp:ContentPlaceHolder' + '>\n', '<%= editorSource.ClientID %>');
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -190,7 +119,7 @@ function insertMacro(alias)
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<div id="splitButton" style="display: inline; height: 23px; vertical-align: top;">
|
||||
<a href="javascript:insertCodeBlock();" id="sb" class="sbLink">
|
||||
<a href="#" id="sb" class="sbLink">
|
||||
<img alt="Insert Inline Razor Macro" src="../images/editor/insRazorMacro.png" title="Insert Inline Razor Macro"
|
||||
style="vertical-align: top;">
|
||||
</a>
|
||||
@@ -205,7 +134,7 @@ function insertMacro(alias)
|
||||
</asp:Repeater>
|
||||
</div>
|
||||
<div id="splitButtonMacro" style="display: inline; height: 23px; vertical-align: top;">
|
||||
<a href="javascript:openMacroModal();" id="sbMacro" class="sbLink">
|
||||
<a href="#" id="sbMacro" class="sbLink">
|
||||
<img alt="Insert Macro" src="../images/editor/insMacroSB.png" title="Insert Macro"
|
||||
style="vertical-align: top;">
|
||||
</a>
|
||||
|
||||
@@ -3,34 +3,39 @@
|
||||
ValidateRequest="False" %>
|
||||
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
|
||||
<asp:Content ID="DocTypeContent" ContentPlaceHolderID="DocType" runat="server">
|
||||
<!DOCTYPE html>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server">
|
||||
|
||||
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="Editors/EditScript.js" PathNameAlias="UmbracoClient" />
|
||||
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
function doSubmit() {
|
||||
var codeVal = jQuery('#<%= editorSource.ClientID %>').val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveScript(jQuery('#<%= NameTxt.ClientID %>').val(), '<%= NameTxt.Text %>', codeVal, submitSucces, submitFailure);
|
||||
}
|
||||
|
||||
function submitSucces(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "fileErrorHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "fileErrorText") %>');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', '<%= umbraco.ui.Text("speechBubbles", "fileSavedHeader") %>', '')
|
||||
}
|
||||
}
|
||||
function submitFailure(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "fileErrorHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "fileErrorText") %>')
|
||||
}
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
var editor = new Umbraco.Editors.EditScript({
|
||||
nameTxtBox: $('#<%= NameTxt.ClientID %>'),
|
||||
originalFileName: '<%= NameTxt.Text %>',
|
||||
saveButton: $("#<%= ((Control)SaveButton).ClientID %>"),
|
||||
editorSourceElement: $('#<%= editorSource.ClientID %>'),
|
||||
text: {
|
||||
fileErrorHeader: '<%= umbraco.ui.Text("speechBubbles", "fileErrorHeader") %>',
|
||||
fileSavedHeader: '<%= umbraco.ui.Text("speechBubbles", "fileSavedHeader") %>',
|
||||
fileSavedText: '',
|
||||
fileErrorText: '<%= umbraco.ui.Text("speechBubbles", "fileErrorText") %>',
|
||||
}
|
||||
});
|
||||
editor.init();
|
||||
|
||||
//bind save shortcut
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
@@ -48,9 +53,5 @@
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
|
||||
</asp:Content>
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
<%@ Page Language="c#" MasterPageFile="../../masterpages/umbracoPage.Master" Codebehind="editstylesheet.aspx.cs" AutoEventWireup="True"
|
||||
Inherits="umbraco.cms.presentation.settings.stylesheet.editstylesheet" ValidateRequest="False" %>
|
||||
<%@ Page Language="c#" MasterPageFile="../../masterpages/umbracoPage.Master" CodeBehind="editstylesheet.aspx.cs" AutoEventWireup="True"
|
||||
Inherits="Umbraco.Web.UI.Umbraco.Settings.Stylesheet.EditStyleSheet" ValidateRequest="False" %>
|
||||
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
<%@ Register TagPrefix="cdf" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server">
|
||||
<script type="text/javascript">
|
||||
|
||||
function doSubmit() {
|
||||
var codeVal = jQuery('#<%= editorSource.ClientID %>').val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof(CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveCss(jQuery('#<%= NameTxt.ClientID %>').val(), '<%= NameTxt.Text %>', codeVal, '<%= Request.QueryString["id"] %>', submitSucces, submitFailure);
|
||||
}
|
||||
<cdf:JsInclude runat="server" FilePath="Editors/EditStyleSheet.js" PathNameAlias="UmbracoClient"></cdf:JsInclude>
|
||||
|
||||
function submitSucces(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "CssErrorHeader") %>', 'Please make sure that you have permissions set correctly');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', '<%= umbraco.ui.Text("speechBubbles", "cssSavedHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "cssSavedText") %>')
|
||||
}
|
||||
}
|
||||
function submitFailure(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "CssErrorHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "CssErrorText") %>')
|
||||
}
|
||||
<script type="text/javascript">
|
||||
|
||||
</script>
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
var editor = new Umbraco.Editors.EditStyleSheet({
|
||||
nameTxtBox: $('#<%= NameTxt.ClientID %>'),
|
||||
originalFileName: '<%= NameTxt.Text %>',
|
||||
cssId: '<%= Request.QueryString["id"] %>',
|
||||
saveButton: $("#<%= ((Control)SaveButton).ClientID %>"),
|
||||
editorSourceElement: $('#<%= editorSource.ClientID %>'),
|
||||
text: {
|
||||
cssErrorHeader: '<%= umbraco.ui.Text("speechBubbles", "cssErrorHeader") %>',
|
||||
cssSavedHeader: '<%= umbraco.ui.Text("speechBubbles", "cssSavedHeader") %>',
|
||||
cssSavedText: '<%= umbraco.ui.Text("speechBubbles", "cssSavedText") %>',
|
||||
cssErrorText: 'Please make sure that you have permissions set correctly',
|
||||
}
|
||||
});
|
||||
editor.init();
|
||||
});
|
||||
|
||||
//bind save shortcut
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
<cc1:UmbracoPanel ID="Panel1" runat="server" CssClass="panel" hasMenu="true">
|
||||
<cc1:Pane ID="Pane7" CssClass="pane" runat="server">
|
||||
<cc1:PropertyPanel ID="pp_name" runat="server">
|
||||
<asp:TextBox ID="NameTxt" Width="350px" runat="server"></asp:TextBox>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_path" runat="server">
|
||||
<asp:Literal ID="lttPath" runat="server"></asp:Literal>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel id="pp_source" runat="server">
|
||||
<cc1:CodeArea id="editorSource" CodeBase="Css" ClientSaveMethod="doSubmit" OffSetX="37" OffSetY="54" AutoResize="true" runat="server" />
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
<cc1:Pane ID="Pane7" CssClass="pane" runat="server">
|
||||
<cc1:PropertyPanel ID="pp_name" runat="server">
|
||||
<asp:TextBox ID="NameTxt" Width="350px" runat="server"></asp:TextBox>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_path" runat="server">
|
||||
<asp:Literal ID="lttPath" runat="server"></asp:Literal>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_source" runat="server">
|
||||
<cc1:CodeArea ID="editorSource" CodeBase="Css" OffSetX="37" OffSetY="54" AutoResize="true" runat="server" />
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
|
||||
</asp:Content>
|
||||
</asp:Content>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Web.UI.Umbraco.Settings.Stylesheet
|
||||
{
|
||||
public partial class EditStyleSheet : global::umbraco.cms.presentation.settings.stylesheet.editstylesheet
|
||||
{
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Umbraco.Web.UI.Umbraco.Settings.Stylesheet {
|
||||
|
||||
|
||||
public partial class EditStyleSheet {
|
||||
}
|
||||
}
|
||||
+15
-13
@@ -1,34 +1,34 @@
|
||||
<%@ Page Language="c#" MasterPageFile="../../../masterpages/umbracoPage.Master" CodeBehind="EditStyleSheetProperty.aspx.cs"
|
||||
AutoEventWireup="True" Inherits="umbraco.cms.presentation.settings.stylesheet.EditStyleSheetProperty"
|
||||
AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Settings.Stylesheet.Property.EditStyleSheetProperty"
|
||||
ValidateRequest="False" %>
|
||||
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
<cc1:UmbracoPanel ID="Panel1" runat="server" Text="Edit stylesheet property" Width="432px"
|
||||
Height="176px" hasMenu="true">
|
||||
<cc1:UmbracoPanel ID="Panel1" runat="server" Text="Edit stylesheet property" Width="432px" Height="176px" hasMenu="true">
|
||||
<cc1:Pane ID="Pane7" CssClass="pane" runat="server">
|
||||
<table cellspacing="0" cellpadding="4" border="0">
|
||||
<tr>
|
||||
<th width="30%">
|
||||
<%=umbraco.ui.Text("name", base.getUser())%>:
|
||||
<%=umbraco.ui.Text("name", UmbracoUser)%>:
|
||||
</th>
|
||||
<td class="propertyContent">
|
||||
<asp:TextBox ID="NameTxt" Width="350px" runat="server" /><br />
|
||||
<small><%=umbraco.ui.Text("stylesheet", "nameHelp", base.getUser())%></small>
|
||||
<small><%=umbraco.ui.Text("stylesheet", "nameHelp", UmbracoUser)%></small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="30%">
|
||||
<%=umbraco.ui.Text("alias", base.getUser())%>:
|
||||
<%=umbraco.ui.Text("alias", UmbracoUser)%>:
|
||||
</th>
|
||||
<td class="propertyContent">
|
||||
<asp:TextBox ID="AliasTxt" Width="350px" runat="server" /><br />
|
||||
<small><%=umbraco.ui.Text("stylesheet", "aliasHelp", base.getUser())%></small>
|
||||
<small><%=umbraco.ui.Text("stylesheet", "aliasHelp", UmbracoUser)%></small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="30%">
|
||||
<%=umbraco.ui.Text("styles", base.getUser())%>:
|
||||
<%=umbraco.ui.Text("styles", UmbracoUser)%>:
|
||||
</th>
|
||||
<td class="propertyContent">
|
||||
<asp:TextBox ID="Content" Style="width: 350px" TextMode="MultiLine" runat="server" />
|
||||
@@ -38,7 +38,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="30%">
|
||||
<%=umbraco.ui.Text("preview", base.getUser())%>:
|
||||
<%=umbraco.ui.Text("preview", UmbracoUser)%>:
|
||||
</th>
|
||||
<td class="propertyContent">
|
||||
<div id="preview" style="padding: 10px; border: 1px solid #ccc; width: 330px;">
|
||||
@@ -57,9 +57,11 @@
|
||||
</table>
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
|
||||
</asp:Content>
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Web.UI.Umbraco.Settings.Stylesheet.Property
|
||||
{
|
||||
public partial class EditStyleSheetProperty : global::umbraco.cms.presentation.settings.stylesheet.EditStyleSheetProperty
|
||||
{
|
||||
}
|
||||
}
|
||||
Generated
+15
@@ -0,0 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Umbraco.Web.UI.Umbraco.Settings.Stylesheet.Property {
|
||||
|
||||
|
||||
public partial class EditStyleSheetProperty {
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
$(document).ready(function () {
|
||||
//create and assign a new EditView object
|
||||
editViewEditor = new Umbraco.Editors.EditView({
|
||||
treeSyncPath: "<%=TemplateTreeSyncPath%>",
|
||||
currentTreeType: "<%=CurrentTreeType%>",
|
||||
editorType: "<%= EditorType.ToString() %>",
|
||||
originalFileName: "<%=OriginalFileName %>",
|
||||
restServiceLocation: "<%= Url.GetSaveFileServicePath() %>",
|
||||
|
||||
@@ -45,6 +45,23 @@ namespace Umbraco.Web.UI.Umbraco.Settings.Views
|
||||
get { return _template == null ? ViewEditorType.PartialView : ViewEditorType.Template; }
|
||||
}
|
||||
|
||||
protected string TemplateTreeSyncPath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// This view is shared between different trees so we'll look for the query string
|
||||
/// </summary>
|
||||
protected string CurrentTreeType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Request.QueryString["treeType"].IsNullOrWhiteSpace())
|
||||
{
|
||||
return TreeDefinitionCollection.Instance.FindTree<PartialViewsTree>().Tree.Alias;
|
||||
}
|
||||
return Request.QueryString["treeType"];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the original file name that the editor was loaded with
|
||||
/// </summary>
|
||||
@@ -89,9 +106,6 @@ namespace Umbraco.Web.UI.Umbraco.Settings.Views
|
||||
AliasTxt.Text = _template.Alias;
|
||||
editorSource.Text = _template.Design;
|
||||
|
||||
ClientTools
|
||||
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<PartialViewsTree>().Tree.Alias)
|
||||
.SyncTree("-1,init," + _template.Path.Replace("-1,", ""), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -105,13 +119,13 @@ namespace Umbraco.Web.UI.Umbraco.Settings.Views
|
||||
var s = sr.ReadToEnd();
|
||||
editorSource.Text = s;
|
||||
}
|
||||
|
||||
//string path = DeepLink.GetTreePathFromFilePath(file);
|
||||
//ClientTools
|
||||
// .SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadPython>().Tree.Alias)
|
||||
// .SyncTree(path, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ClientTools
|
||||
.SetActiveTreeType(CurrentTreeType)
|
||||
.SyncTree(TemplateTreeSyncPath, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -122,12 +136,14 @@ namespace Umbraco.Web.UI.Umbraco.Settings.Views
|
||||
//check if a templateId is assigned, meaning we are editing a template
|
||||
if (!Request.QueryString["templateID"].IsNullOrWhiteSpace())
|
||||
{
|
||||
_template = new Template(int.Parse(Request.QueryString["templateID"]));
|
||||
_template = new Template(int.Parse(Request.QueryString["templateID"]));
|
||||
TemplateTreeSyncPath = "-1,init," + _template.Path.Replace("-1,", "");
|
||||
}
|
||||
else if (!Request.QueryString["file"].IsNullOrWhiteSpace())
|
||||
{
|
||||
//we are editing a view (i.e. partial view)
|
||||
OriginalFileName = HttpUtility.UrlDecode(Request.QueryString["file"]);
|
||||
TemplateTreeSyncPath = "-1,init," + Path.GetFileName(OriginalFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="DocumentService.asmx.cs" Class="umbraco.webservices.documents.documentService" %>
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="FileService.asmx.cs" Class="umbraco.webservices.files.fileService" %>
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="MaintanceService.asmx.cs" Class="umbraco.webservices.maintenance.maintenanceService" %>
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="MediaService.asmx.cs" Class="umbraco.webservices.media.mediaService" %>
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="MemberService.asmx.cs" Class="umbraco.webservices.members.memberService" %>
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="StylesheetService.asmx.cs" Class="umbraco.webservices.stylesheets.stylesheetService" %>
|
||||
@@ -1 +0,0 @@
|
||||
<%@ WebService Language="C#" CodeBehind="TemplateService.asmx.cs" Class="umbraco.webservices.templates.templateService" %>
|
||||
@@ -0,0 +1,70 @@
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Editors");
|
||||
|
||||
(function ($) {
|
||||
|
||||
Umbraco.Editors.EditMacroScripts = base2.Base.extend({
|
||||
//private methods/variables
|
||||
_opts: null,
|
||||
|
||||
// Constructor
|
||||
constructor: function(opts) {
|
||||
// Merge options with default
|
||||
this._opts = $.extend({
|
||||
|
||||
|
||||
// Default options go here
|
||||
}, opts);
|
||||
},
|
||||
|
||||
init: function () {
|
||||
//setup UI elements
|
||||
var self = this;
|
||||
|
||||
//bind to the save event
|
||||
this._opts.saveButton.click(function () {
|
||||
self.doSubmit();
|
||||
});
|
||||
},
|
||||
|
||||
doSubmit: function () {
|
||||
var self = this;
|
||||
|
||||
jQuery('#errorDiv').hide();
|
||||
|
||||
var fileName = this._opts.nameTxtBox.val();
|
||||
var codeVal = this._opts.editorSourceElement.val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveDLRScript(
|
||||
fileName, self._opts.originalFileName, codeVal, self._opts.skipTestingCheckBox.is(':checked'),
|
||||
function (t) { self.submitSucces(t); },
|
||||
function (t) { self.submitFailure(t); });
|
||||
|
||||
},
|
||||
|
||||
submitSucces: function(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', 'Saving scripting file failed', '');
|
||||
jQuery('#errorDiv').html('<p><a href="#" style="position: absolute; right: 10px; top: 10px;" onclick=\'closeErrorDiv()\'>Hide Errors</a><strong>Error occured</strong></p><p>' + t + '</p>');
|
||||
jQuery('#errorDiv').slideDown('fast');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', 'Scripting file saved', '');
|
||||
}
|
||||
|
||||
|
||||
var newFilePath = this._opts.nameTxtBox.val();
|
||||
UmbClientMgr.mainTree().setActiveTreeType('python');
|
||||
//we need to pass in the newId parameter so it knows which node to resync after retreival from the server
|
||||
UmbClientMgr.mainTree().syncTree("-1,init," + this._opts.originalFileName, true, null, newFilePath);
|
||||
//set the original file path to the new one
|
||||
this._opts.originalFileName = newFilePath;
|
||||
},
|
||||
|
||||
submitFailure: function(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('warning', 'Scripting file could not be saved', '');
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,66 @@
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Editors");
|
||||
|
||||
(function ($) {
|
||||
|
||||
Umbraco.Editors.EditScript = base2.Base.extend({
|
||||
//private methods/variables
|
||||
_opts: null,
|
||||
|
||||
// Constructor
|
||||
constructor: function(opts) {
|
||||
// Merge options with default
|
||||
this._opts = $.extend({
|
||||
|
||||
|
||||
// Default options go here
|
||||
}, opts);
|
||||
},
|
||||
|
||||
init: function () {
|
||||
//setup UI elements
|
||||
var self = this;
|
||||
|
||||
//bind to the save event
|
||||
this._opts.saveButton.click(function () {
|
||||
self.doSubmit();
|
||||
});
|
||||
},
|
||||
|
||||
doSubmit: function () {
|
||||
var self = this;
|
||||
|
||||
var fileName = this._opts.nameTxtBox.val();
|
||||
var codeVal = this._opts.editorSourceElement.val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveScript(
|
||||
fileName, self._opts.originalFileName, codeVal,
|
||||
function (t) { self.submitSucces(t); },
|
||||
function (t) { self.submitFailure(t); });
|
||||
|
||||
},
|
||||
|
||||
submitSucces: function(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.fileErrorHeader, this._opts.text.fileErrorText);
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', this._opts.text.fileSavedHeader, this._opts.text.fileSavedText);
|
||||
}
|
||||
|
||||
|
||||
var newFilePath = this._opts.nameTxtBox.val();
|
||||
UmbClientMgr.mainTree().setActiveTreeType('scripts');
|
||||
//we need to pass in the newId parameter so it knows which node to resync after retreival from the server
|
||||
UmbClientMgr.mainTree().syncTree("-1,init," + this._opts.originalFileName, true, null, newFilePath);
|
||||
//set the original file path to the new one
|
||||
this._opts.originalFileName = newFilePath;
|
||||
},
|
||||
|
||||
submitFailure: function(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.fileErrorHeader, this._opts.text.fileErrorText);
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,64 @@
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Editors");
|
||||
|
||||
(function ($) {
|
||||
|
||||
Umbraco.Editors.EditStyleSheet = base2.Base.extend({
|
||||
//private methods/variables
|
||||
_opts: null,
|
||||
|
||||
// Constructor
|
||||
constructor: function(opts) {
|
||||
// Merge options with default
|
||||
this._opts = $.extend({
|
||||
|
||||
|
||||
// Default options go here
|
||||
}, opts);
|
||||
},
|
||||
|
||||
init: function() {
|
||||
//setup UI elements
|
||||
var self = this;
|
||||
|
||||
//bind to the save event
|
||||
this._opts.saveButton.click(function() {
|
||||
self.doSubmit();
|
||||
});
|
||||
},
|
||||
|
||||
doSubmit: function() {
|
||||
var self = this;
|
||||
|
||||
var fileName = this._opts.nameTxtBox.val();
|
||||
var codeVal = this._opts.editorSourceElement.val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof(CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveCss(
|
||||
fileName, self._opts.originalFileName, codeVal, self._opts.cssId,
|
||||
function(t) { self.submitSucces(t); },
|
||||
function(t) { self.submitFailure(t); });
|
||||
|
||||
},
|
||||
|
||||
submitSucces: function(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.cssErrorHeader, this._opts.text.cssErrorText);
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', this._opts.text.cssSavedHeader, this._opts.text.cssSavedText);
|
||||
}
|
||||
|
||||
UmbClientMgr.mainTree().setActiveTreeType('stylesheets');
|
||||
UmbClientMgr.mainTree().syncTree("-1,init," + this._opts.cssId, true);
|
||||
|
||||
//update the originalFileName prop
|
||||
this._opts.originalFileName = this._opts.nameTxtBox.val();
|
||||
},
|
||||
|
||||
submitFailure: function(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.cssErrorHeader, this._opts.text.cssErrorText);
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,127 @@
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Editors");
|
||||
|
||||
(function ($) {
|
||||
|
||||
Umbraco.Editors.EditTemplate = base2.Base.extend({
|
||||
//private methods/variables
|
||||
_opts: null,
|
||||
|
||||
_openMacroModal: function(alias) {
|
||||
var t = "";
|
||||
if (alias != null && alias != "") {
|
||||
t = "&alias=" + alias;
|
||||
}
|
||||
UmbClientMgr.openModalWindow(this._opts.umbracoPath + '/dialogs/editMacro.aspx?renderingEngine=Webforms&objectId=' + this._opts.editorClientId + t, 'Insert Macro', true, 470, 530, 0, 0, '', '');
|
||||
},
|
||||
|
||||
_insertMacro: function(alias) {
|
||||
var macroElement = "umbraco:Macro";
|
||||
if (!this._opts.useMasterPages) {
|
||||
macroElement = "?UMBRACO_MACRO";
|
||||
}
|
||||
var cp = macroElement + ' Alias="' + alias + '" runat="server"';
|
||||
UmbEditor.Insert('<' + cp + ' />', '', this._opts.editorClientId);
|
||||
},
|
||||
|
||||
_insertCodeBlockFromTemplate: function(templateId) {
|
||||
var self = this;
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: this._opts.umbracoPath + "/webservices/templates.asmx/GetCodeSnippet",
|
||||
data: "{templateId: '" + templateId + "'}",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function(msg) {
|
||||
|
||||
var cp = 'umbraco:Macro runat="server" language="cshtml"';
|
||||
UmbEditor.Insert('\n<' + cp + '>\n' + msg.d, '\n</umbraco:Macro' + '>\n', self._opts.editorClientId);
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_insertCodeBlock: function() {
|
||||
var snip = this._umbracoInsertSnippet();
|
||||
UmbEditor.Insert(snip.BeginTag, snip.EndTag, this._opts.editorClientId);
|
||||
},
|
||||
|
||||
_umbracoInsertSnippet: function() {
|
||||
var snip = new UmbracoCodeSnippet();
|
||||
var cp = 'umbraco:Macro runat="server" language="cshtml"';
|
||||
snip.BeginTag = '\n<' + cp + '>\n';
|
||||
snip.EndTag = '\n<' + '/umbraco:Macro' + '>\n';
|
||||
snip.TargetId = this._opts.editorClientId;
|
||||
return snip;
|
||||
},
|
||||
|
||||
// Constructor
|
||||
constructor: function(opts) {
|
||||
// Merge options with default
|
||||
this._opts = $.extend({
|
||||
|
||||
|
||||
// Default options go here
|
||||
}, opts);
|
||||
},
|
||||
|
||||
init: function() {
|
||||
//<summary>Sets up the UI and binds events</summary>
|
||||
|
||||
var self = this;
|
||||
|
||||
$("#sb").click(function() {
|
||||
self._insertCodeBlock();
|
||||
});
|
||||
$("#sbMacro").click(function() {
|
||||
self._openMacroModal();
|
||||
});
|
||||
//macro split button
|
||||
$('#sbMacro').splitbutton({ menu: '#macroMenu' });
|
||||
$("#splitButtonMacro").appendTo("#splitButtonMacroPlaceHolder");
|
||||
|
||||
////razor macro split button
|
||||
$('#sb').splitbutton({ menu: '#codeTemplateMenu' });
|
||||
$("#splitButton").appendTo("#splitButtonPlaceHolder");
|
||||
|
||||
$(".macro").click(function() {
|
||||
var alias = $(this).attr("rel");
|
||||
if ($(this).attr("params") == "1") {
|
||||
self._openMacroModal(alias);
|
||||
}
|
||||
else {
|
||||
self._insertMacro(alias);
|
||||
}
|
||||
});
|
||||
|
||||
$(".codeTemplate").click(function() {
|
||||
self._insertCodeBlockFromTemplate($(this).attr("rel"));
|
||||
});
|
||||
},
|
||||
|
||||
save: function(templateName, templateAlias, codeVal) {
|
||||
var self = this;
|
||||
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveTemplate(
|
||||
templateName, templateAlias, codeVal, self._opts.templateId, self._opts.masterTemplateId,
|
||||
function(t) { self.submitSucces(t); },
|
||||
function(t) { self.submitFailure(t); });
|
||||
|
||||
},
|
||||
|
||||
submitSucces: function(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.templateErrorHeader, this._opts.text.templateErrorText);
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', this._opts.text.templateSavedHeader, this._opts.text.templateSavedText);
|
||||
}
|
||||
|
||||
UmbClientMgr.mainTree().setActiveTreeType('templates');
|
||||
UmbClientMgr.mainTree().syncTree(this._opts.treeSyncPath, true);
|
||||
},
|
||||
|
||||
submitFailure: function(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.templateErrorHeader, this._opts.text.templateErrorText);
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -8,6 +8,21 @@
|
||||
//private methods/variables
|
||||
_opts: null,
|
||||
|
||||
_updateNewProperties: function(filePath) {
|
||||
/// <summary>Updates the current treeSyncPath and original file name to have the new file name</summary>
|
||||
|
||||
//update the originalFileName prop
|
||||
this._opts.originalFileName = filePath;
|
||||
|
||||
//re-create the new path
|
||||
var subPath = this._opts.treeSyncPath.split(",");
|
||||
//remove the last element
|
||||
subPath.pop();
|
||||
//add the new element
|
||||
subPath.push(filePath.split("/")[1]);
|
||||
this._opts.treeSyncPath = subPath.join();
|
||||
},
|
||||
|
||||
// Constructor
|
||||
constructor: function (opts) {
|
||||
// Merge options with default
|
||||
@@ -92,10 +107,26 @@
|
||||
|
||||
submitSuccess: function (err, header) {
|
||||
top.UmbSpeechBubble.ShowMessage('save', header, err);
|
||||
|
||||
UmbClientMgr.mainTree().setActiveTreeType(this._opts.currentTreeType);
|
||||
|
||||
var newFilePath = this._opts.nameTxtBox.val();
|
||||
|
||||
if (this._opts.editorType == "Template") {
|
||||
//templates are different because they are ID based, whereas view files are file based without a static id
|
||||
UmbClientMgr.mainTree().syncTree(this._opts.treeSyncPath, true);
|
||||
}
|
||||
else {
|
||||
//we need to pass in the newId parameter so it knows which node to resync after retreival from the server
|
||||
UmbClientMgr.mainTree().syncTree(this._opts.treeSyncPath, true, null, newFilePath.split("/")[1]);
|
||||
}
|
||||
|
||||
//then we need to update our current tree sync path to represent the new one
|
||||
this._updateNewProperties(newFilePath);
|
||||
},
|
||||
|
||||
submitFailure: function (err, header) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', header, err);
|
||||
top.UmbSpeechBubble.ShowMessage('error', header, err);
|
||||
},
|
||||
|
||||
changeMasterPageFile: function ( ) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#errorDiv
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#errorDiv a
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.propertyItemheader
|
||||
{
|
||||
width: 200px !important;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Editors");
|
||||
|
||||
(function ($) {
|
||||
|
||||
Umbraco.Editors.EditXslt = base2.Base.extend({
|
||||
//private methods/variables
|
||||
_opts: null,
|
||||
|
||||
// Constructor
|
||||
constructor: function(opts) {
|
||||
// Merge options with default
|
||||
this._opts = $.extend({
|
||||
|
||||
|
||||
// Default options go here
|
||||
}, opts);
|
||||
},
|
||||
|
||||
init: function () {
|
||||
//setup UI elements
|
||||
var self = this;
|
||||
|
||||
//bind to the save event
|
||||
this._opts.saveButton.click(function () {
|
||||
self.doSubmit();
|
||||
});
|
||||
},
|
||||
|
||||
doSubmit: function () {
|
||||
var self = this;
|
||||
|
||||
$('#errorDiv').hide();
|
||||
|
||||
var fileName = this._opts.nameTxtBox.val();
|
||||
var codeVal = this._opts.editorSourceElement.val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveXslt(
|
||||
fileName, self._opts.originalFileName, codeVal, self._opts.skipTestingCheckBox.is(':checked'),
|
||||
function (t) { self.submitSucces(t); },
|
||||
function (t) { self.submitFailure(t); });
|
||||
|
||||
},
|
||||
|
||||
submitSucces: function (t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', 'Saving Xslt file failed', '');
|
||||
jQuery('#errorDiv').html('<p><a href="#" onclick=\'closeErrorDiv()\'>Hide Errors</a><strong>Error occured</strong></p><p>' + t + '</p>');
|
||||
jQuery('#errorDiv').slideDown('fast');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', 'Xslt file saved', '');
|
||||
}
|
||||
|
||||
var newFilePath = this._opts.nameTxtBox.val();
|
||||
UmbClientMgr.mainTree().setActiveTreeType('xslt');
|
||||
//we need to pass in the newId parameter so it knows which node to resync after retreival from the server
|
||||
UmbClientMgr.mainTree().syncTree("-1,init," + this._opts.originalFileName, true, null, newFilePath);
|
||||
//set the original file path to the new one
|
||||
this._opts.originalFileName = newFilePath;
|
||||
},
|
||||
|
||||
submitFailure: function(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('warning', 'Xslt file could not be saved', '');
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -173,7 +173,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
var self = this;
|
||||
|
||||
// Inject the upload overlay
|
||||
var instructions = 'draggable' in document.createElement('span') ? "<h1>Drag files here to upload</h1> \<p>Or, click the button below to chose the items to upload</p>" : "<h1>Click the browse button below to chose the items to upload</h1>";
|
||||
var instructions = 'draggable' in document.createElement('span') ? "<h1>Drag files here to upload</h1> \<p>Or, click the button below to choose the items to upload</p>" : "<h1>Click the browse button below to choose the items to upload</h1>";
|
||||
|
||||
var overlay = $("<div class='upload-overlay'>" +
|
||||
"<div class='upload-panel'>" +
|
||||
|
||||
@@ -51,7 +51,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
functionToCall: "",
|
||||
nodeKey: ""
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Umbraco.Controls.UmbracoTree = function() {
|
||||
/// <summary>
|
||||
@@ -100,10 +100,10 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
if (this._opts.appActions != null) {
|
||||
var _this = this;
|
||||
//wrapped functions maintain scope
|
||||
this._opts.appActions.addEventHandler("nodeDeleting", function(E) { _this.onNodeDeleting(E) });
|
||||
this._opts.appActions.addEventHandler("nodeDeleted", function(E) { _this.onNodeDeleted(E) });
|
||||
this._opts.appActions.addEventHandler("nodeRefresh", function(E) { _this.onNodeRefresh(E) });
|
||||
this._opts.appActions.addEventHandler("publicError", function(E, err) { _this.onPublicError(E, err) });
|
||||
this._opts.appActions.addEventHandler("nodeDeleting", function (E) { _this.onNodeDeleting(E); });
|
||||
this._opts.appActions.addEventHandler("nodeDeleted", function (E) { _this.onNodeDeleted(E); });
|
||||
this._opts.appActions.addEventHandler("nodeRefresh", function (E) { _this.onNodeRefresh(E); });
|
||||
this._opts.appActions.addEventHandler("publicError", function (E, err) { _this.onPublicError(E, err); });
|
||||
}
|
||||
|
||||
this._containerId = jItem.attr("id");
|
||||
@@ -309,19 +309,20 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
}
|
||||
},
|
||||
|
||||
syncTree: function(path, forceReload, supressChildReload) {
|
||||
syncTree: function(path, forceReload, supressChildReload, newId) {
|
||||
/// <summary>
|
||||
/// Syncronizes the tree with the path supplied and makes that node visible/selected.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the node</param>
|
||||
/// <param name="forceReload">If true, will ensure that the node to be synced is synced with data from the server</param>
|
||||
/// <param name="newId">This parameter is only used when we don't have a real unique ID for a node, for example for a file. If a filename changes we don't know what the new one is since we are syncing the tree to the old original path. Once we retreive the results the sync the tree we need to find the result by it's new id and update the node.</param>
|
||||
|
||||
this._debug("syncTree: " + path + ", " + forceReload);
|
||||
|
||||
//set the flag so that multiple synces aren't attempted
|
||||
this._isSyncing = true;
|
||||
|
||||
this._syncTree.call(this, path, forceReload, null, null, supressChildReload);
|
||||
this._syncTree.call(this, path, forceReload, null, null, supressChildReload, newId);
|
||||
|
||||
},
|
||||
|
||||
@@ -864,7 +865,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
this._tree.open_branch(liNode, false, callback);
|
||||
},
|
||||
|
||||
_syncTree: function(path, forceReload, numPaths, numAsync, supressChildReload) {
|
||||
_syncTree: function(path, forceReload, numPaths, numAsync, supressChildReload, newId) {
|
||||
/// <summary>
|
||||
/// This is the internal method that will recursively search for the nodes to sync. If an invalid path is
|
||||
/// passed to this method, it will raise an event which can be handled.
|
||||
@@ -873,6 +874,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
/// <param name="forceReload">If true, will ensure that the node to be synced is synced with data from the server</param>
|
||||
/// <param name="numPaths">the number of id's deep to search starting from the end of the path. Used in recursion.</param>
|
||||
/// <param name="numAsync">the number of async calls made so far to sync. Used in recursion and used to determine if the found node has been loaded by ajax.</param>
|
||||
/// <param name="newId">This parameter is only used when we don't have a real unique ID for a node, for example for a file. If a filename changes we don't know what the new one is since we are syncing the tree to the old original path. Once we retreive the results the sync the tree we need to find the result by it's new id and update the node.</param>
|
||||
|
||||
this._debug("_syncTree");
|
||||
|
||||
@@ -917,6 +919,10 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
this._debug("_syncTree: found! numAsync: " + numAsync + ", forceReload: " + forceReload + ", doReload: " + doReload);
|
||||
if (doReload) {
|
||||
this._actionNode = this.getNodeDef(found);
|
||||
//we need to change the id if the newId parameter is set
|
||||
if (newId) {
|
||||
this._actionNode.nodeId = newId;
|
||||
}
|
||||
if (supressChildReload === undefined) {
|
||||
this.reloadActionNode(false, true, null);
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,6 @@ var UmbracoEmbedDialog = {
|
||||
tinyMCEPopup.close();
|
||||
},
|
||||
showPreview: function () {
|
||||
|
||||
$('#insert').attr('disabled', 'disabled');
|
||||
|
||||
var url = $('#url').val();
|
||||
@@ -16,44 +15,39 @@ var UmbracoEmbedDialog = {
|
||||
|
||||
$('#preview').html('<img src="img/ajax-loader.gif" alt="loading"/>');
|
||||
$('#source').val('');
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
async: true,
|
||||
url: '../../../../umbraco/webservices/api/mediaservice.asmx/Embed',
|
||||
data: '{ url: "' + url + '", width: "' + width + '", height: "' + height + '" }',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json',
|
||||
success: function (msg) {
|
||||
var resultAsJson = msg.d;
|
||||
switch (resultAsJson.Status) {
|
||||
case 0:
|
||||
//not supported
|
||||
$('#preview').html('Not Supported');
|
||||
break;
|
||||
case 1:
|
||||
//error
|
||||
$('#preview').html('Error');
|
||||
break;
|
||||
case 2:
|
||||
$('#preview').html(resultAsJson.Markup);
|
||||
$('#source').val(resultAsJson.Markup);
|
||||
if (resultAsJson.SupportsDimensions) {
|
||||
$('#dimensions').show();
|
||||
} else {
|
||||
$('#dimensions').hide();
|
||||
}
|
||||
$('#insert').removeAttr('disabled');
|
||||
break;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
async: true,
|
||||
url: '../../../../base/EmbedMediaService/Embed/',
|
||||
data: { url: url, width: width, height: height },
|
||||
dataType: 'json',
|
||||
success: function (result) {
|
||||
switch (result.Status) {
|
||||
case 0:
|
||||
//not supported
|
||||
$('#preview').html('Not Supported');
|
||||
break;
|
||||
case 1:
|
||||
//error
|
||||
$('#preview').html('Error');
|
||||
break;
|
||||
case 2:
|
||||
$('#preview').html(result.Markup);
|
||||
$('#source').val(result.Markup);
|
||||
if (result.SupportsDimensions) {
|
||||
$('#dimensions').show();
|
||||
} else {
|
||||
$('#dimensions').hide();
|
||||
}
|
||||
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
$('#preview').html("Error");
|
||||
//alert(xhr.status);
|
||||
//alert(thrownError);
|
||||
}
|
||||
});
|
||||
$('#insert').removeAttr('disabled');
|
||||
break;
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
$('#preview').html("Error");
|
||||
}
|
||||
});
|
||||
},
|
||||
beforeResize: function () {
|
||||
this.width = parseInt($('#width').val(), 10);
|
||||
@@ -73,11 +67,9 @@ var UmbracoEmbedDialog = {
|
||||
$('#width').val(this.width);
|
||||
}
|
||||
}
|
||||
|
||||
if ($('#url').val() != '') {
|
||||
UmbracoEmbedDialog.showPreview();
|
||||
}
|
||||
|
||||
},
|
||||
changeSource: function (type) {
|
||||
if ($('#source').val() != '') {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
tinyMCE.addI18n('da.umbracoembed', {
|
||||
desc: 'Inds\u00E6t ekstern mediefil',
|
||||
desc: 'Inds\u00E6t ekstern mediefil'
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
tinyMCE.addI18n('en.umbracoembed', {
|
||||
desc: 'Embed third party media',
|
||||
desc: 'Embed third party media'
|
||||
});
|
||||
@@ -1,3 +1,3 @@
|
||||
tinyMCE.addI18n('en_us.umbracoembed', {
|
||||
desc: 'Embed third party media',
|
||||
desc: 'Embed third party media'
|
||||
});
|
||||
@@ -3,11 +3,6 @@
|
||||
<configSections>
|
||||
<section name="urlrewritingnet" restartOnExternalChanges="true" requirePermission="false" type="UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter" />
|
||||
<section name="microsoft.scripting" type="Microsoft.Scripting.Hosting.Configuration.Section, Microsoft.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
|
||||
|
||||
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="umbraco.presentation.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
|
||||
<section name="clientDependency" type="ClientDependency.Core.Config.ClientDependencySection, ClientDependency.Core" requirePermission="false"/>
|
||||
<section name="Examine" type="Examine.Config.ExamineSettings, Examine" requirePermission="false"/>
|
||||
<section name="ExamineLuceneIndexSets" type="UmbracoExamine.Config.ExamineLuceneIndexes, UmbracoExamine" requirePermission="false"/>
|
||||
@@ -93,7 +88,7 @@
|
||||
<globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />
|
||||
<xhtmlConformance mode="Strict" />
|
||||
|
||||
<httpRuntime requestValidationMode="2.0" />
|
||||
<httpRuntime requestValidationMode="2.0" enableVersionHeader="false" />
|
||||
|
||||
<pages enableEventValidation="false">
|
||||
<!-- ASPNETAJAX -->
|
||||
@@ -107,7 +102,7 @@
|
||||
<!-- URL REWRTIER -->
|
||||
<add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter" />
|
||||
<!-- UMBRACO -->
|
||||
<add name=" UmbracoModule" type="Umbraco.Web.UmbracoModule,umbraco" />
|
||||
<add name="UmbracoModule" type="Umbraco.Web.UmbracoModule,umbraco" />
|
||||
<!-- ASPNETAJAX -->
|
||||
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<!-- CLIENT DEPENDENCY -->
|
||||
@@ -232,6 +227,14 @@
|
||||
<remove fileExtension=".air" />
|
||||
<mimeMap fileExtension=".air" mimeType="application/vnd.adobe.air-application-installer-package+zip" />
|
||||
</staticContent>
|
||||
|
||||
<!-- Ensure the powered by header is not returned -->
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<remove name="X-Powered-By"/>
|
||||
</customHeaders>
|
||||
</httpProtocol>
|
||||
|
||||
</system.webServer>
|
||||
|
||||
<system.codedom>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.XPath;
|
||||
@@ -293,9 +294,9 @@ namespace Umbraco.Web
|
||||
//ok it doesn't exist, we might assume now that Examine didn't index this property because the index is not set up correctly
|
||||
//so before we go loading this from the database, we can check if the alias exists on the content type at all, this information
|
||||
//is cached so will be quicker to look up.
|
||||
if (dd.Properties.Any(x => x.Alias == "__NodeTypeAlias"))
|
||||
if (dd.Properties.Any(x => x.Alias == UmbracoContentIndexer.NodeTypeAliasFieldName))
|
||||
{
|
||||
var aliasesAndNames = ContentType.GetAliasesAndNames(dd.Properties.First(x => x.Alias.InvariantEquals("__NodeTypeAlias")).Value.ToString());
|
||||
var aliasesAndNames = ContentType.GetAliasesAndNames(dd.Properties.First(x => x.Alias.InvariantEquals(UmbracoContentIndexer.NodeTypeAliasFieldName)).Value.ToString());
|
||||
if (aliasesAndNames != null)
|
||||
{
|
||||
if (!aliasesAndNames.ContainsKey(alias))
|
||||
@@ -317,7 +318,12 @@ namespace Umbraco.Web
|
||||
}
|
||||
}
|
||||
|
||||
return dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
|
||||
//We've made it here which means that the value is stored in the Examine index.
|
||||
//We are going to check for a special field however, that is because in some cases we store a 'Raw'
|
||||
//value in the index such as for xml/html.
|
||||
var rawValue = dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals("__Raw_" + alias));
|
||||
return rawValue
|
||||
?? dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -360,9 +366,17 @@ namespace Umbraco.Web
|
||||
|
||||
if (results.Any())
|
||||
{
|
||||
return useLuceneSort
|
||||
? results.Select(ConvertFromSearchResult) //will already be sorted by lucene
|
||||
: results.Select(ConvertFromSearchResult).OrderBy(x => x.SortOrder);
|
||||
return useLuceneSort
|
||||
? results.Select(ConvertFromSearchResult) //will already be sorted by lucene
|
||||
: results.Select(ConvertFromSearchResult).OrderBy(x => x.SortOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if there's no result then return null. Previously we defaulted back to library.GetMedia below
|
||||
//but this will always get called for when we are getting descendents since many items won't have
|
||||
//children and then we are hitting the database again!
|
||||
//So instead we're going to rely on Examine to have the correct results like it should.
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
@@ -373,23 +387,27 @@ namespace Umbraco.Web
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//falling back to get media
|
||||
|
||||
var media = library.GetMedia(parentId, true);
|
||||
if (media != null && media.Current != null)
|
||||
{
|
||||
media.MoveNext();
|
||||
xpath = media.Current;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
}
|
||||
|
||||
//The xpath might be the whole xpath including the current ones ancestors so we need to select the current node
|
||||
var item = xpath.Select("//*[@id='" + parentId + "']");
|
||||
if (item.Current == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//The xpath might be the whole xpath including the current ones ancestors so we need to select the current node
|
||||
var item = xpath.Select("//*[@id='" + parentId + "']");
|
||||
if (item.Current == null)
|
||||
{
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
var children = item.Current.SelectChildren(XPathNodeType.Element);
|
||||
|
||||
var mediaList = new List<IPublishedContent>();
|
||||
|
||||
@@ -22,6 +22,24 @@ namespace Umbraco.Web
|
||||
public static class HtmlHelperRenderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders a partial view that is found in the specified area
|
||||
/// </summary>
|
||||
/// <param name="helper"></param>
|
||||
/// <param name="partial"></param>
|
||||
/// <param name="area"></param>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="viewData"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcHtmlString AreaPartial(this HtmlHelper helper, string partial, string area, object model = null, ViewDataDictionary viewData = null)
|
||||
{
|
||||
var originalArea = helper.ViewContext.RouteData.DataTokens["area"];
|
||||
helper.ViewContext.RouteData.DataTokens["area"] = area;
|
||||
var result = helper.Partial(partial, model, viewData);
|
||||
helper.ViewContext.RouteData.DataTokens["area"] = originalArea;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will render the preview badge when in preview mode which is not required ever unless the MVC page you are
|
||||
/// using does not inherit from UmbracoTemplatePage
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
@@ -20,6 +21,7 @@ namespace Umbraco.Web.Models
|
||||
/// <summary>
|
||||
/// The base dynamic model for views
|
||||
/// </summary>
|
||||
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
|
||||
public class DynamicPublishedContent : DynamicObject, IPublishedContent, IOwnerCollectionAware<IPublishedContent>
|
||||
{
|
||||
protected internal IPublishedContent PublishedContent { get; private set; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core;
|
||||
@@ -17,6 +18,7 @@ namespace Umbraco.Web.Models
|
||||
/// This also ensures that we have an OwnersCollection property so that the IsFirst/IsLast/Index helper methods work
|
||||
/// when referenced inside the result of a collection. http://issues.umbraco.org/issue/U4-1797
|
||||
/// </remarks>
|
||||
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
|
||||
public abstract class PublishedContentBase : IPublishedContent, IOwnerCollectionAware<IPublishedContent>
|
||||
{
|
||||
private string _url;
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Web.Mvc
|
||||
else
|
||||
{
|
||||
//exit the loop
|
||||
currentRouteData = null;
|
||||
currentContext = null;
|
||||
}
|
||||
}
|
||||
return new Attempt<RouteDefinition>(
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace Umbraco.Web.Trees
|
||||
//NOTE: Notice the MacroPartials%2f string below, this is a URLEncoded string of "MacroPartials/" so that the editor knows
|
||||
// to load the file from the correct location
|
||||
javascript.Append(
|
||||
@"
|
||||
@"
|
||||
function openMacroPartialView(id) {
|
||||
UmbClientMgr.contentFrame('Settings/Views/EditView.aspx?file=MacroPartials%2f' + id);
|
||||
UmbClientMgr.contentFrame('Settings/Views/EditView.aspx?treeType=partialViewMacros&file=MacroPartials%2f' + id);
|
||||
}
|
||||
");
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace Umbraco.Web.Trees
|
||||
//NOTE: Notice the Partials%2f string below, this is a URLEncoded string of "Partials/" so that the editor knows
|
||||
// to load the file from the correct location
|
||||
javascript.Append(
|
||||
@"
|
||||
@"
|
||||
function openPartialView(id) {
|
||||
UmbClientMgr.contentFrame('Settings/Views/EditView.aspx?file=Partials%2f' + id);
|
||||
UmbClientMgr.contentFrame('Settings/Views/EditView.aspx?treeType=partialViews&file=Partials%2f' + id);
|
||||
}
|
||||
");
|
||||
}
|
||||
|
||||
@@ -383,6 +383,9 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Packages\directoryBrowser.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Python\editPython.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Packages\StarterKits.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
@@ -416,6 +419,12 @@
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\modals\ShowUmbracoTags.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\editstylesheet.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\property\EditStyleSheetProperty.aspx.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\templateControls\Image.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\uQuery\IGetProperty.cs" />
|
||||
@@ -1148,13 +1157,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Packages\SubmitPackage.aspx.designer.cs">
|
||||
<DependentUpon>SubmitPackage.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Python\editPython.aspx.cs">
|
||||
<DependentUpon>editPython.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Python\editPython.aspx.designer.cs">
|
||||
<DependentUpon>editPython.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Xslt\getXsltStatus.asmx.cs">
|
||||
<DependentUpon>getXsltStatus.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
@@ -1514,20 +1516,6 @@
|
||||
<DependentUpon>editScript.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\editstylesheet.aspx.cs">
|
||||
<DependentUpon>editstylesheet.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\editstylesheet.aspx.designer.cs">
|
||||
<DependentUpon>editstylesheet.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\property\EditStyleSheetProperty.aspx.cs">
|
||||
<DependentUpon>EditStyleSheetProperty.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\property\EditStyleSheetProperty.aspx.designer.cs">
|
||||
<DependentUpon>EditStyleSheetProperty.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\templateControls\Script.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\Trees\BaseMediaTree.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\Trees\loadDLRScripts.cs" />
|
||||
@@ -1817,6 +1805,7 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Reference.map</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WebServices\EmbedMediaService.cs" />
|
||||
<Compile Include="WebServices\FolderBrowserService.cs" />
|
||||
<Compile Include="WebServices\UmbracoAuthorizedHttpHandler.cs" />
|
||||
<Compile Include="WebServices\SaveFileController.cs" />
|
||||
@@ -1952,10 +1941,7 @@
|
||||
<Content Include="umbraco.presentation\install\steps\welcome.ascx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\cacheBrowser.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Python\editPython.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\cacheBrowser.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\members\ViewMembers.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\plugins\tinymce3\insertImage.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -2047,10 +2033,6 @@
|
||||
<Content Include="umbraco.presentation\umbraco\settings\EditMediaType.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\settings\stylesheet\editstylesheet.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\settings\stylesheet\property\EditStyleSheetProperty.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\test.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\tree.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -2170,11 +2152,8 @@
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>xcopy /s /y "$(ProjectDir)umbraco.presentation\*.aspx" "$(ProjectDir)..\Umbraco.Web.UI\"
|
||||
xcopy /s /y "$(ProjectDir)umbraco.presentation\*.ascx" "$(ProjectDir)..\Umbraco.Web.UI\"
|
||||
xcopy /s /y "$(ProjectDir)umbraco.presentation\*.asmx" "$(ProjectDir)..\Umbraco.Web.UI\"
|
||||
xcopy /s /y "$(ProjectDir)umbraco.presentation\*.ashx" "$(ProjectDir)..\Umbraco.Web.UI\"
|
||||
xcopy /s /y "$(ProjectDir)umbraco.presentation\*.master" "$(ProjectDir)..\Umbraco.Web.UI\"</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Web.Routing;
|
||||
@@ -17,7 +18,7 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
public class UmbracoApplication : UmbracoApplicationBase
|
||||
{
|
||||
|
||||
|
||||
protected override IBootManager GetBootManager()
|
||||
{
|
||||
return new WebBootManager(this);
|
||||
|
||||
@@ -426,6 +426,15 @@ namespace Umbraco.Web
|
||||
|
||||
DisposeHttpContextItems(httpContext);
|
||||
};
|
||||
|
||||
//disable asp.net headers (security)
|
||||
app.PreSendRequestHeaders += (sender, args) =>
|
||||
{
|
||||
var httpContext = ((HttpApplication)sender).Context;
|
||||
httpContext.Response.Headers.Remove("Server");
|
||||
//this doesn't normally work since IIS sets it but we'll keep it here anyways.
|
||||
httpContext.Response.Headers.Remove("X-Powered-By");
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Media;
|
||||
using umbraco.BusinessLogic;
|
||||
using Umbraco.Web.BaseRest;
|
||||
|
||||
namespace Umbraco.Web.WebServices
|
||||
{
|
||||
[RestExtension("EmbedMediaService")]
|
||||
public class EmbedMediaService
|
||||
{
|
||||
[RestExtensionMethod(ReturnXml = false)]
|
||||
public static string Embed()
|
||||
{
|
||||
var currentUser = User.GetCurrent();
|
||||
|
||||
if (currentUser == null)
|
||||
throw new UnauthorizedAccessException("You must be logged in to use this service");
|
||||
|
||||
var url = HttpContext.Current.Request.Form["url"];
|
||||
var width = int.Parse(HttpContext.Current.Request.Form["width"]);
|
||||
var height = int.Parse(HttpContext.Current.Request.Form["height"]);
|
||||
|
||||
var result = new Result();
|
||||
|
||||
//todo cache embed doc
|
||||
var xmlConfig = new XmlDocument();
|
||||
xmlConfig.Load(GlobalSettings.FullpathToRoot + Path.DirectorySeparatorChar + "config" + Path.DirectorySeparatorChar + "EmbeddedMedia.config");
|
||||
|
||||
foreach (XmlNode node in xmlConfig.SelectNodes("//provider"))
|
||||
{
|
||||
var regexPattern = new Regex(node.SelectSingleNode("./urlShemeRegex").InnerText, RegexOptions.IgnoreCase);
|
||||
|
||||
if (regexPattern.IsMatch(url))
|
||||
{
|
||||
var prov = (IEmbedProvider)Activator.CreateInstance(Type.GetType(node.Attributes["type"].Value));
|
||||
|
||||
if (node.Attributes["supportsDimensions"] != null)
|
||||
result.SupportsDimensions = node.Attributes["supportsDimensions"].Value == "True";
|
||||
else
|
||||
result.SupportsDimensions = prov.SupportsDimensions;
|
||||
|
||||
var settings = node.ChildNodes.Cast<XmlNode>().ToDictionary(settingNode => settingNode.Name);
|
||||
|
||||
foreach (var prop in prov.GetType().GetProperties().Where(prop => prop.IsDefined(typeof(ProviderSetting), true)))
|
||||
{
|
||||
|
||||
if (settings.Any(s => s.Key.ToLower() == prop.Name.ToLower()))
|
||||
{
|
||||
var setting = settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value;
|
||||
var settingType = typeof(Media.EmbedProviders.Settings.String);
|
||||
|
||||
if (setting.Attributes["type"] != null)
|
||||
settingType = Type.GetType(setting.Attributes["type"].Value);
|
||||
|
||||
var settingProv = (IEmbedSettingProvider)Activator.CreateInstance(settingType);
|
||||
prop.SetValue(prov, settingProv.GetSetting(settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value), null);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
result.Markup = prov.GetMarkup(url, width, height);
|
||||
result.Status = Status.Success;
|
||||
}
|
||||
catch
|
||||
{
|
||||
result.Status = Status.Error;
|
||||
}
|
||||
|
||||
return new JavaScriptSerializer().Serialize(result);
|
||||
}
|
||||
}
|
||||
|
||||
result.Status = Status.NotSupported;
|
||||
return new JavaScriptSerializer().Serialize(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Script.Serialization;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Media.ThumbnailProviders;
|
||||
using umbraco.BasePages;
|
||||
using umbraco.BusinessLogic;
|
||||
using umbraco.IO;
|
||||
using Umbraco.Core.IO;
|
||||
using umbraco.cms.businesslogic.Tags;
|
||||
using umbraco.cms.businesslogic.media;
|
||||
using Umbraco.Web.BaseRest;
|
||||
|
||||
namespace Umbraco.Web.WebServices
|
||||
@@ -23,26 +18,20 @@ namespace Umbraco.Web.WebServices
|
||||
[RestExtensionMethod(ReturnXml = false)]
|
||||
public static string GetChildren(int parentId)
|
||||
{
|
||||
var currentUser = GetCurrentUser();
|
||||
|
||||
var parentMedia = new global::umbraco.cms.businesslogic.media.Media(parentId);
|
||||
var currentUser = User.GetCurrent();
|
||||
AuthorizeAccess(parentMedia, currentUser);
|
||||
|
||||
var data = new List<object>();
|
||||
|
||||
// Check user is logged in
|
||||
if (currentUser == null)
|
||||
throw new UnauthorizedAccessException("You must be logged in to use this service");
|
||||
|
||||
// Check user is allowed to access selected media item
|
||||
if(!("," + parentMedia.Path + ",").Contains("," + currentUser.StartMediaId + ","))
|
||||
throw new UnauthorizedAccessException("You do not have access to this Media node");
|
||||
|
||||
// Get children and filter
|
||||
//TODO: Only fetch files, not containers
|
||||
//TODO: Cache responses to speed up susequent searches
|
||||
foreach (var child in parentMedia.Children)
|
||||
{
|
||||
var fileProp = child.getProperty("umbracoFile") ??
|
||||
child.GenericProperties.FirstOrDefault(x =>
|
||||
x.PropertyType.DataTypeDefinition.DataType.Id == new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"));
|
||||
child.GenericProperties.FirstOrDefault(x => x.PropertyType.DataTypeDefinition.DataType.Id == new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"));
|
||||
|
||||
var fileUrl = fileProp != null ? fileProp.Value.ToString() : "";
|
||||
var thumbUrl = ThumbnailProvidersResolver.Current.GetThumbnailUrl(fileUrl);
|
||||
@@ -55,9 +44,9 @@ namespace Umbraco.Web.WebServices
|
||||
MediaTypeAlias = child.ContentType.Alias,
|
||||
EditUrl = string.Format("editMedia.aspx?id={0}", child.Id),
|
||||
FileUrl = fileUrl,
|
||||
ThumbnailUrl = !string.IsNullOrEmpty(thumbUrl)
|
||||
? thumbUrl
|
||||
: IOHelper.ResolveUrl(SystemDirectories.Umbraco + "/images/thumbnails/" + child.ContentType.Thumbnail)
|
||||
ThumbnailUrl = string.IsNullOrEmpty(thumbUrl)
|
||||
? IOHelper.ResolveUrl(SystemDirectories.Umbraco + "/images/thumbnails/" + child.ContentType.Thumbnail)
|
||||
: thumbUrl
|
||||
};
|
||||
|
||||
data.Add(item);
|
||||
@@ -69,15 +58,19 @@ namespace Umbraco.Web.WebServices
|
||||
[RestExtensionMethod(ReturnXml = false)]
|
||||
public static string Delete(string nodeIds)
|
||||
{
|
||||
var nodeIdParts = nodeIds.Split(',');
|
||||
var currentUser = GetCurrentUser();
|
||||
|
||||
foreach (var nodeIdPart in nodeIdParts.Where(x => !string.IsNullOrEmpty(x)))
|
||||
var nodeIdParts = nodeIds.Split(',');
|
||||
|
||||
foreach (var nodeIdPart in nodeIdParts.Where(x => string.IsNullOrEmpty(x) == false))
|
||||
{
|
||||
var nodeId = 0;
|
||||
if (!Int32.TryParse(nodeIdPart, out nodeId))
|
||||
int nodeId;
|
||||
if (Int32.TryParse(nodeIdPart, out nodeId) == false)
|
||||
continue;
|
||||
|
||||
var node = new global::umbraco.cms.businesslogic.media.Media(nodeId);
|
||||
AuthorizeAccess(node, currentUser);
|
||||
|
||||
node.delete(("," + node.Path + ",").Contains(",-21,"));
|
||||
}
|
||||
|
||||
@@ -86,5 +79,20 @@ namespace Umbraco.Web.WebServices
|
||||
success = true
|
||||
});
|
||||
}
|
||||
|
||||
private static User GetCurrentUser()
|
||||
{
|
||||
var currentUser = User.GetCurrent();
|
||||
if (currentUser == null)
|
||||
throw new UnauthorizedAccessException("You must be logged in to use this service");
|
||||
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
private static void AuthorizeAccess(global::umbraco.cms.businesslogic.media.Media mediaItem, User currentUser)
|
||||
{
|
||||
if (("," + mediaItem.Path + ",").Contains("," + currentUser.StartMediaId + ",") == false)
|
||||
throw new UnauthorizedAccessException("You do not have access to this Media node");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Examine.Providers;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web;
|
||||
@@ -15,6 +17,8 @@ namespace umbraco.presentation.umbraco.Search
|
||||
public class ExamineEvents : IApplicationEventHandler
|
||||
{
|
||||
|
||||
private const string RawFieldPrefix = "__Raw_";
|
||||
|
||||
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
}
|
||||
@@ -51,12 +55,13 @@ namespace umbraco.presentation.umbraco.Search
|
||||
var contentIndexer = ExamineManager.Instance.IndexProviderCollection["InternalIndexer"] as UmbracoContentIndexer;
|
||||
if (contentIndexer != null)
|
||||
{
|
||||
contentIndexer.DocumentWriting += indexer_DocumentWriting;
|
||||
contentIndexer.GatheringNodeData += ContentIndexerGatheringNodeData;
|
||||
contentIndexer.DocumentWriting += IndexerDocumentWriting;
|
||||
}
|
||||
var memberIndexer = ExamineManager.Instance.IndexProviderCollection["InternalMemberIndexer"] as UmbracoMemberIndexer;
|
||||
if (memberIndexer != null)
|
||||
{
|
||||
memberIndexer.DocumentWriting += indexer_DocumentWriting;
|
||||
memberIndexer.DocumentWriting += IndexerDocumentWriting;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,16 +141,64 @@ namespace umbraco.presentation.umbraco.Search
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler to create a lower cased version of the node name, this is so we can support case-insensitive searching and still
|
||||
/// use the Whitespace Analyzer
|
||||
/// This checks if any user data might be xml/html, if so we will duplicate the field and store the raw value
|
||||
/// so we can retreive the raw value when required.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void indexer_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e)
|
||||
/// <remarks>
|
||||
/// This is regarding this issue: http://issues.umbraco.org/issue/U4-644
|
||||
/// The underlying UmbracoContentIndexer strips the HTML values before this event is even fired
|
||||
/// so we need to check in the underlying 'node' document for the value.
|
||||
/// </remarks>
|
||||
static void ContentIndexerGatheringNodeData(object sender, IndexingNodeDataEventArgs e)
|
||||
{
|
||||
if (e.Fields.Keys.Contains("nodeName"))
|
||||
var indexer = sender as UmbracoContentIndexer;
|
||||
if (indexer == null) return;
|
||||
|
||||
//loop through each field that is defined as a UserField for the index
|
||||
foreach (var field in indexer.IndexerData.UserFields)
|
||||
{
|
||||
//add the lower cased version
|
||||
if (e.Fields.ContainsKey(field.Name))
|
||||
{
|
||||
//get the original value from the node
|
||||
var node = e.Node.Descendants(field.Name).FirstOrDefault();
|
||||
if (node == null) continue;
|
||||
|
||||
//check if the node value has html
|
||||
if (XmlHelper.CouldItBeXml(node.Value))
|
||||
{
|
||||
//First save the raw value to a raw field, we will change the policy of this field by detecting the prefix later
|
||||
e.Fields[RawFieldPrefix + field.Name] = node.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler to create a lower cased version of the node name, this is so we can support case-insensitive searching and still
|
||||
/// use the Whitespace Analyzer. This also ensures the 'Raw' values are added to the document.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
static void IndexerDocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e)
|
||||
{
|
||||
//This ensures that the special __Raw_ fields are indexed
|
||||
var d = e.Document;
|
||||
foreach (var f in e.Fields.Where(x => x.Key.StartsWith(RawFieldPrefix)))
|
||||
{
|
||||
d.Add(new Field(
|
||||
f.Key,
|
||||
f.Value,
|
||||
Field.Store.YES,
|
||||
Field.Index.NO, //don't index this field, we never want to search by it
|
||||
Field.TermVector.NO));
|
||||
}
|
||||
|
||||
//add the lower cased version
|
||||
if (e.Fields.Keys.Contains("nodeName"))
|
||||
{
|
||||
e.Document.Add(new Field("__nodeName",
|
||||
e.Fields["nodeName"].ToLower(),
|
||||
Field.Store.YES,
|
||||
|
||||
@@ -494,8 +494,11 @@ namespace umbraco.cms.presentation.Trees
|
||||
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
||||
protected virtual void OnBeforeNodeRender(ref XmlTree sender, ref XmlTreeNode node, EventArgs e)
|
||||
{
|
||||
if (BeforeNodeRender != null)
|
||||
BeforeNodeRender(ref sender, ref node, e);
|
||||
if (node != null && node != null)
|
||||
{
|
||||
if (BeforeNodeRender != null)
|
||||
BeforeNodeRender(ref sender, ref node, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Web.UI.WebControls;
|
||||
using System.Web.UI.WebControls.WebParts;
|
||||
using System.Web.UI.HtmlControls;
|
||||
using System.IO;
|
||||
using umbraco.IO;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace umbraco.cms.presentation.Trees
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace umbraco.cms.presentation.Trees
|
||||
|
||||
private void Init()
|
||||
{
|
||||
m_JSSerializer = new JSONSerializer();
|
||||
m_JSSerializer = new JSONSerializer { MaxJsonLength = int.MaxValue };
|
||||
|
||||
switch (m_TreeType)
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace umbraco
|
||||
}
|
||||
|
||||
function openView(id) {
|
||||
UmbClientMgr.contentFrame('settings/views/editView.aspx?templateID=' + id);
|
||||
UmbClientMgr.contentFrame('settings/views/editView.aspx?treeType=templates&templateID=' + id);
|
||||
}
|
||||
|
||||
function openSkin(id) {
|
||||
|
||||
+158
-34
@@ -63,11 +63,13 @@ namespace umbraco.controls
|
||||
|
||||
//the async saving task
|
||||
private Action<SaveAsyncState> _asyncSaveTask;
|
||||
//the async delete property task
|
||||
private Action<DeleteAsyncState> _asyncDeleteTask;
|
||||
|
||||
override protected void OnInit(EventArgs e)
|
||||
{
|
||||
base.OnInit(e);
|
||||
|
||||
|
||||
LoadContentType();
|
||||
|
||||
SetupInfoPane();
|
||||
@@ -78,17 +80,17 @@ namespace umbraco.controls
|
||||
SetupGenericPropertiesPane();
|
||||
SetupTabPane();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
pp_newTab.Text = ui.Text("newtab", UmbracoEnsuredPage.CurrentUser);
|
||||
pp_alias.Text = ui.Text("alias", UmbracoEnsuredPage.CurrentUser);
|
||||
pp_name.Text = ui.Text("name", UmbracoEnsuredPage.CurrentUser);
|
||||
pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", UmbracoEnsuredPage.CurrentUser);
|
||||
pp_description.Text = ui.Text("editcontenttype", "description");
|
||||
pp_icon.Text = ui.Text("icon", UmbracoEnsuredPage.CurrentUser);
|
||||
pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail");
|
||||
pp_newTab.Text = ui.Text("newtab", CurrentUser);
|
||||
pp_alias.Text = ui.Text("alias", CurrentUser);
|
||||
pp_name.Text = ui.Text("name", CurrentUser);
|
||||
pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", CurrentUser);
|
||||
pp_description.Text = ui.Text("editcontenttype", "description", CurrentUser);
|
||||
pp_icon.Text = ui.Text("icon", CurrentUser);
|
||||
pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail", CurrentUser);
|
||||
|
||||
|
||||
// we'll disable this...
|
||||
@@ -120,38 +122,79 @@ namespace umbraco.controls
|
||||
get { return ((BasePage)Page).getUser(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A class to track the async state for deleting a doc type property
|
||||
/// </summary>
|
||||
private class DeleteAsyncState
|
||||
{
|
||||
public Umbraco.Web.UmbracoContext UmbracoContext { get; private set; }
|
||||
public GenericPropertyWrapper GenericPropertyWrapper { get; private set; }
|
||||
|
||||
public DeleteAsyncState(
|
||||
Umbraco.Web.UmbracoContext umbracoContext,
|
||||
GenericPropertyWrapper genericPropertyWrapper)
|
||||
{
|
||||
UmbracoContext = umbracoContext;
|
||||
GenericPropertyWrapper = genericPropertyWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A class to track the async state for saving the doc type
|
||||
/// </summary>
|
||||
private class SaveAsyncState
|
||||
{
|
||||
public SaveAsyncState(
|
||||
Umbraco.Web.UmbracoContext umbracoContext,
|
||||
SaveClickEventArgs saveArgs,
|
||||
string originalAlias,
|
||||
string originalName,
|
||||
string newAlias,
|
||||
string newName)
|
||||
string newName,
|
||||
string[] originalPropertyAliases)
|
||||
{
|
||||
UmbracoContext = umbracoContext;
|
||||
SaveArgs = saveArgs;
|
||||
OriginalAlias = originalAlias;
|
||||
OriginalName = originalName;
|
||||
NewAlias = newAlias;
|
||||
NewName = newName;
|
||||
_originalAlias = originalAlias;
|
||||
_originalName = originalName;
|
||||
_newAlias = newAlias;
|
||||
_originalPropertyAliases = originalPropertyAliases;
|
||||
_newName = newName;
|
||||
}
|
||||
|
||||
public Umbraco.Web.UmbracoContext UmbracoContext { get; private set; }
|
||||
public SaveClickEventArgs SaveArgs { get; private set; }
|
||||
public string OriginalAlias { get; private set; }
|
||||
public string OriginalName { get; private set; }
|
||||
public string NewAlias { get; private set; }
|
||||
public string NewName { get; private set; }
|
||||
private readonly string _originalAlias;
|
||||
private readonly string _originalName;
|
||||
private readonly string _newAlias;
|
||||
private readonly string _newName;
|
||||
private readonly string[] _originalPropertyAliases;
|
||||
|
||||
|
||||
public bool HasAliasChanged()
|
||||
{
|
||||
return (string.Compare(OriginalAlias, NewAlias, StringComparison.OrdinalIgnoreCase) != 0);
|
||||
return (string.Compare(_originalAlias, _newAlias, StringComparison.OrdinalIgnoreCase) != 0);
|
||||
}
|
||||
public bool HasNameChanged()
|
||||
{
|
||||
return (string.Compare(OriginalName, NewName, StringComparison.OrdinalIgnoreCase) != 0);
|
||||
return (string.Compare(_originalName, _newName, StringComparison.OrdinalIgnoreCase) != 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any property has been removed or if any alias has changed
|
||||
/// </summary>
|
||||
/// <param name="contentType"></param>
|
||||
/// <returns></returns>
|
||||
public bool HasAnyPropertyAliasChanged(ContentType contentType)
|
||||
{
|
||||
var newAliases = contentType.PropertyTypes.Select(x => x.Alias).ToArray();
|
||||
//if any have been removed, return true
|
||||
if (newAliases.Length < _originalPropertyAliases.Count())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//otherwise ensure that all of the original aliases are still existing
|
||||
return newAliases.ContainsAll(_originalPropertyAliases) == false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,10 +273,12 @@ namespace umbraco.controls
|
||||
protected void save_click(object sender, ImageClickEventArgs e)
|
||||
{
|
||||
|
||||
var state = new SaveAsyncState(new SaveClickEventArgs("Saved")
|
||||
var state = new SaveAsyncState(
|
||||
Umbraco.Web.UmbracoContext.Current,
|
||||
new SaveClickEventArgs("Saved")
|
||||
{
|
||||
IconType = BasePage.speechBubbleIcon.success
|
||||
}, _contentType.Alias, _contentType.Text, txtAlias.Text, txtName.Text);
|
||||
}, _contentType.Alias, _contentType.Text, txtAlias.Text, txtName.Text, _contentType.PropertyTypes.Select(x => x.Alias).ToArray());
|
||||
|
||||
//Add the async operation to the page
|
||||
Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncSaveOperation, EndAsyncSaveOperation, HandleAsyncSaveTimeout, state));
|
||||
@@ -243,6 +288,9 @@ namespace umbraco.controls
|
||||
{
|
||||
Trace.Write("ContentTypeControlNew", "executing task");
|
||||
|
||||
//we need to re-set the UmbracoContext since it will be nulled and our cache handlers need it
|
||||
global::Umbraco.Web.UmbracoContext.Current = asyncState.UmbracoContext;
|
||||
|
||||
//NOTE The saving of the 5 properties (Name, Alias, Icon, Description and Thumbnail) are divided
|
||||
//to avoid the multiple cache flushing when each property is set using the legacy ContentType class,
|
||||
//which has been reduced to the else-clause.
|
||||
@@ -310,13 +358,13 @@ namespace umbraco.controls
|
||||
|
||||
_contentType.AllowedChildContentTypeIDs = SaveAllowedChildTypes();
|
||||
_contentType.AllowAtRoot = allowAtRoot.Checked;
|
||||
|
||||
|
||||
_contentType.Save();
|
||||
}
|
||||
|
||||
// Only if the doctype alias changed, cause a regeneration of the xml cache file since
|
||||
// the xml element names will need to be updated to reflect the new alias
|
||||
if (asyncState.HasAliasChanged())
|
||||
if (asyncState.HasAliasChanged() || asyncState.HasAnyPropertyAliasChanged(_contentType))
|
||||
RegenerateXmlCaches();
|
||||
|
||||
Trace.Write("ContentTypeControlNew", "task completing");
|
||||
@@ -347,6 +395,10 @@ namespace umbraco.controls
|
||||
{
|
||||
_contentType = new cms.businesslogic.media.MediaType(docTypeId);
|
||||
}
|
||||
else if (Request.Path.ToLowerInvariant().Contains("editmembertype.aspx"))
|
||||
{
|
||||
_contentType = new cms.businesslogic.member.MemberType(docTypeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType = new ContentType(docTypeId);
|
||||
@@ -356,10 +408,19 @@ namespace umbraco.controls
|
||||
/// <summary>
|
||||
/// Regenerates the XML caches. Used after a document type alias has been changed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We only regenerate any XML cache based on if this is a Document type, not a media type or
|
||||
/// a member type.
|
||||
/// </remarks>
|
||||
private void RegenerateXmlCaches()
|
||||
{
|
||||
Document.RePublishAll();
|
||||
library.RefreshContent();
|
||||
_contentType.RebuildXmlStructuresForContent();
|
||||
|
||||
//special case for DocumentType's
|
||||
if (_contentType is DocumentType)
|
||||
{
|
||||
library.RefreshContent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1001,6 +1062,47 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called asynchronously in order to delete a content type property
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="cb"></param>
|
||||
/// <param name="state"></param>
|
||||
/// <returns></returns>
|
||||
private IAsyncResult BeginAsyncDeleteOperation(object sender, EventArgs e, AsyncCallback cb, object state)
|
||||
{
|
||||
Trace.Write("ContentTypeControlNew", "Start async operation");
|
||||
|
||||
//get the args from the async state
|
||||
var args = (DeleteAsyncState)state;
|
||||
|
||||
//start the task
|
||||
var result = _asyncDeleteTask.BeginInvoke(args, cb, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs once the async database delete operation has completed
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
/// <remarks>
|
||||
/// This updates the UI elements
|
||||
/// </remarks>
|
||||
private void EndAsyncDeleteOperation(IAsyncResult ar)
|
||||
{
|
||||
Trace.Write("ContentTypeControlNew", "ending async operation");
|
||||
|
||||
// reload content type (due to caching)
|
||||
LoadContentType(_contentType.Id);
|
||||
BindDataGenericProperties(true);
|
||||
|
||||
Trace.Write("ContentTypeControlNew", "async operation ended");
|
||||
|
||||
//complete it
|
||||
_asyncDeleteTask.EndInvoke(ar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a PropertyType from the current ContentType when user clicks "red x"
|
||||
/// </summary>
|
||||
@@ -1008,20 +1110,42 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
|
||||
/// <param name="e"></param>
|
||||
protected void gpw_Delete(object sender, EventArgs e)
|
||||
{
|
||||
var gpw = (GenericPropertyWrapper)sender;
|
||||
var state = new DeleteAsyncState(
|
||||
Umbraco.Web.UmbracoContext.Current,
|
||||
(GenericPropertyWrapper)sender);
|
||||
|
||||
if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType)
|
||||
//Add the async operation to the page
|
||||
Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncDeleteOperation, EndAsyncDeleteOperation, HandleAsyncSaveTimeout, state));
|
||||
|
||||
//create the save task to be executed async
|
||||
_asyncDeleteTask = asyncState =>
|
||||
{
|
||||
_contentType.ContentTypeItem.RemovePropertyType(gpw.PropertyType.Alias);
|
||||
_contentType.Save();
|
||||
}
|
||||
Trace.Write("ContentTypeControlNew", "executing task");
|
||||
|
||||
gpw.GenricPropertyControl.PropertyType.delete();
|
||||
//we need to re-set the UmbracoContext since it will be nulled and our cache handlers need it
|
||||
global::Umbraco.Web.UmbracoContext.Current = asyncState.UmbracoContext;
|
||||
|
||||
if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType)
|
||||
{
|
||||
_contentType.ContentTypeItem.RemovePropertyType(asyncState.GenericPropertyWrapper.PropertyType.Alias);
|
||||
_contentType.Save();
|
||||
}
|
||||
|
||||
//delete the property
|
||||
asyncState.GenericPropertyWrapper.GenricPropertyControl.PropertyType.delete();
|
||||
|
||||
//we need to re-generate the xml structures because we're removing a content type property
|
||||
RegenerateXmlCaches();
|
||||
|
||||
Trace.Write("ContentTypeControlNew", "task completing");
|
||||
};
|
||||
|
||||
//execute the async tasks
|
||||
Page.ExecuteRegisteredAsyncTasks();
|
||||
|
||||
LoadContentType(_contentType.Id);
|
||||
BindDataGenericProperties(true);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Tab" Pane
|
||||
|
||||
@@ -79,6 +79,10 @@ namespace umbraco.cms.presentation.developer
|
||||
{
|
||||
int macroID = Convert.ToInt32(Request.QueryString["macroID"]);
|
||||
|
||||
ClientTools
|
||||
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadMacros>().Tree.Alias)
|
||||
.SyncTree("-1,init," + m_macro.Id.ToString(), true); //true forces the reload
|
||||
|
||||
string tempMacroAssembly = macroAssembly.Text;
|
||||
string tempMacroType = macroType.Text;
|
||||
string tempCachePeriod = cachePeriod.Text;
|
||||
|
||||
+41
-18
@@ -10,6 +10,7 @@ using umbraco.cms.businesslogic.language;
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
using umbraco.cms.businesslogic.template;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using umbraco.controls;
|
||||
using umbraco.IO;
|
||||
|
||||
@@ -33,10 +34,11 @@ namespace umbraco.presentation.developer.packages
|
||||
protected ContentPicker cp;
|
||||
private cms.businesslogic.packager.PackageInstance pack;
|
||||
private cms.businesslogic.packager.CreatedPackage createdPackage;
|
||||
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (Request.QueryString["id"] != null) {
|
||||
if (Request.QueryString["id"] != null)
|
||||
{
|
||||
createdPackage = cms.businesslogic.packager.CreatedPackage.GetById(int.Parse(Request.QueryString["id"]));
|
||||
pack = createdPackage.Data;
|
||||
|
||||
@@ -46,18 +48,26 @@ namespace umbraco.presentation.developer.packages
|
||||
content.Controls.Add(cp);
|
||||
|
||||
bt_submitButton.Attributes.Add("onClick", "window.location = 'submitpackage.aspx?id=" + pack.Id.ToString() + "'; return false;");
|
||||
|
||||
if (!String.IsNullOrEmpty(pack.PackagePath)) {
|
||||
|
||||
if (string.IsNullOrEmpty(pack.PackagePath) == false)
|
||||
{
|
||||
packageUmbFile.Text = " <a href='" + Page.ResolveClientUrl(pack.PackagePath) + "'>Download</a>";
|
||||
|
||||
if (cms.businesslogic.packager.repositories.Repository.getAll().Count > 0)
|
||||
bt_submitButton.Visible = true;
|
||||
bt_submitButton.Visible = true;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
packageUmbFile.Text = "<em>This package is not published</em>";
|
||||
}
|
||||
|
||||
if (!Page.IsPostBack) {
|
||||
if (Page.IsPostBack == false)
|
||||
{
|
||||
ClientTools
|
||||
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadPackages>().Tree.Alias)
|
||||
.SyncTree("-1,init," + loadPackages.PACKAGE_TREE_PREFIX + createdPackage.Data.Id, false);
|
||||
|
||||
packageAuthorName.Text = pack.Author;
|
||||
packageAuthorUrl.Text = pack.AuthorUrl;
|
||||
packageLicenseName.Text = pack.License;
|
||||
@@ -71,26 +81,28 @@ namespace umbraco.presentation.developer.packages
|
||||
tb_actions.Text = pack.Actions;
|
||||
|
||||
cp.Value = pack.ContentNodeId.ToString();
|
||||
|
||||
|
||||
//startNode.Value = pack.ContentNodeId.ToString();
|
||||
|
||||
packageContentSubdirs.Checked = pack.ContentLoadChildNodes;
|
||||
|
||||
|
||||
|
||||
/*TEMPLATES */
|
||||
Template[] umbTemplates = Template.GetAllAsList().ToArray();
|
||||
foreach (Template tmp in umbTemplates) {
|
||||
foreach (Template tmp in umbTemplates)
|
||||
{
|
||||
ListItem li = new ListItem(tmp.Text, tmp.Id.ToString());
|
||||
|
||||
if(pack.Templates.Contains(tmp.Id.ToString()))
|
||||
if (pack.Templates.Contains(tmp.Id.ToString()))
|
||||
li.Selected = true;
|
||||
|
||||
|
||||
templates.Items.Add(li);
|
||||
}
|
||||
|
||||
/* DOC TYPES */
|
||||
DocumentType[] docs = DocumentType.GetAllAsList().ToArray();
|
||||
foreach (DocumentType dc in docs) {
|
||||
foreach (DocumentType dc in docs)
|
||||
{
|
||||
ListItem li = new ListItem(dc.Text, dc.Id.ToString());
|
||||
if (pack.Documenttypes.Contains(dc.Id.ToString()))
|
||||
li.Selected = true;
|
||||
@@ -100,7 +112,8 @@ namespace umbraco.presentation.developer.packages
|
||||
|
||||
/*Stylesheets */
|
||||
StyleSheet[] sheets = StyleSheet.GetAll();
|
||||
foreach (StyleSheet st in sheets) {
|
||||
foreach (StyleSheet st in sheets)
|
||||
{
|
||||
ListItem li = new ListItem(st.Text, st.Id.ToString());
|
||||
if (pack.Stylesheets.Contains(st.Id.ToString()))
|
||||
li.Selected = true;
|
||||
@@ -110,7 +123,8 @@ namespace umbraco.presentation.developer.packages
|
||||
}
|
||||
/* MACROS */
|
||||
Macro[] umbMacros = Macro.GetAll();
|
||||
foreach (Macro m in umbMacros) {
|
||||
foreach (Macro m in umbMacros)
|
||||
{
|
||||
ListItem li = new ListItem(m.Name, m.Id.ToString());
|
||||
if (pack.Macros.Contains(m.Id.ToString()))
|
||||
li.Selected = true;
|
||||
@@ -120,7 +134,8 @@ namespace umbraco.presentation.developer.packages
|
||||
|
||||
/*Langauges */
|
||||
Language[] umbLanguages = Language.getAll;
|
||||
foreach (Language l in umbLanguages) {
|
||||
foreach (Language l in umbLanguages)
|
||||
{
|
||||
ListItem li = new ListItem(l.FriendlyName, l.id.ToString());
|
||||
if (pack.Languages.Contains(l.id.ToString()))
|
||||
li.Selected = true;
|
||||
@@ -130,7 +145,8 @@ namespace umbraco.presentation.developer.packages
|
||||
|
||||
/*Dictionary Items*/
|
||||
Dictionary.DictionaryItem[] umbDictionary = Dictionary.getTopMostItems;
|
||||
foreach (Dictionary.DictionaryItem d in umbDictionary) {
|
||||
foreach (Dictionary.DictionaryItem d in umbDictionary)
|
||||
{
|
||||
|
||||
string liName = d.key;
|
||||
if (d.hasChildren)
|
||||
@@ -146,7 +162,8 @@ namespace umbraco.presentation.developer.packages
|
||||
|
||||
/*Data types */
|
||||
cms.businesslogic.datatype.DataTypeDefinition[] umbDataType = cms.businesslogic.datatype.DataTypeDefinition.GetAll();
|
||||
foreach (cms.businesslogic.datatype.DataTypeDefinition umbDtd in umbDataType) {
|
||||
foreach (cms.businesslogic.datatype.DataTypeDefinition umbDtd in umbDataType)
|
||||
{
|
||||
|
||||
ListItem li = new ListItem(umbDtd.Text, umbDtd.Id.ToString());
|
||||
|
||||
@@ -162,6 +179,12 @@ namespace umbraco.presentation.developer.packages
|
||||
|
||||
packageControlPath.Text = pack.LoadControl;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientTools
|
||||
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadPackages>().Tree.Alias)
|
||||
.SyncTree("-1,init," + loadPackages.PACKAGE_TREE_PREFIX + createdPackage.Data.Id, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
<%@ Page ValidateRequest="false" Language="c#" MasterPageFile="../../masterpages/umbracoPage.Master"
|
||||
CodeBehind="editPython.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.developer.editPython" %>
|
||||
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
|
||||
<asp:Content ID="DocTypeContent" ContentPlaceHolderID="DocType" runat="server">
|
||||
<!DOCTYPE html>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="cp0" runat="server" ContentPlaceHolderID="head">
|
||||
<script type="text/javascript">
|
||||
function closeErrorDiv() {
|
||||
jQuery('#errorDiv').hide();
|
||||
}
|
||||
|
||||
function doSubmit() {
|
||||
closeErrorDiv();
|
||||
|
||||
var codeVal = jQuery('#<%= pythonSource.ClientID %>').val();
|
||||
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof (CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
|
||||
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveDLRScript(jQuery('#<%= pythonFileName.ClientID %>').val(), '<%= pythonFileName.Text %>', codeVal, document.getElementById('<%= SkipTesting.ClientID %>').checked, submitSucces, submitFailure);
|
||||
}
|
||||
|
||||
function submitSucces(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', 'Saving scripting file failed', '');
|
||||
jQuery('#errorDiv').html('<p><a href="#" style="position: absolute; right: 10px; top: 10px;" onclick=\'closeErrorDiv()\'>Hide Errors</a><strong>Error occured</strong></p><p>' + t + '</p>');
|
||||
jQuery('#errorDiv').slideDown('fast');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', 'Scripting file saved', '')
|
||||
}
|
||||
}
|
||||
|
||||
function submitFailure(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('warning', 'Scripting file could not be saved', '')
|
||||
}
|
||||
|
||||
|
||||
function showError() {
|
||||
var id = "#errorDiv";
|
||||
if (jQuery(id).is(":visible")) {
|
||||
jQuery(id).hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="cp1" runat="server" ContentPlaceHolderID="body">
|
||||
<cc1:UmbracoPanel ID="UmbracoPanel1" runat="server" Text="Edit scripting file" Height="300"
|
||||
Width="600">
|
||||
<cc1:Pane ID="Pane1" runat="server" Style="margin-bottom: 10px;">
|
||||
<cc1:PropertyPanel ID="pp_filename" Text="Filename" runat="server">
|
||||
<asp:TextBox ID="pythonFileName" runat="server" Width="400" CssClass="guiInputText"></asp:TextBox>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_testing" runat="server" Text="Skip testing (ignore errors)">
|
||||
<asp:CheckBox ID="SkipTesting" runat="server"></asp:CheckBox>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_errorMsg" runat="server">
|
||||
<div id="errorDiv" style="position: relative; display: none;" class="error">
|
||||
-</div>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:CodeArea ID="pythonSource" ClientSaveMethod="doSubmit" AutoSuggest="true" CodeBase="Razor" AutoResize="true" OffSetX="47"
|
||||
OffSetY="55" runat="server" />
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
</asp:Content>
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -17,6 +17,7 @@ using Umbraco.Core.IO;
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using umbraco.cms.helpers;
|
||||
using umbraco.uicontrols;
|
||||
|
||||
namespace umbraco.cms.presentation.developer
|
||||
{
|
||||
@@ -28,12 +29,16 @@ namespace umbraco.cms.presentation.developer
|
||||
|
||||
}
|
||||
|
||||
private List<string> allowedExtensions = new List<string>();
|
||||
protected PlaceHolder buttons;
|
||||
protected uicontrols.CodeArea CodeArea1;
|
||||
protected MenuIconI SaveButton;
|
||||
|
||||
private void Page_Load(object sender, System.EventArgs e)
|
||||
private readonly List<string> _allowedExtensions = new List<string>();
|
||||
protected PlaceHolder buttons;
|
||||
protected CodeArea CodeArea1;
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
UmbracoPanel1.hasMenu = true;
|
||||
|
||||
if (!IsPostBack)
|
||||
@@ -48,28 +53,26 @@ namespace umbraco.cms.presentation.developer
|
||||
|
||||
private List<string> validScriptingExtensions()
|
||||
{
|
||||
if (allowedExtensions.Count == 0)
|
||||
if (_allowedExtensions.Count == 0)
|
||||
{
|
||||
foreach (MacroEngineLanguage lang in MacroEngineFactory.GetSupportedUILanguages())
|
||||
{
|
||||
if (!allowedExtensions.Contains(lang.Extension))
|
||||
allowedExtensions.Add(lang.Extension);
|
||||
if (!_allowedExtensions.Contains(lang.Extension))
|
||||
_allowedExtensions.Add(lang.Extension);
|
||||
}
|
||||
}
|
||||
|
||||
return allowedExtensions;
|
||||
return _allowedExtensions;
|
||||
}
|
||||
|
||||
protected override void OnInit(EventArgs e)
|
||||
{
|
||||
InitializeComponent();
|
||||
base.OnInit(e);
|
||||
|
||||
uicontrols.MenuIconI save = UmbracoPanel1.Menu.NewIcon();
|
||||
save.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif";
|
||||
save.OnClickCommand = "doSubmit()";
|
||||
save.AltText = "Save scripting File";
|
||||
save.ID = "save";
|
||||
SaveButton = UmbracoPanel1.Menu.NewIcon();
|
||||
SaveButton.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif";
|
||||
SaveButton.AltText = "Save scripting File";
|
||||
SaveButton.ID = "save";
|
||||
|
||||
// Add source and filename
|
||||
String file = IOHelper.MapPath(SystemDirectories.MacroScripts + "/" + Request.QueryString["file"]);
|
||||
@@ -89,17 +92,84 @@ namespace umbraco.cms.presentation.developer
|
||||
pythonSource.Text = S;
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.Load += new System.EventHandler(this.Page_Load);
|
||||
}
|
||||
|
||||
protected override void OnPreRender(EventArgs e)
|
||||
{
|
||||
base.OnPreRender(e);
|
||||
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.WebServices) + "/codeEditorSave.asmx"));
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.WebServices) + "/legacyAjaxCalls.asmx"));
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.WebServices) + "/legacyAjaxCalls.asmx"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UmbracoPanel1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.UmbracoPanel UmbracoPanel1;
|
||||
|
||||
/// <summary>
|
||||
/// Pane1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.Pane Pane1;
|
||||
|
||||
/// <summary>
|
||||
/// pp_filename control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_filename;
|
||||
|
||||
/// <summary>
|
||||
/// pythonFileName control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.TextBox pythonFileName;
|
||||
|
||||
/// <summary>
|
||||
/// pp_testing control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_testing;
|
||||
|
||||
/// <summary>
|
||||
/// SkipTesting control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.CheckBox SkipTesting;
|
||||
|
||||
/// <summary>
|
||||
/// pp_errorMsg control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_errorMsg;
|
||||
|
||||
/// <summary>
|
||||
/// pythonSource control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.CodeArea pythonSource;
|
||||
}
|
||||
}
|
||||
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace umbraco.cms.presentation.developer {
|
||||
|
||||
|
||||
public partial class editPython {
|
||||
|
||||
/// <summary>
|
||||
/// UmbracoPanel1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.UmbracoPanel UmbracoPanel1;
|
||||
|
||||
/// <summary>
|
||||
/// Pane1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.Pane Pane1;
|
||||
|
||||
/// <summary>
|
||||
/// pp_filename control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_filename;
|
||||
|
||||
/// <summary>
|
||||
/// pythonFileName control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.TextBox pythonFileName;
|
||||
|
||||
/// <summary>
|
||||
/// pp_testing control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_testing;
|
||||
|
||||
/// <summary>
|
||||
/// SkipTesting control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.CheckBox SkipTesting;
|
||||
|
||||
/// <summary>
|
||||
/// pp_errorMsg control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_errorMsg;
|
||||
|
||||
/// <summary>
|
||||
/// pythonSource control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::umbraco.uicontrols.CodeArea pythonSource;
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,11 @@ using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Xml;
|
||||
using System.Xml.Xsl;
|
||||
using Umbraco.Core.IO;
|
||||
using umbraco.BasePages;
|
||||
using umbraco.uicontrols;
|
||||
using System.Net;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using umbraco.IO;
|
||||
using umbraco.cms.helpers;
|
||||
|
||||
namespace umbraco.cms.presentation.developer
|
||||
@@ -25,9 +25,10 @@ namespace umbraco.cms.presentation.developer
|
||||
{
|
||||
CurrentApp = BusinessLogic.DefaultApps.developer.ToString();
|
||||
}
|
||||
|
||||
protected PlaceHolder buttons;
|
||||
|
||||
|
||||
protected MenuIconI SaveButton;
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
@@ -44,28 +45,20 @@ namespace umbraco.cms.presentation.developer
|
||||
|
||||
}
|
||||
|
||||
#region Web Form Designer generated code
|
||||
|
||||
protected override void OnInit(EventArgs e)
|
||||
{
|
||||
//
|
||||
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
|
||||
//
|
||||
InitializeComponent();
|
||||
{
|
||||
base.OnInit(e);
|
||||
|
||||
|
||||
uicontrols.MenuIconI save = UmbracoPanel1.Menu.NewIcon();
|
||||
save.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif";
|
||||
save.OnClickCommand = "doSubmit()";
|
||||
save.AltText = "Save Xslt File";
|
||||
save.ID = "save";
|
||||
|
||||
SaveButton = UmbracoPanel1.Menu.NewIcon();
|
||||
SaveButton.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif";
|
||||
SaveButton.AltText = "Save Xslt File";
|
||||
SaveButton.ID = "save";
|
||||
|
||||
UmbracoPanel1.Menu.InsertSplitter();
|
||||
|
||||
uicontrols.MenuIconI tmp = UmbracoPanel1.Menu.NewIcon();
|
||||
tmp.ImageURL = umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/images/editor/insField.GIF";
|
||||
tmp.OnClickCommand = ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/developer/xslt/xsltinsertvalueof.aspx?objectId=" + editorSource.ClientID, "Insert value", 750, 250);
|
||||
var tmp = UmbracoPanel1.Menu.NewIcon();
|
||||
tmp.ImageURL = IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/images/editor/insField.GIF";
|
||||
tmp.OnClickCommand = ClientTools.Scripts.OpenModalWindow(IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/developer/xslt/xsltinsertvalueof.aspx?objectId=" + editorSource.ClientID, "Insert value", 750, 250);
|
||||
//"umbracoInsertField(document.getElementById('editorSource'), 'xsltInsertValueOf', '','felt', 750, 230, '');";
|
||||
tmp.AltText = "Insert xslt:value-of";
|
||||
|
||||
@@ -104,7 +97,7 @@ namespace umbraco.cms.presentation.developer
|
||||
|
||||
|
||||
// Add source and filename
|
||||
String file = IOHelper.MapPath(SystemDirectories.Xslt + "/" + Request.QueryString["file"]);
|
||||
var file = IOHelper.MapPath(SystemDirectories.Xslt + "/" + Request.QueryString["file"]);
|
||||
|
||||
// validate file
|
||||
IOHelper.ValidateEditPath(file, SystemDirectories.Xslt);
|
||||
@@ -129,19 +122,10 @@ namespace umbraco.cms.presentation.developer
|
||||
{
|
||||
base.OnPreRender(e);
|
||||
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.Webservices) + "/codeEditorSave.asmx"));
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.Webservices) + "/legacyAjaxCalls.asmx"));
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.WebServices) + "/codeEditorSave.asmx"));
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.WebServices) + "/legacyAjaxCalls.asmx"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// JsInclude1 control.
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<body>
|
||||
<form id="Form1" method="post" runat="server">
|
||||
<cc1:UmbracoPanel Style="text-align: left;" ID="Panel1" runat="server" Height="347px"
|
||||
Width="340px" Text="Umbraco 4 login" AutoResize="false">
|
||||
Width="340px" Text="Umbraco login" AutoResize="false">
|
||||
<div style="padding: 70px 0px 0px 0px;">
|
||||
<p style="margin: 0px; padding: 5px 0px 20px 0px; color: #999">
|
||||
<asp:Literal ID="TopText" runat="server"></asp:Literal>
|
||||
|
||||
@@ -37,11 +37,14 @@ namespace umbraco.cms.presentation.settings
|
||||
new ServiceReference(IOHelper.ResolveUrl(SystemDirectories.Webservices + "/legacyAjaxCalls.asmx")));
|
||||
}
|
||||
|
||||
protected string TemplateTreeSyncPath { get; private set; }
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
MasterTemplate.Attributes.Add("onchange", "changeMasterPageFile()");
|
||||
|
||||
TemplateTreeSyncPath = "-1,init," + _template.Path.Replace("-1,", "");
|
||||
|
||||
if (!IsPostBack)
|
||||
{
|
||||
MasterTemplate.Items.Add(new ListItem(ui.Text("none"), "0"));
|
||||
@@ -70,7 +73,7 @@ namespace umbraco.cms.presentation.settings
|
||||
|
||||
ClientTools
|
||||
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadTemplates>().Tree.Alias)
|
||||
.SyncTree("-1,init," + _template.Path.Replace("-1,", ""), false);
|
||||
.SyncTree(TemplateTreeSyncPath, false);
|
||||
|
||||
LoadScriptingTemplates();
|
||||
LoadMacros();
|
||||
|
||||
@@ -11,10 +11,11 @@ using System.Web.UI.WebControls;
|
||||
using System.Web.UI.HtmlControls;
|
||||
using System.IO;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using umbraco.IO;
|
||||
using System.Linq;
|
||||
using umbraco.cms.helpers;
|
||||
using umbraco.uicontrols;
|
||||
|
||||
namespace umbraco.cms.presentation.settings.scripts
|
||||
{
|
||||
@@ -36,18 +37,20 @@ namespace umbraco.cms.presentation.settings.scripts
|
||||
protected umbraco.uicontrols.PropertyPanel pp_name;
|
||||
protected umbraco.uicontrols.PropertyPanel pp_path;
|
||||
|
||||
protected MenuIconI SaveButton;
|
||||
|
||||
private string file;
|
||||
|
||||
protected void Page_Load(object sender, System.EventArgs e)
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
|
||||
base.OnLoad(e);
|
||||
NameTxt.Text = file;
|
||||
|
||||
string path = "";
|
||||
if (file.StartsWith("~/"))
|
||||
path = Umbraco.Core.IO.IOHelper.ResolveUrl(file);
|
||||
path = Umbraco.Core.IO.IOHelper.ResolveUrl(file);
|
||||
else
|
||||
path = Umbraco.Core.IO.IOHelper.ResolveUrl(Umbraco.Core.IO.SystemDirectories.Scripts + "/" + file);
|
||||
path = Umbraco.Core.IO.IOHelper.ResolveUrl(Umbraco.Core.IO.SystemDirectories.Scripts + "/" + file);
|
||||
|
||||
|
||||
lttPath.Text = "<a target='_blank' href='" + path + "'>" + path + "</a>";
|
||||
@@ -60,19 +63,19 @@ namespace umbraco.cms.presentation.settings.scripts
|
||||
}
|
||||
|
||||
var dirs = Umbraco.Core.IO.SystemDirectories.Scripts;
|
||||
if (Umbraco.Core.Configuration.UmbracoSettings.DefaultRenderingEngine == RenderingEngine.Mvc)
|
||||
if (Umbraco.Core.Configuration.UmbracoSettings.DefaultRenderingEngine == RenderingEngine.Mvc)
|
||||
dirs += "," + Umbraco.Core.IO.SystemDirectories.MvcViews;
|
||||
|
||||
// validate file
|
||||
Umbraco.Core.IO.IOHelper.ValidateEditPath(Umbraco.Core.IO.IOHelper.MapPath(path), dirs.Split(','));
|
||||
|
||||
Umbraco.Core.IO.IOHelper.ValidateEditPath(Umbraco.Core.IO.IOHelper.MapPath(path), dirs.Split(','));
|
||||
|
||||
// validate extension
|
||||
Umbraco.Core.IO.IOHelper.ValidateFileExtension(Umbraco.Core.IO.IOHelper.MapPath(path), exts);
|
||||
Umbraco.Core.IO.IOHelper.ValidateFileExtension(Umbraco.Core.IO.IOHelper.MapPath(path), exts);
|
||||
|
||||
|
||||
StreamReader SR;
|
||||
string S;
|
||||
SR = File.OpenText(Umbraco.Core.IO.IOHelper.MapPath(path));
|
||||
SR = File.OpenText(Umbraco.Core.IO.IOHelper.MapPath(path));
|
||||
S = SR.ReadToEnd();
|
||||
SR.Close();
|
||||
|
||||
@@ -91,25 +94,22 @@ namespace umbraco.cms.presentation.settings.scripts
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Web Form Designer generated code
|
||||
override protected void OnInit(EventArgs e)
|
||||
{
|
||||
base.OnInit(e);
|
||||
|
||||
file = Request.QueryString["file"].TrimStart('/');
|
||||
|
||||
//need to change the editor type if it is XML
|
||||
if (file.EndsWith("xml"))
|
||||
editorSource.CodeBase = umbraco.uicontrols.CodeArea.EditorType.XML;
|
||||
editorSource.CodeBase = uicontrols.CodeArea.EditorType.XML;
|
||||
else if (file.EndsWith("master"))
|
||||
editorSource.CodeBase = umbraco.uicontrols.CodeArea.EditorType.HTML;
|
||||
editorSource.CodeBase = uicontrols.CodeArea.EditorType.HTML;
|
||||
|
||||
uicontrols.MenuIconI save = Panel1.Menu.NewIcon();
|
||||
save.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif";
|
||||
save.OnClickCommand = "doSubmit()";
|
||||
save.AltText = "Save File";
|
||||
save.ID = "save";
|
||||
SaveButton = Panel1.Menu.NewIcon();
|
||||
SaveButton.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif";
|
||||
SaveButton.AltText = "Save File";
|
||||
SaveButton.ID = "save";
|
||||
|
||||
if (editorSource.CodeBase == uicontrols.CodeArea.EditorType.HTML)
|
||||
{
|
||||
@@ -117,19 +117,19 @@ namespace umbraco.cms.presentation.settings.scripts
|
||||
Panel1.Menu.InsertSplitter();
|
||||
uicontrols.MenuIconI umbField = Panel1.Menu.NewIcon();
|
||||
umbField.ImageURL = UmbracoPath + "/images/editor/insField.gif";
|
||||
umbField.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/dialogs/umbracoField.aspx?objectId=" + editorSource.ClientID + "&tagName=UMBRACOGETDATA", ui.Text("template", "insertPageField"), 640, 550);
|
||||
umbField.OnClickCommand = BasePages.ClientTools.Scripts.OpenModalWindow(IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/dialogs/umbracoField.aspx?objectId=" + editorSource.ClientID + "&tagName=UMBRACOGETDATA", ui.Text("template", "insertPageField"), 640, 550);
|
||||
umbField.AltText = ui.Text("template", "insertPageField");
|
||||
|
||||
// TODO: Update icon
|
||||
uicontrols.MenuIconI umbDictionary = Panel1.Menu.NewIcon();
|
||||
umbDictionary.ImageURL = GlobalSettings.Path + "/images/editor/dictionaryItem.gif";
|
||||
umbDictionary.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/dialogs/umbracoField.aspx?objectId=" + editorSource.ClientID + "&tagName=UMBRACOGETDICTIONARY", ui.Text("template", "insertDictionaryItem"), 640, 550);
|
||||
umbDictionary.OnClickCommand = BasePages.ClientTools.Scripts.OpenModalWindow(IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/dialogs/umbracoField.aspx?objectId=" + editorSource.ClientID + "&tagName=UMBRACOGETDICTIONARY", ui.Text("template", "insertDictionaryItem"), 640, 550);
|
||||
umbDictionary.AltText = "Insert umbraco dictionary item";
|
||||
|
||||
uicontrols.MenuIconI umbMacro = Panel1.Menu.NewIcon();
|
||||
umbMacro.ImageURL = UmbracoPath + "/images/editor/insMacro.gif";
|
||||
umbMacro.AltText = ui.Text("template", "insertMacro");
|
||||
umbMacro.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/dialogs/editMacro.aspx?objectId=" + editorSource.ClientID, ui.Text("template", "insertMacro"), 470, 530);
|
||||
umbMacro.OnClickCommand = BasePages.ClientTools.Scripts.OpenModalWindow(IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/dialogs/editMacro.aspx?objectId=" + editorSource.ClientID, ui.Text("template", "insertMacro"), 470, 530);
|
||||
|
||||
// Help
|
||||
Panel1.Menu.InsertSplitter();
|
||||
@@ -141,23 +141,8 @@ namespace umbraco.cms.presentation.settings.scripts
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.Load += new System.EventHandler(Page_Load);
|
||||
InitializeComponent();
|
||||
base.OnInit(e);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void OnPreRender(EventArgs e)
|
||||
{
|
||||
@@ -165,7 +150,6 @@ namespace umbraco.cms.presentation.settings.scripts
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("../webservices/codeEditorSave.asmx"));
|
||||
ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("../webservices/legacyAjaxCalls.asmx"));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
<%@ Page Language="c#" MasterPageFile="../../masterpages/umbracoPage.Master" Codebehind="editstylesheet.aspx.cs" AutoEventWireup="True"
|
||||
Inherits="umbraco.cms.presentation.settings.stylesheet.editstylesheet" ValidateRequest="False" %>
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server">
|
||||
<script type="text/javascript">
|
||||
|
||||
function doSubmit() {
|
||||
var codeVal = jQuery('#<%= editorSource.ClientID %>').val();
|
||||
//if CodeMirror is not defined, then the code editor is disabled.
|
||||
if (typeof(CodeMirror) != "undefined") {
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveCss(jQuery('#<%= NameTxt.ClientID %>').val(), '<%= NameTxt.Text %>', codeVal, '<%= Request.QueryString["id"] %>', submitSucces, submitFailure);
|
||||
}
|
||||
|
||||
function submitSucces(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "CssErrorHeader") %>', 'Please make sure that you have permissions set correctly');
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', '<%= umbraco.ui.Text("speechBubbles", "cssSavedHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "cssSavedText") %>')
|
||||
}
|
||||
}
|
||||
function submitFailure(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', '<%= umbraco.ui.Text("speechBubbles", "CssErrorHeader") %>', '<%= umbraco.ui.Text("speechBubbles", "CssErrorText") %>')
|
||||
}
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
<cc1:UmbracoPanel ID="Panel1" runat="server" CssClass="panel" hasMenu="true">
|
||||
<cc1:Pane ID="Pane7" CssClass="pane" runat="server">
|
||||
<cc1:PropertyPanel ID="pp_name" runat="server">
|
||||
<asp:TextBox ID="NameTxt" Width="350px" runat="server"></asp:TextBox>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_path" runat="server">
|
||||
<asp:Literal ID="lttPath" runat="server"></asp:Literal>
|
||||
</cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel id="pp_source" runat="server">
|
||||
<cc1:CodeArea id="editorSource" CodeBase="Css" ClientSaveMethod="doSubmit" OffSetX="37" OffSetY="54" AutoResize="true" runat="server" />
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
</cc1:UmbracoPanel>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function () {
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
</script>
|
||||
|
||||
</asp:Content>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user