diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000000..412eeda78dc
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000000..fa8446d1109
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,82 @@
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.vspscc
+.builds
+*.dotCover
+*.ldf
+
+## TODO: If you have NuGet Package Restore enabled, uncomment this
+#packages/
+
+# Visual Studio profiler
+*.psess
+*.vsp
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# Others
+[Bb]in
+[Oo]bj
+sql
+TestResults
+*.Cache
+ClientBin
+stylecop.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+
+############
+## DNN
+############
+
+[Dd]esktop[Mm]odules\DNNCorp
+[Dd]esktop[Mm]odules\DNNCorp\HTML
+[Dd]esktop[Mm]odules\DNNCorp\RazorModules
+[Dd]esktop[Mm]odules\DNNCorp
+
+
+############
+## Windows
+############
+
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
diff --git a/DNN Platform/Components/ClientDependency/Source/BaseLoader.cs b/DNN Platform/Components/ClientDependency/Source/BaseLoader.cs
new file mode 100644
index 00000000000..12634e0e792
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/BaseLoader.cs
@@ -0,0 +1,204 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using ClientDependency.Core.Controls;
+using ClientDependency.Core.FileRegistration.Providers;
+using ClientDependency.Core.Config;
+using System.Configuration.Provider;
+using System.Runtime.CompilerServices;
+
+//Make a 'friend' to mvc app
+[assembly: InternalsVisibleTo("ClientDependency.Core.Mvc")]
+
+namespace ClientDependency.Core
+{
+
+ public class BaseLoader
+ {
+
+ public BaseLoader(HttpContextBase http)
+ {
+ CurrentContext = http;
+ }
+
+ protected HttpContextBase CurrentContext { get; private set; }
+
+ public BaseFileRegistrationProvider Provider { get; set; }
+
+ ///
+ /// Tracks all dependencies and maintains a deduplicated list
+ ///
+ internal List Dependencies = new List();
+ ///
+ /// Tracks all paths and maintains a deduplicated list
+ ///
+ internal HashSet Paths = new HashSet();
+
+ ///
+ /// Adds a path to the current loader
+ ///
+ ///
+ ///
+ /// Returns the current loader instance so you can chain calls together
+ public BaseLoader AddPath(string pathNameAlias, string path)
+ {
+ AddPath(new BasicPath() { Name = pathNameAlias, Path = path });
+ return this;
+ }
+
+ ///
+ /// Adds a path to the current loader
+ ///
+ ///
+ /// Returns the current loader instance so you can chain calls together
+ public BaseLoader AddPath(IClientDependencyPath path)
+ {
+ Paths.Add(path);
+ return this;
+ }
+
+ ///
+ /// Registers dependencies with the specified provider.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// This is the top most overloaded method
+ ///
+ public void RegisterClientDependencies(BaseFileRegistrationProvider provider, IEnumerable dependencies, IEnumerable paths, ProviderCollection currProviders)
+ {
+ //find or create the ProviderDependencyList for the provider
+ ProviderDependencyList currList = Dependencies
+ .Where(x => x.ProviderIs(provider))
+ .DefaultIfEmpty(new ProviderDependencyList(provider))
+ .SingleOrDefault();
+
+ //add the dependencies that don't have a provider specified
+ currList.AddDependencies(dependencies
+ .Where(x => string.IsNullOrEmpty(x.ForceProvider)));
+
+ //add the list if it is new
+ if (!Dependencies.Contains(currList) && currList.Dependencies.Count > 0)
+ Dependencies.Add(currList);
+
+ //we need to look up all of the dependencies that have forced providers,
+ //check if we've got a provider list for it, create one if not and add the dependencies
+ //to it.
+ var allProviderNamesInList = dependencies
+ .Select(x => x.ForceProvider)
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Distinct();
+ var forceProviders = (from provName in allProviderNamesInList
+ where currProviders[provName] != null
+ select (BaseFileRegistrationProvider) currProviders[provName]).ToList();
+ foreach (var prov in forceProviders)
+ {
+ //find or create the ProviderDependencyList for the prov
+ var p = prov;
+ var forceList = Dependencies
+ .Where(x => x.ProviderIs(prov))
+ .DefaultIfEmpty(new ProviderDependencyList(prov))
+ .SingleOrDefault();
+ //add the dependencies that don't have a force provider specified
+ forceList.AddDependencies(dependencies
+ .Where(x => x.ForceProvider == p.Name));
+ //add the list if it is new
+ if (!Dependencies.Contains(forceList))
+ Dependencies.Add(forceList);
+ }
+
+ //add the paths, ensure no dups
+ Paths.UnionWith(paths);
+ }
+
+ public void RegisterClientDependencies(List dependencies, params IClientDependencyPath[] paths)
+ {
+ RegisterClientDependencies(Provider, dependencies, paths, ClientDependencySettings.Instance.MvcRendererCollection);
+ }
+
+ public void RegisterClientDependencies(List dependencies, IEnumerable paths)
+ {
+ RegisterClientDependencies(Provider, dependencies, paths, ClientDependencySettings.Instance.MvcRendererCollection);
+ }
+
+
+
+ #region RegisterDependency overloads
+
+ public void RegisterDependency(string filePath, ClientDependencyType type)
+ {
+ RegisterDependency(filePath, "", type);
+ }
+
+ public void RegisterDependency(string filePath, ClientDependencyType type, object htmlAttributes)
+ {
+ RegisterDependency(filePath, "", type, htmlAttributes);
+ }
+
+ public void RegisterDependency(int priority, string filePath, ClientDependencyType type)
+ {
+ RegisterDependency(priority, filePath, "", type);
+ }
+
+ public void RegisterDependency(int priority, string filePath, ClientDependencyType type, object htmlAttributes)
+ {
+ RegisterDependency(priority, filePath, "", type, htmlAttributes);
+ }
+
+ public void RegisterDependency(string filePath, string pathNameAlias, ClientDependencyType type)
+ {
+ RegisterDependency(Constants.DefaultPriority, filePath, pathNameAlias, type);
+ }
+
+ public void RegisterDependency(string filePath, string pathNameAlias, ClientDependencyType type, object htmlAttributes)
+ {
+ RegisterDependency(Constants.DefaultPriority, filePath, pathNameAlias, type, htmlAttributes);
+ }
+
+ ///
+ /// Dynamically registers a dependency into the loader at runtime.
+ /// This is similar to ScriptManager.RegisterClientScriptInclude.
+ /// Registers a file dependency with the default provider.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RegisterDependency(int priority, string filePath, string pathNameAlias, ClientDependencyType type)
+ {
+ RegisterDependency(Constants.DefaultGroup, priority, filePath, pathNameAlias, type);
+ }
+
+ public void RegisterDependency(int priority, string filePath, string pathNameAlias, ClientDependencyType type, object htmlAttributes)
+ {
+ RegisterDependency(Constants.DefaultGroup, priority, filePath, pathNameAlias, type, htmlAttributes);
+ }
+
+ public void RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type)
+ {
+ IClientDependencyFile file = new BasicFile(type) { Group = group, Priority = priority, FilePath = filePath, PathNameAlias = pathNameAlias };
+ RegisterClientDependencies(new List { file }, new List()); //send an empty paths collection
+ }
+
+ public void RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type, object htmlAttributes)
+ {
+ var file = new BasicFile(type) { Group = group, Priority = priority, FilePath = filePath, PathNameAlias = pathNameAlias };
+
+ //now add the attributes to the list
+ foreach(var d in htmlAttributes.ToDictionary())
+ {
+ file.HtmlAttributes.Add(d.Key, d.Value.ToString());
+ }
+
+ RegisterClientDependencies(new List { file }, new List()); //send an empty paths collection
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/BasicFile.cs b/DNN Platform/Components/ClientDependency/Source/BasicFile.cs
new file mode 100644
index 00000000000..de58c3d9636
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/BasicFile.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClientDependency.Core
+{
+ public class BasicFile : IClientDependencyFile, IHaveHtmlAttributes
+ {
+ public BasicFile(ClientDependencyType type)
+ {
+ DependencyType = type;
+ HtmlAttributes = new Dictionary();
+ }
+
+ #region IClientDependencyFile Members
+
+ public string FilePath { get; set; }
+ public ClientDependencyType DependencyType { get; private set; }
+ public int Priority { get; set; }
+ public int Group { get; set; }
+ public string PathNameAlias { get; set; }
+ ///
+ /// This can be empty and will use default provider
+ ///
+ public string ForceProvider { get; set; }
+ public bool ForceBundle { get; set; }
+
+ ///
+ /// Used to store additional attributes in the HTML markup for the item
+ ///
+ ///
+ /// Mostly used for CSS Media, but could be for anything
+ ///
+ public IDictionary HtmlAttributes { get; private set; }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/BasicPath.cs b/DNN Platform/Components/ClientDependency/Source/BasicPath.cs
new file mode 100644
index 00000000000..e81410bae42
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/BasicPath.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.Web.UI;
+
+namespace ClientDependency.Core
+{
+ public class BasicPath : IClientDependencyPath
+ {
+ public BasicPath() { }
+ public BasicPath(string name, string path)
+ {
+ Name = name;
+ Path = path;
+ }
+
+ public string Name { get; set; }
+ public string Path { get; set; }
+ public bool ForceBundle { get; set; }
+ }
+}
+
diff --git a/DNN Platform/Components/ClientDependency/Source/ClientDependency.Core.csproj b/DNN Platform/Components/ClientDependency/Source/ClientDependency.Core.csproj
new file mode 100644
index 00000000000..ce281d23658
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/ClientDependency.Core.csproj
@@ -0,0 +1,166 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {3B64E72E-63CC-4A90-ADFF-4B919EF17239}
+ Library
+ Properties
+ ClientDependency.Core
+ ClientDependency.Core
+ v4.0
+ 512
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+ 3.5
+
+
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\
+ TRACE;MVC
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+
+ 3.5
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/ClientDependencyAttribute.cs b/DNN Platform/Components/ClientDependency/Source/ClientDependencyAttribute.cs
new file mode 100644
index 00000000000..ab383282548
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/ClientDependencyAttribute.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ClientDependency.Core
+{
+ ///
+ /// This attribute is used for data types that uses client assets like Javascript and CSS for liveediting.
+ /// The Live Editing feature in umbraco will look for this attribute and preload all dependencies to the page
+ /// to ensure that all client events and assets gets loaded
+ ///
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class ClientDependencyAttribute : Attribute, IClientDependencyFile, IRequiresHtmlAttributesParsing
+ {
+ public ClientDependencyAttribute()
+ {
+ Priority = Constants.DefaultPriority;
+ Group = Constants.DefaultGroup;
+ PathNameAlias = "";
+ HtmlAttributes = new Dictionary();
+ }
+
+ public ClientDependencyAttribute(ClientDependencyType dependencyType, string fullFilePath)
+ : this(Constants.DefaultPriority, dependencyType, fullFilePath, string.Empty)
+ { }
+
+ public ClientDependencyAttribute(ClientDependencyType dependencyType, string fileName, string pathNameAlias)
+ : this(Constants.DefaultPriority, dependencyType, fileName, pathNameAlias)
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The priority.
+ /// Type of the dependency.
+ /// The file path to the dependency.
+ public ClientDependencyAttribute(int priority, ClientDependencyType dependencyType, string fullFilePath)
+ : this(priority, dependencyType, fullFilePath, string.Empty)
+ { }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The priority.
+ /// Type of the dependency.
+ ///
+ ///
+ public ClientDependencyAttribute(int priority, ClientDependencyType dependencyType, string fileName, string pathNameAlias)
+ : this(Constants.DefaultGroup, priority, dependencyType, fileName, pathNameAlias, false)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The priority.
+ /// Type of the dependency.
+ ///
+ ///
+ public ClientDependencyAttribute(int group, int priority, ClientDependencyType dependencyType, string fileName, string pathNameAlias, bool forceBundle)
+ {
+ if (String.IsNullOrEmpty(fileName))
+ throw new ArgumentNullException("fileName");
+
+ Priority = priority;
+
+ Group = group;
+
+ FilePath = fileName;
+ PathNameAlias = pathNameAlias;
+
+ DependencyType = dependencyType;
+ ForceBundle = forceBundle;
+
+ HtmlAttributes = new Dictionary();
+ }
+
+
+ ///
+ /// Gets or sets the priority.
+ ///
+ /// The priority.
+ public int Priority { get; set; }
+
+ ///
+ /// Gets or sets the group.
+ ///
+ /// The group.
+ public int Group { get; set; }
+
+ ///
+ /// This can be empty and will use default provider
+ ///
+ public string ForceProvider { get; set; }
+
+ public bool ForceBundle { get; set; }
+
+ ///
+ /// Gets or sets the file path.
+ ///
+ /// The file path.
+ public string FilePath { get; set; }
+
+ ///
+ /// The path alias to be pre-pended to the file path if specified.
+ /// The alias is specified in in the ClientDependencyHelper constructor.
+ /// If the alias specified does not exist in the ClientDependencyHelper
+ /// path collection, an exception is thrown.
+ ///
+ public string PathNameAlias { get; set; }
+
+ ///
+ /// Used to set the HtmlAttributes on this class via a string which is parsed
+ ///
+ ///
+ /// The syntax for the string must be: key1:value1,key2:value2 etc...
+ ///
+ public string HtmlAttributesAsString { get; set; }
+
+ ///
+ /// Used to store additional attributes in the HTML markup for the item
+ ///
+ ///
+ /// Mostly used for CSS Media, but could be for anything
+ ///
+ public IDictionary HtmlAttributes { get; private set; }
+
+ ///
+ /// Gets or sets the type of the dependency.
+ ///
+ /// The type of the dependency.
+ public ClientDependencyType DependencyType { get; set; }
+ }
+
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/ClientDependencyType.cs b/DNN Platform/Components/ClientDependency/Source/ClientDependencyType.cs
new file mode 100644
index 00000000000..47fa3b63357
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/ClientDependencyType.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ClientDependency.Core
+{
+ ///
+ /// The type of client file
+ ///
+ public enum ClientDependencyType
+ {
+ Javascript, Css
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CSSMin.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CSSMin.cs
new file mode 100644
index 00000000000..b7462372317
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CSSMin.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace ClientDependency.Core.CompositeFiles
+{
+ public class CssMin
+ {
+
+ public static string CompressCSS(string body)
+ {
+ body = Regex.Replace(body, @"[\n\r]+\s*", string.Empty);
+ body = Regex.Replace(body, @"\s+", " ");
+ body = Regex.Replace(body, @"\s?([:,;{}])\s?", "$1");
+ body = Regex.Replace(body, @"([\s:]0)(px|pt|%|em)", "$1");
+ body = Regex.Replace(body, @"/\*[\d\D]*?\*/", string.Empty);
+ return body;
+
+ }
+
+ }
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeDependencyHandler.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeDependencyHandler.cs
new file mode 100644
index 00000000000..4b1fc73e780
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeDependencyHandler.cs
@@ -0,0 +1,296 @@
+using System;
+using System.Collections.Generic;
+using System.Web;
+using System.Reflection;
+using System.IO;
+using System.Linq;
+using ClientDependency.Core.CompositeFiles.Providers;
+using ClientDependency.Core.Config;
+using System.Text;
+using System.Web.Security;
+
+namespace ClientDependency.Core.CompositeFiles
+{
+ public class CompositeDependencyHandler : IHttpHandler
+ {
+ private readonly static object Lock = new object();
+
+ ///
+ /// When building composite includes, it creates a Base64 encoded string of all of the combined dependency file paths
+ /// for a given composite group. If this group contains too many files, then the file path with the query string will be very long.
+ /// This is the maximum allowed number of characters that there is allowed, otherwise an exception is thrown.
+ ///
+ ///
+ /// If this handler path needs to change, it can be changed by setting it in the global.asax on application start
+ ///
+ public static int MaxHandlerUrlLength = 2048;
+
+ bool IHttpHandler.IsReusable
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ void IHttpHandler.ProcessRequest(HttpContext context)
+ {
+ var contextBase = new HttpContextWrapper(context);
+
+ ClientDependencyType type;
+ string fileset;
+ int version = 0;
+
+ if (string.IsNullOrEmpty(context.Request.PathInfo))
+ {
+ // querystring format
+ fileset = context.Request["s"];
+ if (!string.IsNullOrEmpty(context.Request["cdv"]) && !Int32.TryParse(context.Request["cdv"], out version))
+ throw new ArgumentException("Could not parse the version in the request");
+ try
+ {
+ type = (ClientDependencyType)Enum.Parse(typeof(ClientDependencyType), context.Request["t"], true);
+ }
+ catch
+ {
+ throw new ArgumentException("Could not parse the type set in the request");
+ }
+ }
+ else
+ {
+
+ // path format
+ var segs = context.Request.PathInfo.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ fileset = "";
+ int i = 0;
+ while (i < segs.Length - 1)
+ fileset += segs[i++];
+ int pos;
+ pos = segs[i].IndexOf('.');
+ if (pos < 0)
+ throw new ArgumentException("Could not parse the type set in the request");
+ fileset += segs[i].Substring(0, pos);
+ string ext = segs[i].Substring(pos + 1);
+ pos = ext.IndexOf('.');
+ if (pos > 0)
+ {
+ if (!Int32.TryParse(ext.Substring(0, pos), out version))
+ throw new ArgumentException("Could not parse the version in the request");
+ ext = ext.Substring(pos + 1);
+ }
+ ext = ext.ToLower();
+ if (ext == "js")
+ type = ClientDependencyType.Javascript;
+ else if (ext == "css")
+ type = ClientDependencyType.Css;
+ else
+ throw new ArgumentException("Could not parse the type set in the request");
+
+ }
+
+ fileset = context.Server.UrlDecode(fileset);
+
+ if (string.IsNullOrEmpty(fileset))
+ throw new ArgumentException("Must specify a fileset in the request");
+
+ byte[] outputBytes = null;
+
+ //retry up to 5 times... this is only here due to a bug found in another website that was returning a blank
+ //result. To date, it can't be replicated in VS, but we'll leave it here for error handling support... can't hurt
+ for (int i = 0; i < 5; i++)
+ {
+ outputBytes = ProcessRequestInternal(contextBase, fileset, type, version, outputBytes);
+ if (outputBytes != null && outputBytes.Length > 0)
+ break;
+
+ ClientDependencySettings.Instance.Logger.Error(string.Format("No bytes were returned, this is attempt {0}. Fileset: {1}, Type: {2}, Version: {3}", i, fileset, type, version), null);
+ }
+
+ if (outputBytes == null || outputBytes.Length == 0)
+ {
+ ClientDependencySettings.Instance.Logger.Fatal(string.Format("No bytes were returned after 5 attempts. Fileset: {0}, Type: {1}, Version: {2}", fileset, type, version), null);
+ List fDefs;
+ outputBytes = GetCombinedFiles(contextBase, fileset, type, out fDefs);
+ }
+
+ context.Response.ContentType = type == ClientDependencyType.Javascript ? "application/x-javascript" : "text/css";
+ context.Response.OutputStream.Write(outputBytes, 0, outputBytes.Length);
+ }
+
+ internal byte[] ProcessRequestInternal(HttpContextBase context, string fileset, ClientDependencyType type, int version, byte[] outputBytes)
+ {
+ //get the compression type supported
+ var clientCompression = context.GetClientCompression();
+
+ //get the map to the composite file for this file set, if it exists.
+ var map = ClientDependencySettings.Instance.DefaultFileMapProvider.GetCompositeFile(fileset, version, clientCompression.ToString());
+
+ string compositeFileName = "";
+ if (map != null && map.HasFileBytes)
+ {
+ ProcessFromFile(context, map, out compositeFileName, out outputBytes);
+ }
+ else
+ {
+ lock (Lock)
+ {
+ //check again...
+ if (map != null && map.HasFileBytes)
+ {
+ //there's files there now, so process them
+ ProcessFromFile(context, map, out compositeFileName, out outputBytes);
+ }
+ else
+ {
+ List fileDefinitions;
+ byte[] fileBytes;
+
+ if (ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.UrlType == CompositeUrlType.MappedId)
+ {
+ //need to try to find the map by it's id/version (not compression)
+ var filePaths = ClientDependencySettings.Instance.DefaultFileMapProvider.GetDependentFiles(fileset, version);
+
+ if (filePaths == null)
+ {
+ throw new KeyNotFoundException("no map was found for the dependency key: " + fileset +
+ " ,CompositeUrlType.MappedId requires that a map is found");
+ }
+
+ //combine files and get the definition types of them (internal vs external resources)
+ fileBytes = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider
+ .CombineFiles(filePaths.ToArray(), context, type, out fileDefinitions);
+ }
+ else
+ {
+ //need to do the combining, etc... and save the file map
+ fileBytes = GetCombinedFiles(context, fileset, type, out fileDefinitions);
+ }
+
+ //compress data
+ outputBytes = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.CompressBytes(clientCompression, fileBytes);
+ context.AddCompressionResponseHeader(clientCompression);
+
+ //save combined file
+ var compositeFile = ClientDependencySettings.Instance
+ .DefaultCompositeFileProcessingProvider
+ .SaveCompositeFile(outputBytes, type, context.Server, version);
+
+ if (compositeFile != null)
+ {
+ compositeFileName = compositeFile.FullName;
+ if (!string.IsNullOrEmpty(compositeFileName))
+ {
+ //Update the XML file map
+ ClientDependencySettings.Instance.DefaultFileMapProvider.CreateUpdateMap(fileset, clientCompression.ToString(),
+ fileDefinitions.Select(x => new BasicFile(type) { FilePath = x.Uri }).Cast(),
+ compositeFileName,
+ version);
+ }
+ }
+ }
+ }
+ }
+
+ SetCaching(context, compositeFileName, fileset, clientCompression);
+ return outputBytes;
+ }
+
+ private byte[] GetCombinedFiles(HttpContextBase context, string fileset, ClientDependencyType type, out List fDefs)
+ {
+ //get the file list
+ string[] filePaths = fileset.DecodeFrom64Url().Split(';');
+ //combine files and get the definition types of them (internal vs external resources)
+ return ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.CombineFiles(filePaths, context, type, out fDefs);
+ }
+
+ private void ProcessFromFile(HttpContextBase context, CompositeFileMap map, out string compositeFileName, out byte[] outputBytes)
+ {
+ //the saved file's bytes are already compressed.
+ outputBytes = map.GetCompositeFileBytes();
+ compositeFileName = map.CompositeFileName;
+ CompressionType cType = (CompressionType)Enum.Parse(typeof(CompressionType), map.CompressionType);
+ context.AddCompressionResponseHeader(cType);
+ }
+
+ ///
+ /// Sets the output cache parameters and also the client side caching parameters
+ ///
+ ///
+ /// The name of the file that has been saved to disk
+ /// The Base64 encoded string supplied in the query string for the handler
+ ///
+ private void SetCaching(HttpContextBase context, string fileName, string fileset, CompressionType compressionType)
+ {
+ if (string.IsNullOrEmpty(fileName))
+ {
+ ClientDependencySettings.Instance.Logger.Error("ClientDependency handler path is null", new Exception());
+ return;
+ }
+
+ //This ensures OutputCaching is set for this handler and also controls
+ //client side caching on the browser side. Default is 10 days.
+ var duration = TimeSpan.FromDays(10);
+ var cache = context.Response.Cache;
+ cache.SetCacheability(HttpCacheability.Public);
+
+ cache.SetExpires(DateTime.Now.Add(duration));
+ cache.SetMaxAge(duration);
+ cache.SetValidUntilExpires(true);
+ cache.SetLastModified(DateTime.Now);
+
+ cache.SetETag("\"" + FormsAuthentication.HashPasswordForStoringInConfigFile(fileset + compressionType.ToString(), "MD5") + "\"");
+
+ //set server OutputCache to vary by our params
+
+ /* // proper way to do it is to have
+ * cache.SetVaryByCustom("cdparms");
+ *
+ * // then have this in global.asax
+ * public override string GetVaryByCustomString(HttpContext context, string arg)
+ * {
+ * if (arg == "cdparms")
+ * {
+ * if (string.IsNullOrEmpty(context.Request.PathInfo))
+ * {
+ * // querystring format
+ * return context.Request["s"] + "+" + context.Request["t"] + "+" + (context.Request["v"] ?? "0");
+ * }
+ * else
+ * {
+ * // path format
+ * return context.Request.PathInfo.Replace('/', '');
+ * }
+ * }
+ * }
+ *
+ * // that way, there would be one cache entry for both querystring and path formats.
+ * // but, it requires a global.asax and I can't find a way to do without it.
+ */
+
+ // in any case, cache already varies by pathInfo (build-in) so for path formats, we do not need anything
+ // just add params for querystring format, just in case...
+ cache.VaryByParams["t"] = true;
+ cache.VaryByParams["s"] = true;
+ cache.VaryByParams["cdv"] = true;
+
+ //ensure the cache is different based on the encoding specified per browser
+ cache.VaryByContentEncodings["gzip"] = true;
+ cache.VaryByContentEncodings["deflate"] = true;
+
+ //don't allow varying by wildcard
+ cache.SetOmitVaryStar(true);
+ //ensure client browser maintains strict caching rules
+ cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
+
+ //This is the only way to set the max-age cachability header in ASP.Net!
+ //FieldInfo maxAgeField = cache.GetType().GetField("_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
+ //maxAgeField.SetValue(cache, duration);
+
+ //make this output cache dependent on the file if there is one.
+ if (!string.IsNullOrEmpty(fileName))
+ context.Response.AddFileDependency(fileName);
+ }
+
+ }
+}
+
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeFileDefinition.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeFileDefinition.cs
new file mode 100644
index 00000000000..9504fd56afa
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeFileDefinition.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClientDependency.Core.Config;
+using System.IO;
+using System.Web;
+using System.Net;
+using System.IO.Compression;
+
+namespace ClientDependency.Core.CompositeFiles
+{
+ ///
+ /// A simple class defining a Uri string and whether or not it is a local application file
+ ///
+ public class CompositeFileDefinition
+ {
+ public CompositeFileDefinition(string uri, bool isLocalFile)
+ {
+ IsLocalFile = isLocalFile;
+ Uri = uri;
+ }
+ public bool IsLocalFile { get; set; }
+ public string Uri { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ return (obj.GetType().Equals(this.GetType())
+ && ((CompositeFileDefinition)obj).IsLocalFile.Equals(IsLocalFile)
+ && ((CompositeFileDefinition)obj).Uri.Equals(Uri));
+ }
+
+ ///
+ /// overrides hash code to ensure that it is unique per machine
+ ///
+ ///
+ public override int GetHashCode()
+ {
+ string machineName;
+ //catch usecase where user is running with EnvironmentPermission
+ try
+ {
+ machineName=Environment.MachineName;
+ }
+ catch (Exception)
+ {
+ machineName = HttpContext.Current.Server.MachineName;
+ }
+ return (machineName.ToString() + Uri).GetHashCode();
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeFileMap.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeFileMap.cs
new file mode 100644
index 00000000000..7a38d2c0b82
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/CompositeFileMap.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+using System.IO;
+
+namespace ClientDependency.Core.CompositeFiles
+{
+ ///
+ /// Deserialized structure of the XML stored in the map file
+ ///
+ public class CompositeFileMap
+ {
+
+ internal CompositeFileMap(string key, string compressionType, string file, IEnumerable filePaths, int version)
+ {
+ DependentFiles = filePaths;
+ FileKey = key;
+ CompositeFileName = file;
+ CompressionType = compressionType;
+ Version = version;
+ }
+
+ public string FileKey { get; private set; }
+ public string CompositeFileName { get; private set; }
+ public string CompressionType { get; private set; }
+ public int Version { get; private set; }
+ public IEnumerable DependentFiles { get; private set; }
+
+ private byte[] m_FileBytes;
+
+ ///
+ /// If for some reason the file doesn't exist any more or we cannot read the file, this will return false.
+ ///
+ public bool HasFileBytes
+ {
+ get
+ {
+ GetCompositeFileBytes();
+ return m_FileBytes != null;
+ }
+ }
+
+ ///
+ /// Returns the file's bytes
+ ///
+ public byte[] GetCompositeFileBytes()
+ {
+ if (m_FileBytes == null)
+ {
+ if (string.IsNullOrEmpty(CompositeFileName))
+ {
+ return null;
+ }
+
+ try
+ {
+ FileInfo fi = new FileInfo(CompositeFileName);
+ FileStream fs = fi.OpenRead();
+ byte[] fileBytes = new byte[fs.Length];
+ fs.Read(fileBytes, 0, fileBytes.Length);
+ fs.Close();
+ m_FileBytes = fileBytes;
+ }
+ catch
+ {
+ m_FileBytes = null;
+ }
+ }
+ return m_FileBytes;
+ }
+
+
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/JSMin.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/JSMin.cs
new file mode 100644
index 00000000000..e500c645060
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/JSMin.cs
@@ -0,0 +1,345 @@
+using System;
+using System.IO;
+using System.Text;
+
+/* Originally written in 'C', this code has been converted to the C# language.
+ * The author's copyright message is reproduced below.
+ * All modifications from the original to C# are placed in the public domain.
+ */
+
+/* jsmin.c
+ 2007-05-22
+
+Copyright (c) 2002 Douglas Crockford (www.crockford.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+namespace ClientDependency.Core.CompositeFiles
+{
+ public class JSMin
+ {
+ const int EOF = -1;
+
+ StringReader sr;
+ StringWriter sw;
+ int theA;
+ int theB;
+ int theLookahead = EOF;
+
+ public static string CompressJS(string body)
+ {
+ return new JSMin().Minify(body);
+ }
+
+ public string Minify(string src)
+ {
+ StringBuilder sb = new StringBuilder();
+ using (sr = new StringReader(src))
+ {
+ using (sw = new StringWriter(sb))
+ {
+ jsmin();
+ }
+ }
+ return sb.ToString();
+ }
+
+ /* jsmin -- Copy the input to the output, deleting the characters which are
+ insignificant to JavaScript. Comments will be removed. Tabs will be
+ replaced with spaces. Carriage returns will be replaced with linefeeds.
+ Most spaces and linefeeds will be removed.
+ */
+ void jsmin()
+ {
+ theA = '\n';
+ action(3);
+ while (theA != EOF)
+ {
+ switch (theA)
+ {
+ case ' ':
+ {
+ if (isAlphanum(theB))
+ {
+ action(1);
+ }
+ else
+ {
+ action(2);
+ }
+ break;
+ }
+ case '\n':
+ {
+ switch (theB)
+ {
+ case '{':
+ case '[':
+ case '(':
+ case '+':
+ case '-':
+ {
+ action(1);
+ break;
+ }
+ case ' ':
+ {
+ action(3);
+ break;
+ }
+ default:
+ {
+ if (isAlphanum(theB))
+ {
+ action(1);
+ }
+ else
+ {
+ action(2);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ switch (theB)
+ {
+ case ' ':
+ {
+ if (isAlphanum(theA))
+ {
+ action(1);
+ break;
+ }
+ action(3);
+ break;
+ }
+ case '\n':
+ {
+ switch (theA)
+ {
+ case '}':
+ case ']':
+ case ')':
+ case '+':
+ case '-':
+ case '"':
+ case '\'':
+ {
+ action(1);
+ break;
+ }
+ default:
+ {
+ if (isAlphanum(theA))
+ {
+ action(1);
+ }
+ else
+ {
+ action(3);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ action(1);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ /* action -- do something! What you do is determined by the argument:
+ 1 Output A. Copy B to A. Get the next B.
+ 2 Copy B to A. Get the next B. (Delete A).
+ 3 Get the next B. (Delete B).
+ action treats a string as a single character. Wow!
+ action recognizes a regular expression if it is preceded by ( or , or =.
+ */
+ void action(int d)
+ {
+ if (d <= 1)
+ {
+ put(theA);
+ }
+ if (d <= 2)
+ {
+ theA = theB;
+ if (theA == '\'' || theA == '"')
+ {
+ for (; ; )
+ {
+ put(theA);
+ theA = get();
+ if (theA == theB)
+ {
+ break;
+ }
+ if (theA <= '\n')
+ {
+ throw new Exception(string.Format("Error: JSMIN unterminated string literal: {0}\n", theA));
+ }
+ if (theA == '\\')
+ {
+ put(theA);
+ theA = get();
+ }
+ }
+ }
+ }
+ if (d <= 3)
+ {
+ theB = next();
+ if (theB == '/' && (theA == '(' || theA == ',' || theA == '=' ||
+ theA == '[' || theA == '!' || theA == ':' ||
+ theA == '&' || theA == '|' || theA == '?' ||
+ theA == '{' || theA == '}' || theA == ';' ||
+ theA == '\n'))
+ {
+ put(theA);
+ put(theB);
+ for (; ; )
+ {
+ theA = get();
+ if (theA == '/')
+ {
+ break;
+ }
+ else if (theA == '\\')
+ {
+ put(theA);
+ theA = get();
+ }
+ else if (theA <= '\n')
+ {
+ throw new Exception(string.Format("Error: JSMIN unterminated Regular Expression literal : {0}.\n", theA));
+ }
+ put(theA);
+ }
+ theB = next();
+ }
+ }
+ }
+ /* next -- get the next character, excluding comments. peek() is used to see
+ if a '/' is followed by a '/' or '*'.
+ */
+ int next()
+ {
+ int c = get();
+ if (c == '/')
+ {
+ switch (peek())
+ {
+ case '/':
+ {
+ for (; ; )
+ {
+ c = get();
+ if (c <= '\n')
+ {
+ return c;
+ }
+ }
+ }
+ case '*':
+ {
+ get();
+ for (; ; )
+ {
+ switch (get())
+ {
+ case '*':
+ {
+ if (peek() == '/')
+ {
+ get();
+ return ' ';
+ }
+ break;
+ }
+ case EOF:
+ {
+ throw new Exception("Error: JSMIN Unterminated comment.\n");
+ }
+ }
+ }
+ }
+ default:
+ {
+ return c;
+ }
+ }
+ }
+ return c;
+ }
+ /* peek -- get the next character without getting it.
+ */
+ int peek()
+ {
+ theLookahead = get();
+ return theLookahead;
+ }
+ /* get -- return the next character from stdin. Watch out for lookahead. If
+ the character is a control character, translate it to a space or
+ linefeed.
+ */
+ int get()
+ {
+ int c = theLookahead;
+ theLookahead = EOF;
+ if (c == EOF)
+ {
+ c = sr.Read();
+ }
+ if (c >= ' ' || c == '\n' || c == EOF)
+ {
+ return c;
+ }
+ if (c == '\r')
+ {
+ return '\n';
+ }
+ return ' ';
+ }
+ void put(int c)
+ {
+ sw.Write((char)c);
+ }
+ /* isAlphanum -- return true if the character is a letter, digit, underscore,
+ dollar sign, or non-ASCII character.
+ */
+ bool isAlphanum(int c)
+ {
+ return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' || c == '+' ||
+ c > 126);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/BaseCompositeFileProcessingProvider.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/BaseCompositeFileProcessingProvider.cs
new file mode 100644
index 00000000000..2daefc54a4a
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/BaseCompositeFileProcessingProvider.cs
@@ -0,0 +1,450 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClientDependency.Core.Config;
+using System.IO;
+using System.Web;
+using System.Net;
+using System.Configuration.Provider;
+
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+ public abstract class BaseCompositeFileProcessingProvider : ProviderBase, IHttpProvider
+ {
+
+ private const string DefaultDependencyPath = "~/App_Data/ClientDependency";
+ private readonly string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
+
+ ///
+ /// The path specified in the config
+ ///
+ private string _compositeFilePath;
+
+ ///
+ /// constructor sets defaults
+ ///
+ protected BaseCompositeFileProcessingProvider()
+ {
+ PersistCompositeFiles = true;
+ EnableCssMinify = true;
+ EnableJsMinify = true;
+ UrlType = CompositeUrlType.MappedId;
+
+ _compositeFilePath = DefaultDependencyPath;
+ }
+
+ #region Public Properties
+
+ ///
+ /// Flags whether or not to enable composite file script creation/persistence.
+ /// Composite file persistence will increase performance in the case of cache turnover or application
+ /// startup since the files are already combined and compressed.
+ /// This also allows for the ability to easily clear the cache so the files are refreshed.
+ ///
+ public bool PersistCompositeFiles { get; set; }
+ public bool EnableCssMinify { get; set; }
+ public bool EnableJsMinify { get; set; }
+
+ ///
+ /// The Url type to use for the dependency handler
+ ///
+ public CompositeUrlType UrlType { get; protected set; }
+
+ ///
+ /// Returns the CompositeFilePath
+ ///
+ ///
+ public DirectoryInfo CompositeFilePath { get; protected set; }
+
+ ///
+ /// Returns the set of white listed domains
+ ///
+ public IList BundleDomains { get; protected set; }
+
+ #endregion
+
+ #region IHttpProvider Members
+
+ public void Initialize(HttpContextBase http)
+ {
+ CompositeFilePath = new DirectoryInfo(http.Server.MapPath(_compositeFilePath));
+ }
+
+ #endregion
+
+ public abstract FileInfo SaveCompositeFile(byte[] fileContents, ClientDependencyType type, HttpServerUtilityBase server, int version);
+ public abstract byte[] CombineFiles(string[] filePaths, HttpContextBase context, ClientDependencyType type, out List fileDefs);
+ public abstract byte[] CompressBytes(CompressionType type, byte[] fileBytes);
+
+ ///
+ /// Returns a URL used to return a compbined/compressed/optimized version of all dependencies.
+ ///
+ /// The full url with the encoded query strings for the handler which will process the composite list
+ /// of dependencies. The handler will compbine, compress, minify, and output cache the results
+ /// on the base64 encoded string.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// An array containing the list of composite file URLs. This will generally only contain 1 value unless
+ /// the number of files registered exceeds the maximum length, then it will return more than one file.
+ public virtual string[] ProcessCompositeList(
+ IEnumerable dependencies,
+ ClientDependencyType type,
+ HttpContextBase http)
+ {
+ if (!dependencies.Any())
+ return new string[] { };
+
+ switch (UrlType)
+ {
+ case CompositeUrlType.MappedId:
+
+ //use the file mapper to create us a file key/id for the file set
+ var fileKey = ClientDependencySettings.Instance.DefaultFileMapProvider.CreateNewMap(http, dependencies, GetVersion());
+
+ //create the url
+ return new[] { GetCompositeFileUrl(fileKey, type, http, CompositeUrlType.MappedId) };
+
+ default:
+
+ //build the combined composite list urls
+
+ var files = new List();
+ var currBuilder = new StringBuilder();
+ var base64Builder = new StringBuilder();
+ var builderCount = 1;
+ var stringType = type.ToString();
+ foreach (var a in dependencies)
+ {
+ //update the base64 output to get the length
+ base64Builder.Append(a.FilePath.EncodeTo64());
+
+ //test if the current base64 string exceeds the max length, if so we need to split
+ if ((base64Builder.Length + ClientDependencySettings.Instance.CompositeFileHandlerPath.Length + stringType.Length + 10)
+ >= (CompositeDependencyHandler.MaxHandlerUrlLength))
+ {
+ //add the current output to the array
+ files.Add(currBuilder.ToString());
+ //create some new output
+ currBuilder = new StringBuilder();
+ base64Builder = new StringBuilder();
+ builderCount++;
+ }
+
+ //update the normal builder
+ currBuilder.Append(a.FilePath + ";");
+ }
+
+ if (builderCount > files.Count)
+ {
+ files.Add(currBuilder.ToString());
+ }
+
+ //now, compress each url
+ for (var i = 0; i < files.Count; i++)
+ {
+ //append our version to the combined url
+ var encodedFile = files[i].EncodeTo64Url();
+ files[i] = GetCompositeFileUrl(encodedFile, type, http, UrlType);
+ }
+
+ return files.ToArray();
+ }
+ }
+
+ public virtual int GetVersion()
+ {
+ return ClientDependencySettings.Instance.Version;
+ }
+
+ ///
+ /// Returns the url for the composite file handler for the filePath specified.
+ ///
+ /// The Base64 encoded file paths or the file map key used to lookup the required dependencies
+ ///
+ ///
+ ///
+ ///
+ public virtual string GetCompositeFileUrl(
+ string fileKey,
+ ClientDependencyType type,
+ HttpContextBase http,
+ CompositeUrlType urlType)
+ {
+ var url = new StringBuilder();
+ int version = GetVersion();
+ switch (urlType)
+ {
+ case CompositeUrlType.Base64QueryStrings:
+
+ //Create a URL with a base64 query string
+
+ const string handler = "{0}?s={1}&t={2}";
+ url.Append(string.Format(handler,
+ ClientDependencySettings.Instance.CompositeFileHandlerPath,
+ http.Server.UrlEncode(fileKey), type));
+ url.Append("&cdv=");
+ url.Append(version.ToString());
+ break;
+ default:
+
+ //Create a URL based on base64 paths instead of a query string
+
+
+ //this used to be a "." but this causes problems with mvc and ignore routes for
+ //some very strange reason, so we'll just use normal paths.
+ var versionDelimiter = ".";
+
+ url.Append(ClientDependencySettings.Instance.CompositeFileHandlerPath);
+ int pos = 0;
+ while (fileKey.Length > pos)
+ {
+ url.Append("/");
+ int len = Math.Min(fileKey.Length - pos, 240);
+ url.Append(fileKey.Substring(pos, len));
+ pos += 240;
+ }
+ url.Append(versionDelimiter);
+ url.Append(version.ToString());
+ switch (type)
+ {
+ case ClientDependencyType.Css:
+ url.Append(versionDelimiter);
+ url.Append("css");
+ break;
+ case ClientDependencyType.Javascript:
+ url.Append(versionDelimiter);
+ url.Append("js");
+ break;
+ }
+ break;
+ }
+
+ return url.ToString();
+ }
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ base.Initialize(name, config);
+
+ if (config == null)
+ return;
+
+ if (config["enableCssMinify"] != null)
+ {
+ bool enableCssMinify;
+ if (bool.TryParse(config["enableCssMinify"], out enableCssMinify))
+ EnableCssMinify = enableCssMinify;
+ }
+ if (config["enableJsMinify"] != null)
+ {
+ bool enableJsMinify;
+ if (bool.TryParse(config["enableJsMinify"], out enableJsMinify))
+ EnableJsMinify = enableJsMinify;
+ }
+
+ if (config["persistFiles"] != null)
+ {
+ bool persistFiles;
+ if (bool.TryParse(config["persistFiles"], out persistFiles))
+ PersistCompositeFiles = persistFiles;
+ }
+
+ if (config["urlType"] != null)
+ {
+ try
+ {
+ UrlType = (CompositeUrlType)Enum.Parse(typeof(CompositeUrlType), config["urlType"]);
+ }
+ catch (ArgumentException)
+ {
+ //swallow exception, we've set the default
+ }
+ }
+
+ _compositeFilePath = config["compositeFilePath"] ?? DefaultDependencyPath;
+
+ string bundleDomains = config["bundleDomains"];
+ if (bundleDomains != null)
+ bundleDomains = bundleDomains.Trim();
+ if (string.IsNullOrEmpty(bundleDomains))
+ {
+ BundleDomains = new List();
+ }
+ else
+ {
+ string[] domains = bundleDomains.Split(new char[] { ',' });
+ for (int i = 0; i < domains.Length; i++)
+ {
+ // make sure we have a starting dot and a trailing port
+ // ie 'maps.google.com' will be stored as '.maps.google.com:80'
+ if (domains[i].IndexOf(':') < 0)
+ domains[i] = domains[i] + ":80";
+ if (!domains[i].StartsWith("."))
+ domains[i] = "." + domains[i];
+ }
+ BundleDomains = new List(domains);
+ }
+ }
+
+ ///
+ /// Minifies the file
+ ///
+ ///
+ ///
+ ///
+ protected virtual string MinifyFile(string fileContents, ClientDependencyType type)
+ {
+ switch (type)
+ {
+ case ClientDependencyType.Css:
+ return EnableCssMinify ? CssMin.CompressCSS(fileContents) : fileContents;
+ case ClientDependencyType.Javascript:
+ return EnableJsMinify ? JSMin.CompressJS(fileContents) : fileContents;
+ default:
+ return fileContents;
+ }
+ }
+
+ ///
+ /// This ensures that all paths (i.e. images) in a CSS file have their paths change to absolute paths.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected virtual string ParseCssFilePaths(string fileContents, ClientDependencyType type, string url, HttpContextBase http)
+ {
+ //if it is a CSS file we need to parse the URLs
+ if (type == ClientDependencyType.Css)
+ {
+ var uri = new Uri(url, UriKind.RelativeOrAbsolute);
+ fileContents = CssFileUrlFormatter.TransformCssFile(fileContents, uri.MakeAbsoluteUri(http));
+ }
+ return fileContents;
+ }
+
+ ///
+ /// Tries to convert the url to a uri, then read the request into a string and return it.
+ /// This takes into account relative vs absolute URI's
+ ///
+ ///
+ ///
+ ///
+ /// true if successful, false if not successful
+ ///
+ /// if the path is a relative local path, the we use Server.Execute to get the request output, otherwise
+ /// if it is an absolute path, a WebClient request is made to fetch the contents.
+ ///
+ protected bool TryReadUri(string url, out string requestContents, HttpContextBase http)
+ {
+ Uri uri;
+ if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
+ {
+ //flag of whether or not to make a request to get the external resource (used below)
+ bool bundleExternalUri = false;
+
+ //if its a relative path, then check if we should execute/retreive contents,
+ //otherwise change it to an absolute path and try to request it.
+ if (!uri.IsAbsoluteUri)
+ {
+ //if this is an ASPX page, we should execute it instead of http getting it.
+ if (uri.ToString().EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase))
+ {
+ var sw = new StringWriter();
+ try
+ {
+ http.Server.Execute(url, sw);
+ requestContents = sw.ToString();
+ sw.Close();
+ return true;
+ }
+ catch (Exception ex)
+ {
+ ClientDependencySettings.Instance.Logger.Error(string.Format("Could not load file contents from {0}. EXCEPTION: {1}", url, ex.Message), ex);
+ requestContents = "";
+ return false;
+ }
+ }
+
+ //if this is a call for a web resource, we should http get it
+ if (url.StartsWith(http.Request.ApplicationPath.TrimEnd('/') + "/webresource.axd", StringComparison.InvariantCultureIgnoreCase))
+ {
+ bundleExternalUri = true;
+ }
+ }
+
+ try
+ {
+ //we've gotten this far, make the URI absolute and try to load it
+ uri = uri.MakeAbsoluteUri(http);
+
+ //if this isn't a web resource, we need to check if its approved
+ if (!bundleExternalUri)
+ {
+ // get the domain to test, with starting dot and trailing port, then compare with
+ // declared (authorized) domains. the starting dot is here to allow for subdomain
+ // approval, eg '.maps.google.com:80' will be approved by rule '.google.com:80', yet
+ // '.roguegoogle.com:80' will not.
+ var domain = string.Format(".{0}:{1}", uri.Host, uri.Port);
+
+ foreach (string bundleDomain in BundleDomains)
+ {
+ if (domain.EndsWith(bundleDomain))
+ {
+ bundleExternalUri = true;
+ break;
+ }
+ }
+ }
+
+ if (bundleExternalUri)
+ {
+ requestContents = GetXmlResponse(uri);
+ return true;
+ }
+ else
+ {
+ ClientDependencySettings.Instance.Logger.Error(string.Format("Could not load file contents from {0}. Domain is not white-listed.", url), null);
+ }
+ }
+ catch (Exception ex)
+ {
+ ClientDependencySettings.Instance.Logger.Error(string.Format("Could not load file contents from {0}. EXCEPTION: {1}", url, ex.Message), ex);
+ }
+
+
+ }
+ requestContents = "";
+ return false;
+ }
+
+ ///
+ /// Gets the web response and ensures that the BOM is not present not matter what encoding is specified.
+ ///
+ ///
+ ///
+ private string GetXmlResponse(Uri resource)
+ {
+ string xml;
+
+ using (var client = new WebClient())
+ {
+ client.Credentials = CredentialCache.DefaultNetworkCredentials;
+ client.Encoding = Encoding.UTF8;
+ xml = client.DownloadString(resource);
+ }
+
+ if (xml.StartsWith(_byteOrderMarkUtf8))
+ {
+ xml = xml.Remove(0, _byteOrderMarkUtf8.Length - 1);
+ }
+
+ return xml;
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/BaseFileMapProvider.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/BaseFileMapProvider.cs
new file mode 100644
index 00000000000..75d342b6410
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/BaseFileMapProvider.cs
@@ -0,0 +1,59 @@
+using System.Collections.Generic;
+using System.Configuration.Provider;
+using System.IO;
+using System.Web;
+
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+ public abstract class BaseFileMapProvider : ProviderBase, IHttpProvider
+ {
+
+ ///
+ /// Retreives the file map for the key/version/compression type specified
+ ///
+ ///
+ ///
+ ///
+ ///
+ public abstract CompositeFileMap GetCompositeFile(string fileKey,
+ int version,
+ string compression);
+
+ ///
+ /// Retreives the dependent file paths for the filekey/version (regardless of compression)
+ ///
+ ///
+ ///
+ ///
+ public abstract IEnumerable GetDependentFiles(string fileKey, int version);
+
+ ///
+ /// Creates a map for the version/compression type/dependent file listing
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public abstract void CreateUpdateMap(string fileKey,
+ string compressionType,
+ IEnumerable dependentFiles,
+ string compositeFile,
+ int version);
+
+ ///
+ /// Creates a new file map and file key for the dependent file list, this is used to create URLs with CompositeUrlType.MappedId
+ ///
+ public abstract string CreateNewMap(HttpContextBase http,
+ IEnumerable dependentFiles,
+ int version);
+
+ ///
+ /// Runs initialization with an Http context, this occurs after the initial provider config initialization
+ ///
+ ///
+ public abstract void Initialize(System.Web.HttpContextBase http);
+
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeFileProcessingProvider.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeFileProcessingProvider.cs
new file mode 100644
index 00000000000..75ccb918b02
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeFileProcessingProvider.cs
@@ -0,0 +1,243 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Web.Hosting;
+using ClientDependency.Core.Config;
+using System.IO;
+using System.Web;
+using System.Net;
+using System.IO.Compression;
+using System.Configuration.Provider;
+using ClientDependency.Core.CompositeFiles;
+
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+
+ ///
+ /// A provider for combining, minifying, compressing and saving composite scripts/css files
+ ///
+ public class CompositeFileProcessingProvider : BaseCompositeFileProcessingProvider
+ {
+
+ public const string DefaultName = "CompositeFileProcessor";
+ private static Regex _importCssRegex = new Regex("@import url\\((.+?)\\);?", RegexOptions.Compiled);
+
+ ///
+ /// Saves the file's bytes to disk with a hash of the byte array
+ ///
+ ///
+ ///
+ ///
+ /// The new file path
+ ///
+ /// the extension will be: .cdj for JavaScript and .cdc for CSS
+ ///
+ public override FileInfo SaveCompositeFile(byte[] fileContents, ClientDependencyType type, HttpServerUtilityBase server, int version)
+ {
+ //don't save the file if composite files are disabled.
+ if (!PersistCompositeFiles)
+ return null;
+
+ if (!CompositeFilePath.Exists)
+ CompositeFilePath.Create();
+
+ var fi = new FileInfo(
+ Path.Combine(CompositeFilePath.FullName,
+ version + "_" + Guid.NewGuid().ToString("N") + ".cd" + type.ToString().Substring(0, 1).ToUpper()));
+
+ if (fi.Exists)
+ fi.Delete();
+
+ var fs = fi.Create();
+ fs.Write(fileContents, 0, fileContents.Length);
+ fs.Close();
+ return fi;
+ }
+
+ ///
+ /// combines all files to a byte array
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override byte[] CombineFiles(string[] filePaths, HttpContextBase context, ClientDependencyType type, out List fileDefs)
+ {
+
+ var fDefs = new List();
+
+ var ms = new MemoryStream(5000);
+ var sw = new StreamWriter(ms, Encoding.UTF8);
+
+ foreach (string s in filePaths)
+ {
+ if (!string.IsNullOrEmpty(s))
+ {
+ try
+ {
+ var fi = new FileInfo(context.Server.MapPath(s));
+ if (ClientDependencySettings.Instance.FileBasedDependencyExtensionList.Contains(fi.Extension.ToUpper()))
+ {
+ //if the file doesn't exist, then we'll assume it is a URI external request
+ if (!fi.Exists)
+ {
+ WriteFileToStream(ref sw, s, type, ref fDefs, context);
+ }
+ else
+ {
+ WriteFileToStream(ref sw, fi, type, s, ref fDefs, context);
+ }
+ }
+ else
+ {
+ //if it's not a file based dependency, try to get the request output.
+ WriteFileToStream(ref sw, s, type, ref fDefs, context);
+ }
+ }
+ catch (Exception ex)
+ {
+ Type exType = ex.GetType();
+ if (exType.Equals(typeof(NotSupportedException))
+ || exType.Equals(typeof(ArgumentException))
+ || exType.Equals(typeof(HttpException)))
+ {
+ //could not parse the string into a fileinfo or couldn't mappath, so we assume it is a URI
+ WriteFileToStream(ref sw, s, type, ref fDefs, context);
+ }
+ else
+ {
+ //if this fails, log the exception in trace, but continue
+ ClientDependencySettings.Instance.Logger.Error(string.Format("Could not load file contents from {0}. EXCEPTION: {1}", s, ex.Message), ex);
+ }
+ }
+ }
+
+ if (type == ClientDependencyType.Javascript)
+ {
+ sw.Write(";;;"); //write semicolons in case the js isn't formatted correctly. This also helps for debugging.
+ }
+
+ }
+ sw.Flush();
+ byte[] outputBytes = ms.ToArray();
+ sw.Close();
+ ms.Close();
+ fileDefs = fDefs;
+ return outputBytes;
+ }
+
+ ///
+ /// Compresses the bytes if the browser supports it
+ ///
+ public override byte[] CompressBytes(CompressionType type, byte[] fileBytes)
+ {
+ return SimpleCompressor.CompressBytes(type, fileBytes);
+ }
+
+ ///
+ /// Writes the output of an external request to the stream. Returns true/false if succesful or not.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected virtual void WriteFileToStream(ref StreamWriter sw, string url, ClientDependencyType type, ref List fileDefs, HttpContextBase http)
+ {
+ string requestOutput;
+ var rVal = TryReadUri(url, out requestOutput, http);
+ if (rVal)
+ {
+ //write the contents of the external request.
+ WriteContentToStream(ref sw, MinifyFile(ParseCssFilePaths(requestOutput, type, url, http), type), type, http);
+ fileDefs.Add(new CompositeFileDefinition(url, false));
+ }
+ return;
+ }
+
+ protected virtual void WriteFileToStream(ref StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, ref List fileDefs, HttpContextBase http)
+ {
+ try
+ {
+ //if it is a file based dependency then read it
+ var fileContents = File.ReadAllText(fi.FullName, Encoding.UTF8); //read as utf 8
+
+ WriteContentToStream(ref sw, MinifyFile(ParseCssFilePaths(fileContents, type, origUrl, http), type), type, http);
+ fileDefs.Add(new CompositeFileDefinition(origUrl, true));
+ return;
+ }
+ catch (Exception ex)
+ {
+ ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
+ return;
+ }
+ }
+
+ private void WriteContentToStream(ref StreamWriter sw, string content, ClientDependencyType type, HttpContextBase context)
+ {
+ //need to parse
+ if (type == ClientDependencyType.Css && ClientDependencySettings.Instance.DefaultFileRegistrationProvider.EnableCompositeFiles)
+ {
+ while(_importCssRegex.IsMatch(content))
+ {
+ var match = _importCssRegex.Match(content);
+ //write the previous content
+ sw.WriteLine(content.Substring(0, match.Index));
+ //write import css content
+ var filePath = match.Groups[1].Value.Trim('\'', '"');
+ try
+ {
+ var importContent = string.Empty;
+ if(filePath.StartsWith("http"))
+ {
+ importContent = ParseCssFilePaths(DownloadString(filePath), ClientDependencyType.Css, filePath, context);
+ }
+ else
+ {
+ importContent = ParseCssFilePaths(File.ReadAllText(context.Server.MapPath(filePath)), ClientDependencyType.Css, filePath, context);
+ }
+
+ sw.WriteLine(importContent);
+ }
+ catch
+ {
+ sw.WriteLine(string.Format("/*Invalid CSS: {0}*/", filePath));
+ }
+
+ content = content.Substring(match.Index + match.Length);
+ }
+ sw.WriteLine(content);
+ }
+ else
+ {
+ sw.WriteLine(MinifyFile(content, type));
+ }
+ }
+
+ private string DownloadString(string url)
+ {
+ var content = string.Empty;
+ try
+ {
+ var webRequest = (HttpWebRequest)HttpWebRequest.Create(url);
+ webRequest.UserAgent = "ClientDependency Css Parser";
+ var response = webRequest.GetResponse();
+ using (var reader = new StreamReader(response.GetResponseStream()))
+ {
+ content = reader.ReadToEnd();
+ }
+ response.Close();
+ }
+ catch
+ {
+ content = string.Format("/*Invalid CSS: {0}*/", url);
+ }
+
+ return content;
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeFileProcessingProviderCollection.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeFileProcessingProviderCollection.cs
new file mode 100644
index 00000000000..3859f25842d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeFileProcessingProviderCollection.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration.Provider;
+
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+ public class CompositeFileProcessingProviderCollection : ProviderCollection
+ {
+ public new BaseCompositeFileProcessingProvider this[string name]
+ {
+ get { return (BaseCompositeFileProcessingProvider)base[name]; }
+ }
+
+ public override void Add(ProviderBase provider)
+ {
+ if (provider == null)
+ throw new ArgumentNullException("provider");
+
+ if (!(provider is BaseCompositeFileProcessingProvider))
+ throw new ArgumentException("Invalid provider type", "provider");
+
+ base.Add(provider);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeUrlType.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeUrlType.cs
new file mode 100644
index 00000000000..a36fcbff967
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/CompositeUrlType.cs
@@ -0,0 +1,22 @@
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+ public enum CompositeUrlType
+ {
+ ///
+ /// The original URL type in which full dependency paths are base64 encoded as query strings
+ ///
+ Base64QueryStrings,
+
+ ///
+ /// Creates a URL in which the full dependency paths are base64 encoded as URL paths, however because
+ /// paths can get quite large, this requires that .Net 4 is running and that you increase the maxUrlLength
+ /// configuration property in the httpRuntime section in your web.config
+ ///
+ Base64Paths,
+
+ ///
+ /// Uses the file map provider to store and map the dependency paths with a reference to an ID it generates
+ ///
+ MappedId
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/FileMapProviderCollection.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/FileMapProviderCollection.cs
new file mode 100644
index 00000000000..ac189daf8df
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/FileMapProviderCollection.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Configuration.Provider;
+
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+ public class FileMapProviderCollection : ProviderCollection
+ {
+ public new BaseFileMapProvider this[string name]
+ {
+ get { return (BaseFileMapProvider)base[name]; }
+ }
+
+ public override void Add(ProviderBase provider)
+ {
+ if (provider == null)
+ throw new ArgumentNullException("provider");
+
+ if (!(provider is BaseFileMapProvider))
+ throw new ArgumentException("Invalid provider type", "provider");
+
+ base.Add(provider);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/XmlFileMapper.cs b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/XmlFileMapper.cs
new file mode 100644
index 00000000000..cedf26c16d8
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompositeFiles/Providers/XmlFileMapper.cs
@@ -0,0 +1,363 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.Xml.Linq;
+using System.Xml;
+using System.IO;
+using ClientDependency.Core.Config;
+using System.Security.Cryptography;
+
+namespace ClientDependency.Core.CompositeFiles.Providers
+{
+
+ ///
+ /// Creates an XML file to map a saved composite file to the URL requested for the
+ /// dependency handler.
+ /// This is used in order to determine which individual files are dependant on what composite file so
+ /// a user can remove it to clear the cache, and also if the cache expires but the file still exists
+ /// this allows the system to simply read the one file again instead of compiling all of the other files
+ /// into one again.
+ ///
+ public class XmlFileMapper : BaseFileMapProvider
+ {
+
+ public const string DefaultName = "XmlFileMap";
+
+ private const string MapFileName = "map.xml";
+
+ private XDocument _doc;
+ private FileInfo _xmlFile;
+ private DirectoryInfo _xmlMapFolder;
+ private string _fileMapVirtualFolder = "~/App_Data/ClientDependency";
+ private static readonly object Locker = new object();
+
+ public override void Initialize(HttpContextBase http)
+ {
+ if (http == null) throw new ArgumentNullException("http");
+
+ _xmlMapFolder = new DirectoryInfo(http.Server.MapPath(_fileMapVirtualFolder));
+
+ //Name the map file according to the machine name
+ _xmlFile = new FileInfo(GetXmlMapPath());
+
+ EnsureXmlFile();
+
+ lock (Locker)
+ {
+ try
+ {
+ _doc = XDocument.Load(_xmlFile.FullName);
+ }
+ catch (XmlException)
+ {
+ //if it's an xml exception, create a new one and try one more time... should always work.
+ CreateNewXmlFile();
+ _doc = XDocument.Load(_xmlFile.FullName);
+ }
+ }
+ }
+
+ ///
+ /// Initializes the provider, loads in the existing file contents. If the file doesn't exist, it creates one.
+ ///
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ base.Initialize(name, config);
+
+ if (config == null)
+ return;
+
+ if (config["mapPath"] != null)
+ {
+ _fileMapVirtualFolder = config["mapPath"];
+ }
+
+ }
+
+ ///
+ /// Returns the composite file map associated with the file key, the version and the compression type
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override CompositeFileMap GetCompositeFile(string fileKey, int version, string compression)
+ {
+ if (string.IsNullOrEmpty(fileKey)) throw new ArgumentNullException("fileKey");
+
+ EnsureXmlFile();
+
+ var x = FindItem(fileKey, version, compression);
+ try
+ {
+ return (x == null ? null : new CompositeFileMap(fileKey,
+ (string)x.Attribute("compression"),
+ (string)x.Attribute("file"),
+ x.Descendants("file")
+ .Select(f => ((string)f.Attribute("name"))).ToArray(),
+ int.Parse((string)x.Attribute("version"))));
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Retreives the dependent file paths for the filekey/version (regardless of compression)
+ ///
+ ///
+ ///
+ ///
+ public override IEnumerable GetDependentFiles(string fileKey, int version)
+ {
+ if (string.IsNullOrEmpty(fileKey)) throw new ArgumentNullException("fileKey");
+
+ var x = FindItem(fileKey, version);
+ try
+ {
+ if (x != null)
+ {
+ var file = new CompositeFileMap(fileKey,
+ (string) x.Attribute("compression"),
+ (string) x.Attribute("file"),
+ x.Descendants("file")
+ .Select(f => ((string) f.Attribute("name"))).ToArray(),
+ int.Parse((string) x.Attribute("version")));
+ return file.DependentFiles;
+ }
+ }
+ catch
+ {
+ return null;
+ }
+ return null;
+ }
+
+ ///
+ /// Creates a new file map and file key for the dependent file list, this is used to create URLs with CompositeUrlType.MappedId
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// ]]>
+ ///
+ public override string CreateNewMap(HttpContextBase http,
+ IEnumerable dependentFiles,
+ int version)
+ {
+ if (http == null) throw new ArgumentNullException("http");
+
+ var builder = new StringBuilder();
+ foreach (var d in dependentFiles)
+ {
+ builder.Append(d.FilePath);
+ builder.Append(";");
+ }
+ var combinedFiles = builder.ToString();
+ combinedFiles = combinedFiles.TrimEnd(new[] { ';' });
+
+ var fileKey = (combinedFiles + version).GenerateMd5();
+
+ var x = FindItem(fileKey, version);
+
+ //if no map exists, create one
+ if (x == null)
+ {
+ //now, create a map with the file key so that it can be filled out later with the actual composite file that is created by the handler
+ CreateUpdateMap(fileKey,
+ string.Empty,
+ dependentFiles,
+ string.Empty,
+ version);
+ }
+
+ return fileKey;
+ }
+
+ ///
+ /// Adds/Updates an entry to the file map with the key specified, the version and dependent files listed with a map
+ /// to the composite file created for the files.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// ]]>
+ ///
+ public override void CreateUpdateMap(string fileKey,
+ string compressionType,
+ IEnumerable dependentFiles,
+ string compositeFile,
+ int version)
+ {
+ if (string.IsNullOrEmpty(fileKey)) throw new ArgumentNullException("fileKey");
+
+ lock (Locker)
+ {
+ //see if we can find an item with the key/version/compression that exists
+ var x = FindItem(fileKey, version, compressionType);
+
+ if (x != null)
+ {
+ x.Attribute("file").Value = compositeFile;
+ //remove all of the files so we can re-add them.
+ x.Element("files").Remove();
+
+ x.Add(CreateFileNode(dependentFiles));
+ }
+ else
+ {
+ //if it doesn't exist, create it
+ _doc.Root.Add(new XElement("item",
+ new XAttribute("key", fileKey),
+ new XAttribute("file", compositeFile),
+ new XAttribute("compression", compressionType),
+ new XAttribute("version", version),
+ CreateFileNode(dependentFiles)));
+ }
+
+ _doc.Save(_xmlFile.FullName);
+ }
+ }
+
+ ///
+ /// Finds an element in the map matching the key and version/compression
+ ///
+ ///
+ ///
+ ///
+ ///
+ private XElement FindItem(string key, int version, string compression)
+ {
+ if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
+
+ var items = _doc.Root.Elements("item")
+ .Where(e => (string) e.Attribute("key") == key
+ && (string) e.Attribute("version") == version.ToString());
+ return items.Where(e => (string)e.Attribute("compression") == compression).SingleOrDefault();
+ }
+
+ ///
+ /// Finds a element in the map matching key/version
+ ///
+ ///
+ ///
+ ///
+ private XElement FindItem(string key, int version)
+ {
+ if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
+
+ var items = _doc.Root.Elements("item")
+ .Where(e => (string)e.Attribute("key") == key
+ && (string)e.Attribute("version") == version.ToString());
+ return items.FirstOrDefault();
+ }
+
+ private XElement CreateFileNode(IEnumerable dependentFiles)
+ {
+ var x = new XElement("files");
+
+ //add all of the files
+ foreach (var d in dependentFiles)
+ {
+ x.Add(new XElement("file", new XAttribute("name", d.FilePath)));
+ }
+
+ return x;
+ }
+
+ ///
+ /// Returns the full path the map xml file for the current machine and install folder.
+ ///
+ ///
+ /// We need to create the map based on the combination of both machine name and install folder because
+ /// this deals with issues for load balanced environments and file locking and also
+ /// deals with issues when the ClientDependency folder is deployed between environments
+ /// since you would want your staging ClientDependencies in your live and vice versa.
+ /// This is however based on the theory that each website you have will have a unique combination
+ /// of folder path and machine name.
+ ///
+ ///
+ private string GetXmlMapPath()
+ {
+ var folder = _xmlMapFolder.FullName;
+ var folderMd5 = folder.GenerateMd5();
+ string machineName;
+ //catch usecase where user is running with EnvironmentPermission
+ try
+ {
+ machineName = Environment.MachineName;
+ }
+ catch (Exception)
+ {
+ machineName = HttpContext.Current.Server.MachineName;
+ }
+ return Path.Combine(folder, machineName.ToString() + "-" + folderMd5 + "-" + MapFileName);
+ }
+
+ private void CreateNewXmlFile()
+ {
+ if (File.Exists(_xmlFile.FullName))
+ {
+ File.Delete(_xmlFile.FullName);
+ }
+
+ if (_doc == null)
+ {
+ _doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
+ new XElement("map"));
+ _doc.Save(_xmlFile.FullName);
+ }
+ else
+ {
+ //if there's xml in memory, then the file has been deleted so write out the file
+ _doc.Save(_xmlFile.FullName);
+ }
+
+ }
+
+ private void EnsureXmlFile()
+ {
+ if (!File.Exists(_xmlFile.FullName))
+ {
+ lock (Locker)
+ {
+ //double check
+ if (!File.Exists(_xmlFile.FullName))
+ {
+ if (!_xmlMapFolder.Exists)
+ _xmlMapFolder.Create();
+ CreateNewXmlFile();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CompressionType.cs b/DNN Platform/Components/ClientDependency/Source/CompressionType.cs
new file mode 100644
index 00000000000..feb42f2456d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CompressionType.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClientDependency.Core.Config;
+using System.IO;
+using System.Web;
+using System.Net;
+using System.IO.Compression;
+
+namespace ClientDependency.Core
+{
+ public enum CompressionType
+ {
+ deflate, gzip, none
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/ClientDependencySection.cs b/DNN Platform/Components/ClientDependency/Source/Config/ClientDependencySection.cs
new file mode 100644
index 00000000000..8d6a91dffb7
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/ClientDependencySection.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+using System.Linq;
+using ClientDependency.Core.Logging;
+
+namespace ClientDependency.Core.Config
+{
+ public class ClientDependencySection : ConfigurationSection
+ {
+ ///
+ /// Set the version for the files, this will reset all composite file caching, and if
+ /// composite files are disabled will add a query string to each request so that
+ /// any client side cached files will be re-downloaded.
+ ///
+ [ConfigurationProperty("version", DefaultValue = 0)]
+ public int Version
+ {
+ get { return (int)base["version"]; }
+ set { base["version"] = value; }
+ }
+
+ [ConfigurationProperty("compositeFiles")]
+ public CompositeFileSection CompositeFileElement
+ {
+ get
+ {
+ return (CompositeFileSection)this["compositeFiles"];
+ }
+ }
+
+ [ConfigurationProperty("fileRegistration")]
+ public FileRegistrationSection FileRegistrationElement
+ {
+ get
+ {
+ return (FileRegistrationSection)this["fileRegistration"];
+ }
+ }
+
+ [ConfigurationProperty("mvc")]
+ public MvcSection MvcElement
+ {
+ get
+ {
+ return (MvcSection)this["mvc"];
+ }
+ }
+
+ [ConfigurationProperty("loggerType")]
+ public string LoggerType
+ {
+ get
+ {
+ return (string)this["loggerType"];
+ }
+ }
+
+ ///
+ /// Not really supposed to be used by public, but can implement at your own risk!
+ /// This by default assigns the MvcFilter and RogueFileFilter.
+ ///
+ [ConfigurationProperty("filters", IsRequired = false)]
+ public ProviderSettingsCollection Filters
+ {
+ get
+ {
+ var obj = base["filters"];
+
+ if (obj == null || ((obj is ConfigurationElementCollection) && ((ConfigurationElementCollection)obj).Count == 0))
+ {
+ var col = new ProviderSettingsCollection();
+ col.Add(new ProviderSettings("MvcFilter", "ClientDependency.Core.Mvc.MvcFilter, ClientDependency.Core.Mvc"));
+ col.Add(new ProviderSettings("RogueFileFilter", "ClientDependency.Core.Module.RogueFileFilter, ClientDependency.Core"));
+ return col;
+ }
+ else
+ {
+ return (ProviderSettingsCollection)obj;
+ }
+ }
+ }
+
+ ///
+ /// The configuration section to set the FileBasedDependencyExtensionList. This is a comma separated list.
+ ///
+ ///
+ /// If this is not explicitly set, then the extensions 'js' and 'css' are the defaults.
+ ///
+ [ConfigurationProperty("fileDependencyExtensions", DefaultValue = ".js,.css")]
+ protected string FileBasedDepdendenyExtensions
+ {
+ get { return (string)base["fileDependencyExtensions"]; }
+ set { base["fileDependencyExtensions"] = value; }
+ }
+
+ ///
+ /// The file extensions of Client Dependencies that are file based as opposed to request based.
+ /// Any file that doesn't have the extensions listed here will be request based, request based is
+ /// more overhead for the server to process.
+ ///
+ ///
+ /// A request based JavaScript file may be a .ashx that dynamically creates JavaScript server side.
+ /// Or an asmx/js request based on the proxied javascript created by web services.
+ ///
+ ///
+ /// If this is not explicitly set, then the extensions 'js' and 'css' are the defaults.
+ ///
+ public IEnumerable FileBasedDependencyExtensionList
+ {
+ get
+ {
+ return FileBasedDepdendenyExtensions.Split(',')
+ .Select(x => x.Trim().ToUpper());
+ }
+ }
+ }
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/ClientDependencySettings.cs b/DNN Platform/Components/ClientDependency/Source/Config/ClientDependencySettings.cs
new file mode 100644
index 00000000000..92b11c1a363
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/ClientDependencySettings.cs
@@ -0,0 +1,280 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web.Configuration;
+using System.Configuration.Provider;
+using System.Web;
+using System.Configuration;
+using ClientDependency.Core.FileRegistration.Providers;
+using ClientDependency.Core.CompositeFiles.Providers;
+using ClientDependency.Core.Logging;
+using System.IO;
+
+namespace ClientDependency.Core.Config
+{
+ public class ClientDependencySettings
+ {
+ ///
+ /// used for singleton
+ ///
+ private static ClientDependencySettings _settings;
+ private static readonly object Lock = new object();
+
+ ///
+ /// Default constructor, for use with a web context app
+ ///
+ internal ClientDependencySettings()
+ {
+ if (HttpContext.Current == null)
+ {
+ throw new InvalidOperationException(
+ "HttpContext.Current must exist when using the empty constructor for ClientDependencySettings, otherwise use the alternative constructor");
+ }
+
+ LoadProviders((ClientDependencySection)ConfigurationManager.GetSection("clientDependency"), new HttpContextWrapper(HttpContext.Current));
+
+ }
+
+ internal ClientDependencySettings(FileInfo configFile, HttpContextBase ctx)
+ {
+ var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile.FullName };
+ var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
+ LoadProviders((ClientDependencySection)configuration.GetSection("clientDependency"), ctx);
+ }
+
+ ///
+ /// Singleton, used for web apps
+ ///
+ public static ClientDependencySettings Instance
+ {
+ get
+ {
+ if (_settings == null)
+ {
+ lock(Lock)
+ {
+ //double check
+ if (_settings == null)
+ {
+ _settings = new ClientDependencySettings();
+ }
+ }
+ }
+ return _settings;
+ }
+ }
+
+ ///
+ /// The file extensions of Client Dependencies that are file based as opposed to request based.
+ /// Any file that doesn't have the extensions listed here will be request based, request based is
+ /// more overhead for the server to process.
+ ///
+ ///
+ /// A request based JavaScript file may be a .ashx that dynamically creates JavaScript server side.
+ ///
+ ///
+ /// If this is not explicitly set, then the extensions 'js' and 'css' are the defaults.
+ ///
+ public List FileBasedDependencyExtensionList { get; set; }
+
+ public int Version { get; set; }
+
+ public ILogger Logger { get; private set; }
+
+ ///
+ /// Returns the default MVC renderer
+ ///
+ public BaseRenderer DefaultMvcRenderer { get; private set; }
+
+ ///
+ /// Returns the MVC renderer provider collection
+ ///
+ public RendererCollection MvcRendererCollection { get; private set; }
+
+ ///
+ /// Returns the default file registration provider
+ ///
+ public WebFormsFileRegistrationProvider DefaultFileRegistrationProvider { get; private set; }
+
+ ///
+ /// Returns the file registration provider collection
+ ///
+ public FileRegistrationProviderCollection FileRegistrationProviderCollection { get; private set; }
+
+ ///
+ /// Returns the default composite file processing provider
+ ///
+ public BaseCompositeFileProcessingProvider DefaultCompositeFileProcessingProvider { get; private set; }
+
+ ///
+ /// Returns the composite file processing provider collection
+ ///
+ public CompositeFileProcessingProviderCollection CompositeFileProcessingProviderCollection { get; private set; }
+
+ ///
+ /// Returns the default file map provider
+ ///
+ public BaseFileMapProvider DefaultFileMapProvider { get; private set; }
+
+ ///
+ /// Returns the collection of file map providers
+ ///
+ public FileMapProviderCollection FileMapProviderCollection { get; private set; }
+
+ public ClientDependencySection ConfigSection { get; private set; }
+
+ public string CompositeFileHandlerPath { get; set; }
+
+ internal void LoadProviders(ClientDependencySection section, HttpContextBase http)
+ {
+
+ ConfigSection = section;
+
+ FileRegistrationProviderCollection = new FileRegistrationProviderCollection();
+ CompositeFileProcessingProviderCollection = new CompositeFileProcessingProviderCollection();
+ MvcRendererCollection = new RendererCollection();
+ FileMapProviderCollection = new FileMapProviderCollection();
+
+ // if there is no section found, then create one
+ if (ConfigSection == null)
+ {
+ //create a new section with the default settings
+ ConfigSection = new ClientDependencySection();
+ }
+
+ //need to check if it's an http path or a lambda path
+ var path = ConfigSection.CompositeFileElement.CompositeFileHandlerPath;
+ CompositeFileHandlerPath = path.StartsWith("~/")
+ ? VirtualPathUtility.ToAbsolute(ConfigSection.CompositeFileElement.CompositeFileHandlerPath, http.Request.ApplicationPath)
+ : ConfigSection.CompositeFileElement.CompositeFileHandlerPath;
+ Version = ConfigSection.Version;
+ FileBasedDependencyExtensionList = ConfigSection.FileBasedDependencyExtensionList.ToList();
+
+ //load the providers from the config, if there isn't config sections then add default providers
+ // and then load the defaults.
+
+ LoadDefaultCompositeFileConfig(ConfigSection, http);
+
+ DefaultCompositeFileProcessingProvider = CompositeFileProcessingProviderCollection[ConfigSection.CompositeFileElement.DefaultFileProcessingProvider];
+ if (DefaultCompositeFileProcessingProvider == null)
+ throw new ProviderException("Unable to load default composite file provider");
+
+ LoadDefaultFileMapConfig(ConfigSection, http);
+
+ DefaultFileMapProvider = FileMapProviderCollection[ConfigSection.CompositeFileElement.DefaultFileMapProvider];
+ if (DefaultFileMapProvider == null)
+ throw new ProviderException("Unable to load default file map provider");
+
+ LoadDefaultMvcFileConfig(ConfigSection);
+
+ DefaultMvcRenderer = MvcRendererCollection[ConfigSection.MvcElement.DefaultRenderer];
+ if (DefaultMvcRenderer == null)
+ throw new ProviderException("Unable to load default mvc renderer");
+
+ LoadDefaultFileRegConfig(ConfigSection);
+
+ DefaultFileRegistrationProvider = FileRegistrationProviderCollection[ConfigSection.FileRegistrationElement.DefaultProvider];
+ if (DefaultFileRegistrationProvider == null)
+ throw new ProviderException("Unable to load default file registration provider");
+
+ if (string.IsNullOrEmpty(ConfigSection.LoggerType))
+ {
+ Logger = new NullLogger();
+ }
+ else
+ {
+ var t = Type.GetType(ConfigSection.LoggerType);
+ if (!typeof(ILogger).IsAssignableFrom(t))
+ {
+ throw new ArgumentException("The loggerType '" + ConfigSection.LoggerType + "' does not inherit from ClientDependency.Core.Logging.ILogger");
+ }
+
+ Logger = (ILogger)Activator.CreateInstance(t);
+ }
+
+ }
+
+ private void LoadDefaultFileRegConfig(ClientDependencySection section)
+ {
+ if (section.FileRegistrationElement.Providers.Count == 0)
+ {
+ //create new providers
+ var php = new PageHeaderProvider();
+ php.Initialize(PageHeaderProvider.DefaultName, null);
+ FileRegistrationProviderCollection.Add(php);
+
+ var csrp = new LazyLoadProvider();
+ csrp.Initialize(LazyLoadProvider.DefaultName, null);
+ FileRegistrationProviderCollection.Add(csrp);
+
+ var lcp = new LoaderControlProvider();
+ lcp.Initialize(LoaderControlProvider.DefaultName, null);
+ FileRegistrationProviderCollection.Add(lcp);
+ }
+ else
+ {
+ ProvidersHelper.InstantiateProviders(section.FileRegistrationElement.Providers, FileRegistrationProviderCollection, typeof(BaseFileRegistrationProvider));
+ }
+
+ }
+
+ private void LoadDefaultFileMapConfig(ClientDependencySection section, HttpContextBase http)
+ {
+ if (section.CompositeFileElement.FileMapProviders.Count == 0)
+ {
+ //if not specified, create default
+ var fmp = new XmlFileMapper();
+ fmp.Initialize(XmlFileMapper.DefaultName, null);
+ fmp.Initialize(http);
+ FileMapProviderCollection.Add(fmp);
+ }
+ else
+ {
+ ProvidersHelper.InstantiateProviders(section.CompositeFileElement.FileMapProviders, FileMapProviderCollection, typeof(BaseFileMapProvider));
+ //since the BaseFileMapProvider is an IHttpProvider, we need to do the http init
+ foreach (var p in FileMapProviderCollection.Cast())
+ {
+ p.Initialize(http);
+ }
+ }
+
+ }
+
+ private void LoadDefaultCompositeFileConfig(ClientDependencySection section, HttpContextBase http)
+ {
+ if (section.CompositeFileElement.FileProcessingProviders.Count == 0)
+ {
+ var cfpp = new CompositeFileProcessingProvider();
+ cfpp.Initialize(CompositeFileProcessingProvider.DefaultName, null);
+ cfpp.Initialize(http);
+ CompositeFileProcessingProviderCollection.Add(cfpp);
+ }
+ else
+ {
+ ProvidersHelper.InstantiateProviders(section.CompositeFileElement.FileProcessingProviders, CompositeFileProcessingProviderCollection, typeof(BaseCompositeFileProcessingProvider));
+ //since the BaseCompositeFileProcessingProvider is an IHttpProvider, we need to do the http init
+ foreach(var p in CompositeFileProcessingProviderCollection.Cast())
+ {
+ p.Initialize(http);
+ }
+ }
+
+ }
+
+ private void LoadDefaultMvcFileConfig(ClientDependencySection section)
+ {
+ if (section.MvcElement.Renderers.Count == 0)
+ {
+ var mvc = new StandardRenderer();
+ mvc.Initialize(StandardRenderer.DefaultName, null);
+ MvcRendererCollection.Add(mvc);
+ }
+ else
+ {
+ ProvidersHelper.InstantiateProviders(section.MvcElement.Renderers, MvcRendererCollection, typeof(BaseRenderer));
+ }
+
+ }
+ }
+}
+
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/CompositeFileSection.cs b/DNN Platform/Components/ClientDependency/Source/Config/CompositeFileSection.cs
new file mode 100644
index 00000000000..19c248a8e5d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/CompositeFileSection.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ public class CompositeFileSection : ConfigurationElement
+ {
+
+ ///
+ /// All of the file processing providers registered
+ ///
+ [ConfigurationProperty("fileProcessingProviders")]
+ public ProviderSettingsCollection FileProcessingProviders
+ {
+ get { return (ProviderSettingsCollection)base["fileProcessingProviders"]; }
+ }
+
+ ///
+ /// All of the File map providers registered
+ ///
+ [ConfigurationProperty("fileMapProviders")]
+ public ProviderSettingsCollection FileMapProviders
+ {
+ get { return (ProviderSettingsCollection)base["fileMapProviders"]; }
+ }
+
+ ///
+ /// The default File processing provider
+ ///
+ [StringValidator(MinLength = 1)]
+ [ConfigurationProperty("defaultFileProcessingProvider", DefaultValue = "CompositeFileProcessor")]
+ public string DefaultFileProcessingProvider
+ {
+ get { return (string)base["defaultFileProcessingProvider"]; }
+ set { base["defaultFileProcessingProvider"] = value; }
+ }
+
+ ///
+ /// The default file map provider
+ ///
+ [StringValidator(MinLength = 1)]
+ [ConfigurationProperty("defaultFileMapProvider", DefaultValue = "XmlFileMap")]
+ public string DefaultFileMapProvider
+ {
+ get { return (string)base["defaultFileMapProvider"]; }
+ set { base["defaultFileMapProvider"] = value; }
+ }
+
+ [ConfigurationProperty("compositeFileHandlerPath", DefaultValue = "DependencyHandler.axd")]
+ public string CompositeFileHandlerPath
+ {
+ get { return (string)base["compositeFileHandlerPath"]; }
+ set { base["compositeFileHandlerPath"] = value; }
+ }
+
+ [ConfigurationProperty("mimeTypeCompression")]
+ public MimeTypeCompressionCollection MimeTypeCompression
+ {
+ get
+ {
+ return (MimeTypeCompressionCollection)base["mimeTypeCompression"];
+ }
+ }
+
+ [ConfigurationProperty("rogueFileCompression")]
+ public RogueFileCompressionCollection RogueFileCompression
+ {
+ get
+ {
+ return (RogueFileCompressionCollection)base["rogueFileCompression"];
+ }
+ }
+
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/FileRegistrationSection.cs b/DNN Platform/Components/ClientDependency/Source/Config/FileRegistrationSection.cs
new file mode 100644
index 00000000000..84ef31a0f70
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/FileRegistrationSection.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ public class FileRegistrationSection : ConfigurationElement
+ {
+
+ [ConfigurationProperty("providers")]
+ public ProviderSettingsCollection Providers
+ {
+ get { return (ProviderSettingsCollection)base["providers"]; }
+ }
+
+ [StringValidator(MinLength = 1)]
+ [ConfigurationProperty("defaultProvider", DefaultValue = "LoaderControlProvider")]
+ public string DefaultProvider
+ {
+ get { return (string)base["defaultProvider"]; }
+ set { base["defaultProvider"] = value; }
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/MimeTypeCompressionCollection.cs b/DNN Platform/Components/ClientDependency/Source/Config/MimeTypeCompressionCollection.cs
new file mode 100644
index 00000000000..af20f59d9d4
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/MimeTypeCompressionCollection.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+
+
+ public class MimeTypeCompressionCollection : ConfigurationElementCollection
+ {
+ protected override bool ThrowOnDuplicate
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected override ConfigurationElement CreateNewElement()
+ {
+ var e = new MimeTypeCompressionElement();
+ return e;
+ }
+
+ protected override object GetElementKey(ConfigurationElement element)
+ {
+ return ((MimeTypeCompressionElement)element);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/MimeTypeCompressionElement.cs b/DNN Platform/Components/ClientDependency/Source/Config/MimeTypeCompressionElement.cs
new file mode 100644
index 00000000000..dbe39cf8634
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/MimeTypeCompressionElement.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ public class MimeTypeCompressionElement : ConfigurationElement
+ {
+ [ConfigurationProperty("type", IsRequired = true)]
+ public string MimeType
+ {
+ get
+ {
+ return (string)this["type"];
+ }
+ }
+
+ [ConfigurationProperty("path", DefaultValue = "*")]
+ public string FilePath
+ {
+ get
+ {
+ return (string)this["path"];
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ return (this.MimeType + this.FilePath).GetHashCode();
+ }
+
+ public override bool Equals(object compareTo)
+ {
+ var e = compareTo as MimeTypeCompressionElement;
+ if (e != null)
+ {
+ return (e.GetHashCode().Equals(this.GetHashCode()));
+ }
+ return false;
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/MvcSection.cs b/DNN Platform/Components/ClientDependency/Source/Config/MvcSection.cs
new file mode 100644
index 00000000000..1585009d16e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/MvcSection.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ public class MvcSection : ConfigurationElement
+ {
+
+ [ConfigurationProperty("renderers")]
+ public ProviderSettingsCollection Renderers
+ {
+ get { return (ProviderSettingsCollection)base["renderers"]; }
+ }
+
+ [StringValidator(MinLength = 1)]
+ [ConfigurationProperty("defaultRenderer", DefaultValue = "StandardRenderer")]
+ public string DefaultRenderer
+ {
+ get { return (string)base["defaultRenderer"]; }
+ set { base["defaultRenderer"] = value; }
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionCollection.cs b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionCollection.cs
new file mode 100644
index 00000000000..522f974bb8c
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionCollection.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ public class RogueFileCompressionCollection : ConfigurationElementCollection
+ {
+ protected override bool ThrowOnDuplicate
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected override ConfigurationElement CreateNewElement()
+ {
+ var e = new RogueFileCompressionElement();
+ return e;
+ }
+
+ protected override object GetElementKey(ConfigurationElement element)
+ {
+ return ((RogueFileCompressionElement)element);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionElement.cs b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionElement.cs
new file mode 100644
index 00000000000..3496edbe909
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionElement.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ class RogueFileCompressionElement : ConfigurationElement
+ {
+ [ConfigurationProperty("compressJs", DefaultValue = true)]
+ public bool CompressJs
+ {
+ get
+ {
+ return (bool)this["compressJs"];
+ }
+ }
+
+ [ConfigurationProperty("compressCss", DefaultValue = true)]
+ public bool CompressCss
+ {
+ get
+ {
+ return (bool)this["compressCss"];
+ }
+ }
+
+ [ConfigurationProperty("path", DefaultValue = "*")]
+ public string FilePath
+ {
+ get
+ {
+ return (string)this["path"];
+ }
+ }
+
+ ///
+ /// a collection of file extensions that must match on the rogue file for it to
+ /// be replaced with the composite handler
+ ///
+ [ConfigurationProperty("jsExt", DefaultValue = ".js")]
+ public string JsRequestExtension
+ {
+ get
+ {
+ return (string)this["jsExt"];
+ }
+ }
+
+ ///
+ /// a collection of file extensions that must match on the rogue file for it to
+ /// be replaced with the composite handler
+ ///
+ [ConfigurationProperty("cssExt", DefaultValue = ".css")]
+ public string CssRequestExtension
+ {
+ get
+ {
+ return (string)this["cssExt"];
+ }
+ }
+
+ [ConfigurationProperty("exclusions")]
+ public RogueFileCompressionExcludeCollection ExcludePaths
+ {
+ get
+ {
+ return (RogueFileCompressionExcludeCollection)base["exclusions"];
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ return this.FilePath.GetHashCode();
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionExcludeCollection.cs b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionExcludeCollection.cs
new file mode 100644
index 00000000000..45d31b80713
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionExcludeCollection.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+ public class RogueFileCompressionExcludeCollection : ConfigurationElementCollection
+ {
+ protected override bool ThrowOnDuplicate
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected override ConfigurationElement CreateNewElement()
+ {
+ var e = new RogueFileCompressionExcludeElement();
+ return e;
+ }
+
+ protected override object GetElementKey(ConfigurationElement element)
+ {
+ return ((RogueFileCompressionExcludeElement)element);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionExcludeElement.cs b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionExcludeElement.cs
new file mode 100644
index 00000000000..13374bf43dc
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Config/RogueFileCompressionExcludeElement.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration;
+
+namespace ClientDependency.Core.Config
+{
+
+ public class RogueFileCompressionExcludeElement : ConfigurationElement
+ {
+ [ConfigurationProperty("path", IsRequired = true)]
+ public string FilePath
+ {
+ get
+ {
+ return (string)this["path"];
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ return this.FilePath.GetHashCode();
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Constants.cs b/DNN Platform/Components/ClientDependency/Source/Constants.cs
new file mode 100644
index 00000000000..c377c9b9189
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Constants.cs
@@ -0,0 +1,22 @@
+namespace ClientDependency.Core
+{
+ public static class Constants
+ {
+ ///
+ /// If a priority is not set, the default will be 100.
+ ///
+ ///
+ /// This will generally mean that if a developer doesn't specify a priority it will come after all other dependencies that
+ /// have unless the priority is explicitly set above 100.
+ ///
+ public const int DefaultPriority = 100;
+
+ ///
+ /// If a group is not set, the default will be 100.
+ ///
+ ///
+ /// Unless a group is specified, all dependencies will go into the same, default, group.
+ ///
+ public const int DefaultGroup = 100;
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/ControlExtensions.cs b/DNN Platform/Components/ClientDependency/Source/ControlExtensions.cs
new file mode 100644
index 00000000000..900a3550034
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/ControlExtensions.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web.UI;
+using ClientDependency.Core.Controls;
+using System.Web;
+
+namespace ClientDependency.Core
+{
+ public static class ControlExtensions
+ {
+
+
+
+ public static IEnumerable FlattenChildren(this Control control)
+ {
+ var children = control.Controls.Cast();
+ return children.SelectMany(c => FlattenChildren(c)).Concat(children);
+ }
+
+ public static IEnumerable FlattenChildren(this Control control)
+ {
+ var children = control.Controls
+ .Cast()
+ .Where(x => x is T);
+ return children.SelectMany(c => FlattenChildren(c)).Concat(children);
+ }
+
+
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyInclude.cs b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyInclude.cs
new file mode 100644
index 00000000000..eb0335d5305
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyInclude.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web.UI;
+
+namespace ClientDependency.Core.Controls
+{
+ public abstract class ClientDependencyInclude : Control, IClientDependencyFile, IRequiresHtmlAttributesParsing
+ {
+ protected ClientDependencyInclude()
+ {
+ Priority = Constants.DefaultPriority;
+ Group = Constants.DefaultGroup;
+ PathNameAlias = "";
+ HtmlAttributes = new Dictionary();
+ AddTag = true;
+ }
+
+ protected ClientDependencyInclude(IClientDependencyFile file)
+ {
+ Priority = file.Priority;
+ PathNameAlias = file.PathNameAlias;
+ FilePath = file.FilePath;
+ DependencyType = file.DependencyType;
+ Group = file.Group;
+ AddTag = true;
+ HtmlAttributes = new Dictionary();
+ }
+
+ public ClientDependencyType DependencyType { get; internal set; }
+
+ public string FilePath { get; set; }
+ public string PathNameAlias { get; set; }
+ public int Priority { get; set; }
+ public int Group { get; set; }
+ public bool AddTag { get; set; }
+
+ ///
+ /// This can be empty and will use default provider
+ ///
+ public string ForceProvider { get; set; }
+
+ public bool ForceBundle { get; set; }
+
+ ///
+ /// Used to store additional attributes in the HTML markup for the item
+ ///
+ ///
+ /// Mostly used for CSS Media, but could be for anything
+ ///
+ public IDictionary HtmlAttributes { get; private set; }
+
+ ///
+ /// Used to set the HtmlAttributes on this class via a string which is parsed
+ ///
+ ///
+ /// The syntax for the string must be: key1:value1,key2:value2 etc...
+ ///
+ public string HtmlAttributesAsString { get; set; }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ if (string.IsNullOrEmpty(FilePath))
+ throw new NullReferenceException("Both File and Type properties must be set");
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ if (AddTag)
+ {
+ writer.Write("", DependencyType, FilePath);
+ }
+
+ base.Render(writer);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyLoader.cs b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyLoader.cs
new file mode 100644
index 00000000000..e5d70457788
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyLoader.cs
@@ -0,0 +1,316 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web.UI;
+using System.Web;
+using System.Linq;
+using ClientDependency.Core.Config;
+using ClientDependency.Core.FileRegistration.Providers;
+
+namespace ClientDependency.Core.Controls
+{
+ [ParseChildren(typeof(ClientDependencyPath), ChildrenAsProperties = true)]
+ public class ClientDependencyLoader : Control
+ {
+
+ ///
+ /// Constructor sets the defaults.
+ ///
+ public ClientDependencyLoader()
+ {
+ Paths = new ClientDependencyPathCollection();
+
+ _base = new BaseLoader(new HttpContextWrapper(Context))
+ {
+ //by default the provider is the default provider
+ Provider = ClientDependencySettings.Instance.DefaultFileRegistrationProvider
+ };
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ //add this object to the context and validate the context type
+ if (Context != null)
+ {
+ if (!Context.Items.Contains(ContextKey))
+ {
+ lock (Locker)
+ {
+ if (!Context.Items.Contains(ContextKey))
+ {
+ //The context needs to be a page
+ var page = Context.Handler as Page;
+ if (page == null)
+ throw new InvalidOperationException("ClientDependencyLoader only works with Page based handlers.");
+ Context.Items[ContextKey] = this;
+ }
+ }
+ }
+ else
+ {
+ if (Context.Items[ContextKey] != this)
+ {
+ throw new InvalidOperationException("Only one ClientDependencyLoader may exist on a page");
+ }
+ }
+ }
+ else
+ throw new InvalidOperationException("ClientDependencyLoader requires an HttpContext");
+ }
+
+ public const string ContextKey = "ClientDependencyLoader";
+
+ private static readonly object Locker = new object();
+
+ public string ProviderName
+ {
+ get
+ {
+ return _base.Provider.Name;
+ }
+ set
+ {
+ _base.Provider = ClientDependencySettings.Instance.FileRegistrationProviderCollection[value];
+ }
+ }
+
+ [Obsolete("Use the GetInstance() method instead to pass in an HttpContext object")]
+ public static ClientDependencyLoader Instance
+ {
+ get { return GetInstance(new HttpContextWrapper(HttpContext.Current)); }
+ }
+
+ ///
+ /// Singleton per request instance.
+ ///
+ ///
+ /// If no ClientDependencyLoader control exists on the current page, an exception is thrown.
+ ///
+ public static ClientDependencyLoader GetInstance(HttpContextBase ctx)
+ {
+ if (!ctx.Items.Contains(ContextKey))
+ return null;
+ return ctx.Items[ContextKey] as ClientDependencyLoader;
+ }
+
+ private readonly BaseLoader _base;
+
+ ///
+ /// Need to set the container for each of the paths to support databinding.
+ ///
+ protected override void CreateChildControls()
+ {
+ base.CreateChildControls();
+ foreach (var path in Paths)
+ {
+ path.Parent = this;
+ }
+ }
+
+ ///
+ /// Need to bind all children paths.
+ ///
+ ///
+ protected override void OnDataBinding(EventArgs e)
+ {
+ base.OnDataBinding(e);
+ foreach (var path in Paths)
+ {
+ path.DataBind();
+ }
+ }
+
+ ///
+ /// Finds all dependencies on the page and renders them
+ ///
+ ///
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ _base.Paths.UnionWith(Paths.Cast());
+ RegisterClientDependencies((WebFormsFileRegistrationProvider)_base.Provider, Page, _base.Paths);
+ RenderDependencies();
+ }
+
+ private void RenderDependencies()
+ {
+ _base.Dependencies.ForEach(x => ((WebFormsFileRegistrationProvider)x.Provider)
+ .RegisterDependencies(Page, x.Dependencies, _base.Paths, new HttpContextWrapper(Context)));
+ }
+
+ [PersistenceMode(PersistenceMode.InnerProperty)]
+ public ClientDependencyPathCollection Paths { get; private set; }
+
+ #region Static Helper methods
+
+ ///
+ /// Checks if a loader already exists, if it does, it returns it, otherwise it will
+ /// create a new one in the control specified.
+ /// isNew will be true if a loader was created, otherwise false if it already existed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static ClientDependencyLoader TryCreate(Control parent, HttpContextBase http, out bool isNew)
+ {
+ if (GetInstance(http) == null)
+ {
+ var loader = new ClientDependencyLoader();
+ parent.Controls.Add(loader);
+ isNew = true;
+ return loader;
+ }
+ isNew = false;
+ return GetInstance(http);
+ }
+
+ #endregion
+
+ ///
+ /// Registers a file dependency
+ ///
+ ///
+ ///
+ public ClientDependencyLoader RegisterDependency(string filePath, ClientDependencyType type)
+ {
+ _base.RegisterDependency(filePath, type);
+ return this;
+ }
+
+ ///
+ /// Registers a file dependency
+ ///
+ public ClientDependencyLoader RegisterDependency(int priority, string filePath, ClientDependencyType type)
+ {
+ _base.RegisterDependency(priority, filePath, type);
+ return this;
+ }
+
+ ///
+ /// Registers a file dependency
+ ///
+ public ClientDependencyLoader RegisterDependency(int priority, string filePath, string pathNameAlias, ClientDependencyType type)
+ {
+ _base.RegisterDependency(priority, filePath, pathNameAlias, type);
+ return this;
+ }
+
+ ///
+ /// Registers a file dependency
+ ///
+ ///
+ ///
+ ///
+ public ClientDependencyLoader RegisterDependency(string filePath, string pathNameAlias, ClientDependencyType type)
+ {
+ _base.RegisterDependency(Constants.DefaultGroup, Constants.DefaultPriority, filePath, pathNameAlias, type);
+ return this;
+ }
+
+ ///
+ /// Adds a path to the current loader
+ ///
+ ///
+ ///
+ public ClientDependencyLoader AddPath(string pathNameAlias, string path)
+ {
+ _base.AddPath(pathNameAlias, path);
+ return this;
+ }
+
+ ///
+ /// Adds a path to the current loader
+ ///
+ ///
+ public ClientDependencyLoader AddPath(IClientDependencyPath path)
+ {
+ _base.AddPath(path);
+ return this;
+ }
+
+ ///
+ /// Registers dependencies
+ ///
+ ///
+ ///
+ public void RegisterClientDependencies(Control control, ClientDependencyPathCollection paths)
+ {
+ RegisterClientDependencies((WebFormsFileRegistrationProvider)_base.Provider, control, paths.Cast());
+ }
+
+ ///
+ /// Registers dependencies with the provider name specified
+ ///
+ ///
+ ///
+ ///
+ public void RegisterClientDependencies(string providerName, Control control, IEnumerable paths)
+ {
+ RegisterClientDependencies(ClientDependencySettings.Instance.FileRegistrationProviderCollection[providerName], control, paths);
+ }
+
+ ///
+ /// Registers dependencies with the provider specified by T
+ ///
+ public void RegisterClientDependencies(Control control, List paths)
+ where T : WebFormsFileRegistrationProvider
+ {
+ //need to find the provider with the type
+ var found = ClientDependencySettings.Instance.FileRegistrationProviderCollection
+ .Cast()
+ .FirstOrDefault(p => p.GetType().Equals(typeof (T)));
+ if (found == null)
+ throw new ArgumentException("Could not find the ClientDependencyProvider specified by T");
+
+ RegisterClientDependencies(found, control, paths);
+ }
+
+ public void RegisterClientDependencies(WebFormsFileRegistrationProvider provider, Control control, IEnumerable paths)
+ {
+ var dependencies = FindDependencies(control);
+ _base.RegisterClientDependencies(provider, dependencies, paths, ClientDependencySettings.Instance.FileRegistrationProviderCollection);
+ }
+
+ ///
+ /// Find all dependencies of this control and it's entire child control hierarchy.
+ ///
+ ///
+ ///
+ private static IEnumerable FindDependencies(Control control)
+ {
+ var ctls = new List(control.FlattenChildren()) { control };
+
+ var dependencies = new List();
+
+ // add child dependencies
+ var iClientDependency = typeof(IClientDependencyFile);
+ foreach (var ctl in ctls)
+ {
+ // find dependencies
+ var controlType = ctl.GetType();
+
+ //dependencies.AddRange(Attribute.GetCustomAttributes(controlType)
+ // .OfType()
+ // .Cast());
+
+ if (iClientDependency.IsAssignableFrom(ctl.GetType()))
+ {
+ var include = (IClientDependencyFile)ctl;
+ dependencies.Add(include);
+ }
+
+ }
+
+ return dependencies;
+ }
+
+ }
+
+
+
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyPath.cs b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyPath.cs
new file mode 100644
index 00000000000..203ab3f35d3
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyPath.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web.UI;
+
+namespace ClientDependency.Core.Controls
+{
+
+ ///
+ /// A path object for the client dependency loader. Used to specify all of the base paths (name and path) to
+ /// be used with the client dependencies.
+ /// Databinding support has been enabled.
+ ///
+ [ParseChildren(true)]
+ public class ClientDependencyPath : IClientDependencyPath
+ {
+ string _name = "";
+ string _path = "";
+
+ public string Name { get { return _name; } set { _name = value; } }
+ public string Path { get { return _path; } set { _path = value; } }
+
+ public bool ForceBundle { get; set; }
+
+ #region Logic to allow for databinding non-UI ASP.Net control
+ public event EventHandler DataBinding;
+ public void DataBind()
+ {
+ OnDataBinding(new EventArgs());
+ }
+ protected void OnDataBinding(EventArgs e)
+ {
+ if (DataBinding != null)
+ DataBinding(this, e);
+ }
+ public Control BindingContainer
+ {
+ get
+ {
+ return Parent;
+ }
+ }
+ #endregion
+
+ ///
+ /// This is set at runtime to set the load for this path object. this is required for databinding.
+ ///
+ public ClientDependencyLoader Parent { get; internal set; }
+
+ public string ResolvedPath
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(Path))
+ throw new ArgumentNullException("Path has not been set");
+ return Parent.ResolveUrl(Path);
+ }
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyPathCollection.cs b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyPathCollection.cs
new file mode 100644
index 00000000000..f94f1b3046d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/ClientDependencyPathCollection.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ClientDependency.Core.Controls
+{
+ public class ClientDependencyPathCollection : List
+ {
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/CssInclude.cs b/DNN Platform/Components/ClientDependency/Source/Controls/CssInclude.cs
new file mode 100644
index 00000000000..19b638b4225
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/CssInclude.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClientDependency.Core.Controls
+{
+ public class CssInclude : ClientDependencyInclude
+ {
+ internal bool EncodeImages { get; set; }
+
+ public CssInclude()
+ {
+ DependencyType = ClientDependencyType.Css;
+ CssMedia = CssMediaType.All;
+ }
+ public CssInclude(IClientDependencyFile file)
+ : base(file)
+ {
+ DependencyType = ClientDependencyType.Css;
+ CssMedia = CssMediaType.All;
+ }
+ public CssInclude(IClientDependencyFile file, CssMediaType mediaType)
+ : base(file)
+ {
+ DependencyType = ClientDependencyType.Css;
+ CssMedia = mediaType;
+ }
+
+ public CssMediaType CssMedia { get; set; }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/HtmlInclude.cs b/DNN Platform/Components/ClientDependency/Source/Controls/HtmlInclude.cs
new file mode 100644
index 00000000000..49ee11788a1
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/HtmlInclude.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Web;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Text.RegularExpressions;
+
+namespace ClientDependency.Core.Controls
+{
+ [ToolboxData("<{0}:HtmlInclude runat=\"server\">{0}:HtmlInclude>")]
+ public class HtmlInclude : Literal
+ {
+ public const string TagPattern = @"<{0}((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>";
+ public const string AttributePattern = @"{0}(\s*=\s*(?:""(?.*?)""|'(?.*?)'|(?[^'"">\s]+)))";
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ var isNew = false;
+ var loader = ClientDependencyLoader.TryCreate(Page, new HttpContextWrapper(Context), out isNew);
+
+ RegisterIncludes(Text, loader);
+
+ Text = string.Empty;
+ }
+
+ private static void RegisterIncludes(string innerHtml, ClientDependencyLoader loader)
+ {
+ RegisterCssIncludes(innerHtml, loader);
+ RegisterJsIncludes(innerHtml, loader);
+ }
+
+ private static void RegisterCssIncludes(string innerHtml, ClientDependencyLoader loader)
+ {
+ var tagPattern = string.Format(TagPattern, "link");
+ var typeAttributePattern = string.Format(AttributePattern, "type");
+ var srcAttributePattern = string.Format(AttributePattern, "href");
+
+ var count = 0;
+ foreach (Match match in Regex.Matches(innerHtml, tagPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ {
+ var typeMatch = Regex.Match(match.Value, typeAttributePattern,
+ RegexOptions.Compiled | RegexOptions.IgnoreCase |
+ RegexOptions.CultureInvariant);
+
+ if (typeMatch.Success && typeMatch.Groups["val"].Value == "text/css")
+ {
+ var srcMatch = Regex.Match(match.Value, srcAttributePattern,
+ RegexOptions.Compiled | RegexOptions.IgnoreCase |
+ RegexOptions.CultureInvariant);
+
+ if (srcMatch.Success)
+ {
+ loader.RegisterDependency(Constants.DefaultPriority + count,
+ srcMatch.Groups["val"].Value,
+ ClientDependencyType.Css);
+
+ count++;
+ }
+ }
+ }
+ }
+
+ private static void RegisterJsIncludes(string innerHtml, ClientDependencyLoader loader)
+ {
+ var tagPattern = string.Format(TagPattern, "script");
+ var typeAttributePattern = string.Format(AttributePattern, "type");
+ var srcAttributePattern = string.Format(AttributePattern, "src");
+
+ var count = 0;
+ foreach (Match match in Regex.Matches(innerHtml, tagPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ {
+ var typeMatch = Regex.Match(match.Value, typeAttributePattern,
+ RegexOptions.Compiled | RegexOptions.IgnoreCase |
+ RegexOptions.CultureInvariant);
+
+ if (typeMatch.Success && typeMatch.Groups["val"].Value == "text/javascript")
+ {
+ var srcMatch = Regex.Match(match.Value, srcAttributePattern,
+ RegexOptions.Compiled | RegexOptions.IgnoreCase |
+ RegexOptions.CultureInvariant);
+
+ if (srcMatch.Success)
+ {
+ loader.RegisterDependency(Constants.DefaultPriority + count,
+ srcMatch.Groups["val"].Value,
+ ClientDependencyType.Javascript);
+
+ count++;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Controls/JsInclude.cs b/DNN Platform/Components/ClientDependency/Source/Controls/JsInclude.cs
new file mode 100644
index 00000000000..1aec4b9fb30
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Controls/JsInclude.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClientDependency.Core.Controls
+{
+ public class JsInclude : ClientDependencyInclude
+ {
+
+ public JsInclude()
+ {
+ DependencyType = ClientDependencyType.Javascript;
+ }
+ public JsInclude(IClientDependencyFile file)
+ : base(file)
+ {
+ DependencyType = ClientDependencyType.Javascript;
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CssFileUrlFormatter.cs b/DNN Platform/Components/ClientDependency/Source/CssFileUrlFormatter.cs
new file mode 100644
index 00000000000..d1b1214ca1e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CssFileUrlFormatter.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace ClientDependency.Core
+{
+ public class CssFileUrlFormatter
+ {
+
+ ///
+ /// Returns the CSS file with all of the url's formatted to be absolute locations
+ ///
+ /// content of the css file
+ /// the uri location of the css file
+ ///
+ public static string TransformCssFile(string fileContent, Uri cssLocation)
+ {
+ string str = Regex.Replace(
+ fileContent,
+ @"url\(((?!data:).+?)\)",
+ new MatchEvaluator(
+ delegate(Match m)
+ {
+ if (m.Groups.Count == 2)
+ {
+ var match = m.Groups[1].Value.Trim('\'', '"');
+ var hashSplit = match.Split(new[] {'#'}, StringSplitOptions.RemoveEmptyEntries);
+
+ return string.Format(@"url(""{0}{1}"")",
+ match.StartsWith("http") ? match : new Uri(cssLocation, match).PathAndQuery,
+ hashSplit.Length > 1 ? ("#" + hashSplit[1]) : "");
+ }
+ return m.Value;
+ })
+ );
+
+ return str;
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/CssMediaType.cs b/DNN Platform/Components/ClientDependency/Source/CssMediaType.cs
new file mode 100644
index 00000000000..5aa2cb1937c
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/CssMediaType.cs
@@ -0,0 +1,7 @@
+namespace ClientDependency.Core
+{
+ public enum CssMediaType
+ {
+ All, Screen, Print
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/DependencyHtmlElement.cs b/DNN Platform/Components/ClientDependency/Source/DependencyHtmlElement.cs
new file mode 100644
index 00000000000..1ef46edf03c
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/DependencyHtmlElement.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+
+namespace ClientDependency.Core
+{
+ ///
+ /// A simple model defining the source of the dependency and the Html Elements that need to be rendered as part of the html tag
+ ///
+ public class DependencyHtmlElement
+ {
+ public string Source { get; set; }
+ public IDictionary HtmlAttributes { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/DictionaryExtensions.cs b/DNN Platform/Components/ClientDependency/Source/DictionaryExtensions.cs
new file mode 100644
index 00000000000..de31de434fe
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/DictionaryExtensions.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ClientDependency.Core
+{
+ public static class DictionaryExtensions
+ {
+
+ ///
+ /// Returns the dictionary as formatted html attributes for use in an html tag
+ ///
+ ///
+ ///
+ public static string ToHtmlAttributes(this IDictionary d)
+ {
+ return string.Join(" ", d.Select(x => x.Key + "=\"" + x.Value + "\"").ToArray());
+ }
+
+ ///
+ /// Determines if 2 dictionaries contain the exact same keys/values
+ ///
+ ///
+ ///
+ ///
+ public static bool IsEqualTo(this IDictionary d, IDictionary compareTo)
+ {
+ if (d.Count != compareTo.Count)
+ return false;
+
+ foreach(var i in d)
+ {
+ if (!compareTo.ContainsKey(i.Key))
+ return false;
+ if (!compareTo[i.Key].Equals(i.Value, StringComparison.InvariantCultureIgnoreCase))
+ return false;
+ }
+
+ return true;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/BaseFileRegistrationProvider.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/BaseFileRegistrationProvider.cs
new file mode 100644
index 00000000000..5703276a052
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/BaseFileRegistrationProvider.cs
@@ -0,0 +1,358 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Text;
+using System.Web.UI;
+using System.Configuration.Provider;
+using System.Web;
+using System.Linq;
+using ClientDependency.Core.CompositeFiles.Providers;
+using ClientDependency.Core.Controls;
+using ClientDependency.Core.Config;
+using ClientDependency.Core;
+using ClientDependency.Core.CompositeFiles;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public abstract class BaseFileRegistrationProvider : ProviderBase
+ {
+ ///
+ /// Constructor sets defaults
+ ///
+ protected BaseFileRegistrationProvider()
+ {
+ EnableCompositeFiles = true;
+ }
+
+ //protected HashSet FolderPaths { get; set; }
+ //protected List AllDependencies { get; set; }
+
+ ///
+ /// By default this is true but can be overriden (in either config or code).
+ /// Composite files are never enabled with compilation debug="true" however.
+ ///
+ public virtual bool EnableCompositeFiles { get; set; }
+
+ /////
+ ///// By default this is empty, but if you want to explicity define a base url for dependencies you can
+ /////
+ //public string WebsiteBaseUrl { get; set; }
+
+ #region Abstract methods/properties
+
+ protected abstract string RenderJsDependencies(IEnumerable jsDependencies, HttpContextBase http, IDictionary htmlAttributes);
+ protected abstract string RenderCssDependencies(IEnumerable cssDependencies, HttpContextBase http, IDictionary htmlAttributes);
+
+ protected abstract string RenderSingleJsFile(string js, IDictionary htmlAttributes);
+ protected abstract string RenderSingleCssFile(string css, IDictionary htmlAttributes);
+
+ #endregion
+
+ #region Provider Initialization
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ base.Initialize(name, config);
+
+ if (config != null && config["enableCompositeFiles"] != null && !string.IsNullOrEmpty(config["enableCompositeFiles"]))
+ {
+ EnableCompositeFiles = bool.Parse(config["enableCompositeFiles"]);
+ }
+
+ //if (config != null && config["websiteBaseUrl"] != null && !string.IsNullOrEmpty(config["websiteBaseUrl"]))
+ //{
+ // WebsiteBaseUrl = config["website"];
+ // if (!string.IsNullOrEmpty(WebsiteBaseUrl))
+ // WebsiteBaseUrl = WebsiteBaseUrl.TrimEnd('/');
+ //}
+ }
+
+ #endregion
+
+ #region Protected Methods
+
+ ///
+ /// Because we can have both internal and external dependencies rendered, we need to stagger the script tag output... if they are external, we need to stop the compressing/combining
+ /// and write out the external dependency, then resume the compressing/combining handler.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected void WriteStaggeredDependencies(
+ IEnumerable dependencies,
+ HttpContextBase http,
+ StringBuilder builder,
+ Func, HttpContextBase, IDictionary, string> renderCompositeFiles,
+ Func, string> renderSingle)
+ {
+
+
+ //This action will stagger the output based on whether or not the html attribute declarations are the same for each dependency
+ Action> staggerOnDifferentAttributes = (list) =>
+ {
+ var sameAttributes = new List();
+ var currHtmlAttr = GetHtmlAttributes(list.ElementAt(0));
+ foreach (var c in list)
+ {
+ if (!currHtmlAttr.IsEqualTo(GetHtmlAttributes(c)))
+ {
+ //if the attributes are different we need to stagger
+ if (sameAttributes.Any())
+ {
+ //render the current buffer
+ builder.Append(renderCompositeFiles(sameAttributes, http, currHtmlAttr));
+ //clear the buffer
+ sameAttributes.Clear();
+ }
+ }
+
+ //add the item to the buffer and set the current html attributes
+ sameAttributes.Add(c);
+ currHtmlAttr = GetHtmlAttributes(c);
+ }
+
+ //if there's anything in the buffer then write the remaining
+ if (sameAttributes.Any())
+ builder.Append(renderCompositeFiles(sameAttributes, http, currHtmlAttr));
+ };
+
+ var currNonRemoteFiles = new List();
+ foreach (var f in dependencies)
+ {
+ //if it is an external resource, then we need to break the sequence
+ // unless it has been explicitely required that the dependency be bundled
+ if (http.IsAbsolutePath(f.FilePath)
+ //remote dependencies aren't local
+ && !new Uri(f.FilePath, UriKind.RelativeOrAbsolute).IsLocalUri(http)
+ // not required to be bundled
+ && !f.ForceBundle)
+ {
+ //we've encountered an external dependency, so we need to break the sequence and restart it after
+ //we output the raw script tag
+ if (currNonRemoteFiles.Count > 0)
+ {
+ //render the current buffer
+ staggerOnDifferentAttributes(currNonRemoteFiles);
+ //clear the buffer
+ currNonRemoteFiles.Clear();
+ }
+ //write out the single script tag
+ builder.Append(renderSingle(f.FilePath, GetHtmlAttributes(f)));
+ }
+ else
+ {
+ //its a normal registration, add to the buffer
+ currNonRemoteFiles.Add(f);
+ }
+ }
+ //now check if there's anything in the buffer to render
+ if (currNonRemoteFiles.Count > 0)
+ {
+ //render the current buffer
+ staggerOnDifferentAttributes(currNonRemoteFiles);
+ }
+ }
+
+ ///
+ /// Ensures the correctly resolved file path is set for each dependency (i.e. so that ~ are taken care of) and also
+ /// prefixes the file path with the correct base path specified for the PathNameAlias if specified.
+ ///
+ /// The dependencies list for which file paths will be updated
+ ///
+ ///
+ protected virtual void UpdateFilePaths(IEnumerable dependencies,
+ HashSet folderPaths, HttpContextBase http)
+ {
+ foreach (var dependency in dependencies)
+ {
+ if (!string.IsNullOrEmpty(dependency.PathNameAlias))
+ {
+ var paths = folderPaths.ToList();
+ var d = dependency;
+ var path = paths.Find(
+ (p) => p.Name == d.PathNameAlias);
+ if (path == null)
+ {
+ throw new NullReferenceException("The PathNameAlias specified for dependency " + dependency.FilePath + " does not exist in the ClientDependencyPathCollection");
+ }
+ var resolvedPath = path.ResolvePath(http);
+ var basePath = resolvedPath.EndsWith("/") ? resolvedPath : resolvedPath + "/";
+ dependency.FilePath = basePath + dependency.FilePath;
+ dependency.ForceBundle = (dependency.ForceBundle | path.ForceBundle);
+ }
+ else
+ {
+ dependency.FilePath = dependency.ResolveFilePath(http);
+ }
+
+ //append query strings to each file if we are in debug mode
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ dependency.FilePath = AppendVersion(dependency.FilePath, http);
+ }
+ }
+ }
+
+
+ ///
+ /// This will ensure that no duplicates have made it into the collection.
+ /// Duplicates WILL occur if the same dependency is registered in 2 different ways:
+ /// one with a global path and one with a full path. This is because paths may not be defined
+ /// until we render so we cannot de-duplicate at the time of registration.
+ /// De-duplication will remove the dependency with a lower priority or later in the list.
+ /// This also must be called after UpdatePaths are called since we need to full path filled in.
+ ///
+ /// The dependencies list for which duplicates will be removed
+ ///
+ protected virtual void EnsureNoDuplicates(List dependencies, HashSet folderPaths)
+ {
+ var toKeep = new HashSet();
+
+ foreach (var d in dependencies)
+ {
+ //check if it is a duplicate
+ if (dependencies
+ .Where(x => x.FilePath.ToUpper().Trim().Equals(d.FilePath.ToUpper().Trim()))
+ .Any())
+ {
+ //find the dups and return an object with the associated index
+ var dups = dependencies
+ .Where(x => x.FilePath.ToUpper().Trim().Equals(d.FilePath.ToUpper().Trim()))
+ .Select((x, index) => new { Index = index, File = x })
+ .ToList();
+
+ var priorities = dups.Select(x => x.File.Priority).Distinct().ToList();
+
+ //if there's more than 1 priority defined, we know we need to remove by priority
+ //instead of by index
+ if (priorities.Count() > 1)
+ {
+ toKeep.Add(dups
+ .Where(x => x.File.Priority == priorities.Min())
+ .First().File);
+ }
+ else
+ {
+ //if not by priority, we just need to keep the first on in the list
+ toKeep.Add(dups
+ .Where(x => x.Index == dups
+ .Select(p => p.Index)
+ .Min())
+ .First().File);
+ }
+ }
+ else
+ {
+ //if there's only one found, then just add it to our output
+ toKeep.Add(d);
+ }
+
+
+ }
+
+ dependencies.Clear();
+ dependencies.AddRange(toKeep);
+
+
+ }
+
+ private string AppendVersion(string url, HttpContextBase http)
+ {
+ var version = this.GetVersion();
+ if (version == 0)
+ return url;
+ if ((http.IsDebuggingEnabled || !EnableCompositeFiles)
+ || ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.UrlType == CompositeUrlType.Base64QueryStrings)
+ {
+ //ensure there's not duplicated query string syntax
+ url += url.Contains('?') ? "&" : "?";
+ //append a version
+ url += "cdv=" + version;
+ }
+ else
+ {
+ //the URL should end with a '0'
+ url = url.TrimEnd('0') + version;
+ }
+ return url;
+ }
+
+ public virtual int GetVersion()
+ {
+ return ClientDependencySettings.Instance.Version;
+ }
+
+ #endregion
+
+ /////
+ ///// Checks if the "website" config param has been passed in, if so this formats the url
+ ///// to be an absolute URL with the pre-pended domain
+ /////
+ /////
+ /////
+ //protected string MapToWebsiteBaseUrl(string url)
+ //{
+ // if (!string.IsNullOrEmpty(WebsiteBaseUrl))
+ // {
+ // if (url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)
+ // || url.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
+ // return url;
+
+ // // make sure the url begins with a /
+ // string slashedUrl = (url[0] != '/' ? "/" : string.Empty) + url;
+
+ // return WebsiteBaseUrl + slashedUrl;
+ // }
+ // return url;
+ //}
+
+
+ ///
+ /// Checks if the current file implements the html attribute interfaces and returns the appropriate html attributes
+ ///
+ ///
+ ///
+ private static IDictionary GetHtmlAttributes(IClientDependencyFile file)
+ {
+ IDictionary attributes = new Dictionary();
+
+ if (file is IHaveHtmlAttributes)
+ {
+ var fileWithAttributes = (IHaveHtmlAttributes)file;
+ attributes = fileWithAttributes.HtmlAttributes;
+
+ if (file is IRequiresHtmlAttributesParsing)
+ {
+ //we need to parse the attributes into the dictionary
+ HtmlAttributesStringParser.ParseIntoDictionary(((IRequiresHtmlAttributesParsing)file).HtmlAttributesAsString, attributes);
+ }
+ }
+
+ //now we must ensure that the correct js/css attribute exist!
+ switch(file.DependencyType)
+ {
+ case ClientDependencyType.Javascript:
+ if (!attributes.ContainsKey("type"))
+ attributes.Add("type", "text/javascript");
+ if (attributes.ContainsKey("src"))
+ attributes.Remove("src");
+ break;
+ case ClientDependencyType.Css:
+ if (!attributes.ContainsKey("type"))
+ attributes.Add("type", "text/css");
+ if (!attributes.ContainsKey("rel"))
+ attributes.Add("rel", "stylesheet");
+ if (attributes.ContainsKey("href"))
+ attributes.Remove("href");
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ //just return an empty dictionary
+ return attributes;
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/BaseRenderer.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/BaseRenderer.cs
new file mode 100644
index 00000000000..5b0a30e81dc
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/BaseRenderer.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration.Provider;
+using ClientDependency.Core.Config;
+using ClientDependency.Core.FileRegistration.Providers;
+using System.IO;
+using System.Web;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public abstract class BaseRenderer : BaseFileRegistrationProvider
+ {
+
+
+ public virtual void RegisterDependencies(List allDependencies,
+ HashSet paths,
+ out string jsOutput,
+ out string cssOutput,
+ HttpContextBase http)
+ {
+ var folderPaths = paths;
+
+ UpdateFilePaths(allDependencies, folderPaths, http);
+ EnsureNoDuplicates(allDependencies, folderPaths);
+
+ var cssBuilder = new StringBuilder();
+ var jsBuilder = new StringBuilder();
+
+ // find the groups
+ var groups = allDependencies
+ .Select(x => x.Group)
+ .Distinct()
+ .ToList();
+
+ // sort them
+ groups.Sort((a, b) => a.CompareTo(b));
+
+ foreach (var group in groups)
+ {
+ var g = group;
+ var jsDependencies = allDependencies
+ .Where(x => x.Group == g && x.DependencyType == ClientDependencyType.Javascript)
+ .ToList();
+
+ var cssDependencies = allDependencies
+ .Where(x => x.Group == g && x.DependencyType == ClientDependencyType.Css)
+ .ToList();
+
+ // sort by priority
+ jsDependencies.Sort((a, b) => a.Priority.CompareTo(b.Priority));
+ cssDependencies.Sort((a, b) => a.Priority.CompareTo(b.Priority));
+
+ //render
+ WriteStaggeredDependencies(cssDependencies, http, cssBuilder, RenderCssDependencies, RenderSingleCssFile);
+ WriteStaggeredDependencies(jsDependencies, http, jsBuilder, RenderJsDependencies, RenderSingleJsFile);
+
+ }
+ cssOutput = cssBuilder.ToString();
+ jsOutput = jsBuilder.ToString();
+ }
+ }
+}
+
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/FileRegistrationProviderCollection.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/FileRegistrationProviderCollection.cs
new file mode 100644
index 00000000000..5e43e0f9e5e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/FileRegistrationProviderCollection.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration.Provider;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class FileRegistrationProviderCollection : ProviderCollection
+ {
+ public new WebFormsFileRegistrationProvider this[string name]
+ {
+ get { return (WebFormsFileRegistrationProvider)base[name]; }
+ }
+
+ public override void Add(ProviderBase provider)
+ {
+ if (provider == null)
+ throw new ArgumentNullException("provider");
+
+ if (!(provider is WebFormsFileRegistrationProvider))
+ throw new ArgumentException("Invalid provider type", "provider");
+
+ base.Add(provider);
+ }
+
+ }
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/HtmlEmbedContants.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/HtmlEmbedContants.cs
new file mode 100644
index 00000000000..037775fc65d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/HtmlEmbedContants.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class HtmlEmbedContants
+ {
+ public const string ScriptEmbedWithSource = "";
+ public const string CssEmbedWithSource = "";
+
+ public const string ScriptEmbedWithCode = "";
+ //public const string CssEmbed = "";
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LazyLoadProvider.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LazyLoadProvider.cs
new file mode 100644
index 00000000000..5a5c5f4c2c2
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LazyLoadProvider.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.Web.UI;
+using ClientDependency.Core.Config;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class LazyLoadProvider : WebFormsFileRegistrationProvider
+ {
+
+ public const string DefaultName = "LazyLoadProvider";
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ // Assign the provider a default name if it doesn't have one
+ if (string.IsNullOrEmpty(name))
+ name = DefaultName;
+
+ base.Initialize(name, config);
+ }
+
+ /// Path to the dependency loader we need for adding control dependencies.
+ protected const string DependencyLoaderResourceName = "ClientDependency.Core.Resources.LazyLoader.js";
+
+ protected override string RenderJsDependencies(IEnumerable jsDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!jsDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in jsDependencies)
+ {
+ sb.Append(RenderSingleJsFile(string.Format("'{0}','{1}'", dependency.FilePath, string.Empty), htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(jsDependencies, ClientDependencyType.Javascript, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleJsFile(string.Format("'{0}','{1}'", s, string.Empty), htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleJsFile(string js, IDictionary htmlAttributes)
+ {
+ var strClientLoader = new StringBuilder("CDLazyLoader");
+ strClientLoader.AppendFormat(".AddJs({0})", js);
+ strClientLoader.Append(';');
+ return strClientLoader.ToString();
+ }
+
+ protected override string RenderCssDependencies(IEnumerable cssDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!cssDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in cssDependencies)
+ {
+ sb.Append(RenderSingleCssFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(cssDependencies, ClientDependencyType.Css, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleCssFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleCssFile(string css, IDictionary htmlAttributes)
+ {
+ var strClientLoader = new StringBuilder("CDLazyLoader");
+ strClientLoader.AppendFormat(".AddCss('{0}')", css);
+ strClientLoader.Append(';');
+ return strClientLoader.ToString();
+ }
+
+ protected override void RegisterDependencies(HttpContextBase http, string js, string css)
+ {
+ if (!(http.CurrentHandler is Page))
+ {
+ throw new InvalidOperationException("The current HttpHandler in a WebFormsFileRegistrationProvider must be of type Page");
+ }
+ var page = (Page)http.CurrentHandler;
+
+ page.ClientScript.RegisterClientScriptResource(typeof(LazyLoadProvider), DependencyLoaderResourceName);
+
+ RegisterScript(js, page);
+ RegisterScript(css, page);
+ }
+
+ private void RegisterScript(string strScript, Page page)
+ {
+ var mgr = ScriptManager.GetCurrent(page);
+
+ if (mgr == null)
+ {
+ if (page.Form == null)
+ throw new InvalidOperationException("A form tag must be present on the page with a runat='server' attribute specified");
+ page.ClientScript.RegisterStartupScript(GetType(), strScript.GetHashCode().ToString(), strScript, true);
+ }
+ else
+ {
+ ScriptManager.RegisterStartupScript(page, GetType(), strScript.GetHashCode().ToString(), strScript, true);
+ }
+ }
+
+ }
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LazyLoadRenderer.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LazyLoadRenderer.cs
new file mode 100644
index 00000000000..6c39439dd79
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LazyLoadRenderer.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClientDependency.Core.FileRegistration.Providers;
+using ClientDependency.Core.Config;
+using System.Web.UI;
+using System.Web;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class LazyLoadRenderer : BaseRenderer
+ {
+ public const string DefaultName = "LazyLoadRenderer";
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ // Assign the provider a default name if it doesn't have one
+ if (string.IsNullOrEmpty(name))
+ name = DefaultName;
+
+ base.Initialize(name, config);
+ }
+
+ /// Path to the dependency loader we need for adding control dependencies.
+ protected const string DependencyLoaderResourceName = "ClientDependency.Core.Resources.LazyLoader.js";
+
+
+ private static readonly object Locker = new object();
+
+
+ ///
+ /// This is silly to have to do this but MS don't give you a way in MVC to do this
+ ///
+ ///
+ ///
+ ///
+ private string GetWebResourceUrl(Type type, string resourceId)
+ {
+ if (type == null)
+ type = GetType();
+
+ var page = new Page();
+ return page.ClientScript.GetWebResourceUrl(type, resourceId);
+ }
+
+ ///
+ /// This will check if the lazy loader script has been registered yet (it does this by storing a flah in the HttpContext.Items)
+ /// if it hasn't then it will add the script registration to the StringBuilder
+ ///
+ ///
+ ///
+ private void RegisterLazyLoadScript(StringBuilder sb, HttpContextBase http)
+ {
+ if (http.Items["LazyLoaderLoaded"] == null || (bool)http.Items["LazyLoaderLoaded"] == false)
+ {
+ lock (Locker)
+ {
+ if (http.Items["LazyLoaderLoaded"] == null || (bool)http.Items["LazyLoaderLoaded"] == false)
+ {
+ http.Items["LazyLoaderLoaded"] = true;
+
+ var url = GetWebResourceUrl(typeof(LazyLoadProvider), DependencyLoaderResourceName);
+ sb.Append(string.Format(HtmlEmbedContants.ScriptEmbedWithSource, url, ""));
+ }
+ }
+ }
+ }
+
+ protected override string RenderJsDependencies(IEnumerable jsDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!jsDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in jsDependencies)
+ {
+ sb.Append(RenderSingleJsFile(string.Format("'{0}','{1}'", dependency.FilePath, string.Empty), htmlAttributes));
+ }
+ }
+ else
+ {
+
+ RegisterLazyLoadScript(sb, http);
+
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(jsDependencies, ClientDependencyType.Javascript, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleJsFile(string.Format("'{0}','{1}'", s, string.Empty), htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Registers the Css dependencies.
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected override string RenderCssDependencies(IEnumerable cssDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!cssDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in cssDependencies)
+ {
+ sb.Append(RenderSingleCssFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+
+ RegisterLazyLoadScript(sb, http);
+
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(cssDependencies, ClientDependencyType.Css, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleCssFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleJsFile(string js, IDictionary htmlAttributes)
+ {
+ var strClientLoader = new StringBuilder("CDLazyLoader");
+ strClientLoader.AppendFormat(".AddJs({0})", js);
+ strClientLoader.Append(';');
+
+ return string.Format(HtmlEmbedContants.ScriptEmbedWithCode, strClientLoader.ToString());
+ }
+
+ protected override string RenderSingleCssFile(string css, IDictionary htmlAttributes)
+ {
+ var strClientLoader = new StringBuilder("CDLazyLoader");
+ strClientLoader.AppendFormat(".AddCss('{0}')", css);
+ strClientLoader.Append(';');
+
+ return string.Format(HtmlEmbedContants.ScriptEmbedWithCode, strClientLoader);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LoaderControlProvider.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LoaderControlProvider.cs
new file mode 100644
index 00000000000..2e18ee1598e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/LoaderControlProvider.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Text;
+using System.Web.UI;
+using ClientDependency.Core.Controls;
+using ClientDependency.Core.Config;
+using System.Web;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class LoaderControlProvider : WebFormsFileRegistrationProvider
+ {
+
+ public const string DefaultName = "LoaderControlProvider";
+
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ // Assign the provider a default name if it doesn't have one
+ if (string.IsNullOrEmpty(name))
+ name = DefaultName;
+
+ base.Initialize(name, config);
+ }
+
+ protected override string RenderJsDependencies(IEnumerable jsDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!jsDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in jsDependencies)
+ {
+ sb.Append(RenderSingleJsFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(jsDependencies, ClientDependencyType.Javascript, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleJsFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderCssDependencies(IEnumerable cssDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!cssDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in cssDependencies)
+ {
+ sb.Append(RenderSingleCssFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(cssDependencies, ClientDependencyType.Css, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleCssFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleJsFile(string js, IDictionary htmlAttributes)
+ {
+ return string.Format(HtmlEmbedContants.ScriptEmbedWithSource, js, htmlAttributes.ToHtmlAttributes());
+ }
+
+ protected override string RenderSingleCssFile(string css, IDictionary htmlAttributes)
+ {
+ return string.Format(HtmlEmbedContants.CssEmbedWithSource, css, htmlAttributes.ToHtmlAttributes());
+ }
+
+ ///
+ /// Registers the dependencies as controls of the LoaderControl controls collection
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// For some reason ampersands that aren't html escaped are not compliant to HTML standards when they exist in 'link' or 'script' tags in URLs,
+ /// we need to replace the ampersands with & . This is only required for this one w3c compliancy, the URL itself is a valid URL.
+ ///
+ protected override void RegisterDependencies(HttpContextBase http, string js, string css)
+ {
+ AddToControl(http, css.Replace("&", "&"));
+ AddToControl(http, js.Replace("&", "&"));
+ }
+
+ private static void AddToControl(HttpContextBase http, string literal)
+ {
+ var dCtl = new LiteralControl(literal);
+ ClientDependencyLoader.GetInstance(http).Controls.Add(dCtl);
+ }
+
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/PageHeaderProvider.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/PageHeaderProvider.cs
new file mode 100644
index 00000000000..a18d052850c
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/PageHeaderProvider.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web.UI;
+using System.Linq;
+using ClientDependency.Core.Config;
+using System.Web;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class PageHeaderProvider : WebFormsFileRegistrationProvider
+ {
+
+ public const string DefaultName = "PageHeaderProvider";
+
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ // Assign the provider a default name if it doesn't have one
+ if (string.IsNullOrEmpty(name))
+ name = DefaultName;
+
+ base.Initialize(name, config);
+ }
+
+ protected override string RenderJsDependencies(IEnumerable jsDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!jsDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in jsDependencies)
+ {
+ sb.Append(RenderSingleJsFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(jsDependencies, ClientDependencyType.Javascript, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleJsFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleJsFile(string js, IDictionary htmlAttributes)
+ {
+ return string.Format(HtmlEmbedContants.ScriptEmbedWithSource, js, htmlAttributes.ToHtmlAttributes());
+ }
+
+ protected override string RenderCssDependencies(IEnumerable cssDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!cssDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in cssDependencies)
+ {
+ sb.Append(RenderSingleCssFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(cssDependencies, ClientDependencyType.Css, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleCssFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleCssFile(string css, IDictionary htmlAttributes)
+ {
+ return string.Format(HtmlEmbedContants.CssEmbedWithSource, css, htmlAttributes.ToHtmlAttributes());
+ }
+
+ ///
+ /// Registers the dependencies in the page header
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// For some reason ampersands that aren't html escaped are not compliant to HTML standards when they exist in 'link' or 'script' tags in URLs,
+ /// we need to replace the ampersands with & . This is only required for this one w3c compliancy, the URL itself is a valid URL.
+ ///
+ ///
+ protected override void RegisterDependencies(HttpContextBase http, string js, string css)
+ {
+ if (!(http.CurrentHandler is Page))
+ {
+ throw new InvalidOperationException("The current HttpHandler in a WebFormsFileRegistrationProvider must be of type Page");
+ }
+ var page = (Page) http.CurrentHandler;
+
+ if (page.Header == null)
+ throw new NullReferenceException("PageHeaderProvider requires a runat='server' tag in the page's header tag");
+
+ var jsScriptBlock = new LiteralControl(js.Replace("&", "&"));
+ var cssStyleBlock = new LiteralControl(css.Replace("&", "&"));
+ page.Header.Controls.Add(cssStyleBlock);
+ page.Header.Controls.Add(jsScriptBlock);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/RendererCollection.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/RendererCollection.cs
new file mode 100644
index 00000000000..e85a07174c3
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/RendererCollection.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration.Provider;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class RendererCollection : ProviderCollection
+ {
+ public new BaseRenderer this[string name]
+ {
+ get { return (BaseRenderer)base[name]; }
+ }
+
+ public override void Add(ProviderBase provider)
+ {
+ if (provider == null)
+ throw new ArgumentNullException("provider");
+
+ if (!(provider is BaseRenderer))
+ throw new ArgumentException("Invalid provider type", "provider");
+
+ base.Add(provider);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/StandardRenderer.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/StandardRenderer.cs
new file mode 100644
index 00000000000..7187e2866c8
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/StandardRenderer.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using ClientDependency.Core.FileRegistration.Providers;
+using ClientDependency.Core.Config;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public class StandardRenderer : BaseRenderer
+ {
+
+ public const string DefaultName = "StandardRenderer";
+
+ public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
+ {
+ // Assign the provider a default name if it doesn't have one
+ if (string.IsNullOrEmpty(name))
+ name = DefaultName;
+
+ base.Initialize(name, config);
+ }
+
+ protected override string RenderJsDependencies(IEnumerable jsDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!jsDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in jsDependencies)
+ {
+ sb.Append(RenderSingleJsFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(jsDependencies, ClientDependencyType.Javascript, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleJsFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderCssDependencies(IEnumerable cssDependencies, HttpContextBase http, IDictionary htmlAttributes)
+ {
+ if (!cssDependencies.Any())
+ return string.Empty;
+
+ var sb = new StringBuilder();
+
+ if (http.IsDebuggingEnabled || !EnableCompositeFiles)
+ {
+ foreach (var dependency in cssDependencies)
+ {
+ sb.Append(RenderSingleCssFile(dependency.FilePath, htmlAttributes));
+ }
+ }
+ else
+ {
+ var comp = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(cssDependencies, ClientDependencyType.Css, http);
+ foreach (var s in comp)
+ {
+ sb.Append(RenderSingleCssFile(s, htmlAttributes));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ protected override string RenderSingleJsFile(string js, IDictionary htmlAttributes)
+ {
+ return string.Format(HtmlEmbedContants.ScriptEmbedWithSource, js, htmlAttributes.ToHtmlAttributes());
+ }
+
+ protected override string RenderSingleCssFile(string css, IDictionary htmlAttributes)
+ {
+ return string.Format(HtmlEmbedContants.CssEmbedWithSource, css, htmlAttributes.ToHtmlAttributes());
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/WebFormsFileRegistrationProvider.cs b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/WebFormsFileRegistrationProvider.cs
new file mode 100644
index 00000000000..a7b2a6820f7
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/FileRegistration/Providers/WebFormsFileRegistrationProvider.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web.UI;
+using System.Configuration.Provider;
+using System.Web;
+using System.Linq;
+using ClientDependency.Core.Controls;
+using ClientDependency.Core.Config;
+
+namespace ClientDependency.Core.FileRegistration.Providers
+{
+ public abstract class WebFormsFileRegistrationProvider : BaseFileRegistrationProvider
+ {
+ ///
+ /// Called to register the js and css into the page/control/output.
+ ///
+ ///
+ ///
+ ///
+ protected abstract void RegisterDependencies(HttpContextBase http, string js, string css);
+
+ ///
+ /// Called to register the dependencies into the page/control/output
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RegisterDependencies(
+ Control dependantControl,
+ List allDependencies,
+ HashSet paths,
+ HttpContextBase http)
+ {
+ var ctl = dependantControl;
+
+ var folderPaths = paths;
+
+ UpdateFilePaths(allDependencies, folderPaths, http);
+ EnsureNoDuplicates(allDependencies, folderPaths);
+
+ var cssBuilder = new StringBuilder();
+ var jsBuilder = new StringBuilder();
+
+ // find the groups
+ var groups = allDependencies
+ .Select(x => x.Group)
+ .Distinct()
+ .ToList();
+
+ // sort them
+ groups.Sort((a, b) => a.CompareTo(b));
+
+ foreach (var group in groups)
+ {
+ var g = group;
+ // get the js and css dependencies for this group
+ var jsDependencies = allDependencies
+ .Where(x => x.Group == g && x.DependencyType == ClientDependencyType.Javascript)
+ .ToList();
+
+ var cssDependencies = allDependencies
+ .Where(x => x.Group == g && x.DependencyType == ClientDependencyType.Css)
+ .ToList();
+
+ // sort according to priority
+ jsDependencies.Sort((a, b) => a.Priority.CompareTo(b.Priority));
+ cssDependencies.Sort((a, b) => a.Priority.CompareTo(b.Priority));
+
+ //render
+ WriteStaggeredDependencies(cssDependencies, http, cssBuilder, RenderCssDependencies, RenderSingleCssFile);
+ WriteStaggeredDependencies(jsDependencies, http, jsBuilder, RenderJsDependencies, RenderSingleJsFile);
+ }
+
+ var cssOutput = cssBuilder.ToString();
+ var jsOutput = jsBuilder.ToString();
+ RegisterDependencies(http, jsOutput, cssOutput);
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/HtmlAttributesStringParser.cs b/DNN Platform/Components/ClientDependency/Source/HtmlAttributesStringParser.cs
new file mode 100644
index 00000000000..11478924eea
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/HtmlAttributesStringParser.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web.Query.Dynamic;
+
+namespace ClientDependency.Core
+{
+ internal static class HtmlAttributesStringParser
+ {
+
+ internal static void ParseIntoDictionary(string attributes, IDictionary destination)
+ {
+ if (string.IsNullOrEmpty(attributes))
+ return;
+ if (destination == null)
+ return;
+
+ foreach (var parts in attributes.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(i => i.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries)))
+ {
+ if (parts.Length != 2)
+ {
+ throw new ParseException("Could not parse html string attributes, the format must be key1:value1,key2:value2", parts.Length);
+ }
+
+ if (!destination.ContainsKey(parts[0]))
+ destination.Add(parts[0], parts[1]);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/HttpContextBaseExtensions.cs b/DNN Platform/Components/ClientDependency/Source/HttpContextBaseExtensions.cs
new file mode 100644
index 00000000000..9517d780611
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/HttpContextBaseExtensions.cs
@@ -0,0 +1,164 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+
+namespace ClientDependency.Core
+{
+
+ ///
+ /// Extension methods for the HttpContext object
+ ///
+ public static class HttpContextBaseExtensions
+ {
+
+ public static void AddCompressionResponseHeader(this HttpContextBase context, CompressionType cType)
+ {
+ if (cType == CompressionType.deflate)
+ {
+ context.Response.AddHeader("Content-encoding", "deflate");
+ }
+ else if (cType == CompressionType.gzip)
+ {
+ context.Response.AddHeader("Content-encoding", "gzip");
+ }
+ }
+
+ ///
+ /// Check what kind of compression to use. Need to select the first available compression
+ /// from the header value as this is how .Net performs caching by compression so we need to follow
+ /// this process.
+ /// If IE 6 is detected, we will ignore compression as it's known that some versions of IE 6
+ /// have issues with it.
+ ///
+ public static CompressionType GetClientCompression(this HttpContextBase context)
+ {
+ CompressionType type = CompressionType.none;
+
+ if (context.Request.UserAgent.Contains("MSIE 6"))
+ {
+ return type;
+ }
+
+ string acceptEncoding = context.Request.Headers["Accept-Encoding"];
+
+ if (!string.IsNullOrEmpty(acceptEncoding))
+ {
+ string[] supported = acceptEncoding.Split(',');
+ //get the first type that we support
+ for (var i = 0; i < supported.Length; i++)
+ {
+ if (supported[i].Contains("deflate"))
+ {
+ type = CompressionType.deflate;
+ break;
+ }
+ else if (supported[i].Contains("gzip")) //sometimes it could be x-gzip!
+ {
+ type = CompressionType.gzip;
+ break;
+ }
+ }
+ }
+
+ return type;
+ }
+
+
+ ///
+ /// Checks for absolute path to root of the website.
+ ///
+ ///
+ /// This was taken from the mono source so should be accurate.
+ /// The reason we're not using the VirtualPathUtility one is because it has bugs in 3.5 whereas
+ /// if the path has query strings, it throws exceptions.
+ ///
+ ///
+ ///
+ ///
+ public static bool IsAbsolute(this HttpContextBase context, string virtualPath)
+ {
+ if (IsAbsolutePath(context, virtualPath))
+ {
+ throw new InvalidOperationException("IsAbsolute method will check if a Virtual path is absolute, it is not supported for full URLs");
+ }
+
+ if (string.IsNullOrEmpty(virtualPath))
+ throw new ArgumentNullException("virtualPath");
+
+ return (virtualPath[0] == '/' || virtualPath[0] == '\\');
+ }
+
+ ///
+ /// Returns a site relative HTTP path from a partial path starting out with a ~.
+ /// Same syntax that ASP.Net internally supports but this method can be used
+ /// outside of the Page framework.
+ ///
+ /// Works like Control.ResolveUrl including support for ~ syntax
+ /// but returns an absolute URL.
+ ///
+ ///
+ /// Any Url including those starting with ~
+ /// relative url
+ public static string ResolveUrl(this HttpContextBase context, string originalUrl)
+ {
+ if (string.IsNullOrEmpty(originalUrl))
+ return originalUrl;
+
+ // *** Absolute path - just return
+ if (context.IsAbsolutePath(originalUrl))
+ return originalUrl;
+
+ // *** We don't start with the '~' -> we don't process the Url
+ if (!originalUrl.StartsWith("~/"))
+ return originalUrl;
+
+ // *** Fix up path for ~ root app dir directory
+ // VirtualPathUtility blows up if there is a
+ // query string, so we have to account for this.
+ int queryStringStartIndex = originalUrl.IndexOf('?');
+ if (queryStringStartIndex != -1)
+ {
+ string queryString = originalUrl.Substring(queryStringStartIndex);
+ string baseUrl = originalUrl.Substring(0, queryStringStartIndex);
+
+ return string.Concat(
+ VirtualPathUtility.ToAbsolute(baseUrl, context.Request.ApplicationPath),
+ queryString);
+ }
+ else
+ {
+ return VirtualPathUtility.ToAbsolute(originalUrl, context.Request.ApplicationPath);
+ }
+
+ }
+
+ ///
+ /// Checks for an absolute http path
+ ///
+ ///
+ /// Takes into account this type of url:
+ /// ~/pathtoresolve/page.aspx?returnurl=http://servertoredirect/resource.aspx
+ /// which is not an absolute path but contains the characters to describe it as one.
+ ///
+ ///
+ ///
+ ///
+ public static bool IsAbsolutePath(this HttpContextBase context, string originalUrl)
+ {
+ // *** Absolute path - just return
+ var indexOfSlashes = originalUrl.IndexOf("://");
+ var indexOfQuestionMarks = originalUrl.IndexOf("?");
+
+ if (indexOfSlashes > -1 &&
+ (indexOfQuestionMarks < 0 ||
+ (indexOfQuestionMarks > -1 && indexOfQuestionMarks > indexOfSlashes)
+ )
+ )
+ return true;
+
+ return false;
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/IClientDependencyFile.cs b/DNN Platform/Components/ClientDependency/Source/IClientDependencyFile.cs
new file mode 100644
index 00000000000..c2b93372985
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IClientDependencyFile.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ClientDependency.Core
+{
+ public interface IClientDependencyFile
+ {
+ string FilePath { get; set; }
+ ClientDependencyType DependencyType { get; }
+ int Priority { get; set; }
+ int Group { get; set; }
+ string PathNameAlias { get; set; }
+ string ForceProvider { get; set; }
+ bool ForceBundle { get; set; }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/IClientDependencyFileExtensions.cs b/DNN Platform/Components/ClientDependency/Source/IClientDependencyFileExtensions.cs
new file mode 100644
index 00000000000..ed137752b9e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IClientDependencyFileExtensions.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+
+namespace ClientDependency.Core
+{
+ public static class ClientDependencyFileExtensions
+ {
+ ///
+ /// Resolves an absolute web path for the file path
+ ///
+ ///
+ ///
+ ///
+ public static string ResolveFilePath(this IClientDependencyFile file, HttpContextBase http)
+ {
+ var trimmedPath = file.FilePath.Trim();
+ if (string.IsNullOrEmpty(trimmedPath))
+ {
+ throw new ArgumentException("The Path specified is null", "Path");
+ }
+ if (trimmedPath.StartsWith("~/"))
+ {
+ return http.ResolveUrl(file.FilePath);
+ }
+ if (trimmedPath.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)
+ || trimmedPath.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return file.FilePath;
+ }
+ if (!http.IsAbsolute(file.FilePath))
+ {
+ //get the relative path
+ var path = http.Request.AppRelativeCurrentExecutionFilePath.Substring(0, http.Request.AppRelativeCurrentExecutionFilePath.LastIndexOf('/') + 1);
+ return http.ResolveUrl(path + file.FilePath);
+ }
+ return file.FilePath;
+ }
+
+
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/IClientDependencyPath.cs b/DNN Platform/Components/ClientDependency/Source/IClientDependencyPath.cs
new file mode 100644
index 00000000000..15b2fccb60d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IClientDependencyPath.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClientDependency.Core
+{
+ public interface IClientDependencyPath
+ {
+
+ string Name { get; set; }
+ string Path { get; set; }
+ bool ForceBundle { get; set; }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/IClientDependencyPathExtensions.cs b/DNN Platform/Components/ClientDependency/Source/IClientDependencyPathExtensions.cs
new file mode 100644
index 00000000000..7682b91f3ab
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IClientDependencyPathExtensions.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+
+namespace ClientDependency.Core
+{
+ public static class ClientDependencyPathExtensions
+ {
+
+ public static string ResolvePath(this IClientDependencyPath path, HttpContextBase http)
+ {
+ if (string.IsNullOrEmpty(path.Path))
+ {
+ throw new ArgumentException("The Path specified is null", "Path");
+ }
+ if (path.Path.StartsWith("~/"))
+ {
+ return http.ResolveUrl(path.Path);
+ }
+ return path.Path;
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/IHaveHtmlAttributes.cs b/DNN Platform/Components/ClientDependency/Source/IHaveHtmlAttributes.cs
new file mode 100644
index 00000000000..a3fcb3bd76f
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IHaveHtmlAttributes.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+
+namespace ClientDependency.Core
+{
+ ///
+ /// interface defining that an object has Html attributes
+ ///
+ public interface IHaveHtmlAttributes
+ {
+
+ ///
+ /// Used to store additional attributes in the HTML markup for the item
+ ///
+ ///
+ /// Mostly used for CSS Media, but could be for anything
+ ///
+ IDictionary HtmlAttributes { get; }
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/IHttpProvider.cs b/DNN Platform/Components/ClientDependency/Source/IHttpProvider.cs
new file mode 100644
index 00000000000..d45d466970d
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IHttpProvider.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+
+namespace ClientDependency.Core
+{
+ ///
+ /// A provider that requires initialization under an Http context.
+ /// The Http initialization will happen after the standard provider initialization.
+ ///
+ public interface IHttpProvider
+ {
+
+ void Initialize(HttpContextBase http);
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/IRequiresHtmlAttributesParsing.cs b/DNN Platform/Components/ClientDependency/Source/IRequiresHtmlAttributesParsing.cs
new file mode 100644
index 00000000000..9184f681c8e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/IRequiresHtmlAttributesParsing.cs
@@ -0,0 +1,16 @@
+namespace ClientDependency.Core
+{
+ ///
+ /// interface defining that an IClientDependencyFile has html attributes applied as a string which require parsing
+ ///
+ public interface IRequiresHtmlAttributesParsing : IHaveHtmlAttributes
+ {
+ ///
+ /// Used to set the HtmlAttributes on this class via a string which is parsed
+ ///
+ ///
+ /// The syntax for the string must be: key1:value1,key2:value2 etc...
+ ///
+ string HtmlAttributesAsString { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/Logging/ILogger.cs b/DNN Platform/Components/ClientDependency/Source/Logging/ILogger.cs
new file mode 100644
index 00000000000..05b1189df68
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Logging/ILogger.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Configuration.Provider;
+
+namespace ClientDependency.Core.Logging
+{
+ public interface ILogger
+ {
+ void Debug(string msg);
+ void Info(string msg);
+ void Warn(string msg);
+ void Error(string msg, Exception ex);
+ void Fatal(string msg, Exception ex);
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Logging/NullLogger.cs b/DNN Platform/Components/ClientDependency/Source/Logging/NullLogger.cs
new file mode 100644
index 00000000000..ffccca56b1b
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Logging/NullLogger.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClientDependency.Core.Logging
+{
+ internal class NullLogger : ILogger
+ {
+ #region ILogger Members
+
+ public void Debug(string msg)
+ {
+ }
+
+ public void Info(string msg)
+ {
+ }
+
+ public void Warn(string msg)
+ {
+ }
+
+ public void Error(string msg, Exception ex)
+ {
+ }
+
+ public void Fatal(string msg, Exception ex)
+ {
+ }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Module/ClientDependencyModule.cs b/DNN Platform/Components/ClientDependency/Source/Module/ClientDependencyModule.cs
new file mode 100644
index 00000000000..0b07370c917
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Module/ClientDependencyModule.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Web;
+using System.Web.Compilation;
+using ClientDependency.Core.Config;
+
+namespace ClientDependency.Core.Module
+{
+
+ ///
+ /// This module currently replaces rogue scripts with composite scripts.
+ /// Eventually it will handle css files and MVC implementation
+ ///
+ public class ClientDependencyModule : IHttpModule
+ {
+ #region IHttpModule Members
+
+ void IHttpModule.Dispose() { }
+
+ ///
+ /// Binds the events
+ ///
+ ///
+ void IHttpModule.Init(HttpApplication app)
+ {
+ //This event is late enough that the ContentType of the request is set
+ //but not too late that we've lost the ability to change the response
+ //app.BeginRequest += new EventHandler(HandleRequest);
+ app.PostRequestHandlerExecute += HandleRequest;
+ LoadFilterTypes();
+ }
+
+ ///
+ /// Checks if any assigned filters validate the current handler, if so then assigns any filter
+ /// that CanExecute to the response filter chain.
+ ///
+ /// Checks if the request MIME type matches the list of mime types specified in the config,
+ /// if it does, then it compresses it.
+ ///
+ ///
+ ///
+ void HandleRequest(object sender, EventArgs e)
+ {
+ var app = (HttpApplication)sender;
+ var http = new HttpContextWrapper(app.Context);
+
+ var filters = LoadFilters(http);
+
+ if (ValidateCurrentHandler(filters))
+ {
+ ExecuteFilter(http, filters);
+ }
+
+ //if debug is on, then don't compress
+ if (!http.IsDebuggingEnabled)
+ {
+ var c = new MimeTypeCompressor(new HttpContextWrapper(app.Context));
+ c.AddCompression();
+ }
+ }
+
+ #endregion
+
+ private List m_FilterTypes = new List();
+
+ #region Private Methods
+
+ private void LoadFilterTypes()
+ {
+ foreach (var f in ClientDependencySettings.Instance.ConfigSection.Filters.Cast())
+ {
+ var t = BuildManager.GetType(f.Type, false, true);
+ if (t != null)
+ {
+ m_FilterTypes.Add(t);
+ }
+ }
+ }
+
+ ///
+ /// loads instances of all registered filters.
+ ///
+ ///
+ private IEnumerable LoadFilters(HttpContextBase http)
+ {
+ var loadedFilters = new List();
+
+ foreach (var t in m_FilterTypes)
+ {
+ var filter = (IFilter)Activator.CreateInstance(t);
+ filter.SetHttpContext(http);
+ loadedFilters.Add(filter);
+
+ }
+
+ return loadedFilters;
+ }
+
+ ///
+ /// Ensure the current running handler is valid in order to proceed with the module filter.
+ ///
+ ///
+ ///
+ private static bool ValidateCurrentHandler(IEnumerable filters)
+ {
+ return filters.Any(f => f.ValidateCurrentHandler());
+ }
+
+ private void ExecuteFilter(HttpContextBase http, IEnumerable filters)
+ {
+ var filter = new ResponseFilterStream(http.Response.Filter, http);
+ foreach (var f in filters.Where(f => f.CanExecute()))
+ {
+ filter.TransformString += f.UpdateOutputHtml;
+ }
+ http.Response.Filter = filter;
+ }
+
+ #endregion
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Module/IFilter.cs b/DNN Platform/Components/ClientDependency/Source/Module/IFilter.cs
new file mode 100644
index 00000000000..931cccacdd9
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Module/IFilter.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+
+namespace ClientDependency.Core.Module
+{
+ public interface IFilter
+ {
+ void SetHttpContext(HttpContextBase ctx);
+ string UpdateOutputHtml(string html);
+ HttpContextBase CurrentContext { get; }
+ bool CanExecute();
+ bool ValidateCurrentHandler();
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Module/MimeTypeCompressor.cs b/DNN Platform/Components/ClientDependency/Source/Module/MimeTypeCompressor.cs
new file mode 100644
index 00000000000..251c9c08037
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Module/MimeTypeCompressor.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClientDependency.Core.Config;
+using System.Web;
+using System.IO.Compression;
+using System.Text.RegularExpressions;
+
+namespace ClientDependency.Core.Module
+{
+ public class MimeTypeCompressor
+ {
+ public MimeTypeCompressor(HttpContextBase ctx)
+ {
+ Context = ctx;
+ MatchedTypes = ClientDependencySettings.Instance
+ .ConfigSection
+ .CompositeFileElement
+ .MimeTypeCompression
+ .Cast()
+ .Where(x => Context.Request.ContentType.ToUpper().Split(';').Contains(x.MimeType.ToUpper()));
+ }
+
+ protected HttpContextBase Context;
+ protected IEnumerable MatchedTypes;
+
+ public void AddCompression()
+ {
+ HttpRequestBase request = Context.Request;
+ HttpResponseBase response = Context.Response;
+
+ //if debug is on, then don't compress
+ if (!Context.IsDebuggingEnabled)
+ {
+ //check if this request should be compressed based on the mime type and path
+ var m = GetSupportedPath();
+ if (IsSupportedMimeType() && m != null)
+ {
+ var cType = Context.GetClientCompression();
+ Context.AddCompressionResponseHeader(cType);
+
+
+
+ if (cType == CompressionType.deflate)
+ {
+ response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
+ }
+ else if (cType == CompressionType.gzip)
+ {
+ response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
+ }
+
+
+
+ }
+ }
+ }
+
+ protected MimeTypeCompressionElement GetSupportedPath()
+ {
+ //we're not supporting the ASP.Net AJAX calls for compression
+ var uRawUrl = Context.Request.RawUrl.ToUpper();
+ if (uRawUrl.Contains("WEBRESOURCE.AXD") || uRawUrl.Contains("SCRIPTRESOURCE.AXD"))
+ return null;
+
+ foreach (var m in MatchedTypes)
+ {
+ //if it is only "*" then convert it to proper regex
+ var reg = m.FilePath == "*" ? ".*" : m.FilePath;
+ var matched = Regex.IsMatch(Context.Request.RawUrl, reg, RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ if (matched) return m;
+ }
+ return null;
+ }
+
+ protected bool IsSupportedMimeType()
+ {
+ return MatchedTypes.Count() > 0;
+
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Module/ResponseFilterStream.cs b/DNN Platform/Components/ClientDependency/Source/Module/ResponseFilterStream.cs
new file mode 100644
index 00000000000..26afe7dc62f
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Module/ResponseFilterStream.cs
@@ -0,0 +1,385 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.IO;
+using System.Web.UI;
+using System.Text.RegularExpressions;
+using ClientDependency.Core.Controls;
+using ClientDependency.Core.FileRegistration.Providers;
+using ClientDependency.Core.Config;
+using ClientDependency.Core;
+using System.Net;
+
+
+namespace ClientDependency.Core.Module
+{
+ ///
+ /// A semi-generic Stream implementation for Response.Filter with
+ /// an event interface for handling Content transformations via
+ /// Stream or String.
+ ///
+ /// Use with care for large output as this implementation copies
+ /// the output into a memory stream and so increases memory usage.
+ ///
+ ///
+ public class
+ ResponseFilterStream : Stream
+ {
+ ///
+ /// The original stream
+ ///
+ readonly Stream _stream;
+
+ private readonly HttpContextBase _http;
+
+ ///
+ /// Current position in the original stream
+ ///
+ long _position;
+
+ ///
+ /// Stream that original content is read into
+ /// and then passed to TransformStream function
+ ///
+ MemoryStream _cacheStream = new MemoryStream(5000);
+
+ ///
+ /// Internal pointer that that keeps track of the size
+ /// of the cacheStream
+ ///
+ int _cachePointer = 0;
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ResponseFilterStream(Stream responseStream, HttpContextBase http)
+ {
+ _stream = responseStream;
+ _http = http;
+ }
+
+
+ ///
+ /// Determines whether the stream is captured
+ ///
+ private bool IsCaptured
+ {
+ get
+ {
+
+ if (CaptureStream != null || CaptureString != null ||
+ TransformStream != null || TransformString != null)
+ return true;
+
+ return false;
+ }
+ }
+
+ ///
+ /// Determines whether the Write method is outputting data immediately
+ /// or delaying output until Flush() is fired.
+ ///
+ private bool IsOutputDelayed
+ {
+ get
+ {
+ if (TransformStream != null || TransformString != null)
+ return true;
+
+ return false;
+ }
+ }
+
+
+ ///
+ /// Event that captures Response output and makes it available
+ /// as a MemoryStream instance. Output is captured but won't
+ /// affect Response output.
+ ///
+ public event Action CaptureStream;
+
+ ///
+ /// Event that captures Response output and makes it available
+ /// as a string. Output is captured but won't affect Response output.
+ ///
+ public event Action CaptureString;
+
+
+
+ ///
+ /// Event that allows you transform the stream as each chunk of
+ /// the output is written in the Write() operation of the stream.
+ /// This means that that it's possible/likely that the input
+ /// buffer will not contain the full response output but only
+ /// one of potentially many chunks.
+ ///
+ /// This event is called as part of the filter stream's Write()
+ /// operation.
+ ///
+ public event Func TransformWrite;
+
+
+ ///
+ /// Event that allows you to transform the response stream as
+ /// each chunk of bytep[] output is written during the stream's write
+ /// operation. This means it's possibly/likely that the string
+ /// passed to the handler only contains a portion of the full
+ /// output. Typical buffer chunks are around 16k a piece.
+ ///
+ /// This event is called as part of the stream's Write operation.
+ ///
+ public event Func TransformWriteString;
+
+ ///
+ /// This event allows capturing and transformation of the entire
+ /// output stream by caching all write operations and delaying final
+ /// response output until Flush() is called on the stream.
+ ///
+ public event Func TransformStream;
+
+ ///
+ /// Event that can be hooked up to handle Response.Filter
+ /// Transformation. Passed a string that you can modify and
+ /// return back as a return value. The modified content
+ /// will become the final output.
+ ///
+ public event Func TransformString;
+
+
+ protected virtual void OnCaptureStream(MemoryStream ms)
+ {
+ if (CaptureStream != null)
+ CaptureStream(ms);
+ }
+
+
+ private void OnCaptureStringInternal(MemoryStream ms)
+ {
+ if (CaptureString != null)
+ {
+ string content = _http.Response.ContentEncoding.GetString(ms.ToArray());
+ OnCaptureString(content);
+ }
+ }
+
+ protected virtual void OnCaptureString(string output)
+ {
+ if (CaptureString != null)
+ CaptureString(output);
+ }
+
+ protected virtual byte[] OnTransformWrite(byte[] buffer)
+ {
+ if (TransformWrite != null)
+ return TransformWrite(buffer);
+ return buffer;
+ }
+
+ private byte[] OnTransformWriteStringInternal(byte[] buffer)
+ {
+ Encoding encoding = _http.Response.ContentEncoding;
+ string output = OnTransformWriteString(encoding.GetString(buffer));
+ return encoding.GetBytes(output);
+ }
+
+ private string OnTransformWriteString(string value)
+ {
+ if (TransformWriteString != null)
+ return TransformWriteString(value);
+ return value;
+ }
+
+
+ protected virtual MemoryStream OnTransformCompleteStream(MemoryStream ms)
+ {
+ if (TransformStream != null)
+ return TransformStream(ms);
+
+ return ms;
+ }
+
+
+
+
+ ///
+ /// Allows transforming of strings
+ ///
+ /// Note this handler is internal and not meant to be overridden
+ /// as the TransformString Event has to be hooked up in order
+ /// for this handler to even fire to avoid the overhead of string
+ /// conversion on every pass through.
+ ///
+ ///
+ ///
+ private string OnTransformCompleteString(string responseText)
+ {
+ if (TransformString != null)
+ TransformString(responseText);
+
+ return responseText;
+ }
+
+ ///
+ /// Wrapper method form OnTransformString that handles
+ /// stream to string and vice versa conversions
+ ///
+ ///
+ ///
+ internal MemoryStream OnTransformCompleteStringInternal(MemoryStream ms)
+ {
+ if (TransformString == null)
+ return ms;
+
+ //string content = ms.GetAsString();
+ string content = _http.Response.ContentEncoding.GetString(ms.ToArray());
+
+ content = TransformString(content);
+ byte[] buffer = _http.Response.ContentEncoding.GetBytes(content);
+ ms = new MemoryStream();
+ ms.Write(buffer, 0, buffer.Length);
+ //ms.WriteString(content);
+
+ return ms;
+ }
+
+ ///
+ ///
+ ///
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return true; }
+ }
+ ///
+ ///
+ ///
+ public override bool CanWrite
+ {
+ get { return true; }
+ }
+
+ ///
+ ///
+ ///
+ public override long Length
+ {
+ get { return 0; }
+ }
+
+ ///
+ ///
+ ///
+ public override long Position
+ {
+ get { return _position; }
+ set { _position = value; }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override long Seek(long offset, System.IO.SeekOrigin direction)
+ {
+ return _stream.Seek(offset, direction);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public override void SetLength(long length)
+ {
+ _stream.SetLength(length);
+ }
+
+ ///
+ ///
+ ///
+ public override void Close()
+ {
+ _stream.Close();
+ }
+
+ ///
+ /// Override flush by writing out the cached stream data
+ ///
+ public override void Flush()
+ {
+
+ if (IsCaptured && _cacheStream.Length > 0)
+ {
+ // Check for transform implementations
+ _cacheStream = OnTransformCompleteStream(_cacheStream);
+ _cacheStream = OnTransformCompleteStringInternal(_cacheStream);
+
+ OnCaptureStream(_cacheStream);
+ OnCaptureStringInternal(_cacheStream);
+
+ // write the stream back out if output was delayed
+ if (IsOutputDelayed)
+ _stream.Write(_cacheStream.ToArray(), 0, (int)_cacheStream.Length);
+
+ // Clear the cache once we've written it out
+ _cacheStream.SetLength(0);
+ }
+
+ // default flush behavior
+ _stream.Flush();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return _stream.Read(buffer, offset, count);
+ }
+
+
+ ///
+ /// Overriden to capture output written by ASP.NET and captured
+ /// into a cached stream that is written out later when Flush()
+ /// is called.
+ ///
+ ///
+ ///
+ ///
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (IsCaptured)
+ {
+ // copy to holding buffer only - we'll write out later
+ _cacheStream.Write(buffer, 0, count);
+ _cachePointer += count;
+ }
+
+ // just transform this buffer
+ if (TransformWrite != null)
+ buffer = OnTransformWrite(buffer);
+ if (TransformWriteString != null)
+ buffer = OnTransformWriteStringInternal(buffer);
+
+ if (!IsOutputDelayed)
+ _stream.Write(buffer, offset, count);
+
+ }
+
+ }
+
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Module/RogueFileFilter.cs b/DNN Platform/Components/ClientDependency/Source/Module/RogueFileFilter.cs
new file mode 100644
index 00000000000..cf28d566e44
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Module/RogueFileFilter.cs
@@ -0,0 +1,211 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.IO;
+using System.Web.UI;
+using System.Text.RegularExpressions;
+using ClientDependency.Core.CompositeFiles.Providers;
+using ClientDependency.Core.Controls;
+using ClientDependency.Core.FileRegistration.Providers;
+using ClientDependency.Core.Config;
+using ClientDependency.Core;
+using System.Net;
+
+namespace ClientDependency.Core.Module
+{
+
+ ///
+ /// Used as an http response filter to modify the contents of the output html.
+ /// This filter is used to intercept js and css rogue registrations on the html page.
+ ///
+ public class RogueFileFilter : IFilter
+ {
+
+ #region Private members
+
+ private bool? m_Runnable = null;
+ private string m_MatchScript = "";
+ private string m_MatchLink = "]*(href\\s*=\\s*(['\"])(?.*?)\\2)";
+
+ private RogueFileCompressionElement m_FoundPath = null;
+
+ #endregion
+
+ #region IFilter Members
+
+ public void SetHttpContext(HttpContextBase ctx)
+ {
+ CurrentContext = ctx;
+ m_FoundPath = GetSupportedPath();
+ }
+
+ ///
+ /// This filter can only execute when it's a Page or MvcHandler
+ ///
+ ///
+ public virtual bool ValidateCurrentHandler()
+ {
+ //don't filter if we're in debug mode
+ if (CurrentContext.IsDebuggingEnabled || !ClientDependencySettings.Instance.DefaultFileRegistrationProvider.EnableCompositeFiles)
+ return false;
+
+ return (CurrentContext.CurrentHandler is Page);
+ }
+
+ ///
+ /// Returns true when this filter should be applied
+ ///
+ ///
+ public bool CanExecute()
+ {
+ if (!ValidateCurrentHandler())
+ {
+ return false;
+ }
+
+ if (!m_Runnable.HasValue)
+ {
+ m_Runnable = (m_FoundPath != null);
+ }
+ return m_Runnable.Value;
+
+ }
+
+ ///
+ /// Replaces any rogue script tag's with calls to the compression handler instead
+ /// of just the script.
+ ///
+ public string UpdateOutputHtml(string html)
+ {
+ html = ReplaceScripts(html);
+ html = ReplaceStyles(html);
+ return html;
+ }
+
+ public HttpContextBase CurrentContext { get; private set; }
+
+ #endregion
+
+ #region Private methods
+
+ private RogueFileCompressionElement GetSupportedPath()
+ {
+ var rogueFiles = ClientDependencySettings.Instance
+ .ConfigSection
+ .CompositeFileElement
+ .RogueFileCompression;
+
+ return (from m in rogueFiles.Cast()
+ let reg = m.FilePath == "*" ? ".*" : m.FilePath
+ let matched = Regex.IsMatch(CurrentContext.Request.RawUrl, reg, RegexOptions.Compiled | RegexOptions.IgnoreCase)
+ where matched
+ let isGood = m.ExcludePaths.Cast().Select(e => Regex.IsMatch(CurrentContext.Request.RawUrl, e.FilePath, RegexOptions.Compiled | RegexOptions.IgnoreCase)).All(excluded => !excluded)
+ where isGood
+ select m).FirstOrDefault();
+ }
+
+ ///
+ /// Replaces all src attribute values for a script tag with their corresponding
+ /// URLs as a composite script.
+ ///
+ ///
+ ///
+ private string ReplaceScripts(string html)
+ {
+ //check if we should be processing!
+ if (CanExecute() && m_FoundPath.CompressJs)
+ {
+ return ReplaceContent(html, "src", m_FoundPath.JsRequestExtension.Split(','), ClientDependencyType.Javascript, m_MatchScript, CurrentContext);
+ }
+ return html;
+ }
+
+ ///
+ /// Replaces all href attribute values for a link tag with their corresponding
+ /// URLs as a composite style.
+ ///
+ ///
+ ///
+ private string ReplaceStyles(string html)
+ {
+ //check if we should be processing!
+ if (CanExecute() && m_FoundPath.CompressCss)
+ {
+ return ReplaceContent(html, "href", m_FoundPath.CssRequestExtension.Split(','), ClientDependencyType.Css, m_MatchLink, CurrentContext);
+ }
+ return html;
+ }
+
+ ///
+ /// Replaces the content with the new js/css paths
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// For some reason ampersands that aren't html escaped are not compliant to HTML standards when they exist in 'link' or 'script' tags in URLs,
+ /// we need to replace the ampersands with & . This is only required for this one w3c compliancy, the URL itself is a valid URL.
+ ///
+ private static string ReplaceContent(string html, string namedGroup, string[] extensions,
+ ClientDependencyType type, string regex, HttpContextBase http)
+ {
+ html = Regex.Replace(html, regex,
+ (m) =>
+ {
+ var grp = m.Groups[namedGroup];
+
+ //if there is no namedGroup group name or it doesn't end with a js/css extension or it's already using the composite handler,
+ //the return the existing string.
+ if (grp == null
+ || string.IsNullOrEmpty(grp.ToString())
+ || !grp.ToString().EndsWithOneOf(extensions)
+ || grp.ToString().StartsWith(ClientDependencySettings.Instance.CompositeFileHandlerPath))
+ return m.ToString();
+
+
+ //make sure that it's an internal request, though we can deal with external
+ //requests, we'll leave that up to the developer to register an external request
+ //explicitly if they want to include in the composite scripts.
+ try
+ {
+ var url = new Uri(grp.ToString(), UriKind.RelativeOrAbsolute);
+ if (!url.IsLocalUri(http))
+ return m.ToString(); //not a local uri
+ else
+ {
+
+ var dependency = new BasicFile(type) { FilePath = grp.ToString() };
+
+ var file = new[] { new BasicFile(type) { FilePath = dependency.ResolveFilePath(http) } };
+
+ var resolved = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.ProcessCompositeList(
+ file,
+ type,
+ http).Single();
+
+ return m.ToString().Replace(grp.ToString(), resolved.Replace("&", "&"));
+ }
+ }
+ catch (UriFormatException)
+ {
+ //malformed url, let's exit
+ return m.ToString();
+ }
+
+ },
+ RegexOptions.Compiled);
+
+ return html;
+ }
+
+
+ #endregion
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/ObjectExtensions.cs b/DNN Platform/Components/ClientDependency/Source/ObjectExtensions.cs
new file mode 100644
index 00000000000..7c359addf9e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/ObjectExtensions.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace ClientDependency.Core
+{
+ public static class ObjectExtensions
+ {
+ public static IDictionary ToDictionary(this object o)
+ {
+ if (o != null)
+ {
+ var props = TypeDescriptor.GetProperties(o);
+ var d = new Dictionary();
+ foreach (var prop in props.Cast())
+ {
+ var val = prop.GetValue(o);
+ if (val != null)
+ {
+ d.Add(prop.Name, val);
+ }
+ }
+ return d;
+ }
+ return new Dictionary();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/Properties/AssemblyInfo.cs b/DNN Platform/Components/ClientDependency/Source/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..9026f91c94e
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Properties/AssemblyInfo.cs
@@ -0,0 +1,24 @@
+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("ClientDependency.Core")]
+[assembly: AssemblyDescription("Script file and Css file management for web sites")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyProduct("ClientDependency.Core")]
+
+// 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("acb95044-dd5c-4d0a-8523-a6352470c424")]
+
+//ADD RESOURCES
+[assembly: System.Web.UI.WebResource("ClientDependency.Core.Resources.LazyLoader.js", "text/javascript")]
+
+[assembly: InternalsVisibleTo("ClientDependency.UnitTests")]
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/ProviderDependencyList.cs b/DNN Platform/Components/ClientDependency/Source/ProviderDependencyList.cs
new file mode 100644
index 00000000000..146bb230b4a
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/ProviderDependencyList.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClientDependency.Core.FileRegistration.Providers;
+
+
+namespace ClientDependency.Core
+{
+ internal class ProviderDependencyList
+ {
+ internal ProviderDependencyList(BaseFileRegistrationProvider provider)
+ {
+ Provider = provider;
+ Dependencies = new List();
+ }
+
+ internal bool ProviderIs(BaseFileRegistrationProvider provider)
+ {
+ return Provider.Name == provider.Name;
+ }
+
+ internal void AddDependencies(IEnumerable list)
+ {
+ Dependencies.AddRange(list);
+ }
+
+ internal void AddDependency(IClientDependencyFile file)
+ {
+ Dependencies.Add(file);
+ }
+
+ internal List Dependencies { get; private set; }
+ internal BaseFileRegistrationProvider Provider { get; private set; }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/Resources/LazyLoader.js b/DNN Platform/Components/ClientDependency/Source/Resources/LazyLoader.js
new file mode 100644
index 00000000000..5f608bbd4d9
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/Resources/LazyLoader.js
@@ -0,0 +1,141 @@
+/*Special Thanks to Ruben Verborgh for his work on this and in the Umbraco core!*/
+
+if (typeof ClientDependency == 'undefined') var ClientDependency = {};
+if (!ClientDependency.Sys) ClientDependency.Sys = {};
+
+
+ClientDependency.Sys.LazyLoader = function() {
+ this.addedDependencies = [];
+ this.jsQueue = new Array();
+ this.jsQueueWaiting = false;
+}
+
+// ********************* Dependency Loader Methods *********************
+ClientDependency.Sys.LazyLoader.prototype.AddJs = function(filePath, callbackMethod) {
+ if (this.addedDependencies[filePath] == undefined) {
+ //Sys.Debug.trace("LazyLoader: Queueing '" + filePath + "'.");
+
+ // add script to queue
+ var script = new Array();
+ script.filePath = filePath;
+ script.callbackMethod = callbackMethod;
+ script.loaded = false;
+ this.jsQueue[this.jsQueue.length] = script;
+ this.addedDependencies[filePath] = true;
+
+ //Sys.Debug.trace("LazyLoader: Queued '" + filePath + "', queue length " + this.jsQueue.length + ".");
+
+ if (!this.jsQueueWaiting)
+ this.LoadNextJs();
+ }
+ else {
+ //Sys.Debug.trace("LazyLoader: Javascript file has already been added '" + filePath + "'.");
+ }
+
+ return this;
+}
+
+ClientDependency.Sys.LazyLoader.prototype.RegisterCallbackMethod = function(callbackMethod) {
+ ///
+ /// This registers a method to be called. The system will check if the method is available in the DOM
+ /// to be called, if it is not, it will wait until it is.
+ ///
+
+ if (callbackMethod == "") {
+ return this;
+ }
+ var script = { loaded: false, callbackMethod: callbackMethod };
+ ClientDependency.Sys.onScriptAvailable(script);
+
+ return this;
+}
+
+function logthis(txt) {
+
+}
+
+ClientDependency.Sys.LazyLoader.prototype.AddCss = function(filePath) {
+ if (this.addedDependencies[filePath] == undefined) {
+
+ var tempCss = document.createElement("link")
+ tempCss.setAttribute("href", filePath);
+ tempCss.setAttribute("rel", "stylesheet");
+ tempCss.setAttribute("type", "text/css");
+ document.getElementsByTagName("head")[0].appendChild(tempCss);
+
+ this.addedDependencies[filePath] = "loaded";
+
+ }
+ else {
+ //Sys.Debug.trace("LazyLoader: Css file has already been added: '" + filePath + "'.");
+ }
+ return this;
+}
+
+ClientDependency.Sys.LazyLoader.prototype.LoadNextJs = function() {
+ if (this.jsQueue.length > 0) {
+ this.jsQueueWaiting = true;
+
+ var script = this.jsQueue[0];
+ this.jsQueue.splice(0, 1);
+
+ //Sys.Debug.trace("LazyLoader: Loading '" + script.filePath + "'. (" + this.jsQueue.length + " scripts left)");
+ var tempJs = document.createElement('script');
+ tempJs.setAttribute("src", script.filePath);
+ tempJs.setAttribute("type", "text/javascript");
+
+ tempJs.onload = function() { ClientDependency.Sys.onScriptAvailable(script); };
+ tempJs.onreadystatechange = function() {
+ if (this.readyState == 'loaded' || this.readyState == 'complete') {
+ ClientDependency.Sys.onScriptAvailable(script);
+ }
+ };
+ document.getElementsByTagName("head")[0].appendChild(tempJs);
+ }
+ else {
+ //Sys.Debug.trace('LazyLoader: No scripts left.');
+ this.jsQueueWaiting = false;
+ }
+}
+
+// Initialize
+var CDLazyLoader = new ClientDependency.Sys.LazyLoader();
+
+ClientDependency.Sys.onScriptAvailable = function(script) {
+ ///
+ /// This method checks if the string representation of a method (sMethod) is registered as a function yet,
+ /// and if it is it'll call the function (oCallback), if not it'll try again after 50 ms.
+ ///
+ if (!script.loaded) {
+ //Sys.Debug.trace("LazyLoader: Loaded '" + script.filePath + "'.");
+ script.loaded = true;
+ }
+ if (script.callbackMethod == '') {
+ CDLazyLoader.LoadNextJs();
+ }
+ else {
+
+ try {
+ eval(script.callbackMethod);
+ }
+ catch (err) {
+ //the object definitely doesn't exist.
+ setTimeout(function() {
+ ClientDependency.Sys.onScriptAvailable(script);
+ }, 50);
+ return;
+ }
+
+ if (typeof (eval(script.callbackMethod)) == 'function') {
+ CDLazyLoader.LoadNextJs();
+ //Sys.Debug.trace("LazyLoader: Executing '" + script.filePath + "' callback '" + script.callbackMethod + "'.");
+ var func = eval(script.callbackMethod);
+ func.call(this);
+ }
+ else {
+ setTimeout(function() {
+ ClientDependency.Sys.onScriptAvailable(script);
+ }, 50);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Components/ClientDependency/Source/SimpleCompressor.cs b/DNN Platform/Components/ClientDependency/Source/SimpleCompressor.cs
new file mode 100644
index 00000000000..bfd9b440f54
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/SimpleCompressor.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.IO.Compression;
+
+namespace ClientDependency.Core
+{
+ public class SimpleCompressor
+ {
+ public static byte[] CompressBytes(CompressionType type, byte[] fileBytes)
+ {
+ MemoryStream ms = new MemoryStream();
+ Stream compressedStream = null;
+
+ if (type == CompressionType.deflate)
+ {
+ compressedStream = new DeflateStream(ms, CompressionMode.Compress, true);
+ }
+ else if (type == CompressionType.gzip)
+ {
+ compressedStream = new GZipStream(ms, CompressionMode.Compress, true);
+ }
+
+ if (type != CompressionType.none)
+ {
+ //write the bytes to the compressed stream
+ compressedStream.Write(fileBytes, 0, fileBytes.Length);
+ compressedStream.Close();
+ byte[] output = ms.ToArray();
+ ms.Close();
+ return output;
+ }
+
+ //not compressed
+ return fileBytes;
+ }
+
+ public static byte[] DecompressBytes(CompressionType type, byte[] compressedBytes)
+ {
+ MemoryStream ms = new MemoryStream();
+ Stream decompressedStream = null;
+
+ if (type == CompressionType.deflate)
+ {
+ decompressedStream = new DeflateStream(ms, CompressionMode.Decompress, true);
+ }
+ else if (type == CompressionType.gzip)
+ {
+ decompressedStream = new GZipStream(ms, CompressionMode.Decompress, true);
+ }
+
+ if (type != CompressionType.none)
+ {
+ //write the bytes to the compressed stream
+ decompressedStream.Write(compressedBytes, 0, compressedBytes.Length);
+ decompressedStream.Close();
+ byte[] output = ms.ToArray();
+ ms.Close();
+ return output;
+ }
+
+ //not compressed
+ return compressedBytes;
+ }
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/StringExtensions.cs b/DNN Platform/Components/ClientDependency/Source/StringExtensions.cs
new file mode 100644
index 00000000000..e01df0b4add
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/StringExtensions.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace ClientDependency.Core
+{
+ public static class StringExtensions
+ {
+
+ public static string EncodeTo64Url(this string toEncode)
+ {
+ string returnValue = EncodeTo64(toEncode);
+
+ // returnValue is base64 = may contain a-z, A-Z, 0-9, +, /, and =.
+ // the = at the end is just a filler, can remove
+ // then convert the + and / to "base64url" equivalent
+ //
+ returnValue = returnValue.TrimEnd(new char[] { '=' });
+ returnValue = returnValue.Replace("+", "-");
+ returnValue = returnValue.Replace("/", "_");
+
+ return returnValue;
+ }
+
+ public static string EncodeTo64(this string toEncode)
+ {
+ byte[] toEncodeAsBytes = Encoding.Default.GetBytes(toEncode);
+ string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
+ return returnValue;
+ }
+ public static string DecodeFrom64Url(this string toDecode)
+ {
+ // see BaseFileRegistrationProvider.EncodeTo64Url
+ //
+ toDecode = toDecode.Replace("-", "+");
+ toDecode = toDecode.Replace("_", "/");
+ int rem = toDecode.Length % 4; // 0 (aligned), 1, 2 or 3 (not aligned)
+ if (rem > 0)
+ toDecode = toDecode.PadRight(toDecode.Length + 4 - rem, '='); // align
+
+ return DecodeFrom64(toDecode);
+ }
+
+ public static string DecodeFrom64(this string toDecode)
+ {
+ byte[] toDecodeAsBytes = System.Convert.FromBase64String(toDecode);
+ return Encoding.Default.GetString(toDecodeAsBytes);
+ }
+
+ /// Generate a MD5 hash of a string
+ ///
+ public static string GenerateMd5(this string str)
+ {
+ var md5 = new MD5CryptoServiceProvider();
+ var byteArray = Encoding.ASCII.GetBytes(str);
+ byteArray = md5.ComputeHash(byteArray);
+ return byteArray.Aggregate("", (current, b) => current + b.ToString("x2"));
+ }
+
+ ///
+ /// checks if the string ends with one of the strings specified. This ignores case.
+ ///
+ ///
+ ///
+ ///
+ public static bool EndsWithOneOf(this string str, string[] ext)
+ {
+ var upper = str.ToUpper();
+ bool isExt = false;
+ foreach (var e in ext)
+ {
+ if (upper.EndsWith(e.ToUpper()))
+ {
+ isExt = true;
+ break;
+ }
+ }
+ return isExt;
+ }
+
+ }
+}
diff --git a/DNN Platform/Components/ClientDependency/Source/UriExtensions.cs b/DNN Platform/Components/ClientDependency/Source/UriExtensions.cs
new file mode 100644
index 00000000000..34a8361051f
--- /dev/null
+++ b/DNN Platform/Components/ClientDependency/Source/UriExtensions.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.Net;
+
+namespace ClientDependency.Core
+{
+ public static class UriExtensions
+ {
+ ///
+ /// Checks if the url is a local/relative uri, if it is, it makes it absolute based on the
+ /// current request uri.
+ ///
+ ///
+ ///
+ ///
+ public static Uri MakeAbsoluteUri(this Uri uri, HttpContextBase http)
+ {
+ if (!uri.IsAbsoluteUri)
+ {
+ if (http.Request.Url != null)
+ {
+ var left = http.Request.Url.GetLeftPart(UriPartial.Authority);
+ var absoluteUrl = new Uri(new Uri(left), uri);
+ return absoluteUrl;
+ }
+ }
+ return uri;
+ }
+
+ ///
+ /// Determines if the uri is a locally based file
+ ///
+ ///
+ ///
+ ///
+ public static bool IsLocalUri(this Uri uri, HttpContextBase http)
+ {
+ var isLocal = false;
+
+ try
+ {
+ if (!uri.IsAbsoluteUri)
+ {
+ uri = uri.MakeAbsoluteUri(http);
+ }
+
+ var host = Dns.GetHostAddresses(uri.Host);
+ var local = Dns.GetHostAddresses(Dns.GetHostName());
+ foreach (var hostAddress in host)
+ {
+ if (IPAddress.IsLoopback(hostAddress))
+ {
+ isLocal = true;
+ break;
+ }
+ if (local.Contains(hostAddress))
+ {
+ isLocal = true;
+ }
+
+ if (isLocal)
+ {
+ break;
+ }
+ }
+ }
+ catch (Exception)
+ {
+
+ //suppress error - triggered if user has no internet connection or environment permission
+ //we assume local files as we cannot support non local files without an internet connection
+ return true;
+ }
+
+ return isLocal;
+ }
+ }
+}
diff --git a/DNN Platform/Components/MVC4/System.Web.WebPages.Deployment.dll b/DNN Platform/Components/MVC4/System.Web.WebPages.Deployment.dll
new file mode 100644
index 00000000000..89e7d27450b
Binary files /dev/null and b/DNN Platform/Components/MVC4/System.Web.WebPages.Deployment.dll differ
diff --git a/DNN Platform/Components/MVC4/System.Web.WebPages.dll b/DNN Platform/Components/MVC4/System.Web.WebPages.dll
new file mode 100644
index 00000000000..60e9abab508
Binary files /dev/null and b/DNN Platform/Components/MVC4/System.Web.WebPages.dll differ
diff --git a/DNN Platform/Components/SharpZipLib/Readme.rtf b/DNN Platform/Components/SharpZipLib/Readme.rtf
new file mode 100644
index 00000000000..30552306f21
Binary files /dev/null and b/DNN Platform/Components/SharpZipLib/Readme.rtf differ
diff --git a/DNN Platform/Components/SharpZipLib/Readme.txt b/DNN Platform/Components/SharpZipLib/Readme.txt
new file mode 100644
index 00000000000..1c685e410ae
--- /dev/null
+++ b/DNN Platform/Components/SharpZipLib/Readme.txt
@@ -0,0 +1,10 @@
+Please note:
+
+In order for this component to be used in a Medium Trust environment, the DLL has been recompiled without the strong naming attribute from AssemblyInfo.cs:
+
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("../ICSharpCode.SharpZipLib.key")]
+
+In addition, the dependency on NUnit.Framework.dll was also removed.
+
+This was done with written notification and permission from Christoph Wille of AlphaSierraPapa ( christophw@alphasierrapapa.com ) on September 23, 2004
\ No newline at end of file
diff --git a/DNN Platform/Components/Telerik/DotNetNuke.Telerik.Web.dnn b/DNN Platform/Components/Telerik/DotNetNuke.Telerik.Web.dnn
new file mode 100644
index 00000000000..f6d35588f90
--- /dev/null
+++ b/DNN Platform/Components/Telerik/DotNetNuke.Telerik.Web.dnn
@@ -0,0 +1,80 @@
+
+
+
+ DotNetNuke Telerik Web Components
+ Provides Telerik Components for DotNetNuke.
+
+
+ DNNCorp
+ DotNetNuke Corporation
+ www.dotnetnuke.com
+ support@dotnetnuke.com
+
+ Please refer to the Telerik EULA.pdf in your site's documentation folder.
+
+ This package includes Telerik.Web.UI assembly version 2013.2.717.40.
+ Please go to www.telerik.com to view release notes on this particular version.
+
+
+
+
+ bin
+ Telerik.Web.UI.dll
+ 2013.2.717.40
+
+
+ bin
+ Telerik.Web.UI.Skins.dll
+ 2013.2.717.40
+
+
+
+
+
+
+ Documentation
+ Telerik_EULA.pdf
+
+
+
+
+
+ web.config
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DNN Platform/Components/WebAPI/Microsoft.Web.Infrastructure.dll b/DNN Platform/Components/WebAPI/Microsoft.Web.Infrastructure.dll
new file mode 100644
index 00000000000..85f1138c57b
Binary files /dev/null and b/DNN Platform/Components/WebAPI/Microsoft.Web.Infrastructure.dll differ
diff --git a/DNN Platform/Components/WebAPI/Newtonsoft.Json.dll b/DNN Platform/Components/WebAPI/Newtonsoft.Json.dll
new file mode 100644
index 00000000000..7fe9514d7c0
Binary files /dev/null and b/DNN Platform/Components/WebAPI/Newtonsoft.Json.dll differ
diff --git a/DNN Platform/Components/WebAPI/System.Net.Http.Formatting.dll b/DNN Platform/Components/WebAPI/System.Net.Http.Formatting.dll
new file mode 100644
index 00000000000..367d253b9d4
Binary files /dev/null and b/DNN Platform/Components/WebAPI/System.Net.Http.Formatting.dll differ
diff --git a/DNN Platform/Components/WebAPI/System.Net.Http.WebRequest.dll b/DNN Platform/Components/WebAPI/System.Net.Http.WebRequest.dll
new file mode 100644
index 00000000000..b26b59a5412
Binary files /dev/null and b/DNN Platform/Components/WebAPI/System.Net.Http.WebRequest.dll differ
diff --git a/DNN Platform/Components/WebAPI/System.Net.Http.dll b/DNN Platform/Components/WebAPI/System.Net.Http.dll
new file mode 100644
index 00000000000..2ee8ff7a577
Binary files /dev/null and b/DNN Platform/Components/WebAPI/System.Net.Http.dll differ
diff --git a/DNN Platform/Components/WebAPI/System.Web.Http.WebHost.dll b/DNN Platform/Components/WebAPI/System.Web.Http.WebHost.dll
new file mode 100644
index 00000000000..1dfa8d28fe7
Binary files /dev/null and b/DNN Platform/Components/WebAPI/System.Web.Http.WebHost.dll differ
diff --git a/DNN Platform/Components/WebAPI/System.Web.Http.dll b/DNN Platform/Components/WebAPI/System.Web.Http.dll
new file mode 100644
index 00000000000..206c331767b
Binary files /dev/null and b/DNN Platform/Components/WebAPI/System.Web.Http.dll differ
diff --git a/DNN Platform/Components/WebPages/Microsoft.Web.Helpers.dll b/DNN Platform/Components/WebPages/Microsoft.Web.Helpers.dll
new file mode 100644
index 00000000000..2d852ee9705
Binary files /dev/null and b/DNN Platform/Components/WebPages/Microsoft.Web.Helpers.dll differ
diff --git a/DNN Platform/Components/WebPages/System.Web.Helpers.dll b/DNN Platform/Components/WebPages/System.Web.Helpers.dll
new file mode 100644
index 00000000000..a41bdcc651e
Binary files /dev/null and b/DNN Platform/Components/WebPages/System.Web.Helpers.dll differ
diff --git a/DNN Platform/Components/WebPages/System.Web.Razor.dll b/DNN Platform/Components/WebPages/System.Web.Razor.dll
new file mode 100644
index 00000000000..470f0c70685
Binary files /dev/null and b/DNN Platform/Components/WebPages/System.Web.Razor.dll differ
diff --git a/DNN Platform/Components/WebPages/System.Web.WebPages.Razor.dll b/DNN Platform/Components/WebPages/System.Web.WebPages.Razor.dll
new file mode 100644
index 00000000000..f9e71f8419c
Binary files /dev/null and b/DNN Platform/Components/WebPages/System.Web.WebPages.Razor.dll differ
diff --git a/DNN Platform/Components/WebPages/WebMatrix.Data.dll b/DNN Platform/Components/WebPages/WebMatrix.Data.dll
new file mode 100644
index 00000000000..19287cea24c
Binary files /dev/null and b/DNN Platform/Components/WebPages/WebMatrix.Data.dll differ
diff --git a/DNN Platform/Components/WebPages/WebMatrix.WebData.dll b/DNN Platform/Components/WebPages/WebMatrix.WebData.dll
new file mode 100644
index 00000000000..e058ba8664d
Binary files /dev/null and b/DNN Platform/Components/WebPages/WebMatrix.WebData.dll differ
diff --git a/DNN Platform/Controls/CountryListBox/CountryListBox.cs b/DNN Platform/Controls/CountryListBox/CountryListBox.cs
new file mode 100644
index 00000000000..855ff1c6404
--- /dev/null
+++ b/DNN Platform/Controls/CountryListBox/CountryListBox.cs
@@ -0,0 +1,208 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+//------------------------------------------------------------------------------------------------
+// CountryListBox ASP.NET Web Control, lists countries and
+// automatically detects country of visitors.
+//
+// This web control will load a listbox with all countries and
+// upon loading will attempt to automatically recognize the
+// country that the visitor is visiting the website from.
+//------------------------------------------------------------------------------------------------
+
+#region Usings
+
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Web.Caching;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.UI.WebControls
+{
+ [ToolboxData("<{0}:CountryListBox runat=server>{0}:CountryListBox>")]
+ public class CountryListBox : DropDownList
+ {
+ private bool _CacheGeoIPData = true;
+ private string _GeoIPFile;
+ private string _LocalhostCountryCode;
+ private string _TestIP;
+
+ [Bindable(true), Category("Caching"), DefaultValue(true)]
+ public bool CacheGeoIPData
+ {
+ get
+ {
+ return _CacheGeoIPData;
+ }
+ set
+ {
+ _CacheGeoIPData = value;
+ if (value == false)
+ {
+ Context.Cache.Remove("GeoIPData");
+ }
+ }
+ }
+
+ [Bindable(true), Category("Appearance"), DefaultValue("")]
+ public string GeoIPFile
+ {
+ get
+ {
+ return _GeoIPFile;
+ }
+ set
+ {
+ _GeoIPFile = value;
+ }
+ }
+
+ [Bindable(true), Category("Appearance"), DefaultValue("")]
+ public string TestIP
+ {
+ get
+ {
+ return _TestIP;
+ }
+ set
+ {
+ _TestIP = value;
+ }
+ }
+
+ [Bindable(true), Category("Appearance"), DefaultValue("")]
+ public string LocalhostCountryCode
+ {
+ get
+ {
+ return _LocalhostCountryCode;
+ }
+ set
+ {
+ _LocalhostCountryCode = value;
+ }
+ }
+
+ protected override void OnDataBinding(EventArgs e)
+ {
+ bool IsLocal = false;
+ string IP;
+ if (!Page.IsPostBack)
+ {
+ //If GeoIPFile is not provided, assume they put it in BIN.
+ if (String.IsNullOrEmpty(_GeoIPFile))
+ {
+ _GeoIPFile = "controls/CountryListBox/Data/GeoIP.dat";
+ }
+ EnsureChildControls();
+ //Check to see if a TestIP is specified
+ if (!String.IsNullOrEmpty(_TestIP))
+ {
+ //TestIP is specified, let's use it
+ IP = _TestIP;
+ }
+ else if (Page.Request.UserHostAddress == "127.0.0.1")
+ {
+ //The country cannot be detected because the user is local.
+ IsLocal = true;
+ //Set the IP address in case they didn't specify LocalhostCountryCode
+ IP = Page.Request.UserHostAddress;
+ }
+ else
+ {
+ //Set the IP address so we can find the country
+ IP = Page.Request.UserHostAddress;
+ }
+
+ //Check to see if we need to generate the Cache for the GeoIPData file
+ if (Context.Cache.Get("GeoIPData") == null && _CacheGeoIPData)
+ {
+ //Store it as well as setting a dependency on the file
+ Context.Cache.Insert("GeoIPData", CountryLookup.FileToMemory(Context.Server.MapPath(_GeoIPFile)), new CacheDependency(Context.Server.MapPath(_GeoIPFile)));
+ }
+
+ //Check to see if the request is a localhost request
+ //and see if the LocalhostCountryCode is specified
+ if (IsLocal && !String.IsNullOrEmpty(_LocalhostCountryCode))
+ {
+ //Bing the data
+ base.OnDataBinding(e);
+ //Pre-Select the value in the drop-down based
+ //on the LocalhostCountryCode specified.
+ if (Items.FindByValue(_LocalhostCountryCode) != null)
+ {
+ Items.FindByValue(_LocalhostCountryCode).Selected = true;
+ }
+ }
+ else
+ {
+ //Either this is a remote request or it is a local
+ //request with no LocalhostCountryCode specified
+ CountryLookup _CountryLookup;
+
+ //Check to see if we are using the Cached
+ //version of the GeoIPData file
+ if (_CacheGeoIPData)
+ {
+ //Yes, get it from cache
+ _CountryLookup = new CountryLookup((MemoryStream) Context.Cache.Get("GeoIPData"));
+ }
+ else
+ {
+ //No, get it from file
+ _CountryLookup = new CountryLookup(Context.Server.MapPath(_GeoIPFile));
+ }
+ //Get the country code based on the IP address
+ string _UserCountryCode = _CountryLookup.LookupCountryCode(IP);
+
+ //Bind the datasource
+ base.OnDataBinding(e);
+
+ //Make sure the value returned is actually
+ //in the drop-down list.
+ if (Items.FindByValue(_UserCountryCode) != null)
+ {
+ //Yes, it's there, select it based on its value
+ Items.FindByValue(_UserCountryCode).Selected = true;
+ }
+ else
+ {
+ //No it's not there. Let's get the Country description
+ //and add a new list item for the Country detected
+ string _UserCountry = _CountryLookup.LookupCountryName(IP);
+ if (_UserCountry != "N/A")
+ {
+ var newItem = new ListItem();
+ newItem.Value = _UserCountryCode;
+ newItem.Text = _UserCountry;
+ Items.Insert(0, newItem);
+ //Now let's Pre-Select it
+ Items.FindByValue(_UserCountryCode).Selected = true;
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Controls/CountryListBox/CountryListBox.csproj b/DNN Platform/Controls/CountryListBox/CountryListBox.csproj
new file mode 100644
index 00000000000..d65545b49f9
--- /dev/null
+++ b/DNN Platform/Controls/CountryListBox/CountryListBox.csproj
@@ -0,0 +1,112 @@
+
+
+
+ 9.0.30729
+ 2.0
+ {CA056730-5759-41F8-A6C1-420F9C0C63E7}
+ Debug
+ AnyCPU
+ CountryListBox
+ None
+ Library
+ v4.0
+ SAK
+ SAK
+ SAK
+ SAK
+ CountryListBox
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ bin\
+ CountryListBox.xml
+ true
+ true
+ 4
+ full
+ AllRules.ruleset
+ 1591
+ default
+
+
+ bin\
+ CountryListBox.xml
+ true
+ true
+ 4
+ pdbonly
+ AllRules.ruleset
+ 1591
+
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+ System.Web
+
+
+
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Controls/CountryListBox/CountryLookup.cs b/DNN Platform/Controls/CountryListBox/CountryLookup.cs
new file mode 100644
index 00000000000..cb0e276cdfc
--- /dev/null
+++ b/DNN Platform/Controls/CountryListBox/CountryLookup.cs
@@ -0,0 +1,286 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+//------------------------------------------------------------------------------------------------
+// This class uses an IP lookup database from MaxMind, specifically
+// the GeoIP Free Database.
+//
+// The database and the c# implementation of this class
+// are available from http://www.maxmind.com/app/csharp
+//------------------------------------------------------------------------------------------------
+#region Usings
+
+using System;
+using System.IO;
+using System.Net;
+
+#endregion
+
+namespace DotNetNuke.UI.WebControls
+{
+ public class CountryLookup
+ {
+ private static long CountryBegin = 16776960;
+
+ private static readonly string[] CountryName = new[]
+ {
+ "N/A", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", "Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania",
+ "Armenia", "Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", "Austria", "Australia", "Aruba", "Azerbaijan",
+ "Bosnia and Herzegovina", "Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", "Burundi", "Benin", "Bermuda",
+ "Brunei Darussalam", "Bolivia", "Brazil", "Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", "Canada",
+ "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", "Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire",
+ "Cook Islands", "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde", "Christmas Island", "Cyprus", "Czech Republic"
+ , "Germany", "Djibouti", "Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", "Egypt", "Western Sahara", "Eritrea",
+ "Spain", "Ethiopia", "Finland", "Fiji", "Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands", "France",
+ "France, Metropolitan", "Gabon", "United Kingdom", "Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", "Gambia",
+ "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia and the South Sandwich Islands", "Guatemala", "Guam", "Guinea-Bissau",
+ "Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", "Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel",
+ "India", "British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", "Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya",
+ "Kyrgyzstan", "Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic People's Republic of", "Korea, Republic of",
+ "Kuwait", "Cayman Islands", "Kazakstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", "Liechtenstein", "Sri Lanka",
+ "Liberia", "Lesotho", "Lithuania", "Luxembourg", "Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of",
+ "Madagascar", "Marshall Islands", "Macedonia, the Former Yugoslav Republic of", "Mali", "Myanmar", "Mongolia", "Macau",
+ "Northern Mariana Islands", "Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", "Malawi", "Mexico", "Malaysia",
+ "Mozambique", "Namibia", "New Caledonia", "Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", "Nepal", "Nauru",
+ "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia", "Papua New Guinea", "Philippines", "Pakistan", "Poland",
+ "Saint Pierre and Miquelon", "Pitcairn", "Puerto Rico", "Palestinian Territory, Occupied", "Portugal", "Palau", "Paraguay", "Qatar",
+ "Reunion", "Romania", "Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", "Seychelles", "Sudan", "Sweden", "Singapore",
+ "Saint Helena", "Slovenia", "Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", "Somalia", "Suriname",
+ "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic", "Swaziland", "Turks and Caicos Islands", "Chad",
+ "French Southern Territories", "Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", "Tunisia", "Tonga", "East Timor", "Turkey",
+ "Trinidad and Tobago", "Tuvalu", "Taiwan, Province of China", "Tanzania, United Republic of", "Ukraine", "Uganda",
+ "United States Minor Outlying Islands", "United States", "Uruguay", "Uzbekistan", "Holy See (Vatican City State)",
+ "Saint Vincent and the Grenadines", "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", "Vietnam", "Vanuatu",
+ "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", "Yugoslavia", "South Africa", "Zambia", "Zaire", "Zimbabwe", "Anonymous Proxy",
+ "Satellite Provider"
+ };
+
+ private static readonly string[] CountryCode = new[]
+ {
+ "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE",
+ "BF", "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK",
+ "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET",
+ "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU",
+ "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH",
+ "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG",
+ "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI",
+ "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE",
+ "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC",
+ "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC",
+ "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZR", "ZW", "A1", "A2"
+ };
+
+ public MemoryStream m_MemoryStream;
+
+ public CountryLookup(MemoryStream ms)
+ {
+ m_MemoryStream = ms;
+ }
+
+ public CountryLookup(string FileLocation)
+ {
+ //------------------------------------------------------------------------------------------------
+ //Load the passed in GeoIP Data file to the memorystream
+ //------------------------------------------------------------------------------------------------
+ var _FileStream = new FileStream(FileLocation, FileMode.Open, FileAccess.Read);
+ m_MemoryStream = new MemoryStream();
+ var _Byte = new byte[256];
+ while (_FileStream.Read(_Byte, 0, _Byte.Length) != 0)
+ {
+ m_MemoryStream.Write(_Byte, 0, _Byte.Length);
+ }
+ _FileStream.Close();
+ }
+
+ private long ConvertIPAddressToNumber(IPAddress _IPAddress)
+ {
+ //Convert an IP Address, (e.g. 127.0.0.1), to the numeric equivalent
+ string[] _Address = _IPAddress.ToString().Split('.');
+ if (_Address.Length == 4)
+ {
+ return Convert.ToInt64(16777216*Convert.ToDouble(_Address[0]) + 65536*Convert.ToDouble(_Address[1]) + 256*Convert.ToDouble(_Address[2]) + Convert.ToDouble(_Address[3]));
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private string ConvertIPNumberToAddress(long _IPNumber)
+ {
+ //Convert an IP Number to the IP Address equivalent
+ string _IPNumberPart1 = Convert.ToString(((int) (_IPNumber/16777216))%256);
+ string _IPNumberPart2 = Convert.ToString(((int) (_IPNumber/65536))%256);
+ string _IPNumberPart3 = Convert.ToString(((int) (_IPNumber/256))%256);
+ string _IPNumberPart4 = Convert.ToString(((int) (_IPNumber))%256);
+ return _IPNumberPart1 + "." + _IPNumberPart2 + "." + _IPNumberPart3 + "." + _IPNumberPart4;
+ }
+
+ public static MemoryStream FileToMemory(string FileLocation)
+ {
+ //Read a given file into a Memory Stream to return as the result
+ FileStream _FileStream;
+ var _MemStream = new MemoryStream();
+ var _Byte = new byte[256];
+ try
+ {
+ _FileStream = new FileStream(FileLocation, FileMode.Open, FileAccess.Read);
+ while (_FileStream.Read(_Byte, 0, _Byte.Length) != 0)
+ {
+ _MemStream.Write(_Byte, 0, _Byte.Length);
+ }
+ _FileStream.Close();
+ }
+ catch (FileNotFoundException exc)
+ {
+ throw new Exception(exc.Message +
+ " Please set the \"GeoIPFile\" Property to specify the location of this file. The property value must be set to the virtual path to GeoIP.dat (i.e. \"/controls/CountryListBox/Data/GeoIP.dat\")");
+ }
+ return _MemStream;
+ }
+
+ public string LookupCountryCode(IPAddress _IPAddress)
+ {
+ //Look up the country code, e.g. US, for the passed in IP Address
+ return CountryCode[Convert.ToInt32(SeekCountry(0, ConvertIPAddressToNumber(_IPAddress), 31))];
+ }
+
+ public string LookupCountryCode(string _IPAddress)
+ {
+ //Look up the country code, e.g. US, for the passed in IP Address
+ IPAddress _Address;
+ try
+ {
+ _Address = IPAddress.Parse(_IPAddress);
+ }
+ catch (FormatException)
+ {
+ return "--";
+ }
+ return LookupCountryCode(_Address);
+ }
+
+ public string LookupCountryName(IPAddress addr)
+ {
+ //Look up the country name, e.g. United States, for the IP Address
+ return CountryName[Convert.ToInt32(SeekCountry(0, ConvertIPAddressToNumber(addr), 31))];
+ }
+
+ public string LookupCountryName(string _IPAddress)
+ {
+ //Look up the country name, e.g. United States, for the IP Address
+ IPAddress _Address;
+ try
+ {
+ _Address = IPAddress.Parse(_IPAddress);
+ }
+ catch (FormatException)
+ {
+ return "N/A";
+ }
+ return LookupCountryName(_Address);
+ }
+
+ private long vbShiftLeft(long value, int Count)
+ {
+ //------------------------------------------------------------------------------------------------
+ // Replacement for Bitwise operators which are missing in VB.NET,
+ // these functions are present in .NET 1.1, but for developers
+ // using 1.0, replacement functions must be implemented
+ //------------------------------------------------------------------------------------------------
+ long returnValue = 0;
+ int _Iterator;
+ returnValue = value;
+ for (_Iterator = 1; _Iterator <= Count; _Iterator++)
+ {
+ returnValue = returnValue*2;
+ }
+ return returnValue;
+ }
+
+ private long vbShiftRight(long value, int Count)
+ {
+ //------------------------------------------------------------------------------------------------
+ // Replacement for Bitwise operators which are missing in VB.NET,
+ // these functions are present in .NET 1.1, but for developers
+ // using 1.0, replacement functions must be implemented
+ //------------------------------------------------------------------------------------------------
+ long returnValue = 0;
+ int _Iterator;
+ returnValue = value;
+ for (_Iterator = 1; _Iterator <= Count; _Iterator++)
+ {
+ returnValue = returnValue/2;
+ }
+ return returnValue;
+ }
+
+ public int SeekCountry(int Offset, long Ipnum, short Depth)
+ {
+ try
+ {
+ var Buffer = new byte[6];
+ var X = new int[2];
+ short I;
+ short J;
+ byte Y;
+ if (Depth == 0)
+ {
+ throw new Exception();
+ }
+ m_MemoryStream.Seek(6*Offset, 0);
+ m_MemoryStream.Read(Buffer, 0, 6);
+ for (I = 0; I <= 1; I++)
+ {
+ X[I] = 0;
+ for (J = 0; J <= 2; J++)
+ {
+ Y = Buffer[I*3 + J];
+ if (Y < 0)
+ {
+ Y = Convert.ToByte(Y + 256);
+ }
+ X[I] = Convert.ToInt32(X[I] + vbShiftLeft(Y, J*8));
+ }
+ }
+ if ((Ipnum & vbShiftLeft(1, Depth)) > 0)
+ {
+ if (X[1] >= CountryBegin)
+ {
+ return Convert.ToInt32(X[1] - CountryBegin);
+ }
+ return SeekCountry(X[1], Ipnum, Convert.ToInt16(Depth - 1));
+ }
+ else
+ {
+ if (X[0] >= CountryBegin)
+ {
+ return Convert.ToInt32(X[0] - CountryBegin);
+ }
+ return SeekCountry(X[0], Ipnum, Convert.ToInt16(Depth - 1));
+ }
+ }
+ catch (Exception exc)
+ {
+ throw new Exception("Error seeking country: " + exc.Message);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Controls/CountryListBox/Properties/AssemblyInfo.cs b/DNN Platform/Controls/CountryListBox/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..835f8af5d27
--- /dev/null
+++ b/DNN Platform/Controls/CountryListBox/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Web.UI;
+
+#endregion
+
+[assembly: AssemblyTitle("DotNetNuke")]
+[assembly: AssemblyDescription("Open Source Web Application Framework")]
+[assembly: AssemblyCompany("DotNetNuke Corporation")]
+[assembly: AssemblyProduct("http://www.dotnetnuke.com")]
+[assembly: AssemblyCopyright("DotNetNuke is copyright 2002-2013 by DotNetNuke Corporation. All Rights Reserved.")]
+[assembly: AssemblyTrademark("DotNetNuke")]
+[assembly: CLSCompliant(true)]
+[assembly: Guid("3D57E77F-F723-48BB-A58C-3FAB63C562D4")]
+[assembly: AssemblyVersion("6.2.1.11")]
+[assembly: TagPrefix("DotNetNuke.UI.WebControls.CountryListBox", "DotNetNuke")]
diff --git a/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.cs b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.cs
new file mode 100644
index 00000000000..855ff1c6404
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.cs
@@ -0,0 +1,208 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+//------------------------------------------------------------------------------------------------
+// CountryListBox ASP.NET Web Control, lists countries and
+// automatically detects country of visitors.
+//
+// This web control will load a listbox with all countries and
+// upon loading will attempt to automatically recognize the
+// country that the visitor is visiting the website from.
+//------------------------------------------------------------------------------------------------
+
+#region Usings
+
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Web.Caching;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.UI.WebControls
+{
+ [ToolboxData("<{0}:CountryListBox runat=server>{0}:CountryListBox>")]
+ public class CountryListBox : DropDownList
+ {
+ private bool _CacheGeoIPData = true;
+ private string _GeoIPFile;
+ private string _LocalhostCountryCode;
+ private string _TestIP;
+
+ [Bindable(true), Category("Caching"), DefaultValue(true)]
+ public bool CacheGeoIPData
+ {
+ get
+ {
+ return _CacheGeoIPData;
+ }
+ set
+ {
+ _CacheGeoIPData = value;
+ if (value == false)
+ {
+ Context.Cache.Remove("GeoIPData");
+ }
+ }
+ }
+
+ [Bindable(true), Category("Appearance"), DefaultValue("")]
+ public string GeoIPFile
+ {
+ get
+ {
+ return _GeoIPFile;
+ }
+ set
+ {
+ _GeoIPFile = value;
+ }
+ }
+
+ [Bindable(true), Category("Appearance"), DefaultValue("")]
+ public string TestIP
+ {
+ get
+ {
+ return _TestIP;
+ }
+ set
+ {
+ _TestIP = value;
+ }
+ }
+
+ [Bindable(true), Category("Appearance"), DefaultValue("")]
+ public string LocalhostCountryCode
+ {
+ get
+ {
+ return _LocalhostCountryCode;
+ }
+ set
+ {
+ _LocalhostCountryCode = value;
+ }
+ }
+
+ protected override void OnDataBinding(EventArgs e)
+ {
+ bool IsLocal = false;
+ string IP;
+ if (!Page.IsPostBack)
+ {
+ //If GeoIPFile is not provided, assume they put it in BIN.
+ if (String.IsNullOrEmpty(_GeoIPFile))
+ {
+ _GeoIPFile = "controls/CountryListBox/Data/GeoIP.dat";
+ }
+ EnsureChildControls();
+ //Check to see if a TestIP is specified
+ if (!String.IsNullOrEmpty(_TestIP))
+ {
+ //TestIP is specified, let's use it
+ IP = _TestIP;
+ }
+ else if (Page.Request.UserHostAddress == "127.0.0.1")
+ {
+ //The country cannot be detected because the user is local.
+ IsLocal = true;
+ //Set the IP address in case they didn't specify LocalhostCountryCode
+ IP = Page.Request.UserHostAddress;
+ }
+ else
+ {
+ //Set the IP address so we can find the country
+ IP = Page.Request.UserHostAddress;
+ }
+
+ //Check to see if we need to generate the Cache for the GeoIPData file
+ if (Context.Cache.Get("GeoIPData") == null && _CacheGeoIPData)
+ {
+ //Store it as well as setting a dependency on the file
+ Context.Cache.Insert("GeoIPData", CountryLookup.FileToMemory(Context.Server.MapPath(_GeoIPFile)), new CacheDependency(Context.Server.MapPath(_GeoIPFile)));
+ }
+
+ //Check to see if the request is a localhost request
+ //and see if the LocalhostCountryCode is specified
+ if (IsLocal && !String.IsNullOrEmpty(_LocalhostCountryCode))
+ {
+ //Bing the data
+ base.OnDataBinding(e);
+ //Pre-Select the value in the drop-down based
+ //on the LocalhostCountryCode specified.
+ if (Items.FindByValue(_LocalhostCountryCode) != null)
+ {
+ Items.FindByValue(_LocalhostCountryCode).Selected = true;
+ }
+ }
+ else
+ {
+ //Either this is a remote request or it is a local
+ //request with no LocalhostCountryCode specified
+ CountryLookup _CountryLookup;
+
+ //Check to see if we are using the Cached
+ //version of the GeoIPData file
+ if (_CacheGeoIPData)
+ {
+ //Yes, get it from cache
+ _CountryLookup = new CountryLookup((MemoryStream) Context.Cache.Get("GeoIPData"));
+ }
+ else
+ {
+ //No, get it from file
+ _CountryLookup = new CountryLookup(Context.Server.MapPath(_GeoIPFile));
+ }
+ //Get the country code based on the IP address
+ string _UserCountryCode = _CountryLookup.LookupCountryCode(IP);
+
+ //Bind the datasource
+ base.OnDataBinding(e);
+
+ //Make sure the value returned is actually
+ //in the drop-down list.
+ if (Items.FindByValue(_UserCountryCode) != null)
+ {
+ //Yes, it's there, select it based on its value
+ Items.FindByValue(_UserCountryCode).Selected = true;
+ }
+ else
+ {
+ //No it's not there. Let's get the Country description
+ //and add a new list item for the Country detected
+ string _UserCountry = _CountryLookup.LookupCountryName(IP);
+ if (_UserCountry != "N/A")
+ {
+ var newItem = new ListItem();
+ newItem.Value = _UserCountryCode;
+ newItem.Text = _UserCountry;
+ Items.Insert(0, newItem);
+ //Now let's Pre-Select it
+ Items.FindByValue(_UserCountryCode).Selected = true;
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.csproj b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.csproj
new file mode 100644
index 00000000000..d65545b49f9
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.csproj
@@ -0,0 +1,112 @@
+
+
+
+ 9.0.30729
+ 2.0
+ {CA056730-5759-41F8-A6C1-420F9C0C63E7}
+ Debug
+ AnyCPU
+ CountryListBox
+ None
+ Library
+ v4.0
+ SAK
+ SAK
+ SAK
+ SAK
+ CountryListBox
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ bin\
+ CountryListBox.xml
+ true
+ true
+ 4
+ full
+ AllRules.ruleset
+ 1591
+ default
+
+
+ bin\
+ CountryListBox.xml
+ true
+ true
+ 4
+ pdbonly
+ AllRules.ruleset
+ 1591
+
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+ System.Web
+
+
+
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.xml b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.xml
new file mode 100644
index 00000000000..f7a42ea7544
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryListBox.xml
@@ -0,0 +1,8 @@
+
+
+
+ CountryListBox
+
+
+
+
diff --git a/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryLookup.cs b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryLookup.cs
new file mode 100644
index 00000000000..cb0e276cdfc
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/CountryListBox/CountryLookup.cs
@@ -0,0 +1,286 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+//------------------------------------------------------------------------------------------------
+// This class uses an IP lookup database from MaxMind, specifically
+// the GeoIP Free Database.
+//
+// The database and the c# implementation of this class
+// are available from http://www.maxmind.com/app/csharp
+//------------------------------------------------------------------------------------------------
+#region Usings
+
+using System;
+using System.IO;
+using System.Net;
+
+#endregion
+
+namespace DotNetNuke.UI.WebControls
+{
+ public class CountryLookup
+ {
+ private static long CountryBegin = 16776960;
+
+ private static readonly string[] CountryName = new[]
+ {
+ "N/A", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", "Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania",
+ "Armenia", "Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", "Austria", "Australia", "Aruba", "Azerbaijan",
+ "Bosnia and Herzegovina", "Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", "Burundi", "Benin", "Bermuda",
+ "Brunei Darussalam", "Bolivia", "Brazil", "Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", "Canada",
+ "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", "Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire",
+ "Cook Islands", "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde", "Christmas Island", "Cyprus", "Czech Republic"
+ , "Germany", "Djibouti", "Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", "Egypt", "Western Sahara", "Eritrea",
+ "Spain", "Ethiopia", "Finland", "Fiji", "Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands", "France",
+ "France, Metropolitan", "Gabon", "United Kingdom", "Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", "Gambia",
+ "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia and the South Sandwich Islands", "Guatemala", "Guam", "Guinea-Bissau",
+ "Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", "Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel",
+ "India", "British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", "Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya",
+ "Kyrgyzstan", "Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic People's Republic of", "Korea, Republic of",
+ "Kuwait", "Cayman Islands", "Kazakstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", "Liechtenstein", "Sri Lanka",
+ "Liberia", "Lesotho", "Lithuania", "Luxembourg", "Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of",
+ "Madagascar", "Marshall Islands", "Macedonia, the Former Yugoslav Republic of", "Mali", "Myanmar", "Mongolia", "Macau",
+ "Northern Mariana Islands", "Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", "Malawi", "Mexico", "Malaysia",
+ "Mozambique", "Namibia", "New Caledonia", "Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", "Nepal", "Nauru",
+ "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia", "Papua New Guinea", "Philippines", "Pakistan", "Poland",
+ "Saint Pierre and Miquelon", "Pitcairn", "Puerto Rico", "Palestinian Territory, Occupied", "Portugal", "Palau", "Paraguay", "Qatar",
+ "Reunion", "Romania", "Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", "Seychelles", "Sudan", "Sweden", "Singapore",
+ "Saint Helena", "Slovenia", "Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", "Somalia", "Suriname",
+ "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic", "Swaziland", "Turks and Caicos Islands", "Chad",
+ "French Southern Territories", "Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", "Tunisia", "Tonga", "East Timor", "Turkey",
+ "Trinidad and Tobago", "Tuvalu", "Taiwan, Province of China", "Tanzania, United Republic of", "Ukraine", "Uganda",
+ "United States Minor Outlying Islands", "United States", "Uruguay", "Uzbekistan", "Holy See (Vatican City State)",
+ "Saint Vincent and the Grenadines", "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", "Vietnam", "Vanuatu",
+ "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", "Yugoslavia", "South Africa", "Zambia", "Zaire", "Zimbabwe", "Anonymous Proxy",
+ "Satellite Provider"
+ };
+
+ private static readonly string[] CountryCode = new[]
+ {
+ "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE",
+ "BF", "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK",
+ "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET",
+ "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU",
+ "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH",
+ "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG",
+ "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI",
+ "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE",
+ "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC",
+ "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC",
+ "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZR", "ZW", "A1", "A2"
+ };
+
+ public MemoryStream m_MemoryStream;
+
+ public CountryLookup(MemoryStream ms)
+ {
+ m_MemoryStream = ms;
+ }
+
+ public CountryLookup(string FileLocation)
+ {
+ //------------------------------------------------------------------------------------------------
+ //Load the passed in GeoIP Data file to the memorystream
+ //------------------------------------------------------------------------------------------------
+ var _FileStream = new FileStream(FileLocation, FileMode.Open, FileAccess.Read);
+ m_MemoryStream = new MemoryStream();
+ var _Byte = new byte[256];
+ while (_FileStream.Read(_Byte, 0, _Byte.Length) != 0)
+ {
+ m_MemoryStream.Write(_Byte, 0, _Byte.Length);
+ }
+ _FileStream.Close();
+ }
+
+ private long ConvertIPAddressToNumber(IPAddress _IPAddress)
+ {
+ //Convert an IP Address, (e.g. 127.0.0.1), to the numeric equivalent
+ string[] _Address = _IPAddress.ToString().Split('.');
+ if (_Address.Length == 4)
+ {
+ return Convert.ToInt64(16777216*Convert.ToDouble(_Address[0]) + 65536*Convert.ToDouble(_Address[1]) + 256*Convert.ToDouble(_Address[2]) + Convert.ToDouble(_Address[3]));
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private string ConvertIPNumberToAddress(long _IPNumber)
+ {
+ //Convert an IP Number to the IP Address equivalent
+ string _IPNumberPart1 = Convert.ToString(((int) (_IPNumber/16777216))%256);
+ string _IPNumberPart2 = Convert.ToString(((int) (_IPNumber/65536))%256);
+ string _IPNumberPart3 = Convert.ToString(((int) (_IPNumber/256))%256);
+ string _IPNumberPart4 = Convert.ToString(((int) (_IPNumber))%256);
+ return _IPNumberPart1 + "." + _IPNumberPart2 + "." + _IPNumberPart3 + "." + _IPNumberPart4;
+ }
+
+ public static MemoryStream FileToMemory(string FileLocation)
+ {
+ //Read a given file into a Memory Stream to return as the result
+ FileStream _FileStream;
+ var _MemStream = new MemoryStream();
+ var _Byte = new byte[256];
+ try
+ {
+ _FileStream = new FileStream(FileLocation, FileMode.Open, FileAccess.Read);
+ while (_FileStream.Read(_Byte, 0, _Byte.Length) != 0)
+ {
+ _MemStream.Write(_Byte, 0, _Byte.Length);
+ }
+ _FileStream.Close();
+ }
+ catch (FileNotFoundException exc)
+ {
+ throw new Exception(exc.Message +
+ " Please set the \"GeoIPFile\" Property to specify the location of this file. The property value must be set to the virtual path to GeoIP.dat (i.e. \"/controls/CountryListBox/Data/GeoIP.dat\")");
+ }
+ return _MemStream;
+ }
+
+ public string LookupCountryCode(IPAddress _IPAddress)
+ {
+ //Look up the country code, e.g. US, for the passed in IP Address
+ return CountryCode[Convert.ToInt32(SeekCountry(0, ConvertIPAddressToNumber(_IPAddress), 31))];
+ }
+
+ public string LookupCountryCode(string _IPAddress)
+ {
+ //Look up the country code, e.g. US, for the passed in IP Address
+ IPAddress _Address;
+ try
+ {
+ _Address = IPAddress.Parse(_IPAddress);
+ }
+ catch (FormatException)
+ {
+ return "--";
+ }
+ return LookupCountryCode(_Address);
+ }
+
+ public string LookupCountryName(IPAddress addr)
+ {
+ //Look up the country name, e.g. United States, for the IP Address
+ return CountryName[Convert.ToInt32(SeekCountry(0, ConvertIPAddressToNumber(addr), 31))];
+ }
+
+ public string LookupCountryName(string _IPAddress)
+ {
+ //Look up the country name, e.g. United States, for the IP Address
+ IPAddress _Address;
+ try
+ {
+ _Address = IPAddress.Parse(_IPAddress);
+ }
+ catch (FormatException)
+ {
+ return "N/A";
+ }
+ return LookupCountryName(_Address);
+ }
+
+ private long vbShiftLeft(long value, int Count)
+ {
+ //------------------------------------------------------------------------------------------------
+ // Replacement for Bitwise operators which are missing in VB.NET,
+ // these functions are present in .NET 1.1, but for developers
+ // using 1.0, replacement functions must be implemented
+ //------------------------------------------------------------------------------------------------
+ long returnValue = 0;
+ int _Iterator;
+ returnValue = value;
+ for (_Iterator = 1; _Iterator <= Count; _Iterator++)
+ {
+ returnValue = returnValue*2;
+ }
+ return returnValue;
+ }
+
+ private long vbShiftRight(long value, int Count)
+ {
+ //------------------------------------------------------------------------------------------------
+ // Replacement for Bitwise operators which are missing in VB.NET,
+ // these functions are present in .NET 1.1, but for developers
+ // using 1.0, replacement functions must be implemented
+ //------------------------------------------------------------------------------------------------
+ long returnValue = 0;
+ int _Iterator;
+ returnValue = value;
+ for (_Iterator = 1; _Iterator <= Count; _Iterator++)
+ {
+ returnValue = returnValue/2;
+ }
+ return returnValue;
+ }
+
+ public int SeekCountry(int Offset, long Ipnum, short Depth)
+ {
+ try
+ {
+ var Buffer = new byte[6];
+ var X = new int[2];
+ short I;
+ short J;
+ byte Y;
+ if (Depth == 0)
+ {
+ throw new Exception();
+ }
+ m_MemoryStream.Seek(6*Offset, 0);
+ m_MemoryStream.Read(Buffer, 0, 6);
+ for (I = 0; I <= 1; I++)
+ {
+ X[I] = 0;
+ for (J = 0; J <= 2; J++)
+ {
+ Y = Buffer[I*3 + J];
+ if (Y < 0)
+ {
+ Y = Convert.ToByte(Y + 256);
+ }
+ X[I] = Convert.ToInt32(X[I] + vbShiftLeft(Y, J*8));
+ }
+ }
+ if ((Ipnum & vbShiftLeft(1, Depth)) > 0)
+ {
+ if (X[1] >= CountryBegin)
+ {
+ return Convert.ToInt32(X[1] - CountryBegin);
+ }
+ return SeekCountry(X[1], Ipnum, Convert.ToInt16(Depth - 1));
+ }
+ else
+ {
+ if (X[0] >= CountryBegin)
+ {
+ return Convert.ToInt32(X[0] - CountryBegin);
+ }
+ return SeekCountry(X[0], Ipnum, Convert.ToInt16(Depth - 1));
+ }
+ }
+ catch (Exception exc)
+ {
+ throw new Exception("Error seeking country: " + exc.Message);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Controls/SolpartMenu/CountryListBox/Properties/AssemblyInfo.cs b/DNN Platform/Controls/SolpartMenu/CountryListBox/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..835f8af5d27
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/CountryListBox/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Web.UI;
+
+#endregion
+
+[assembly: AssemblyTitle("DotNetNuke")]
+[assembly: AssemblyDescription("Open Source Web Application Framework")]
+[assembly: AssemblyCompany("DotNetNuke Corporation")]
+[assembly: AssemblyProduct("http://www.dotnetnuke.com")]
+[assembly: AssemblyCopyright("DotNetNuke is copyright 2002-2013 by DotNetNuke Corporation. All Rights Reserved.")]
+[assembly: AssemblyTrademark("DotNetNuke")]
+[assembly: CLSCompliant(true)]
+[assembly: Guid("3D57E77F-F723-48BB-A58C-3FAB63C562D4")]
+[assembly: AssemblyVersion("6.2.1.11")]
+[assembly: TagPrefix("DotNetNuke.UI.WebControls.CountryListBox", "DotNetNuke")]
diff --git a/DNN Platform/Controls/SolpartMenu/License.txt b/DNN Platform/Controls/SolpartMenu/License.txt
new file mode 100644
index 00000000000..15cd5411ff3
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/License.txt
@@ -0,0 +1,27 @@
+'=============================================================================
+'No Nonsense Copyright and License for Solpart ASP.NET Hierarchical WebControl
+'=============================================================================
+'
+'Copyright:
+'
+'This library was written by me. You are welcome to use it, modify it to suit
+'your needs, distribute it as you see fit. I'm happy if you use it for
+'personal stuff or for commercial gain.
+'
+'The only thing you can't do is to restrict anyone else from using it however
+'they see fit. You may not copyright it yourself or change the rules I have
+'set on how it can be used.
+'
+'Solpart ASP.NET Hierarchical WebControl Copyright (C) 2002 by Jon Henning
+'
+'License:
+'
+'You can use this however you like. I make no guarantees whatsoever that it
+'will suit your purpose. You take full responsibility for getting it working
+'properly and for any implications of its failure or inability to satisfy your
+'every need.
+'
+'=============================================================================
+'
+'Email: jhenning@solpart.com
+'Web: http://www.solpart.com/techcorner
diff --git a/DNN Platform/Controls/SolpartMenu/ReleaseNotes.txt b/DNN Platform/Controls/SolpartMenu/ReleaseNotes.txt
new file mode 100644
index 00000000000..af19cd51569
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/ReleaseNotes.txt
@@ -0,0 +1,348 @@
+==========================================================
+SolpartMenu v1.6.0.1 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- MacIE support added!
+
+==========================================================
+SolpartMenu v1.6.0.0 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Addition of SPMenuCaps.config file to configure which browsers
+ have which features (i.e. which ones render uplevel vs. downlevel)
+
+
+==========================================================
+SolpartMenu v1.5.0.2 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed issue with Safari upgrade 1.3.312
+
+==========================================================
+SolpartMenu v1.5.0.0 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed issue with Safari (IFrame trick caused menu not to show)
+- Fixed function naming for Netscape/FireFox/Mozilla
+ when control has '-' character in it.
+
+==========================================================
+SolpartMenu v1.4.0.3 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed issue with IFRAME trick and SSL (void(0) no longer
+ works no using src=spacer.gif
+
+==========================================================
+SolpartMenu v1.4.0.2 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed minor issue with rendering vertical menu and it
+ scrolled off page.
+- Fixed error When rendering ForceFullMenuList and no child nodes
+ exist
+- Fixed issue that stopped menu from being used in a
+ Trust=Medium
+
+==========================================================
+SolpartMenu v1.4.0.0 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed issues with Safari
+ - sub-menu alignment (Safari bug workaround)
+ - mouseout delay always set to 5 sec
+ - Browser identification sometimes rendered downlevel
+
+- applying keeping saved css class on hover
+- Applying submenu class to menu when forcefullmenuList on
+- reading in zindex for menu and incrementing 1 higher for
+ iframe trick.
+
+
+==========================================================
+SolpartMenu v1.3.0.5 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed MapPath issue with menu module
+- Added new menu provider to allow role based custom menus
+
+==========================================================
+SolpartMenu v1.3.0.3 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Made IFrame trick a property to turn off
+- When using IFrame trick setting src = javascript code
+ to avoid page not found message bleeding through
+- Made different technique to avoid operation aborted and
+ load up front at the same time
+
+==========================================================
+SolpartMenu v1.3.0.2 - Notes
+==========================================================
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Changed dir="rtl" alignment of submenus to be from right corner
+- Fixed issue with IFRAME trick and SSL
+- Fixed issue with IE5/5.5 for pages with menus that were set
+ to be invisible.
+- Absolute positioned menu support added!
+- Default way of handling windowed controls now is using an
+ IFRAME. Therefore you will no longer see your SELECT and
+ OBJECT tags disappear when the menu overlaps.
+ It should be noted that this idea originated from
+ http://dotnetjunkies.com/WebLog/jking/archive/2003/07/21/488.aspx
+- New CSS class ability ItemSelectedCss - for specifying a
+ different class for the selected item than the default MenuItemSel
+- Allowing Seperators to contain HTML - new overloaded methods
+ for AddBreak now accepts HTML parameter
+- New MenuEffect Property MouseOverScroll. Defaults to true,
+ when set having the mouse over the ... will scroll the menu
+ in addition to clicking ...
+- Added Target property to allow menu items with urls specified
+ to change the source of specified frame.
+- New examples - showing absolute positioning and image menus
+
+
+==========================================================
+SolpartMenu v1.2.0.3 - Notes
+==========================================================
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Added new method FindMenuItem. Useful for applying a
+ specific style to selected menu item.
+- Now hiding overlapping OBJECT tags (along with SELECT tags)
+- Fixed issue with submenus positioning when root menu items
+ scrolled off page
+- Fixed issue with Mozilla/NS/Opera where submenu would scroll
+ off page
+- ItemStyle now applying to TDs in addition to the TR
+ WARNING: MAY CAUSE DISPLAY CHANGES IF PROPERTY WAS USED!
+- Added ItemCss to go along with ItemStyle so that special
+ class can be applied on item level.
+- Fixed minor issue with savecss (for menuitem css).
+
+--- DNN MenuModule Specific ---
+----------------------------------------------------------
+- Added new MenuDataProvider to allow the showing of only
+ child tabs from current active tab
+- Changed ForceFullMenuList to output tree-like structure,
+ complete with styles. Allows for an easy way to do a site
+ map.
+- Added ForceFullMenuList to MenuDesigner in DNN
+- Added Tooltip to menuitem for MenuDesigner in DNN
+- Added css to menuitem for MenuDesigner in DNN
+- Fixed css style applying to preview in MenuDesigner
+
+
+==========================================================
+SolpartMenu v1.2.0.0 - Notes
+==========================================================
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+
+- Added ToolTip functionality
+- When menu detects there is not enough room to display
+ it will automatically add a scroll menu item to the top
+ and bottom when applicable.
+- New MenuCSS.MenuScroll class to customize display
+- Fixed Mozilla/Netscape border color issues
+- Minor fixes to ALT text of images
+- Fixed issue with menu designer where left/righthtml
+ not safely encoded
+- If menu detects dir="rtl" it will cause sub-menus to be
+ displayed on the left instead of right. IE seems to work
+ correctly, Mozilla/Netscape seem to have problems.
+
+
+==========================================================
+SolpartMenu v1.1.1.2 - Notes
+==========================================================
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+
+- Added functionality to detect Crawlers and have menu
+ render in a fashion that the Crawler can detect
+- Added property ForceFullMenuList - to force output to
+ render as if Crawler is requesting the page
+- Added DataBindMappings collection to allow for any menu
+ item attribute to be bound to datasource
+- Fixed Netscape 7.1 problem where doesn't report 'this'
+ onclick of menu item (now runat server works for this
+ browser)
+- Fixed Opera 7 postbacks (cannot access name property on client)
+- Added root level menubreak
+- Added script type to SCRIPT tags (javascript)
+
+
+==========================================================
+SolpartMenu v1.1.1.0 - Notes
+==========================================================
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Fixed problem with MenuClick event when in a UserControl
+- Added MenuItems collection to navigate through nodes
+- Added SeparateCSS property to stop sending of CSS styles
+- Fixed Shadow issue when no transition style specified
+- Fixed problem with sending duplicate styles down after postback
+- renamed attributes to be under 15 characters to allow
+ getAttribute to work with Konqueror and Safari.
+ (SystemImagesPath --> SysImgPath)
+- Allowing Data binding to have non-numeric keys
+- Fixed positioning when window is scrolled
+- Updated Safari support
+- Fixed problem when SmartNavigation is turned on
+ - Problem: postback with SmartNav enabled does
+ not fire the readystate event
+ - Solution: when smartnav is enabled menu will
+ use setTimeout to continually poll
+ the page until readyState is complete
+
+==========================================================
+SolpartMenu v1.1.0.7 - Notes
+==========================================================
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Support for new Mac browser Safari
+ - Problem: Safari doesn't report offsetWidths/heights of some elements
+ - Solution: go to parent to get width/height
+ - Problem: Safari needs to include BODY when getting element positions via offsetTop/Left
+ - Solution: apparently only the root menu items need to include Body offset
+ - Problem: a bug in Safari where the HTMLcollection object returned for cells is always empty
+ - Solution: none, safari menus cannot display selected border colors until its resolved by safari development team.
+ this has been entered into the Safari bug tracking system (#3426081)
+
+- Added new property MenuItems to access collection of SPMenuItemNode
+- Added script to handle lack of events firing when SmartNavigation is enabled
+
+
+
+==========================================================
+SolpartMenu v1.1.0.6 - Notes
+==========================================================
+I just realized that you may want the source of the menu
+that is used in the DNN menu designer. Thus, am doing this
+minor release.
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- using SafeClientID property to render menu (fixes IDs starting with _)
+- attempting to fix Safari (not there yet)
+
+
+==========================================================
+SolpartMenu v1.1 - Notes
+==========================================================
+
+----------------------------------------------------------
+Enhancements
+----------------------------------------------------------
+- Introduced wrapper class around Menu Item XMLNode called SPMenuItemNode to ease programming of attributes.
+- Downlevel browser appearance has been updated to handle new properties, including placing icons on menu bar (also supported on uplevel browsers)
+- Added ability to render UpLevel menu in browser without an XML parser using JS array
+- Added Menu designer - see comments in code to help out integrating with DNN
+- Added ALT tags to images to improve ADA compliance
+
+
+----------------------------------------------------------
+Properties of interest
+----------------------------------------------------------
+- Menu Object
+-- IconImagesPath Location of the icon images (in DNN this would be the GUID location) if not specified defaults to SystemImagePath
+-- SystemImagesPath Location of the images specific to the rendering of the menu (i.e. spacer.gif)
+-- MenuBarLeftHTML - allows custom HTML to be placed to the left of the menu bar
+-- MenuBarRightHTML - allows custom HTML to be placed to the right of the menu bar
+-- MenuCSSPlaceHolderControl - allows a placeholder tag to be specified so menu's css properties can be set within the tag.
+
+-MenuItem Object
+-- ImagePath If icon is not coming from the IconImagesPath then specify a path here. This is for admin icons.
+-- LeftHTML Allows for a custom HTML to be displayed to the left of the menuitems Title.
+-- RightHTML Allows for a custom HTML to be displayed to the right of the menuitems Title. This is for the selected menu item image.
+
+
+
+----------------------------------------------------------
+The following browsers will render the UpLevel menu
+----------------------------------------------------------
+IE 5.0 - uses JSXMLArray
+IE5.5 - uses XML DataIslands (for superior caching)
+IE6 - uses XML DataIslands (for superior caching)
+Mozilla (Mac/Win/Linux) - uses XML Parser
+Netscape 6 (Mac/Win/Linux) - uses XML Parser
+Netscape 7 (Mac/Win/Linux) - uses XML Parser
+Opera 7 (Win/Linux) - uses JSXMLArray - DNN HTML Layout issues causes transparent menus
+Konqueror(Linux) - minor positioning issues
+Safari (Mac) - trying...
+
+----------------------------------------------------------
+The following browsers will render the DownLevel menu
+----------------------------------------------------------
+IE5 (Mac) - Absolute positioning issues
+NS 4 -
+Opera 6 -
+Any other browser -
+
+
+----------------------------------------------------------
+IMPORTANT! MenuCSSPlaceHolderControl
+----------------------------------------------------------
+I have added a property called MenuCSSPlaceHolderControl which is set to SPMenuStyle. This allows the menu's
+CSS style to be inserted at the desired location within the tag. It is highly
+recommended that you place the following tag within the section.
+
+Failure to do so will result in the menu placing its style at the very beginning of the output stream,
+which I believe is not valid in some browsers.
+
+
+----------------------------------------------------------
+Fixes
+----------------------------------------------------------
+- Fixed registering of systemscript so only sends down once
+- Fixed 1 pixel jump to right on entry of submenu, was due to the menu not having a border set. Now am checking this before applying left border on icon.
+- Fixed issue with border on root arrow
+- Fixed style issue for netscape 4
+
+
+
+----------------------------------------------------------
+IE For the Mac
+----------------------------------------------------------
+Well what can I say? After many attempts at getting this to work in an uplevel fashion I have
+made some headway but not enough. I have determined that this is not going to hold up my release
+any longer, so for now the menu will render downlevel. On a positive note I have determined
+what was causing the css not to render properly (extra spaces in the class property). Unfortunately,
+I have not been able to resolve the positioning yet (you should only need to modify the spm_elementTop
+and spm_elementLeft functions in the .js file). I want to say thank you to everyone who has
+helped out with this issue, especially Davor and Erin.
+
+
+
diff --git a/DNN Platform/Controls/SolpartMenu/SPMenuCaps.config b/DNN Platform/Controls/SolpartMenu/SPMenuCaps.config
new file mode 100644
index 00000000000..30754e38ba5
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/SPMenuCaps.config
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Controls/SolpartMenu/Solution Partners ASP.NET Hierarchical Menu.doc b/DNN Platform/Controls/SolpartMenu/Solution Partners ASP.NET Hierarchical Menu.doc
new file mode 100644
index 00000000000..d387aa9e0b1
Binary files /dev/null and b/DNN Platform/Controls/SolpartMenu/Solution Partners ASP.NET Hierarchical Menu.doc differ
diff --git a/DNN Platform/Controls/SolpartMenu/spmenu.js b/DNN Platform/Controls/SolpartMenu/spmenu.js
new file mode 100644
index 00000000000..013fd4ab71b
--- /dev/null
+++ b/DNN Platform/Controls/SolpartMenu/spmenu.js
@@ -0,0 +1,2134 @@
+//------------------------------------------------------//
+// Solution Partner's ASP.NET Hierarchical Menu Control //
+// Copyright (c) 2002-2010 //
+// Jon Henning - Solution Partner's Inc //
+// jhenning@solpart.com - http://www.solpart.com //
+// Compatible Menu Version: //
+// //
+// \r\n");
+ cs.RegisterClientScriptBlock(GetType(), scriptName, scriptBuilder.ToString());
+ }
+ }
+ }
+
+ protected override object SaveControlState()
+ {
+ return _itemCount > 0 ? (object) _itemCount : null;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormEmptyTemplate.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormEmptyTemplate.cs
new file mode 100644
index 00000000000..caaaf9f407f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormEmptyTemplate.cs
@@ -0,0 +1,41 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnFormEmptyTemplate : WebControl, INamingContainer
+ {
+ protected override HtmlTextWriterTag TagKey
+ {
+ get
+ {
+ return HtmlTextWriterTag.Div;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormEnumItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormEnumItem.cs
new file mode 100644
index 00000000000..1063ed38f6d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormEnumItem.cs
@@ -0,0 +1,58 @@
+#region Copyright
+
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+using System;
+using System.Linq;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormEnumItem : DnnFormComboBoxItem
+ {
+ private string _enumType;
+
+ public string EnumType
+ {
+ get
+ {
+ return _enumType;
+ }
+ set
+ {
+ _enumType = value;
+ // ReSharper disable AssignNullToNotNullAttribute
+ ListSource = (from object enumValue in Enum.GetValues(Type.GetType(_enumType))
+ select new { Name = Enum.GetName(Type.GetType(_enumType), enumValue), Value = (int)enumValue })
+ .ToList();
+ // ReSharper restore AssignNullToNotNullAttribute
+ }
+ }
+
+ protected override void BindList()
+ {
+ ListTextField = "Name";
+ ListValueField = "Value";
+
+ BindListInternal(ComboBox, Convert.ToInt32(Value), ListSource, ListTextField, ListValueField);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormItemBase.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormItemBase.cs
new file mode 100644
index 00000000000..1a9aa1a6d03
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormItemBase.cs
@@ -0,0 +1,447 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+#region Usings
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Collections;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public abstract class DnnFormItemBase : WebControl, INamingContainer
+ {
+ private object _value;
+ private string _requiredMessageSuffix = ".Required";
+ private string _validationMessageSuffix = ".RegExError";
+
+ protected DnnFormItemBase()
+ {
+ FormMode = DnnFormMode.Inherit;
+ IsValid = true;
+
+ Validators = new List();
+ }
+
+ #region Protected Properties
+
+ protected PropertyInfo ChildProperty
+ {
+ get
+ {
+ Type type = Property.PropertyType;
+ IList props = new List(type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static));
+ return props.SingleOrDefault(p => p.Name == DataField);
+ }
+ }
+
+ protected PortalSettings PortalSettings
+ {
+ get { return PortalController.GetCurrentPortalSettings(); }
+ }
+
+ protected PropertyInfo Property
+ {
+ get
+ {
+ Type type = DataSource.GetType();
+ IList props = new List(type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static));
+ return !String.IsNullOrEmpty(DataMember)
+ ? props.SingleOrDefault(p => p.Name == DataMember)
+ : props.SingleOrDefault(p => p.Name == DataField);
+ }
+ }
+
+ protected override HtmlTextWriterTag TagKey
+ {
+ get
+ {
+ return HtmlTextWriterTag.Div;
+ }
+ }
+
+ public object Value
+ {
+ get { return _value; }
+ set { _value = value; }
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ public string DataField { get; set; }
+
+ public string DataMember { get; set; }
+
+ internal object DataSource { get; set; }
+
+ public DnnFormMode FormMode { get; set; }
+
+ public bool IsValid { get; private set; }
+
+ public string OnClientClicked { get; set; }
+
+ public string LocalResourceFile { get; set; }
+
+ public bool Required { get; set; }
+
+ public string ResourceKey { get; set; }
+
+ public string RequiredMessageSuffix
+ {
+ get
+ {
+ return _requiredMessageSuffix;
+ }
+ set
+ {
+ _requiredMessageSuffix = value;
+ }
+ }
+
+ public string ValidationMessageSuffix
+ {
+ get
+ {
+ return _validationMessageSuffix;
+ }
+ set
+ {
+ _validationMessageSuffix = value;
+ }
+ }
+
+ [Category("Behavior"), PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public List Validators { get; private set; }
+
+ public string ValidationExpression { get; set; }
+
+ #endregion
+
+ #region Control Hierarchy and Data Binding
+
+ private void AddValidators(string controlId)
+ {
+ var value = Value as String;
+ Validators.Clear();
+
+ //Add Validators
+ if (Required)
+ {
+ var requiredValidator = new RequiredFieldValidator
+ {
+ ID = ID + "_Required",
+ ErrorMessage = ResourceKey + RequiredMessageSuffix
+ };
+ if (String.IsNullOrEmpty(value) && Page.IsPostBack)
+ {
+ requiredValidator.IsValid = false;
+ IsValid = requiredValidator.IsValid;
+ }
+ Validators.Add(requiredValidator);
+ }
+
+ if (!String.IsNullOrEmpty(ValidationExpression))
+ {
+ var regexValidator = new RegularExpressionValidator
+ {
+ ID = ID + "_RegEx",
+ ErrorMessage = ResourceKey + ValidationMessageSuffix,
+ ValidationExpression = ValidationExpression
+ };
+ if (!String.IsNullOrEmpty(value))
+ {
+ regexValidator.IsValid = Regex.IsMatch(value, ValidationExpression);
+ IsValid = regexValidator.IsValid;
+ }
+ Validators.Add(regexValidator);
+ }
+
+ if (Validators.Count > 0)
+ {
+ foreach (BaseValidator validator in Validators)
+ {
+ validator.ControlToValidate = controlId;
+ validator.Display = ValidatorDisplay.Dynamic;
+ validator.ErrorMessage = LocalizeString(validator.ErrorMessage);
+ validator.CssClass = "dnnFormMessage dnnFormError";
+ Controls.Add(validator);
+ }
+ }
+ }
+
+ public void CheckIsValid()
+ {
+ IsValid = true;
+ foreach (BaseValidator validator in Validators)
+ {
+ validator.Validate();
+ if (!validator.IsValid)
+ {
+ IsValid = false;
+ break;
+ }
+ }
+ }
+
+ protected virtual void CreateControlHierarchy()
+ {
+ //Load Item Style
+ CssClass = "dnnFormItem";
+ CssClass += (FormMode == DnnFormMode.Long) ? "" : " dnnFormShort";
+
+ if (String.IsNullOrEmpty(ResourceKey))
+ {
+ ResourceKey = DataField;
+ }
+
+ //Add Label
+ var label = new DnnFormLabel
+ {
+ LocalResourceFile = LocalResourceFile,
+ ResourceKey = ResourceKey + ".Text",
+ ToolTipKey = ResourceKey + ".Help"
+ };
+
+ if (Required) {
+
+ label.RequiredField = true;
+ }
+
+ Controls.Add(label);
+
+ WebControl inputControl = CreateControlInternal(this);
+ label.AssociatedControlID = inputControl.ID;
+ AddValidators(inputControl.ID);
+ }
+
+ ///
+ /// Use container to add custom control hierarchy to
+ ///
+ ///
+ /// An "input" control that can be used for attaching validators
+ protected virtual WebControl CreateControlInternal(Control container)
+ {
+ return null;
+ }
+
+ protected override void CreateChildControls()
+ {
+ // CreateChildControls re-creates the children (the items)
+ // using the saved view state.
+ // First clear any existing child controls.
+ Controls.Clear();
+
+ CreateControlHierarchy();
+ }
+
+ protected void DataBindInternal(string dataField, ref object value)
+ {
+ var dictionary = DataSource as IDictionary;
+ if (dictionary != null)
+ {
+ if (!String.IsNullOrEmpty(dataField) && dictionary.Contains(dataField))
+ {
+ value = dictionary[dataField];
+ }
+ }
+ else
+ {
+ if (!String.IsNullOrEmpty(dataField))
+ {
+ if (String.IsNullOrEmpty(DataMember))
+ {
+ if (Property != null && Property.GetValue(DataSource, null) != null)
+ {
+ // ReSharper disable PossibleNullReferenceException
+ value = Property.GetValue(DataSource, null);
+ // ReSharper restore PossibleNullReferenceException
+ }
+ }
+ else
+ {
+ if (Property != null && Property.GetValue(DataSource, null) != null)
+ {
+ // ReSharper disable PossibleNullReferenceException
+ object parentValue = Property.GetValue(DataSource, null);
+ if (ChildProperty != null && ChildProperty.GetValue(parentValue, null) != null)
+ {
+ value = ChildProperty.GetValue(parentValue, null);
+ }
+ // ReSharper restore PossibleNullReferenceException
+ }
+ }
+ }
+ }
+ }
+
+ protected virtual void DataBindInternal()
+ {
+ DataBindInternal(DataField, ref _value);
+ }
+
+ public void DataBindItem(bool useDataSource)
+ {
+ if (useDataSource)
+ {
+ base.OnDataBinding(EventArgs.Empty);
+ Controls.Clear();
+ ClearChildViewState();
+ TrackViewState();
+
+ DataBindInternal();
+
+ CreateControlHierarchy();
+ ChildControlsCreated = true;
+ }
+ else
+ {
+ if (!String.IsNullOrEmpty(DataField))
+ {
+ UpdateDataSourceInternal(null, _value, DataField);
+ }
+ }
+ }
+
+ private void UpdateDataSourceInternal(object oldValue, object newValue, string dataField)
+ {
+ if (DataSource != null)
+ {
+ if (DataSource is IDictionary)
+ {
+ var dictionary = DataSource as IDictionary;
+ if (dictionary.ContainsKey(dataField) && !ReferenceEquals(newValue, oldValue))
+ {
+ dictionary[dataField] = newValue as string;
+ }
+ }
+ else if(DataSource is IIndexable)
+ {
+ var indexer = DataSource as IIndexable;
+ indexer[dataField] = newValue;
+ }
+ else
+ {
+ if (String.IsNullOrEmpty(DataMember))
+ {
+ if (Property != null)
+ {
+ if (!ReferenceEquals(newValue, oldValue))
+ {
+ if (Property.PropertyType.IsEnum)
+ {
+ Property.SetValue(DataSource, Enum.Parse(Property.PropertyType, newValue.ToString()), null);
+ }
+ else
+ {
+ Property.SetValue(DataSource, Convert.ChangeType(newValue, Property.PropertyType), null);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (Property != null)
+ {
+ object parentValue = Property.GetValue(DataSource, null);
+ if (parentValue != null)
+ {
+ if (parentValue is IDictionary)
+ {
+ var dictionary = parentValue as IDictionary;
+ if (dictionary.ContainsKey(dataField) && !ReferenceEquals(newValue, oldValue))
+ {
+ dictionary[dataField] = newValue as string;
+ }
+ }
+ else if (parentValue is IIndexable)
+ {
+ var indexer = parentValue as IIndexable;
+ indexer[dataField] = newValue;
+ }
+ else if (ChildProperty != null)
+ {
+ if (Property.PropertyType.IsEnum)
+ {
+ ChildProperty.SetValue(parentValue, Enum.Parse(ChildProperty.PropertyType, newValue.ToString()), null);
+ }
+ else
+ {
+ ChildProperty.SetValue(parentValue, Convert.ChangeType(newValue, ChildProperty.PropertyType), null);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected void UpdateDataSource(object oldValue, object newValue, string dataField)
+ {
+ CheckIsValid();
+
+ _value = newValue;
+
+ UpdateDataSourceInternal(oldValue, newValue, dataField);
+ }
+
+ #endregion
+
+ #region Protected Methods
+
+ protected override void LoadControlState(object state)
+ {
+ _value = state;
+ }
+
+ protected string LocalizeString(string key)
+ {
+ return Localization.GetString(key, LocalResourceFile);
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ Page.RegisterRequiresControlState(this);
+ base.OnInit(e);
+ }
+
+ protected override object SaveControlState()
+ {
+ return _value;
+ }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormLabel.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormLabel.cs
new file mode 100644
index 00000000000..b0067f4f9d2
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormLabel.cs
@@ -0,0 +1,106 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Framework;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.UI.UserControls;
+using DotNetNuke.UI.Utilities;
+using DotNetNuke.Web.Client.ClientResourceManagement;
+
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormLabel : Panel
+ {
+ public string AssociatedControlID { get; set; }
+
+ public string LocalResourceFile { get; set; }
+
+ public string ResourceKey { get; set; }
+
+ public string ToolTipKey { get; set; }
+
+ public bool RequiredField { get; set; }
+
+ protected override void CreateChildControls()
+ {
+ string toolTipText = LocalizeString(ToolTipKey);
+ if (string.IsNullOrEmpty(CssClass))
+ CssClass = "dnnLabel";
+
+ else if (!CssClass.Contains("dnnLabel"))
+ CssClass += " dnnLabel";
+
+
+ //var outerPanel = new Panel();
+ //outerPanel.CssClass = "dnnLabel";
+ //Controls.Add(outerPanel);
+
+ var outerLabel = new System.Web.UI.HtmlControls.HtmlGenericControl { TagName = "label" };
+ Controls.Add(outerLabel);
+
+ var label = new Label { ID = "Label", Text = LocalizeString(ResourceKey) };
+ if (RequiredField)
+ {
+ label.CssClass += " dnnFormRequired";
+ }
+ outerLabel.Controls.Add(label);
+
+ var link = new LinkButton { ID = "Link", CssClass = "dnnFormHelp", TabIndex = -1 };
+ Controls.Add(link);
+
+ if (!String.IsNullOrEmpty(toolTipText))
+ {
+ //CssClass += "dnnLabel";
+
+ var tooltipPanel = new Panel() { CssClass = "dnnTooltip"};
+ Controls.Add(tooltipPanel);
+
+ var panel = new Panel { ID = "Help", CssClass = "dnnFormHelpContent dnnClear" };
+ tooltipPanel.Controls.Add(panel);
+
+ var helpLabel = new Label { ID = "Text", CssClass="dnnHelpText", Text = LocalizeString(ToolTipKey) };
+ panel.Controls.Add(helpLabel);
+
+ var pinLink = new HyperLink {CssClass = "pinHelp"};
+ pinLink.Attributes.Add("href", "#");
+ panel.Controls.Add(pinLink);
+
+ ClientAPI.RegisterClientReference(Page, ClientAPI.ClientNamespaceReferences.dnn);
+ jQuery.RequestHoverIntentRegistration();
+ jQuery.RequestDnnPluginsRegistration();
+ //ClientResourceManager.RegisterScript(this.Page, "~/Resources/Shared/Scripts/initTooltips.js");
+ }
+ }
+
+ protected string LocalizeString(string key)
+ {
+ return Localization.GetString(key, LocalResourceFile);
+ }
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormListItemBase.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormListItemBase.cs
new file mode 100644
index 00000000000..7030bab54e1
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormListItemBase.cs
@@ -0,0 +1,59 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Collections;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public abstract class DnnFormListItemBase : DnnFormItemBase
+ {
+ private IEnumerable _listSource;
+
+ public string DefaultValue { get; set; }
+
+ public IEnumerable ListSource
+ {
+ get
+ {
+ return _listSource;
+ }
+ set
+ {
+ if (_listSource != value)
+ {
+ _listSource = value;
+ BindList();
+ }
+ }
+ }
+
+ public string ListTextField { get; set; }
+
+ public string ListValueField { get; set; }
+
+ protected virtual void BindList()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormLiteralItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormLiteralItem.cs
new file mode 100644
index 00000000000..6ca180eaf15
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormLiteralItem.cs
@@ -0,0 +1,40 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormLiteralItem : DnnFormItemBase
+ {
+ protected override WebControl CreateControlInternal(Control container)
+ {
+ var literal = new Label {ID = ID + "_Label", Text = Convert.ToString(Value)};
+ container.Controls.Add(literal);
+ return literal;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormMode.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormMode.cs
new file mode 100644
index 00000000000..88775a8682a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormMode.cs
@@ -0,0 +1,29 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public enum DnnFormMode
+ {
+ Inherit = 0,
+ Short = 1,
+ Long = 2
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormNumericTextBoxItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormNumericTextBoxItem.cs
new file mode 100644
index 00000000000..54e5c817b0e
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormNumericTextBoxItem.cs
@@ -0,0 +1,92 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Framework;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormNumericTextBoxItem : DnnFormItemBase
+ {
+ //private DnnNumericTextBox _textBox;
+ private TextBox _textBox;
+
+ public DnnFormNumericTextBoxItem()
+ {
+ TextBoxWidth = new Unit(100);
+ ShowSpinButtons = true;
+ Type = NumericType.Number;
+ DecimalDigits = 0;
+ }
+
+ public int DecimalDigits { get; set; }
+
+ public bool ShowSpinButtons { get; set; }
+
+ public Unit TextBoxWidth { get; set; }
+
+ public NumericType Type { get; set; }
+
+ private void TextChanged(object sender, EventArgs e)
+ {
+ UpdateDataSource(Value, _textBox.Text, DataField);
+ }
+
+ protected override WebControl CreateControlInternal(Control container)
+ {
+ //_textBox = new DnnNumericTextBox {EmptyMessage = LocalizeString(ResourceKey + ".Hint"), ID = ID + "_TextBox", Width = TextBoxWidth };
+ _textBox = new TextBox();
+ _textBox.CssClass = "DnnNumericTextBox";
+ //_textBox.Style.Add("float", "none");
+ //_textBox.EmptyMessageStyle.CssClass += "dnnformHint";
+ //_textBox.Type = Type;
+ //_textBox.NumberFormat.DecimalDigits = DecimalDigits;
+ //_textBox.ShowSpinButtons = ShowSpinButtons;
+ _textBox.TextChanged += TextChanged;
+
+ //Load from ControlState
+ _textBox.Text = Convert.ToString(Value);
+
+ container.Controls.Add(_textBox);
+ jQuery.RegisterDnnJQueryPlugins(this.Page);
+
+ var initalizeScript = "";
+ Page.ClientScript.RegisterClientScriptBlock(GetType(), "DnnFormNumericTextBoxItem", initalizeScript);
+
+ return _textBox;
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ FormMode = DnnFormMode.Short;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPagesItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPagesItem.cs
new file mode 100644
index 00000000000..f3bb15694bb
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPagesItem.cs
@@ -0,0 +1,39 @@
+#region Copyright
+
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Services.Localization;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormPagesItem : DnnFormComboBoxItem
+ {
+ public DnnFormPagesItem()
+ {
+ ListSource = TabController.GetPortalTabs(PortalSettings.PortalId, Null.NullInteger, true, "<" + Localization.GetString("None_Specified") + ">", true, false, true, true, false);
+ ListTextField = "TabName";
+ ListValueField = "TabID";
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPanel.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPanel.cs
new file mode 100644
index 00000000000..49f1e47b063
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPanel.cs
@@ -0,0 +1,56 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormPanel : WebControl
+ {
+
+ public bool Expanded { get; set; }
+
+ public string Text { get; set; }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
+ writer.RenderBeginTag(HtmlTextWriterTag.H2);
+
+ if (Expanded)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "dnnSectionExpanded");
+ }
+ writer.RenderBeginTag(HtmlTextWriterTag.A);
+ writer.Write(Text);
+ writer.RenderEndTag();
+
+ writer.RenderEndTag();
+
+ writer.RenderBeginTag(HtmlTextWriterTag.Fieldset);
+
+ RenderChildren(writer);
+
+ writer.RenderEndTag();
+ }
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPasswordItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPasswordItem.cs
new file mode 100644
index 00000000000..a178e8d04e7
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormPasswordItem.cs
@@ -0,0 +1,128 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Framework;
+using DotNetNuke.Web.Client.ClientResourceManagement;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormPasswordItem : DnnFormItemBase
+ {
+ private TextBox _password;
+
+ public string TextBoxCssClass
+ {
+ get
+ {
+ return ViewState.GetValue("TextBoxCssClass", string.Empty);
+ }
+ set
+ {
+ ViewState.SetValue("TextBoxCssClass", value, string.Empty);
+ }
+ }
+
+ public string ContainerCssClass
+ {
+ get
+ {
+ return ViewState.GetValue("ContainerCssClass", string.Empty);
+ }
+ set
+ {
+ ViewState.SetValue("ContainerCssClass", value, string.Empty);
+ }
+ }
+
+ private void TextChanged(object sender, EventArgs e)
+ {
+ UpdateDataSource(Value, _password.Text, DataField);
+ }
+
+ ///
+ /// Use container to add custom control hierarchy to
+ ///
+ ///
+ /// An "input" control that can be used for attaching validators
+ protected override WebControl CreateControlInternal(Control container)
+ {
+ _password = new TextBox()
+ {
+ ID = ID + "_TextBox",
+ TextMode = TextBoxMode.Password,
+ CssClass = TextBoxCssClass,
+ MaxLength = 20, //ensure password cannot be cut if too long
+ Text = Convert.ToString(Value) // Load from ControlState
+ };
+ _password.TextChanged += TextChanged;
+
+ var passwordContainer = new Panel() { ID = "passwordContainer", CssClass = ContainerCssClass };
+
+ // add control hierarchy to the container
+ container.Controls.Add(passwordContainer);
+
+ passwordContainer.Controls.Add(_password);
+
+ // return input control that can be used for validation
+ return _password;
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ ClientResourceManager.RegisterScript(Page, "~/Resources/Shared/scripts/dnn.jquery.extensions.js");
+ ClientResourceManager.RegisterScript(Page, "~/Resources/Shared/scripts/dnn.jquery.tooltip.js");
+ ClientResourceManager.RegisterScript(Page, "~/Resources/Shared/scripts/dnn.PasswordStrength.js");
+
+ jQuery.RequestDnnPluginsRegistration();
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ var options = new DnnPaswordStrengthOptions();
+ var optionsAsJsonString = Json.Serialize(options);
+ var script = string.Format("dnn.initializePasswordStrength('.{0}', {1});{2}",
+ TextBoxCssClass, optionsAsJsonString, Environment.NewLine);
+
+ if (ScriptManager.GetCurrent(Page) != null)
+ {
+ // respect MS AJAX
+ ScriptManager.RegisterStartupScript(Page, GetType(), "PasswordStrength", script, true);
+ }
+ else
+ {
+ Page.ClientScript.RegisterStartupScript(GetType(), "PasswordStrength", script, true);
+ }
+
+ }
+
+ }
+
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormRadioButtonListItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormRadioButtonListItem.cs
new file mode 100644
index 00000000000..815a18003d1
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormRadioButtonListItem.cs
@@ -0,0 +1,93 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormRadioButtonListItem : DnnFormListItemBase
+ {
+ private RadioButtonList _radioButtonList;
+
+ protected override void BindList()
+ {
+ if (_radioButtonList != null)
+ {
+ string selectedValue = !_radioButtonList.Page.IsPostBack ? Convert.ToString(Value) : _radioButtonList.Page.Request.Form[_radioButtonList.UniqueID];
+
+ if (ListSource is Dictionary)
+ {
+ var items = ListSource as Dictionary;
+ foreach (var item in items)
+ {
+ var listItem = new ListItem(item.Key, item.Value);
+ listItem.Attributes.Add("onClick", OnClientClicked);
+
+ _radioButtonList.Items.Add(listItem);
+ }
+ }
+ else
+ {
+ _radioButtonList.DataTextField = ListTextField;
+ _radioButtonList.DataValueField = ListValueField;
+ _radioButtonList.DataSource = ListSource;
+
+ _radioButtonList.DataBind();
+ }
+ if (String.IsNullOrEmpty(selectedValue))
+ {
+ selectedValue = DefaultValue;
+ }
+
+ //Reset SelectedValue
+ if (_radioButtonList.Items.FindByValue(selectedValue) != null)
+ {
+ _radioButtonList.Items.FindByValue(selectedValue).Selected = true;
+ }
+
+ if (selectedValue != Convert.ToString(Value))
+ {
+ UpdateDataSource(Value, selectedValue, DataField);
+ }
+ }
+ }
+
+ protected override WebControl CreateControlInternal(Control container)
+ {
+ _radioButtonList = new RadioButtonList { ID = ID + "_RadioButtonList", RepeatColumns = 1, RepeatDirection = RepeatDirection.Vertical, RepeatLayout = RepeatLayout.Flow};
+
+ container.Controls.Add(_radioButtonList);
+
+ if (ListSource != null)
+ {
+ BindList();
+ }
+
+ return _radioButtonList;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSection.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSection.cs
new file mode 100644
index 00000000000..7fb5d721581
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSection.cs
@@ -0,0 +1,47 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnFormSection : WebControl, INamingContainer
+ {
+ public DnnFormSection()
+ {
+ Items = new List();
+ }
+
+ public bool Expanded { get; set; }
+
+ [Category("Behavior"), PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public List Items { get; private set; }
+
+ public string ResourceKey { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSectionTemplate.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSectionTemplate.cs
new file mode 100644
index 00000000000..a7237a40128
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSectionTemplate.cs
@@ -0,0 +1,55 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Collections.Generic;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ internal class DnnFormSectionTemplate : ITemplate
+ {
+ public DnnFormSectionTemplate()
+ {
+ Items = new List();
+ }
+
+ public List Items { get; private set; }
+
+ public string LocalResourceFile { get; set; }
+
+ #region ITemplate Members
+
+ public void InstantiateIn(Control container)
+ {
+ var webControl = container as WebControl;
+ if (webControl != null)
+ {
+ DnnFormEditor.SetUpItems(Items, webControl, LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSkinsItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSkinsItem.cs
new file mode 100644
index 00000000000..4047e3614dd
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormSkinsItem.cs
@@ -0,0 +1,135 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.UI.Skins;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormSkinsItem : DnnFormItemBase
+ {
+ //private DropDownList _containerCombo;
+ private DnnComboBox _containerCombo;
+ private object _containerValue;
+ //private DropDownList _skinCombo;
+ private DnnComboBox _skinCombo;
+ private object _skinValue;
+
+ public string ContainerDataField { get; set; }
+
+ public bool IncludePortalSkins { get; set; }
+
+ public int PortalId { get; set; }
+
+ public string SkinDataField { get; set; }
+
+ private void ContainerIndexChanged(object sender, EventArgs e)
+ {
+ UpdateDataSource(_containerValue, _containerCombo.SelectedValue, ContainerDataField);
+ }
+
+ private void SkinIndexChanged(object sender, EventArgs e)
+ {
+ UpdateDataSource(_skinValue, _skinCombo.SelectedValue, SkinDataField);
+ }
+
+ private Dictionary GetSkins(string skinRoot)
+ {
+ // load host skins
+ var skins = SkinController.GetSkins(null, skinRoot, SkinScope.Host).ToDictionary(skin => skin.Key, skin => skin.Value);
+
+ if (IncludePortalSkins)
+ {
+ // load portal skins
+ var portalController = new PortalController();
+ var portal = portalController.GetPortal(PortalId);
+
+ foreach (var skin in SkinController.GetSkins(portal, skinRoot, SkinScope.Site))
+ {
+ skins.Add(skin.Key, skin.Value);
+ }
+ }
+ return skins;
+ }
+
+ protected override WebControl CreateControlInternal(Control container)
+ {
+ var panel = new Panel();
+
+ container.Controls.Add(panel);
+
+ var skinLabel = new Label { Text = LocalizeString("Skin") };
+ skinLabel.CssClass += "dnnFormSkinLabel";
+ panel.Controls.Add(skinLabel);
+
+ //_skinCombo = new DropDownList { ID = ID + "_SkinComboBox" };
+ _skinCombo = new DnnComboBox { ID = ID + "_SkinComboBox" };
+ _skinCombo.CssClass += "dnnFormSkinInput";
+ _skinCombo.SelectedIndexChanged += SkinIndexChanged;
+ panel.Controls.Add(_skinCombo);
+
+ DnnFormComboBoxItem.BindListInternal(_skinCombo, _skinValue, GetSkins(SkinController.RootSkin), "Key", "Value");
+
+ var containerLabel = new Label { Text = LocalizeString("Container") };
+ containerLabel.CssClass += "dnnFormSkinLabel";
+ panel.Controls.Add(containerLabel);
+
+ //_containerCombo = new DropDownList { ID = ID + "_ContainerComboBox" };
+ _containerCombo = new DnnComboBox { ID = ID + "_ContainerComboBox" };
+ _containerCombo.CssClass += "dnnFormSkinInput";
+ _containerCombo.SelectedIndexChanged += ContainerIndexChanged;
+ panel.Controls.Add(_containerCombo);
+
+ DnnFormComboBoxItem.BindListInternal(_containerCombo, _containerValue, GetSkins(SkinController.RootContainer), "Key", "Value");
+
+ return panel;
+ }
+
+ protected override void DataBindInternal()
+ {
+ DataBindInternal(SkinDataField, ref _skinValue);
+
+ DataBindInternal(ContainerDataField, ref _containerValue);
+
+ Value = new Pair {First = _skinValue, Second = _containerValue};
+ }
+
+ protected override void LoadControlState(object state)
+ {
+ base.LoadControlState(state);
+ var pair = Value as Pair;
+ if (pair != null)
+ {
+ _skinValue = pair.First;
+ _containerValue = pair.Second;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTab.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTab.cs
new file mode 100644
index 00000000000..ec93219d656
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTab.cs
@@ -0,0 +1,53 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnFormTab : WebControl, INamingContainer
+ {
+ public DnnFormTab()
+ {
+ Sections = new List();
+ Items = new List();
+ }
+
+ public bool IncludeExpandAll { get; set; }
+
+ internal string ExpandAllScript { get; set; }
+
+ [Category("Behavior"), PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public List Items { get; private set; }
+
+ [Category("Behavior"), PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public List Sections { get; private set; }
+
+ public string ResourceKey { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTabStrip.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTabStrip.cs
new file mode 100644
index 00000000000..8506740ed52
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTabStrip.cs
@@ -0,0 +1,51 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormTabStrip : ListControl
+ {
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
+ writer.RenderBeginTag(HtmlTextWriterTag.Ul);
+
+ foreach (ListItem item in Items)
+ {
+ writer.RenderBeginTag(HtmlTextWriterTag.Li);
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Href, item.Value);
+ writer.RenderBeginTag(HtmlTextWriterTag.A);
+ writer.Write(item.Text);
+
+ writer.RenderEndTag();
+
+ writer.RenderEndTag();
+ }
+
+ writer.RenderEndTag();
+ }
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTemplateItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTemplateItem.cs
new file mode 100644
index 00000000000..2b282f61148
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTemplateItem.cs
@@ -0,0 +1,47 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.ComponentModel;
+using System.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnFormTemplateItem : DnnFormItemBase
+ {
+ [Browsable(false), DefaultValue(null), Description("The Item Template."), TemplateInstance(TemplateInstance.Single), PersistenceMode(PersistenceMode.InnerProperty),
+ TemplateContainer(typeof (DnnFormEmptyTemplate))]
+ public ITemplate ItemTemplate { get; set; }
+
+ protected override void CreateControlHierarchy()
+ {
+ CssClass += " dnnFormItem";
+ CssClass += (FormMode == DnnFormMode.Long) ? " dnnFormLong" : " dnnFormShort";
+
+ var template = new DnnFormEmptyTemplate();
+ ItemTemplate.InstantiateIn(template);
+ Controls.Add(template);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTextBoxItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTextBoxItem.cs
new file mode 100644
index 00000000000..f79200daf10
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormTextBoxItem.cs
@@ -0,0 +1,95 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormTextBoxItem : DnnFormItemBase
+ {
+ private TextBox _textBox;
+
+ public AutoCompleteType AutoCompleteType { get; set; }
+
+ public int Columns { get; set; }
+
+ public int Rows { get; set; }
+
+ public string TextBoxCssClass
+ {
+ get
+ {
+ return ViewState.GetValue("TextBoxCssClass", string.Empty);
+ }
+ set
+ {
+ ViewState.SetValue("TextBoxCssClass", value, string.Empty);
+ }
+ }
+
+ public TextBoxMode TextMode { get; set; }
+
+ private void TextChanged(object sender, EventArgs e)
+ {
+ UpdateDataSource(Value, _textBox.Text, DataField);
+ }
+
+ protected override WebControl CreateControlInternal(Control container)
+ {
+
+ _textBox = new TextBox { ID = ID + "_TextBox" };
+
+ _textBox.Rows = Rows;
+ _textBox.Columns = Columns;
+ _textBox.TextMode = TextMode;
+ _textBox.CssClass = TextBoxCssClass;
+ _textBox.AutoCompleteType = AutoCompleteType;
+ _textBox.TextChanged += TextChanged;
+
+ //Load from ControlState
+ _textBox.Text = Convert.ToString(Value);
+
+ container.Controls.Add(_textBox);
+
+ return _textBox;
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ if (TextMode == TextBoxMode.Password)
+ {
+ _textBox.Attributes.Add("value", Convert.ToString(Value));
+ }
+ }
+
+ }
+
+}
+
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormToggleButtonItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormToggleButtonItem.cs
new file mode 100644
index 00000000000..3f9741c61c9
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFormToggleButtonItem.cs
@@ -0,0 +1,111 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnFormToggleButtonItem : DnnFormItemBase
+ {
+ #region CheckBoxMode enum
+
+ public enum CheckBoxMode
+ {
+ TrueFalse = 0,
+ YN = 1,
+ YesNo = 2
+ }
+
+ #endregion
+
+ //private DnnRadButton _checkBox;
+ private CheckBox _checkBox;
+
+ public DnnFormToggleButtonItem()
+ {
+ Mode = CheckBoxMode.TrueFalse;
+ }
+
+ public CheckBoxMode Mode { get; set; }
+
+ private void CheckedChanged(object sender, EventArgs e)
+ {
+ string newValue;
+ switch (Mode)
+ {
+ case CheckBoxMode.YN:
+ newValue = (_checkBox.Checked) ? "Y" : "N";
+ break;
+ case CheckBoxMode.YesNo:
+ newValue = (_checkBox.Checked) ? "Yes" : "No";
+ break;
+ default:
+ newValue = (_checkBox.Checked) ? "true" : "false";
+ break;
+ }
+ UpdateDataSource(Value, newValue, DataField);
+ }
+
+ protected override WebControl CreateControlInternal(Control container)
+ {
+ //_checkBox = new DnnRadButton {ID = ID + "_CheckBox", ButtonType = RadButtonType.ToggleButton, ToggleType = ButtonToggleType.CheckBox, AutoPostBack = false};
+ _checkBox = new CheckBox{ ID = ID + "_CheckBox", AutoPostBack = false };
+
+ _checkBox.CheckedChanged += CheckedChanged;
+ container.Controls.Add(_checkBox);
+
+ //Load from ControlState
+ if (!_checkBox.Page.IsPostBack)
+ {
+ }
+ switch (Mode)
+ {
+ case CheckBoxMode.YN:
+ case CheckBoxMode.YesNo:
+ var stringValue = Value as string;
+ if (stringValue != null)
+ {
+ _checkBox.Checked = stringValue.ToUpperInvariant().StartsWith("Y");
+ }
+ break;
+ default:
+ _checkBox.Checked = Convert.ToBoolean(Value);
+ break;
+ }
+
+ return _checkBox;
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ FormMode = DnnFormMode.Short;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGenericHiddenField.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGenericHiddenField.cs
new file mode 100644
index 00000000000..64f3b0c219d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGenericHiddenField.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Specialized;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGenericHiddenField : HiddenField where T : class, new()
+ {
+
+ private T _typedValue = null;
+
+ private bool _isValueSerialized = false;
+ public T TypedValue
+ {
+ get
+ {
+ return _typedValue;
+ }
+ set
+ {
+ _typedValue = value;
+ _isValueSerialized = false;
+ }
+ }
+
+ public T TypedValueOrDefault
+ {
+ get
+ {
+ return TypedValue ?? (TypedValue = new T());
+ }
+ }
+
+ public bool HasValue
+ {
+ get { return _typedValue != null; }
+ }
+
+ protected override object SaveViewState()
+ {
+ // The _typedValue can be a composite class. To ensure that all the chnaged properties of
+ // this class are serialized we need to call the SerializeValue method.
+ SerializeValue();
+ return base.SaveViewState();
+ }
+
+ protected override void LoadViewState(object savedState)
+ {
+ base.LoadViewState(savedState);
+ SetTypedValue();
+ }
+
+ protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
+ {
+ var stateChanged = base.LoadPostData(postDataKey, postCollection);
+ if (stateChanged)
+ {
+ SetTypedValue();
+ }
+ return stateChanged;
+ }
+
+ private void SetTypedValue()
+ {
+ _typedValue = string.IsNullOrEmpty(Value) ? null : Json.Deserialize(Value);
+ }
+
+ private void EnsureValue()
+ {
+ if (!_isValueSerialized)
+ {
+ SerializeValue();
+ }
+ }
+
+ private void SerializeValue()
+ {
+ Value = _typedValue == null ? string.Empty : Json.Serialize(_typedValue);
+ _isValueSerialized = true;
+ }
+
+ protected override void TrackViewState()
+ {
+ // The _typedValue can be a composite class. To ensure that all the chnaged properties of
+ // this class are serialized we need to call the SerializeValue method.
+ SerializeValue();
+ base.TrackViewState();
+ }
+
+ public override void RenderControl(HtmlTextWriter writer)
+ {
+ EnsureValue();
+ base.RenderControl(writer);
+ }
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGrid.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGrid.cs
new file mode 100644
index 00000000000..1e10aef13ad
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGrid.cs
@@ -0,0 +1,84 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using DotNetNuke.Framework;
+
+#endregion
+
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGrid : RadGrid
+ {
+
+ #region public properties
+
+ public int ScreenRowNumber { get; set; }
+
+ public int RowHeight { get; set; }
+
+ #endregion
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ base.EnableEmbeddedBaseStylesheet = false;
+ Utilities.ApplySkin(this);
+ jQuery.RegisterDnnJQueryPlugins(this.Page);
+ if (string.IsNullOrEmpty(ClientSettings.ClientEvents.OnGridCreated))
+ {
+ ClientSettings.ClientEvents.OnGridCreated = "$.dnnGridCreated";
+ }
+
+ this.PreRender += new EventHandler(DnnGrid_PreRender);
+ }
+
+ void DnnGrid_PreRender(object sender, EventArgs e)
+ {
+ var items = this.MasterTableView.Items;
+ if (ScreenRowNumber == 0)
+ ScreenRowNumber = 15;
+
+ if (items.Count > ScreenRowNumber)
+ {
+ // need scroll
+ this.ClientSettings.Scrolling.AllowScroll = true;
+ this.ClientSettings.Scrolling.UseStaticHeaders = true;
+
+ if(RowHeight == 0)
+ RowHeight = 25;
+
+ this.ClientSettings.Scrolling.ScrollHeight = RowHeight * ScreenRowNumber;
+ }
+ else
+ {
+ this.ClientSettings.Scrolling.AllowScroll = false;
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridAttachmentColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridAttachmentColumn.cs
new file mode 100644
index 00000000000..7f1feced767
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridAttachmentColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridGroupSplitterColumn : GridGroupSplitterColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridGroupSplitterColumn dnnGridColumn = new DnnGridGroupSplitterColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridBinaryImageColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridBinaryImageColumn.cs
new file mode 100644
index 00000000000..64c3db38f95
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridBinaryImageColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridBinaryImageColumn : GridBinaryImageColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridBinaryImageColumn dnnGridColumn = new DnnGridBinaryImageColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridBoundColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridBoundColumn.cs
new file mode 100644
index 00000000000..143182fa59b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridBoundColumn.cs
@@ -0,0 +1,81 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridBoundColumn : GridBoundColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ DnnGridBoundColumn dnnGridColumn = new DnnGridBoundColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ GridHeaderItem headerItem = inItem as GridHeaderItem;
+ string columnName = DataField;
+ if (!Owner.AllowSorting)
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ else
+ {
+ LinkButton button = (LinkButton) headerItem[columnName].Controls[0];
+ button.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridButtonColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridButtonColumn.cs
new file mode 100644
index 00000000000..fa30101e44f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridButtonColumn.cs
@@ -0,0 +1,110 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridButtonColumn : GridButtonColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ DnnGridButtonColumn dnnGridColumn = new DnnGridButtonColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ /// -----------------------------------------------------------------------------
+ ///
+ /// The Icon Key to obtain ImageURL
+ ///
+ /// A String
+ /// -----------------------------------------------------------------------------
+ public string IconKey { get; set; }
+
+ /// -----------------------------------------------------------------------------
+ ///
+ /// The Icon Siz to obtain ImageURL
+ ///
+ /// A String
+ /// -----------------------------------------------------------------------------
+ public string IconSize { get; set; }
+
+ /// -----------------------------------------------------------------------------
+ ///
+ /// The Icon Style to obtain ImageURL
+ ///
+ /// A String
+ /// -----------------------------------------------------------------------------
+ public string IconStyle { get; set; }
+
+ public override string ImageUrl
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(base.ImageUrl))
+ base.ImageUrl = Entities.Icons.IconController.IconURL(IconKey, IconSize, IconStyle);
+
+ return base.ImageUrl;
+ }
+ set
+ {
+ base.ImageUrl = value;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridCalculatedColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridCalculatedColumn.cs
new file mode 100644
index 00000000000..102608c6bb7
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridCalculatedColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridCalculatedColumn : GridCalculatedColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridCalculatedColumn dnnGridColumn = new DnnGridCalculatedColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridCheckBoxColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridCheckBoxColumn.cs
new file mode 100644
index 00000000000..d976ccec893
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridCheckBoxColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridCheckBoxColumn : GridCheckBoxColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ DnnGridCheckBoxColumn dnnGridColumn = new DnnGridCheckBoxColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridClientSelectColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridClientSelectColumn.cs
new file mode 100644
index 00000000000..8434893ce42
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridClientSelectColumn.cs
@@ -0,0 +1,74 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridClientSelectColumn : GridClientSelectColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ var dnnGridColumn = new DnnGridClientSelectColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ if (! inItem.OwnerTableView.OwnerGrid.AllowMultiRowSelection)
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridColumn.cs
new file mode 100644
index 00000000000..ef3f15f11a2
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridColumn.cs
@@ -0,0 +1,86 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridColumn : GridColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ var dnnGridColumn = new DnnGridColumn();
+ dnnGridColumn.CopyBaseProperties(this);
+ dnnGridColumn.setHeaderText = HeaderText;
+ return dnnGridColumn;
+ }
+
+ private String _HeaderText;
+
+ public override string HeaderText
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(base.HeaderText))
+ base.HeaderText = Localization.GetString(string.Format("{0}.Header", _HeaderText), DotNetNuke.Web.UI.Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent));
+ return base.HeaderText;
+ }
+ set
+ {
+ _HeaderText = value;
+ base.HeaderText = "";
+ }
+ }
+
+ public String setHeaderText
+ {
+ set
+ {
+ base.HeaderText = value;
+ }
+ }
+
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDataItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDataItem.cs
new file mode 100644
index 00000000000..f5c3c6f7bb1
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDataItem.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridDataItem : GridDataItem
+ {
+ public DnnGridDataItem(GridTableView ownerTableView, int itemIndex, int dataSetIndex) : base(ownerTableView, itemIndex, dataSetIndex)
+ {
+ }
+
+ public DnnGridDataItem(GridTableView ownerTableView, int itemIndex, int dataSetIndex, GridItemType itemType) : base(ownerTableView, itemIndex, dataSetIndex, itemType)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDateTimeColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDateTimeColumn.cs
new file mode 100644
index 00000000000..c6627c3fa1c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDateTimeColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridDateTimeColumn : GridDateTimeColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridDateTimeColumn dnnGridColumn = new DnnGridDateTimeColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDropDownColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDropDownColumn.cs
new file mode 100644
index 00000000000..bd4051486d2
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridDropDownColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridDropDownColumn : GridDropDownColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridDropDownColumn dnnGridColumn = new DnnGridDropDownColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridEditColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridEditColumn.cs
new file mode 100644
index 00000000000..aa2fe36aeb1
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridEditColumn.cs
@@ -0,0 +1,57 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridEditColumn : GridEditCommandColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ DnnGridEditColumn dnnGridColumn = new DnnGridEditColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridEditFormSettings.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridEditFormSettings.cs
new file mode 100644
index 00000000000..aadbf0398d4
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridEditFormSettings.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridEditFormSettings : GridEditFormSettings
+ {
+ public DnnGridEditFormSettings(DnnGridTableView owner) : base(owner)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridExpandColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridExpandColumn.cs
new file mode 100644
index 00000000000..701cabb6582
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridExpandColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridExpandColumn : GridColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridExpandColumn dnnGridColumn = new DnnGridExpandColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridFooterItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridFooterItem.cs
new file mode 100644
index 00000000000..ca43a05dd54
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridFooterItem.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridFooterItem : GridFooterItem
+ {
+ public DnnGridFooterItem(GridTableView ownerTableView, int itemIndex, int dataSetIndex) : base(ownerTableView, itemIndex, dataSetIndex)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridGroupSplitterColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridGroupSplitterColumn.cs
new file mode 100644
index 00000000000..a2a01a8751b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridGroupSplitterColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridAttachmentColumn : GridAttachmentColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridAttachmentColumn dnnGridColumn = new DnnGridAttachmentColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHTMLEditorColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHTMLEditorColumn.cs
new file mode 100644
index 00000000000..170d0cc9dee
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHTMLEditorColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridHTMLEditorColumn : GridHTMLEditorColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridHTMLEditorColumn dnnGridColumn = new DnnGridHTMLEditorColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHeaderItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHeaderItem.cs
new file mode 100644
index 00000000000..a6ca00e5f30
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHeaderItem.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridHeaderItem : GridHeaderItem
+ {
+ public DnnGridHeaderItem(GridTableView ownerTableView, int itemIndex, int dataSetIndex) : base(ownerTableView, itemIndex, dataSetIndex)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHyperlinkColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHyperlinkColumn.cs
new file mode 100644
index 00000000000..a01daaa5fee
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridHyperlinkColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridHyperLinkColumn : GridHyperLinkColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridHyperLinkColumn dnnGridColumn = new DnnGridHyperLinkColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageColumn.cs
new file mode 100644
index 00000000000..fa49d57b72a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridImageColumn : GridImageColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ DnnGridImageColumn dnnGridColumn = new DnnGridImageColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageCommandColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageCommandColumn.cs
new file mode 100644
index 00000000000..20409e7123d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageCommandColumn.cs
@@ -0,0 +1,207 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Web;
+using System.Web.UI.WebControls;
+using DotNetNuke.Entities.Icons;
+using DotNetNuke.UI.WebControls;
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridImageCommandColumn : DnnGridTemplateColumn
+ {
+ private ImageCommandColumnEditMode _editMode = ImageCommandColumnEditMode.Command;
+ private bool _showImage = true;
+
+ private string _imageURL = string.Empty;
+
+ ///
+ /// Gets or sets the CommandName for the Column
+ ///
+ /// A String
+ public string CommandName { get; set; }
+
+
+ ///
+ /// EditMode for the Column
+ ///
+ /// A String
+ public ImageCommandColumnEditMode EditMode
+ {
+ get { return _editMode; }
+ set { _editMode = value; }
+ }
+
+
+ ///
+ /// Gets or sets the URL of the Image
+ ///
+ /// A String
+ public string ImageURL
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(_imageURL))
+ {
+ return _imageURL;
+ }
+
+ return IconController.IconURL(IconKey, IconSize, IconStyle);
+ }
+ set { _imageURL = value; }
+ }
+
+
+ ///
+ /// The Icon Key to obtain ImageURL
+ ///
+ /// A String
+ public string IconKey { get; set; }
+
+
+ ///
+ /// The Icon Siz to obtain ImageURL
+ ///
+ /// A String
+ public string IconSize { get; set; }
+
+
+ ///
+ /// The Icon Style to obtain ImageURL
+ ///
+ /// A String
+ public string IconStyle { get; set; }
+
+
+ ///
+ /// The Key Field that provides a Unique key to the data Item
+ ///
+ /// A String
+ public string KeyField { get; set; }
+
+
+ ///
+ /// Gets or sets the URL of the Link (unless DataBinding through KeyField)
+ ///
+ /// A String
+ ///
+ /// [cnurse] 02/17/2006 Created
+ ///
+ public string NavigateURL { get; set; }
+
+
+ ///
+ /// Gets or sets the URL Formatting string
+ ///
+ /// A String
+ ///
+ /// [cnurse] 01/06/2006 Created
+ ///
+ public string NavigateURLFormatString { get; set; }
+
+
+ ///
+ /// Javascript text to attach to the OnClick Event
+ ///
+ /// A String
+ public string OnClickJs { get; set; }
+
+
+ ///
+ /// Gets or sets whether an Image is displayed
+ ///
+ /// Defaults to True
+ /// A Boolean
+ public bool ShowImage
+ {
+ get { return _showImage; }
+ set { _showImage = value; }
+ }
+
+
+ ///
+ /// Gets or sets the Text (for Header/Footer Templates)
+ ///
+ /// A String
+ public string Text { get; set; }
+
+
+ ///
+ /// An flag that indicates whether the buttons are visible.
+ ///
+ /// A Boolean
+ public string VisibleField { get; set; }
+
+
+ ///
+ /// Creates a ImageCommandColumnTemplate
+ ///
+ /// A ImageCommandColumnTemplate
+ private DnnGridImageCommandColumnTemplate CreateTemplate(GridItemType type)
+ {
+ bool isDesignMode = HttpContext.Current == null;
+ var template = new DnnGridImageCommandColumnTemplate(type);
+ if (type != GridItemType.Header)
+ {
+ template.ImageURL = ImageURL;
+ if (!isDesignMode)
+ {
+ template.CommandName = CommandName;
+ template.VisibleField = VisibleField;
+ template.KeyField = KeyField;
+ }
+ }
+ template.EditMode = EditMode;
+ template.NavigateURL = NavigateURL;
+ template.NavigateURLFormatString = NavigateURLFormatString;
+ template.OnClickJs = OnClickJs;
+ template.ShowImage = ShowImage;
+ template.Visible = Visible;
+
+ template.Text = type == GridItemType.Header ? HeaderText : Text;
+
+ //Set Design Mode to True
+ template.DesignMode = isDesignMode;
+
+ return template;
+ }
+
+ ///
+ /// Initialises the Column
+ ///
+ public override void Initialize()
+ {
+ ItemTemplate = CreateTemplate(GridItemType.Item);
+ EditItemTemplate = CreateTemplate(GridItemType.EditItem);
+ HeaderTemplate = CreateTemplate(GridItemType.Header);
+
+ if (HttpContext.Current == null)
+ {
+ HeaderStyle.Font.Names = new[] { "Tahoma, Verdana, Arial" };
+ HeaderStyle.Font.Size = new FontUnit("10pt");
+ HeaderStyle.Font.Bold = true;
+ }
+ ItemStyle.HorizontalAlign = HorizontalAlign.Center;
+ HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageCommandColumnTemplate.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageCommandColumnTemplate.cs
new file mode 100644
index 00000000000..c38c2dbb181
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridImageCommandColumnTemplate.cs
@@ -0,0 +1,323 @@
+#region Copyright
+
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+using System;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.UI.Utilities;
+using DotNetNuke.UI.WebControls;
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridImageCommandColumnTemplate : IBindableTemplate
+ {
+ private ImageCommandColumnEditMode _editMode = ImageCommandColumnEditMode.Command;
+ private GridItemType _itemType = GridItemType.Item;
+ private bool _showImage = true;
+ private bool _visible = true;
+
+ public DnnGridImageCommandColumnTemplate()
+ : this(GridItemType.Item)
+ {
+ }
+
+ public DnnGridImageCommandColumnTemplate(GridItemType itemType)
+ {
+ ItemType = itemType;
+ }
+
+
+ ///
+ /// Gets or sets the CommandName for the Column
+ ///
+ /// A String
+ ///
+ /// [cnurse] 02/17/2006 Created
+ ///
+ public string CommandName { get; set; }
+
+
+ ///
+ /// Gets or sets the Design Mode of the Column
+ ///
+ /// A Boolean
+ ///
+ /// [cnurse] 02/24/2006 Created
+ ///
+ public bool DesignMode { get; set; }
+
+
+ ///
+ /// Gets or sets the CommandName for the Column
+ ///
+ /// A String
+ public ImageCommandColumnEditMode EditMode
+ {
+ get { return _editMode; }
+ set { _editMode = value; }
+ }
+
+
+ ///
+ /// Gets or sets the URL of the Image
+ ///
+ /// A String
+ public string ImageURL { get; set; }
+
+
+ ///
+ /// The type of Template to Create
+ ///
+ /// A String
+ public GridItemType ItemType
+ {
+ get { return _itemType; }
+ set { _itemType = value; }
+ }
+
+
+ ///
+ /// The Key Field that provides a Unique key to the data Item
+ ///
+ /// A String
+ public string KeyField { get; set; }
+
+
+ ///
+ /// Gets or sets the URL of the Link (unless DataBinding through KeyField)
+ ///
+ /// A String
+ public string NavigateURL { get; set; }
+
+
+ ///
+ /// Gets or sets the URL Formatting string
+ ///
+ /// A String
+ public string NavigateURLFormatString { get; set; }
+
+
+ ///
+ /// Javascript text to attach to the OnClick Event
+ ///
+ /// A String
+ public string OnClickJs { get; set; }
+
+
+ ///
+ /// Gets or sets whether an Image is displayed
+ ///
+ /// Defaults to True
+ /// A Boolean
+ public bool ShowImage
+ {
+ get { return _showImage; }
+ set { _showImage = value; }
+ }
+
+
+ ///
+ /// Gets or sets the Text (for Header/Footer Templates)
+ ///
+ /// A String
+ public string Text { get; set; }
+
+
+ ///
+ /// An flag that indicates whether the buttons are visible (this is overridden if
+ /// the VisibleField is set)
+ /// changed
+ ///
+ /// A Boolean
+ public bool Visible
+ {
+ get { return _visible; }
+ set { _visible = value; }
+ }
+
+
+ ///
+ /// An flag that indicates whether the buttons are visible.
+ ///
+ /// A Boolean
+ public string VisibleField { get; set; }
+
+ #region ITemplate Members
+
+ ///
+ /// InstantiateIn instantiates the template (implementation of ITemplate)
+ ///
+ ///
+ ///
+ /// The parent container (DataGridItem)
+ public void InstantiateIn(Control container)
+ {
+ switch (ItemType)
+ {
+ case GridItemType.Item:
+ case GridItemType.AlternatingItem:
+ case GridItemType.SelectedItem:
+ case GridItemType.EditItem:
+ if (EditMode == ImageCommandColumnEditMode.URL)
+ {
+ var hypLink = new HyperLink {ToolTip = Text};
+ if (!String.IsNullOrEmpty(ImageURL) && ShowImage)
+ {
+ var img = new Image {ImageUrl = DesignMode ? ImageURL.Replace("~/", "../../") : ImageURL};
+ hypLink.Controls.Add(img);
+ img.ToolTip = Text;
+ }
+ else
+ {
+ hypLink.Text = Text;
+ }
+ hypLink.DataBinding += ItemDataBinding;
+ container.Controls.Add(hypLink);
+ }
+ else
+ {
+ if (!String.IsNullOrEmpty(ImageURL) && ShowImage)
+ {
+ var colIcon = new ImageButton
+ {ImageUrl = DesignMode ? ImageURL.Replace("~/", "../../") : ImageURL, ToolTip = Text};
+ if (!String.IsNullOrEmpty(OnClickJs))
+ {
+ ClientAPI.AddButtonConfirm(colIcon, OnClickJs);
+ }
+ colIcon.CommandName = CommandName;
+ colIcon.DataBinding += ItemDataBinding;
+ container.Controls.Add(colIcon);
+ }
+ if (!String.IsNullOrEmpty(Text) && !ShowImage)
+ {
+ var colLink = new LinkButton {ToolTip = Text};
+ if (!String.IsNullOrEmpty(OnClickJs))
+ {
+ ClientAPI.AddButtonConfirm(colLink, OnClickJs);
+ }
+ colLink.CommandName = CommandName;
+ colLink.Text = Text;
+ colLink.DataBinding += ItemDataBinding;
+ container.Controls.Add(colLink);
+ }
+ }
+ break;
+ case GridItemType.Footer:
+ case GridItemType.Header:
+ container.Controls.Add(new LiteralControl(Text));
+ break;
+ }
+ }
+
+ public IOrderedDictionary ExtractValues(Control container)
+ {
+ //do nothing we don't really support databinding
+ //but the telerik grid trys to databind to all template columns regardless
+ return new OrderedDictionary();
+ }
+
+ #endregion
+
+ ///
+ /// Gets whether theButton is visible
+ ///
+ /// The parent container (DataGridItem)
+ private bool GetIsVisible(GridItem container)
+ {
+ if (!String.IsNullOrEmpty(VisibleField))
+ {
+ return Convert.ToBoolean(DataBinder.Eval(container.DataItem, VisibleField));
+ }
+
+ return Visible;
+ }
+
+
+ ///
+ /// Gets the value of the key
+ ///
+ /// The parent container (DataGridItem)
+ private int GetValue(GridItem container)
+ {
+ int keyValue = Null.NullInteger;
+ if (!String.IsNullOrEmpty(KeyField))
+ {
+ keyValue = Convert.ToInt32(DataBinder.Eval(container.DataItem, KeyField));
+ }
+ return keyValue;
+ }
+
+
+ ///
+ /// Item_DataBinding runs when an Item of type GridItemType.Item is being data-bound
+ ///
+ ///
+ ///
+ /// The object that triggers the event
+ /// An EventArgs object
+ private void ItemDataBinding(object sender, EventArgs e)
+ {
+ GridItem container;
+ int keyValue;
+ if (EditMode == ImageCommandColumnEditMode.URL)
+ {
+ var hypLink = (HyperLink) sender;
+ container = (GridItem) hypLink.NamingContainer;
+ keyValue = GetValue(container);
+ if (!String.IsNullOrEmpty(NavigateURLFormatString))
+ {
+ hypLink.NavigateUrl = string.Format(NavigateURLFormatString, keyValue);
+ }
+ else
+ {
+ hypLink.NavigateUrl = keyValue.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+ else
+ {
+ //Bind Image Button
+ if (!String.IsNullOrEmpty(ImageURL) && ShowImage)
+ {
+ var colIcon = (ImageButton) sender;
+ container = (GridItem) colIcon.NamingContainer;
+ keyValue = GetValue(container);
+ colIcon.CommandArgument = keyValue.ToString(CultureInfo.InvariantCulture);
+ colIcon.Visible = GetIsVisible(container);
+ }
+ if (!String.IsNullOrEmpty(Text) && !ShowImage)
+ {
+ //Bind Link Button
+ var colLink = (LinkButton) sender;
+ container = (GridItem) colLink.NamingContainer;
+ keyValue = GetValue(container);
+ colLink.CommandArgument = keyValue.ToString(CultureInfo.InvariantCulture);
+ colLink.Visible = GetIsVisible(container);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItem.cs
new file mode 100644
index 00000000000..6ba04cf7e2c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItem.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridItem : GridItem
+ {
+ public DnnGridItem(GridTableView ownerTableView, int itemIndex, int dataSetIndex, GridItemType itemType) : base(ownerTableView, itemIndex, dataSetIndex, itemType)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItemSelectedEventArgs.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItemSelectedEventArgs.cs
new file mode 100644
index 00000000000..36e319f1744
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItemSelectedEventArgs.cs
@@ -0,0 +1,56 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridItemSelectedEventArgs : EventArgs
+ {
+ private readonly GridItemCollection _SelectedItems;
+
+ #region "Constructors"
+
+ public DnnGridItemSelectedEventArgs(GridItemCollection selectedItems)
+ {
+ _SelectedItems = selectedItems;
+ }
+
+ #endregion
+
+ #region "Public Properties"
+
+ public GridItemCollection SelectedItems
+ {
+ get
+ {
+ return _SelectedItems;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItemSelectedEventHandler.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItemSelectedEventHandler.cs
new file mode 100644
index 00000000000..5ff7559c8b2
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridItemSelectedEventHandler.cs
@@ -0,0 +1,24 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public delegate void DnnGridItemSelectedEventHandler(object sender, DnnGridItemSelectedEventArgs e);
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridMaskedColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridMaskedColumn.cs
new file mode 100644
index 00000000000..e03af42c2da
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridMaskedColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridMaskedColumn : GridMaskedColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridMaskedColumn dnnGridColumn = new DnnGridMaskedColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridNumericColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridNumericColumn.cs
new file mode 100644
index 00000000000..48ee56935be
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridNumericColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridNumericColumn : GridNumericColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridNumericColumn dnnGridColumn = new DnnGridNumericColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridRatingColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridRatingColumn.cs
new file mode 100644
index 00000000000..046cd0775ce
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridRatingColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridRatingColumn : GridRatingColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridRatingColumn dnnGridColumn = new DnnGridRatingColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridRowIndicatorColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridRowIndicatorColumn.cs
new file mode 100644
index 00000000000..bdc47e292cc
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridRowIndicatorColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridRowIndicatorColumn : GridRowIndicatorColumn
+ {
+ #region Public Properties
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override GridColumn Clone()
+ {
+ DnnGridRowIndicatorColumn dnnGridColumn = new DnnGridRowIndicatorColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridTableView.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridTableView.cs
new file mode 100644
index 00000000000..7d5db57167f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridTableView.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridTableView : GridTableView
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridTemplateColumn.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridTemplateColumn.cs
new file mode 100644
index 00000000000..2977d4c5ec5
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnGridTemplateColumn.cs
@@ -0,0 +1,71 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnGridTemplateColumn : GridTemplateColumn
+ {
+ #region "Public Properties"
+
+ public string LocalResourceFile
+ {
+ get
+ {
+ return Utilities.GetLocalResourceFile(Owner.OwnerGrid.Parent);
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public override GridColumn Clone()
+ {
+ DnnGridTemplateColumn dnnGridColumn = new DnnGridTemplateColumn();
+
+ //you should override CopyBaseProperties if you have some column specific properties
+ dnnGridColumn.CopyBaseProperties(this);
+
+ return dnnGridColumn;
+ }
+
+ public override void InitializeCell(TableCell cell, int columnIndex, GridItem inItem)
+ {
+ base.InitializeCell(cell, columnIndex, inItem);
+ if (inItem is GridHeaderItem && HeaderTemplate == null && !String.IsNullOrEmpty(HeaderText))
+ {
+ cell.Text = Localization.GetString(string.Format("{0}.Header", HeaderText), LocalResourceFile);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImage.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImage.cs
new file mode 100644
index 00000000000..8f16e1dc5e7
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImage.cs
@@ -0,0 +1,55 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnImage : Image
+ {
+
+ #region Public Properties
+
+ public string IconKey { get; set; }
+ public string IconSize { get; set; }
+ public string IconStyle { get; set; }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ if (string.IsNullOrEmpty(ImageUrl))
+ ImageUrl = Entities.Icons.IconController.IconURL(IconKey, IconSize, IconStyle);
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImageButton.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImageButton.cs
new file mode 100644
index 00000000000..ec8e4d75d8a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImageButton.cs
@@ -0,0 +1,55 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnImageButton : ImageButton
+ {
+
+ #region Public Properties
+
+ public string IconKey { get; set; }
+ public string IconSize { get; set; }
+ public string IconStyle { get; set; }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ if (string.IsNullOrEmpty(ImageUrl))
+ ImageUrl = Entities.Icons.IconController.IconURL(IconKey, IconSize, IconStyle);
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImageEditControl.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImageEditControl.cs
new file mode 100644
index 00000000000..8d5298579dc
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnImageEditControl.cs
@@ -0,0 +1,30 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnImageEditControl : DnnFileEditControl
+ {
+ public DnnImageEditControl()
+ {
+ FileFilter = "jpg,jpeg,gif,png";
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnInputManager.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnInputManager.cs
new file mode 100644
index 00000000000..fc7409a7667
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnInputManager.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnInputManager : RadInputManager
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLabel.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLabel.cs
new file mode 100644
index 00000000000..fe6a56a9da7
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLabel.cs
@@ -0,0 +1,105 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnLabel : Label, ILocalizable
+ {
+
+ private bool _localize = true;
+
+ #region Constructors
+
+ public DnnLabel()
+ {
+ CssClass = "dnnFormLabel";
+ }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ base.Render(writer);
+ }
+
+ #endregion
+
+ #region ILocalizable Implementation
+
+ public bool Localize
+ {
+ get
+ {
+ return !DesignMode && _localize;
+ }
+ set
+ {
+ _localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if (Localize)
+ {
+ if (!string.IsNullOrEmpty(ToolTip))
+ {
+ ToolTip = Localization.GetString(ToolTip, LocalResourceFile);
+ }
+
+ if (!string.IsNullOrEmpty(Text))
+ {
+ var unLocalized = Text;
+
+ Text = Localization.GetString(unLocalized, LocalResourceFile);
+
+ if (string.IsNullOrEmpty(ToolTip))
+ {
+ ToolTip = Localization.GetString(unLocalized + ".ToolTip", LocalResourceFile);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLanguageComboBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLanguageComboBox.cs
new file mode 100644
index 00000000000..5a475a3d6a2
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLanguageComboBox.cs
@@ -0,0 +1,329 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Services.Personalization;
+
+using Telerik.Web.UI;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnLanguageComboBox : WebControl
+ {
+ private readonly string _viewTypePersonalizationKey;
+ private DnnComboBox _englishCombo;
+ private LanguagesListType _languagesListType = LanguagesListType.Enabled;
+ private RadioButtonList _modeRadioButtonList;
+ private DnnComboBox _nativeCombo;
+
+ private string _originalValue;
+
+ protected override HtmlTextWriterTag TagKey
+ {
+ get
+ {
+ return HtmlTextWriterTag.Div;
+ }
+ }
+
+ #region "Public Events"
+
+ public event EventHandler ItemChanged;
+ public event EventHandler ModeChanged;
+
+ #endregion
+
+ #region "Constructor"
+
+ public DnnLanguageComboBox()
+ {
+ AutoPostBack = Null.NullBoolean;
+ CausesValidation = Null.NullBoolean;
+ ShowFlag = true;
+ ShowModeButtons = true;
+ HideLanguagesList = new Dictionary();
+ FlagImageUrlFormatString = "~/images/Flags/{0}.gif";
+ _viewTypePersonalizationKey = "ViewType" + PortalId;
+ }
+
+ #endregion
+
+ #region "Public Properties"
+
+ private string DisplayMode
+ {
+ get
+ {
+ string displayMode = Convert.ToString(Personalization.GetProfile("LanguageDisplayMode", _viewTypePersonalizationKey));
+ if (string.IsNullOrEmpty(displayMode))
+ {
+ displayMode = "NATIVE";
+ }
+ return displayMode;
+ }
+ }
+
+ public string FlagImageUrlFormatString { get; set; }
+
+ public Dictionary HideLanguagesList { get; set; }
+
+ public bool IncludeNoneSpecified { get; set; }
+
+ public LanguagesListType LanguagesListType
+ {
+ get
+ {
+ return _languagesListType;
+ }
+ set
+ {
+ _languagesListType = value;
+ }
+ }
+
+ public int PortalId { get; set; }
+
+ public string SelectedValue
+ {
+ get
+ {
+ string selectedValue = DisplayMode.ToUpperInvariant() == "NATIVE" ? _nativeCombo.SelectedValue : _englishCombo.SelectedValue;
+ if (selectedValue == "None")
+ {
+ selectedValue = Null.NullString;
+ }
+ return selectedValue;
+ }
+ }
+
+ public bool ShowFlag { get; set; }
+
+ public bool ShowModeButtons { get; set; }
+
+ /// -----------------------------------------------------------------------------
+ ///
+ /// Determines whether the List Auto Posts Back
+ ///
+ /// -----------------------------------------------------------------------------
+ public bool AutoPostBack { get; set; }
+
+ public bool CausesValidation { get; set; }
+
+ #endregion
+
+ #region "Private Methods"
+
+ public void BindData(bool refresh)
+ {
+ if (refresh)
+ {
+ List cultures;
+ switch (LanguagesListType)
+ {
+ case LanguagesListType.Supported:
+ cultures = LocaleController.Instance.GetCultures(LocaleController.Instance.GetLocales(Null.NullInteger));
+ break;
+ case LanguagesListType.Enabled:
+ cultures = LocaleController.Instance.GetCultures(LocaleController.Instance.GetLocales(PortalId));
+ break;
+ default:
+ cultures = new List(CultureInfo.GetCultures(CultureTypes.SpecificCultures));
+ break;
+ }
+
+ foreach (KeyValuePair lang in HideLanguagesList)
+ {
+ string cultureCode = lang.Value.Code;
+ CultureInfo culture = cultures.Where(c => c.Name == cultureCode).SingleOrDefault();
+ if (culture != null)
+ {
+ cultures.Remove(culture);
+ }
+ }
+
+ _nativeCombo.DataSource = cultures.OrderBy(c => c.NativeName);
+ _englishCombo.DataSource = cultures.OrderBy(c => c.EnglishName);
+ }
+
+
+ _nativeCombo.DataBind();
+ _englishCombo.DataBind();
+
+ if (IncludeNoneSpecified && refresh)
+ {
+ _englishCombo.Items.Insert(0, new RadComboBoxItem(Localization.GetString("System_Default", Localization.SharedResourceFile), "None"));
+ _nativeCombo.Items.Insert(0, new RadComboBoxItem(Localization.GetString("System_Default", Localization.SharedResourceFile), "None"));
+ }
+ }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ _nativeCombo = new DnnComboBox();
+ _nativeCombo.DataValueField = "Name";
+ _nativeCombo.DataTextField = "NativeName";
+ _nativeCombo.SelectedIndexChanged += ItemChangedInternal;
+ Controls.Add(_nativeCombo);
+
+ _englishCombo = new DnnComboBox();
+ _englishCombo.DataValueField = "Name";
+ _englishCombo.DataTextField = "EnglishName";
+ _englishCombo.SelectedIndexChanged += ItemChangedInternal;
+ Controls.Add(_englishCombo);
+
+ _modeRadioButtonList = new RadioButtonList();
+ _modeRadioButtonList.AutoPostBack = true;
+ _modeRadioButtonList.RepeatDirection = RepeatDirection.Horizontal;
+ _modeRadioButtonList.Items.Add(new ListItem(Localization.GetString("NativeName", Localization.GlobalResourceFile), "NATIVE"));
+ _modeRadioButtonList.Items.Add(new ListItem(Localization.GetString("EnglishName", Localization.GlobalResourceFile), "ENGLISH"));
+ _modeRadioButtonList.SelectedIndexChanged += ModeChangedInternal;
+ Controls.Add(_modeRadioButtonList);
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+
+ _originalValue = SelectedValue;
+ }
+
+ protected virtual void OnItemChanged()
+ {
+ if (ItemChanged != null)
+ {
+ ItemChanged(this, new EventArgs());
+ }
+ }
+
+ protected void OnModeChanged(EventArgs e)
+ {
+ if (ModeChanged != null)
+ {
+ ModeChanged(this, e);
+ }
+ }
+
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ if (DisplayMode.ToUpperInvariant() == "ENGLISH")
+ {
+ if (_englishCombo.Items.FindItemByValue(_originalValue) != null)
+ {
+ _englishCombo.Items.FindItemByValue(_originalValue).Selected = true;
+ }
+ }
+ else
+ {
+ if (_nativeCombo.Items.FindItemByValue(_originalValue) != null)
+ {
+ _nativeCombo.Items.FindItemByValue(_originalValue).Selected = true;
+ }
+ }
+
+ _modeRadioButtonList.Items.FindByValue(DisplayMode).Selected = true;
+
+ foreach (RadComboBoxItem item in _englishCombo.Items)
+ {
+ item.ImageUrl = string.Format(FlagImageUrlFormatString, item.Value);
+ }
+ foreach (RadComboBoxItem item in _nativeCombo.Items)
+ {
+ item.ImageUrl = string.Format(FlagImageUrlFormatString, item.Value);
+ }
+
+ _englishCombo.AutoPostBack = AutoPostBack;
+ _englishCombo.CausesValidation = CausesValidation;
+ _englishCombo.Visible = (DisplayMode.ToUpperInvariant() == "ENGLISH");
+
+ _nativeCombo.AutoPostBack = AutoPostBack;
+ _nativeCombo.CausesValidation = CausesValidation;
+ _nativeCombo.Visible = (DisplayMode.ToUpperInvariant() == "NATIVE");
+
+ _modeRadioButtonList.Visible = ShowModeButtons;
+
+ _englishCombo.Width = Width;
+ _nativeCombo.Width = Width;
+
+ base.OnPreRender(e);
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public void SetLanguage(string code)
+ {
+ if (string.IsNullOrEmpty(code))
+ {
+ _nativeCombo.SelectedIndex = _nativeCombo.FindItemIndexByValue("None");
+ _englishCombo.SelectedIndex = _englishCombo.FindItemIndexByValue("None");
+ }
+ else
+ {
+ _nativeCombo.SelectedIndex = _nativeCombo.FindItemIndexByValue(code);
+ _englishCombo.SelectedIndex = _englishCombo.FindItemIndexByValue(code);
+ }
+ }
+
+ public override void DataBind()
+ {
+ BindData(!Page.IsPostBack);
+ }
+
+ #endregion
+
+ #region "Event Handlers"
+
+ private void ModeChangedInternal(object sender, EventArgs e)
+ {
+ Personalization.SetProfile("LanguageDisplayMode", _viewTypePersonalizationKey, _modeRadioButtonList.SelectedValue);
+
+ //Resort
+ BindData(true);
+
+ OnModeChanged(EventArgs.Empty);
+ }
+
+ private void ItemChangedInternal(object sender, EventArgs e)
+ {
+ OnItemChanged();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLanguageLabel.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLanguageLabel.cs
new file mode 100644
index 00000000000..860c09e9710
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLanguageLabel.cs
@@ -0,0 +1,182 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Services.Personalization;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnLanguageLabel : CompositeControl, ILocalizable
+ {
+ #region "Public Enums"
+
+ #endregion
+
+ #region "Controls"
+
+ private Image _Flag;
+
+ private Label _Label;
+
+ #endregion
+
+ private bool _Localize = true;
+
+ #region "Public Properties"
+
+ public CultureDropDownTypes DisplayType { get; set; }
+
+ public string Language
+ {
+ get
+ {
+ return (string) ViewState["Language"];
+ }
+ set
+ {
+ ViewState["Language"] = value;
+ }
+ }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ /// -----------------------------------------------------------------------------
+ ///
+ /// CreateChildControls overrides the Base class's method to correctly build the
+ /// control based on the configuration
+ ///
+ ///
+ /// [cnurse] 07/31/2006 created
+ ///
+ /// -----------------------------------------------------------------------------
+ protected override void CreateChildControls()
+ {
+ //First clear the controls collection
+ Controls.Clear();
+
+ _Flag = new Image();
+ Controls.Add(_Flag);
+
+ Controls.Add(new LiteralControl(" "));
+
+ _Label = new Label();
+ Controls.Add(_Label);
+
+ //Call base class's method
+
+ base.CreateChildControls();
+ }
+
+ /// -----------------------------------------------------------------------------
+ ///
+ /// OnPreRender runs just before the control is rendered
+ ///
+ ///
+ /// [cnurse] 07/31/2006 created
+ ///
+ /// -----------------------------------------------------------------------------
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ if (string.IsNullOrEmpty(Language))
+ {
+ _Flag.ImageUrl = "~/images/Flags/none.gif";
+ }
+ else
+ {
+ _Flag.ImageUrl = string.Format("~/images/Flags/{0}.gif", Language);
+ }
+
+ if (DisplayType == 0)
+ {
+ PortalSettings _PortalSettings = PortalController.GetCurrentPortalSettings();
+ string _ViewTypePersonalizationKey = "ViewType" + _PortalSettings.PortalId;
+ string _ViewType = Convert.ToString(Personalization.GetProfile("LanguageDisplayMode", _ViewTypePersonalizationKey));
+ switch (_ViewType)
+ {
+ case "NATIVE":
+ DisplayType = CultureDropDownTypes.NativeName;
+ break;
+ case "ENGLISH":
+ DisplayType = CultureDropDownTypes.EnglishName;
+ break;
+ default:
+ DisplayType = CultureDropDownTypes.DisplayName;
+ break;
+ }
+ }
+
+ string localeName = null;
+ if (string.IsNullOrEmpty(Language))
+ {
+ localeName = Localization.GetString("NeutralCulture", Localization.GlobalResourceFile);
+ }
+ else
+ {
+ localeName = Localization.GetLocaleName(Language, DisplayType);
+ }
+ _Label.Text = localeName;
+ _Flag.AlternateText = localeName;
+ }
+
+ #endregion
+
+ #region "ILocalizable Implementation"
+
+ public bool Localize
+ {
+ get
+ {
+ return _Localize;
+ }
+ set
+ {
+ _Localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListBox.cs
new file mode 100644
index 00000000000..1204dcff348
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListBox.cs
@@ -0,0 +1,40 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnListBox : RadListBox
+ {
+
+ //public DnnListBox()
+ //{
+ // Utilities.ApplySkin(this);
+ //}
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListBoxItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListBoxItem.cs
new file mode 100644
index 00000000000..3fa130d7062
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListBoxItem.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnListBoxItem : RadListBoxItem
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListView.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListView.cs
new file mode 100644
index 00000000000..acd01f178c3
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListView.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnListView : RadListView
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListViewItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListViewItem.cs
new file mode 100644
index 00000000000..655115f3441
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListViewItem.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnListViewItem : RadListViewItem
+ {
+ public DnnListViewItem(RadListViewItemType itemType, RadListView ownerView) : base(itemType, ownerView)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListViewItemDragHandle.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListViewItemDragHandle.cs
new file mode 100644
index 00000000000..4762c5c97f7
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnListViewItemDragHandle.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnListViewItemDragHandle : RadListViewItemDragHandle
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLiteral.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLiteral.cs
new file mode 100644
index 00000000000..323b6bda02b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnLiteral.cs
@@ -0,0 +1,82 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnLiteral : Literal, ILocalizable
+ {
+ private bool _Localize = true;
+
+ #region "Protected Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ base.Render(writer);
+ }
+
+ #endregion
+
+ #region "ILocalizable Implementation"
+
+ public bool Localize
+ {
+ get
+ {
+ return _Localize;
+ }
+ set
+ {
+ _Localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((Localize))
+ {
+ if ((!string.IsNullOrEmpty(Text)))
+ {
+ Text = Localization.GetString(Text, LocalResourceFile);
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMaskedTextBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMaskedTextBox.cs
new file mode 100644
index 00000000000..d7f7d64650c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMaskedTextBox.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnMaskedTextBox : RadMaskedTextBox
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMemberListControl.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMemberListControl.cs
new file mode 100644
index 00000000000..25ec5ef1042
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMemberListControl.cs
@@ -0,0 +1,221 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Linq;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Entities.Users;
+using DotNetNuke.Entities.Users.Social;
+using DotNetNuke.Services.Tokens;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ ///
+ /// This control is used for displaying a template based list of users based upon various filter and sorting capabilities.
+ ///
+ [ToolboxData("<{0}:DnnMemberListControl runat=\"server\">{0}:DnnMemberListControl>")]
+ public class DnnMemberListControl : WebControl
+ {
+ #region Private Variables
+
+ private UserInfo _currentUser;
+ private RelationshipController _relationshipController;
+
+ #endregion
+
+ #region Properties
+
+ #region Layout Properties
+
+ ///
+ /// Gets or sets the template for displaying the header section of a DnnMemberListControl object.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string HeaderTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for the row header.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string RowHeaderTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for displaying an item in a DnnMemberListControl object.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string ItemTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for the row footer.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string RowFooterTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for displaying the alternating row headers in a DnnMemberListControl object.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string AlternatingRowHeaderTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for displaying the alternating items in a DnnMemberListControl object.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string AlternatingItemTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for displaying the alternating row footers in a DnnMemberListControl object.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string AlternatingRowFooterTemplate { get; set; }
+
+ ///
+ /// Gets or sets the template for displaying the footer section of a DnnMemberListControl object.
+ ///
+ [DefaultValue(""), PersistenceMode(PersistenceMode.InnerProperty)]
+ public string FooterTemplate { get; set; }
+
+ #endregion
+
+ #region Filter Properties
+
+ ///
+ /// Gets or sets the index of the currently displayed page.
+ ///
+ [DefaultValue(1)]
+ public int PageIndex { get; set; }
+
+ ///
+ /// Gets or sets the number of records to display on a page in a DnnMemberListControl object.
+ ///
+ [DefaultValue(10)]
+ public int PageSize { get; set; }
+
+ ///
+ /// Gets or sets the number of items displayed on each row.
+ ///
+ [DefaultValue(1)]
+ public int RowSize { get; set; }
+
+ ///
+ /// Sets the property value to sort by.
+ ///
+ [DefaultValue("UserId")]
+ public string SortBy { get; set; }
+
+ ///
+ /// Gets or sets the sort direction
+ ///
+ [DefaultValue(true)]
+ public bool SortAscending { get; set; }
+
+ ///
+ /// Gets or sets the collection of filters to apply when getting the list of members.
+ ///
+ ///
+ /// Posible keys are: RoleId, RelationshipTypeId, UserId, Profile:PropertyName, FirstName, LastName, DisplayName, Username, Email.
+ ///
+ public IDictionary Filters { get; set; }
+
+ #endregion
+
+ #endregion
+
+ #region Event Handlers
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ _currentUser = UserController.GetCurrentUserInfo();
+ _relationshipController = new RelationshipController();
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ if (ItemTemplate == "") return;
+
+ writer.Write(HeaderTemplate);
+
+ // Filters
+ if (Filters == null) Filters = new Dictionary();
+ var additionalFilters = new Dictionary();
+ additionalFilters.Add("Records", PageSize.ToString());
+ additionalFilters.Add("PageIndex", PageIndex.ToString());
+ additionalFilters.Add("Rowsize", RowSize.ToString());
+ additionalFilters.Add("SortBy", SortBy);
+ additionalFilters.Add("SortAscending", SortAscending.ToString());
+
+ // Currently Not Used by the SPROC
+ var filterUser = Filters.ContainsKey("UserId") && Filters["UserId"] != null ? new UserInfo() { UserID = int.Parse(Filters["UserId"]) } : new UserInfo() { PortalID = _currentUser.PortalID };
+ var role = Filters.ContainsKey("RoleId") && Filters["RoleId"] != null ? new UserRoleInfo() { RoleID = int.Parse(Filters["RoleId"]) } : null;
+ var relationship = Filters.ContainsKey("RelationshipTypeId") && Filters["RelationshipTypeId"] != null ? new RelationshipType() { RelationshipTypeId = int.Parse(Filters["RelationshipTypeId"]) } : null;
+
+ foreach (var filter in Filters.Where(filter => !additionalFilters.ContainsKey(filter.Key)))
+ {
+ additionalFilters.Add(filter.Key, filter.Value);
+ }
+
+ var row = 0;
+ var users = new DataTable();
+
+ //users.Load(_relationshipController.GetUsersAdvancedSearch(_currentUser, filterUser, role, relationship, Filters, additionalFilters));
+
+ if (users.Rows.Count > 0)
+ {
+ foreach (DataRow user in users.Rows)
+ {
+ //Row Header
+ writer.Write(string.IsNullOrEmpty(AlternatingRowHeaderTemplate) || row%2 == 0 ? RowHeaderTemplate : AlternatingRowHeaderTemplate);
+
+ var tokenReplace = new TokenReplace();
+ var tokenKeyValues = new Dictionary();
+
+ foreach (var col in user.Table.Columns.Cast().Where(col => !tokenKeyValues.ContainsKey(col.ColumnName)))
+ {
+ tokenKeyValues.Add(col.ColumnName, user[col.ColumnName].ToString());
+ }
+
+ var listItem = string.IsNullOrEmpty(AlternatingItemTemplate) || row%2 == 0 ? ItemTemplate : AlternatingItemTemplate;
+ listItem = tokenReplace.ReplaceEnvironmentTokens(listItem, tokenKeyValues, "Member");
+ writer.Write(listItem);
+
+ //Row Footer
+ writer.Write(string.IsNullOrEmpty(AlternatingRowFooterTemplate) || row%2 == 0 ? RowFooterTemplate : AlternatingRowFooterTemplate);
+
+ row++;
+ }
+ }
+
+ writer.Write(FooterTemplate);
+ }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenu.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenu.cs
new file mode 100644
index 00000000000..bca4ba20df4
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenu.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnMenu : RadMenu
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenuItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenuItem.cs
new file mode 100644
index 00000000000..f43b0a6540a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenuItem.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnMenuItem : RadMenuItem
+ {
+ public DnnMenuItem()
+ {
+ }
+
+ public DnnMenuItem(string text) : base(text)
+ {
+ }
+
+ public DnnMenuItem(string text, string navigateUrl) : base(text, navigateUrl)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenuItemBinding.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenuItemBinding.cs
new file mode 100644
index 00000000000..dbd10a97290
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMenuItemBinding.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnMenuItemBinding : RadMenuItemBinding
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnModuleComboBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnModuleComboBox.cs
new file mode 100644
index 00000000000..8031c49006c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnModuleComboBox.cs
@@ -0,0 +1,235 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Modules;
+using DotNetNuke.Entities.Modules.Definitions;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Security.Permissions;
+using DotNetNuke.Services.Installer.Packages;
+
+using Telerik.Web.UI;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnModuleComboBox : WebControl
+ {
+ private const string DefaultExtensionImage = "icon_extensions_32px.png";
+
+ #region Public Events
+
+ public event EventHandler ItemChanged;
+
+ #endregion
+
+ #region Public Properties
+
+ public Func, bool> Filter { get; set; }
+
+ public int ItemCount
+ {
+ get
+ {
+ return _moduleCombo.Items.Count;
+ }
+ }
+
+ public string SelectedValue
+ {
+ get
+ {
+ return _moduleCombo.SelectedValue;
+ }
+ }
+
+ public string RadComboBoxClientId
+ {
+ get
+ {
+ return _moduleCombo.ClientID;
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private Dictionary GetPortalDesktopModules()
+ {
+ IOrderedEnumerable> portalModulesList;
+ if (Filter == null)
+ {
+ portalModulesList = DesktopModuleController.GetPortalDesktopModules(PortalSettings.Current.PortalId)
+ .Where((kvp) => kvp.Value.DesktopModule.Category == "Uncategorised" || String.IsNullOrEmpty(kvp.Value.DesktopModule.Category))
+ .OrderBy(c => c.Key);
+ }
+ else
+ {
+ portalModulesList = DesktopModuleController.GetPortalDesktopModules(PortalSettings.Current.PortalId)
+ .Where(Filter)
+ .OrderBy(c => c.Key);
+ }
+
+ return portalModulesList.ToDictionary(portalModule => portalModule.Value.DesktopModuleID,
+ portalModule => portalModule.Key);
+ }
+
+ private static Dictionary GetTabModules(int tabID)
+ {
+ var tabCtrl = new TabController();
+ var moduleCtrl = new ModuleController();
+ var tabModules = moduleCtrl.GetTabModules(tabID);
+
+ // Is this tab from another site?
+ var isRemote = tabCtrl.GetTab(tabID, Null.NullInteger, false).PortalID != PortalSettings.Current.PortalId;
+
+ var pageModules = tabModules.Values.Where(m => !isRemote || ModuleSuportsSharing(m)).Where(m => ModulePermissionController.CanAdminModule(m) && m.IsDeleted == false).ToList();
+
+ return pageModules.ToDictionary(module => module.ModuleID, module => module.ModuleTitle);
+ }
+
+ private static bool ModuleSuportsSharing(ModuleInfo moduleInfo)
+ {
+ switch (moduleInfo.DesktopModule.Shareable)
+ {
+ case ModuleSharing.Supported:
+ case ModuleSharing.Unknown:
+ return moduleInfo.IsShareable;
+ default:
+ return false;
+ }
+ }
+
+ private void BindPortalDesktopModuleImages()
+ {
+ var portalDesktopModules = DesktopModuleController.GetDesktopModules(PortalSettings.Current.PortalId);
+ var packages = PackageController.GetPackages(PortalSettings.Current.PortalId);
+
+ foreach (RadComboBoxItem item in _moduleCombo.Items)
+ {
+ string imageUrl =
+ (from pkgs in packages
+ join portMods in portalDesktopModules on pkgs.PackageID equals portMods.Value.PackageID
+ where portMods.Value.DesktopModuleID.ToString() == item.Value
+ select pkgs.IconFile).FirstOrDefault();
+
+ item.ImageUrl = String.IsNullOrEmpty(imageUrl) ? Globals.ImagePath + DefaultExtensionImage : imageUrl;
+ }
+ }
+
+ private void BindTabModuleImages(int tabID)
+ {
+ var tabModules = new ModuleController().GetTabModules(tabID);
+ var portalDesktopModules = DesktopModuleController.GetDesktopModules(PortalSettings.Current.PortalId);
+ var moduleDefnitions = ModuleDefinitionController.GetModuleDefinitions();
+ var packages = PackageController.GetPackages(PortalSettings.Current.PortalId);
+
+ foreach (RadComboBoxItem item in _moduleCombo.Items)
+ {
+ string imageUrl = (from pkgs in packages
+ join portMods in portalDesktopModules on pkgs.PackageID equals portMods.Value.PackageID
+ join modDefs in moduleDefnitions on portMods.Value.DesktopModuleID equals modDefs.Value.DesktopModuleID
+ join tabMods in tabModules on modDefs.Value.DesktopModuleID equals tabMods.Value.DesktopModuleID
+ where tabMods.Value.ModuleID.ToString() == item.Value
+ select pkgs.IconFile).FirstOrDefault();
+
+ item.ImageUrl = String.IsNullOrEmpty(imageUrl) ? Globals.ImagePath + DefaultExtensionImage : imageUrl;
+ }
+ }
+
+ #endregion
+
+ #region Protected Methods
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ _moduleCombo = new DnnComboBox();
+ _moduleCombo.DataValueField = "key";
+ _moduleCombo.DataTextField = "value";
+ Controls.Add(_moduleCombo);
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+ _originalValue = SelectedValue;
+ }
+
+ protected virtual void OnItemChanged()
+ {
+ if (ItemChanged != null)
+ {
+ ItemChanged(this, new EventArgs());
+ }
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ if (_moduleCombo.Items.FindItemByValue(_originalValue) != null)
+ {
+ _moduleCombo.Items.FindItemByValue(_originalValue).Selected = true;
+ }
+
+ _moduleCombo.Width = Width;
+ base.OnPreRender(e);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public void BindAllPortalDesktopModules()
+ {
+ _moduleCombo.DataSource = GetPortalDesktopModules();
+ _moduleCombo.DataBind();
+ BindPortalDesktopModuleImages();
+ }
+
+ public void BindTabModulesByTabID(int tabID)
+ {
+ _moduleCombo.DataSource = GetTabModules(tabID);
+ _moduleCombo.DataBind();
+ BindTabModuleImages(tabID);
+ }
+
+ public void SetModule(string code)
+ {
+ _moduleCombo.SelectedIndex = _moduleCombo.FindItemIndexByValue(code);
+ }
+
+ #endregion
+
+ private DnnComboBox _moduleCombo;
+ private string _originalValue;
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMonthYearPicker.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMonthYearPicker.cs
new file mode 100644
index 00000000000..d4e6b8e0b7f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMonthYearPicker.cs
@@ -0,0 +1,30 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ class DnnMonthYearPicker : RadMonthYearPicker
+ {
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMultiPage.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMultiPage.cs
new file mode 100644
index 00000000000..7ffdc3c513a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnMultiPage.cs
@@ -0,0 +1,33 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnMultiPage : RadMultiPage
+ {
+ //TODO: Hide properties that we don't want to expose
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnNumericTextBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnNumericTextBox.cs
new file mode 100644
index 00000000000..06f8d97f6ec
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnNumericTextBox.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnNumericTextBox : RadNumericTextBox
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPageDropDownList.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPageDropDownList.cs
new file mode 100644
index 00000000000..16e648ea2a0
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPageDropDownList.cs
@@ -0,0 +1,90 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Web.UI.WebControls.Extensions;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ToolboxData("<{0}:DnnPageDropDownList runat='server'>{0}:DnnPageDropDownList>")]
+ public class DnnPageDropDownList : DnnDropDownList
+ {
+
+ private readonly Lazy _controller = new Lazy(() => new TabController());
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ SelectItemDefaultText = Localization.GetString("DropDownList.SelectWebPageDefaultText", Localization.SharedResourceFile);
+ Services.GetTreeMethod = "ItemListService/GetPages";
+ Services.GetNodeDescendantsMethod = "ItemListService/GetPageDescendants";
+ Services.SearchTreeMethod = "ItemListService/SearchPages";
+ Services.GetTreeWithNodeMethod = "ItemListService/GetTreePathForPage";
+ Services.ServiceRoot = "InternalServices";
+ Services.SortTreeMethod = "ItemListService/SortPages";
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ this.AddCssClass("page");
+ if (InternalPortalId.HasValue)
+ {
+ Services.Parameters.Add("PortalId", InternalPortalId.Value.ToString(CultureInfo.InvariantCulture));
+ }
+ base.OnPreRender(e);
+ }
+
+ public int PortalId
+ {
+ get
+ {
+ if (InternalPortalId.HasValue)
+ {
+ return InternalPortalId.Value;
+ }
+ return PortalSettings.Current.ActiveTab.IsSuperTab ? -1 : PortalSettings.Current.PortalId;
+ }
+ set
+ {
+ InternalPortalId = value;
+ }
+ }
+
+ private int? InternalPortalId
+ {
+ get
+ {
+ return ViewState.GetValue("PortalId", null);
+ }
+ set
+ {
+ ViewState.SetValue("PortalId", value, null);
+ }
+ }
+
+ ///
+ /// Gets the selected Page in the control, or selects the Page in the control.
+ ///
+ [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public TabInfo SelectedPage
+ {
+ get
+ {
+ var pageId = SelectedItemValueAsInt;
+ return (pageId == Null.NullInteger) ? null : _controller.Value.GetTab(pageId, PortalId, false);
+ }
+ set
+ {
+ SelectedItem = (value != null) ? new ListItem() { Text = value.IndentedTabName, Value = value.TabID.ToString(CultureInfo.InvariantCulture) } : null;
+ }
+ }
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPageView.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPageView.cs
new file mode 100644
index 00000000000..8b0be5e5aaa
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPageView.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnPageView : RadPageView
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelBar.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelBar.cs
new file mode 100644
index 00000000000..048d7d43a14
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelBar.cs
@@ -0,0 +1,41 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnPanelBar : RadPanelBar
+ {
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ Utilities.ApplySkin(this);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelItem.cs
new file mode 100644
index 00000000000..fccb293735b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelItem.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnPanelItem : RadPanelItem
+ {
+ public DnnPanelItem()
+ {
+ }
+
+ public DnnPanelItem(string text) : base(text)
+ {
+ }
+
+ public DnnPanelItem(string text, string navigateUrl) : base(text, navigateUrl)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelItemBinding.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelItemBinding.cs
new file mode 100644
index 00000000000..11eecb90d4b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPanelItemBinding.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnPanelItemBinding : RadPanelItemBinding
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPaswordStrengthOptions.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPaswordStrengthOptions.cs
new file mode 100644
index 00000000000..fe6ecdc8723
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPaswordStrengthOptions.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Runtime.Serialization;
+
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Users.Membership;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [DataContract]
+ public class DnnPaswordStrengthOptions
+ {
+ [DataMember(Name = "minLength")]
+ public int MinLength;
+
+ [DataMember(Name = "minNumberOfSpecialChars")]
+ public int MinNumberOfSpecialChars;
+
+ [DataMember(Name = "minLengthText")]
+ public string MinLengthText;
+
+ [DataMember(Name = "weakText")]
+ public string WeakText;
+
+ [DataMember(Name = "fairText")]
+ public string FairText;
+
+ [DataMember(Name = "strongText")]
+ public string StrongText;
+
+ [DataMember(Name = "weakColor")]
+ public string WeakColor;
+
+ [DataMember(Name = "fairColor")]
+ public string FairColor;
+
+ [DataMember(Name = "strongColor")]
+ public string StrongColor;
+
+ [DataMember(Name = "labelCss")]
+ public string LabelCss;
+
+ [DataMember(Name = "meterCss")]
+ public string MeterCss;
+
+ [DataMember(Name = "criteriaOneUpperCaseLetterText")]
+ public string CriteriaOneUpperCaseLetterText;
+
+ [DataMember(Name = "criteriaOneLowerCaseLetterText")]
+ public string CriteriaOneLowerCaseLetterText;
+
+ [DataMember(Name = "criteriaSpecialCharText")]
+ public string CriteriaSpecialCharText;
+
+ [DataMember(Name = "criteriaOneNumberText")]
+ public string CriteriaOneNumberText;
+
+ [DataMember(Name = "criteriaAtLeastNCharsText")]
+ public string CriteriaAtLeastNCharsText;
+
+ public DnnPaswordStrengthOptions()
+ {
+ // all the PasswordStrength related resources are located under the Website\App_GlobalResources\WebControls.resx
+ MinLengthText = Utilities.GetLocalizedString("PasswordStrengthMinLength");
+ WeakText = Utilities.GetLocalizedString("PasswordStrengthWeak");
+ FairText = Utilities.GetLocalizedString("PasswordStrengthFair"); ;
+ StrongText = Utilities.GetLocalizedString("PasswordStrengthStrong"); ;
+
+ CriteriaOneUpperCaseLetterText = Utilities.GetLocalizedString("CriteriaOneUpperCaseLetter");
+ CriteriaOneLowerCaseLetterText = Utilities.GetLocalizedString("CriteriaOneLowerCaseLetter");
+ CriteriaOneNumberText = Utilities.GetLocalizedString("CriteriaOneNumber");
+ CriteriaAtLeastNCharsText = Utilities.GetLocalizedString("CriteriaAtLeastNChars");
+
+ WeakColor = "#ed1e24";
+ FairColor = "#f6d50a";
+ StrongColor = "#69bd44";
+
+ LabelCss = "min-length-text";
+ MeterCss = "meter";
+ }
+
+ ///
+ /// To avoid fetching data from the database in constructor, the OnSerializing method is consumed
+ ///
+ ///
+ [OnSerializing]
+ public void OnSerializing(StreamingContext context)
+ {
+ var settings = new MembershipPasswordSettings(PortalController.GetCurrentPortalSettings().PortalId);
+ MinLength = settings.MinPasswordLength;
+ CriteriaAtLeastNCharsText = string.Format(CriteriaAtLeastNCharsText, MinLength);
+
+ MinNumberOfSpecialChars = settings.MinNonAlphanumericCharacters;
+ CriteriaSpecialCharText = MinNumberOfSpecialChars > 0 ?
+ string.Format(Utilities.GetLocalizedString("CriteriaAtLeastNSpecialChars"), MinNumberOfSpecialChars) :
+ Utilities.GetLocalizedString("CriteriaSpecialChar");
+ }
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPortalPageDropDownList.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPortalPageDropDownList.cs
new file mode 100644
index 00000000000..7d72afb8502
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnPortalPageDropDownList.cs
@@ -0,0 +1,59 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Web.UI.WebControls.Extensions;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ToolboxData("<{0}:DnnPortalPageDropDownList runat='server'>{0}:DnnPortalPageDropDownList>")]
+ public class DnnPortalPageDropDownList : DnnDropDownList
+ {
+
+ private readonly Lazy _controller = new Lazy(() => new TabController());
+ private readonly Lazy _portalId = new Lazy(() => PortalSettings.Current.ActiveTab.IsSuperTab ? -1 : PortalSettings.Current.PortalId);
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+
+ SelectItemDefaultText = Localization.GetString("DropDownList.SelectWebPageDefaultText", Localization.SharedResourceFile);
+ Services.GetTreeMethod = "ItemListService/GetPagesInPortalGroup";
+ Services.GetNodeDescendantsMethod = "ItemListService/GetPageDescendantsInPortalGroup";
+ Services.SearchTreeMethod = "ItemListService/SearchPagesInPortalGroup";
+ Services.GetTreeWithNodeMethod = "ItemListService/GetTreePathForPageInPortalGroup";
+ Services.SortTreeMethod = "ItemListService/SortPagesInPortalGroup";
+ Services.ServiceRoot = "InternalServices";
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ this.AddCssClass("page");
+ base.OnPreRender(e);
+ }
+
+ ///
+ /// Gets the selected Page in the control, or selects the Page in the control.
+ ///
+ [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public TabInfo SelectedPage
+ {
+ get
+ {
+ var pageId = SelectedItemValueAsInt;
+ return (pageId == Null.NullInteger) ? null : _controller.Value.GetTab(pageId, _portalId.Value, false);
+ }
+ set
+ {
+ SelectedItem = (value != null) ? new ListItem() { Text = value.IndentedTabName, Value = value.TabID.ToString(CultureInfo.InvariantCulture) } : null;
+ }
+ }
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnProgressArea.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnProgressArea.cs
new file mode 100644
index 00000000000..a21969ca928
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnProgressArea.cs
@@ -0,0 +1,40 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnProgressArea : RadProgressArea
+ {
+
+ //public DnnProgressArea()
+ //{
+ // Utilities.ApplySkin(this);
+ //}
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnProgressManager.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnProgressManager.cs
new file mode 100644
index 00000000000..454bb45648a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnProgressManager.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnProgressManager : RadProgressManager
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadButton.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadButton.cs
new file mode 100644
index 00000000000..a16e7ef7831
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadButton.cs
@@ -0,0 +1,97 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+
+using DotNetNuke.Services.Localization;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRadButton : RadButton
+ {
+ private bool _Localize = true;
+
+ #region Protected Methods
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ base.Render(writer);
+ }
+
+ #endregion
+
+ #region ILocalizable Implementation
+
+ public bool Localize
+ {
+ get
+ {
+ if (DesignMode)
+ {
+ return false;
+ }
+ return _Localize;
+ }
+ set
+ {
+ _Localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((Localize))
+ {
+ if ((!string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(ToolTip, LocalResourceFile);
+ }
+
+ if ((!string.IsNullOrEmpty(Text)))
+ {
+ Text = Localization.GetString(Text, LocalResourceFile);
+
+ if ((string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(string.Format("{0}.ToolTip", Text), LocalResourceFile);
+ }
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadRibbonBar.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadRibbonBar.cs
new file mode 100644
index 00000000000..0618318dfda
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadRibbonBar.cs
@@ -0,0 +1,30 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRadRibbonBar : RadRibbonBar
+ {
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadioButton.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadioButton.cs
new file mode 100644
index 00000000000..291b4c59a5d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRadioButton.cs
@@ -0,0 +1,101 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRadioButton : RadioButton, ILocalizable
+ {
+ private bool _Localize = true;
+
+ #region "Constructors"
+
+ public DnnRadioButton()
+ {
+ CssClass = "SubHead dnnLabel";
+ }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ base.Render(writer);
+ }
+
+ #endregion
+
+ #region "ILocalizable Implementation"
+
+ public bool Localize
+ {
+ get
+ {
+ return _Localize;
+ }
+ set
+ {
+ _Localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((Localize))
+ {
+ if ((!string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(ToolTip, LocalResourceFile);
+ }
+
+ if ((!string.IsNullOrEmpty(Text)))
+ {
+ Text = Localization.GetString(Text, LocalResourceFile);
+
+ if ((string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(Text + ".ToolTip", LocalResourceFile);
+ }
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRating.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRating.cs
new file mode 100644
index 00000000000..741b0186d7d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRating.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRating : RadRating
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRatingItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRatingItem.cs
new file mode 100644
index 00000000000..e7bbae71753
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRatingItem.cs
@@ -0,0 +1,52 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRatingItem : RadRatingItem
+ {
+ public DnnRatingItem()
+ {
+ }
+
+ public DnnRatingItem(string imageUrl) : base(imageUrl)
+ {
+ }
+
+ public DnnRatingItem(string imageUrl, string selectedImageUrl) : base(imageUrl, selectedImageUrl)
+ {
+ }
+
+ public DnnRatingItem(string imageUrl, string selectedImageUrl, string hoveredImageUrl) : base(imageUrl, selectedImageUrl, hoveredImageUrl)
+ {
+ }
+
+ public DnnRatingItem(string imageUrl, string selectedImageUrl, string hoveredImageUrl, string hoveredSelectedImageUrl)
+ : base(imageUrl, selectedImageUrl, hoveredImageUrl, hoveredSelectedImageUrl)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBar.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBar.cs
new file mode 100644
index 00000000000..7a57e9ac4d5
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBar.cs
@@ -0,0 +1,126 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.ComponentModel;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnRibbonBar : WebControl
+ {
+ public DnnRibbonBar() : base("div")
+ {
+ CssClass = "dnnRibbon";
+ Control control = this;
+ Utilities.ApplySkin(control, "", "RibbonBar", "RibbonBar");
+ }
+
+ [Category("Behavior"), PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public DnnRibbonBarGroupCollection Groups
+ {
+ get
+ {
+ return (DnnRibbonBarGroupCollection) Controls;
+ }
+ }
+
+ protected override void AddParsedSubObject(object obj)
+ {
+ if (obj is DnnRibbonBarGroup)
+ {
+ base.AddParsedSubObject(obj);
+ }
+ else
+ {
+ throw new NotSupportedException("DnnRibbonBarGroupCollection must contain controls of type DnnRibbonBarGroup");
+ }
+ }
+
+ protected override ControlCollection CreateControlCollection()
+ {
+ return new DnnRibbonBarGroupCollection(this);
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ if (Visible)
+ {
+ Utilities.ApplySkin(this, "", "RibbonBar", "RibbonBar");
+ }
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ if ((Groups.Count > 0))
+ {
+ Groups[0].CssClass = Groups[0].CssClass + " " + Groups[0].CssClass.Trim() + "First";
+ Groups[Groups.Count - 1].CssClass = Groups[Groups.Count - 1].CssClass + " " + Groups[Groups.Count - 1].CssClass.Trim() + "Last";
+ }
+
+ base.RenderBeginTag(writer);
+
+ writer.AddAttribute("class", "barContent");
+ writer.RenderBeginTag("div");
+
+ writer.AddAttribute("cellpadding", "0");
+ writer.AddAttribute("cellspacing", "0");
+ writer.AddAttribute("border", "0");
+ writer.RenderBeginTag("table");
+ writer.RenderBeginTag("tr");
+
+ foreach (DnnRibbonBarGroup grp in Groups)
+ {
+ if ((grp.Visible))
+ {
+ writer.RenderBeginTag("td");
+ grp.RenderControl(writer);
+ writer.RenderEndTag();
+ }
+ }
+ //MyBase.RenderChildren(writer)
+
+ writer.RenderEndTag();
+ //tr
+ writer.RenderEndTag();
+ //table
+ writer.RenderEndTag();
+ //div
+
+ writer.AddAttribute("class", "barBottomLeft");
+ writer.RenderBeginTag("div");
+ writer.RenderEndTag();
+
+ writer.AddAttribute("class", "barBottomRight");
+ writer.RenderBeginTag("div");
+ writer.RenderEndTag();
+
+ base.RenderEndTag(writer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarGroup.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarGroup.cs
new file mode 100644
index 00000000000..e9c0c649e3e
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarGroup.cs
@@ -0,0 +1,173 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Web.UI;
+using System.Web.UI.HtmlControls;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnRibbonBarGroup : WebControl
+ {
+ private bool _CheckToolVisibility = true;
+ private HtmlGenericControl _contentContainer;
+
+ public DnnRibbonBarGroup() : base("div")
+ {
+ CssClass = "dnnRibbonGroup";
+ }
+
+ public override ControlCollection Controls
+ {
+ get
+ {
+ EnsureChildControls();
+ return base.Controls;
+ }
+ }
+
+ [TemplateInstance(TemplateInstance.Single)]
+ public virtual ITemplate Footer { get; set; }
+
+ [TemplateInstance(TemplateInstance.Single)]
+ public virtual ITemplate Content { get; set; }
+
+ public virtual bool CheckToolVisibility
+ {
+ get
+ {
+ return _CheckToolVisibility;
+ }
+ set
+ {
+ _CheckToolVisibility = value;
+ }
+ }
+
+ protected override void CreateChildControls()
+ {
+ Controls.Clear();
+
+ HtmlGenericControl topLeft = new HtmlGenericControl("div");
+ topLeft.Attributes.Add("class", "topLeft");
+ HtmlGenericControl topRight = new HtmlGenericControl("div");
+ topRight.Attributes.Add("class", "topRight");
+
+ HtmlGenericControl bottomLeft = new HtmlGenericControl("div");
+ bottomLeft.Attributes.Add("class", "bottomLeft");
+ HtmlGenericControl bottomRight = new HtmlGenericControl("div");
+ bottomRight.Attributes.Add("class", "bottomRight");
+
+ _contentContainer = new HtmlGenericControl("div");
+ _contentContainer.Attributes.Add("class", "content");
+
+ HtmlGenericControl footerContainer = new HtmlGenericControl("div");
+ footerContainer.Attributes.Add("class", "footer");
+
+ Controls.Add(topLeft);
+ Controls.Add(topRight);
+ Controls.Add(_contentContainer);
+ Controls.Add(footerContainer);
+ Controls.Add(bottomLeft);
+ Controls.Add(bottomRight);
+
+ if (Content != null)
+ {
+ Content.InstantiateIn(_contentContainer);
+ }
+
+ if (Footer != null)
+ {
+ Footer.InstantiateIn(footerContainer);
+ }
+ }
+
+ private bool CheckVisibility()
+ {
+ bool returnValue = true;
+ if ((Visible && CheckToolVisibility))
+ {
+ //Hide group if all tools are invisible
+ bool foundTool = false;
+ ControlCollection controls = _contentContainer.Controls;
+ returnValue = AreChildToolsVisible(ref controls, ref foundTool);
+ }
+ return returnValue;
+ }
+
+ private bool AreChildToolsVisible(ref ControlCollection children, ref bool foundTool)
+ {
+ bool returnValue = false;
+
+ foreach (Control ctrl in children)
+ {
+ if ((ctrl is IDnnRibbonBarTool))
+ {
+ foundTool = true;
+ if ((ctrl.Visible))
+ {
+ returnValue = true;
+ break;
+ }
+ }
+ else
+ {
+ ControlCollection controls = ctrl.Controls;
+ if ((AreChildToolsVisible(ref controls, ref foundTool)))
+ {
+ if ((foundTool))
+ {
+ returnValue = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if ((!foundTool))
+ {
+ return true;
+ }
+
+ return returnValue;
+ }
+
+ public override Control FindControl(string id)
+ {
+ EnsureChildControls();
+ return base.FindControl(id);
+ }
+
+ public override void RenderControl(HtmlTextWriter writer)
+ {
+ if ((CheckVisibility()))
+ {
+ base.RenderBeginTag(writer);
+ base.RenderChildren(writer);
+ base.RenderEndTag(writer);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarGroupCollection.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarGroupCollection.cs
new file mode 100644
index 00000000000..ecc2276e350
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarGroupCollection.cs
@@ -0,0 +1,69 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRibbonBarGroupCollection : ControlCollection
+ {
+ public DnnRibbonBarGroupCollection(Control owner) : base(owner)
+ {
+ }
+
+ public new DnnRibbonBarGroup this[int index]
+ {
+ get
+ {
+ return (DnnRibbonBarGroup) base[index];
+ }
+ }
+
+ public override void Add(Control child)
+ {
+ if (child is DnnRibbonBarGroup)
+ {
+ base.Add(child);
+ }
+ else
+ {
+ throw new ArgumentException("DnnRibbonBarGroupCollection must contain controls of type DnnRibbonBarGroup");
+ }
+ }
+
+ public override void AddAt(int index, Control child)
+ {
+ if (child is DnnRibbonBarGroup)
+ {
+ base.AddAt(index, child);
+ }
+ else
+ {
+ throw new ArgumentException("DnnRibbonBarGroupCollection must contain controls of type DnnRibbonBarGroup");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarTool.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarTool.cs
new file mode 100644
index 00000000000..22c609895af
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRibbonBarTool.cs
@@ -0,0 +1,618 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Web.UI;
+
+using DotNetNuke.Application;
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Host;
+using DotNetNuke.Entities.Modules;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Entities.Users;
+using DotNetNuke.Security;
+using DotNetNuke.Security.Permissions;
+using DotNetNuke.Services.Log.EventLog;
+using DotNetNuke.Web.Client.ClientResourceManagement;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnRibbonBarTool : Control, IDnnRibbonBarTool
+ {
+ #region Properties
+
+ private IDictionary _allTools;
+ private DnnTextLink _dnnLink;
+ private DnnTextButton _dnnLinkButton;
+
+ public virtual RibbonBarToolInfo ToolInfo
+ {
+ get
+ {
+ if ((ViewState["ToolInfo"] == null))
+ {
+ ViewState.Add("ToolInfo", new RibbonBarToolInfo());
+ }
+ return (RibbonBarToolInfo) ViewState["ToolInfo"];
+ }
+ set
+ {
+ ViewState["ToolInfo"] = value;
+ }
+ }
+
+ public virtual string NavigateUrl
+ {
+ get
+ {
+ return Utilities.GetViewStateAsString(ViewState["NavigateUrl"], Null.NullString);
+ }
+ set
+ {
+ ViewState["NavigateUrl"] = value;
+ }
+ }
+
+ public virtual string ToolCssClass
+ {
+ get
+ {
+ return Utilities.GetViewStateAsString(ViewState["ToolCssClass"], Null.NullString);
+ }
+ set
+ {
+ ViewState["ToolCssClass"] = value;
+ }
+ }
+
+ public virtual string Text
+ {
+ get
+ {
+ return Utilities.GetViewStateAsString(ViewState["Text"], Null.NullString);
+ }
+ set
+ {
+ ViewState["Text"] = value;
+ }
+ }
+
+ public virtual string ToolTip
+ {
+ get
+ {
+ return Utilities.GetViewStateAsString(ViewState["ToolTip"], Null.NullString);
+ }
+ set
+ {
+ ViewState["ToolTip"] = value;
+ }
+ }
+
+ protected virtual DnnTextButton DnnLinkButton
+ {
+ get
+ {
+ if ((_dnnLinkButton == null))
+ {
+ // Appending _CPCommandBtn is also assumed in the RibbonBar.ascx. If changed, one would need to change in both places.
+ _dnnLinkButton = new DnnTextButton {ID = ID + "_CPCommandBtn"};
+ }
+ return _dnnLinkButton;
+ }
+ }
+
+ protected virtual DnnTextLink DnnLink
+ {
+ get
+ {
+ if ((_dnnLink == null))
+ {
+ _dnnLink = new DnnTextLink();
+ }
+ return _dnnLink;
+ }
+ }
+
+ protected virtual IDictionary AllTools
+ {
+ get
+ {
+ if (_allTools == null)
+ {
+ _allTools = new Dictionary
+ {
+ //Framework
+ {"PageSettings", new RibbonBarToolInfo("PageSettings", false, false, "", "", "", true)},
+ {"CopyPage", new RibbonBarToolInfo("CopyPage", false, false, "", "", "", true)},
+ {"DeletePage", new RibbonBarToolInfo("DeletePage", false, true, "", "", "", true)},
+ {"ImportPage", new RibbonBarToolInfo("ImportPage", false, false, "", "", "", true)},
+ {"ExportPage", new RibbonBarToolInfo("ExportPage", false, false, "", "", "", true)},
+ {"NewPage", new RibbonBarToolInfo("NewPage", false, false, "", "", "", true)},
+ {"CopyPermissionsToChildren", new RibbonBarToolInfo("CopyPermissionsToChildren", false, true, "", "", "", false)},
+ {"CopyDesignToChildren", new RibbonBarToolInfo("CopyDesignToChildren", false, true, "", "", "", false)},
+ {"Help", new RibbonBarToolInfo("Help", false, false, "_Blank", "", "", false)},
+ //Modules On Tabs
+ {"Console", new RibbonBarToolInfo("Console", false, false, "", "Console", "", false)},
+ {"HostConsole", new RibbonBarToolInfo("HostConsole", true, false, "", "Console", "", false)},
+ {"UploadFile", new RibbonBarToolInfo("UploadFile", false, false, "", "", "WebUpload", true)},
+ {"NewRole", new RibbonBarToolInfo("NewRole", false, false, "", "Security Roles", "Edit", true)},
+ {"NewUser", new RibbonBarToolInfo("NewUser", false, false, "", "User Accounts", "Edit", true)},
+ {"ClearCache", new RibbonBarToolInfo("ClearCache", true, true, "", "", "", false)},
+ {"RecycleApp", new RibbonBarToolInfo("RecycleApp", true, true, "", "", "", false)}
+ };
+ }
+
+ return _allTools;
+ }
+ }
+
+ private static PortalSettings PortalSettings
+ {
+ get
+ {
+ return PortalSettings.Current;
+ }
+ }
+
+ public virtual string ToolName
+ {
+ get
+ {
+ return ToolInfo.ToolName;
+ }
+ set
+ {
+ if ((AllTools.ContainsKey(value)))
+ {
+ ToolInfo = AllTools[value];
+ }
+ else
+ {
+ throw new NotSupportedException("Tool not found [" + value + "]");
+ }
+ }
+ }
+
+ #endregion
+
+ #region Events
+
+ protected override void CreateChildControls()
+ {
+ Controls.Clear();
+ Controls.Add(DnnLinkButton);
+ Controls.Add(DnnLink);
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ EnsureChildControls();
+ DnnLinkButton.Click += ControlPanelTool_OnClick;
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ ProcessTool();
+ Visible = (DnnLink.Visible || DnnLinkButton.Visible);
+ base.OnPreRender(e);
+ }
+
+ public virtual void ControlPanelTool_OnClick(object sender, EventArgs e)
+ {
+ switch (ToolInfo.ToolName)
+ {
+ case "DeletePage":
+ if ((HasToolPermissions("DeletePage")))
+ {
+ string url = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "Tab", "action=delete");
+ Page.Response.Redirect(url, true);
+ }
+ break;
+ case "CopyPermissionsToChildren":
+ if ((HasToolPermissions("CopyPermissionsToChildren")))
+ {
+ TabController.CopyPermissionsToChildren(PortalSettings.ActiveTab, PortalSettings.ActiveTab.TabPermissions);
+ Page.Response.Redirect(Page.Request.RawUrl);
+ }
+ break;
+ case "CopyDesignToChildren":
+ if ((HasToolPermissions("CopyDesignToChildren")))
+ {
+ TabController.CopyDesignToChildren(PortalSettings.ActiveTab, PortalSettings.ActiveTab.SkinSrc, PortalSettings.ActiveTab.ContainerSrc);
+ Page.Response.Redirect(Page.Request.RawUrl);
+ }
+ break;
+ case "ClearCache":
+ if ((HasToolPermissions("ClearCache")))
+ {
+ ClearCache();
+ ClientResourceManager.ClearCache();
+ Page.Response.Redirect(Page.Request.RawUrl);
+ }
+ break;
+ case "RecycleApp":
+ if ((HasToolPermissions("RecycleApp")))
+ {
+ RestartApplication();
+ Page.Response.Redirect(Page.Request.RawUrl);
+ }
+ break;
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected virtual void ProcessTool()
+ {
+ DnnLink.Visible = false;
+ DnnLinkButton.Visible = false;
+
+ if ((!string.IsNullOrEmpty(ToolInfo.ToolName)))
+ {
+ if ((ToolInfo.UseButton))
+ {
+ DnnLinkButton.Visible = HasToolPermissions(ToolInfo.ToolName);
+ DnnLinkButton.Enabled = EnableTool();
+ DnnLinkButton.Localize = false;
+
+ DnnLinkButton.CssClass = ToolCssClass;
+ DnnLinkButton.DisabledCssClass = ToolCssClass + " dnnDisabled";
+
+ DnnLinkButton.Text = GetText();
+ DnnLinkButton.ToolTip = GetToolTip();
+ }
+ else
+ {
+ DnnLink.Visible = HasToolPermissions(ToolInfo.ToolName);
+ DnnLink.Enabled = EnableTool();
+ DnnLink.Localize = false;
+
+ if ((DnnLink.Enabled))
+ {
+ DnnLink.NavigateUrl = BuildToolUrl();
+
+ //can't find the page, disable it?
+ if ((string.IsNullOrEmpty(DnnLink.NavigateUrl)))
+ {
+ DnnLink.Enabled = false;
+ }
+ //create popup event
+ else if (ToolInfo.ShowAsPopUp && PortalSettings.EnablePopUps)
+ {
+ // Prevent PageSettings in a popup if SSL is enabled and enforced, which causes redirection/javascript broswer security issues.
+ if (ToolInfo.ToolName == "PageSettings" || ToolInfo.ToolName == "CopyPage" || ToolInfo.ToolName == "NewPage")
+ {
+ if (!(PortalSettings.SSLEnabled && PortalSettings.SSLEnforced))
+ {
+ DnnLink.Attributes.Add("onclick", "return " + UrlUtils.PopUpUrl(DnnLink.NavigateUrl, this, PortalSettings, true, false));
+ }
+ }
+ else
+ {
+ DnnLink.Attributes.Add("onclick", "return " + UrlUtils.PopUpUrl(DnnLink.NavigateUrl, this, PortalSettings, true, false));
+ }
+ }
+ }
+
+ DnnLink.CssClass = ToolCssClass;
+ DnnLink.DisabledCssClass = ToolCssClass + " dnnDisabled";
+
+ DnnLink.Text = GetText();
+ DnnLink.ToolTip = GetToolTip();
+ DnnLink.Target = ToolInfo.LinkWindowTarget;
+ }
+ }
+ }
+
+ protected virtual bool EnableTool()
+ {
+ bool returnValue = true;
+
+ switch (ToolInfo.ToolName)
+ {
+ case "DeletePage":
+ if ((TabController.IsSpecialTab(TabController.CurrentPage.TabID, PortalSettings.PortalId)))
+ {
+ returnValue = false;
+ }
+ break;
+ case "CopyDesignToChildren":
+ case "CopyPermissionsToChildren":
+ returnValue = ActiveTabHasChildren();
+ if ((returnValue && ToolInfo.ToolName == "CopyPermissionsToChildren"))
+ {
+ if ((PortalSettings.ActiveTab.IsSuperTab))
+ {
+ returnValue = false;
+ }
+ }
+ break;
+ }
+
+ return returnValue;
+ }
+
+ protected virtual bool HasToolPermissions(string toolName)
+ {
+ bool isHostTool = false;
+ if ((ToolInfo.ToolName == toolName))
+ {
+ isHostTool = ToolInfo.IsHostTool;
+ }
+ else if ((AllTools.ContainsKey(toolName)))
+ {
+ isHostTool = AllTools[toolName].IsHostTool;
+ }
+
+ if ((isHostTool && !UserController.GetCurrentUserInfo().IsSuperUser))
+ {
+ return false;
+ }
+
+ bool returnValue = true;
+ switch (toolName)
+ {
+ case "PageSettings":
+ case "CopyDesignToChildren":
+ case "CopyPermissionsToChildren":
+ returnValue = TabPermissionController.CanManagePage();
+
+ if ((returnValue && toolName == "CopyPermissionsToChildren"))
+ {
+ if ((!PortalSecurity.IsInRole("Administrators")))
+ {
+ returnValue = false;
+ }
+ }
+ break;
+ case "CopyPage":
+ returnValue = TabPermissionController.CanCopyPage();
+ break;
+ case "DeletePage":
+ returnValue = (TabPermissionController.CanDeletePage());
+ break;
+ case "ImportPage":
+ returnValue = TabPermissionController.CanImportPage();
+ break;
+ case "ExportPage":
+ returnValue = TabPermissionController.CanExportPage();
+ break;
+ case "NewPage":
+ returnValue = TabPermissionController.CanAddPage();
+ break;
+ case "Help":
+ returnValue = !string.IsNullOrEmpty(Host.HelpURL);
+ break;
+ default:
+ //if it has a module definition, look it up and check permissions
+ //if it doesn't exist, assume no permission
+ string friendlyName = "";
+ if ((ToolInfo.ToolName == toolName))
+ {
+ friendlyName = ToolInfo.ModuleFriendlyName;
+ }
+ else if ((AllTools.ContainsKey(toolName)))
+ {
+ friendlyName = AllTools[toolName].ModuleFriendlyName;
+ }
+
+ if ((!string.IsNullOrEmpty(friendlyName)))
+ {
+ returnValue = false;
+ ModuleInfo moduleInfo;
+
+ if ((isHostTool))
+ {
+ moduleInfo = GetInstalledModule(Null.NullInteger, friendlyName);
+ }
+ else
+ {
+ moduleInfo = GetInstalledModule(PortalSettings.PortalId, friendlyName);
+ }
+
+ if ((moduleInfo != null))
+ {
+ returnValue = ModulePermissionController.CanViewModule(moduleInfo);
+ }
+ }
+ break;
+ }
+
+ return returnValue;
+ }
+
+ protected virtual string BuildToolUrl()
+ {
+ if ((ToolInfo.IsHostTool && !UserController.GetCurrentUserInfo().IsSuperUser))
+ {
+ return "javascript:void(0);";
+ }
+
+ if ((!string.IsNullOrEmpty(NavigateUrl)))
+ {
+ return NavigateUrl;
+ }
+
+ string returnValue = "javascript:void(0);";
+ switch (ToolInfo.ToolName)
+ {
+ case "PageSettings":
+ returnValue = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "Tab", "action=edit");
+ break;
+
+ case "CopyPage":
+ returnValue = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "Tab", "action=copy");
+ break;
+
+ case "DeletePage":
+ returnValue = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "Tab", "action=delete");
+ break;
+
+ case "ImportPage":
+ returnValue = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "ImportTab");
+ break;
+
+ case "ExportPage":
+ returnValue = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "ExportTab");
+ break;
+
+ case "NewPage":
+ returnValue = Globals.NavigateURL("Tab");
+ break;
+ case "Help":
+ if (!string.IsNullOrEmpty(Host.HelpURL))
+ {
+ var version = Globals.FormatVersion(DotNetNukeContext.Current.Application.Version, false);
+ returnValue = Globals.FormatHelpUrl(Host.HelpURL, PortalSettings, "Home", version);
+ }
+ break;
+ case "UploadFile":
+ case "HostUploadFile":
+ returnValue = Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "WebUpload");
+ break;
+ default:
+ if ((!string.IsNullOrEmpty(ToolInfo.ModuleFriendlyName)))
+ {
+ var additionalParams = new List();
+ returnValue = GetTabURL(additionalParams);
+ }
+ break;
+ }
+ return returnValue;
+ }
+
+ protected virtual string GetText()
+ {
+ if ((string.IsNullOrEmpty(Text)))
+ {
+ return GetString(string.Format("Tool.{0}.Text", ToolInfo.ToolName));
+ }
+
+ return Text;
+ }
+
+ protected virtual string GetToolTip()
+ {
+ if ((ToolInfo.ToolName == "DeletePage"))
+ {
+ if ((TabController.IsSpecialTab(TabController.CurrentPage.TabID, PortalSettings.PortalId)))
+ {
+ return GetString("Tool.DeletePage.Special.ToolTip");
+ }
+ }
+
+ if ((string.IsNullOrEmpty(Text)))
+ {
+ string tip = GetString(string.Format("Tool.{0}.ToolTip", ToolInfo.ToolName));
+ if ((string.IsNullOrEmpty(tip)))
+ {
+ tip = GetString(string.Format("Tool.{0}.Text", ToolInfo.ToolName));
+ }
+ return tip;
+ }
+
+ return ToolTip;
+ }
+
+ protected virtual string GetTabURL(List additionalParams)
+ {
+ int portalId = (ToolInfo.IsHostTool) ? Null.NullInteger : PortalSettings.PortalId;
+
+ string strURL = string.Empty;
+
+ if (((additionalParams == null)))
+ {
+ additionalParams = new List();
+ }
+
+ var moduleCtrl = new ModuleController();
+ var moduleInfo = moduleCtrl.GetModuleByDefinition(portalId, ToolInfo.ModuleFriendlyName);
+
+ if (((moduleInfo != null)))
+ {
+ bool isHostPage = (portalId == Null.NullInteger);
+ if ((!string.IsNullOrEmpty(ToolInfo.ControlKey)))
+ {
+ additionalParams.Insert(0, "mid=" + moduleInfo.ModuleID);
+ if (ToolInfo.ShowAsPopUp && PortalSettings.EnablePopUps)
+ {
+ additionalParams.Add("popUp=true");
+ }
+ }
+
+ string currentCulture = Thread.CurrentThread.CurrentCulture.Name;
+ strURL = Globals.NavigateURL(moduleInfo.TabID, isHostPage, PortalSettings, ToolInfo.ControlKey, currentCulture, additionalParams.ToArray());
+ }
+
+ return strURL;
+ }
+
+ protected virtual bool ActiveTabHasChildren()
+ {
+ var children = TabController.GetTabsByParent(PortalSettings.ActiveTab.TabID, PortalSettings.ActiveTab.PortalID);
+
+ if (((children == null) || children.Count < 1))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ protected virtual string GetString(string key)
+ {
+ return Utilities.GetLocalizedStringFromParent(key, this);
+ }
+
+ private static ModuleInfo GetInstalledModule(int portalID, string friendlyName)
+ {
+ var moduleCtrl = new ModuleController();
+ return moduleCtrl.GetModuleByDefinition(portalID, friendlyName);
+ }
+
+ protected virtual void ClearCache()
+ {
+ DataCache.ClearCache();
+ }
+
+ protected virtual void RestartApplication()
+ {
+ var objEv = new EventLogController();
+ var objEventLogInfo = new LogInfo { BypassBuffering = true, LogTypeKey = EventLogController.EventLogType.HOST_ALERT.ToString() };
+ objEventLogInfo.AddProperty("Message", GetString("UserRestart"));
+ objEv.AddLog(objEventLogInfo);
+ Config.Touch();
+ }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRotator.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRotator.cs
new file mode 100644
index 00000000000..97939b8b767
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRotator.cs
@@ -0,0 +1,32 @@
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRotator : RadRotator
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRotatorItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRotatorItem.cs
new file mode 100644
index 00000000000..cbdc674473d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnRotatorItem.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnRotatorItem : RadRotatorItem
+ {
+ public DnnRotatorItem()
+ {
+ }
+
+ public DnnRotatorItem(object dataItem) : base(dataItem)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScheduler.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScheduler.cs
new file mode 100644
index 00000000000..a30fd1664dd
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScheduler.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnScheduler : RadScheduler
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerContextMenu.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerContextMenu.cs
new file mode 100644
index 00000000000..67bc9ca734e
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerContextMenu.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSchedulerContextMenu : RadSchedulerContextMenu
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerResourceStyleMapping.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerResourceStyleMapping.cs
new file mode 100644
index 00000000000..745a1c10594
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerResourceStyleMapping.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSchedulerResourceStyleMapping : ResourceStyleMapping
+ {
+ public DnnSchedulerResourceStyleMapping()
+ {
+ }
+
+ public DnnSchedulerResourceStyleMapping(string type, string key, string applyCssClass) : base(type, key, applyCssClass)
+ {
+ }
+
+ public DnnSchedulerResourceStyleMapping(string type, string key, string text, string applyCssClass) : base(type, key, text, applyCssClass)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerResourceType.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerResourceType.cs
new file mode 100644
index 00000000000..6f2f9adac30
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSchedulerResourceType.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSchedulerResourceType : ResourceType
+ {
+ public DnnSchedulerResourceType()
+ {
+ }
+
+ public DnnSchedulerResourceType(string resourceTypeName) : base(resourceTypeName)
+ {
+ }
+
+ public DnnSchedulerResourceType(string resourceTypeName, bool allowMultipleResourceValues) : base(resourceTypeName, allowMultipleResourceValues)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScriptBlock.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScriptBlock.cs
new file mode 100644
index 00000000000..08fd01b3bc3
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScriptBlock.cs
@@ -0,0 +1,30 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnScriptBlock : RadScriptBlock
+ {
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScriptManager.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScriptManager.cs
new file mode 100644
index 00000000000..adfe19a6470
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnScriptManager.cs
@@ -0,0 +1,30 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using Telerik.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ class DnnScriptManager : RadScriptManager
+ {
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMap.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMap.cs
new file mode 100644
index 00000000000..025e8d49596
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMap.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSiteMap : RadSiteMap
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapLevelSetting.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapLevelSetting.cs
new file mode 100644
index 00000000000..00544bb0839
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapLevelSetting.cs
@@ -0,0 +1,47 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSiteMapLevelSetting : SiteMapLevelSetting
+ {
+ public DnnSiteMapLevelSetting()
+ {
+ }
+
+ public DnnSiteMapLevelSetting(int level) : base(level)
+ {
+ }
+
+ public DnnSiteMapLevelSetting(int level, SiteMapLayout layout) : base(level, layout)
+ {
+ }
+
+ public DnnSiteMapLevelSetting(SiteMapLayout layout) : base(layout)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapNode.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapNode.cs
new file mode 100644
index 00000000000..d566829b1bd
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapNode.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSiteMapNode : RadSiteMapNode
+ {
+ public DnnSiteMapNode()
+ {
+ }
+
+ public DnnSiteMapNode(string text, string navigateUrl) : base(text, navigateUrl)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapNodeBinding.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapNodeBinding.cs
new file mode 100644
index 00000000000..c1d0a2563cb
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSiteMapNodeBinding.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSiteMapNodeBinding : RadSiteMapNodeBinding
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSlider.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSlider.cs
new file mode 100644
index 00000000000..dec1a588d6e
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSlider.cs
@@ -0,0 +1,86 @@
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Web.UI;
+using System.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSlider : RadSlider, ILocalizable
+ {
+ private bool _localize = true;
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ base.Render(writer);
+ }
+
+ public string ResourceKey { get; set; }
+
+#region ILocalizable Implementation
+ public bool Localize
+ {
+ get
+ {
+ if (base.DesignMode)
+ {
+ return false;
+ }
+ return _localize;
+ }
+ set
+ {
+ _localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((this.Localize) && (!(String.IsNullOrEmpty(this.ResourceKey))))
+ {
+ if (!(String.IsNullOrEmpty(base.DecreaseText)))
+ {
+ base.DecreaseText = Utilities.GetLocalizedStringFromParent(String.Format("{0}.Decrease", this.ResourceKey), this);
+ }
+
+ if (!(String.IsNullOrEmpty(base.DragText)))
+ {
+ base.DragText = Utilities.GetLocalizedStringFromParent(String.Format("{0}.Drag", this.ResourceKey), this);
+ }
+
+ if (!(String.IsNullOrEmpty(base.IncreaseText)))
+ {
+ base.IncreaseText = Utilities.GetLocalizedStringFromParent(String.Format("{0}.Increase", this.ResourceKey), this);
+ }
+ }
+ }
+#endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSliderItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSliderItem.cs
new file mode 100644
index 00000000000..fd5ed7fa586
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSliderItem.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSliderItem : RadSliderItem
+ {
+ public DnnSliderItem()
+ {
+ }
+
+ public DnnSliderItem(string text) : base(text)
+ {
+ }
+
+ public DnnSliderItem(string text, string value) : base(text, value)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSpell.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSpell.cs
new file mode 100644
index 00000000000..38040cb3a7f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSpell.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSpell : RadSpell
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitBar.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitBar.cs
new file mode 100644
index 00000000000..14ec3137c6f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitBar.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSplitBar : RadSplitBar
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitPane.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitPane.cs
new file mode 100644
index 00000000000..e4ba628ebbb
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitPane.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSplitPane : RadPane
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitSlidingPane.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitSlidingPane.cs
new file mode 100644
index 00000000000..d49ce9bf433
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitSlidingPane.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSplitSlidingPane : RadSlidingPane
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitSlidingZone.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitSlidingZone.cs
new file mode 100644
index 00000000000..14b3ddda3d7
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitSlidingZone.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSplitSlidingZone : RadSlidingZone
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitter.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitter.cs
new file mode 100644
index 00000000000..2cde741bdc3
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnSplitter.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnSplitter : RadSplitter
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTab.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTab.cs
new file mode 100644
index 00000000000..47985c06c7f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTab.cs
@@ -0,0 +1,75 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildren(true)]
+ public class DnnTab : WebControl
+ {
+ public DnnTab() : base("div")
+ {
+ }
+
+ public override ControlCollection Controls
+ {
+ get
+ {
+ EnsureChildControls();
+ return base.Controls;
+ }
+ }
+
+ [TemplateInstance(TemplateInstance.Single)]
+ public virtual ITemplate Header { get; set; }
+
+ [TemplateInstance(TemplateInstance.Single)]
+ public virtual ITemplate Content { get; set; }
+
+ protected override void CreateChildControls()
+ {
+ Controls.Clear();
+
+ if (Content != null)
+ {
+ Content.InstantiateIn(this);
+ }
+ }
+
+ public override Control FindControl(string id)
+ {
+ EnsureChildControls();
+ return base.FindControl(id);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ base.RenderBeginTag(writer);
+ base.RenderChildren(writer);
+ base.RenderEndTag(writer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabCollection.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabCollection.cs
new file mode 100644
index 00000000000..621adeb1883
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabCollection.cs
@@ -0,0 +1,69 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTabCollection : ControlCollection
+ {
+ public DnnTabCollection(Control owner) : base(owner)
+ {
+ }
+
+ public new DnnTab this[int index]
+ {
+ get
+ {
+ return (DnnTab) base[index];
+ }
+ }
+
+ public override void Add(Control child)
+ {
+ if (child is DnnTab)
+ {
+ base.Add(child);
+ }
+ else
+ {
+ throw new ArgumentException("DnnTabCollection must contain controls of type DnnTab");
+ }
+ }
+
+ public override void AddAt(int index, Control child)
+ {
+ if (child is DnnTab)
+ {
+ base.AddAt(index, child);
+ }
+ else
+ {
+ throw new ArgumentException("DnnTabCollection must contain controls of type DnnTab");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabPanel.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabPanel.cs
new file mode 100644
index 00000000000..06c318311b3
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabPanel.cs
@@ -0,0 +1,135 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using Telerik.Web.UI;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [ParseChildrenAttribute(true)]
+ public class DnnTabPanel : WebControl
+ {
+ private DnnTabCollection _Tabs;
+ private RadMultiPage _TelerikPages;
+ private RadTabStrip _TelerikTabs;
+
+ private RadTabStrip TelerikTabs
+ {
+ get
+ {
+ if (_TelerikTabs == null)
+ {
+ _TelerikTabs = new RadTabStrip();
+ }
+
+ return _TelerikTabs;
+ }
+ }
+
+ private RadMultiPage TelerikPages
+ {
+ get
+ {
+ if (_TelerikPages == null)
+ {
+ _TelerikPages = new RadMultiPage();
+ }
+
+ return _TelerikPages;
+ }
+ }
+
+ public DnnTabCollection Tabs
+ {
+ get
+ {
+ if (_Tabs == null)
+ {
+ _Tabs = new DnnTabCollection(this);
+ }
+
+ return _Tabs;
+ }
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.EnsureChildControls();
+ }
+
+ protected override void CreateChildControls()
+ {
+ Controls.Clear();
+
+ TelerikTabs.ID = ID + "_Tabs";
+ TelerikTabs.Skin = "Office2007";
+ TelerikTabs.EnableEmbeddedSkins = true;
+
+ TelerikPages.ID = ID + "_Pages";
+
+ TelerikTabs.MultiPageID = TelerikPages.ID;
+
+ Controls.Add(TelerikTabs);
+ Controls.Add(TelerikPages);
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ if ((!Page.IsPostBack))
+ {
+ TelerikTabs.SelectedIndex = 0;
+ TelerikPages.SelectedIndex = 0;
+
+ int idIndex = 0;
+
+ foreach (DnnTab t in Tabs)
+ {
+ RadTab tab = new RadTab();
+ tab.TabTemplate = t.Header;
+ RadPageView pageView = new RadPageView();
+ pageView.Controls.Add(t);
+
+ tab.PageViewID = "PV_" + idIndex;
+ pageView.ID = "PV_" + idIndex;
+
+ TelerikTabs.Tabs.Add(tab);
+ TelerikPages.PageViews.Add(pageView);
+
+ idIndex = idIndex + 1;
+ }
+ }
+
+ base.OnPreRender(e);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ base.Render(writer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabStrip.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabStrip.cs
new file mode 100644
index 00000000000..91bb785c9fb
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTabStrip.cs
@@ -0,0 +1,41 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTabStrip : RadTabStrip
+ {
+
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ Utilities.ApplySkin(this);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTagCloud.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTagCloud.cs
new file mode 100644
index 00000000000..212c733d37e
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTagCloud.cs
@@ -0,0 +1,36 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTagCloud : RadTagCloud
+ {
+ protected void OnItemDataBound(DnnTagCloudItem item)
+ {
+ base.OnItemDataBound(item);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTagCloudItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTagCloudItem.cs
new file mode 100644
index 00000000000..2f992630041
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTagCloudItem.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTagCloudItem : RadTagCloudItem
+ {
+ public DnnTagCloudItem()
+ {
+ }
+
+ public DnnTagCloudItem(string text) : base(text)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextBox.cs
new file mode 100644
index 00000000000..c7a86cd203c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextBox.cs
@@ -0,0 +1,40 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTextBox : RadTextBox
+ {
+
+ //public DnnTextBox()
+ //{
+ // Utilities.ApplySkin(this);
+ //}
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextButton.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextButton.cs
new file mode 100644
index 00000000000..acfe5ca5551
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextButton.cs
@@ -0,0 +1,167 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.ComponentModel;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTextButton : LinkButton, ILocalizable
+ {
+ private bool _localize = true;
+
+ #region "Public Properties"
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public string ConfirmMessage
+ {
+ get
+ {
+ return ViewState["ConfirmMessage"] == null ? string.Empty : (string) ViewState["ConfirmMessage"];
+ }
+ set
+ {
+ ViewState["ConfirmMessage"] = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public override string CssClass
+ {
+ get
+ {
+ return ViewState["CssClass"] == null ? string.Empty : (string) ViewState["CssClass"];
+ }
+ set
+ {
+ ViewState["CssClass"] = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public new string DisabledCssClass
+ {
+ get
+ {
+ return ViewState["DisabledCssClass"] == null ? string.Empty : (string) ViewState["DisabledCssClass"];
+ }
+ set
+ {
+ ViewState["DisabledCssClass"] = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public new string Text
+ {
+ get
+ {
+ return ViewState["Text"] == null ? string.Empty : (string) ViewState["Text"];
+ }
+ set
+ {
+ ViewState["Text"] = value;
+ }
+ }
+
+ #endregion
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ if (!Enabled && !string.IsNullOrEmpty(DisabledCssClass))
+ {
+ CssClass = DisabledCssClass;
+ }
+ writer.AddAttribute("class", CssClass.Trim());
+ base.Render(writer);
+ }
+
+ #region "ILocalizable Implementation"
+
+ public bool Localize
+ {
+ get
+ {
+ return _localize;
+ }
+ set
+ {
+ _localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((Localize))
+ {
+ if ((!string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(ToolTip, LocalResourceFile);
+ }
+
+ if ((!string.IsNullOrEmpty(Text)))
+ {
+ Text = Localization.GetString(Text, LocalResourceFile);
+
+ if ((string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(string.Format("{0}.ToolTip", Text), LocalResourceFile);
+ }
+
+ if ((string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Text;
+ }
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextLink.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextLink.cs
new file mode 100644
index 00000000000..b1ba9f6d393
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTextLink.cs
@@ -0,0 +1,214 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.ComponentModel;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTextLink : WebControl, ILocalizable
+ {
+ private bool _localize = true;
+ private HyperLink _textHyperlinkControl;
+
+ public DnnTextLink() : base("span")
+ {
+ CssClass = "dnnTextLink";
+ DisabledCssClass = "dnnTextLink disabled";
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public string Text
+ {
+ get
+ {
+ return TextHyperlinkControl.Text;
+ }
+ set
+ {
+ TextHyperlinkControl.Text = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public override string ToolTip
+ {
+ get
+ {
+ return TextHyperlinkControl.ToolTip;
+ }
+ set
+ {
+ TextHyperlinkControl.ToolTip = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Behavior")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public string NavigateUrl
+ {
+ get
+ {
+ return TextHyperlinkControl.NavigateUrl;
+ }
+ set
+ {
+ TextHyperlinkControl.NavigateUrl = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Behavior")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public string Target
+ {
+ get
+ {
+ return TextHyperlinkControl.Target;
+ }
+ set
+ {
+ TextHyperlinkControl.Target = value;
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DefaultValue("")]
+ [Localizable(true)]
+ public new string DisabledCssClass
+ {
+ get
+ {
+ return ViewState["DisabledCssClass"] == null ? string.Empty : (string) ViewState["DisabledCssClass"];
+ }
+ set
+ {
+ ViewState["DisabledCssClass"] = value;
+ }
+ }
+
+ private HyperLink TextHyperlinkControl
+ {
+ get
+ {
+ if (_textHyperlinkControl == null)
+ {
+ _textHyperlinkControl = new HyperLink();
+ }
+ return _textHyperlinkControl;
+ }
+ }
+
+ protected override void CreateChildControls()
+ {
+ Controls.Clear();
+ Controls.Add(TextHyperlinkControl);
+ }
+
+ #region "Protected Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ }
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+
+ if ((!Enabled))
+ {
+ if ((!string.IsNullOrEmpty(DisabledCssClass)))
+ {
+ CssClass = DisabledCssClass;
+ }
+ NavigateUrl = "javascript:void(0);";
+ }
+
+ base.RenderBeginTag(writer);
+ base.RenderChildren(writer);
+ base.RenderEndTag(writer);
+ }
+
+ #endregion
+
+ #region "ILocalizable Implementation"
+
+ public bool Localize
+ {
+ get
+ {
+ return _localize;
+ }
+ set
+ {
+ _localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((Localize))
+ {
+ if ((!string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(ToolTip, LocalResourceFile);
+ }
+
+ if ((!string.IsNullOrEmpty(Text)))
+ {
+ Text = Localization.GetString(Text, LocalResourceFile);
+
+ if ((string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Localization.GetString(string.Format("{0}.ToolTip", Text), LocalResourceFile);
+ }
+
+ if ((string.IsNullOrEmpty(ToolTip)))
+ {
+ ToolTip = Text;
+ }
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTicker.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTicker.cs
new file mode 100644
index 00000000000..60820ee1ebd
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTicker.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTicker : RadTicker
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTickerItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTickerItem.cs
new file mode 100644
index 00000000000..1c77e24160b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTickerItem.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTickerItem : RadTickerItem
+ {
+ public DnnTickerItem()
+ {
+ }
+
+ public DnnTickerItem(string text) : base(text)
+ {
+ }
+
+ public DnnTickerItem(string text, string navigateUrl) : base(text, navigateUrl)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimePicker.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimePicker.cs
new file mode 100644
index 00000000000..e5e8564a047
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimePicker.cs
@@ -0,0 +1,41 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTimePicker : RadTimePicker
+ {
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
+ base.EnableEmbeddedBaseStylesheet = true;
+ Utilities.ApplySkin(this, string.Empty, "DatePicker");
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeView.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeView.cs
new file mode 100644
index 00000000000..36985957587
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeView.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTimeView : RadTimeView
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeZoneComboBox.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeZoneComboBox.cs
new file mode 100644
index 00000000000..1c7dfc8af4b
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeZoneComboBox.cs
@@ -0,0 +1,47 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web.UI.WebControls;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnTimeZoneComboBox : DropDownList
+ {
+
+ protected override void OnInit(System.EventArgs e)
+ {
+ //Utilities.ApplySkin(this);
+ base.OnInit(e);
+
+ this.DataTextField = "DisplayName";
+ this.DataValueField = "Id";
+
+ this.DataSource = TimeZoneInfo.GetSystemTimeZones();
+ this.DataBind();
+ }
+ }
+}
+
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeZoneEditControl.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeZoneEditControl.cs
new file mode 100644
index 00000000000..ff8978ba33c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTimeZoneEditControl.cs
@@ -0,0 +1,114 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using DotNetNuke.UI.WebControls;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using DotNetNuke.Web.UI.WebControls.Extensions;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnTimeZoneEditControl : TextEditControl
+ {
+
+
+ private DnnTimeZoneComboBox TimeZones;
+ #region "Constructors"
+
+ public DnnTimeZoneEditControl()
+ {
+ }
+
+ #endregion
+
+ protected override void CreateChildControls()
+ {
+ TimeZones = new DnnTimeZoneComboBox();
+
+ Controls.Clear();
+ Controls.Add(TimeZones);
+
+ base.CreateChildControls();
+ }
+
+ public override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
+ {
+ bool dataChanged = false;
+ string presentValue = StringValue;
+ string postedValue = TimeZones.SelectedValue;
+ if (!presentValue.Equals(postedValue))
+ {
+ Value = postedValue;
+ dataChanged = true;
+ }
+
+ return dataChanged;
+ }
+
+ protected override void OnDataChanged(EventArgs e)
+ {
+ var args = new PropertyEditorEventArgs(Name);
+ args.Value = TimeZoneInfo.FindSystemTimeZoneById(StringValue);
+ args.OldValue = OldStringValue;
+ args.StringValue = StringValue;
+ base.OnValueChanged(args);
+ }
+
+ protected override void OnInit(System.EventArgs e)
+ {
+ this.EnsureChildControls();
+ base.OnInit(e);
+ }
+
+ protected override void OnPreRender(System.EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ TimeZones.DataBind(StringValue);
+
+ if ((Page != null) && this.EditMode == PropertyEditorMode.Edit)
+ {
+ this.Page.RegisterRequiresPostBack(this);
+ }
+ }
+
+ protected override void RenderEditMode(System.Web.UI.HtmlTextWriter writer)
+ {
+ this.RenderChildren(writer);
+ }
+
+ protected override void RenderViewMode(System.Web.UI.HtmlTextWriter writer)
+ {
+ string propValue = this.Page.Server.HtmlDecode(Convert.ToString(this.Value));
+ ControlStyle.AddAttributesToRender(writer);
+ writer.RenderBeginTag(HtmlTextWriterTag.Span);
+ writer.Write(propValue);
+ writer.RenderEndTag();
+ }
+
+ }
+
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBar.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBar.cs
new file mode 100644
index 00000000000..83a79213587
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBar.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnToolBar : RadToolBar
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarButton.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarButton.cs
new file mode 100644
index 00000000000..80f0933090c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarButton.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnToolBarButton : RadToolBarButton
+ {
+ public DnnToolBarButton()
+ {
+ }
+
+ public DnnToolBarButton(string text) : base(text)
+ {
+ }
+
+ public DnnToolBarButton(string text, bool isChecked, string @group) : base(text, isChecked, @group)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarDropDown.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarDropDown.cs
new file mode 100644
index 00000000000..8fd69719b6c
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarDropDown.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnToolBarDropDown : RadToolBarDropDown
+ {
+ public DnnToolBarDropDown()
+ {
+ }
+
+ public DnnToolBarDropDown(string text) : base(text)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarSplitButton.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarSplitButton.cs
new file mode 100644
index 00000000000..29717a89169
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolBarSplitButton.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnToolBarSplitButton : RadToolBarSplitButton
+ {
+ public DnnToolBarSplitButton()
+ {
+ }
+
+ public DnnToolBarSplitButton(string text) : base(text)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolTip.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolTip.cs
new file mode 100644
index 00000000000..c45ae69ba54
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolTip.cs
@@ -0,0 +1,84 @@
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#region Usings
+
+using System;
+using System.Web.UI;
+using DotNetNuke.Web.UI;
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnToolTip : RadToolTip, ILocalizable
+ {
+ private bool _localize = true;
+
+ protected override void Render(HtmlTextWriter writer)
+ {
+ LocalizeStrings();
+ base.Render(writer);
+ }
+
+ public string ResourceKey { get; set; }
+
+#region ILocalizable Implementation
+ public bool Localize
+ {
+ get
+ {
+ if (base.DesignMode)
+ {
+ return false;
+ }
+ return _localize;
+ }
+ set
+ {
+ _localize = value;
+ }
+ }
+
+ public string LocalResourceFile { get; set; }
+
+ public virtual void LocalizeStrings()
+ {
+ if ((this.Localize) && (!(String.IsNullOrEmpty(this.ResourceKey))))
+ {
+ if (!(String.IsNullOrEmpty(base.ManualCloseButtonText)))
+ {
+ base.ManualCloseButtonText = Utilities.GetLocalizedStringFromParent(String.Format("{0}.ManualCloseButtonText", this.ResourceKey), this);
+ }
+
+ if (!(String.IsNullOrEmpty(base.Text)))
+ {
+ base.Text = Utilities.GetLocalizedStringFromParent(String.Format("{0}.Text", this.ResourceKey), this);
+ }
+
+ if (!(String.IsNullOrEmpty(base.ToolTip)))
+ {
+ base.ToolTip = Utilities.GetLocalizedStringFromParent(String.Format("{0}.ToolTip", this.ResourceKey), this);
+ }
+ }
+ }
+#endregion
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolTipManager.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolTipManager.cs
new file mode 100644
index 00000000000..ac20bca5f57
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnToolTipManager.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnToolTipManager : RadToolTipManager
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeList.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeList.cs
new file mode 100644
index 00000000000..1455b29d060
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeList.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTreeList : RadTreeList
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeNode.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeNode.cs
new file mode 100644
index 00000000000..31cd7ce9145
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeNode.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnTreeNode : RadTreeNode
+ {
+
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeView.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeView.cs
new file mode 100644
index 00000000000..7ba7eada588
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeView.cs
@@ -0,0 +1,40 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnTreeView : RadTreeView
+ {
+
+ //public DnnTreeView()
+ //{
+ // Utilities.ApplySkin(this);
+ //}
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeViewContextMenu.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeViewContextMenu.cs
new file mode 100644
index 00000000000..2b00890ff34
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnTreeViewContextMenu.cs
@@ -0,0 +1,41 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public class DnnTreeViewContextMenu : RadTreeViewContextMenu
+ {
+
+ //public DnnTreeViewContextMenu()
+ //{
+ // Utilities.ApplySkin(this);
+ //}
+
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUnsortedList.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUnsortedList.cs
new file mode 100644
index 00000000000..f539e314a1a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUnsortedList.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Web.UI;
+using System.ComponentModel;
+using System.Web.UI.WebControls;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ ///
+ /// Creates a control that renders its childs as a bulleted list.
+ ///
+ ///
+ /// Control renders an unordered list HTML contol.
+ /// Each child control in is rendered as a separate list item.
+ /// To obtain a control over list item style, add a to a controls list,
+ /// and tune this object appropriately.
+ ///
+ public class DnnUnsortedList : WebControl, INamingContainer
+ {
+ private UniformControlCollection _listItems = null;
+
+ public DnnUnsortedList() : base(HtmlTextWriterTag.Ul)
+ {
+ }
+
+ protected override sealed ControlCollection CreateControlCollection()
+ {
+ return new TypedControlCollection(this);
+ }
+
+ [PersistenceMode(PersistenceMode.InnerDefaultProperty), MergableProperty(false)]
+ public virtual UniformControlCollection ListItems
+ {
+ get
+ {
+ return _listItems ?? (_listItems = new UniformControlCollection(this));
+ }
+ }
+
+ protected override void AddAttributesToRender(HtmlTextWriter writer)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
+ if (!string.IsNullOrEmpty(CssClass))
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
+ }
+ }
+
+ ///
+ /// A "macro" that adds a set of controls or control as a single list item (li). Use ListItems.Add(UnsortedListItem) method
+ ///
+ ///
+ /// All controls from the list will be rendered as a childs of a single list item.
+ ///
+ public void AddListItem(params Control[] listItemControls)
+ {
+ var listItem = new DnnUnsortedListItem();
+ listItem.AddControls(listItemControls);
+ ListItems.Add(listItem);
+ }
+
+ }
+
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUnsortedListItem.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUnsortedListItem.cs
new file mode 100644
index 00000000000..42d4617dbf4
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUnsortedListItem.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ ///
+ /// Creates a control that render one item in a list ($lt;li> control).
+ ///
+ ///
+ public class DnnUnsortedListItem : WebControl
+ {
+
+ public DnnUnsortedListItem() : base(HtmlTextWriterTag.Li)
+ {
+ }
+
+ public void AddControls(params Control[] childControls)
+ {
+ foreach (var childControl in childControls)
+ {
+ if (childControl != null)
+ {
+ Controls.Add(childControl);
+ }
+ }
+ }
+
+ protected override void AddAttributesToRender(HtmlTextWriter writer)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
+ if (!string.IsNullOrEmpty(CssClass))
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
+ }
+ if (!string.IsNullOrEmpty(ToolTip))
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, ToolTip);
+ }
+ }
+
+ }
+
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUpload.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUpload.cs
new file mode 100644
index 00000000000..4c7f411ac66
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnUpload.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnUpload : RadUpload
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnWindow.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnWindow.cs
new file mode 100644
index 00000000000..de7ed20af15
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnWindow.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnWindow : RadWindow
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnWindowManager.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnWindowManager.cs
new file mode 100644
index 00000000000..4626ded1851
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/DnnWindowManager.cs
@@ -0,0 +1,32 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class DnnWindowManager : RadWindowManager
+ {
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/Extensions/ListControlExtensions.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/Extensions/ListControlExtensions.cs
new file mode 100644
index 00000000000..5f0c0b260ce
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/Extensions/ListControlExtensions.cs
@@ -0,0 +1,109 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using System.Linq;
+using System.Web.UI.WebControls;
+
+namespace DotNetNuke.Web.UI.WebControls.Extensions
+{
+ public static class ListControlExtensions
+ {
+ public static void AddItem(this ListControl control, string text, string value)
+ {
+ control.Items.Add(new ListItem(text, value));
+ }
+
+ public static void InsertItem(this ListControl control, int index, string text, string value)
+ {
+ control.Items.Insert(index, new ListItem(text, value));
+ }
+
+ public static void DataBind(this ListControl control, string initialValue)
+ {
+ DataBind(control, initialValue, false);
+ }
+
+ public static void DataBind(this ListControl control, string initial, bool findByText)
+ {
+ control.DataBind();
+
+ Select(control, initial, findByText);
+ }
+
+ public static void Select(this ListControl control, string initial)
+ {
+ Select(control, initial, false, -1);
+ }
+
+ public static void Select(this ListControl control, string initial, bool findByText)
+ {
+ Select(control, initial, findByText, -1);
+ }
+
+ public static void Select(this ListControl control, string initial, bool findByText, int fallbackIndex)
+ {
+ control.ClearSelection();
+ if (findByText)
+ {
+ if (control.Items.FindByTextWithIgnoreCase(initial) != null)
+ {
+ control.Items.FindByTextWithIgnoreCase(initial).Selected = true;
+ }
+ else if (fallbackIndex > -1)
+ {
+ control.Items[fallbackIndex].Selected = true;
+ }
+ }
+ else
+ {
+ if (control.Items.FindByValueWithIgnoreCase(initial) != null)
+ {
+ control.Items.FindByValueWithIgnoreCase(initial).Selected = true;
+ }
+ else if (fallbackIndex > -1)
+ {
+ control.Items[fallbackIndex].Selected = true;
+ }
+ }
+ }
+ ///
+ /// Use this method instead of ListItemCollection.FindByText to find the specific item with case-insensitive.
+ ///
+ /// the items.
+ /// the item with this text want to find.
+ /// the specific item or null if didn't match the text with any item.
+ public static ListItem FindByTextWithIgnoreCase(this ListItemCollection listItems, string text)
+ {
+ return listItems.Cast().FirstOrDefault(item => item.Text.Equals(text, StringComparison.InvariantCultureIgnoreCase));
+ }
+
+ ///
+ /// Use this method instead of ListItemCollection.FindBValue to find the specific item with case-insensitive.
+ ///
+ /// the items.
+ /// the item with this value want to find.
+ /// the specific item or null if didn't match the value with any item.
+ public static ListItem FindByValueWithIgnoreCase(this ListItemCollection listItems, string value)
+ {
+ return listItems.Cast().FirstOrDefault(item => item.Value.Equals(value, StringComparison.InvariantCultureIgnoreCase));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/Extensions/WebControlExtensions.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/Extensions/WebControlExtensions.cs
new file mode 100644
index 00000000000..68ff079b9dd
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/Extensions/WebControlExtensions.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Linq;
+using System.Web.UI.WebControls;
+
+namespace DotNetNuke.Web.UI.WebControls.Extensions
+{
+ public static class WebControlExtensions
+ {
+ public static void AddCssClass(this WebControl control, string cssClass)
+ {
+ if (string.IsNullOrEmpty(control.CssClass))
+ {
+ control.CssClass = cssClass;
+ }
+ else
+ {
+ var cssClasses = control.CssClass.Split(' ');
+ var classExists = cssClasses.Any(@class => @class == cssClass);
+
+ if (!classExists)
+ {
+ control.CssClass += " " + cssClass;
+ }
+ }
+ }
+
+ public static void RemoveCssClass(this WebControl control, string cssClass)
+ {
+ if (!string.IsNullOrEmpty(control.CssClass))
+ {
+ var cssClasses = control.CssClass.Split(' ');
+ control.CssClass = string.Join(" ", cssClasses.Where(@class => @class != cssClass).ToArray());
+ }
+ }
+ }
+
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/IDnnRibbonBarTool.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/IDnnRibbonBarTool.cs
new file mode 100644
index 00000000000..f35a072063a
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/IDnnRibbonBarTool.cs
@@ -0,0 +1,27 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public interface IDnnRibbonBarTool
+ {
+ string ToolName { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/Resources/TermsSelector.js b/DNN Platform/DotNetNuke.Web/UI/WebControls/Resources/TermsSelector.js
new file mode 100644
index 00000000000..7e773c209ca
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/Resources/TermsSelector.js
@@ -0,0 +1,82 @@
+(function ($, t, sys) {
+ t.registerNamespace("dnn.controls");
+ dnn.controls.termsSelector = {};
+
+ dnn.controls.termsSelector.OnClientDropDownOpened = function (sender, e) {
+ dnn.controls.termsSelector.fire(sender);
+ };
+
+ dnn.controls.termsSelector.OnClientNodeChecked = function (sender, e) {
+ dnn.controls.termsSelector.update(sender);
+ };
+
+ dnn.controls.termsSelector.update = function (tree) {
+ var treeDiv = $("#" + tree.get_id());
+ var comboBox = treeDiv.data("combo");
+ var nodes = tree.get_checkedNodes();
+ var text = '', value = '';
+ for (var i = 0; i < nodes.length; i++) {
+ text += nodes[i].get_text() + ", ";
+ value += nodes[i].get_value() + ", ";
+ }
+ if (text != '' && text.substr(text.length - 2, 2) == ', ') {
+ text = text.substr(0, text.length - 2);
+ }
+ if (value != '' && value.substr(value.length - 2, 2) == ', ') {
+ value = value.substr(0, value.length - 2);
+ }
+
+ comboBox.trackChanges();
+ var valueItem;
+ if (comboBox.get_items().get_count() == 1) {
+ valueItem = new Telerik.Web.UI.RadComboBoxItem();
+ comboBox.get_items().add(valueItem);
+ valueItem.set_visible(false);
+ } else {
+ valueItem = comboBox.get_items().getItem(1);
+ }
+ valueItem.set_text(text);
+ valueItem.set_value(value);
+ valueItem.select();
+ comboBox.commitChanges();
+ };
+
+ dnn.controls.termsSelector.fire = function(combobox) {
+ var $this = $("#" + combobox.get_id());
+ var treeDiv = $("div[id^=" + combobox.get_id() + "][id$=_TreeView]");
+ if (treeDiv.data("combo")) {
+ return;
+ }
+ treeDiv.data("combo", combobox);
+
+ treeDiv.click(function (e) {
+ if (!$(e.srcElement).is(":checkbox")) {
+ return false;
+ }
+ });
+ };
+
+ var updateTerms = function() {
+ setTimeout(function() {
+ $("div[class*=TermsSelector]").each(function() {
+ var clientId = $(this).attr("id");
+ var combo = $find(clientId);
+ if (combo != null) {
+ dnn.controls.termsSelector.fire(combo);
+ var tree = $find($("div[id^=" + clientId + "][id$=_TreeView]").attr("id"));
+ dnn.controls.termsSelector.update(tree);
+ }
+ });
+ }, 0);
+ };
+
+ $().ready(function () {
+ updateTerms();
+ if (typeof sys != "undefined") {
+ sys.WebForms.PageRequestManager.getInstance().add_endRequest(function () {
+ updateTerms();
+ });
+ }
+ });
+}(jQuery, Type, window.Sys));
+
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/RibbonBarToolInfo.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/RibbonBarToolInfo.cs
new file mode 100644
index 00000000000..c84432bb750
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/RibbonBarToolInfo.cs
@@ -0,0 +1,65 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ [Serializable]
+ public class RibbonBarToolInfo
+ {
+ public RibbonBarToolInfo()
+ {
+ ControlKey = "";
+ ModuleFriendlyName = "";
+ LinkWindowTarget = "";
+ ToolName = "";
+ }
+
+ public RibbonBarToolInfo(string toolName, bool isHostTool, bool useButton, string linkWindowTarget, string moduleFriendlyName, string controlKey, bool showAsPopUp)
+ {
+ ToolName = toolName;
+ IsHostTool = isHostTool;
+ UseButton = useButton;
+ LinkWindowTarget = linkWindowTarget;
+ ModuleFriendlyName = moduleFriendlyName;
+ ControlKey = controlKey;
+ ShowAsPopUp = showAsPopUp;
+ }
+
+ public string ControlKey { get; set; }
+
+ public bool IsHostTool { get; set; }
+
+ public string LinkWindowTarget { get; set; }
+
+ public string ModuleFriendlyName { get; set; }
+
+ public bool ShowAsPopUp { get; set; }
+
+ public string ToolName { get; set; }
+
+ public bool UseButton { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/Tags.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/Tags.cs
new file mode 100644
index 00000000000..fe639128319
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/Tags.cs
@@ -0,0 +1,400 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Content;
+using DotNetNuke.Entities.Content.Taxonomy;
+using DotNetNuke.Security;
+using DotNetNuke.Services.Localization;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class Tags : WebControl, IPostBackEventHandler, IPostBackDataHandler
+ {
+ private string _RepeatDirection = "Horizontal";
+ private string _Separator = ", ";
+
+ private string _Tags;
+
+ private Vocabulary TagVocabulary
+ {
+ get
+ {
+ VocabularyController vocabularyController = new VocabularyController();
+ return (from v in vocabularyController.GetVocabularies() where v.IsSystem && v.Name == "Tags" select v).SingleOrDefault();
+ }
+ }
+
+ #region "Public Properties"
+
+ public string AddImageUrl { get; set; }
+
+ public bool AllowTagging { get; set; }
+
+ public string CancelImageUrl { get; set; }
+
+ public ContentItem ContentItem { get; set; }
+
+ public bool IsEditMode
+ {
+ get
+ {
+ bool _IsEditMode = false;
+ if (ViewState["IsEditMode"] != null)
+ {
+ _IsEditMode = Convert.ToBoolean(ViewState["IsEditMode"]);
+ }
+ return _IsEditMode;
+ }
+ set
+ {
+ ViewState["IsEditMode"] = value;
+ }
+ }
+
+ public string NavigateUrlFormatString { get; set; }
+
+ public string RepeatDirection
+ {
+ get
+ {
+ return _RepeatDirection;
+ }
+ set
+ {
+ _RepeatDirection = value;
+ }
+ }
+
+ public string SaveImageUrl { get; set; }
+
+ public string Separator
+ {
+ get
+ {
+ return _Separator;
+ }
+ set
+ {
+ _Separator = value;
+ }
+ }
+
+ public bool ShowCategories { get; set; }
+
+ public bool ShowTags { get; set; }
+
+ #endregion
+
+ #region "Private Methods"
+
+ private string LocalizeString(string key)
+ {
+ string LocalResourceFile = Utilities.GetLocalResourceFile(this);
+ string localizedString = null;
+ if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(LocalResourceFile))
+ {
+ localizedString = Localization.GetString(key, LocalResourceFile);
+ }
+ else
+ {
+ localizedString = Null.NullString;
+ }
+ return localizedString;
+ }
+
+ private void RenderButton(HtmlTextWriter writer, string buttonType, string imageUrl)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, LocalizeString(string.Format("{0}.ToolTip", buttonType)));
+ writer.AddAttribute(HtmlTextWriterAttribute.Href, Page.ClientScript.GetPostBackClientHyperlink(this, buttonType));
+ writer.RenderBeginTag(HtmlTextWriterTag.A);
+
+ //Image
+ if (!string.IsNullOrEmpty(imageUrl))
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Src, ResolveUrl(imageUrl));
+ writer.RenderBeginTag(HtmlTextWriterTag.Img);
+ writer.RenderEndTag();
+ }
+
+ writer.Write(LocalizeString(buttonType));
+ writer.RenderEndTag();
+ }
+
+ private void RenderTerm(HtmlTextWriter writer, Term term, bool renderSeparator)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Href, string.Format(NavigateUrlFormatString, term.Name));
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, term.Name);
+ writer.AddAttribute(HtmlTextWriterAttribute.Rel, "tag");
+ writer.RenderBeginTag(HtmlTextWriterTag.A);
+ writer.Write(term.Name);
+ writer.RenderEndTag();
+
+ if (renderSeparator)
+ {
+ writer.Write(Separator);
+ }
+ }
+
+ private void SaveTags()
+ {
+ string tags = new PortalSecurity().InputFilter(_Tags, PortalSecurity.FilterFlag.NoMarkup | PortalSecurity.FilterFlag.NoScripting);
+ tags = HttpContext.Current.Server.HtmlEncode(tags);
+ if (!string.IsNullOrEmpty(tags))
+ {
+ foreach (string t in tags.Split(','))
+ {
+ if (!string.IsNullOrEmpty(t))
+ {
+ string tagName = t.Trim(' ');
+ Term existingTerm = (from term in ContentItem.Terms.AsQueryable() where term.Name.Equals(tagName, StringComparison.CurrentCultureIgnoreCase) select term).SingleOrDefault();
+
+ if (existingTerm == null)
+ {
+ //Not tagged
+ TermController termController = new TermController();
+ Term term =
+ (from te in termController.GetTermsByVocabulary(TagVocabulary.VocabularyId) where te.Name.Equals(tagName, StringComparison.CurrentCultureIgnoreCase) select te).
+ SingleOrDefault();
+ if (term == null)
+ {
+ //Add term
+ term = new Term(TagVocabulary.VocabularyId);
+ term.Name = tagName;
+ termController.AddTerm(term);
+ }
+
+ //Add term to content
+ ContentItem.Terms.Add(term);
+ termController.AddTermToContent(term, ContentItem);
+ }
+ }
+ }
+ }
+
+ IsEditMode = false;
+
+ //Raise the Tags Updated Event
+ OnTagsUpdate(EventArgs.Empty);
+ }
+
+ #endregion
+
+ public event EventHandler TagsUpdated;
+
+ protected void OnTagsUpdate(EventArgs e)
+ {
+ if (TagsUpdated != null)
+ {
+ TagsUpdated(this, e);
+ }
+ }
+
+ #region "Public Methods"
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+
+ if ((!Page.ClientScript.IsClientScriptBlockRegistered(UniqueID)))
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append("");
+
+ Page.ClientScript.RegisterClientScriptBlock(GetType(), UniqueID, sb.ToString());
+ }
+ }
+
+
+ public override void RenderControl(HtmlTextWriter writer)
+ {
+ //Render Outer Div
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, RepeatDirection.ToLower());
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
+
+ //Render Categories
+ if (ShowCategories)
+ {
+ //Render UL
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "categories");
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, LocalizeString("Category.ToolTip"));
+ writer.RenderBeginTag(HtmlTextWriterTag.Ul);
+
+ //Render Category Links
+ var categories = (from cat in ContentItem.Terms where cat.VocabularyId != TagVocabulary.VocabularyId select cat);
+
+ for (int i = 0; i <= categories.Count() - 1; i++)
+ {
+ if (i == 0)
+ {
+ //First Category
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "first_tag");
+ }
+ else if (i == categories.Count() - 1)
+ {
+ //Last Category
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "last_tag");
+ }
+ writer.RenderBeginTag(HtmlTextWriterTag.Li);
+
+ RenderTerm(writer, categories.ToList()[i], i < categories.Count() - 1 && RepeatDirection.ToLower() == "horizontal");
+
+ writer.RenderEndTag();
+ }
+
+ writer.RenderEndTag();
+ }
+
+ if (ShowTags)
+ {
+ //Render UL
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "tags");
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, LocalizeString("Tag.ToolTip"));
+ writer.RenderBeginTag(HtmlTextWriterTag.Ul);
+
+ //Render Tag Links
+ var tags = (from cat in ContentItem.Terms where cat.VocabularyId == TagVocabulary.VocabularyId select cat);
+
+ for (int i = 0; i <= tags.Count() - 1; i++)
+ {
+ if (i == 0)
+ {
+ //First Tag
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "first_tag");
+ }
+ else if (i == tags.Count() - 1)
+ {
+ //Last Tag
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "last_tag");
+ }
+ writer.RenderBeginTag(HtmlTextWriterTag.Li);
+
+ RenderTerm(writer, tags.ToList()[i], i < tags.Count() - 1 && RepeatDirection.ToLower() == "horizontal");
+
+ writer.RenderEndTag();
+ }
+
+ if (AllowTagging)
+ {
+ writer.RenderBeginTag(HtmlTextWriterTag.Li);
+
+ if (IsEditMode)
+ {
+ writer.Write(" ");
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
+ writer.AddAttribute("OnKeyPress", "return disableEnterKey(event)");
+ writer.RenderBeginTag(HtmlTextWriterTag.Input);
+ writer.RenderEndTag();
+
+ writer.Write(" ");
+
+ //Render Save Button
+ RenderButton(writer, "Save", SaveImageUrl);
+
+ writer.Write(" ");
+
+ //Render Add Button
+ RenderButton(writer, "Cancel", CancelImageUrl);
+ }
+ else
+ {
+ writer.Write(" ");
+
+ //Render Add Button
+ RenderButton(writer, "Add", AddImageUrl);
+ }
+
+ writer.RenderEndTag();
+ }
+
+ writer.RenderEndTag();
+ }
+
+ writer.RenderEndTag();
+ }
+
+ #endregion
+
+ #region "IPostBackDataHandler Implementation"
+
+ public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
+ {
+ _Tags = postCollection[postDataKey];
+
+ return true;
+ }
+
+
+ public void RaisePostDataChangedEvent()
+ {
+ }
+
+ #endregion
+
+ #region "IPostBackEventHandler Implementation"
+
+ public void RaisePostBackEvent(string eventArgument)
+ {
+ switch (eventArgument)
+ {
+ case "Add":
+ IsEditMode = true;
+ break;
+ case "Cancel":
+ IsEditMode = false;
+ break;
+ case "Save":
+ SaveTags();
+ break;
+ default:
+ IsEditMode = false;
+ break;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsEventArgs.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsEventArgs.cs
new file mode 100644
index 00000000000..da5695bcf11
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsEventArgs.cs
@@ -0,0 +1,56 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+using DotNetNuke.Entities.Content.Taxonomy;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class TermsEventArgs : EventArgs
+ {
+ private readonly Term _SelectedTerm;
+
+ #region "Constructors"
+
+ public TermsEventArgs(Term selectedTerm)
+ {
+ _SelectedTerm = selectedTerm;
+ }
+
+ #endregion
+
+ #region "Public Properties"
+
+ public Term SelectedTerm
+ {
+ get
+ {
+ return _SelectedTerm;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsList.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsList.cs
new file mode 100644
index 00000000000..ce099a9a52d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsList.cs
@@ -0,0 +1,213 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Web.UI.WebControls;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Content.Taxonomy;
+
+using Telerik.Web.UI;
+
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class TermsList : WebControl
+ {
+ private bool _IsHeirarchical;
+ private DnnListBox _ListBox;
+
+ private DnnTreeView _TreeView;
+
+ #region "Events"
+
+ public event EventHandler SelectedTermChanged;
+
+ #endregion
+
+ #region "Public Properties"
+
+ public bool IsHeirarchical
+ {
+ get
+ {
+ return _IsHeirarchical;
+ }
+ }
+
+ public Term SelectedTerm
+ {
+ get
+ {
+ Term _SelectedTerm = null;
+ if (!string.IsNullOrEmpty(SelectedValue))
+ {
+ int _TermId = int.Parse(SelectedValue);
+ foreach (Term term in Terms)
+ {
+ if (term.TermId == _TermId)
+ {
+ _SelectedTerm = term;
+ break;
+ }
+ }
+ }
+ return _SelectedTerm;
+ }
+ }
+
+ public string SelectedValue
+ {
+ get
+ {
+ string _SelectedValue = Null.NullString;
+ if (IsHeirarchical)
+ {
+ _SelectedValue = _TreeView.SelectedValue;
+ }
+ else
+ {
+ _SelectedValue = _ListBox.SelectedValue;
+ }
+ return _SelectedValue;
+ }
+ }
+
+ public List Terms
+ {
+ get
+ {
+ object _DataSource = null;
+ if (IsHeirarchical)
+ {
+ _DataSource = _TreeView.DataSource;
+ }
+ else
+ {
+ _DataSource = _ListBox.DataSource;
+ }
+ return _DataSource as List;
+ }
+ }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void CreateChildControls()
+ {
+ Controls.Clear();
+
+ _ListBox = new DnnListBox();
+ _ListBox.ID = string.Concat(ID, "_List");
+ _ListBox.DataTextField = "Name";
+ _ListBox.DataValueField = "TermId";
+ _ListBox.AutoPostBack = true;
+ _ListBox.SelectedIndexChanged += ListBoxSelectedIndexChanged;
+
+ _TreeView = new DnnTreeView();
+ _TreeView.ID = string.Concat(ID, "_Tree");
+ _TreeView.DataTextField = "Name";
+ _TreeView.DataValueField = "TermId";
+ _TreeView.DataFieldID = "TermId";
+ _TreeView.DataFieldParentID = "ParentTermId";
+ _TreeView.NodeClick += TreeViewNodeClick;
+
+ Controls.Add(_ListBox);
+ Controls.Add(_TreeView);
+ }
+
+ protected override void OnInit(EventArgs e)
+ {
+ EnsureChildControls();
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ _ListBox.Visible = !IsHeirarchical;
+ _TreeView.Visible = IsHeirarchical;
+
+ _ListBox.Height = Height;
+ _ListBox.Width = Width;
+ _TreeView.Height = Height;
+ _TreeView.Width = Width;
+
+ _TreeView.ExpandAllNodes();
+
+ base.OnPreRender(e);
+ }
+
+ protected virtual void OnSelectedTermChanged(TermsEventArgs e)
+ {
+ //Raise the SelectedTermChanged Event
+ if (SelectedTermChanged != null)
+ {
+ SelectedTermChanged(this, e);
+ }
+ }
+
+ #endregion
+
+ #region "Event Handlers"
+
+ private void ListBoxSelectedIndexChanged(object sender, EventArgs e)
+ {
+ //Raise the SelectedTermChanged Event
+ OnSelectedTermChanged(new TermsEventArgs(SelectedTerm));
+ }
+
+ private void TreeViewNodeClick(object sender, RadTreeNodeEventArgs e)
+ {
+ //Raise the SelectedTermChanged Event
+ OnSelectedTermChanged(new TermsEventArgs(SelectedTerm));
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public void BindTerms(List terms, bool isHeirarchical, bool dataBind)
+ {
+ _IsHeirarchical = isHeirarchical;
+
+ _ListBox.DataSource = terms;
+ _TreeView.DataSource = terms;
+
+ if (dataBind)
+ {
+ _ListBox.DataBind();
+ _TreeView.DataBind();
+ }
+ }
+
+ public void ClearSelectedTerm()
+ {
+ _ListBox.SelectedIndex = Null.NullInteger;
+ _TreeView.UnselectAllNodes();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsSelector.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsSelector.cs
new file mode 100644
index 00000000000..2f82c588c81
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/TermsSelector.cs
@@ -0,0 +1,360 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web.UI;
+
+using DotNetNuke.Entities.Content.Common;
+using DotNetNuke.Entities.Content.Taxonomy;
+using DotNetNuke.Framework;
+
+using Telerik.Web.UI;
+
+#endregion
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ public class TermsSelector : DnnComboBox
+ {
+ public event EventHandler DataSourceChanged;
+ public TermsSelector()
+ {
+ IncludeSystemVocabularies = false;
+ IncludeTags = true;
+ }
+
+ #region "Public Properties"
+
+ public int PortalId
+ {
+ get
+ {
+ return Convert.ToInt32(ViewState["PortalId"]);
+ }
+ set
+ {
+ ViewState["PortalId"] = value;
+ OnDataSourceChanged();
+ }
+ }
+
+ public bool IncludeSystemVocabularies
+ {
+ get
+ {
+ return Convert.ToBoolean(ViewState["IncludeSystemVocabularies"]);
+ }
+ set
+ {
+ ViewState["IncludeSystemVocabularies"] = value;
+ OnDataSourceChanged();
+ }
+
+ }
+
+ public bool IncludeTags
+ {
+ get
+ {
+ return Convert.ToBoolean(ViewState["IncludeTags"]);
+ }
+ set
+ {
+ ViewState["IncludeTags"] = value;
+ OnDataSourceChanged();
+ }
+
+ }
+
+ public List Terms
+ {
+ get
+ {
+ return ViewState["Terms"] as List;
+ }
+ set
+ {
+ ViewState["Terms"] = value;
+ }
+ }
+
+ #endregion
+
+ #region "Protected Methods"
+
+ protected override void OnInit(EventArgs e)
+ {
+ ItemTemplate = new TreeViewTemplate();
+ Items.Add(new RadComboBoxItem());
+ base.OnInit(e);
+
+ OnClientDropDownOpened = "dnn.controls.termsSelector.OnClientDropDownOpened";
+ if (!string.IsNullOrEmpty(CssClass))
+ {
+ CssClass = string.Format("{0} TermsSelector", CssClass);
+ }
+ else
+ {
+ CssClass = "TermsSelector";
+ }
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+
+ if(Page.IsPostBack)
+ {
+ if(Terms == null)
+ {
+ Terms = new List();
+ }
+ else
+ {
+ Terms.Clear();
+ }
+
+ if (!string.IsNullOrEmpty(SelectedValue))
+ {
+ foreach (var id in SelectedValue.Split(','))
+ {
+ var termId = Convert.ToInt32(id.Trim());
+ var term = Util.GetTermController().GetTerm(termId);
+ if (term != null)
+ {
+ Terms.Add(term);
+ }
+ }
+
+ //clear the append item by client side
+ if(Items.Count > 1)
+ {
+ Items.Remove(1);
+ }
+ }
+ }
+ }
+
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
+ Text = Terms.ToDelimittedString(", ");
+ ToolTip = Terms.ToDelimittedString(", ");
+ }
+
+ protected override void LoadViewState(object savedState)
+ {
+ base.LoadViewState(savedState);
+
+ OnDataSourceChanged();
+ }
+
+ protected override object SaveViewState()
+ {
+ Page.ClientScript.RegisterClientScriptResource(GetType(), "DotNetNuke.Web.UI.WebControls.Resources.TermsSelector.js");
+
+ return base.SaveViewState();
+ }
+
+ protected void OnDataSourceChanged()
+ {
+ if(DataSourceChanged != null)
+ {
+ DataSourceChanged(this, new EventArgs());
+ }
+ }
+ #endregion
+
+ #region "Private Template Class"
+
+ public class TreeViewTemplate : ITemplate
+ {
+ #region Private Fields
+
+ private RadComboBoxItem _container;
+ private List _terms;
+ private TermsSelector _termsSelector;
+
+ private DnnTreeView _tree;
+
+ #endregion
+
+ #region Private Properties
+
+ private bool IncludeSystemVocabularies
+ {
+ get
+ {
+ return _termsSelector.IncludeSystemVocabularies;
+ }
+ }
+
+ private bool IncludeTags
+ {
+ get
+ {
+ return _termsSelector.IncludeTags;
+ }
+ }
+
+ private int PortalId
+ {
+ get
+ {
+ return _termsSelector.PortalId;
+ }
+ }
+
+ private List SelectedTerms
+ {
+ get
+ {
+ return _termsSelector.Terms;
+ }
+ }
+
+ private List Terms
+ {
+ get
+ {
+ if (_terms == null)
+ {
+ IVocabularyController vocabRep = Util.GetVocabularyController();
+ _terms = new List();
+ var vocabularies = from v in vocabRep.GetVocabularies() where v.ScopeType.ScopeType == "Application" || (v.ScopeType.ScopeType == "Portal" && v.ScopeId == PortalId) select v;
+
+ foreach (Vocabulary v in vocabularies)
+ {
+ if(v.IsSystem)
+ {
+ if (IncludeSystemVocabularies || (IncludeTags && v.Name == "Tags"))
+ {
+ AddTerms(v);
+ }
+ }
+ else
+ {
+ AddTerms(v);
+ }
+ }
+ }
+ return _terms;
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private void AddTerms(Vocabulary v)
+ {
+ ITermController termRep = Util.GetTermController();
+
+ //Add a dummy parent term if simple vocabulary
+ if (v.Type == VocabularyType.Simple)
+ {
+ Term dummyTerm = new Term(v.VocabularyId);
+ dummyTerm.ParentTermId = null;
+ dummyTerm.Name = v.Name;
+ dummyTerm.TermId = -v.VocabularyId;
+ _terms.Add(dummyTerm);
+ }
+ foreach (Term t in termRep.GetTermsByVocabulary(v.VocabularyId))
+ {
+ if (v.Type == VocabularyType.Simple)
+ {
+ t.ParentTermId = -v.VocabularyId;
+ }
+ _terms.Add(t);
+ }
+
+ }
+
+ #endregion
+
+ #region ITemplate Members
+
+ public void InstantiateIn(Control container)
+ {
+ _container = (RadComboBoxItem) container;
+ _termsSelector = (TermsSelector) container.Parent;
+
+ _tree = new DnnTreeView();
+ _tree.ID = string.Format("{0}_TreeView", _termsSelector.ID);
+ _tree.DataTextField = "Name";
+ _tree.DataValueField = "TermId";
+ _tree.DataFieldID = "TermId";
+ _tree.DataFieldParentID = "ParentTermId";
+ _tree.CheckBoxes = true;
+ _tree.ExpandAllNodes();
+
+ //bind client-side events
+ _tree.OnClientNodeChecked = "dnn.controls.termsSelector.OnClientNodeChecked";
+
+ _tree.DataSource = Terms;
+
+ _tree.NodeDataBound += TreeNodeDataBound;
+ _tree.DataBound += TreeDataBound;
+
+ _container.Controls.Add(_tree);
+
+ _termsSelector.DataSourceChanged += TermsSelector_DataSourceChanged;
+ }
+
+ #endregion
+
+ private void TreeDataBound(object sender, EventArgs e)
+ {
+ _tree.ExpandAllNodes();
+ }
+
+ private void TreeNodeDataBound(object sender, RadTreeNodeEventArgs e)
+ {
+ RadTreeNode node = e.Node;
+ Term term = node.DataItem as Term;
+
+ if (term.TermId < 0)
+ {
+ node.Checkable = false;
+ }
+ foreach (Term tag in SelectedTerms)
+ {
+ if (tag.TermId == term.TermId)
+ {
+ node.Checked = true;
+ break;
+ }
+ }
+ }
+
+ private void TermsSelector_DataSourceChanged(object sender, EventArgs e)
+ {
+ _terms = null;
+ _tree.DataSource = Terms;
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/TypedControlCollection.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/TypedControlCollection.cs
new file mode 100644
index 00000000000..6edd53f18b5
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/TypedControlCollection.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Web.UI;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+ ///
+ /// Restricts the client to add only controls of specific type into the control collection
+ ///
+ ///
+ public sealed class TypedControlCollection : ControlCollection where T : Control
+ {
+
+ public TypedControlCollection(Control owner) : base(owner)
+ {
+ }
+
+ public override void Add(Control child)
+ {
+ if (!(child is T))
+ {
+ throw new InvalidOperationException("Not supported");
+ }
+ base.Add(child);
+ }
+
+ public override void AddAt(int index, Control child)
+ {
+ if (!(child is T))
+ {
+ throw new InvalidOperationException("Not supported");
+ }
+ base.AddAt(index, child);
+ }
+
+ }
+
+}
diff --git a/DNN Platform/DotNetNuke.Web/UI/WebControls/UniformControlCollection.cs b/DNN Platform/DotNetNuke.Web/UI/WebControls/UniformControlCollection.cs
new file mode 100644
index 00000000000..bf30e2b8e49
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/UI/WebControls/UniformControlCollection.cs
@@ -0,0 +1,253 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Web.UI;
+using System.Threading;
+
+namespace DotNetNuke.Web.UI.WebControls
+{
+
+ public sealed class UniformControlCollection : IList where TOwner : Control where TChildren : Control
+ {
+
+ private readonly TOwner _owner;
+
+ internal UniformControlCollection(TOwner owner)
+ {
+ _owner = owner;
+ }
+
+ public void AddAt(int index, TChildren childControl)
+ {
+ _owner.Controls.AddAt(index, childControl);
+ }
+
+ ///
+ ///Determines the index of a specific item in the .
+ ///
+ ///
+ ///The index of if found in the list; otherwise, -1.
+ ///
+ ///
+ ///The object to locate in the .
+ ///
+ public int IndexOf(TChildren item)
+ {
+ return _owner.Controls.IndexOf(item);
+ }
+
+ ///
+ /// Inserts an item to the at the specified index.
+ ///
+ ///
+ /// The zero-based index at which should be inserted.
+ ///
+ ///
+ /// The object to insert into the .
+ ///
+ /// is not a valid index in the .
+ ///
+ ///
+ ///The is read-only.
+ ///
+ public void Insert(int index, TChildren item)
+ {
+ _owner.Controls.AddAt(index, item);
+ }
+
+ ///
+ ///Removes the item at the specified index.
+ ///
+ ///
+ ///The zero-based index of the item to remove.
+ ///
+ /// is not a valid index in the .
+ ///
+ ///
+ ///The is read-only.
+ ///
+ public void RemoveAt(int index)
+ {
+ _owner.Controls.RemoveAt(index);
+ }
+
+ ///
+ ///Gets or sets the element at the specified index.
+ ///
+ ///
+ ///The element at the specified index.
+ ///
+ ///
+ ///The zero-based index of the element to get or set.
+ ///
+ /// is not a valid index in the .
+ ///
+ ///
+ ///The property is set and the is read-only.
+ ///
+ public TChildren this[int index]
+ {
+ get
+ {
+ return _owner.Controls[index] as TChildren;
+ }
+ set
+ {
+ RemoveAt(index);
+ AddAt(index, value);
+ }
+ }
+
+ ///
+ ///Gets the number of elements contained in the .
+ ///
+ ///
+ ///The number of elements contained in the .
+ ///
+ public int Count
+ {
+ get
+ {
+ return _owner.HasControls() ? _owner.Controls.Count : 0;
+ }
+ }
+
+ ///
+ ///Removes the first occurrence of a specific object from the .
+ ///
+ ///
+ ///true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original .
+ ///
+ ///
+ ///The object to remove from the .
+ ///
+ ///
+ ///The is read-only.
+ ///
+ public bool Remove(TChildren item)
+ {
+ _owner.Controls.Remove(item);
+ return true;
+ }
+
+ ///
+ ///Gets a value indicating whether the is read-only.
+ ///
+ ///
+ ///true if the is read-only; otherwise, false.
+ ///
+ public bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ ///Returns an enumerator that iterates through the collection.
+ ///
+ ///
+ ///A that can be used to iterate through the collection.
+ ///
+ ///1
+ public IEnumerator GetEnumerator()
+ {
+ var enumerator = _owner.Controls.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ yield return enumerator.Current as TChildren;
+ }
+ }
+
+ ///
+ ///Removes all items from the .
+ ///
+ ///
+ ///The is read-only.
+ ///
+ public void Clear()
+ {
+ if (_owner.HasControls())
+ {
+ _owner.Controls.Clear();
+ }
+ }
+
+ ///
+ ///Adds an item to the .
+ ///
+ ///
+ ///The object to add to the .
+ ///
+ ///
+ ///The is read-only.
+ ///
+ public void Add(TChildren item)
+ {
+ _owner.Controls.Add(item);
+ }
+
+ ///
+ ///Copies the elements of the to an , starting at a particular index.
+ ///
+ ///
+ ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing.
+ ///
+ ///
+ ///The zero-based index in at which copying begins.
+ ///
+ /// is null.
+ ///
+ /// is less than 0.
+ ///
+ /// is multidimensional.
+ ///-or-
+ /// is equal to or greater than the length of .
+ ///-or-
+ ///The number of elements in the source is greater than the available space from to the end of the destination .
+ ///-or-
+ ///Type paramref name="T" cannot be cast automatically to the type of the destination .
+ ///
+ public void CopyTo(TChildren[] array, int arrayIndex)
+ {
+ var enumerator = GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ array.SetValue(enumerator.Current, Math.Max(Interlocked.Increment(ref arrayIndex), arrayIndex - 1));
+ }
+ }
+
+ ///
+ ///Determines whether the contains a specific value.
+ ///
+ ///
+ ///true if is found in the ; otherwise, false.
+ ///
+ ///
+ ///The object to locate in the .
+ ///
+ public bool Contains(TChildren item)
+ {
+ return _owner.Controls.Contains(item);
+ }
+
+ ///
+ ///Returns an enumerator that iterates through a collection.
+ ///
+ ///
+ ///An object that can be used to iterate through the collection.
+ ///
+ ///2
+ private IEnumerator EnumerableGetEnumerator()
+ {
+ return _owner.Controls.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return EnumerableGetEnumerator();
+ }
+
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/Validators/AttributeBasedObjectValidator.cs b/DNN Platform/DotNetNuke.Web/Validators/AttributeBasedObjectValidator.cs
new file mode 100644
index 00000000000..5a575ce1314
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/AttributeBasedObjectValidator.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Linq;
+using System.Reflection;
+
+#endregion
+
+namespace DotNetNuke.Web.Validators
+{
+ public abstract class AttributeBasedObjectValidator : PropertyBasedObjectValidator where TAttribute : Attribute
+ {
+ protected override ValidationResult ValidateProperty(object target, PropertyInfo targetProperty)
+ {
+ return targetProperty.GetCustomAttributes(true).OfType().Aggregate(ValidationResult.Successful,
+ (result, attribute) =>
+ result.CombineWith(ValidateAttribute(target, targetProperty, attribute) ?? ValidationResult.Successful));
+ }
+
+
+ protected abstract ValidationResult ValidateAttribute(object target, PropertyInfo targetProperty, TAttribute attribute);
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/Validators/DataAnnotationsObjectValidator.cs b/DNN Platform/DotNetNuke.Web/Validators/DataAnnotationsObjectValidator.cs
new file mode 100644
index 00000000000..7878ec2306f
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/DataAnnotationsObjectValidator.cs
@@ -0,0 +1,43 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.ComponentModel.DataAnnotations;
+using System.Reflection;
+
+#endregion
+
+namespace DotNetNuke.Web.Validators
+{
+ public class DataAnnotationsObjectValidator : AttributeBasedObjectValidator
+ {
+ protected override ValidationResult ValidateAttribute(object target, PropertyInfo targetProperty, ValidationAttribute attribute)
+ {
+ return !attribute.IsValid(targetProperty.GetValue(target, new object[] {})) ? new ValidationResult(new[] {CreateError(targetProperty.Name, attribute)}) : ValidationResult.Successful;
+ }
+
+
+ protected virtual ValidationError CreateError(string propertyName, ValidationAttribute attribute)
+ {
+ return new ValidationError {ErrorMessage = attribute.FormatErrorMessage(propertyName), PropertyName = propertyName, Validator = attribute};
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/Validators/ObjectValidator.cs b/DNN Platform/DotNetNuke.Web/Validators/ObjectValidator.cs
new file mode 100644
index 00000000000..652353e4c47
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/ObjectValidator.cs
@@ -0,0 +1,27 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.Web.Validators
+{
+ public abstract class ObjectValidator
+ {
+ public abstract ValidationResult ValidateObject(object target);
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/Validators/PropertyBasedObjectValidator.cs b/DNN Platform/DotNetNuke.Web/Validators/PropertyBasedObjectValidator.cs
new file mode 100644
index 00000000000..7b4be8aac81
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/PropertyBasedObjectValidator.cs
@@ -0,0 +1,39 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Linq;
+using System.Reflection;
+
+#endregion
+
+namespace DotNetNuke.Web.Validators
+{
+ public abstract class PropertyBasedObjectValidator : ObjectValidator
+ {
+ public override ValidationResult ValidateObject(object target)
+ {
+ return target.GetType().GetProperties().Aggregate(ValidationResult.Successful, (result, member) => result.CombineWith(ValidateProperty(target, member) ?? ValidationResult.Successful));
+ }
+
+ protected abstract ValidationResult ValidateProperty(object target, PropertyInfo targetProperty);
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/Validators/ValidationError.cs b/DNN Platform/DotNetNuke.Web/Validators/ValidationError.cs
new file mode 100644
index 00000000000..bacb2bbbabb
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/ValidationError.cs
@@ -0,0 +1,35 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.Web.Validators
+{
+ public class ValidationError
+ {
+ #region "Public Properties"
+
+ public string ErrorMessage { get; set; }
+
+ public string PropertyName { get; set; }
+
+ public object Validator { get; set; }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/Validators/ValidationResult.cs b/DNN Platform/DotNetNuke.Web/Validators/ValidationResult.cs
new file mode 100644
index 00000000000..8859857cc4d
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/ValidationResult.cs
@@ -0,0 +1,92 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Collections.Generic;
+using System.Linq;
+
+using DotNetNuke.Common;
+
+
+#endregion
+
+namespace DotNetNuke.Web.Validators
+{
+ public class ValidationResult
+ {
+ private readonly IEnumerable _Errors;
+
+ #region "Constructors"
+
+ public ValidationResult()
+ {
+ _Errors = Enumerable.Empty();
+ }
+
+ public ValidationResult(IEnumerable errors)
+ {
+ Requires.NotNull("errors", errors);
+ _Errors = errors;
+ }
+
+ #endregion
+
+ #region "Public Properties"
+
+ public IEnumerable Errors
+ {
+ get
+ {
+ return _Errors;
+ }
+ }
+
+ public bool IsValid
+ {
+ get
+ {
+ return (_Errors.Count() == 0);
+ }
+ }
+
+ public static ValidationResult Successful
+ {
+ get
+ {
+ return new ValidationResult();
+ }
+ }
+
+ #endregion
+
+ #region "Public Methods"
+
+ public ValidationResult CombineWith(ValidationResult other)
+ {
+ Requires.NotNull("other", other);
+
+ //Just concatenate the errors collection
+ return new ValidationResult(_Errors.Concat(other.Errors));
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/Validators/Validator.cs b/DNN Platform/DotNetNuke.Web/Validators/Validator.cs
new file mode 100644
index 00000000000..f0d353e21d5
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/Validators/Validator.cs
@@ -0,0 +1,57 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.Collections.Generic;
+using System.Linq;
+
+#endregion
+
+namespace DotNetNuke.Web.Validators
+{
+ public class Validator
+ {
+ private readonly IList _Validators;
+
+ public Validator()
+ {
+ _Validators = new List();
+ }
+
+ public Validator(ObjectValidator validator) : this()
+ {
+ _Validators.Add(validator);
+ }
+
+ public IList Validators
+ {
+ get
+ {
+ return _Validators;
+ }
+ }
+
+ public ValidationResult ValidateObject(object target)
+ {
+ return _Validators.Aggregate(ValidationResult.Successful, (result, validator) => result.CombineWith(validator.ValidateObject(target) ?? ValidationResult.Successful));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/DotNetNuke.Web/packages.config b/DNN Platform/DotNetNuke.Web/packages.config
new file mode 100644
index 00000000000..9576480c7f5
--- /dev/null
+++ b/DNN Platform/DotNetNuke.Web/packages.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Externally Sourced/Class1.cs b/DNN Platform/Externally Sourced/Class1.cs
new file mode 100644
index 00000000000..c8fdcaedd67
--- /dev/null
+++ b/DNN Platform/Externally Sourced/Class1.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Provider.RadEditor
+{
+ class Class1
+ {
+ }
+}
diff --git a/DNN Platform/Externally Sourced/DDRMenu_02.00.03_Install.zip b/DNN Platform/Externally Sourced/DDRMenu_02.00.03_Install.zip
new file mode 100644
index 00000000000..06c77c31a31
Binary files /dev/null and b/DNN Platform/Externally Sourced/DDRMenu_02.00.03_Install.zip differ
diff --git a/DNN Platform/Externally Sourced/Externally.Sourced.csproj b/DNN Platform/Externally Sourced/Externally.Sourced.csproj
new file mode 100644
index 00000000000..41396bee1fc
--- /dev/null
+++ b/DNN Platform/Externally Sourced/Externally.Sourced.csproj
@@ -0,0 +1,68 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {9E1E178B-844B-40B8-9665-384220C46C1E}
+ Library
+ Properties
+ Provider.RadEditor
+ Provider.RadEditor
+ v4.0
+ 512
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ default
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(MSBuildProjectDirectory)\..\..\Build\BuildScripts
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Externally Sourced/ReadMe.txt b/DNN Platform/Externally Sourced/ReadMe.txt
new file mode 100644
index 00000000000..b73e4630221
--- /dev/null
+++ b/DNN Platform/Externally Sourced/ReadMe.txt
@@ -0,0 +1,4 @@
+This project does not contain any code, all projects here have their sources in an external open source repository. This project is here to extract the required bits from the module zips and copy the zips to the correct locaktions during a release biuld.
+
+RadEditor Provider source can be found at http://radeditor.codeplex.com
+DDRMenu source can be found at http://dnnddrmenu.codeplex.com/
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Analytics/AnalyticsModule.cs b/DNN Platform/HttpModules/Analytics/AnalyticsModule.cs
new file mode 100644
index 00000000000..8def7b474b2
--- /dev/null
+++ b/DNN Platform/HttpModules/Analytics/AnalyticsModule.cs
@@ -0,0 +1,198 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web;
+using System.Web.UI;
+using System.Web.UI.HtmlControls;
+
+using DotNetNuke.Framework;
+using DotNetNuke.HttpModules.Config;
+using DotNetNuke.Instrumentation;
+using DotNetNuke.Services.Analytics;
+using DotNetNuke.Services.Log.EventLog;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Analytics
+{
+ /// -----------------------------------------------------------------------------
+ /// Namespace: DotNetNuke.HttpModules.Analytics
+ /// Project: HttpModules
+ /// Module: AnalyticsModule
+ /// -----------------------------------------------------------------------------
+ ///
+ /// This module contains functionality for injecting web analytics scripts into the page
+ ///
+ ///
+ ///
+ ///
+ /// [cniknet] 05/03/2009 created
+ ///
+ /// -----------------------------------------------------------------------------
+ public class AnalyticsModule : IHttpModule
+ {
+ private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof (AnalyticsModule));
+ public string ModuleName
+ {
+ get
+ {
+ return "AnalyticsModule";
+ }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ application.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ private void OnPreRequestHandlerExecute(object sender, EventArgs e)
+ {
+ try
+ {
+ //First check if we are upgrading/installing or if it is a non-page request
+ var app = (HttpApplication) sender;
+ HttpRequest request = app.Request;
+
+ //First check if we are upgrading/installing
+ if (request.Url.LocalPath.ToLower().EndsWith("install.aspx")
+ || request.Url.LocalPath.ToLower().Contains("upgradewizard.aspx")
+ || request.Url.LocalPath.ToLower().Contains("installwizard.aspx"))
+ {
+ return;
+ }
+
+ //exit if a request for a .net mapping that isn't a content page is made i.e. axd
+ if (request.Url.LocalPath.ToLower().EndsWith(".aspx") == false && request.Url.LocalPath.ToLower().EndsWith(".asmx") == false &&
+ request.Url.LocalPath.ToLower().EndsWith(".ashx") == false)
+ {
+ return;
+ }
+ if (HttpContext.Current != null)
+ {
+ HttpContext context = HttpContext.Current;
+ if ((context == null))
+ {
+ return;
+ }
+ var page = context.Handler as CDefault;
+ if ((page == null))
+ {
+ return;
+ }
+ page.Load += OnPageLoad;
+ }
+ }
+ catch (Exception ex)
+ {
+ var objEventLog = new EventLogController();
+ var objEventLogInfo = new LogInfo();
+ objEventLogInfo.AddProperty("Analytics.AnalyticsModule", "OnPreRequestHandlerExecute");
+ objEventLogInfo.AddProperty("ExceptionMessage", ex.Message);
+ objEventLogInfo.LogTypeKey = EventLogController.EventLogType.HOST_ALERT.ToString();
+ objEventLog.AddLog(objEventLogInfo);
+ Logger.Error(objEventLogInfo);
+
+ }
+ }
+
+ private void OnPageLoad(object sender, EventArgs e)
+ {
+ try
+ {
+ AnalyticsEngineCollection analyticsEngines = AnalyticsEngineConfiguration.GetConfig().AnalyticsEngines;
+ if (analyticsEngines == null || analyticsEngines.Count == 0)
+ {
+ return;
+ }
+ var page = (Page) sender;
+ if ((page == null))
+ {
+ return;
+ }
+ foreach (AnalyticsEngine engine in analyticsEngines)
+ {
+ if ((!String.IsNullOrEmpty(engine.ElementId)))
+ {
+ AnalyticsEngineBase objEngine = null;
+ if ((!String.IsNullOrEmpty(engine.EngineType)))
+ {
+ Type engineType = Type.GetType(engine.EngineType);
+ if (engineType == null)
+ objEngine = new GenericAnalyticsEngine();
+ else
+ objEngine = (AnalyticsEngineBase) Activator.CreateInstance(engineType);
+ }
+ else
+ {
+ objEngine = new GenericAnalyticsEngine();
+ }
+ if (objEngine != null)
+ {
+ string script = engine.ScriptTemplate;
+ if ((!String.IsNullOrEmpty(script)))
+ {
+ script = objEngine.RenderScript(script);
+ if ((!String.IsNullOrEmpty(script)))
+ {
+ var element = (HtmlContainerControl) page.FindControl(engine.ElementId);
+ if (element != null)
+ {
+ var scriptControl = new LiteralControl();
+ scriptControl.Text = script;
+ if (engine.InjectTop)
+ {
+ element.Controls.AddAt(0, scriptControl);
+ }
+ else
+ {
+ element.Controls.Add(scriptControl);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ var objEventLog = new EventLogController();
+ var objEventLogInfo = new LogInfo();
+ objEventLogInfo.AddProperty("Analytics.AnalyticsModule", "OnPageLoad");
+ objEventLogInfo.AddProperty("ExceptionMessage", ex.Message);
+ objEventLogInfo.LogTypeKey = EventLogController.EventLogType.HOST_ALERT.ToString();
+ objEventLog.AddLog(objEventLogInfo);
+ Logger.Error(ex);
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngine.cs b/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngine.cs
new file mode 100644
index 00000000000..3b3f4babd88
--- /dev/null
+++ b/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngine.cs
@@ -0,0 +1,85 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Config
+{
+ [Serializable]
+ public class AnalyticsEngine
+ {
+ private string _elementId;
+ private string _engineType;
+ private bool _injectTop;
+ private string _scriptTemplate;
+
+ public string EngineType
+ {
+ get
+ {
+ return _engineType;
+ }
+ set
+ {
+ _engineType = value;
+ }
+ }
+
+ public string ScriptTemplate
+ {
+ get
+ {
+ return _scriptTemplate;
+ }
+ set
+ {
+ _scriptTemplate = value;
+ }
+ }
+
+ public string ElementId
+ {
+ get
+ {
+ return _elementId;
+ }
+ set
+ {
+ _elementId = value;
+ }
+ }
+
+ public bool InjectTop
+ {
+ get
+ {
+ return _injectTop;
+ }
+ set
+ {
+ _injectTop = value;
+ }
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngineCollection.cs b/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngineCollection.cs
new file mode 100644
index 00000000000..32080b5a56d
--- /dev/null
+++ b/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngineCollection.cs
@@ -0,0 +1,50 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Config
+{
+ [Serializable]
+ public class AnalyticsEngineCollection : CollectionBase
+ {
+ public virtual AnalyticsEngine this[int index]
+ {
+ get
+ {
+ return (AnalyticsEngine) base.List[index];
+ }
+ set
+ {
+ base.List[index] = value;
+ }
+ }
+
+ public void Add(AnalyticsEngine a)
+ {
+ InnerList.Add(a);
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngineConfiguration.cs b/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngineConfiguration.cs
new file mode 100644
index 00000000000..9b93725bd2a
--- /dev/null
+++ b/DNN Platform/HttpModules/Analytics/Config/AnalyticsEngineConfiguration.cs
@@ -0,0 +1,129 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.IO;
+using System.Xml.Serialization;
+using System.Xml.XPath;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Instrumentation;
+using DotNetNuke.Services.Cache;
+using DotNetNuke.Services.Log.EventLog;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Config
+{
+ /// -----------------------------------------------------------------------------
+ /// Namespace: DotNetNuke.HttpModules.Analytics
+ /// Project: HttpModules
+ /// Module: AnalyticsEngineConfiguration
+ /// -----------------------------------------------------------------------------
+ ///
+ /// Class definition for AnalyticsEngineConfiguration which is used to create
+ /// an AnalyticsEngineCollection
+ ///
+ ///
+ ///
+ ///
+ /// [cniknet] 05/03/2009 created
+ ///
+ /// -----------------------------------------------------------------------------
+ [Serializable, XmlRoot("AnalyticsEngineConfig")]
+ public class AnalyticsEngineConfiguration
+ {
+ private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof (AnalyticsEngineConfiguration));
+ private AnalyticsEngineCollection _analyticsEngines;
+
+ public AnalyticsEngineCollection AnalyticsEngines
+ {
+ get
+ {
+ return _analyticsEngines;
+ }
+ set
+ {
+ _analyticsEngines = value;
+ }
+ }
+
+ public static AnalyticsEngineConfiguration GetConfig()
+ {
+ var config = new AnalyticsEngineConfiguration {AnalyticsEngines = new AnalyticsEngineCollection()};
+ FileStream fileReader = null;
+ string filePath = "";
+ try
+ {
+ config = (AnalyticsEngineConfiguration) DataCache.GetCache("AnalyticsEngineConfig");
+ if ((config == null))
+ {
+ filePath = Common.Utilities.Config.GetPathToFile(Common.Utilities.Config.ConfigFileType.SiteAnalytics);
+
+ //Create a FileStream for the Config file
+ fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ var doc = new XPathDocument(fileReader);
+ config = new AnalyticsEngineConfiguration {AnalyticsEngines = new AnalyticsEngineCollection()};
+ foreach (XPathNavigator nav in
+ doc.CreateNavigator().Select("AnalyticsEngineConfig/Engines/AnalyticsEngine"))
+ {
+ var analyticsEngine = new AnalyticsEngine
+ {
+ EngineType = nav.SelectSingleNode("EngineType").Value,
+ ElementId = nav.SelectSingleNode("ElementId").Value,
+ InjectTop = Convert.ToBoolean(nav.SelectSingleNode("InjectTop").Value),
+ ScriptTemplate = nav.SelectSingleNode("ScriptTemplate").Value
+ };
+ config.AnalyticsEngines.Add(analyticsEngine);
+ }
+ if (File.Exists(filePath))
+ {
+ //Set back into Cache
+ DataCache.SetCache("AnalyticsEngineConfig", config, new DNNCacheDependency(filePath));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ //log it
+ var objEventLog = new EventLogController();
+ var objEventLogInfo = new LogInfo();
+ objEventLogInfo.AddProperty("Analytics.AnalyticsEngineConfiguration", "GetConfig Failed");
+ objEventLogInfo.AddProperty("FilePath", filePath);
+ objEventLogInfo.AddProperty("ExceptionMessage", ex.Message);
+ objEventLogInfo.LogTypeKey = EventLogController.EventLogType.HOST_ALERT.ToString();
+ objEventLog.AddLog(objEventLogInfo);
+ Logger.Error(objEventLogInfo);
+
+ }
+ finally
+ {
+ if (fileReader != null)
+ {
+ //Close the Reader
+ fileReader.Close();
+ }
+ }
+ return config;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Compression/CompressionModule.cs b/DNN Platform/HttpModules/Compression/CompressionModule.cs
new file mode 100644
index 00000000000..9ca8844b5b0
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/CompressionModule.cs
@@ -0,0 +1,66 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.IO;
+using System.Web;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Framework;
+using DotNetNuke.Instrumentation;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Compression
+{
+
+ [Obsolete("Removed in version 6.2 - class still exists but does nothing.")]
+ public class CompressionModule : IHttpModule
+ {
+ #region IHttpModule Members
+
+ ///
+ /// Init the handler and fulfill
+ ///
+ ///
+ /// This implementation hooks the ReleaseRequestState and PreSendRequestHeaders events to
+ /// figure out as late as possible if we should install the filter. Previous versions did
+ /// not do this as well.
+ ///
+ /// The this handler is working for.
+ public void Init(HttpApplication context)
+ {
+ }
+
+ ///
+ /// Implementation of
+ ///
+ ///
+ /// Currently empty. Nothing to really do, as I have no member variables.
+ ///
+ public void Dispose()
+ {
+ }
+
+ #endregion
+ }
+}
diff --git a/DNN Platform/HttpModules/Compression/Config/Enums.cs b/DNN Platform/HttpModules/Compression/Config/Enums.cs
new file mode 100644
index 00000000000..24fd8deb3a2
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/Config/Enums.cs
@@ -0,0 +1,33 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.HttpModules.Compression
+{
+ ///
+ /// The available compression algorithms to use with the HttpCompressionModule
+ ///
+ public enum Algorithms
+ {
+ Deflate = 2,
+ GZip = 1,
+ None = 0,
+ Default = -1
+ }
+}
diff --git a/DNN Platform/HttpModules/Compression/Config/Settings.cs b/DNN Platform/HttpModules/Compression/Config/Settings.cs
new file mode 100644
index 00000000000..05ee72a9c9a
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/Config/Settings.cs
@@ -0,0 +1,130 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Specialized;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Xml.XPath;
+
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Host;
+using DotNetNuke.Services.Cache;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Compression
+{
+ ///
+ /// This class encapsulates the settings for an HttpCompressionModule
+ ///
+ [Serializable]
+ public class Settings
+ {
+ private readonly StringCollection _excludedPaths;
+ private Algorithms _preferredAlgorithm;
+
+ private Settings()
+ {
+ _preferredAlgorithm = Algorithms.None;
+ _excludedPaths = new StringCollection();
+ }
+
+ ///
+ /// The default settings. Deflate + normal.
+ ///
+ public static Settings Default
+ {
+ get
+ {
+ return new Settings();
+ }
+ }
+
+ ///
+ /// The preferred algorithm to use for compression
+ ///
+ public Algorithms PreferredAlgorithm
+ {
+ get
+ {
+ return _preferredAlgorithm;
+ }
+ }
+
+ ///
+ /// Get the current settings from the xml config file
+ ///
+ public static Settings GetSettings()
+ {
+ var settings = (Settings) DataCache.GetCache("CompressionConfig");
+ if (settings == null)
+ {
+ settings = Default;
+ //Place this in a try/catch as during install the host settings will not exist
+ try
+ {
+ settings._preferredAlgorithm = (Algorithms) Host.HttpCompressionAlgorithm;
+ }
+ catch (Exception e)
+ {
+ DotNetNuke.Services.Exceptions.Exceptions.LogException(e);
+ }
+
+ string filePath = Common.Utilities.Config.GetPathToFile(Common.Utilities.Config.ConfigFileType.Compression);
+
+ //Create a FileStream for the Config file
+ var fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ var doc = new XPathDocument(fileReader);
+ foreach (XPathNavigator nav in doc.CreateNavigator().Select("compression/excludedPaths/path"))
+ {
+ settings._excludedPaths.Add(nav.Value.ToLower());
+ }
+ if ((File.Exists(filePath)))
+ {
+ //Set back into Cache
+ DataCache.SetCache("CompressionConfig", settings, new DNNCacheDependency(filePath));
+ }
+ }
+ return settings;
+ }
+
+ ///
+ /// Looks for a given path in the list of paths excluded from compression
+ ///
+ /// the relative url to check
+ /// true if excluded, false if not
+ public bool IsExcludedPath(string relUrl)
+ {
+ bool match = false;
+ foreach (string path in _excludedPaths)
+ {
+ if (relUrl.ToLower().Contains(path))
+ {
+ match = true;
+ break;
+ }
+ }
+ return match;
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Compression/Filters/CompressingFilter.cs b/DNN Platform/HttpModules/Compression/Filters/CompressingFilter.cs
new file mode 100644
index 00000000000..47920c87df6
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/Filters/CompressingFilter.cs
@@ -0,0 +1,84 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.IO;
+using System.Web;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Compression
+{
+ ///
+ /// Base for any HttpFilter that performing compression
+ ///
+ ///
+ /// When implementing this class, you need to implement a
+ /// along with a . The latter corresponds to a
+ /// content coding (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
+ /// that your implementation will support.
+ ///
+ public abstract class CompressingFilter : HttpOutputFilter
+ {
+ private bool _HasWrittenHeaders;
+
+ ///
+ /// Protected constructor that sets up the underlying stream we're compressing into
+ ///
+ /// The stream we're wrapping up
+ protected CompressingFilter(Stream baseStream) : base(baseStream)
+ {
+ }
+
+ ///
+ /// The name of the content-encoding that's being implemented
+ ///
+ ///
+ /// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5 for more
+ /// details on content codings.
+ ///
+ public abstract string ContentEncoding { get; }
+
+ ///
+ /// Keeps track of whether or not we're written the compression headers
+ ///
+ protected bool HasWrittenHeaders
+ {
+ get
+ {
+ return _HasWrittenHeaders;
+ }
+ }
+
+ ///
+ /// Writes out the compression-related headers. Subclasses should call this once before writing to the output stream.
+ ///
+ internal void WriteHeaders()
+ {
+ //this is dangerous. if Response.End is called before the filter is used, directly or indirectly,
+ //the content will not pass through the filter. However, this header will still be appended.
+ //Look for handling cases in PreRequestSendHeaders and Pre
+ HttpContext.Current.Response.AppendHeader("Content-Encoding", ContentEncoding);
+ HttpContext.Current.Response.AppendHeader("X-Compressed-By", "DotNetNuke-Compression");
+ _HasWrittenHeaders = true;
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Compression/Filters/DeflateFilter.cs b/DNN Platform/HttpModules/Compression/Filters/DeflateFilter.cs
new file mode 100644
index 00000000000..7b551d551e6
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/Filters/DeflateFilter.cs
@@ -0,0 +1,69 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.IO;
+using System.IO.Compression;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Compression
+{
+ ///
+ /// Summary description for DeflateFilter.
+ ///
+ public class DeflateFilter : CompressingFilter
+ {
+ private readonly DeflateStream m_stream;
+
+ public DeflateFilter(Stream baseStream) : base(baseStream)
+ {
+ m_stream = new DeflateStream(baseStream, CompressionMode.Compress);
+ }
+
+ public override string ContentEncoding
+ {
+ get
+ {
+ return "deflate";
+ }
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (!HasWrittenHeaders)
+ {
+ WriteHeaders();
+ }
+ m_stream.Write(buffer, offset, count);
+ }
+
+ public override void Close()
+ {
+ m_stream.Close();
+ }
+
+ public override void Flush()
+ {
+ m_stream.Flush();
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Compression/Filters/GZipFilter.cs b/DNN Platform/HttpModules/Compression/Filters/GZipFilter.cs
new file mode 100644
index 00000000000..49d2d3815ca
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/Filters/GZipFilter.cs
@@ -0,0 +1,69 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System.IO;
+using System.IO.Compression;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Compression
+{
+ ///
+ /// This is a little filter to support HTTP compression using GZip
+ ///
+ public class GZipFilter : CompressingFilter
+ {
+ private readonly GZipStream m_stream;
+
+ public GZipFilter(Stream baseStream) : base(baseStream)
+ {
+ m_stream = new GZipStream(baseStream, CompressionMode.Compress);
+ }
+
+ public override string ContentEncoding
+ {
+ get
+ {
+ return "gzip";
+ }
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (!HasWrittenHeaders)
+ {
+ WriteHeaders();
+ }
+ m_stream.Write(buffer, offset, count);
+ }
+
+ public override void Close()
+ {
+ m_stream.Close();
+ }
+
+ public override void Flush()
+ {
+ m_stream.Flush();
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Compression/Filters/HttpOutputFilter.cs b/DNN Platform/HttpModules/Compression/Filters/HttpOutputFilter.cs
new file mode 100644
index 00000000000..162545c2f83
--- /dev/null
+++ b/DNN Platform/HttpModules/Compression/Filters/HttpOutputFilter.cs
@@ -0,0 +1,116 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.IO;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Compression
+{
+ public abstract class HttpOutputFilter : Stream
+ {
+ private readonly Stream _sink;
+
+ protected HttpOutputFilter(Stream baseStream)
+ {
+ _sink = baseStream;
+ }
+
+ protected Stream BaseStream
+ {
+ get
+ {
+ return _sink;
+ }
+ }
+
+ public override bool CanRead
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override bool CanSeek
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override bool CanWrite
+ {
+ get
+ {
+ return _sink.CanWrite;
+ }
+ }
+
+ public override long Length
+ {
+ get
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override long Position
+ {
+ get
+ {
+ throw new NotSupportedException();
+ }
+ set
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override long Seek(long offset, SeekOrigin direction)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long length)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void Close()
+ {
+ _sink.Close();
+ }
+
+ public override void Flush()
+ {
+ _sink.Flush();
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/DotNetNuke.HttpModules.csproj b/DNN Platform/HttpModules/DotNetNuke.HttpModules.csproj
new file mode 100644
index 00000000000..4ce00ab990a
--- /dev/null
+++ b/DNN Platform/HttpModules/DotNetNuke.HttpModules.csproj
@@ -0,0 +1,145 @@
+
+
+
+ 9.0.30729
+ 2.0
+ {3D9C3F5F-1D2D-4D89-995B-438055A5E3A6}
+ Debug
+ AnyCPU
+ DotNetNuke.HttpModules
+ Library
+ v4.0
+ SAK
+ SAK
+ SAK
+ SAK
+ DotNetNuke.HttpModules
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ bin\
+ DotNetNuke.HttpModules.xml
+ true
+ true
+ 4
+ full
+ AllRules.ruleset
+ 1591
+ default
+ DEBUG
+
+
+ bin\
+ DotNetNuke.HttpModules.xml
+ true
+ true
+ 4
+ pdbonly
+ AllRules.ruleset
+ 1591
+
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+ Code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {ddf18e36-41a0-4ca7-a098-78ca6e6f41c1}
+ DotNetNuke.Instrumentation
+
+
+ {6b29aded-7b56-4484-bea5-c0e09079535b}
+ DotNetNuke.Library
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Exception/ExceptionModule.cs b/DNN Platform/HttpModules/Exception/ExceptionModule.cs
new file mode 100644
index 00000000000..aa0b7ead098
--- /dev/null
+++ b/DNN Platform/HttpModules/Exception/ExceptionModule.cs
@@ -0,0 +1,101 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web;
+
+using DotNetNuke.Instrumentation;
+using DotNetNuke.Services.Log.EventLog;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Exceptions
+{
+ public class ExceptionModule : IHttpModule
+ {
+ private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof (ExceptionModule));
+ public string ModuleName
+ {
+ get
+ {
+ return "ExceptionModule";
+ }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ application.Error += OnErrorRequest;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ public void OnErrorRequest(object s, EventArgs e)
+ {
+ try
+ {
+ if(HttpContext.Current == null)
+ {
+ return;
+ }
+
+ HttpContext Context = HttpContext.Current;
+ HttpServerUtility Server = Context.Server;
+ HttpRequest Request = Context.Request;
+
+ //exit if a request for a .net mapping that isn't a content page is made i.e. axd
+ if (Request.Url.LocalPath.ToLower().EndsWith(".aspx") == false && Request.Url.LocalPath.ToLower().EndsWith(".asmx") == false &&
+ Request.Url.LocalPath.ToLower().EndsWith(".ashx") == false)
+ {
+ return;
+ }
+ Exception lastException = Server.GetLastError();
+
+ //HttpExceptions are logged elsewhere
+ if (!(lastException is HttpException))
+ {
+ var lex = new Exception("Unhandled Error: ", Server.GetLastError());
+ var objExceptionLog = new ExceptionLogController();
+ try
+ {
+ objExceptionLog.AddLog(lex);
+ }
+ catch (Exception ex)
+ {
+ Logger.Error(ex);
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ //it is possible when terminating the request for the context not to exist
+ //in this case we just want to exit since there is nothing else we can do
+ Logger.Error(exc);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Membership/MembershipModule.cs b/DNN Platform/HttpModules/Membership/MembershipModule.cs
new file mode 100644
index 00000000000..772a433cfd5
--- /dev/null
+++ b/DNN Platform/HttpModules/Membership/MembershipModule.cs
@@ -0,0 +1,190 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Linq;
+using System.Security.Principal;
+using System.Web;
+
+using DotNetNuke.Application;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Host;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Users;
+using DotNetNuke.Security;
+using DotNetNuke.Security.Roles;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Services.Personalization;
+using DotNetNuke.UI.Skins.Controls;
+using DotNetNuke.UI.Skins.EventListeners;
+using DotNetNuke.Security.Roles.Internal;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Membership
+{
+ public class MembershipModule : IHttpModule
+ {
+ public string ModuleName
+ {
+ get
+ {
+ return "DNNMembershipModule";
+ }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ application.AuthenticateRequest += OnAuthenticateRequest;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ private void OnAuthenticateRequest(object sender, EventArgs e)
+ {
+ var application = (HttpApplication) sender;
+ AuthenticateRequest(new HttpContextWrapper(application.Context), false);
+ }
+
+ public static void OnUnverifiedUserSkinInit(object sender, SkinEventArgs e)
+ {
+ var strMessage = Localization.GetString("UnverifiedUser");
+ UI.Skins.Skin.AddPageMessage(e.Skin, "", strMessage, ModuleMessage.ModuleMessageType.YellowWarning);
+ }
+
+ public static void AuthenticateRequest(HttpContextBase context, bool allowUnknownExtensinons)
+ {
+ HttpRequestBase request = context.Request;
+ HttpResponseBase response = context.Response;
+
+ //First check if we are upgrading/installing
+ if (request == null || request.Url == null
+ || request.Url.LocalPath.ToLower().EndsWith("install.aspx")
+ || request.Url.LocalPath.ToLower().Contains("upgradewizard.aspx")
+ || request.Url.LocalPath.ToLower().Contains("installwizard.aspx"))
+ {
+ return;
+ }
+
+ //exit if a request for a .net mapping that isn't a content page is made i.e. axd
+ if (allowUnknownExtensinons == false
+ && request.Url.LocalPath.ToLower().EndsWith(".aspx") == false
+ && request.Url.LocalPath.ToLower().EndsWith(".asmx") == false
+ && request.Url.LocalPath.ToLower().EndsWith(".ashx") == false)
+ {
+ return;
+ }
+
+ //Obtain PortalSettings from Current Context
+ PortalSettings portalSettings = PortalController.GetCurrentPortalSettings();
+
+ bool isActiveDirectoryAuthHeaderPresent = false;
+ var auth = request.Headers.Get("Authorization");
+ if(!string.IsNullOrEmpty(auth))
+ {
+ if(auth.StartsWith("Negotiate"))
+ {
+ isActiveDirectoryAuthHeaderPresent = true;
+ }
+ }
+
+ if (request.IsAuthenticated && !isActiveDirectoryAuthHeaderPresent && portalSettings != null)
+ {
+ var roleController = new RoleController();
+ var user = UserController.GetCachedUser(portalSettings.PortalId, context.User.Identity.Name);
+ //if current login is from windows authentication, the ignore the process
+ if (user == null && context.User is WindowsPrincipal)
+ {
+ return;
+ }
+
+ //authenticate user and set last login ( this is necessary for users who have a permanent Auth cookie set )
+ if (user == null || user.IsDeleted || user.Membership.LockedOut
+ || (!user.Membership.Approved && !user.IsInRole("Unverified Users"))
+ || user.Username.ToLower() != context.User.Identity.Name.ToLower())
+ {
+ var portalSecurity = new PortalSecurity();
+ portalSecurity.SignOut();
+
+ //Remove user from cache
+ if (user != null)
+ {
+ DataCache.ClearUserCache(portalSettings.PortalId, context.User.Identity.Name);
+ }
+
+ //Redirect browser back to home page
+ response.Redirect(request.RawUrl, true);
+ return;
+ }
+
+ if (!user.IsSuperUser && user.IsInRole("Unverified Users") && !HttpContext.Current.Items.Contains(DotNetNuke.UI.Skins.Skin.OnInitMessage))
+ {
+ HttpContext.Current.Items.Add(DotNetNuke.UI.Skins.Skin.OnInitMessage, Localization.GetString("UnverifiedUser"));
+ }
+
+ if (!user.IsSuperUser && HttpContext.Current.Request.QueryString.AllKeys.Contains("VerificationSuccess") && !HttpContext.Current.Items.Contains(DotNetNuke.UI.Skins.Skin.OnInitMessage))
+ {
+ HttpContext.Current.Items.Add(DotNetNuke.UI.Skins.Skin.OnInitMessage, Localization.GetString("VerificationSuccess"));
+ HttpContext.Current.Items.Add(DotNetNuke.UI.Skins.Skin.OnInitMessageType, ModuleMessage.ModuleMessageType.GreenSuccess);
+ }
+
+ //if users LastActivityDate is outside of the UsersOnlineTimeWindow then record user activity
+ if (DateTime.Compare(user.Membership.LastActivityDate.AddMinutes(Host.UsersOnlineTimeWindow), DateTime.Now) < 0)
+ {
+ //update LastActivityDate and IP Address for user
+ user.Membership.LastActivityDate = DateTime.Now;
+ user.LastIPAddress = request.UserHostAddress;
+ UserController.UpdateUser(portalSettings.PortalId, user, false, false);
+ }
+
+ //check for RSVP code
+ if (request.QueryString["rsvp"] != null && !string.IsNullOrEmpty(request.QueryString["rsvp"]))
+ {
+ foreach (var role in TestableRoleController.Instance.GetRoles(portalSettings.PortalId, r => (r.SecurityMode != SecurityMode.SocialGroup || r.IsPublic) && r.Status == RoleStatus.Approved))
+ {
+ if (role.RSVPCode == request.QueryString["rsvp"])
+ {
+ roleController.UpdateUserRole(portalSettings.PortalId, user.UserID, role.RoleID);
+ }
+ }
+ }
+
+ //save userinfo object in context
+ context.Items.Add("UserInfo", user);
+
+ //Localization.SetLanguage also updates the user profile, so this needs to go after the profile is loaded
+ Localization.SetLanguage(user.Profile.PreferredLocale);
+ }
+
+ if (context.Items["UserInfo"] == null)
+ {
+ context.Items.Add("UserInfo", new UserInfo());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/MobileRedirect/MobileRedirectModule.cs b/DNN Platform/HttpModules/MobileRedirect/MobileRedirectModule.cs
new file mode 100644
index 00000000000..a3b27829261
--- /dev/null
+++ b/DNN Platform/HttpModules/MobileRedirect/MobileRedirectModule.cs
@@ -0,0 +1,157 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Web;
+
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Controllers;
+using DotNetNuke.Entities.Host;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Entities.Urls;
+using DotNetNuke.HttpModules.Config;
+using DotNetNuke.HttpModules.Services;
+using DotNetNuke.Instrumentation;
+using DotNetNuke.Services.EventQueue;
+using DotNetNuke.Services.Localization;
+using DotNetNuke.Services.Mobile;
+
+#endregion
+
+namespace DotNetNuke.HttpModules
+{
+ public class MobileRedirectModule : IHttpModule
+ {
+ private IRedirectionController _redirectionController;
+ private IList _specialPages = new List { "/login.aspx", "/register.aspx", "/terms.aspx", "/privacy.aspx", "/login", "/register", "/terms", "/privacy" };
+ public string ModuleName
+ {
+ get
+ {
+ return "MobileRedirectModule";
+ }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ _redirectionController = new RedirectionController();
+ application.BeginRequest += OnBeginRequest;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ public void OnBeginRequest(object s, EventArgs e)
+ {
+ var app = (HttpApplication)s;
+ var portalSettings = PortalController.GetCurrentPortalSettings();
+
+ //First check if we are upgrading/installing
+ if (app.Request.Url.LocalPath.ToLower().EndsWith("install.aspx")
+ || app.Request.Url.LocalPath.ToLower().Contains("upgradewizard.aspx")
+ || app.Request.Url.LocalPath.ToLower().Contains("installwizard.aspx")
+ || app.Request.Url.LocalPath.ToLower().EndsWith("captcha.aspx")
+ || app.Request.Url.LocalPath.ToLower().EndsWith("scriptresource.axd")
+ || app.Request.Url.LocalPath.ToLower().EndsWith("webresource.axd")
+ || app.Request.Url.LocalPath.ToLower().EndsWith("sitemap.aspx")
+ || app.Request.Url.LocalPath.ToLower().EndsWith(".asmx")
+ || app.Request.Url.LocalPath.ToLower().EndsWith(".ashx")
+ || app.Request.Url.LocalPath.ToLower().EndsWith(".svc")
+ || app.Request.HttpMethod == "POST"
+ || ServicesModule.ServiceApi.IsMatch(app.Context.Request.RawUrl)
+ || IsSpecialPage(app.Request.RawUrl)
+ || (portalSettings != null && !IsRedirectAllowed(app.Request.RawUrl, app, portalSettings)))
+ {
+ return;
+ }
+ if (_redirectionController != null)
+ {
+ if (portalSettings != null && portalSettings.ActiveTab != null)
+ {
+ if (app != null && app.Request != null && !string.IsNullOrEmpty(app.Request.UserAgent))
+ {
+ //Check if redirection has been disabled for the session
+ //This method inspects cookie and query string. It can also setup / clear cookies.
+ if (!_redirectionController.IsRedirectAllowedForTheSession(app))
+ {
+ return;
+ }
+
+ string redirectUrl = _redirectionController.GetRedirectUrl(app.Request.UserAgent);
+ if (!string.IsNullOrEmpty(redirectUrl))
+ {
+ //append thr query string from original url
+ var queryString = app.Request.RawUrl.Contains("?") ? app.Request.RawUrl.Substring(app.Request.RawUrl.IndexOf("?") + 1) : string.Empty;
+ if (!string.IsNullOrEmpty(queryString))
+ {
+ redirectUrl = string.Format("{0}{1}{2}", redirectUrl, redirectUrl.Contains("?") ? "&" : "?", queryString);
+ }
+ app.Response.Redirect(redirectUrl);
+ }
+ }
+ }
+ }
+ }
+
+ private bool IsRedirectAllowed(string url, HttpApplication app, PortalSettings portalSettings)
+ {
+ var urlAction = new UrlAction(app.Request);
+ urlAction.SetRedirectAllowed(url, new FriendlyUrlSettings(portalSettings.PortalId));
+ return urlAction.RedirectAllowed;
+ }
+
+ private bool IsSpecialPage(string url)
+ {
+ var tabPath = url.ToLowerInvariant();
+ if (tabPath.Contains("?"))
+ {
+ tabPath = tabPath.Substring(0, tabPath.IndexOf("?"));
+ }
+
+ var portalSettings = PortalController.GetCurrentPortalSettings();
+ if (portalSettings == null)
+ {
+ return true;
+ }
+
+ var alias = PortalController.GetCurrentPortalSettings().PortalAlias.HTTPAlias.ToLowerInvariant();
+ if (alias.Contains("/"))
+ {
+ tabPath = tabPath.Replace(alias.Substring(alias.IndexOf("/")), string.Empty);
+ }
+ return _specialPages.Contains(tabPath);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Personalization/PersonalizationModule.cs b/DNN Platform/HttpModules/Personalization/PersonalizationModule.cs
new file mode 100644
index 00000000000..f6d5c8a5b28
--- /dev/null
+++ b/DNN Platform/HttpModules/Personalization/PersonalizationModule.cs
@@ -0,0 +1,78 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web;
+
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Users;
+using DotNetNuke.Services.Personalization;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Personalization
+{
+ public class PersonalizationModule : IHttpModule
+ {
+ public string ModuleName
+ {
+ get
+ {
+ return "PersonalizationModule";
+ }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ application.EndRequest += OnEndRequest;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ public void OnEndRequest(object s, EventArgs e)
+ {
+ HttpContext Context = ((HttpApplication) s).Context;
+ HttpRequest Request = Context.Request;
+ //exit if a request for a .net mapping that isn't a content page is made i.e. axd
+ if (Request.Url.LocalPath.ToLower().EndsWith(".aspx") == false && Request.Url.LocalPath.ToLower().EndsWith(".asmx") == false && Request.Url.LocalPath.ToLower().EndsWith(".ashx") == false)
+ {
+ return;
+ }
+
+ //Obtain PortalSettings from Current Context
+ var _portalSettings = (PortalSettings) Context.Items["PortalSettings"];
+ if (_portalSettings != null)
+ {
+ //load the user info object
+ UserInfo UserInfo = UserController.GetCurrentUserInfo();
+ var personalization = new PersonalizationController();
+ personalization.SaveProfile(Context, UserInfo.UserID, _portalSettings.PortalId);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Properties/AssemblyInfo.cs b/DNN Platform/HttpModules/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..0f17bdd5a60
--- /dev/null
+++ b/DNN Platform/HttpModules/Properties/AssemblyInfo.cs
@@ -0,0 +1,41 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+#endregion
+
+[assembly: AssemblyTitle("DotNetNuke.HttpModules")]
+[assembly: AssemblyDescription("Open Source Web Application Framework")]
+[assembly: AssemblyCompany("DotNetNuke Corporation")]
+[assembly: AssemblyProduct("http://www.dotnetnuke.com")]
+[assembly: AssemblyCopyright("DotNetNuke is copyright 2002-2013 by DotNetNuke Corporation. All Rights Reserved.")]
+[assembly: AssemblyTrademark("DotNetNuke")]
+[assembly: CLSCompliant(true)]
+[assembly: Guid("7FF35751-D6A3-4DA0-A5E7-2F1AB026832B")]
+[assembly: AssemblyVersion("6.2.1.11")]
+
+[assembly: InternalsVisibleTo("DotNetNuke.Tests.Core")]
+[assembly: InternalsVisibleTo("DotNetNuke.Tests.Urls")]
diff --git a/DNN Platform/HttpModules/RequestFilter/Config/Enums.cs b/DNN Platform/HttpModules/RequestFilter/Config/Enums.cs
new file mode 100644
index 00000000000..ee6c3515211
--- /dev/null
+++ b/DNN Platform/HttpModules/RequestFilter/Config/Enums.cs
@@ -0,0 +1,36 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+namespace DotNetNuke.HttpModules.RequestFilter
+{
+ public enum RequestFilterRuleType
+ {
+ Redirect,
+ PermanentRedirect,
+ NotFound
+ }
+
+ public enum RequestFilterOperatorType
+ {
+ Equal,
+ NotEqual,
+ Regex
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/RequestFilter/Config/RequestFilterSettings.cs b/DNN Platform/HttpModules/RequestFilter/Config/RequestFilterSettings.cs
new file mode 100644
index 00000000000..45dbc69e328
--- /dev/null
+++ b/DNN Platform/HttpModules/RequestFilter/Config/RequestFilterSettings.cs
@@ -0,0 +1,150 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Xml.XPath;
+
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Host;
+using DotNetNuke.Services.Cache;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.RequestFilter
+{
+ [Serializable, XmlRoot("RewriterConfig")]
+ public class RequestFilterSettings
+ {
+ private const string RequestFilterConfig = "RequestFilter.Config";
+
+ private List _rules = new List();
+
+ public bool Enabled
+ {
+ get
+ {
+ return Host.EnableRequestFilters;
+ }
+ }
+
+ public List Rules
+ {
+ get
+ {
+ return _rules;
+ }
+ set
+ {
+ _rules = value;
+ }
+ }
+
+ ///
+ /// Get the current settings from the xml config file
+ ///
+ public static RequestFilterSettings GetSettings()
+ {
+ var settings = (RequestFilterSettings) DataCache.GetCache(RequestFilterConfig);
+ if (settings == null)
+ {
+ settings = new RequestFilterSettings();
+ string filePath = Common.Utilities.Config.GetPathToFile(Common.Utilities.Config.ConfigFileType.DotNetNuke);
+
+ //Create a FileStream for the Config file
+ var fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ var doc = new XPathDocument(fileReader);
+ XPathNodeIterator ruleList = doc.CreateNavigator().Select("/configuration/blockrequests/rule");
+ while (ruleList.MoveNext())
+ {
+ try
+ {
+ string serverVar = ruleList.Current.GetAttribute("servervar", string.Empty);
+ string values = ruleList.Current.GetAttribute("values", string.Empty);
+ var ac = (RequestFilterRuleType) Enum.Parse(typeof (RequestFilterRuleType), ruleList.Current.GetAttribute("action", string.Empty));
+ var op = (RequestFilterOperatorType) Enum.Parse(typeof (RequestFilterOperatorType), ruleList.Current.GetAttribute("operator", string.Empty));
+ string location = ruleList.Current.GetAttribute("location", string.Empty);
+ var rule = new RequestFilterRule(serverVar, values, op, ac, location);
+ settings.Rules.Add(rule);
+ }
+ catch (Exception ex)
+ {
+ DotNetNuke.Services.Exceptions.Exceptions.LogException(new Exception(string.Format("Unable to read RequestFilter Rule: {0}:", ruleList.Current.OuterXml), ex));
+ }
+ }
+ if ((File.Exists(filePath)))
+ {
+ //Set back into Cache
+ DataCache.SetCache(RequestFilterConfig, settings, new DNNCacheDependency(filePath));
+ }
+ }
+ return settings;
+ }
+
+ public static void Save(List rules)
+ {
+ string filePath = Common.Utilities.Config.GetPathToFile(Common.Utilities.Config.ConfigFileType.DotNetNuke);
+ if (!File.Exists(filePath))
+ {
+ string defaultConfigFile = Globals.ApplicationMapPath + Globals.glbConfigFolder + Globals.glbDotNetNukeConfig;
+ if ((File.Exists(defaultConfigFile)))
+ {
+ File.Copy(defaultConfigFile, filePath, true);
+ }
+ }
+ var doc = new XmlDocument();
+ doc.Load(filePath);
+ XmlNode ruleRoot = doc.SelectSingleNode("/configuration/blockrequests");
+ ruleRoot.RemoveAll();
+ foreach (RequestFilterRule rule in rules)
+ {
+ XmlElement xmlRule = doc.CreateElement("rule");
+ XmlAttribute var = doc.CreateAttribute("servervar");
+ var.Value = rule.ServerVariable;
+ xmlRule.Attributes.Append(var);
+ XmlAttribute val = doc.CreateAttribute("values");
+ val.Value = rule.RawValue;
+ xmlRule.Attributes.Append(val);
+ XmlAttribute op = doc.CreateAttribute("operator");
+ op.Value = rule.Operator.ToString();
+ xmlRule.Attributes.Append(op);
+ XmlAttribute action = doc.CreateAttribute("action");
+ action.Value = rule.Action.ToString();
+ xmlRule.Attributes.Append(action);
+ XmlAttribute location = doc.CreateAttribute("location");
+ location.Value = rule.Location;
+ xmlRule.Attributes.Append(location);
+ ruleRoot.AppendChild(xmlRule);
+ }
+ var settings = new XmlWriterSettings();
+ settings.Indent = true;
+ using (XmlWriter writer = XmlWriter.Create(filePath, settings))
+ {
+ doc.WriteContentTo(writer);
+ }
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/RequestFilter/RequestFilterModule.cs b/DNN Platform/HttpModules/RequestFilter/RequestFilterModule.cs
new file mode 100644
index 00000000000..030de21649f
--- /dev/null
+++ b/DNN Platform/HttpModules/RequestFilter/RequestFilterModule.cs
@@ -0,0 +1,126 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web;
+
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utils;
+using DotNetNuke.Entities.Urls;
+using DotNetNuke.HttpModules.UrlRewrite;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.RequestFilter
+{
+ public class RequestFilterModule : IHttpModule
+ {
+ private const string InstalledKey = "httprequestfilter.attemptedinstall";
+
+ #region IHttpModule Members
+
+ ///
+ /// Implementation of
+ ///
+ ///
+ /// Currently empty. Nothing to really do, as I have no member variables.
+ ///
+ public void Dispose()
+ {
+ }
+
+ public void Init(HttpApplication context)
+ {
+ context.BeginRequest += FilterRequest;
+ }
+
+ #endregion
+
+ private static void FilterRequest(object sender, EventArgs e)
+ {
+ var app = (HttpApplication) sender;
+ if ((app == null) || (app.Context == null) || (app.Context.Items == null))
+ {
+ return;
+ }
+ var request = app.Context.Request;
+ if (RewriterUtils.OmitFromRewriteProcessing(request.Url.LocalPath))
+ {
+ return;
+ }
+
+ //Carry out first time initialization tasks
+ Initialize.Init(app);
+ if (request.Url.LocalPath.ToLower().EndsWith("install.aspx")
+ || request.Url.LocalPath.ToLower().Contains("upgradewizard.aspx")
+ || request.Url.LocalPath.ToLower().Contains("installwizard.aspx"))
+ {
+ return;
+ }
+
+ //only do this if we havn't already attempted an install. This prevents PreSendRequestHeaders from
+ //trying to add this item way to late. We only want the first run through to do anything.
+ //also, we use the context to store whether or not we've attempted an add, as it's thread-safe and
+ //scoped to the request. An instance of this module can service multiple requests at the same time,
+ //so we cannot use a member variable.
+ if (!app.Context.Items.Contains(InstalledKey))
+ {
+ //log the install attempt in the HttpContext
+ //must do this first as several IF statements
+ //below skip full processing of this method
+ app.Context.Items.Add(InstalledKey, true);
+ var settings = RequestFilterSettings.GetSettings();
+ if ((settings == null || settings.Rules.Count == 0 || !settings.Enabled))
+ {
+ return;
+ }
+ foreach (var rule in settings.Rules)
+ {
+ //Added ability to determine the specific value types for addresses
+ //this check was necessary so that your rule could deal with IPv4 or IPv6
+ //To use this mode, add ":IPv4" or ":IPv6" to your servervariable name.
+ var varArray = rule.ServerVariable.Split(':');
+ var varVal = request.ServerVariables[varArray[0]];
+ if (varArray[0].EndsWith("_ADDR", StringComparison.InvariantCultureIgnoreCase) && varArray.Length > 1)
+ {
+ switch (varArray[1])
+ {
+ case "IPv4":
+ varVal = NetworkUtils.GetAddress(varVal, AddressType.IPv4);
+ break;
+ case "IPv6":
+ varVal = NetworkUtils.GetAddress(varVal, AddressType.IPv4);
+ break;
+ }
+ }
+ if ((!string.IsNullOrEmpty(varVal)))
+ {
+ if ((rule.Matches(varVal)))
+ {
+ rule.Execute();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/RequestFilter/RequestFilterRule.cs b/DNN Platform/HttpModules/RequestFilter/RequestFilterRule.cs
new file mode 100644
index 00000000000..b970c54f7a8
--- /dev/null
+++ b/DNN Platform/HttpModules/RequestFilter/RequestFilterRule.cs
@@ -0,0 +1,186 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Web;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.RequestFilter
+{
+ [Serializable]
+ public class RequestFilterRule
+ {
+ private RequestFilterRuleType _Action;
+ private string _Location;
+ private RequestFilterOperatorType _Operator;
+ private string _ServerVariable;
+ private List _Values = new List();
+
+ ///
+ /// Initializes a new instance of the RequestFilterRule class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public RequestFilterRule(string serverVariable, string values, RequestFilterOperatorType op, RequestFilterRuleType action, string location)
+ {
+ _ServerVariable = serverVariable;
+ SetValues(values, op);
+ _Operator = op;
+ _Action = action;
+ _Location = location;
+ }
+
+ ///
+ /// Initializes a new instance of the RequestFilterRule class.
+ ///
+ public RequestFilterRule()
+ {
+ }
+
+ public string ServerVariable
+ {
+ get
+ {
+ return _ServerVariable;
+ }
+ set
+ {
+ _ServerVariable = value;
+ }
+ }
+
+ public List Values
+ {
+ get
+ {
+ return _Values;
+ }
+ set
+ {
+ _Values = value;
+ }
+ }
+
+ public string RawValue
+ {
+ get
+ {
+ return string.Join(" ", _Values.ToArray());
+ }
+ }
+
+ public RequestFilterRuleType Action
+ {
+ get
+ {
+ return _Action;
+ }
+ set
+ {
+ _Action = value;
+ }
+ }
+
+ public RequestFilterOperatorType Operator
+ {
+ get
+ {
+ return _Operator;
+ }
+ set
+ {
+ _Operator = value;
+ }
+ }
+
+ public string Location
+ {
+ get
+ {
+ return _Location;
+ }
+ set
+ {
+ _Location = value;
+ }
+ }
+
+ public void SetValues(string values, RequestFilterOperatorType op)
+ {
+ _Values.Clear();
+ if ((op != RequestFilterOperatorType.Regex))
+ {
+ string[] vals = values.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
+ foreach (string value in vals)
+ {
+ _Values.Add(value.ToUpperInvariant());
+ }
+ }
+ else
+ {
+ _Values.Add(values);
+ }
+ }
+
+ public bool Matches(string ServerVariableValue)
+ {
+ switch (Operator)
+ {
+ case RequestFilterOperatorType.Equal:
+ return Values.Contains(ServerVariableValue.ToUpperInvariant());
+ case RequestFilterOperatorType.NotEqual:
+ return !Values.Contains(ServerVariableValue.ToUpperInvariant());
+ case RequestFilterOperatorType.Regex:
+ return Regex.IsMatch(ServerVariableValue, Values[0], RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ }
+ return false;
+ }
+
+ public void Execute()
+ {
+ HttpResponse response = HttpContext.Current.Response;
+ switch (Action)
+ {
+ case RequestFilterRuleType.Redirect:
+ response.Redirect(Location, true);
+ break;
+ case RequestFilterRuleType.PermanentRedirect:
+ response.StatusCode = 301;
+ response.Status = "301 Moved Permanently";
+ response.RedirectLocation = Location;
+ response.End();
+ break;
+ case RequestFilterRuleType.NotFound:
+ response.StatusCode = 404;
+ response.SuppressContent = true;
+ response.End();
+ break;
+ }
+ }
+ }
+}
diff --git a/DNN Platform/HttpModules/Services/ServicesModule.cs b/DNN Platform/HttpModules/Services/ServicesModule.cs
new file mode 100644
index 00000000000..5fbc577006c
--- /dev/null
+++ b/DNN Platform/HttpModules/Services/ServicesModule.cs
@@ -0,0 +1,50 @@
+#region Copyright
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+using System;
+using System.Text.RegularExpressions;
+using System.Web;
+using DotNetNuke.Common;
+
+namespace DotNetNuke.HttpModules.Services
+{
+ public class ServicesModule : IHttpModule
+ {
+ public static readonly Regex ServiceApi = new Regex(@"DesktopModules/.+/API");
+
+ public void Init(HttpApplication context)
+ {
+ context.BeginRequest += InitDnn;
+ }
+
+ private void InitDnn(object sender, EventArgs e)
+ {
+ var app = sender as HttpApplication;
+ if (app != null && ServiceApi.IsMatch(app.Context.Request.RawUrl))
+ {
+ Initialize.Init(app);
+ }
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/UrlRewrite/BasicUrlRewriter.cs b/DNN Platform/HttpModules/UrlRewrite/BasicUrlRewriter.cs
new file mode 100644
index 00000000000..fbd6f6cf438
--- /dev/null
+++ b/DNN Platform/HttpModules/UrlRewrite/BasicUrlRewriter.cs
@@ -0,0 +1,822 @@
+#region Copyright
+
+//
+// DotNetNuke® - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region Usings
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Web;
+
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Entities.Controllers;
+using DotNetNuke.Entities.Host;
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Portals.Internal;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Entities.Urls;
+using DotNetNuke.Entities.Urls.Config;
+using DotNetNuke.Instrumentation;
+using DotNetNuke.Services.EventQueue;
+using DotNetNuke.Services.Localization;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.UrlRewrite
+{
+ internal class BasicUrlRewriter : UrlRewriterBase
+ {
+ private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(BasicUrlRewriter));
+
+ #region overridden methods
+
+ internal override void RewriteUrl(object sender, EventArgs e)
+ {
+ var app = (HttpApplication) sender;
+ HttpServerUtility server = app.Server;
+ HttpRequest request = app.Request;
+ HttpResponse response = app.Response;
+ HttpContext context = app.Context;
+ string requestedPath = app.Request.Url.AbsoluteUri;
+
+ if (RewriterUtils.OmitFromRewriteProcessing(request.Url.LocalPath))
+ {
+ return;
+ }
+
+ //'Carry out first time initialization tasks
+ Initialize.Init(app);
+ if (request.Url.LocalPath.ToLower().EndsWith("/install/install.aspx")
+ || request.Url.LocalPath.ToLower().Contains("/install/upgradewizard.aspx")
+ || request.Url.LocalPath.ToLower().Contains("/install/installwizard.aspx")
+ || request.Url.LocalPath.ToLower().EndsWith("captcha.aspx")
+ || request.Url.LocalPath.ToLower().EndsWith("scriptresource.axd")
+ || request.Url.LocalPath.ToLower().EndsWith("webresource.axd"))
+ {
+ return;
+ }
+
+ //URL validation
+ //check for ".." escape characters commonly used by hackers to traverse the folder tree on the server
+ //the application should always use the exact relative location of the resource it is requesting
+ string strURL = request.Url.AbsolutePath;
+ string strDoubleDecodeURL = server.UrlDecode(server.UrlDecode(request.RawUrl));
+ if (Regex.Match(strURL, "[\\\\/]\\.\\.[\\\\/]").Success ||
+// ReSharper disable AssignNullToNotNullAttribute
+ Regex.Match(strDoubleDecodeURL, "[\\\\/]\\.\\.[\\\\/]").Success)
+// ReSharper restore AssignNullToNotNullAttribute
+ {
+ DotNetNuke.Services.Exceptions.Exceptions.ProcessHttpException(request);
+ }
+ try
+ {
+ //fix for ASP.NET canonicalization issues http://support.microsoft.com/?kbid=887459
+ if ((request.Path.IndexOf("\\", StringComparison.Ordinal) >= 0 || Path.GetFullPath(request.PhysicalPath) != request.PhysicalPath))
+ {
+ DotNetNuke.Services.Exceptions.Exceptions.ProcessHttpException(request);
+ }
+ }
+ catch (Exception exc)
+ {
+ //DNN 5479
+ //request.physicalPath throws an exception when the path of the request exceeds 248 chars.
+ //example to test: http://localhost/dotnetnuke_2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/default.aspx
+ Logger.Error(exc);
+ }
+
+
+ String domainName;
+ RewriteUrl(app, out domainName);
+
+ //blank DomainName indicates RewriteUrl couldn't locate a current portal
+ //reprocess url for portal alias if auto add is an option
+ if (domainName == "" && CanAutoAddPortalAlias())
+ {
+ domainName = Globals.GetDomainName(app.Request, true);
+ }
+
+ //from this point on we are dealing with a "standard" querystring ( ie. http://www.domain.com/default.aspx?tabid=## )
+ //if the portal/url was succesfully identified
+
+ int tabId = Null.NullInteger;
+ int portalId = Null.NullInteger;
+ string portalAlias = null;
+ PortalAliasInfo portalAliasInfo = null;
+ bool parsingError = false;
+
+ // get TabId from querystring ( this is mandatory for maintaining portal context for child portals )
+ if (!string.IsNullOrEmpty(request.QueryString["tabid"]))
+ {
+ if (!Int32.TryParse(request.QueryString["tabid"], out tabId))
+ {
+ tabId = Null.NullInteger;
+ parsingError = true;
+ }
+ }
+
+ // get PortalId from querystring ( this is used for host menu options as well as child portal navigation )
+ if (!string.IsNullOrEmpty(request.QueryString["portalid"]))
+ {
+ if (!Int32.TryParse(request.QueryString["portalid"], out portalId))
+ {
+ portalId = Null.NullInteger;
+ parsingError = true;
+ }
+ }
+
+ if (parsingError)
+ {
+ //The tabId or PortalId are incorrectly formatted (potential DOS)
+ DotNetNuke.Services.Exceptions.Exceptions.ProcessHttpException(request);
+ }
+
+
+ try
+ {
+ //alias parameter can be used to switch portals
+ if (request.QueryString["alias"] != null)
+ {
+ // check if the alias is valid
+ string childAlias = request.QueryString["alias"];
+ if (!Globals.UsePortNumber())
+ {
+ childAlias = childAlias.Replace(":" + request.Url.Port, "");
+ }
+
+ if (PortalAliasController.GetPortalAliasInfo(childAlias) != null)
+ {
+ //check if the domain name contains the alias
+ if (childAlias.IndexOf(domainName, StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ //redirect to the url defined in the alias
+ response.Redirect(Globals.GetPortalDomainName(childAlias, request, true), true);
+ }
+ else //the alias is the same as the current domain
+ {
+ portalAlias = childAlias;
+ }
+ }
+ }
+
+ //PortalId identifies a portal when set
+ if (portalAlias == null)
+ {
+ if (portalId != Null.NullInteger)
+ {
+ portalAlias = PortalAliasController.GetPortalAliasByPortal(portalId, domainName);
+ }
+ }
+
+ //TabId uniquely identifies a Portal
+ if (portalAlias == null)
+ {
+ if (tabId != Null.NullInteger)
+ {
+ //get the alias from the tabid, but only if it is for a tab in that domain
+ portalAlias = PortalAliasController.GetPortalAliasByTab(tabId, domainName);
+ if (String.IsNullOrEmpty(portalAlias))
+ {
+ //if the TabId is not for the correct domain
+ //see if the correct domain can be found and redirect it
+ portalAliasInfo = PortalAliasController.GetPortalAliasInfo(domainName);
+ if (portalAliasInfo != null && !request.Url.LocalPath.ToLower().EndsWith("/linkclick.aspx"))
+ {
+ if (app.Request.Url.AbsoluteUri.StartsWith("https://",
+ StringComparison.InvariantCultureIgnoreCase))
+ {
+ strURL = "https://" + portalAliasInfo.HTTPAlias.Replace("*.", "");
+ }
+ else
+ {
+ strURL = "http://" + portalAliasInfo.HTTPAlias.Replace("*.", "");
+ }
+ if (strURL.IndexOf(domainName, StringComparison.InvariantCultureIgnoreCase) == -1)
+ {
+ strURL += app.Request.Url.PathAndQuery;
+ }
+ response.Redirect(strURL, true);
+ }
+ }
+ }
+ }
+
+ //else use the domain name
+ if (String.IsNullOrEmpty(portalAlias))
+ {
+ portalAlias = domainName;
+ }
+ //using the DomainName above will find that alias that is the domainname portion of the Url
+ //ie. dotnetnuke.com will be found even if zzz.dotnetnuke.com was entered on the Url
+ portalAliasInfo = PortalAliasController.GetPortalAliasInfo(portalAlias);
+ if (portalAliasInfo != null)
+ {
+ portalId = portalAliasInfo.PortalID;
+ }
+
+ //if the portalid is not known
+ if (portalId == Null.NullInteger)
+ {
+ bool autoAddPortalAlias = CanAutoAddPortalAlias();
+
+ if (!autoAddPortalAlias && !request.Url.LocalPath.EndsWith(Globals.glbDefaultPage, StringComparison.InvariantCultureIgnoreCase))
+ {
+ // allows requests for aspx pages in custom folder locations to be processed
+ return;
+ }
+
+ if (autoAddPortalAlias)
+ {
+ AutoAddAlias(context);
+ }
+ }
+ }
+ catch (ThreadAbortException exc)
+ {
+ //Do nothing if Thread is being aborted - there are two response.redirect calls in the Try block
+ Logger.Debug(exc);
+ }
+ catch (Exception ex)
+ {
+ //500 Error - Redirect to ErrorPage
+ Logger.Error(ex);
+
+ strURL = "~/ErrorPage.aspx?status=500&error=" + server.UrlEncode(ex.Message);
+ HttpContext.Current.Response.Clear();
+ HttpContext.Current.Server.Transfer(strURL);
+ }
+ if (portalId != -1)
+ {
+ //load the PortalSettings into current context
+ var portalSettings = new PortalSettings(tabId, portalAliasInfo);
+ app.Context.Items.Add("PortalSettings", portalSettings);
+
+ // load PortalSettings and HostSettings dictionaries into current context
+ // specifically for use in DotNetNuke.Web.Client, which can't reference DotNetNuke.dll to get settings the normal way
+ app.Context.Items.Add("PortalSettingsDictionary", PortalController.GetPortalSettingsDictionary(portalId));
+ app.Context.Items.Add("HostSettingsDictionary", HostController.Instance.GetSettingsDictionary());
+
+ if (portalSettings.PortalAliasMappingMode == PortalSettings.PortalAliasMapping.Redirect &&
+ portalAliasInfo != null && !portalAliasInfo.IsPrimary)
+ {
+ //Permanently Redirect
+ response.StatusCode = 301;
+
+ string redirectAlias = Globals.AddHTTP(portalSettings.DefaultPortalAlias);
+ string checkAlias = Globals.AddHTTP(portalAliasInfo.HTTPAlias);
+ string redirectUrl = redirectAlias + request.RawUrl;
+ if (redirectUrl.StartsWith(checkAlias, StringComparison.InvariantCultureIgnoreCase))
+ {
+ redirectUrl = redirectAlias + redirectUrl.Substring(checkAlias.Length);
+ }
+
+ response.AppendHeader("Location", redirectUrl);
+ }
+
+ //manage page URL redirects - that reach here because they bypass the built-in navigation
+ //ie Spiders, saved favorites, hand-crafted urls etc
+ if (!String.IsNullOrEmpty(portalSettings.ActiveTab.Url) && request.QueryString["ctl"] == null &&
+ request.QueryString["fileticket"] == null)
+ {
+ //Target Url
+ string redirectUrl = portalSettings.ActiveTab.FullUrl;
+ if (portalSettings.ActiveTab.PermanentRedirect)
+ {
+ //Permanently Redirect
+ response.StatusCode = 301;
+ response.AppendHeader("Location", redirectUrl);
+ }
+ else
+ {
+ //Normal Redirect
+ response.Redirect(redirectUrl, true);
+ }
+ }
+
+ //manage secure connections
+ if (request.Url.AbsolutePath.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase))
+ {
+ //request is for a standard page
+ strURL = "";
+ //if SSL is enabled
+ if (portalSettings.SSLEnabled)
+ {
+ //if page is secure and connection is not secure orelse ssloffload is enabled and server value exists
+ if ((portalSettings.ActiveTab.IsSecure && !request.IsSecureConnection) &&
+ (IsSSLOffloadEnabled(request) == false))
+ {
+ //switch to secure connection
+ strURL = requestedPath.Replace("http://", "https://");
+ strURL = FormatDomain(strURL, portalSettings.STDURL, portalSettings.SSLURL);
+ }
+ }
+ //if SSL is enforced
+ if (portalSettings.SSLEnforced)
+ {
+ //if page is not secure and connection is secure
+ if ((!portalSettings.ActiveTab.IsSecure && request.IsSecureConnection))
+ {
+ //check if connection has already been forced to secure orelse ssloffload is disabled
+ if (request.QueryString["ssl"] == null)
+ {
+ strURL = requestedPath.Replace("https://", "http://");
+ strURL = FormatDomain(strURL, portalSettings.SSLURL, portalSettings.STDURL);
+ }
+ }
+ }
+
+ //if a protocol switch is necessary
+ if (!String.IsNullOrEmpty(strURL))
+ {
+ if (strURL.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
+ {
+ //redirect to secure connection
+ response.Redirect(strURL, true);
+ }
+ else
+ //when switching to an unsecure page, use a clientside redirector to avoid the browser security warning
+ {
+ response.Clear();
+ //add a refresh header to the response
+ response.AddHeader("Refresh", "0;URL=" + strURL);
+ //add the clientside javascript redirection script
+ response.Write("");
+ response.Write("");
+ response.Write("");
+ //send the response
+ response.End();
+ }
+ }
+ }
+ }
+ else
+ {
+ //alias does not exist in database
+ //and all attempts to find another have failed
+ //this should only happen if the HostPortal does not have any aliases
+ //404 Error - Redirect to ErrorPage
+ strURL = "~/ErrorPage.aspx?status=404&error=" + domainName;
+ HttpContext.Current.Response.Clear();
+ HttpContext.Current.Server.Transfer(strURL);
+ }
+
+ if (app.Context.Items["FirstRequest"] != null)
+ {
+ app.Context.Items.Remove("FirstRequest");
+
+ //Process any messages in the EventQueue for the Application_Start_FirstRequest event
+ EventQueueController.ProcessMessages("Application_Start_FirstRequest");
+ }
+ }
+
+ #endregion
+
+ #region rewriting methods
+
+ //Note these formerly lived in the 'UrlRewriteModule.cs' class
+ private string FormatDomain(string url, string replaceDomain, string withDomain)
+ {
+ if (!String.IsNullOrEmpty(replaceDomain) && !String.IsNullOrEmpty(withDomain))
+ {
+ if (url.IndexOf(replaceDomain, StringComparison.Ordinal) != -1)
+ {
+ url = url.Replace(replaceDomain, withDomain);
+ }
+ }
+ return url;
+ }
+
+ private void RewriteUrl(HttpApplication app, out string portalAlias)
+ {
+ HttpRequest request = app.Request;
+ HttpResponse response = app.Response;
+ string requestedPath = app.Request.Url.AbsoluteUri;
+
+
+ portalAlias = "";
+
+ //determine portal alias looking for longest possible match
+ String myAlias = Globals.GetDomainName(app.Request, true);
+ PortalAliasInfo objPortalAlias;
+ do
+ {
+ objPortalAlias = PortalAliasController.GetPortalAliasInfo(myAlias);
+
+ if (objPortalAlias != null)
+ {
+ portalAlias = myAlias;
+ break;
+ }
+
+ int slashIndex = myAlias.LastIndexOf('/');
+ myAlias = slashIndex > 1 ? myAlias.Substring(0, slashIndex) : "";
+ } while (myAlias.Length > 0);
+
+
+ app.Context.Items.Add("UrlRewrite:OriginalUrl", app.Request.Url.AbsoluteUri);
+
+ //Friendly URLs are exposed externally using the following format
+ //http://www.domain.com/tabid/###/mid/###/ctl/xxx/default.aspx
+ //and processed internally using the following format
+ //http://www.domain.com/default.aspx?tabid=###&mid=###&ctl=xxx
+ //The system for accomplishing this is based on an extensible Regex rules definition stored in /SiteUrls.config
+ string sendTo = "";
+
+ //save and remove the querystring as it gets added back on later
+ //path parameter specifications will take precedence over querystring parameters
+ string strQueryString = "";
+ if ((!String.IsNullOrEmpty(app.Request.Url.Query)))
+ {
+ strQueryString = request.QueryString.ToString();
+ requestedPath = requestedPath.Replace(app.Request.Url.Query, "");
+ }
+
+ //get url rewriting rules
+ RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;
+
+ //iterate through list of rules
+ int matchIndex = -1;
+ for (int ruleIndex = 0; ruleIndex <= rules.Count - 1; ruleIndex++)
+ {
+ //check for the existence of the LookFor value
+ string pattern = "^" +
+ RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[ruleIndex].LookFor) +
+ "$";
+ Match objMatch = Regex.Match(requestedPath, pattern, RegexOptions.IgnoreCase);
+
+ //if there is a match
+ if ((objMatch.Success))
+ {
+ //create a new URL using the SendTo regex value
+ sendTo = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath,
+ Regex.Replace(requestedPath, pattern, rules[ruleIndex].SendTo,
+ RegexOptions.IgnoreCase));
+
+ string parameters = objMatch.Groups[2].Value;
+ //process the parameters
+ if ((parameters.Trim().Length > 0))
+ {
+ //split the value into an array based on "/" ( ie. /tabid/##/ )
+ parameters = parameters.Replace("\\", "/");
+ string[] splitParameters = parameters.Split('/');
+ //icreate a well formed querystring based on the array of parameters
+ for (int parameterIndex = 0; parameterIndex < splitParameters.Length; parameterIndex++)
+ {
+ //ignore the page name
+ if (
+ splitParameters[parameterIndex].IndexOf(".aspx",
+ StringComparison.InvariantCultureIgnoreCase) ==
+ -1)
+ {
+ //get parameter name
+ string parameterName = splitParameters[parameterIndex].Trim();
+ if (parameterName.Length > 0)
+ {
+ //add parameter to SendTo if it does not exist already
+ if (
+ sendTo.IndexOf("?" + parameterName + "=",
+ StringComparison.InvariantCultureIgnoreCase) == -1 &&
+ sendTo.IndexOf("&" + parameterName + "=",
+ StringComparison.InvariantCultureIgnoreCase) == -1)
+ {
+ //get parameter delimiter
+ string parameterDelimiter = sendTo.IndexOf("?", StringComparison.Ordinal) != -1 ? "&" : "?";
+ sendTo = sendTo + parameterDelimiter + parameterName;
+ //get parameter value
+ string parameterValue = "";
+ if (parameterIndex < splitParameters.Length - 1)
+ {
+ parameterIndex += 1;
+ if (!String.IsNullOrEmpty(splitParameters[parameterIndex].Trim()))
+ {
+ parameterValue = splitParameters[parameterIndex].Trim();
+ }
+ }
+ //add the parameter value
+ if (parameterValue.Length > 0)
+ {
+ sendTo = sendTo + "=" + parameterValue;
+ }
+ }
+ }
+ }
+ }
+ }
+ matchIndex = ruleIndex;
+ break; //exit as soon as it processes the first match
+ }
+ }
+ if (!String.IsNullOrEmpty(strQueryString))
+ {
+ //add querystring parameters back to SendTo
+ string[] parameters = strQueryString.Split('&');
+ //iterate through the array of parameters
+ for (int parameterIndex = 0; parameterIndex <= parameters.Length - 1; parameterIndex++)
+ {
+ //get parameter name
+ string parameterName = parameters[parameterIndex];
+ if (parameterName.IndexOf("=", StringComparison.Ordinal) != -1)
+ {
+ parameterName = parameterName.Substring(0, parameterName.IndexOf("=", StringComparison.Ordinal));
+ }
+ //check if parameter already exists
+ if (sendTo.IndexOf("?" + parameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1 &&
+ sendTo.IndexOf("&" + parameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1)
+ {
+ //add parameter to SendTo value
+ sendTo = sendTo.IndexOf("?", StringComparison.Ordinal) != -1
+ ? sendTo + "&" + parameters[parameterIndex]
+ : sendTo + "?" + parameters[parameterIndex];
+ }
+ }
+ }
+
+ //if a match was found to the urlrewrite rules
+ if (matchIndex != -1)
+ {
+ if (rules[matchIndex].SendTo.StartsWith("~"))
+ {
+ //rewrite the URL for internal processing
+ RewriterUtils.RewriteUrl(app.Context, sendTo);
+ }
+ else
+ {
+ //it is not possible to rewrite the domain portion of the URL so redirect to the new URL
+ response.Redirect(sendTo, true);
+ }
+ }
+ else
+ {
+ //Try to rewrite by TabPath
+ string url;
+ if (Globals.UsePortNumber() &&
+ ((app.Request.Url.Port != 80 && !app.Request.IsSecureConnection) ||
+ (app.Request.Url.Port != 443 && app.Request.IsSecureConnection)))
+ {
+ url = app.Request.Url.Host + ":" + app.Request.Url.Port + app.Request.Url.LocalPath;
+ }
+ else
+ {
+ url = app.Request.Url.Host + app.Request.Url.LocalPath;
+ }
+
+ if (!String.IsNullOrEmpty(myAlias))
+ {
+ if (objPortalAlias != null)
+ {
+ int portalID = objPortalAlias.PortalID;
+ //Identify Tab Name
+ string tabPath = url;
+ if (tabPath.StartsWith(myAlias))
+ {
+ tabPath = url.Remove(0, myAlias.Length);
+ }
+ //Default Page has been Requested
+ if ((tabPath == "/" + Globals.glbDefaultPage.ToLower()))
+ {
+ return;
+ }
+
+ //Start of patch
+ string cultureCode = string.Empty;
+
+ Dictionary dicLocales = LocaleController.Instance.GetLocales(portalID);
+ if (dicLocales.Count > 1)
+ {
+ String[] splitUrl = app.Request.Url.ToString().Split('/');
+
+ foreach (string culturePart in splitUrl)
+ {
+ if (culturePart.IndexOf("-", StringComparison.Ordinal) > -1)
+ {
+ foreach (KeyValuePair key in dicLocales)
+ {
+ if (key.Key.ToLower().Equals(culturePart.ToLower()))
+ {
+ cultureCode = key.Value.Code;
+ tabPath = tabPath.Replace("/" + culturePart, "");
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Check to see if the tab exists (if localization is enable, check for the specified culture)
+ int tabID = TabController.GetTabByTabPath(portalID,
+ tabPath.Replace("/", "//").Replace(".aspx", ""),
+ cultureCode);
+
+ // Check to see if neutral culture tab exists
+ if ((tabID == Null.NullInteger && cultureCode.Length > 0))
+ {
+ tabID = TabController.GetTabByTabPath(portalID,
+ tabPath.Replace("/", "//").Replace(".aspx", ""), "");
+ }
+ //End of patch
+
+ if ((tabID != Null.NullInteger))
+ {
+ string sendToUrl = "~/" + Globals.glbDefaultPage + "?TabID=" + tabID;
+ if (!cultureCode.Equals(string.Empty))
+ {
+ sendToUrl = sendToUrl + "&language=" + cultureCode;
+ }
+ if ((!String.IsNullOrEmpty(app.Request.Url.Query)))
+ {
+ sendToUrl = sendToUrl + "&" + app.Request.Url.Query.TrimStart('?');
+ }
+ RewriterUtils.RewriteUrl(app.Context, sendToUrl);
+ return;
+ }
+ tabPath = tabPath.ToLower();
+ if ((tabPath.IndexOf('?') != -1))
+ {
+ tabPath = tabPath.Substring(0, tabPath.IndexOf('?'));
+ }
+
+ //Get the Portal
+ PortalInfo portal = new PortalController().GetPortal(portalID);
+ string requestQuery = app.Request.Url.Query;
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ requestQuery = Regex.Replace(requestQuery, "&?tabid=\\d+", string.Empty,
+ RegexOptions.IgnoreCase);
+ requestQuery = Regex.Replace(requestQuery, "&?portalid=\\d+", string.Empty,
+ RegexOptions.IgnoreCase);
+ requestQuery = requestQuery.TrimStart('?', '&');
+ }
+ if (tabPath == "/login.aspx")
+ {
+ if (portal.LoginTabId > Null.NullInteger && Globals.ValidateLoginTabID(portal.LoginTabId))
+ {
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.LoginTabId + "&" + requestQuery);
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.LoginTabId);
+ }
+ }
+ else
+ {
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.HomeTabId + "&portalid=" + portalID + "&ctl=login&" +
+ requestQuery);
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.HomeTabId + "&portalid=" + portalID + "&ctl=login");
+ }
+ }
+ return;
+ }
+ if (tabPath == "/register.aspx")
+ {
+ if (portal.RegisterTabId > Null.NullInteger)
+ {
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.RegisterTabId + "&portalid=" + portalID + "&" +
+ requestQuery);
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.RegisterTabId + "&portalid=" + portalID);
+ }
+ }
+ else
+ {
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.HomeTabId + "&portalid=" + portalID +
+ "&ctl=Register&" + requestQuery);
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" +
+ portal.HomeTabId + "&portalid=" + portalID +
+ "&ctl=Register");
+ }
+ }
+ return;
+ }
+ if (tabPath == "/terms.aspx")
+ {
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId +
+ "&portalid=" + portalID + "&ctl=Terms&" + requestQuery);
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId +
+ "&portalid=" + portalID + "&ctl=Terms");
+ }
+ return;
+ }
+ if (tabPath == "/privacy.aspx")
+ {
+ if (!string.IsNullOrEmpty(requestQuery))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId +
+ "&portalid=" + portalID + "&ctl=Privacy&" + requestQuery);
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId +
+ "&portalid=" + portalID + "&ctl=Privacy");
+ }
+ return;
+ }
+ tabPath = tabPath.Replace("/", "//");
+ tabPath = tabPath.Replace(".aspx", "");
+ var objTabController = new TabController();
+ TabCollection objTabs = objTabController.GetTabsByPortal(tabPath.StartsWith("//host") ? Null.NullInteger : portalID);
+ foreach (KeyValuePair kvp in objTabs)
+ {
+ if ((kvp.Value.IsDeleted == false && kvp.Value.TabPath.ToLower() == tabPath))
+ {
+ if ((!String.IsNullOrEmpty(app.Request.Url.Query)))
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" + kvp.Value.TabID +
+ "&" + app.Request.Url.Query.TrimStart('?'));
+ }
+ else
+ {
+ RewriterUtils.RewriteUrl(app.Context,
+ "~/" + Globals.glbDefaultPage + "?TabID=" + kvp.Value.TabID);
+ }
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ private bool IsSSLOffloadEnabled(HttpRequest request)
+ {
+ string ssloffloadheader = HostController.Instance.GetString("SSLOffloadHeader", "");
+ //if the ssloffloadheader variable has been set check to see if a request header with that type exists
+ if (!string.IsNullOrEmpty(ssloffloadheader))
+ {
+ string ssloffload = request.Headers[ssloffloadheader];
+ if (!string.IsNullOrEmpty(ssloffload))
+ {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/UrlRewrite/Config/RewriterConfiguration.cs b/DNN Platform/HttpModules/UrlRewrite/Config/RewriterConfiguration.cs
new file mode 100644
index 00000000000..8242a83bf64
--- /dev/null
+++ b/DNN Platform/HttpModules/UrlRewrite/Config/RewriterConfiguration.cs
@@ -0,0 +1,141 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.IO;
+using System.Xml.Serialization;
+using System.Xml.XPath;
+
+using DotNetNuke.Common;
+using DotNetNuke.Common.Utilities;
+using DotNetNuke.Instrumentation;
+using DotNetNuke.Services.Cache;
+using DotNetNuke.Services.Log.EventLog;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Config
+{
+ [Serializable, XmlRoot("RewriterConfig")]
+ public class RewriterConfiguration
+ {
+ private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof (RewriterConfiguration));
+ private RewriterRuleCollection _rules;
+
+ public RewriterRuleCollection Rules
+ {
+ get
+ {
+ return _rules;
+ }
+ set
+ {
+ _rules = value;
+ }
+ }
+
+ public static RewriterConfiguration GetConfig()
+ {
+ var config = new RewriterConfiguration {Rules = new RewriterRuleCollection()};
+ FileStream fileReader = null;
+ string filePath = "";
+ try
+ {
+ config = (RewriterConfiguration) DataCache.GetCache("RewriterConfig");
+ if ((config == null))
+ {
+ filePath = Common.Utilities.Config.GetPathToFile(Common.Utilities.Config.ConfigFileType.SiteUrls);
+
+ //Create a FileStream for the Config file
+ fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ var doc = new XPathDocument(fileReader);
+ config = new RewriterConfiguration {Rules = new RewriterRuleCollection()};
+ foreach (XPathNavigator nav in doc.CreateNavigator().Select("RewriterConfig/Rules/RewriterRule"))
+ {
+ var rule = new RewriterRule {LookFor = nav.SelectSingleNode("LookFor").Value, SendTo = nav.SelectSingleNode("SendTo").Value};
+ config.Rules.Add(rule);
+ }
+ if (File.Exists(filePath))
+ {
+ //Set back into Cache
+ DataCache.SetCache("RewriterConfig", config, new DNNCacheDependency(filePath));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ //log it
+ var objEventLog = new EventLogController();
+ var objEventLogInfo = new LogInfo();
+ objEventLogInfo.AddProperty("UrlRewriter.RewriterConfiguration", "GetConfig Failed");
+ objEventLogInfo.AddProperty("FilePath", filePath);
+ objEventLogInfo.AddProperty("ExceptionMessage", ex.Message);
+ objEventLogInfo.LogTypeKey = EventLogController.EventLogType.HOST_ALERT.ToString();
+ objEventLog.AddLog(objEventLogInfo);
+ Logger.Error(objEventLogInfo);
+
+ }
+ finally
+ {
+ if (fileReader != null)
+ {
+ //Close the Reader
+ fileReader.Close();
+ }
+ }
+ return config;
+ }
+
+ public static void SaveConfig(RewriterRuleCollection rules)
+ {
+ if (rules != null)
+ {
+ var config = new RewriterConfiguration {Rules = rules};
+
+ //Create a new Xml Serializer
+ var ser = new XmlSerializer(typeof (RewriterConfiguration));
+
+ //Create a FileStream for the Config file
+ string filePath = Globals.ApplicationMapPath + "\\SiteUrls.config";
+ if (File.Exists(filePath))
+ {
+ //make sure file is not read-only
+ File.SetAttributes(filePath, FileAttributes.Normal);
+ }
+ var fileWriter = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write);
+
+ //Open up the file to serialize
+ var writer = new StreamWriter(fileWriter);
+
+ //Serialize the RewriterConfiguration
+ ser.Serialize(writer, config);
+
+ //Close the Writers
+ writer.Close();
+ fileWriter.Close();
+
+ //Set Cache
+ DataCache.SetCache("RewriterConfig", config, new DNNCacheDependency(filePath));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/UrlRewrite/Config/RewriterRule.cs b/DNN Platform/HttpModules/UrlRewrite/Config/RewriterRule.cs
new file mode 100644
index 00000000000..89aefe26f6a
--- /dev/null
+++ b/DNN Platform/HttpModules/UrlRewrite/Config/RewriterRule.cs
@@ -0,0 +1,59 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Config
+{
+ [Serializable]
+ public class RewriterRule
+ {
+ private string _lookFor;
+ private string _sendTo;
+
+ public string LookFor
+ {
+ get
+ {
+ return _lookFor;
+ }
+ set
+ {
+ _lookFor = value;
+ }
+ }
+
+ public string SendTo
+ {
+ get
+ {
+ return _sendTo;
+ }
+ set
+ {
+ _sendTo = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/UrlRewrite/Config/RewriterRuleCollection.cs b/DNN Platform/HttpModules/UrlRewrite/Config/RewriterRuleCollection.cs
new file mode 100644
index 00000000000..f33429916c7
--- /dev/null
+++ b/DNN Platform/HttpModules/UrlRewrite/Config/RewriterRuleCollection.cs
@@ -0,0 +1,50 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Collections;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.Config
+{
+ [Serializable]
+ public class RewriterRuleCollection : CollectionBase
+ {
+ public virtual RewriterRule this[int index]
+ {
+ get
+ {
+ return (RewriterRule) List[index];
+ }
+ set
+ {
+ List[index] = value;
+ }
+ }
+
+ public void Add(RewriterRule r)
+ {
+ InnerList.Add(r);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/UrlRewrite/FriendlyUrlProvider.cs b/DNN Platform/HttpModules/UrlRewrite/FriendlyUrlProvider.cs
new file mode 100644
index 00000000000..8bf30b0f99e
--- /dev/null
+++ b/DNN Platform/HttpModules/UrlRewrite/FriendlyUrlProvider.cs
@@ -0,0 +1,120 @@
+#region Copyright
+
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region Usings
+
+using System;
+
+using DotNetNuke.Entities.Portals;
+using DotNetNuke.Entities.Tabs;
+using DotNetNuke.Entities.Urls;
+using DotNetNuke.Framework.Providers;
+using DotNetNuke.HttpModules.UrlRewrite;
+
+#endregion
+
+// ReSharper disable CheckNamespace
+namespace DotNetNuke.Services.Url.FriendlyUrl
+// ReSharper restore CheckNamespace
+{
+ public class DNNFriendlyUrlProvider : FriendlyUrlProvider
+ {
+ internal const string ProviderType = "friendlyUrl";
+
+ private readonly ProviderConfiguration _providerConfiguration = ProviderConfiguration.GetProviderConfiguration(ProviderType);
+
+ private readonly FriendlyUrlProviderBase _providerInstance;
+ private readonly UrlFormatType _urlFormat = UrlFormatType.SearchFriendly;
+ private readonly string[] _validExtensions;
+
+ public DNNFriendlyUrlProvider()
+ {
+ //Read the configuration specific information for this provider
+ var objProvider = (Provider) _providerConfiguration.Providers[_providerConfiguration.DefaultProvider];
+
+ if (!String.IsNullOrEmpty(objProvider.Attributes["urlFormat"]))
+ {
+ switch (objProvider.Attributes["urlFormat"].ToLower())
+ {
+ case "searchfriendly":
+ _urlFormat = UrlFormatType.SearchFriendly;
+ break;
+ case "humanfriendly":
+ _urlFormat = UrlFormatType.HumanFriendly;
+ break;
+ case "advanced":
+ case "customonly":
+ _urlFormat = UrlFormatType.Advanced;
+ break;
+ default:
+ _urlFormat = UrlFormatType.SearchFriendly;
+ break;
+ }
+ }
+ //instance the correct provider implementation
+ switch (_urlFormat)
+ {
+ case UrlFormatType.Advanced:
+ _providerInstance = new AdvancedFriendlyUrlProvider(objProvider.Attributes);
+ break;
+ case UrlFormatType.HumanFriendly:
+ case UrlFormatType.SearchFriendly:
+ _providerInstance = new BasicFriendlyUrlProvider(objProvider.Attributes);
+ break;
+ }
+
+ string extensions = !String.IsNullOrEmpty(objProvider.Attributes["validExtensions"]) ? objProvider.Attributes["validExtensions"] : ".aspx";
+ _validExtensions = extensions.Split(',');
+ }
+
+ public string[] ValidExtensions
+ {
+ get { return _validExtensions; }
+ }
+
+ public UrlFormatType UrlFormat
+ {
+ get { return _urlFormat; }
+ }
+
+ public override string FriendlyUrl(TabInfo tab, string path)
+ {
+ return _providerInstance.FriendlyUrl(tab, path);
+ }
+
+ public override string FriendlyUrl(TabInfo tab, string path, string pageName)
+ {
+ return _providerInstance.FriendlyUrl(tab, path, pageName);
+ }
+
+ public override string FriendlyUrl(TabInfo tab, string path, string pageName, PortalSettings settings)
+ {
+ return _providerInstance.FriendlyUrl(tab, path, pageName, settings);
+ }
+
+ public override string FriendlyUrl(TabInfo tab, string path, string pageName, string portalAlias)
+ {
+ return _providerInstance.FriendlyUrl(tab, path, pageName, portalAlias);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/UrlRewrite/UrlRewriteModule.cs b/DNN Platform/HttpModules/UrlRewrite/UrlRewriteModule.cs
new file mode 100644
index 00000000000..6fa5f9996d0
--- /dev/null
+++ b/DNN Platform/HttpModules/UrlRewrite/UrlRewriteModule.cs
@@ -0,0 +1,78 @@
+#region Copyright
+
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region Usings
+
+using System.Web;
+
+using DotNetNuke.Entities.Urls;
+using DotNetNuke.Framework.Providers;
+using DotNetNuke.HttpModules.UrlRewrite;
+
+#endregion
+
+namespace DotNetNuke.HttpModules
+{
+ public class UrlRewriteModule : IHttpModule
+ {
+ private string _providerToUse;
+ private UrlRewriterBase _urlRewriter;
+
+ public string ModuleName
+ {
+ get { return "UrlRewriteModule"; }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ _providerToUse = DotNetNuke.Common.Utilities.Config.GetFriendlyUrlProvider();
+
+ //bind events depending on currently configured friendly url provider
+ //note that the current configured friendly url provider determines what type
+ //of url rewriting is required.
+
+ switch (_providerToUse)
+ {
+ case "advanced":
+ var advancedRewriter = new AdvancedUrlRewriter();
+ _urlRewriter = advancedRewriter;
+ //bind the rewrite event to the begin request event
+ application.BeginRequest += _urlRewriter.RewriteUrl;
+ break;
+ default:
+ var basicRewriter = new BasicUrlRewriter();
+ _urlRewriter = basicRewriter;
+ application.BeginRequest += _urlRewriter.RewriteUrl;
+ break;
+ }
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/HttpModules/Users Online/UsersOnlineModule.cs b/DNN Platform/HttpModules/Users Online/UsersOnlineModule.cs
new file mode 100644
index 00000000000..76431f00e5f
--- /dev/null
+++ b/DNN Platform/HttpModules/Users Online/UsersOnlineModule.cs
@@ -0,0 +1,81 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Web;
+
+using DotNetNuke.Entities.Users;
+
+#endregion
+
+namespace DotNetNuke.HttpModules.UsersOnline
+{
+ public class UsersOnlineModule : IHttpModule
+ {
+ public string ModuleName
+ {
+ get
+ {
+ return "UsersOnlineModule";
+ }
+ }
+
+ #region IHttpModule Members
+
+ public void Init(HttpApplication application)
+ {
+ application.AuthorizeRequest += OnAuthorizeRequest;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ public void OnAuthorizeRequest(object s, EventArgs e)
+ {
+ //First check if we are upgrading/installing
+ var app = (HttpApplication) s;
+ HttpRequest request = app.Request;
+
+ //check if we are upgrading/installing or if this is a captcha request
+ if (request.Url.LocalPath.ToLower().EndsWith("/install/install.aspx")
+ || request.Url.LocalPath.ToLower().Contains("/install/installwizard.aspx")
+ || request.Url.LocalPath.ToLower().Contains("/install/upgradewizard.aspx")
+ || request.Url.LocalPath.ToLower().EndsWith("captcha.aspx")
+ || request.Url.LocalPath.ToLower().EndsWith("scriptresource.axd")
+ || request.Url.LocalPath.ToLower().EndsWith("webresource.axd"))
+ {
+ return;
+ }
+ //Create a Users Online Controller
+ var objUserOnlineController = new UserOnlineController();
+
+ //Is Users Online Enabled?
+ if ((objUserOnlineController.IsEnabled()))
+ {
+ objUserOnlineController.TrackUsers();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DNN Platform/Library/Application/Application.cs b/DNN Platform/Library/Application/Application.cs
new file mode 100644
index 00000000000..d7a03b49b0a
--- /dev/null
+++ b/DNN Platform/Library/Application/Application.cs
@@ -0,0 +1,248 @@
+#region Copyright
+//
+// DotNetNuke - http://www.dotnetnuke.com
+// Copyright (c) 2002-2013
+// by DotNetNuke Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+#region Usings
+
+using System;
+using System.Reflection;
+
+using DotNetNuke.Common.Utilities;
+
+#endregion
+
+namespace DotNetNuke.Application
+{
+ /// -----------------------------------------------------------------------------
+ /// Namespace: DotNetNuke.Application
+ /// Project: DotNetNuke
+ /// Module: Application
+ /// -----------------------------------------------------------------------------
+ ///