Compare commits

...

46 Commits

Author SHA1 Message Date
Sebastiaan Janssen b4d88b0361 U4-2279 TryGetRouteDefinitionFromAncestorViewContexts has infinite loop when
currentContext doesnt contain umbraco-route-def
2013-05-29 03:44:01 -02:00
Sebastiaan Janssen b41cf37dd5 U4-2290 Notifications do not handle fields that have null values. 2013-05-29 03:42:20 -02:00
Sebastiaan Janssen 7ecbc3b391 Fixes U4-2248 Spelling error in back office 2013-05-28 15:44:59 -02:00
Sebastiaan Janssen 13a86624ff Fixes U4-2248 Spelling error in back office 2013-05-28 15:39:12 -02:00
dmilic f36ab37f6a Fix for the U4-2229 issue - broken PublishWithSubs method 2013-05-13 15:49:59 -12:00
Sebastiaan Janssen aeff33d0a6 Bump version number 2013-05-28 15:17:55 -02:00
Sebastiaan Janssen d3ed90c23e Some fixes & refactor 2013-05-28 12:10:29 -02:00
Sebastiaan Janssen db4b93dbc3 Update test because of new added restextension (EmbedMediaService) 2013-05-27 10:21:14 -02:00
Sebastiaan Janssen 562851b93e Possible fix for U4-2251 TreeDataService throws JSON JavaScriptSerializer. The
length of the string exceeds the value set on the maxJsonLength property
2013-05-27 09:59:02 -02:00
Sebastiaan Janssen f5bf05a6f5 Move embed media service from webservices dll into it's own /base class 2013-05-27 07:19:42 -02:00
Sebastiaan Janssen e50569597b Minor update to legacy ajax calls 2013-05-27 06:10:04 -02:00
Sebastiaan Janssen 071f3dcc01 Fix javascript error with the speechbubble 2013-05-27 06:05:13 -02:00
Shannon Deminick 834d04f8ed Fixes: #U4-1469, #U4-1156 2013-05-14 14:18:41 -10:00
Sebastiaan Janssen 4863e657df Fixes U4-2226 Javascript error "tinyMCE is undefined" in IE - THANKS Adriano Buscema! 2013-05-13 13:42:57 -02:00
Sebastiaan Janssen 53e4308c29 Fixes U4-2205 Log.GetLogItems(LogTypes, DateTime) fails with 'Conversion failed
when converting the nvarchar value 'Custom' to data type int'
2013-05-10 08:44:47 -02:00
Shannon Deminick 41e87fca98 Fixes macro tree syncing 2013-05-08 17:04:51 -10:00
Shannon Deminick f23c6c53cc Fixes up created package tree sync. 2013-05-08 17:11:50 -10:00
Sebastiaan Janssen 25be0621b2 Whoops, connection string doesn't contain the datalayer here 2013-05-08 13:14:02 -02:00
Sebastiaan Janssen d5d00553b4 Fixed U4-2176 MySql Dashboard error for 4.11 as well 2013-05-08 08:09:13 -02:00
Shannon Deminick ca99319ead Fixes: #U4-644 - DynamicNode and MVC don't output RTE values for media 2013-05-06 15:09:24 -10:00
Sebastiaan Janssen 09e31d6595 Fixes U4-2179 Error with GetChildNodes after upgrade to Umbraco 6.0.5 from
Umbraco 6.0.0
2013-05-06 12:06:45 -02:00
Robert Stocks 6d66fc6cb8 Remove extra space in name of http module in web.config 2013-05-03 07:24:28 -01:00
Shannon Deminick f0cacf0d52 Fixed app_code assembly check. 2013-05-05 23:03:31 -10:00
Shannon Deminick d501fcb679 Fixes TypeFinder issue but retains the improved performance. Adds TypeHelper tests. 2013-05-05 22:57:41 -10:00
Shannon Deminick f5994d8442 Fixes up async methods in ContentTypeControlNew to ensure that the UmbracoContext is current since
the actions might run on different threads and therefore some event handlers might need access to the context.
2013-05-04 19:33:49 -10:00
Shannon Deminick 4295cba915 Updated unit tests for TypeFinder - this shows the issue with the new refactored performance changes. 2013-05-04 18:12:02 -10:00
Sebastiaan Janssen 2170380f7b Opening new branch 2013-05-01 13:07:53 -02:00
Sebastiaan Janssen 43b2a2185e Fix unit test 2013-05-01 13:02:09 -02:00
Sebastiaan Janssen bcb90d64a5 Fixes U4-1136 Class in MediaPickerDataType.cs wrongly named MemberPickerDataType
+ a bit of code cleanup
2013-05-01 05:32:29 -02:00
Shannon Deminick 6d994f48ac merged in patch for TypeFinder changes 2013-04-29 19:55:44 -10:00
Shannon Deminick ad06aded1b Removed strange old legacy config section that never did anything 2013-04-29 12:08:36 -10:00
Sebastiaan Janssen 25eea8d599 Re-add internals visible to umbraco.webservices in case people install the
seperate project.
2013-04-29 11:17:32 -02:00
Sebastiaan Janssen 22498649b1 Merge 2013-04-29 10:36:30 -02:00
Sebastiaan Janssen 25ce7baa7d Removing the umbraco.webservices project 2013-04-29 10:36:11 -02:00
Shannon Deminick 528209f8da instantly improve performance by 45% for regenerating xml structures for documents when a doc type alias changes
or when a doc type property alias is changed or a doc type property is removed.
2013-04-28 13:37:36 -10:00
Shannon Deminick 385d6396b0 disables auto-complete on the login page. 2013-04-25 13:28:47 -10:00
Shannon Deminick 46858af1ed Ensures user cookie is encrypted, removes ASP.Net headers from being returned in our response. Ensures
that our auth cookie is httponly.
2013-04-25 13:25:25 -10:00
Shannon Deminick 34163625fe Merge with 4.11.7 - cmsContentXml fixes 2013-04-25 12:20:06 -10:00
Sebastiaan Janssen 461f032777 Added tag release-4.11.7 for changeset ce47176bc6b9 2013-04-25 11:17:07 -02:00
Sebastiaan Janssen a3347c0037 Opening new branch 2013-04-25 11:14:46 -02:00
Sebastiaan Janssen f3835d1ca3 Closing branch 4.11.7 2013-04-25 11:14:09 -02:00
Shannon Deminick d30c4791fe fixed a documentation error 2013-04-24 15:46:38 -10:00
Shannon Deminick 7ee9b9ebcc Fixes: #U4-2144 - ensures that the xml is re-gen'd when a content type alias is changed or a content type property is removed.
Also had to change the property type deletion to be async as well since it might be long running to re-gen the xml.
2013-04-24 15:31:36 -10:00
Shannon Deminick b4caf109f7 Working on #U4-2144 - ensures that xml is re-gen'd when a property alias is changed. 2013-04-24 15:17:20 -10:00
Shannon Deminick 0e8ffe528a Fixes: #U4-2149 - updates the logic for changing aliases for any content type. Now if an alias changes for any content type, the
xml is regenerated for any entity that is of that content type. For DocumentType's this is slightly different because we regenerate
the xml for the doc type and any document of the doc type's descendant types.
2013-04-24 14:57:20 -10:00
Shannon Deminick a8029d1dc5 Fixes: #U4-1772 - ensures that when changing a doc type alias that we only rebuild the data in the cmsContentXml table for Document types, not media types or member types, now we need
to fix all of the other bugs assocated with cmsContentXml table and alias changes.
2013-04-24 13:19:30 -10:00
87 changed files with 2052 additions and 2950 deletions
+1
View File
@@ -28,3 +28,4 @@ e4d0c7e740555d8707ba71f55a623a3f96da8e65 Release-4.11.3.1
0000000000000000000000000000000000000000 Release-4.11.3.1
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
ce47176bc6b9298741783e20f1fe2672c811f744 release-4.11.7
+1 -1
View File
@@ -1,5 +1,5 @@
@ECHO OFF
set version=4.11.7
set version=4.11.9
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%version%
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Code\dummy.txt
+1 -28
View File
@@ -172,7 +172,7 @@
<!--
Now, because of all the circular dependencies we need to build those projects and have them dump their DLLs/assets out to the same folder. Really wish this wasn't the case!
These are: umbraco.editorControls umbraco.webservices umbraco.MacroEngines
These are: umbraco.editorControls umbraco.MacroEngines
Each of these projects has a post build to put their stuff in the correct location based on the solution and unfortunately for us each
of these projects references the web application! So if we specify an OutDir parameter it will also trigger a web deploy and chuck another
@@ -204,33 +204,6 @@
<Copy SourceFiles="@(EditorControlsDll)"
DestinationFolder="$(WebAppFolder)\bin" OverwriteReadOnlyFiles="True"/>
<!-- WEBSERVICES -->
<Message Text="Compiling webservices project" Importance="high" />
<MSBuild Projects="..\src\umbraco.webservices\umbraco.webservices.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
</MSBuild>
<ItemGroup>
<WebServicesDll Include="..\src\umbraco.webservices\bin\$(BuildConfiguration)\umbraco.webservices.dll"/>
<WebServicesASMX Include="..\src\umbraco.webservices\*.asmx"/>
</ItemGroup>
<Copy SourceFiles="@(WebServicesDll)"
DestinationFolder="$(SolutionBinFolder)" OverwriteReadOnlyFiles="True"/>
<Copy SourceFiles="@(WebServicesDll)"
DestinationFolder="$(WebAppFolder)\bin" OverwriteReadOnlyFiles="True"/>
<Copy SourceFiles="@(WebServicesASMX)"
DestinationFolder="$(WebAppFolder)\umbraco\webservices\api" OverwriteReadOnlyFiles="True"/>
<!-- SQLCE4UMBRACO -->
<!--<Message Text="Compiling SQLCE4Umbraco project" Importance="high" />
<MSBuild Projects="..\src\SQLCE4Umbraco\SQLCE4Umbraco.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
</MSBuild>
<ItemGroup>
<SQLCE4UmbracoDll Include="..\src\SQLCE4Umbraco\bin\$(BuildConfiguration)\SQLCE4Umbraco.dll" />
</ItemGroup>
<Copy SourceFiles="@(SQLCE4UmbracoDll)"
DestinationFolder="$(SolutionBinFolder)" OverwriteReadOnlyFiles="True"/>
<Copy SourceFiles="@(SQLCE4UmbracoDll)"
DestinationFolder="$(WebAppFolder)\bin" OverwriteReadOnlyFiles="True"/>-->
<!-- DONE -->
<Message Text="Finished compiling projects" Importance="high" />
</Target>
-1
View File
@@ -51,7 +51,6 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.dll" target="lib\umbraco.macroRenderings.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<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.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" />
+35 -1
View File
@@ -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>
@@ -28,7 +28,7 @@ namespace Umbraco.Core.Configuration
#region Private static fields
// CURRENT UMBRACO VERSION ID
private const string CurrentUmbracoVersion = "4.11.7";
private const string CurrentUmbracoVersion = "4.11.9";
private static readonly object Locker = new object();
//make this volatile so that we can ensure thread safety with a double check lock
+2 -49
View File
@@ -679,57 +679,10 @@ namespace Umbraco.Core.Dynamics
return test(this) ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
}
[Obsolete("Use XmlHelper.StripDashesInElementOrAttributeNames instead")]
public static string StripDashesInElementOrAttributeNames(string xml)
{
using (MemoryStream outputms = new MemoryStream())
{
using (TextWriter outputtw = new StreamWriter(outputms))
{
using (MemoryStream ms = new MemoryStream())
{
using (TextWriter tw = new StreamWriter(ms))
{
tw.Write(xml);
tw.Flush();
ms.Position = 0;
using (TextReader tr = new StreamReader(ms))
{
bool IsInsideElement = false, IsInsideQuotes = false;
int ic = 0;
while ((ic = tr.Read()) != -1)
{
if (ic == (int)'<' && !IsInsideQuotes)
{
if (tr.Peek() != (int)'!')
{
IsInsideElement = true;
}
}
if (ic == (int)'>' && !IsInsideQuotes)
{
IsInsideElement = false;
}
if (ic == (int)'"')
{
IsInsideQuotes = !IsInsideQuotes;
}
if (!IsInsideElement || ic != (int)'-' || IsInsideQuotes)
{
outputtw.Write((char)ic);
}
}
}
}
}
outputtw.Flush();
outputms.Position = 0;
using (TextReader outputtr = new StreamReader(outputms))
{
return outputtr.ReadToEnd();
}
}
}
return XmlHelper.StripDashesInElementOrAttributeNames(xml);
}
@@ -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)
{
@@ -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 -1
View File
@@ -25,11 +25,11 @@ using System.Runtime.InteropServices;
[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")]
+179 -65
View File
@@ -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);
@@ -237,42 +236,72 @@ namespace Umbraco.Core
"umbraco.interfaces,",
"umbraco.providers,",
"Umbraco.Web.UI,",
"umbraco.webservices",
"umbraco.webservices",
"Lucene.",
"Examine,",
"Examine."
};
/// <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>
@@ -296,7 +325,7 @@ namespace Umbraco.Core
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetAssignablesFromType<T>(assemblies, onlyConcreteClasses);
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
@@ -323,32 +352,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>
@@ -374,29 +421,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)
@@ -411,7 +525,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());
}
+108 -7
View File
@@ -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)
+1 -1
View File
@@ -150,7 +150,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" />
+130 -10
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
@@ -16,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>
@@ -71,6 +137,60 @@ namespace Umbraco.Core
}
}
}
public static string StripDashesInElementOrAttributeNames(string xml)
{
using (var outputms = new MemoryStream())
{
using (TextWriter outputtw = new StreamWriter(outputms))
{
using (var ms = new MemoryStream())
{
using (var tw = new StreamWriter(ms))
{
tw.Write(xml);
tw.Flush();
ms.Position = 0;
using (var tr = new StreamReader(ms))
{
bool IsInsideElement = false, IsInsideQuotes = false;
int ic = 0;
while ((ic = tr.Read()) != -1)
{
if (ic == (int)'<' && !IsInsideQuotes)
{
if (tr.Peek() != (int)'!')
{
IsInsideElement = true;
}
}
if (ic == (int)'>' && !IsInsideQuotes)
{
IsInsideElement = false;
}
if (ic == (int)'"')
{
IsInsideQuotes = !IsInsideQuotes;
}
if (!IsInsideElement || ic != (int)'-' || IsInsideQuotes)
{
outputtw.Write((char)ic);
}
}
}
}
}
outputtw.Flush();
outputms.Position = 0;
using (TextReader outputtr = new StreamReader(outputms))
{
return outputtr.ReadToEnd();
}
}
}
}
/// <summary>
/// Imports a XML node from text.
@@ -78,7 +198,7 @@ namespace Umbraco.Core
/// <param name="text">The text.</param>
/// <param name="xmlDoc">The XML doc.</param>
/// <returns></returns>
internal static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
public static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
{
xmlDoc.LoadXml(text);
return xmlDoc.FirstChild;
@@ -138,7 +258,7 @@ namespace Umbraco.Core
/// <param name="name">The node name.</param>
/// <param name="value">The node value.</param>
/// <returns>A XmlNode</returns>
public static XmlNode AddCDataNode(XmlDocument xd, string name, string value)
public static XmlNode AddCDataNode(XmlDocument xd, string name, string value)
{
var temp = xd.CreateNode(XmlNodeType.Element, name, "");
temp.AppendChild(xd.CreateCDataSection(value));
@@ -150,7 +270,7 @@ namespace Umbraco.Core
/// </summary>
/// <param name="n">The XmlNode.</param>
/// <returns>the value as a string</returns>
internal static string GetNodeValue(XmlNode n)
public static string GetNodeValue(XmlNode n)
{
var value = string.Empty;
if (n == null || n.FirstChild == null)
@@ -166,13 +286,13 @@ namespace Umbraco.Core
/// <returns>
/// <c>true</c> if the specified string appears to be XML; otherwise, <c>false</c>.
/// </returns>
internal static bool CouldItBeXml(string xml)
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;
}
@@ -189,7 +309,7 @@ namespace Umbraco.Core
/// <param name="rootName">Name of the root.</param>
/// <param name="elementName">Name of the element.</param>
/// <returns>Returns an <c>System.Xml.XmlDocument</c> representation of the delimited string data.</returns>
internal static XmlDocument Split(string data, string[] separator, string rootName, string elementName)
public static XmlDocument Split(string data, string[] separator, string rootName, string elementName)
{
return Split(new XmlDocument(), data, separator, rootName, elementName);
}
@@ -203,7 +323,7 @@ namespace Umbraco.Core
/// <param name="rootName">Name of the root node.</param>
/// <param name="elementName">Name of the element node.</param>
/// <returns>Returns an <c>System.Xml.XmlDocument</c> representation of the delimited string data.</returns>
internal static XmlDocument Split(XmlDocument xml, string data, string[] separator, string rootName, string elementName)
public static XmlDocument Split(XmlDocument xml, string data, string[] separator, string rootName, string elementName)
{
// load new XML document.
xml.LoadXml(string.Concat("<", rootName, "/>"));
@@ -232,7 +352,7 @@ namespace Umbraco.Core
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
internal static Dictionary<string, string> GetAttributesFromElement(string tag)
public static Dictionary<string, string> GetAttributesFromElement(string tag)
{
var m =
Regex.Matches(tag, "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"",
@@ -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);
}
+2 -2
View File
@@ -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]
+577 -32
View File
@@ -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(4, typesFound.Count());
Assert.AreEqual(4, 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
}
}
}
+84
View File
@@ -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()
{
}
}
}
+1
View File
@@ -121,6 +121,7 @@
<DependentUpon>ExamineResources.resx</DependentUpon>
</Compile>
<Compile Include="TestHelpers\ExamineHelpers\IndexInitializer.cs" />
<Compile Include="TypeHelperTests.cs" />
<Compile Include="UriUtilityTests.cs" />
<Compile Include="Resolvers\MacroFieldEditorsResolverTests.cs" />
<Compile Include="MacroEngineFactoryTests.cs" />
-11
View File
@@ -252,10 +252,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>
@@ -509,13 +505,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" />
@@ -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 {
+3 -3
View File
@@ -21,7 +21,7 @@
}
body
{
font-size: 11px;
font-size: 11px;
width: 100%;
font-family: Trebuchet MS, verdana, arial, Lucida Grande;
text-align: center;
@@ -70,7 +70,7 @@
<asp:Label ID="username" runat="server" AssociatedControlID="lname"></asp:Label>
</td>
<td>
<asp:TextBox ID="lname" Style="padding-left: 3px; background: url(images/gradientBackground.png);
<asp:TextBox AutoCompleteType="None" autocomplete="off" ID="lname" Style="padding-left: 3px; background: url(images/gradientBackground.png);
_background: none; border-right: #999999 1px solid; border-top: #999999 1px solid;
border-left: #999999 1px solid; border-bottom: #999999 1px solid; width: 180px;"
runat="server"></asp:TextBox>
@@ -85,7 +85,7 @@
<asp:Label ID="password" runat="server" AssociatedControlID="passw"></asp:Label>
</td>
<td>
<asp:TextBox ID="passw" Style="padding-left: 3px; background: url(images/gradientBackground.png);
<asp:TextBox AutoCompleteType="None" autocomplete="off" ID="passw" Style="padding-left: 3px; background: url(images/gradientBackground.png);
_background: none; border-right: #999999 1px solid; border-top: #999999 1px solid;
border-left: #999999 1px solid; border-bottom: #999999 1px solid; width: 180px;"
runat="server" TextMode="Password"></asp:TextBox>
@@ -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" %>
@@ -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'>" +
@@ -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'
});
+10 -7
View File
@@ -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"/>
@@ -81,7 +76,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 -->
@@ -95,7 +90,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 -->
@@ -220,6 +215,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>
+10 -4
View File
@@ -11,6 +11,7 @@ using Umbraco.Core;
using Umbraco.Core.Dynamics;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using UmbracoExamine;
using umbraco;
using umbraco.cms.businesslogic;
using Examine.LuceneEngine.SearchCriteria;
@@ -286,9 +287,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))
@@ -310,7 +311,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>
@@ -435,7 +441,7 @@ namespace Umbraco.Web
ValidateAndSetProperty(valueDictionary, val => SortOrder = int.Parse(val), "sortOrder");
ValidateAndSetProperty(valueDictionary, val => Name = val, "nodeName", "__nodeName");
ValidateAndSetProperty(valueDictionary, val => UrlName = val, "urlName");
ValidateAndSetProperty(valueDictionary, val => DocumentTypeAlias = val, "nodeTypeAlias", "__NodeTypeAlias");
ValidateAndSetProperty(valueDictionary, val => DocumentTypeAlias = val, "nodeTypeAlias", UmbracoContentIndexer.NodeTypeAliasFieldName);
ValidateAndSetProperty(valueDictionary, val => DocumentTypeId = int.Parse(val), "nodeType");
ValidateAndSetProperty(valueDictionary, val => WriterName = val, "writerName");
ValidateAndSetProperty(valueDictionary, val => CreatorName = val, "creatorName", "writerName"); //this is a bit of a hack fix for: U4-1132
@@ -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 -1
View File
@@ -114,7 +114,7 @@ namespace Umbraco.Web.Mvc
else
{
//exit the loop
currentRouteData = null;
currentContext = null;
}
}
return new Attempt<RouteDefinition>(
+1 -1
View File
@@ -29,5 +29,5 @@ using System.Security;
[assembly: InternalsVisibleTo("Umbraco.Tests")]
[assembly: InternalsVisibleTo("umbraco.MacroEngines")]
[assembly: InternalsVisibleTo("umbraco.webservices")]
[assembly: InternalsVisibleTo("umbraco.webservices")]
[assembly: InternalsVisibleTo("Umbraco.Web.UI")]
+3 -5
View File
@@ -1803,6 +1803,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\UmbracoAuthorizedWebService.cs">
@@ -2150,11 +2151,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" />
+4
View File
@@ -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;
@@ -34,6 +35,9 @@ namespace Umbraco.Web
/// <param name="e"></param>
protected void Application_Start(object sender, EventArgs e)
{
//don't output the MVC version header (security)
MvcHandler.DisableMvcResponseHeader = true;
//boot up the application
_bootManager
.Initialize()
+9
View File
@@ -424,6 +424,15 @@ namespace Umbraco.Web
LogHelper.Debug<UmbracoModule>("Total milliseconds for umbraco request to process: " + DateTime.Now.Subtract(UmbracoContext.Current.ObjectCreated).TotalMilliseconds);
}
};
//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
@@ -21,26 +16,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);
@@ -53,9 +42,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);
@@ -67,15 +56,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,"));
}
@@ -84,5 +77,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");
}
}
}
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Examine.Providers;
using Umbraco.Core;
using umbraco.BusinessLogic;
using Examine;
using UmbracoExamine;
@@ -17,32 +19,83 @@ namespace umbraco.presentation.umbraco.Search
public class ExamineEvents : IApplicationStartupHandler
{
private const string RawFieldPrefix = "__Raw_";
public ExamineEvents()
: base()
{
var contentIndexer = ExamineManager.Instance.IndexProviderCollection["InternalIndexer"] as UmbracoContentIndexer;
if (contentIndexer != null)
{
contentIndexer.DocumentWriting += new EventHandler<Examine.LuceneEngine.DocumentWritingEventArgs>(indexer_DocumentWriting);
contentIndexer.GatheringNodeData += ContentIndexerGatheringNodeData;
contentIndexer.DocumentWriting += IndexerDocumentWriting;
}
var memberIndexer = ExamineManager.Instance.IndexProviderCollection["InternalMemberIndexer"] as UmbracoMemberIndexer;
if (memberIndexer != null)
{
memberIndexer.DocumentWriting += new EventHandler<Examine.LuceneEngine.DocumentWritingEventArgs>(indexer_DocumentWriting);
memberIndexer.DocumentWriting += IndexerDocumentWriting;
}
}
/// <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,
@@ -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)
{
@@ -13,6 +13,7 @@ using ClientDependency.Core;
using Umbraco.Core;
using Umbraco.Core.Logging;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using umbraco.cms.helpers;
using umbraco.cms.presentation.Trees;
using umbraco.controls.GenericProperties;
@@ -61,13 +62,14 @@ 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);
int docTypeId = GetDocTypeId();
_contentType = new cms.businesslogic.ContentType(docTypeId);
LoadContentType();
SetupInfoPane();
if (!HideStructure)
@@ -77,12 +79,7 @@ namespace umbraco.controls
SetupGenericPropertiesPane();
SetupTabPane();
}
private int GetDocTypeId()
{
return int.Parse(Request.QueryString["id"]);
}
}
protected void Page_Load(object sender, System.EventArgs e)
{
@@ -124,28 +121,72 @@ 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(SaveClickEventArgs saveArgs, string originalAlias, string originalName)
public SaveAsyncState(
Umbraco.Web.UmbracoContext umbracoContext,
SaveClickEventArgs saveArgs,
string originalAlias,
string originalName,
string[] originalPropertyAliases)
{
UmbracoContext = umbracoContext;
SaveArgs = saveArgs;
OriginalAlias = originalAlias;
OriginalName = originalName;
_originalAlias = originalAlias;
_originalName = originalName;
_originalPropertyAliases = originalPropertyAliases;
}
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; }
private readonly string _originalAlias;
private readonly string _originalName;
private readonly string[] _originalPropertyAliases;
public bool HasAliasChanged(ContentType contentType)
{
return (string.Compare(OriginalAlias, contentType.Alias, StringComparison.OrdinalIgnoreCase) != 0);
return (string.Compare(_originalAlias, contentType.Alias, StringComparison.OrdinalIgnoreCase) != 0);
}
public bool HasNameChanged(ContentType contentType)
{
return (string.Compare(OriginalName, contentType.Text, StringComparison.OrdinalIgnoreCase) != 0);
return (string.Compare(_originalName, contentType.Text, 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;
}
}
@@ -187,6 +228,8 @@ namespace umbraco.controls
//get the args from the async state
var state = (SaveAsyncState)ar.AsyncState;
// reload content type (due to caching)
LoadContentType();
BindDataGenericProperties(true);
// we need to re-bind the alias as the SafeAlias method can have changed it
@@ -221,10 +264,12 @@ namespace umbraco.controls
protected void save_click(object sender, System.Web.UI.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);
}, _contentType.Alias, _contentType.Text, _contentType.PropertyTypes.Select(x => x.Alias).ToArray());
//Add the async operation to the page
Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncSaveOperation, EndAsyncSaveOperation, HandleAsyncSaveTimeout, state));
@@ -234,6 +279,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;
_contentType.Text = txtName.Text;
_contentType.Alias = txtAlias.Text;
_contentType.IconUrl = ddlIcons.SelectedValue;
@@ -245,13 +293,10 @@ namespace umbraco.controls
SaveTabs();
SaveAllowedChildTypes();
// reload content type (due to caching)
_contentType = new ContentType(_contentType.Id);
// 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(_contentType))
if (asyncState.HasAliasChanged(_contentType) || asyncState.HasAnyPropertyAliasChanged(_contentType))
RegenerateXmlCaches();
Trace.Write("ContentTypeControlNew", "task completing");
@@ -261,13 +306,53 @@ namespace umbraco.controls
Page.ExecuteRegisteredAsyncTasks();
}
/// <summary>
/// Loads the current ContentType from the id found in the querystring.
/// The correct type is loaded based on editing location (DocumentType, MediaType or MemberType).
/// </summary>
private void LoadContentType()
{
int docTypeId = int.Parse(Request.QueryString["id"]);
LoadContentType(docTypeId);
}
private void LoadContentType(int docTypeId)
{
//Fairly hacky code to load the ContentType as the real type instead of its base type, so it can be properly saved.
if (Request.Path.ToLowerInvariant().Contains("editnodetypenew.aspx"))
{
_contentType = new DocumentType(docTypeId);
}
else if (Request.Path.ToLowerInvariant().Contains("editmediatype.aspx"))
{
_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);
}
}
/// <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()
{
umbraco.cms.businesslogic.web.Document.RePublishAll();
library.RefreshContent();
_contentType.RebuildXmlStructuresForContent();
//special case for DocumentType's
if (_contentType is DocumentType)
{
library.RefreshContent();
}
}
private void UpdateTreeNode()
@@ -679,12 +764,76 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
PropertyTypes.Controls.Add(new LiteralControl("<div style=\"margin: 10px; padding: 4px; border: 1px solid #ccc;\">No properties defined on this tab. Click on the \"add a new property\" link at the top to create a new property.</div>"));
}
protected void gpw_Delete(object sender, System.EventArgs e)
/// <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)
{
GenericProperties.GenericPropertyWrapper gpw = (GenericProperties.GenericPropertyWrapper)sender;
gpw.GenricPropertyControl.PropertyType.delete();
_contentType = ContentType.GetContentType(_contentType.Id);
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();
this.BindDataGenericProperties(true);
Trace.Write("ContentTypeControlNew", "async operation ended");
//complete it
_asyncDeleteTask.EndInvoke(ar);
}
protected void gpw_Delete(object sender, EventArgs e)
{
var state = new DeleteAsyncState(
Umbraco.Web.UmbracoContext.Current,
(GenericPropertyWrapper)sender);
//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 =>
{
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;
//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();
}
private void SaveProperties(SaveClickEventArgs e)
@@ -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;
@@ -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 = " &nbsp; <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);
}
}
}
@@ -238,7 +238,8 @@ namespace umbraco
/// <returns>Nodes as IEnumerable</returns>
public static IEnumerable<Node> GetDescendantNodes(this Node node, Func<Node, bool> func)
{
return GetDescendantNodes((INode)node, (Func<INode, bool>) func).Cast<Node>();
Func<INode, bool> convertedFunc = x => func((Node)x);
return GetDescendantNodes((INode)node, convertedFunc).Cast<Node>();
}
/// <summary>
@@ -322,7 +323,8 @@ namespace umbraco
/// <returns>Nodes as IEnumerable</returns>
public static IEnumerable<Node> GetChildNodes(this Node node, Func<Node, bool> func)
{
return GetChildNodes((INode)node, (Func<INode, bool>) func).Cast<Node>();
Func<INode, bool> convertedFunc = x => func((Node)x);
return GetChildNodes((INode)node, convertedFunc).Cast<Node>();
}
/// <summary>
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using Umbraco.Web.WebServices;
using umbraco.BasePages;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic;
@@ -25,77 +25,44 @@ namespace umbraco.presentation.umbraco.webservices
public override void ProcessRequest(HttpContext context)
{
//user must be allowed to see content or media
if (!AuthorizeRequest(DefaultApps.content.ToString()) && !AuthorizeRequest(DefaultApps.media.ToString()))
return;
if (BasePage.ValidateUserContextID(BasePage.umbracoUserContextID) == false)
throw new Exception("Client authorization failed. User is not logged in");
//user must be allowed to see content or media
if (AuthorizeRequest(DefaultApps.content.ToString()) == false && AuthorizeRequest(DefaultApps.media.ToString()) == false)
return;
context.Response.ContentType = "text/plain";
_prefix = context.Request.QueryString["q"];
int parentNodeId = Convert.ToInt32(context.Request.QueryString["id"]);
bool showGrandChildren = Convert.ToBoolean(context.Request.QueryString["showchildren"]);
var parentNodeId = Convert.ToInt32(context.Request.QueryString["id"]);
var showGrandChildren = Convert.ToBoolean(context.Request.QueryString["showchildren"]);
string documentAliasFilter = context.Request.QueryString["filter"];
string[] documentAliasFilters = documentAliasFilter.Split(",".ToCharArray());
var documentAliasFilter = context.Request.QueryString["filter"];
var documentAliasFilters = documentAliasFilter.Split(",".ToCharArray());
var parent = new CMSNode(parentNodeId);
CMSNode parent = new CMSNode(parentNodeId);
if (!showGrandChildren)
_nodeCount = 0;
//store children array here because iterating over an Array property object is very inneficient.
var children = parent.Children;
foreach (CMSNode child in children)
{
_nodeCount = 0;
//store children array here because iterating over an Array property object is very inneficient.
var children = parent.Children;
foreach (CMSNode child in children)
{
NodeChildrenCount(child, false, documentAliasFilters);
}
_output = new string[_nodeCount];
_counter = 0;
int level = 1;
//why is there a 2nd iteration of the same thing here?
foreach (CMSNode child in children)
{
AddNode(child, level, showGrandChildren, documentAliasFilters);
}
}
else
{
_nodeCount = 0;
//store children array here because iterating over an Array property object is very inneficient.
var children = parent.Children;
foreach (CMSNode child in children)
{
NodeChildrenCount(child, true, documentAliasFilters);
}
_output = new string[_nodeCount];
_counter = 0;
int level = 1;
foreach (CMSNode child in children)
{
AddNode(child, level, showGrandChildren, documentAliasFilters);
}
NodeChildrenCount(child, showGrandChildren, documentAliasFilters);
}
_output = new string[_nodeCount];
_counter = 0;
int level = 1;
foreach (string item in _output)
foreach (CMSNode child in children)
{
AddNode(child, level, showGrandChildren, documentAliasFilters);
}
foreach (var item in _output)
{
context.Response.Write(item + Environment.NewLine);
}
@@ -103,38 +70,21 @@ namespace umbraco.presentation.umbraco.webservices
private bool ValidNode(string nodeText)
{
if (nodeText.Length >= _prefix.Length)
{
if (nodeText.Substring(0, _prefix.Length).ToLower() == _prefix.ToLower())
{
return true;
}
}
return false;
return nodeText.Length >= _prefix.Length && nodeText.Substring(0, _prefix.Length).ToLower() == _prefix.ToLower();
}
private void NodeChildrenCount(CMSNode node, bool countChildren, string[] documentAliasFilters)
{
if (documentAliasFilters.Length > 0)
{
foreach (string filter in documentAliasFilters)
foreach (var filter in documentAliasFilters)
{
string trimmedFilter = filter.TrimStart(" ".ToCharArray());
var trimmedFilter = filter.TrimStart(" ".ToCharArray());
trimmedFilter = trimmedFilter.TrimEnd(" ".ToCharArray());
if (new Document(node.Id).ContentType.Alias == trimmedFilter || trimmedFilter == string.Empty)
if ((new Document(node.Id).ContentType.Alias == trimmedFilter || trimmedFilter == string.Empty) && ValidNode(node.Text))
{
if (ValidNode(node.Text))
{
_nodeCount += 1;
}
_nodeCount += 1;
}
}
}
@@ -160,28 +110,24 @@ namespace umbraco.presentation.umbraco.webservices
private void AddNode(CMSNode node, int level, bool showGrandChildren, string[] documentAliasFilters)
{
var preText = string.Empty;
string preText = string.Empty;
for (int i = 1; i < level; i++)
for (var i = 1; i < level; i++)
{
preText += "- ";
}
if (documentAliasFilters.Length > 0)
{
foreach (string filter in documentAliasFilters)
foreach (var filter in documentAliasFilters)
{
string trimmedFilter = filter.TrimStart(" ".ToCharArray());
var trimmedFilter = filter.TrimStart(" ".ToCharArray());
trimmedFilter = trimmedFilter.TrimEnd(" ".ToCharArray());
if (new Document(node.Id).ContentType.Alias == trimmedFilter || trimmedFilter == string.Empty)
if ((new Document(node.Id).ContentType.Alias == trimmedFilter || trimmedFilter == string.Empty) && ValidNode(node.Text))
{
if (ValidNode(node.Text))
{
_output[_counter] = preText + node.Text + " [" + node.Id + "]";
_counter++;
}
_output[_counter] = preText + node.Text + " [" + node.Id + "]";
_counter++;
}
}
@@ -211,10 +157,7 @@ namespace umbraco.presentation.umbraco.webservices
public override bool IsReusable
{
get
{
return false;
}
get { return false; }
}
}
}
@@ -163,6 +163,8 @@ namespace umbraco.presentation.webservices
[ScriptMethod]
public string ProgressStatus(string Key)
{
AuthorizeRequest(true);
return Application[helper.Request("key")].ToString();
}
@@ -789,18 +789,18 @@ namespace umbraco.MacroEngines
if (result != null)
{
//a really rough check to see if this may be valid xml
if (sResult.StartsWith("<") && sResult.EndsWith(">") && sResult.Contains("/"))
if (XmlHelper.CouldItBeXml(sResult))
{
try
{
XElement e = XElement.Parse(DynamicXml.StripDashesInElementOrAttributeNames(sResult), LoadOptions.None);
XElement e = XElement.Parse(XmlHelper.StripDashesInElementOrAttributeNames(sResult), LoadOptions.None);
if (e != null)
{
//check that the document element is not one of the disallowed elements
//allows RTE to still return as html if it's valid xhtml
string documentElement = e.Name.LocalName;
if (!UmbracoSettings.NotDynamicXmlDocumentElements.Any(tag =>
string.Equals(tag, documentElement, StringComparison.CurrentCultureIgnoreCase)))
if (UmbracoSettings.NotDynamicXmlDocumentElements.Any(tag =>
string.Equals(tag, documentElement, StringComparison.CurrentCultureIgnoreCase)) == false)
{
result = new DynamicXml(e);
return true;
@@ -8,6 +8,7 @@ using System.Xml.XPath;
using System.Collections;
using System.IO;
using System.Web;
using Umbraco.Core;
namespace umbraco.MacroEngines
{
@@ -381,9 +382,10 @@ namespace umbraco.MacroEngines
return test(this) ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
}
[Obsolete("Use XmlHelper.StripDashesInElementOrAttributeNames instead")]
public static string StripDashesInElementOrAttributeNames(string xml)
{
return Umbraco.Core.Dynamics.DynamicXml.StripDashesInElementOrAttributeNames(xml);
return XmlHelper.StripDashesInElementOrAttributeNames(xml);
}
}
}
@@ -467,13 +467,18 @@ namespace umbraco.MacroEngines
public IProperty GetProperty(string alias, out bool propertyExists)
{
string value = null;
if (Values.TryGetValue(alias, out value))
//First, try to get the 'raw' value, if that doesn't work try to get the normal one
if (Values.TryGetValue("__Raw_" + alias, out value)
|| Values.TryGetValue(alias, out value))
{
propertyExists = true;
return new PropertyResult(alias, value, Guid.Empty);
}
propertyExists = false;
return null;
}
}
}
+12 -30
View File
@@ -237,29 +237,21 @@ namespace umbraco.BasePages
{
get
{
// zb-00004 #29956 : refactor cookies names & handling
if (StateHelper.Cookies.HasCookies && StateHelper.Cookies.UserContext.HasValue)
return StateHelper.Cookies.UserContext.GetValue();
else
{
try
{
string encTicket = StateHelper.Cookies.UserContext.GetValue();
if (!String.IsNullOrEmpty(encTicket))
return FormsAuthentication.Decrypt(encTicket).UserData;
var encTicket = StateHelper.Cookies.UserContext.GetValue();
if (string.IsNullOrEmpty(encTicket) == false)
{
return encTicket.DecryptWithMachineKey();
}
}
catch (HttpException ex)
{
// we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set
}
catch (ArgumentException ex)
{
// we swallow this one because it's 99.99% certaincy is legacy based. We'll still log it, though
LogHelper.Error<BasePage>("An error occurred reading auth cookie value", ex);
}
}
return "";
}
set
@@ -271,25 +263,15 @@ namespace umbraco.BasePages
if (StateHelper.Cookies.UserContext.HasValue)
StateHelper.Cookies.ClearAll();
if (!String.IsNullOrEmpty(value))
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
value,
DateTime.Now,
DateTime.Now.AddDays(1),
false,
value,
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
if (string.IsNullOrEmpty(value) == false)
{
// Encrypt the value
var encTicket = value.EncryptWithMachineKey();
// Create new cookie.
StateHelper.Cookies.UserContext.SetValue(value, 1);
} else
StateHelper.Cookies.UserContext.SetValue(encTicket, 1);
}
else
{
StateHelper.Cookies.UserContext.Clear();
}
+11 -5
View File
@@ -3,7 +3,8 @@ using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Threading;
using System.Web.UI.WebControls;
using Umbraco.Core;
using umbraco.DataLayer;
using System.Collections.Generic;
using System.Reflection;
@@ -198,7 +199,7 @@ namespace umbraco.BusinessLogic
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@logHeader", type),
SqlHelper.CreateParameter("@logHeader", type.ToString()),
SqlHelper.CreateParameter("@dateStamp", sinceDate)));
}
@@ -230,7 +231,7 @@ namespace umbraco.BusinessLogic
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@logHeader", type),
SqlHelper.CreateParameter("@logHeader", type.ToString()),
SqlHelper.CreateParameter("@user", user.Id),
SqlHelper.CreateParameter("@dateStamp", sinceDate)));
}
@@ -344,8 +345,13 @@ namespace umbraco.BusinessLogic
[Obsolete("Use the Instance.GetLogItems method which return a list of LogItems instead")]
internal static IRecordsReader GetLogReader(User user, LogTypes type, DateTime sinceDate, int numberOfResults)
{
return SqlHelper.ExecuteReader(
"select top " + numberOfResults + " userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
var query = "select {0} userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc {1}";
query = SqlHelper.GetType().ToString().ToLowerInvariant().Contains("MySql.MySqlHelper".ToLowerInvariant())
? string.Format(query, string.Empty, "limit 0," + numberOfResults)
: string.Format(query, "top " + numberOfResults, string.Empty);
return SqlHelper.ExecuteReader(query,
SqlHelper.CreateParameter("@logHeader", type.ToString()),
SqlHelper.CreateParameter("@user", user.Id),
SqlHelper.CreateParameter("@dateStamp", sinceDate));
+3
View File
@@ -454,6 +454,9 @@ namespace umbraco.BusinessLogic
if (GlobalSettings.UseSSL)
cookie.Secure = true;
//ensure http only, this should only be able to be accessed via the server
cookie.HttpOnly = true;
cookie.Expires = expires;
ResponseCookie = cookie;
+18 -18
View File
@@ -5,6 +5,7 @@ using System.Linq;
using System.Data;
using System.Xml;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.property;
using umbraco.cms.businesslogic.propertytype;
using umbraco.DataLayer;
@@ -416,8 +417,7 @@ namespace umbraco.cms.businesslogic
/// <param name="xd"></param>
public virtual void XmlGenerate(XmlDocument xd)
{
XmlNode node = generateXmlWithoutSaving(xd);
SaveXmlDocument(node);
SaveXmlDocument(generateXmlWithoutSaving(xd));
}
public virtual void XmlPopulate(XmlDocument xd, ref XmlNode x, bool Deep)
@@ -428,27 +428,27 @@ namespace umbraco.cms.businesslogic
x.AppendChild(p.ToXml(xd));
// attributes
x.Attributes.Append(xmlHelper.addAttribute(xd, "id", this.Id.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "version", this.Version.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "id", this.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "version", this.Version.ToString()));
if (this.Level > 1)
x.Attributes.Append(xmlHelper.addAttribute(xd, "parentID", this.Parent.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "parentID", this.Parent.Id.ToString()));
else
x.Attributes.Append(xmlHelper.addAttribute(xd, "parentID", "-1"));
x.Attributes.Append(xmlHelper.addAttribute(xd, "level", this.Level.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "writerID", this.User.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "parentID", "-1"));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "level", this.Level.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "writerID", this.User.Id.ToString()));
if (this.ContentType != null)
x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeType", this.ContentType.Id.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "template", "0"));
x.Attributes.Append(xmlHelper.addAttribute(xd, "sortOrder", this.sortOrder.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "createDate", this.CreateDateTime.ToString("s")));
x.Attributes.Append(xmlHelper.addAttribute(xd, "updateDate", this.VersionDate.ToString("s")));
x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeName", this.Text));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeType", this.ContentType.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "template", "0"));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "sortOrder", this.sortOrder.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "createDate", this.CreateDateTime.ToString("s")));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "updateDate", this.VersionDate.ToString("s")));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeName", this.Text));
if (this.Text != null)
x.Attributes.Append(xmlHelper.addAttribute(xd, "urlName", this.Text.Replace(" ", "").ToLower()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "writerName", this.User.Name));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "urlName", this.Text.Replace(" ", "").ToLower()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "writerName", this.User.Name));
if (this.ContentType != null)
x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeTypeAlias", this.ContentType.Alias));
x.Attributes.Append(xmlHelper.addAttribute(xd, "path", this.Path));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeTypeAlias", this.ContentType.Alias));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "path", this.Path));
if (Deep)
{
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Linq;
using System.Xml;
using Umbraco.Core;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.web;
@@ -282,6 +283,84 @@ namespace umbraco.cms.businesslogic
#region Public Properties
#region Regenerate Xml Structures
/// <summary>
/// Used to rebuild all of the xml structures for content of the current content type in the cmsContentXml table
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
internal void RebuildXmlStructuresForContent()
{
//Clears all xml structures in the cmsContentXml table for the current content type
ClearXmlStructuresForContent();
foreach (var i in GetContentIdsForContentType())
{
RebuildXmlStructureForContentItem(i);
}
}
/// <summary>
/// Returns all content ids associated with this content type
/// </summary>
/// <returns></returns>
/// <remarks>
/// This will generally just return the content ids associated with this content type but in the case
/// of a DocumentType where we can have inherited types, this will return all content Ids that are of
/// this content type or any descendant types as well.
/// </remarks>
internal virtual IEnumerable<int> GetContentIdsForContentType()
{
var ids = new List<int>();
//get all the content item ids of the current content type
using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @nodeId",
SqlHelper.CreateParameter("@nodeId", this.Id)))
{
while (dr.Read())
{
ids.Add(dr.GetInt("nodeId"));
}
dr.Close();
}
return ids;
}
/// <summary>
/// Rebuilds the xml structure for the content item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal virtual void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Content(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<ContentType>("Error generating xml", ee);
}
}
/// <summary>
/// Clears all xml structures in the cmsContentXml table for the current content type
/// </summary>
internal virtual void ClearXmlStructuresForContent()
{
//Remove all items from the cmsContentXml table that are of this current content type
SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @nodeId)",
SqlHelper.CreateParameter("@nodeId", this.Id));
}
#endregion
/// <summary>
/// Get or Sets the Container status of the Content Type. A Container Content Type doesn't show its children in the tree,
/// but instead adds a tab when edited showing its children in a grid
+1 -10
View File
@@ -585,16 +585,7 @@ namespace umbraco.cms.businesslogic.member
FireAfterSave(e);
}
}
/// <summary>
/// Generates the xmlrepresentation of a member
/// </summary>
/// <param name="xd"></param>
public override void XmlGenerate(XmlDocument xd)
{
SaveXmlDocument(generateXmlWithoutSaving(xd));
}
/// <summary>
/// Xmlrepresentation of a member
/// </summary>
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Xml;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.propertytype;
using System.Linq;
using umbraco.BusinessLogic;
@@ -27,6 +28,30 @@ namespace umbraco.cms.businesslogic.member
/// <param name="id">MemberType id</param>
public MemberType(Guid id) : base(id) { }
#region Regenerate Xml Structures
/// <summary>
/// Rebuilds the xml structure for the member item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Member(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<MemberType>("Error generating xml", ee);
}
}
#endregion
/// <summary>
/// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
/// </summary>
+39 -14
View File
@@ -7,6 +7,7 @@ using System.Threading;
using System.Web;
using System.Xml;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using umbraco.BusinessLogic;
using umbraco.BusinessLogic.Actions;
using umbraco.cms.businesslogic.property;
@@ -628,31 +629,55 @@ order by {1}
return tmp;
}
/// <summary>
/// This will clear out the cmsContentXml table for all Documents (not media or members) and then
/// rebuild the xml for each Docuemtn item and store it in this table.
/// </summary>
/// <remarks>
/// This method is thread safe
/// </remarks>
[MethodImpl(MethodImplOptions.Synchronized)]
public static void RePublishAll()
{
XmlDocument xd = new XmlDocument();
var xd = new XmlDocument();
if (!DataLayerHelper.IsEmbeddedDatabase(SqlHelper.ConnectionString))
{
SqlHelper.ExecuteNonQuery("truncate table cmsContentXml");
}
else
{
SqlHelper.ExecuteNonQuery("delete from cmsContentXml");
}
IRecordsReader dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument where published = 1");
//Remove all Documents (not media or members), only Documents are stored in the cmsDocument table
SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
INNER JOIN cmsDocument ON cmsContentXml.nodeId = cmsDocument.nodeId)");
var dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument where published = 1");
while (dr.Read())
{
try
{
new Document(dr.GetInt("nodeId")).XmlGenerate(xd);
//create the document in optimized mode!
// (not sure why we wouldn't always do that ?!)
new Document(true, dr.GetInt("nodeId"))
.XmlGenerate(xd);
//The benchmark results that I found based contructing the Document object with 'true' for optimized
//mode, vs using the normal ctor. Clearly optimized mode is better!
/*
* The average page rendering time (after 10 iterations) for submitting /umbraco/dialogs/republish?xml=true when using
* optimized mode is
*
* 0.060400555555556
*
* The average page rendering time (after 10 iterations) for submitting /umbraco/dialogs/republish?xml=true when not
* using optimized mode is
*
* 0.107037777777778
*
* This means that by simply changing this to use optimized mode, it is a 45% improvement!
*
*/
}
catch (Exception ee)
{
Log.Add(LogTypes.Error, User.GetUser(0), dr.GetInt("nodeId"),
string.Format("Error generating xml: {0}", ee));
LogHelper.Error<Document>("Error generating xml", ee);
}
}
dr.Close();
@@ -1248,7 +1273,7 @@ and node.nodeObjectType=@nodeObjectType";
Guid newVersion = createNewVersion(versionDate);
SqlHelper.ExecuteNonQuery("insert into cmsDocument (nodeId, published, documentUser, versionId, updateDate, Text) "
+ "values (" + Id + ", 0, " + u.Id + ", @versionId, @text)",
+ "values (" + Id + ", 0, " + u.Id + ", @versionId, @updateDate, @text)",
SqlHelper.CreateParameter("@versionId", newVersion),
SqlHelper.CreateParameter("@updateDate", versionDate),
SqlHelper.CreateParameter("@text", Text));
@@ -4,6 +4,7 @@ using System.Data;
using System.Text;
using System.Xml;
using System.Linq;
using Umbraco.Core.Logging;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.propertytype;
using umbraco.DataLayer;
@@ -166,7 +167,7 @@ namespace umbraco.cms.businesslogic.web
while (dr.Read())
{
//check if the document id has already been added
if (documentTypes.Where(x => x.Id == dr.Get<int>("id")).Count() == 0)
if (documentTypes.Any(x => x.Id == dr.Get<int>("id")) == false)
{
//create the DocumentType object without setting up
DocumentType dt = new DocumentType(dr.Get<int>("id"), true);
@@ -182,7 +183,7 @@ namespace umbraco.cms.businesslogic.web
else
{
//we've already created the document type with this id, so we'll add the rest of it's templates to itself
var dt = documentTypes.Where(x => x.Id == dr.Get<int>("id")).Single();
var dt = documentTypes.Single(x => x.Id == dr.Get<int>("id"));
dt.PopulateDocumentTypeNodeFromReader(dr);
}
}
@@ -294,6 +295,106 @@ namespace umbraco.cms.businesslogic.web
#region Public Methods
#region Regenerate Xml Structures
/// <summary>
/// This will return all PUBLISHED content Ids that are of this content type or any descendant types as well.
/// </summary>
/// <returns></returns>
internal override IEnumerable<int> GetContentIdsForContentType()
{
var ids = new List<int>();
int? currentContentTypeId = this.Id;
while (currentContentTypeId != null)
{
//get all the content item ids of the current content type
using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsDocument.nodeId FROM cmsDocument
INNER JOIN cmsContent ON cmsContent.nodeId = cmsDocument.nodeId
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @contentTypeId AND cmsDocument.published = 1",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)))
{
while (dr.Read())
{
ids.Add(dr.GetInt("nodeId"));
}
dr.Close();
}
//lookup the child content type if there is one
currentContentTypeId = SqlHelper.ExecuteScalar<int?>("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
}
return ids;
}
/// <summary>
/// Rebuilds the xml structure for the content item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
//create the document in optimized mode!
// (not sure why we wouldn't always do that ?!)
new Document(true, contentId).XmlGenerate(xd);
//The benchmark results that I found based contructing the Document object with 'true' for optimized
//mode, vs using the normal ctor. Clearly optimized mode is better!
/*
* The average page rendering time (after 10 iterations) for submitting /umbraco/dialogs/republish?xml=true when using
* optimized mode is
*
* 0.060400555555556
*
* The average page rendering time (after 10 iterations) for submitting /umbraco/dialogs/republish?xml=true when not
* using optimized mode is
*
* 0.107037777777778
*
* This means that by simply changing this to use optimized mode, it is a 45% improvement!
*
*/
}
catch (Exception ee)
{
LogHelper.Error<DocumentType>("Error generating xml", ee);
}
}
/// <summary>
/// Clears all xml structures in the cmsContentXml table for the current content type and any of it's descendant types
/// </summary>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void ClearXmlStructuresForContent()
{
int? currentContentTypeId = this.Id;
while (currentContentTypeId != null)
{
//Remove all items from the cmsContentXml table that are of this current content type
SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @contentTypeId)",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
//lookup the child content type if there is one
currentContentTypeId = SqlHelper.ExecuteScalar<int?>("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
}
}
#endregion
public void RemoveTemplate(int templateId)
{
// remove if default template
@@ -84,8 +84,8 @@ namespace umbraco.cms.businesslogic.workflow
{
// check if something was changed and display the changes otherwise display the fields
Property oldProperty = oldDoc.getProperty(p.PropertyType.Alias);
string oldText = oldProperty.Value.ToString();
string newText = p.Value.ToString();
string oldText = oldProperty.Value != null ? oldProperty.Value.ToString() : "";
string newText = p.Value != null ? p.Value.ToString() : "";
// replace html with char equivalent
ReplaceHTMLSymbols(ref oldText);
@@ -124,7 +124,7 @@ namespace umbraco.cms.businesslogic.workflow
summary.Append("<tr>");
summary.Append("<th style='text-align: left; vertical-align: top; width: 25%;'>" +
p.PropertyType.Name + "</th>");
summary.Append("<td style='text-align: left; vertical-align: top;'>" + p.Value.ToString() + "</td>");
summary.Append("<td style='text-align: left; vertical-align: top;'>" + newText + "</td>");
summary.Append("</tr>");
}
summary.Append(
@@ -2,60 +2,40 @@ using System;
namespace umbraco.editorControls.mediapicker
{
/// <summary>
/// Summary description for MemberPickerDataType.
/// </summary>
public class MemberPickerDataType : cms.businesslogic.datatype.BaseDataType,interfaces.IDataType
{
private interfaces.IDataEditor _Editor;
private interfaces.IData _baseData;
private interfaces.IDataPrevalue _prevalueeditor;
//TODO: Properly rename this for a major release
public class MediaPickerDataType : MemberPickerDataType
{ }
public override interfaces.IDataEditor DataEditor
{
get
{
if (_Editor == null)
_Editor = new mediaChooser(Data,
((MediaPickerPrevalueEditor)PrevalueEditor).ShowPreview,
((MediaPickerPrevalueEditor)PrevalueEditor).ShowAdvancedDialog);
return _Editor;
}
}
[Obsolete("Renamed to MediaPickerDataType because.. that is what it was all along")]
public class MemberPickerDataType : cms.businesslogic.datatype.BaseDataType, interfaces.IDataType
{
private interfaces.IDataEditor _editor;
private interfaces.IData _baseData;
private interfaces.IDataPrevalue _prevalueeditor;
public override interfaces.IData Data
{
get
{
if (_baseData == null)
_baseData = new cms.businesslogic.datatype.DefaultData(this);
return _baseData;
}
}
public override interfaces.IDataEditor DataEditor
{
get { return _editor ?? (_editor = new mediaChooser(Data, ((MediaPickerPrevalueEditor)PrevalueEditor).ShowPreview, ((MediaPickerPrevalueEditor)PrevalueEditor).ShowAdvancedDialog)); }
}
public override interfaces.IData Data
{
get { return _baseData ?? (_baseData = new cms.businesslogic.datatype.DefaultData(this)); }
}
public override Guid Id
{
get
{
return new Guid ("EAD69342-F06D-4253-83AC-28000225583B");
}
}
public override string DataTypeName
{
get
{
return "Media Picker";
}
}
public override interfaces.IDataPrevalue PrevalueEditor
{
get
{
if (_prevalueeditor == null)
_prevalueeditor = new MediaPickerPrevalueEditor(this);
return _prevalueeditor;
}
}
}
public override Guid Id
{
get { return new Guid("EAD69342-F06D-4253-83AC-28000225583B"); }
}
public override string DataTypeName
{
get { return "Media Picker"; }
}
public override interfaces.IDataPrevalue PrevalueEditor
{
get { return _prevalueeditor ?? (_prevalueeditor = new MediaPickerPrevalueEditor(this)); }
}
}
}
@@ -2,52 +2,34 @@ using System;
namespace umbraco.editorControls.memberpicker
{
/// <summary>
/// Summary description for MemberPickerDataType.
/// </summary>
public class MemberPickerDataType : cms.businesslogic.datatype.BaseDataType,interfaces.IDataType
{
private interfaces.IDataEditor _Editor;
private interfaces.IData _baseData;
private interfaces.IDataPrevalue _prevalueeditor;
public class MemberPickerDataType : cms.businesslogic.datatype.BaseDataType, interfaces.IDataType
{
private interfaces.IDataEditor _editor;
private interfaces.IData _baseData;
private interfaces.IDataPrevalue _prevalueeditor;
public override interfaces.IDataEditor DataEditor
{
get
{
if (_Editor == null)
_Editor = new memberPicker(Data);
return _Editor;
}
}
public override interfaces.IDataEditor DataEditor
{
get { return _editor ?? (_editor = new memberPicker(Data)); }
}
public override interfaces.IData Data
{
get
{
if (_baseData == null)
_baseData = new cms.businesslogic.datatype.DefaultData(this);
return _baseData;
}
}
public override string DataTypeName
{
get {return "Member Picker";}
}
public override interfaces.IData Data
{
get { return _baseData ?? (_baseData = new cms.businesslogic.datatype.DefaultData(this)); }
}
public override string DataTypeName
{
get { return "Member Picker"; }
}
public override Guid Id
{
get {return new Guid("39F533E4-0551-4505-A64B-E0425C5CE775");}
}
public override Guid Id
{
get { return new Guid("39F533E4-0551-4505-A64B-E0425C5CE775"); }
}
public override interfaces.IDataPrevalue PrevalueEditor
{
get
{
if (_prevalueeditor == null)
_prevalueeditor = new DefaultPrevalueEditor(this,false);
return _prevalueeditor;
}
}
}
public override interfaces.IDataPrevalue PrevalueEditor
{
get { return _prevalueeditor ?? (_prevalueeditor = new DefaultPrevalueEditor(this, false)); }
}
}
}
-2
View File
@@ -34,8 +34,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "umbraco.datalayer", "umbrac
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "umbraco.controls", "umbraco.controls\umbraco.controls.csproj", "{6EDD2061-82F2-461B-BB6E-879245A832DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "umbraco.webservices", "umbraco.webservices\umbraco.webservices.csproj", "{CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlCE4Umbraco", "SQLCE4Umbraco\SqlCE4Umbraco.csproj", "{5BA5425F-27A7-4677-865E-82246498AA2E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "umbraco.MacroEngines", "umbraco.MacroEngines\umbraco.MacroEngines.csproj", "{89C09045-1064-466B-B94A-DB3AFE2A5853}"
-194
View File
@@ -1,194 +0,0 @@
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Services;
using System.Web.Services.Protocols;
using umbraco.BusinessLogic;
using System.IO;
namespace umbraco.webservices
{
/// <summary>
/// The base-class all webservices should inherit from
/// </summary>
/// <remarks>
/// This class contains all basic methods for authenticating requests. Do not implement these functions yourself.
/// </remarks>
public abstract class BaseWebService : System.Web.Services.WebService
{
public abstract Services Service
{
get;
}
/// <summary>
/// Enum of services available
/// </summary>
public enum Services
{
DocumentService,
FileService,
StylesheetService,
MemberService,
MaintenanceService,
TemplateService,
MediaService
};
/// <summary>
/// Gets the umbraco-user from username and password
/// </summary>
public umbraco.BusinessLogic.User GetUser(string username, string password)
{
User u = new User(username);
if(!HttpContext.Current.Request.Url.Scheme.Equals("https"))
BusinessLogic.Log.Add(BusinessLogic.LogTypes.Debug, u, -1, "Webservices login attempted without https");
try
{
if (Membership.Providers[UmbracoSettings.DefaultBackofficeProvider].ValidateUser(username, password))
{
BusinessLogic.Log.Add(BusinessLogic.LogTypes.Login, u, -1,"Webservices");
return u;
}
}
catch
{
}
return null;
}
/// <summary>
/// Standart user-validation. All services must perform this
/// </summary>
public void Authenticate(string username, string password)
{
if (!WebservicesEnabled()) throw new Exception("Webservices not enabled");
if (!UserAuthenticates(username, password)) throw new Exception("The user does not authenticate");
if (!UserHasAccess(username)) throw new Exception("The user (" + username + ") does not have access to this service");
}
[WebMethod]
public bool WebservicesEnabled()
{
return umbraco.UmbracoSettings.Webservices.Enabled;
}
[WebMethod]
public bool UserAuthenticates(string username, string password)
{
if (!WebservicesEnabled()) throw new Exception("Webservices not enabled");
return GetUser(username, password) != null;
}
/// <summary>
/// Checks if a user has access to a specific webservice
/// </summary>
[WebMethod]
public bool UserHasAccess(string username)
{
switch (Service)
{
case Services.DocumentService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.documentServiceUsers, username);
case Services.FileService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.fileServiceUsers, username);
case Services.StylesheetService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.stylesheetServiceUsers, username);
case Services.MemberService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.memberServiceUsers, username);
case Services.MaintenanceService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.maintenanceServiceUsers, username);
case Services.TemplateService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.templateServiceUsers, username);
case Services.MediaService:
return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.mediaServiceUsers, username);
default:
return false;
}
}
public class FileIO
{
/// <summary>
/// Validates a filename. Must be used when user inputs a filename
/// </summary>
public static bool ValidFileName(string fileName)
{
// Check if a "levelup" string is included, so they dont move out of the folder
// Dont know if its necesary?
if (fileName.IndexOf("..") > -1)
return false;
return true;
}
/// <summary>
/// Checks if user has access to a specific folder
/// </summary>
public static bool FolderAccess(String folderName)
{
// Check if the folder is in "fileServiceFolders"
if (Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.fileServiceFolders, folderName) > -1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// Gets the webservers path for a file
/// </summary>
public static string GetFilePath(string folderName, string fileName)
{
string FullPath = GetFolderPath(folderName) + fileName;
return FullPath;
}
/// <summary>
/// Gets the webservers path for a folder
/// </summary>
public static string GetFolderPath(string folderName)
{
if (string.IsNullOrEmpty(folderName))
{
return AppRoot;
}
else
{
return AppRoot + folderName + @"\";
}
}
/// <summary>
/// Gets the webservers path for the application
/// </summary>
public static string AppRoot
{
get
{
return System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
}
}
}
}
}
-108
View File
@@ -1,108 +0,0 @@
//using System;
//using System.Data;
//using System.Configuration;
//using System.Web;
//using System.Web.Security;
//using System.Web.UI;
//using System.Web.UI.WebControls;
//using System.Web.UI.WebControls.WebParts;
//using System.Web.UI.HtmlControls;
//using System.Xml.Serialization;
//using System.Xml;
//namespace umbraco.webservices
//{
// public class authentication
// {
// /// <summary>
// /// Standart user-validation. All services must perform this
// /// </summary>
// /// <param name="username"></param>
// /// <param name="password"></param>
// /// <param name="service"></param>
// /// <remarks>First checks if the webservices are enabled. Then checks if the user is valid
// /// (username and password). Finally it checks if the user has access to the specific service
// /// </remarks>
// public static void StandartRequestCheck(string username, string password, authentication.EService service)
// {
// // We check if services are enabled and user has access
// if (!umbraco.UmbracoSettings.Webservices.Enabled)
// throw new Exception("webservices not enabled");
// // Validating the user
// GetUser(username, password);
// // Checking if user can use that specific service
// if (!authentication.UserHasAccess(username, service))
// throw new Exception("user has not access to this service");
// }
// /// <summary>
// /// Gets the umbraco-user from username and password
// /// </summary>
// /// <param name="username"></param>
// /// <param name="password"></param>
// /// <returns></returns>
// public static umbraco.BusinessLogic.User GetUser(string username, string password)
// {
// umbraco.BusinessLogic.User user;
// try
// {
// user = new umbraco.BusinessLogic.User(username, password);
// if (user == null)
// throw new Exception("Incorrect credentials. No user found. Call aborted");
// }
// catch (Exception ex)
// {
// throw new Exception("Incorrect credentials. Call aborted (error: " + ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace + ")");
// }
// return user;
// }
// /// <summary>
// /// List of accesible the services
// /// </summary>
// public enum EService
// {
// DocumentService,
// FileService,
// StylesheetService,
// MemberService,
// MaintenanceService,
// TemplateService
// };
// /// <summary>
// /// Checks if a user has access to a specific webservice
// /// </summary>
// /// <param name="username">user to check</param>
// /// <param name="service">the webservice to check for</param>
// /// <returns>true, if user has access otherwise false</returns>
// public static bool UserHasAccess(string username, EService service)
// {
// switch (service)
// {
// case EService.DocumentService:
// return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.documentServiceUsers, username);
// case EService.FileService:
// return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.fileServiceUsers, username);
// case EService.StylesheetService:
// return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.stylesheetServiceUsers, username);
// case EService.MemberService :
// return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.memberServiceUsers, username);
// case EService.MaintenanceService:
// return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.maintenanceServiceUsers, username);
// case EService.TemplateService :
// return -1 < Array.IndexOf<string>(umbraco.UmbracoSettings.Webservices.templateServiceUsers, username);
// default:
// return false;
// }
// }
// }
//}
@@ -1,19 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("umbraco.webservices")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("umbraco.webservices")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("58e13174-1338-40a8-b864-f47c7678a976")]
@@ -1,105 +0,0 @@
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace umbraco.webservices.documents
{
[Serializable]
[XmlType(Namespace = "http://umbraco.org/webservices/")]
public class documentCarrier
{
public enum EPublishAction
{
Ignore,
Publish,
Unpublish
};
public enum EPublishStatus
{
Published,
NotPublished
};
public documentCarrier()
{
DocumentProperties = new List<documentProperty>();
}
private int id;
private string name;
private List<documentProperty> documentProperties;
private int documentTypeID;
private int parentID;
private bool hasChildren;
private EPublishAction publishAction;
private bool published;
private DateTime releaseDate;
private DateTime expireDate;
public int Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public List<documentProperty> DocumentProperties
{
get { return documentProperties; }
set { documentProperties = value; }
}
public int DocumentTypeID
{
get { return documentTypeID; }
set { documentTypeID = value; }
}
public int ParentID
{
get { return parentID; }
set { parentID = value; }
}
public bool HasChildren
{
get { return hasChildren; }
set { hasChildren = value; }
}
public EPublishAction PublishAction
{
get { return publishAction; }
set { publishAction = value; }
}
public bool Published
{
get { return published; }
set { published = value; }
}
public DateTime ReleaseDate
{
get { return releaseDate; }
set { releaseDate = value; }
}
public DateTime ExpireDate
{
get { return expireDate; }
set { expireDate = value; }
}
}
}
@@ -1,29 +0,0 @@
using System;
using System.Xml.Serialization;
namespace umbraco.webservices.documents
{
[Serializable]
[XmlType(Namespace = "http://umbraco.org/webservices/")]
public class documentProperty
{
private string key;
private object propertyValue;
public documentProperty()
{
}
public object PropertyValue
{
get { return propertyValue; }
set { propertyValue = value; }
}
public string Key
{
get { return key; }
set { key = value; }
}
}
}
@@ -1,318 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web.Services;
using umbraco.cms.businesslogic.web;
namespace umbraco.webservices.documents
{
/// <summary>
/// Service managing documents in umbraco
/// </summary>
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class documentService : BaseWebService
{
override public Services Service
{
get
{
return Services.DocumentService;
}
}
[WebMethod]
public int create(documentCarrier carrier, string username, string password)
{
Authenticate(username, password);
// Some validation
if (carrier == null) throw new Exception("No carrier specified");
if (carrier.ParentID == 0) throw new Exception("Document needs a parent");
if (carrier.DocumentTypeID == 0) throw new Exception("Documenttype must be specified");
if (carrier.Id != 0) throw new Exception("ID cannot be specifed when creating. Must be 0");
if (carrier.Name == null || carrier.Name.Length == 0) carrier.Name = "unnamed";
umbraco.BusinessLogic.User user = GetUser(username, password);
// We get the documenttype
umbraco.cms.businesslogic.web.DocumentType docType = new umbraco.cms.businesslogic.web.DocumentType(carrier.DocumentTypeID);
if (docType == null) throw new Exception("DocumenttypeID " + carrier.DocumentTypeID + " not found");
// We create the document
Document newDoc = Document.MakeNew(carrier.Name, docType, user, carrier.ParentID);
newDoc.ReleaseDate = carrier.ReleaseDate;
newDoc.ExpireDate = carrier.ExpireDate;
// We iterate the properties in the carrier
if (carrier.DocumentProperties != null)
{
foreach (documentProperty updatedproperty in carrier.DocumentProperties)
{
umbraco.cms.businesslogic.property.Property property = newDoc.getProperty(updatedproperty.Key);
if (property == null) throw new Exception("property " + updatedproperty.Key + " was not found");
property.Value = updatedproperty.PropertyValue;
}
}
// We check the publishaction and do the appropiate
handlePublishing(newDoc, carrier, user);
// We return the ID of the document..65
return newDoc.Id;
}
[WebMethod]
public documentCarrier read(int id, string username, string password)
{
Authenticate(username, password);
umbraco.cms.businesslogic.web.Document doc = null;
try
{
doc = new umbraco.cms.businesslogic.web.Document(id);
}
catch
{ }
if (doc == null)
throw new Exception("Could not load Document with ID: " + id);
documentCarrier carrier = createCarrier(doc);
return carrier;
}
[WebMethod]
public documentCarrier ReadPublished(int id, string username, string password)
{
Authenticate(username, password);
var doc = new Document(id, true);
var publishedDoc = doc.GetPublishedVersion();
doc = publishedDoc == null ? new Document(id) : new Document(id, publishedDoc.Version);
if (doc == null)
throw new Exception("Could not load Document with ID: " + id);
return createCarrier(doc);
}
[WebMethod]
public List<documentCarrier> readList(int parentid, string username, string password)
{
Authenticate(username, password);
umbraco.cms.businesslogic.web.Document[] docList;
umbraco.cms.businesslogic.web.Document doc = null;
List<documentCarrier> carriers = new List<documentCarrier>();
if (parentid == 0)
{
docList = Document.GetRootDocuments();
}
else
{
try
{
doc = new umbraco.cms.businesslogic.web.Document(parentid);
}
catch
{ }
if (doc == null)
throw new Exception("Parent document with ID " + parentid + " not found");
try
{
if (!doc.HasChildren)
return carriers;
docList = doc.Children;
}
catch (Exception exception)
{
throw new Exception("Could not load children: " + exception.Message);
}
}
// Loop the nodes in docList
foreach (Document childdoc in docList)
{
carriers.Add(createCarrier(childdoc));
}
return carriers;
}
[WebMethod]
public void update(documentCarrier carrier, string username, string password)
{
Authenticate(username, password);
if (carrier.Id == 0) throw new Exception("ID must be specifed when updating");
if (carrier == null) throw new Exception("No carrier specified");
umbraco.BusinessLogic.User user = GetUser(username, password);
Document doc = null;
try
{
doc = new Document(carrier.Id);
}
catch { }
if (doc == null)
// We assign the new values:
doc.ReleaseDate = carrier.ReleaseDate;
doc.ExpireDate = carrier.ExpireDate;
if (carrier.ParentID != 0)
{
doc.Move(carrier.ParentID);
}
if (carrier.Name.Length != 0)
{
doc.Text = carrier.Name;
}
// We iterate the properties in the carrier
if (carrier.DocumentProperties != null)
{
foreach (documentProperty updatedproperty in carrier.DocumentProperties)
{
umbraco.cms.businesslogic.property.Property property = doc.getProperty(updatedproperty.Key);
if (property == null)
{
}
else
{
property.Value = updatedproperty.PropertyValue;
}
}
}
handlePublishing(doc, carrier, user);
}
[WebMethod]
public void delete(int id, string username, string password)
{
Authenticate(username, password);
// Some validation, to prevent deletion of system-documents.. (nessecary?)
if (id < 0)
{
throw new Exception("Cannot delete documents with id lower than 1");
}
// We load the document
Document doc = null;
try
{
doc = new Document(id);
}
catch
{ }
if (doc == null)
throw new Exception("Document not found");
try
{
doc.delete();
}
catch (Exception ex)
{
throw new Exception("Document could not be deleted" + ex.Message);
}
}
private void handlePublishing(Document doc, documentCarrier carrier, umbraco.BusinessLogic.User user)
{
switch (carrier.PublishAction)
{
case documentCarrier.EPublishAction.Publish:
if (doc.PublishWithResult(user))
{
umbraco.library.UpdateDocumentCache(doc);
}
break;
case documentCarrier.EPublishAction.Unpublish:
if (doc.PublishWithResult(user))
{
umbraco.library.UnPublishSingleNode(doc);
}
break;
case documentCarrier.EPublishAction.Ignore:
if (doc.Published)
{
if (doc.PublishWithResult(user))
{
umbraco.library.UpdateDocumentCache(doc);
}
}
else
{
if (doc.PublishWithResult(user))
{
umbraco.library.UpdateDocumentCache(doc);
}
}
break;
}
}
private documentCarrier createCarrier(Document doc)
{
documentCarrier carrier = new documentCarrier();
carrier.ExpireDate = doc.ExpireDate;
carrier.ReleaseDate = doc.ReleaseDate;
carrier.Id = doc.Id;
carrier.Name = doc.Text;
try
{
carrier.ParentID = doc.Parent.Id;
}
catch
{
}
carrier.Published = doc.Published;
carrier.HasChildren = doc.HasChildren;
var props = doc.getProperties;
foreach (umbraco.cms.businesslogic.property.Property prop in props)
{
documentProperty carrierprop = new documentProperty();
if (prop.Value == System.DBNull.Value)
{
carrierprop.PropertyValue = null;
}
else
{
carrierprop.PropertyValue = prop.Value;
}
carrierprop.Key = prop.PropertyType.Alias;
carrier.DocumentProperties.Add(carrierprop);
}
return carrier;
}
}
}
@@ -1,190 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Web.Services;
namespace umbraco.webservices.files
{
/// <summary>
/// Summary description for FileService
/// </summary>
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class fileService : BaseWebService
{
override public Services Service
{
get
{
return Services.FileService;
}
}
[WebMethod]
public void DeleteFile(String folderName, string fileName, string username, string password)
{
Authenticate(username, password);
// Check if folder is accessible
if (FileIO.FolderAccess(folderName))
{
// Check if the filename is valid
if (!FileIO.ValidFileName(fileName))
throw new ArgumentException(String.Format("Filename {0} not valid", fileName));
// Check if the file exists. If it does, we delete it
if (System.IO.File.Exists(FileIO.GetFilePath(folderName, fileName)))
{
System.IO.File.Delete(FileIO.GetFilePath(folderName, fileName));
}
else
{
throw new FileNotFoundException();
}
}
else
{
throw new ArgumentException("no access to specified folder");
}
}
[WebMethod]
public Byte[] DownloadFile(String folderName, string fileName, string username, string password)
{
Authenticate(username, password);
// Check if folder is accessible
if (FileIO.FolderAccess(folderName))
{
// Check if the filename is valid
if (!FileIO.ValidFileName(fileName))
throw new ArgumentException(String.Format("Filename {0} not valid", fileName));
// Check if the file even exists
if (!System.IO.File.Exists(FileIO.GetFilePath(folderName, fileName)))
{
throw new FileNotFoundException("Could not find file to delete");
}
// Create a stream, and send it to the client
FileStream objfilestream = new FileStream(FileIO.GetFilePath(folderName, fileName), FileMode.Open, FileAccess.Read);
int len = (int)objfilestream.Length;
Byte[] documentcontents = new Byte[len];
objfilestream.Read(documentcontents, 0, len);
objfilestream.Close();
return documentcontents;
}
else
{
throw new ArgumentException("no access to specified folder");
}
}
[WebMethod]
public void UploadFile(Byte[] docbinaryarray, String folderName, string fileName, string username, string password, bool deleteOld)
{
Authenticate(username, password);
// Check if folder is accessible
if (FileIO.FolderAccess(folderName))
{
// Check if the filename is valid
if (FileIO.ValidFileName(fileName))
throw new ArgumentException(String.Format("Filename {0} not valid", fileName));
// Check if the file exists. If it does, we delete it first ..
// TODO: Maybe we should have "deleted files, folder for this?
if (System.IO.File.Exists(FileIO.GetFilePath(folderName, fileName)))
{
if (deleteOld)
{
System.IO.File.Delete(FileIO.GetFilePath(folderName, fileName));
}
else
{
throw new ArgumentException("Cannot save. File allready exist");
}
}
// Open a filestream, and write the data from the client to it
FileStream objfilestream = new FileStream(FileIO.GetFilePath(folderName, fileName), FileMode.Create, FileAccess.ReadWrite);
objfilestream.Write(docbinaryarray, 0, docbinaryarray.Length);
objfilestream.Close();
}
else
{
throw new ArgumentException("no access to specified folder");
}
}
/// <summary>
/// To download a file, we need to know how big its going to be
/// </summary>
[WebMethod]
public int GetFileSize(String folderName, string fileName, string username, string password)
{
Authenticate(username, password);
// Check if folder is accessible
if (FileIO.FolderAccess(folderName))
{
// Check if the filename is valid
if (!FileIO.ValidFileName(fileName))
throw new ArgumentException(String.Format("Filename {0} not valid", fileName));
string strdocPath;
strdocPath = FileIO.GetFilePath(folderName, fileName);
// Load file into stream
FileStream objfilestream = new FileStream(strdocPath, FileMode.Open, FileAccess.Read);
// Find and return the lenght of the stream
int len = (int)objfilestream.Length;
objfilestream.Close();
return len;
}
else
{
throw new ArgumentException("no access to specified folder");
}
}
/// <summary>
/// Get all files in a specific folder
/// </summary>
/// <returns></returns>
[WebMethod]
public string[] GetFilesList(String folderName, string username, string password)
{
Authenticate(username, password);
if (FileIO.FolderAccess(folderName))
{
string fullPath = FileIO.GetFolderPath(folderName);
DirectoryInfo folder = new DirectoryInfo(fullPath);
FileInfo[] files = folder.GetFiles();
List<string> shortNames = new List<string>();
foreach (FileInfo file in files)
{
shortNames.Add(file.Name);
}
return shortNames.ToArray();
}
else
{
throw new ArgumentException("no access to specified folder");
}
}
}
}
@@ -1,39 +0,0 @@
using System;
using System.ComponentModel;
using System.Web.Services;
namespace umbraco.webservices.maintenance
{
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class maintenanceService : BaseWebService
{
override public Services Service
{
get
{
return Services.MaintenanceService;
}
}
[WebMethod]
public string getWebservicesVersion(string username, string password)
{
// We check if services are enabled and user has access
Authenticate(username, password);
var thisVersion = new Version(0, 10);
return Convert.ToString(thisVersion);
}
[WebMethod]
public void restartApplication(string username, string password)
{
// We check if services are enabled and user has access
Authenticate(username, password);
System.Web.HttpRuntime.UnloadAppDomain();
}
}
}
@@ -1,84 +0,0 @@
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace umbraco.webservices.media
{
[Serializable]
[XmlType(Namespace = "http://umbraco.org/webservices/")]
public class mediaCarrier
{
public int Id
{
get;
set;
}
public string Text
{
get;
set;
}
public string TypeAlias
{
get;
set;
}
public int TypeId
{
get;
set;
}
public DateTime CreateDateTime
{
get;
set;
}
public Boolean HasChildren
{
get;
set;
}
public int Level
{
get;
set;
}
public int ParentId
{
get;
set;
}
public string Path
{
get;
set;
}
public int SortOrder
{
get;
set;
}
public List<mediaProperty> MediaProperties
{
get;
set;
}
public mediaCarrier()
{
MediaProperties = new List<mediaProperty>();
}
}
}
@@ -1,24 +0,0 @@
using System.Xml.Serialization;
namespace umbraco.webservices.media
{
[XmlType(Namespace = "http://umbraco.org/webservices/")]
public class mediaProperty
{
public mediaProperty()
{
}
public object PropertyValue
{
get;
set;
}
public string Key
{
get;
set;
}
}
}
@@ -1,304 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Web.Services;
using Umbraco.Core.Media;
using umbraco.IO;
using umbraco.cms.businesslogic.media;
using umbraco.cms.businesslogic.property;
using Umbraco.Core.IO;
using System.Xml;
using System.Web;
using System.Text.RegularExpressions;
using System.Linq;
using System.Web.Script.Services;
namespace umbraco.webservices.media
{
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class mediaService : BaseWebService
{
internal MediaFileSystem _fs;
public mediaService()
{
_fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
}
override public Services Service
{
get
{
return Services.MediaService;
}
}
[WebMethod]
public void update(mediaCarrier carrier, string username, string password)
{
Authenticate(username, password);
if (carrier == null) throw new Exception("No carrier specified");
Media m = new Media(carrier.Id);
if (carrier.MediaProperties != null)
{
foreach (mediaProperty updatedproperty in carrier.MediaProperties)
{
if (!(updatedproperty.Key.ToLower().Equals("umbracofile")))
{
Property property = m.getProperty(updatedproperty.Key);
if (property == null)
throw new Exception("property " + updatedproperty.Key + " was not found");
property.Value = updatedproperty.PropertyValue;
}
}
}
m.Save();
}
[WebMethod]
public int create(mediaCarrier carrier, string username, string password)
{
Authenticate(username, password);
if (carrier == null) throw new Exception("No carrier specified");
if (carrier.ParentId == 0) throw new Exception("Media needs a parent");
if (carrier.TypeId == 0) throw new Exception("Type must be specified");
if (carrier.Text == null || carrier.Text.Length == 0) carrier.Text = "unnamed";
umbraco.BusinessLogic.User user = GetUser(username, password);
MediaType mt = new MediaType(carrier.TypeId);
Media m = Media.MakeNew(carrier.Text, mt, user, carrier.ParentId);
if (carrier.MediaProperties != null)
{
foreach (mediaProperty updatedproperty in carrier.MediaProperties)
{
if (!(updatedproperty.Key.ToLower().Equals("umbracofile")))
{
Property property = m.getProperty(updatedproperty.Key);
if (property == null)
throw new Exception("property " + updatedproperty.Key + " was not found");
property.Value = updatedproperty.PropertyValue;
}
}
}
return m.Id;
}
[WebMethod]
public void delete(int id, string username, string password)
{
Authenticate(username, password);
Media m = new Media(id);
if (m.HasChildren)
throw new Exception("Cannot delete Media " + id + " as it has child nodes");
Property p = m.getProperty("umbracoFile");
if (p != null)
{
if (!(p.Value == System.DBNull.Value))
{
var path = _fs.GetRelativePath(p.Value.ToString());
if(_fs.FileExists(path))
_fs.DeleteFile(path, true);
}
}
m.delete();
}
[WebMethod]
public void writeContents(int id, string filename, Byte[] contents, string username, string password)
{
Authenticate(username, password);
filename = filename.Replace("/", global::Umbraco.Core.IO.IOHelper.DirSepChar.ToString());
filename = filename.Replace(@"\", global::Umbraco.Core.IO.IOHelper.DirSepChar.ToString());
filename = filename.Substring(filename.LastIndexOf(global::Umbraco.Core.IO.IOHelper.DirSepChar) + 1, filename.Length - filename.LastIndexOf(global::Umbraco.Core.IO.IOHelper.DirSepChar) - 1).ToLower();
Media m = new Media(id);
var path = _fs.GetRelativePath(m.getProperty("umbracoFile").Id, filename);
var stream = new MemoryStream();
stream.Write(contents, 0, contents.Length);
stream.Seek(0, 0);
_fs.AddFile(path, stream);
m.getProperty("umbracoFile").Value = _fs.GetUrl(path);
m.getProperty("umbracoExtension").Value = Path.GetExtension(filename).Substring(1);
m.getProperty("umbracoBytes").Value = _fs.GetSize(path);
}
[WebMethod]
public mediaCarrier read(int id, string username, string password)
{
Authenticate(username, password);
Media m = new Media(id);
return createCarrier(m);
}
[WebMethod]
public List<mediaCarrier> readList(int parentId, string username, string password)
{
Authenticate(username, password);
List<mediaCarrier> carriers = new List<mediaCarrier>();
Media[] mediaList;
if (parentId < 1)
{
mediaList = Media.GetRootMedias();
}
else
{
Media m = new Media(parentId);
mediaList = m.Children;
}
foreach (Media child in mediaList)
{
carriers.Add(createCarrier(child));
}
return carriers;
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Result Embed(string url, int width, int height)
{
Result r = 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 type = node.Attributes["type"].Value;
var prov = (IEmbedProvider)Activator.CreateInstance(Type.GetType(node.Attributes["type"].Value));
if (node.Attributes["supportsDimensions"] != null)
r.SupportsDimensions = node.Attributes["supportsDimensions"].Value == "True";
else
r.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()))
{
XmlNode setting = settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value;
var settingType = typeof(Umbraco.Web.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
{
r.Markup = prov.GetMarkup(url, width, height);
r.Status = Status.Success;
}
catch
{
r.Status = Status.Error;
}
return r;
}
}
r.Status = Status.NotSupported;
return r;
}
private mediaCarrier createCarrier(Media m)
{
mediaCarrier carrier = new mediaCarrier();
carrier.Id = m.Id;
carrier.Text = m.Text;
carrier.TypeAlias = m.ContentType.Alias;
carrier.TypeId = m.ContentType.Id;
carrier.CreateDateTime = m.CreateDateTime;
carrier.HasChildren = m.HasChildren;
carrier.Level = m.Level;
carrier.Path = m.Path;
carrier.SortOrder = m.sortOrder;
try
{
carrier.ParentId = m.Parent.Id;
}
catch
{
carrier.ParentId = -1;
}
foreach (Property p in m.getProperties)
{
mediaProperty carrierprop = new mediaProperty();
if (p.Value == System.DBNull.Value)
{
carrierprop.PropertyValue = "";
}
else
{
carrierprop.PropertyValue = p.Value;
}
carrierprop.Key = p.PropertyType.Alias;
carrier.MediaProperties.Add(carrierprop);
}
return carrier;
}
}
}
@@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace umbraco.webservices.members
{
[Serializable]
[XmlType(Namespace = "http://umbraco.org/webservices/")]
public class memberCarrier
{
public memberCarrier()
{
memberProperties = new List<memberProperty>();
groups = new List<memberGroup>();
}
#region Fields
private int id;
private string password;
private string email;
private string displayedName;
private string loginName;
private int membertypeId;
private string membertypeName;
private List<memberGroup> groups;
private List<memberProperty> memberProperties;
#endregion
#region Properties
public int Id
{
get { return id; }
set { id = value; }
}
public string DisplayedName
{
get { return displayedName; }
set { displayedName = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
public string Email
{
get { return email; }
set { email = value; }
}
public string LoginName
{
get { return loginName; }
set { loginName = value; }
}
public int MembertypeId
{
get { return membertypeId; }
set { membertypeId = value; }
}
public string MembertypeName
{
get { return membertypeName; }
set { membertypeName = value; }
}
public List<memberGroup> Groups
{
get { return groups; }
set { groups = value; }
}
public List<memberProperty> MemberProperties
{
get { return memberProperties; }
set { memberProperties = value; }
}
#endregion
}
}
@@ -1,34 +0,0 @@
using System;
namespace umbraco.webservices.members
{
[Serializable]
public class memberGroup
{
int groupID;
string groupName;
public memberGroup()
{
}
public memberGroup(int groupID, string groupName)
{
GroupID = groupID;
GroupName = groupName;
}
public int GroupID
{
get { return groupID; }
set { groupID = value; }
}
public string GroupName
{
get { return groupName; }
set { groupName = value; }
}
}
}
@@ -1,29 +0,0 @@
using System;
using System.Xml.Serialization;
namespace umbraco.webservices.members
{
[Serializable]
[XmlType(Namespace = "http://umbraco.org/webservices/")]
public class memberProperty
{
private string key;
private object propertyValue;
public memberProperty()
{
}
public object PropertyValue
{
get { return propertyValue; }
set { propertyValue = value; }
}
public string Key
{
get { return key; }
set { key = value; }
}
}
}
@@ -1,240 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.Services;
using umbraco.cms.businesslogic.member;
namespace umbraco.webservices.members
{
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class memberService : BaseWebService
{
override public Services Service
{
get
{
return Services.MemberService;
}
}
/// <summary>
/// Reads the user with the specified memberId
/// </summary>
/// <returns></returns>
[WebMethod]
public memberCarrier readByLogin(string memberLoginName, string memberPassword, string username, string password)
{
Authenticate(username, password);
umbraco.cms.businesslogic.member.Member foundMember = umbraco.cms.businesslogic.member.Member.GetMemberFromLoginNameAndPassword(memberLoginName, memberPassword);
if (foundMember == null)
return null;
return CreateMemberCarrier(foundMember);
}
/// <summary>
/// Reads the user with the specified memberId
/// </summary>
/// <returns></returns>
[WebMethod]
public memberCarrier readById(int memberId, string username, string password)
{
Authenticate(username, password);
umbraco.cms.businesslogic.member.Member foundMember = new umbraco.cms.businesslogic.member.Member(memberId);
if (foundMember == null)
return null;
return CreateMemberCarrier(foundMember);
}
/// <summary>
/// Reads the full list of members
/// </summary>
/// <returns></returns>
[WebMethod]
public List<memberCarrier> readList(string username, string password)
{
Authenticate(username, password);
Member[] members = Member.GetAll;
List<memberCarrier> Members = new List<memberCarrier>();
foreach (umbraco.cms.businesslogic.member.Member member in members)
{
Members.Add(CreateMemberCarrier(member));
}
return Members;
}
[WebMethod]
public void update(memberCarrier carrier, string username, string password)
{
Authenticate(username, password);
// Some validation
if (carrier.Id == 0) throw new Exception("ID must be specifed when updating");
if (carrier == null) throw new Exception("No carrier specified");
// Get the user
umbraco.BusinessLogic.User user = GetUser(username, password);
// We load the member
Member member = new Member(carrier.Id);
// We assign the new values:
member.LoginName = carrier.LoginName;
member.Text = carrier.DisplayedName;
member.Email = carrier.Email;
member.Password = carrier.Password;
// We iterate the properties in the carrier
if (carrier.MemberProperties != null)
{
foreach (memberProperty updatedproperty in carrier.MemberProperties)
{
umbraco.cms.businesslogic.property.Property property = member.getProperty(updatedproperty.Key);
if (property != null)
{
property.Value = updatedproperty.PropertyValue;
}
}
}
}
[WebMethod]
public int create(memberCarrier carrier, int memberTypeId, string username, string password)
{
Authenticate(username, password);
// Some validation
if (carrier == null) throw new Exception("No carrier specified");
if (carrier.Id != 0) throw new Exception("ID cannot be specifed when creating. Must be 0");
if (string.IsNullOrEmpty(carrier.DisplayedName)) carrier.DisplayedName = "unnamed";
// we fetch the membertype
umbraco.cms.businesslogic.member.MemberType mtype = new umbraco.cms.businesslogic.member.MemberType(memberTypeId);
// Check if the membertype exists
if (mtype == null) throw new Exception("Membertype " + memberTypeId + " not found");
// Get the user that creates
umbraco.BusinessLogic.User user = GetUser(username, password);
// Create the new member
umbraco.cms.businesslogic.member.Member newMember = umbraco.cms.businesslogic.member.Member.MakeNew(carrier.DisplayedName, mtype, user);
// We iterate the properties in the carrier
if (carrier.MemberProperties != null)
{
foreach (memberProperty updatedproperty in carrier.MemberProperties)
{
umbraco.cms.businesslogic.property.Property property = newMember.getProperty(updatedproperty.Key);
if (property != null)
{
property.Value = updatedproperty.PropertyValue;
}
}
}
return newMember.Id;
}
/// <summary>
/// Deletes the document with the specified ID
/// </summary>
/// <param name="id"></param>
/// <param name="cred"></param>
/// <returns></returns>
[WebMethod]
public void delete(int id, string username, string password)
{
Authenticate(username, password);
// We load the member
umbraco.cms.businesslogic.member.Member deleteMember;
try
{
deleteMember = new umbraco.cms.businesslogic.member.Member(id);
}
catch (Exception ex)
{
throw new Exception("Member not found" + ex.Message);
}
// We delete him (cruel world)
try
{
deleteMember.delete();
}
catch (Exception ex)
{
throw new Exception("Member could not be deleted" + ex.Message);
}
}
/// <summary>
/// Creates container-object for member
/// </summary>
/// <param name="member"></param>
/// <returns></returns>
private memberCarrier CreateMemberCarrier(umbraco.cms.businesslogic.member.Member member)
{
memberCarrier carrier = new memberCarrier();
carrier.Id = member.Id;
carrier.LoginName = member.LoginName;
carrier.DisplayedName = member.Text;
carrier.Email = member.Email;
carrier.Password = member.Password;
carrier.MembertypeId = member.ContentType.Id;
carrier.MembertypeName = member.ContentType.Text;
// Adding groups to member-carrier
IDictionaryEnumerator Enumerator;
Enumerator = member.Groups.GetEnumerator();
while (Enumerator.MoveNext())
{
memberGroup group = new memberGroup(Convert.ToInt32(Enumerator.Key), ((umbraco.cms.businesslogic.member.MemberGroup)Enumerator.Value).Text);
carrier.Groups.Add(group);
}
// Loading properties to carrier
var props = member.getProperties;
foreach (umbraco.cms.businesslogic.property.Property prop in props)
{
memberProperty carrierprop = new memberProperty();
if (prop.Value == System.DBNull.Value)
{
carrierprop.PropertyValue = null;
}
else
{
carrierprop.PropertyValue = prop.Value;
}
carrierprop.Key = prop.PropertyType.Alias;
carrier.MemberProperties.Add(carrierprop);
}
return carrier;
}
}
}
@@ -1,137 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.Services;
using umbraco.cms.businesslogic.web;
namespace umbraco.webservices.stylesheets
{
/// <summary>
/// Summary description for StylesheetService
/// </summary>
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class stylesheetService : BaseWebService
{
override public Services Service
{
get
{
return Services.StylesheetService;
}
}
[WebMethod]
public int create(stylesheetCarrier carrier, string username, string password)
{
Authenticate(username, password);
umbraco.BusinessLogic.User user = GetUser(username, password);
StyleSheet stylesheet = StyleSheet.MakeNew(user, carrier.Name, (carrier.Name + ".css"), carrier.Content);
stylesheet.saveCssToFile();
return stylesheet.Id;
}
[WebMethod]
public stylesheetCarrier read(int id, string username, string password)
{
Authenticate(username, password);
StyleSheet stylesheet;
try
{
stylesheet = new StyleSheet(id);
}
catch (Exception)
{
throw new Exception("Could not load stylesheet with id: " + id + ", not found");
}
if (stylesheet == null)
throw new Exception("Could not load stylesheet with id: " + id + ", not found");
return createCarrier(stylesheet);
}
[WebMethod]
public List<stylesheetCarrier> readList(string username, string password)
{
Authenticate(username, password);
List<stylesheetCarrier> stylesheets = new List<stylesheetCarrier>();
StyleSheet[] foundstylesheets = StyleSheet.GetAll();
foreach (StyleSheet stylesheet in foundstylesheets)
{
stylesheets.Add(createCarrier(stylesheet));
}
return stylesheets;
}
[WebMethod]
public void update(stylesheetCarrier carrier, string username, string password)
{
Authenticate(username, password);
StyleSheet stylesheet = null;
try
{
stylesheet = new StyleSheet(carrier.Id);
}
catch
{ }
if (stylesheet == null)
throw new Exception("Could not load stylesheet with id: " + carrier.Id);
stylesheet.Content = carrier.Content;
stylesheet.saveCssToFile();
}
private stylesheetCarrier createCarrier(StyleSheet stylesheet)
{
stylesheetCarrier carrier = new stylesheetCarrier();
carrier.Id = stylesheet.Id;
carrier.Name = stylesheet.Text;
carrier.Content = stylesheet.Content;
return carrier;
}
public class stylesheetCarrier
{
private int id;
private string name;
private string content;
public int Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Content
{
get { return content; }
set { content = value; }
}
}
}
}
@@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Services;
namespace umbraco.webservices.templates
{
/// <summary>
/// Summary description for TemplateService
/// </summary>
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class templateService : BaseWebService
{
override public Services Service
{
get
{
return Services.TemplateService;
}
}
[WebMethod]
public int readIdFromAlias(string alias, string username, string password)
{
Authenticate(username, password);
cms.businesslogic.template.Template template;
try
{
template = cms.businesslogic.template.Template.GetByAlias(alias, true);
}
catch (Exception)
{
throw new Exception("Could not load template from alias: " + alias);
}
if (template == null)
{
throw new Exception("Could not load template from alias: " + alias);
}
return template.Id;
}
[WebMethod]
public List<templateCarrier> readList(string username, string password)
{
Authenticate(username, password);
return cms.businesslogic.template.Template.GetAllAsList().Select(createTemplateCarrier).ToList();
}
[WebMethod]
public void delete(int id, string username, string password)
{
Authenticate(username, password);
if (id == 0)
throw new Exception("ID must be specifed when updating");
var template = new cms.businesslogic.template.Template(id);
template.delete();
}
[WebMethod]
public int create(templateCarrier carrier, string username, string password)
{
Authenticate(username, password);
if (carrier.Id != 0) throw new Exception("ID may not be specified when creating");
if (carrier == null) throw new Exception("No carrier specified");
// Get the user
BusinessLogic.User user = GetUser(username, password);
// Create template
var template = cms.businesslogic.template.Template.MakeNew(carrier.Name, user);
template.MasterTemplate = carrier.MastertemplateId;
template.Alias = carrier.Alias;
template.Text = carrier.Name;
template.Design = carrier.Design;
template.Save();
ClearCachedTemplate(template);
return template.Id;
}
[WebMethod]
public void update(templateCarrier carrier, string username, string password)
{
Authenticate(username, password);
if (carrier.Id == 0) throw new Exception("ID must be specifed when updating");
if (carrier == null) throw new Exception("No carrier specified");
cms.businesslogic.template.Template template;
try
{
template = new cms.businesslogic.template.Template(carrier.Id);
}
catch (Exception)
{
throw new Exception("Template with ID " + carrier.Id + " not found");
}
template.MasterTemplate = carrier.MastertemplateId;
template.Alias = carrier.Alias;
template.Text = carrier.Name;
template.Design = carrier.Design;
template.Save();
ClearCachedTemplate(template);
}
[WebMethod]
public templateCarrier read(int id, string username, string password)
{
Authenticate(username, password);
cms.businesslogic.template.Template template;
try
{
template = new cms.businesslogic.template.Template(id);
}
catch (Exception)
{
throw new Exception("Template with ID " + id + " not found");
}
if (template == null)
throw new Exception("Template with ID " + id + " not found");
return createTemplateCarrier(template);
}
public templateCarrier createTemplateCarrier(cms.businesslogic.template.Template template)
{
var carrier = new templateCarrier
{
Id = template.Id,
MastertemplateId = template.MasterTemplate,
Alias = template.Alias,
Name = template.Text,
Design = template.Design,
MasterPageFile = template.MasterPageFile
};
return carrier;
}
public class templateCarrier
{
public int Id { get; set; }
public int MastertemplateId { get; set; }
public string MasterPageFile { get; set; }
public string Name { get; set; }
public string Alias { get; set; }
public string Design { get; set; }
}
private static void ClearCachedTemplate(cms.businesslogic.template.Template cachedTemplate)
{
// Clear cache in rutime
if (UmbracoSettings.UseDistributedCalls)
presentation.cache.dispatcher.Refresh(new Guid("dd12b6a0-14b9-46e8-8800-c154f74047c8"), cachedTemplate.Id);
else
template.ClearCachedTemplate(cachedTemplate.Id);
}
}
}
@@ -1,162 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>umbraco.webservices</RootNamespace>
<AssemblyName>umbraco.webservices</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\umbraco.webservices.XML</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link>
</Compile>
<Compile Include="BaseWebService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Common.cs" />
<Compile Include="documents\documentCarrier.cs" />
<Compile Include="documents\documentProperty.cs" />
<Compile Include="files\fileService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="maintenance\maintenanceService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="media\mediaCarrier.cs" />
<Compile Include="media\mediaProperty.cs" />
<Compile Include="media\mediaService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="members\memberCarrier.cs" />
<Compile Include="members\memberGroup.cs" />
<Compile Include="members\memberProperty.cs" />
<Compile Include="members\memberService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="stylesheets\stylesheetService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="templates\templateService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="documents\documentService.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\umbraco.businesslogic\umbraco.businesslogic.csproj">
<Project>{E469A9CE-1BEC-423F-AC44-713CD72457EA}</Project>
<Name>umbraco.businesslogic</Name>
</ProjectReference>
<ProjectReference Include="..\umbraco.cms\umbraco.cms.csproj">
<Project>{CCD75EC3-63DB-4184-B49D-51C1DD337230}</Project>
<Name>umbraco.cms</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
<Project>{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}</Project>
<Name>Umbraco.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Web\Umbraco.Web.csproj">
<Project>{651E1350-91B6-44B7-BD60-7207006D7003}</Project>
<Name>umbraco.presentation</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>