2009-06-19 07:39:16 +00:00
using System ;
using System.Collections ;
2010-03-03 17:13:42 +00:00
using System.Collections.Generic ;
2009-06-19 07:39:16 +00:00
using System.Diagnostics ;
using System.IO ;
using System.Net ;
2011-05-09 09:58:12 -02:00
using System.Net.Security ;
2009-06-19 07:39:16 +00:00
using System.Reflection ;
2011-05-09 09:58:12 -02:00
using System.Security.Cryptography.X509Certificates ;
2010-12-06 11:47:46 +00:00
using System.Security.Permissions ;
2009-06-19 07:39:16 +00:00
using System.Text ;
using System.Text.RegularExpressions ;
using System.Web ;
using System.Web.Caching ;
using System.Web.UI ;
using System.Web.UI.WebControls ;
using System.Xml ;
using System.Xml.Xsl ;
using umbraco.BusinessLogic ;
2011-11-25 14:03:09 -01:00
using umbraco.BusinessLogic.Utils ;
2010-12-06 13:49:34 +00:00
using umbraco.cms.businesslogic.macro ;
2009-06-19 07:39:16 +00:00
using umbraco.cms.businesslogic.member ;
using umbraco.DataLayer ;
using umbraco.interfaces ;
2010-12-06 11:47:46 +00:00
using umbraco.IO ;
2010-12-23 20:42:50 -01:00
using umbraco.NodeFactory ;
2011-11-10 08:07:16 -01:00
using umbraco.presentation ;
2010-12-06 11:47:46 +00:00
using umbraco.presentation.templateControls ;
2009-06-19 07:39:16 +00:00
using umbraco.presentation.xslt.Exslt ;
2010-12-06 11:47:46 +00:00
using Content = umbraco . cms . businesslogic . Content ;
using Macro = umbraco . cms . businesslogic . macro . Macro ;
2009-06-19 07:39:16 +00:00
namespace umbraco
{
/// <summary>
/// Summary description for macro.
/// </summary>
2011-11-25 14:03:09 -01:00
public class macro
2009-06-19 07:39:16 +00:00
{
#region private properties
2011-09-12 11:19:37 -02:00
2010-12-06 11:47:46 +00:00
/// <summary>Cache for <see cref="GetPredefinedXsltExtensions"/>.</summary>
private static Dictionary < string , object > m_PredefinedExtensions ;
private readonly string loadUserControlKey = "loadUserControl" ;
2009-06-19 07:39:16 +00:00
private readonly StringBuilder mContent = new StringBuilder ( ) ;
private readonly Cache macroCache = HttpRuntime . Cache ;
2011-11-25 14:03:09 -01:00
private static readonly object macroRuntimeCacheSyncLock = new object ( ) ;
private static readonly string macroRuntimeCacheKey = "UmbracoRuntimeMacroCache" ;
2009-06-19 07:39:16 +00:00
private readonly string macrosAddedKey = "macrosAdded" ;
2011-11-25 14:03:09 -01:00
public IList < Exception > Exceptions = new List < Exception > ( ) ;
2009-06-19 07:39:16 +00:00
// Macro-elements
2011-11-25 14:03:09 -01:00
2009-06-19 07:39:16 +00:00
protected static ISqlHelper SqlHelper
{
2011-11-25 14:03:09 -01:00
get { return Application . SqlHelper ; }
2009-06-19 07:39:16 +00:00
}
#endregion
#region public properties
2011-11-25 14:03:09 -01:00
public bool CacheByPersonalization
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
get { return Model . CacheByMember ; }
2009-06-19 07:39:16 +00:00
}
2011-11-25 14:03:09 -01:00
public bool CacheByPage
{
get { return Model . CacheByPage ; }
}
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
public bool DontRenderInEditor
{
get { return ! Model . RenderInEditor ; }
}
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
public int RefreshRate
{
get { return Model . CacheDuration ; }
}
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
public String Alias
{
get { return Model . Alias ; }
}
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
public String Name
{
get { return Model . Name ; }
}
2009-06-19 07:39:16 +00:00
public String XsltFile
{
2011-11-25 14:03:09 -01:00
get { return Model . Xslt ; }
2009-06-19 07:39:16 +00:00
}
2010-01-28 12:51:46 +00:00
public String ScriptFile
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
get { return Model . ScriptName ; }
2009-06-19 07:39:16 +00:00
}
public String ScriptType
{
2011-11-25 14:03:09 -01:00
get { return Model . TypeName ; }
2009-06-19 07:39:16 +00:00
}
public String ScriptAssembly
{
2011-11-25 14:03:09 -01:00
get { return Model . TypeName ; }
2009-06-19 07:39:16 +00:00
}
public int MacroType
{
2011-12-20 07:44:43 -13:00
get { return ( int ) Model . MacroType ; }
2009-06-19 07:39:16 +00:00
}
public String MacroContent
{
set { mContent . Append ( value ) ; }
get { return mContent . ToString ( ) ; }
}
#endregion
2011-11-25 14:03:09 -01:00
#region REFACTOR
2009-06-19 07:39:16 +00:00
/// <summary>
/// Creates a macro object
/// </summary>
/// <param name="id">Specify the macro-id which should be loaded (from table macro)</param>
public macro ( int id )
{
2011-11-25 14:03:09 -01:00
Macro m = Macro . GetById ( id ) ;
Model = new MacroModel ( m ) ;
2009-06-19 07:39:16 +00:00
}
2011-11-25 14:03:09 -01:00
public macro ( string alias )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
Macro m = Macro . GetByAlias ( alias ) ;
Model = new MacroModel ( m ) ;
2010-12-06 11:47:46 +00:00
}
2010-03-03 07:20:55 +00:00
2011-11-25 14:03:09 -01:00
public MacroModel Model { get ; set ; }
public static macro GetMacro ( string alias )
2010-12-06 11:47:46 +00:00
{
2011-11-25 14:03:09 -01:00
return cms . businesslogic . cache . Cache . GetCacheItem ( GetCacheKey ( alias ) , macroRuntimeCacheSyncLock ,
TimeSpan . FromMinutes ( 60 ) ,
delegate
{
try
{
return new macro ( alias ) ;
}
catch
{
return null ;
}
} ) ;
2010-12-06 11:47:46 +00:00
}
2011-11-25 14:03:09 -01:00
public static macro GetMacro ( int id )
2010-12-06 11:47:46 +00:00
{
2011-11-25 14:03:09 -01:00
return cms . businesslogic . cache . Cache . GetCacheItem ( GetCacheKey ( string . Format ( "by_id_{0}" , id ) ) , macroRuntimeCacheSyncLock ,
TimeSpan . FromMinutes ( 60 ) ,
delegate
{
try
{
return new macro ( id ) ;
}
catch
{
return null ;
}
} ) ;
2009-06-19 07:39:16 +00:00
}
2011-11-25 14:03:09 -01:00
#endregion
private const string _xsltExtensionsCacheKey = "UmbracoXsltExtensions" ;
private static readonly string _xsltExtensionsConfig =
IOHelper . MapPath ( SystemDirectories . Config + "/xsltExtensions.config" ) ;
private static readonly object _xsltExtensionsSyncLock = new object ( ) ;
private static readonly Lazy < CacheDependency > _xsltExtensionsDependency =
new Lazy < CacheDependency > ( ( ) = > new CacheDependency ( _xsltExtensionsConfig ) ) ;
/// <summary>
/// Creates an empty macro object.
/// </summary>
public macro ( )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
Model = new MacroModel ( ) ;
2009-06-19 07:39:16 +00:00
}
2011-11-25 14:03:09 -01:00
public override string ToString ( )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
return Model . Name ;
2009-06-19 07:39:16 +00:00
}
2011-11-25 14:03:09 -01:00
private static string GetCacheKey ( string alias )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
return macroRuntimeCacheKey + alias ;
2009-06-19 07:39:16 +00:00
}
/// <summary>
/// Deletes macro definition from cache.
/// </summary>
/// <returns>True if succesfull, false if nothing has been removed</returns>
2011-11-25 14:03:09 -01:00
//TODO: Update implementation!
2009-06-19 07:39:16 +00:00
public bool removeFromCache ( )
{
2011-11-25 14:03:09 -01:00
if ( Model . Id > 0 )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
cms . businesslogic . cache . Cache . ClearCacheItem ( GetCacheKey ( Model . Alias ) ) ;
2011-09-12 11:19:37 -02:00
}
return false ;
2009-06-19 07:39:16 +00:00
}
2011-12-20 13:41:51 -01:00
string GetCacheIdentifier ( MacroModel model , Hashtable pageElements , int pageId )
2009-06-19 07:39:16 +00:00
{
2012-01-06 08:32:50 -01:00
StringBuilder id = new StringBuilder ( ) ;
2011-12-20 13:41:51 -01:00
2012-01-06 08:32:50 -01:00
var alias = string . IsNullOrEmpty ( model . ScriptCode ) ? model . Alias : Macro . GenerateCacheKeyFromCode ( model . ScriptCode ) ;
id . AppendFormat ( "{0}-" , alias ) ;
2010-10-20 10:25:28 +00:00
2009-06-19 07:39:16 +00:00
if ( CacheByPage )
2010-10-20 10:25:28 +00:00
{
2012-01-06 08:32:50 -01:00
id . AppendFormat ( "{0}-" , pageId ) ;
2010-10-20 10:25:28 +00:00
}
2009-06-19 07:39:16 +00:00
if ( CacheByPersonalization )
{
2012-01-06 08:32:50 -01:00
var currentMember = Member . GetCurrentMember ( ) ;
id . AppendFormat ( "m{0}-" , currentMember = = null ? 0 : currentMember . Id ) ;
2009-06-19 07:39:16 +00:00
}
2011-12-20 13:41:51 -01:00
2012-01-06 08:32:50 -01:00
foreach ( MacroPropertyModel prop in model . Properties )
2009-06-19 07:39:16 +00:00
{
2011-12-20 13:41:51 -01:00
var propValue = prop . Value ;
2012-01-06 08:32:50 -01:00
id . AppendFormat ( "{0}-" , propValue . Length < = 255 ? propValue : propValue . Substring ( 0 , 255 ) ) ;
2009-06-19 07:39:16 +00:00
}
2011-12-20 13:41:51 -01:00
2012-01-06 08:32:50 -01:00
return id . ToString ( ) ;
2009-06-19 07:39:16 +00:00
}
public Control renderMacro ( Hashtable attributes , Hashtable pageElements , int pageId )
2011-01-10 12:23:26 -01:00
{
2011-11-25 14:03:09 -01:00
// TODO: Parse attributes
UpdateMacroModel ( attributes ) ;
return renderMacro ( pageElements , pageId ) ;
2011-01-10 12:23:26 -01:00
}
2011-11-25 14:03:09 -01:00
public Control renderMacro ( Hashtable pageElements , int pageId )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "renderMacro" ,
string . Format (
"Rendering started (macro: {0}, type: {1}, cacheRate: {2})" ,
Name , MacroType , Model . CacheDuration ) ) ;
2009-06-19 07:39:16 +00:00
StateHelper . SetContextValue ( macrosAddedKey , StateHelper . GetContextValue < int > ( macrosAddedKey ) + 1 ) ;
2010-10-20 10:25:28 +00:00
String macroHtml = null ;
Control macroControl = null ;
2009-06-19 07:39:16 +00:00
2011-02-22 11:52:58 -01:00
// zb-00037 #29875 : parse attributes here (and before anything else)
2011-11-25 14:03:09 -01:00
foreach ( MacroPropertyModel prop in Model . Properties )
2011-02-22 11:52:58 -01:00
prop . Value = helper . parseAttribute ( pageElements , prop . Value ) ;
2011-01-17 14:19:54 -01:00
2011-12-20 13:41:51 -01:00
Model . CacheIdentifier = GetCacheIdentifier ( Model , pageElements , pageId ) ;
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
if ( Model . CacheDuration > 0 )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
if ( cacheMacroAsString ( Model ) )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
macroHtml = macroCache [ "macroHtml_" + Model . CacheIdentifier ] as String ;
2011-02-22 11:52:58 -01:00
if ( ! String . IsNullOrEmpty ( macroHtml ) )
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "renderMacro" ,
2012-01-06 08:32:50 -01:00
string . Format ( "Macro Content loaded from cache '{0}'." , Model . CacheIdentifier ) ) ;
2011-02-22 11:52:58 -01:00
}
}
else
{
2012-01-06 08:32:50 -01:00
var cacheContent = macroCache [ "macroControl_" + Model . CacheIdentifier ] as MacroCacheContent ;
2011-12-20 13:41:51 -01:00
2012-01-06 08:32:50 -01:00
if ( cacheContent ! = null )
2011-02-22 11:52:58 -01:00
{
macroControl = cacheContent . Content ;
macroControl . ID = cacheContent . ID ;
2011-12-20 13:41:51 -01:00
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "renderMacro" ,
2012-01-06 08:32:50 -01:00
string . Format ( "Macro Control loaded from cache '{0}'." , Model . CacheIdentifier ) ) ;
2011-02-22 11:52:58 -01:00
}
2009-06-19 07:39:16 +00:00
}
}
2011-02-22 11:52:58 -01:00
if ( String . IsNullOrEmpty ( macroHtml ) & & macroControl = = null )
2009-06-19 07:39:16 +00:00
{
2011-11-10 08:07:16 -01:00
bool renderFailed = false ;
2011-12-20 07:44:43 -13:00
int macroType = Model . MacroType ! = MacroTypes . Unknown ? ( int ) Model . MacroType : MacroType ;
2011-01-10 12:23:26 -01:00
switch ( macroType )
2009-06-19 07:39:16 +00:00
{
2011-12-20 07:44:43 -13:00
case ( int ) MacroTypes . UserControl :
2009-06-19 07:39:16 +00:00
try
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" ,
"Usercontrol added (" + Model . TypeName + ")" ) ;
macroControl = loadUserControl ( ScriptType , Model , pageElements ) ;
2009-06-19 07:39:16 +00:00
break ;
}
catch ( Exception e )
{
2011-11-10 08:07:16 -01:00
renderFailed = true ;
2011-09-12 11:19:37 -02:00
Exceptions . Add ( e ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro" ,
"Error loading userControl (" + Model . TypeName + ")" , e ) ;
macroControl = new LiteralControl ( "Error loading userControl '" + Model . TypeName + "'" ) ;
2009-06-19 07:39:16 +00:00
break ;
}
2011-12-20 07:44:43 -13:00
case ( int ) MacroTypes . CustomControl :
2009-06-19 07:39:16 +00:00
try
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" ,
"Custom control added (" + Model . TypeName + ")" ) ;
UmbracoContext . Current . Trace . Write ( "umbracoMacro" ,
"ScriptAssembly (" + Model . TypeAssembly + ")" ) ;
macroControl = loadControl ( Model . TypeAssembly , ScriptType , Model , pageElements ) ;
2009-06-19 07:39:16 +00:00
break ;
}
catch ( Exception e )
{
2011-11-10 08:07:16 -01:00
renderFailed = true ;
2011-09-12 11:19:37 -02:00
Exceptions . Add ( e ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro" ,
"Error loading customControl (Assembly: " +
Model . TypeAssembly +
", Type: '" + Model . TypeName + "'" , e ) ;
2010-10-20 10:25:28 +00:00
macroControl =
2011-11-25 14:03:09 -01:00
new LiteralControl ( "Error loading customControl (Assembly: " + Model . TypeAssembly +
2009-06-19 07:39:16 +00:00
", Type: '" +
2011-11-25 14:03:09 -01:00
Model . TypeName + "'" ) ;
2009-06-19 07:39:16 +00:00
break ;
}
2011-12-20 07:44:43 -13:00
case ( int ) MacroTypes . XSLT :
2011-11-25 14:03:09 -01:00
macroControl = loadMacroXSLT ( this , Model , pageElements ) ;
2009-06-19 07:39:16 +00:00
break ;
2011-12-20 07:44:43 -13:00
case ( int ) MacroTypes . Script :
2009-06-19 07:39:16 +00:00
try
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" ,
"MacroEngine script added (" + ScriptFile + ")" ) ;
2011-12-22 09:35:06 -01:00
ScriptingMacroResult result = loadMacroScript ( Model ) ;
macroControl = new LiteralControl ( result . Result ) ;
2011-11-10 08:07:16 -01:00
if ( result . ResultException ! = null )
{
// we'll throw the error if we run in release mode, show details if we're in release mode!
renderFailed = true ;
if ( HttpContext . Current ! = null & & ! HttpContext . Current . IsDebuggingEnabled )
throw result . ResultException ;
}
2009-06-19 07:39:16 +00:00
break ;
}
catch ( Exception e )
{
2011-11-10 08:07:16 -01:00
renderFailed = true ;
2011-09-12 11:19:37 -02:00
Exceptions . Add ( e ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro" ,
"Error loading MacroEngine script (file: " + ScriptFile +
", Type: '" + Model . TypeName + "'" , e ) ;
2010-01-28 12:51:46 +00:00
2011-11-25 14:03:09 -01:00
var result =
new LiteralControl ( "Error loading MacroEngine script (file: " + ScriptFile + ")" ) ;
2010-01-28 12:51:46 +00:00
/ *
string args = "<ul>" ;
foreach ( object key in attributes . Keys )
args + = "<li><strong>" + key . ToString ( ) + ": </strong> " + attributes [ key ] + "</li>" ;
foreach ( object key in pageElements . Keys )
args + = "<li><strong>" + key . ToString ( ) + ": </strong> " + pageElements [ key ] + "</li>" ;
args + = "</ul>" ;
result . Text + = args ;
* /
2010-10-20 10:25:28 +00:00
macroControl = result ;
2010-01-28 12:51:46 +00:00
2009-06-19 07:39:16 +00:00
break ;
}
default :
if ( GlobalSettings . DebugMode )
2010-10-20 10:25:28 +00:00
macroControl =
2009-06-19 07:39:16 +00:00
new LiteralControl ( "<Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType +
")>" ) ;
break ;
}
2011-11-10 08:07:16 -01:00
// Add result to cache if successful
2011-11-25 14:03:09 -01:00
if ( ! renderFailed & & Model . CacheDuration > 0 )
2009-06-19 07:39:16 +00:00
{
// do not add to cache if there's no member and it should cache by personalization
2011-11-25 14:03:09 -01:00
if ( ! Model . CacheByMember | | ( Model . CacheByMember & & Member . GetCurrentMember ( ) ! = null ) )
2010-10-20 10:25:28 +00:00
{
if ( macroControl ! = null )
{
2011-02-22 11:52:58 -01:00
// NH: Scripts and XSLT can be generated as strings, but not controls as page events wouldn't be hit (such as Page_Load, etc)
2011-11-25 14:03:09 -01:00
if ( cacheMacroAsString ( Model ) )
2011-02-22 11:52:58 -01:00
{
using ( var sw = new StringWriter ( ) )
{
var hw = new HtmlTextWriter ( sw ) ;
macroControl . RenderControl ( hw ) ;
2011-11-25 14:03:09 -01:00
macroCache . Insert ( "macroHtml_" + Model . CacheIdentifier ,
2011-02-22 11:52:58 -01:00
sw . ToString ( ) ,
null ,
2011-11-25 14:03:09 -01:00
DateTime . Now . AddSeconds ( Model . CacheDuration ) ,
2011-02-22 11:52:58 -01:00
TimeSpan . Zero ,
CacheItemPriority . Low ,
null ) ;
// zb-00003 #29470 : replace by text if not already text
// otherwise it is rendered twice
if ( ! ( macroControl is LiteralControl ) )
macroControl = new LiteralControl ( sw . ToString ( ) ) ;
2011-12-20 13:41:51 -01:00
2012-01-06 08:32:50 -01:00
UmbracoContext . Current . Trace . Write ( "renderMacro" ,
string . Format ( "Macro Content saved to cache '{0}'." , Model . CacheIdentifier ) ) ;
}
2011-02-22 11:52:58 -01:00
}
else
2010-10-20 10:25:28 +00:00
{
2011-11-25 14:03:09 -01:00
macroCache . Insert ( "macroControl_" + Model . CacheIdentifier ,
new MacroCacheContent ( macroControl , macroControl . ID ) , null ,
DateTime . Now . AddSeconds ( Model . CacheDuration ) , TimeSpan . Zero ,
CacheItemPriority . Low ,
null ) ;
2011-12-20 13:41:51 -01:00
2012-01-06 08:32:50 -01:00
UmbracoContext . Current . Trace . Write ( "renderMacro" ,
string . Format ( "Macro Control saved to cache '{0}'." , Model . CacheIdentifier ) ) ;
}
2010-10-20 10:25:28 +00:00
}
}
2009-06-19 07:39:16 +00:00
}
}
2011-02-22 11:52:58 -01:00
else if ( macroControl = = null )
2010-10-20 10:25:28 +00:00
{
macroControl = new LiteralControl ( macroHtml ) ;
}
return macroControl ;
2009-06-19 07:39:16 +00:00
}
2011-02-22 11:52:58 -01:00
private bool cacheMacroAsString ( MacroModel model )
{
return model . MacroType = = MacroTypes . XSLT | | model . MacroType = = MacroTypes . Python ;
}
2009-06-19 07:39:16 +00:00
public static XslCompiledTransform getXslt ( string XsltFile )
{
if ( HttpRuntime . Cache [ "macroXslt_" + XsltFile ] ! = null )
{
2011-12-20 07:44:43 -13:00
return ( XslCompiledTransform ) HttpRuntime . Cache [ "macroXslt_" + XsltFile ] ;
2009-06-19 07:39:16 +00:00
}
else
{
2010-12-06 11:47:46 +00:00
var xslReader =
2010-03-03 07:20:55 +00:00
new XmlTextReader ( IOHelper . MapPath ( SystemDirectories . Xslt + "/" + XsltFile ) ) ;
2009-06-19 07:39:16 +00:00
2010-12-06 11:47:46 +00:00
XslCompiledTransform macroXSLT = CreateXsltTransform ( xslReader , GlobalSettings . DebugMode ) ;
2009-06-19 07:39:16 +00:00
HttpRuntime . Cache . Insert (
"macroXslt_" + XsltFile ,
macroXSLT ,
2010-03-03 07:20:55 +00:00
new CacheDependency ( IOHelper . MapPath ( SystemDirectories . Xslt + "/" + XsltFile ) ) ) ;
2009-06-19 07:39:16 +00:00
return macroXSLT ;
}
}
2011-11-25 14:03:09 -01:00
public void UpdateMacroModel ( Hashtable attributes )
2010-12-06 13:49:34 +00:00
{
2011-11-25 14:03:09 -01:00
foreach ( MacroPropertyModel mp in Model . Properties )
{
if ( attributes . ContainsKey ( mp . Key . ToLower ( ) ) )
2012-01-06 08:39:26 -01:00
{
2011-11-25 14:03:09 -01:00
mp . Value = attributes [ mp . Key . ToLower ( ) ] . ToString ( ) ;
2012-01-06 08:39:26 -01:00
}
else
{
mp . Value = string . Empty ;
}
2011-11-25 14:03:09 -01:00
}
}
2010-12-06 13:49:34 +00:00
2011-11-25 14:03:09 -01:00
public void GenerateMacroModelPropertiesFromAttributes ( Hashtable attributes )
{
2010-12-06 13:49:34 +00:00
foreach ( string key in attributes . Keys )
{
2011-11-25 14:03:09 -01:00
Model . Properties . Add ( new MacroPropertyModel ( key , attributes [ key ] . ToString ( ) ) ) ;
2010-12-06 13:49:34 +00:00
}
}
2009-06-19 07:39:16 +00:00
public static XslCompiledTransform CreateXsltTransform ( XmlTextReader xslReader , bool debugMode )
{
2010-12-06 11:47:46 +00:00
var macroXSLT = new XslCompiledTransform ( debugMode ) ;
var xslResolver = new XmlUrlResolver ( ) ;
2009-06-19 07:39:16 +00:00
xslResolver . Credentials = CredentialCache . DefaultCredentials ;
xslReader . EntityHandling = EntityHandling . ExpandEntities ;
2010-03-03 07:20:55 +00:00
try
{
if ( GlobalSettings . ApplicationTrustLevel > AspNetHostingPermissionLevel . Medium )
{
2010-03-03 02:50:06 +00:00
macroXSLT . Load ( xslReader , XsltSettings . TrustedXslt , xslResolver ) ;
2010-03-03 07:20:55 +00:00
}
else
{
2010-03-03 02:50:06 +00:00
macroXSLT . Load ( xslReader , XsltSettings . Default , xslResolver ) ;
}
2010-03-03 07:20:55 +00:00
}
finally
{
2009-06-19 07:39:16 +00:00
xslReader . Close ( ) ;
}
return macroXSLT ;
}
public static void unloadXslt ( string XsltFile )
{
if ( HttpRuntime . Cache [ "macroXslt_" + XsltFile ] ! = null )
HttpRuntime . Cache . Remove ( "macroXslt_" + XsltFile ) ;
}
2010-01-28 12:51:46 +00:00
private Hashtable keysToLowerCase ( Hashtable input )
{
2010-12-06 11:47:46 +00:00
var retval = new Hashtable ( ) ;
2010-01-28 12:51:46 +00:00
foreach ( object key in input . Keys )
retval . Add ( key . ToString ( ) . ToLower ( ) , input [ key ] ) ;
return retval ;
}
2010-12-06 11:47:46 +00:00
2011-01-10 12:23:26 -01:00
public Control loadMacroXSLT ( macro macro , MacroModel model , Hashtable pageElements )
2009-06-19 07:39:16 +00:00
{
if ( XsltFile . Trim ( ) ! = string . Empty )
{
// Get main XML
XmlDocument umbracoXML = content . Instance . XmlContent ;
// Create XML document for Macro
2010-12-06 11:47:46 +00:00
var macroXML = new XmlDocument ( ) ;
2009-06-19 07:39:16 +00:00
macroXML . LoadXml ( "<macro/>" ) ;
2011-11-25 14:03:09 -01:00
foreach ( MacroPropertyModel prop in macro . Model . Properties )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
addMacroXmlNode ( umbracoXML , macroXML , prop . Key , prop . Type ,
prop . Value ) ;
2009-06-19 07:39:16 +00:00
}
if ( HttpContext . Current . Request . QueryString [ "umbDebug" ] ! = null & & GlobalSettings . DebugMode )
{
return
new LiteralControl ( "<div style=\"border: 2px solid green; padding: 5px;\"><b>Debug from " +
macro . Name +
2011-11-25 14:03:09 -01:00
"</b><br/><p>" + UmbracoContext . Current . Server . HtmlEncode ( macroXML . OuterXml ) +
"</p></div>" ) ;
2009-06-19 07:39:16 +00:00
}
else
{
try
{
XslCompiledTransform xsltFile = getXslt ( XsltFile ) ;
try
{
Control result = CreateControlsFromText ( GetXsltTransformResult ( macroXML , xsltFile ) ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" , "After performing transformation" ) ;
2009-06-19 07:39:16 +00:00
return result ;
}
catch ( Exception e )
{
2011-09-12 11:19:37 -02:00
Exceptions . Add ( e ) ;
2009-06-19 07:39:16 +00:00
// inner exception code by Daniel Lindstr<74> m from SBBS.se
2010-05-11 05:27:28 +00:00
Exception ie = e ;
2009-06-19 07:39:16 +00:00
while ( ie ! = null )
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro InnerException" , ie . Message , ie ) ;
2009-06-19 07:39:16 +00:00
ie = ie . InnerException ;
}
return new LiteralControl ( "Error parsing XSLT file: \\xslt\\" + XsltFile ) ;
}
}
catch ( Exception e )
{
2011-09-12 11:19:37 -02:00
Exceptions . Add ( e ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro" , "Error loading XSLT " + Model . Xslt , e ) ;
2009-06-19 07:39:16 +00:00
return new LiteralControl ( "Error reading XSLT file: \\xslt\\" + XsltFile ) ;
}
}
}
else
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "macro" , "Xslt is empty" ) ;
2009-06-19 07:39:16 +00:00
return new LiteralControl ( string . Empty ) ;
}
}
/// <summary>
/// Parses the text for umbraco Item controls that need to be rendered.
/// </summary>
/// <param name="text">The text to parse.</param>
/// <returns>A control containing the parsed text.</returns>
protected Control CreateControlsFromText ( string text )
{
// the beginning and end tags
const string tagStart = "[[[[umbraco:Item" ;
const string tagEnd = "]]]]" ;
// container that will hold parsed controls
2010-12-06 11:47:46 +00:00
var container = new PlaceHolder ( ) ;
2009-06-19 07:39:16 +00:00
// loop through all text
int textPos = 0 ;
while ( textPos < text . Length )
{
// try to find an item tag, carefully staying inside the string bounds (- 1)
int tagStartPos = text . IndexOf ( tagStart , textPos ) ;
int tagEndPos = tagStartPos < 0 ? - 1 : text . IndexOf ( tagEnd , tagStartPos + tagStart . Length - 1 ) ;
// item tag found?
if ( tagStartPos > = 0 & & tagEndPos > = 0 )
{
// add the preceding text as a literal control
if ( tagStartPos > textPos )
container . Controls . Add ( new LiteralControl ( text . Substring ( textPos , tagStartPos - textPos ) ) ) ;
// extract the tag and parse it
string tag = text . Substring ( tagStartPos , ( tagEndPos + tagEnd . Length ) - tagStartPos ) ;
Hashtable attributes = helper . ReturnAttributes ( tag ) ;
// create item with the parameters specified in the tag
2010-12-06 11:47:46 +00:00
var item = new Item ( ) ;
2009-06-19 07:39:16 +00:00
item . NodeId = helper . FindAttribute ( attributes , "nodeid" ) ;
item . Field = helper . FindAttribute ( attributes , "field" ) ;
item . Xslt = helper . FindAttribute ( attributes , "xslt" ) ;
item . XsltDisableEscaping = helper . FindAttribute ( attributes , "xsltdisableescaping" ) = = "true" ;
container . Controls . Add ( item ) ;
// advance past the end of the tag
textPos = tagEndPos + tagEnd . Length ;
}
else
{
// no more tags found, just add the remaning text
container . Controls . Add ( new LiteralControl ( text . Substring ( textPos ) ) ) ;
textPos = text . Length ;
}
}
return container ;
}
public static string GetXsltTransformResult ( XmlDocument macroXML , XslCompiledTransform xslt )
{
return GetXsltTransformResult ( macroXML , xslt , null ) ;
}
2010-12-06 11:47:46 +00:00
public static string GetXsltTransformResult ( XmlDocument macroXML , XslCompiledTransform xslt ,
Dictionary < string , object > parameters )
2009-06-19 07:39:16 +00:00
{
TextWriter tw = new StringWriter ( ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" , "Before adding extensions" ) ;
2009-06-19 07:39:16 +00:00
XsltArgumentList xslArgs ;
xslArgs = AddXsltExtensions ( ) ;
2010-12-06 11:47:46 +00:00
var lib = new library ( ) ;
2009-06-19 07:39:16 +00:00
xslArgs . AddExtensionObject ( "urn:umbraco.library" , lib ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" , "After adding extensions" ) ;
2009-06-19 07:39:16 +00:00
// Add parameters
if ( parameters = = null | | ! parameters . ContainsKey ( "currentPage" ) )
{
xslArgs . AddParam ( "currentPage" , string . Empty , library . GetXmlNodeCurrent ( ) ) ;
}
if ( parameters ! = null )
{
2010-12-06 11:47:46 +00:00
foreach ( var parameter in parameters )
2009-06-19 07:39:16 +00:00
xslArgs . AddParam ( parameter . Key , string . Empty , parameter . Value ) ;
}
// Do transformation
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" , "Before performing transformation" ) ;
2009-06-19 07:39:16 +00:00
xslt . Transform ( macroXML . CreateNavigator ( ) , xslArgs , tw ) ;
2010-07-20 08:39:13 +00:00
return IOHelper . ResolveUrlsFromTextString ( tw . ToString ( ) ) ;
2009-06-19 07:39:16 +00:00
}
public static XsltArgumentList AddXsltExtensions ( )
{
return AddMacroXsltExtensions ( ) ;
}
/// <summary>
/// Gets a collection of all XSLT extensions for macros, including predefined extensions.
/// </summary>
/// <returns>A dictionary of name/extension instance pairs.</returns>
2011-02-22 11:52:58 -01:00
public static Dictionary < string , object > GetXsltExtensions ( )
{
// zb-00041 #29966 : cache the extensions
// We could cache the extensions in a static variable but then the cache
// would not be refreshed when the .config file is modified. An application
// restart would be required. Better use the cache and add a dependency.
2011-11-25 14:03:09 -01:00
return cms . businesslogic . cache . Cache . GetCacheItem (
2011-02-22 11:52:58 -01:00
_xsltExtensionsCacheKey , _xsltExtensionsSyncLock ,
2011-09-12 11:19:37 -02:00
CacheItemPriority . NotRemovable , // NH 4.7.1, Changing to NotRemovable
2011-02-22 11:52:58 -01:00
null , // no refresh action
2011-11-25 14:03:09 -01:00
_xsltExtensionsDependency . Value , // depends on the .config file
2011-02-22 11:52:58 -01:00
TimeSpan . FromDays ( 1 ) , // expires in 1 day (?)
( ) = > { return GetXsltExtensionsImpl ( ) ; } ) ;
}
// zb-00041 #29966 : cache the extensions
2011-01-26 10:46:47 -01:00
2011-11-25 14:03:09 -01:00
private static Dictionary < string , object > GetXsltExtensionsImpl ( )
2009-06-19 07:39:16 +00:00
{
// fill a dictionary with the predefined extensions
2010-12-06 11:47:46 +00:00
var extensions = new Dictionary < string , object > ( GetPredefinedXsltExtensions ( ) ) ;
2009-06-19 07:39:16 +00:00
// Load the XSLT extensions configuration
2010-12-06 11:47:46 +00:00
var xsltExt = new XmlDocument ( ) ;
2011-02-22 11:52:58 -01:00
xsltExt . Load ( _xsltExtensionsConfig ) ;
2009-06-19 07:39:16 +00:00
// add all descendants of the XsltExtensions element
foreach ( XmlNode xsltEx in xsltExt . SelectSingleNode ( "/XsltExtensions" ) )
{
if ( xsltEx . NodeType = = XmlNodeType . Element )
{
Debug . Assert ( xsltEx . Attributes [ "assembly" ] ! = null , "Extension attribute 'assembly' not specified." ) ;
Debug . Assert ( xsltEx . Attributes [ "type" ] ! = null , "Extension attribute 'type' not specified." ) ;
Debug . Assert ( xsltEx . Attributes [ "alias" ] ! = null , "Extension attribute 'alias' not specified." ) ;
// load the extension assembly
2010-12-06 11:47:46 +00:00
string extensionFile =
IOHelper . MapPath ( string . Format ( "{0}/{1}.dll" , SystemDirectories . Bin ,
xsltEx . Attributes [ "assembly" ] . Value ) ) ;
2010-03-03 07:20:55 +00:00
2009-06-19 07:39:16 +00:00
Assembly extensionAssembly ;
try
{
extensionAssembly = Assembly . LoadFrom ( extensionFile ) ;
}
2010-03-03 07:20:55 +00:00
catch ( Exception ex )
2009-06-19 07:39:16 +00:00
{
2010-12-06 11:47:46 +00:00
throw new Exception (
String . Format (
"Could not load assembly {0} for XSLT extension {1}. Please check config/xsltExentions.config." ,
extensionFile , xsltEx . Attributes [ "alias" ] . Value ) , ex ) ;
2009-06-19 07:39:16 +00:00
}
// load the extension type
Type extensionType = extensionAssembly . GetType ( xsltEx . Attributes [ "type" ] . Value ) ;
2010-03-03 07:20:55 +00:00
if ( extensionType = = null )
2010-12-06 11:47:46 +00:00
throw new Exception (
String . Format (
"Could not load type {0} ({1}) for XSLT extension {1}. Please check config/xsltExentions.config." ,
xsltEx . Attributes [ "type" ] . Value , extensionFile , xsltEx . Attributes [ "alias" ] . Value ) ) ;
2009-06-19 07:39:16 +00:00
// create an instance and add it to the extensions list
extensions . Add ( xsltEx . Attributes [ "alias" ] . Value , Activator . CreateInstance ( extensionType ) ) ;
}
}
2010-12-16 11:15:56 -01:00
//also get types marked with XsltExtension attribute
2011-02-22 11:52:58 -01:00
// zb-00042 #29949 : do not hide errors, refactor
2011-12-20 07:44:43 -13:00
foreach ( Type xsltType in TypeFinder . FindClassesMarkedWithAttribute ( typeof ( XsltExtensionAttribute ) ) )
2010-05-10 14:34:18 +00:00
{
2011-12-20 07:44:43 -13:00
object [ ] tpAttributes = xsltType . GetCustomAttributes ( typeof ( XsltExtensionAttribute ) , true ) ;
2011-02-01 13:18:22 -01:00
foreach ( XsltExtensionAttribute tpAttribute in tpAttributes )
2010-05-10 14:34:18 +00:00
{
2011-02-22 11:52:58 -01:00
string ns = ! string . IsNullOrEmpty ( tpAttribute . Namespace ) ? tpAttribute . Namespace : xsltType . FullName ;
extensions . Add ( ns , Activator . CreateInstance ( xsltType ) ) ;
2010-05-10 14:34:18 +00:00
}
2010-03-03 02:50:06 +00:00
}
2009-06-19 07:39:16 +00:00
return extensions ;
}
/// <summary>
/// Gets the predefined XSLT extensions.
/// </summary>
/// <remarks>
/// This is a legacy list of EXSLT extensions.
/// The Umbraco library is not included, because its instance is page specific.
/// </remarks>
/// <returns>A dictionary of name/extension instance pairs.</returns>
public static Dictionary < string , object > GetPredefinedXsltExtensions ( )
{
if ( m_PredefinedExtensions = = null )
{
m_PredefinedExtensions = new Dictionary < string , object > ( ) ;
// add predefined EXSLT extensions
m_PredefinedExtensions . Add ( "Exslt.ExsltCommon" , new ExsltCommon ( ) ) ;
m_PredefinedExtensions . Add ( "Exslt.ExsltDatesAndTimes" , new ExsltDatesAndTimes ( ) ) ;
m_PredefinedExtensions . Add ( "Exslt.ExsltMath" , new ExsltMath ( ) ) ;
m_PredefinedExtensions . Add ( "Exslt.ExsltRegularExpressions" , new ExsltRegularExpressions ( ) ) ;
m_PredefinedExtensions . Add ( "Exslt.ExsltStrings" , new ExsltStrings ( ) ) ;
m_PredefinedExtensions . Add ( "Exslt.ExsltSets" , new ExsltSets ( ) ) ;
}
return m_PredefinedExtensions ;
}
/// <summary>
/// Returns an XSLT argument list with all XSLT extensions added,
/// both predefined and configured ones.
/// </summary>
/// <returns>A new XSLT argument list.</returns>
public static XsltArgumentList AddMacroXsltExtensions ( )
{
2010-12-06 11:47:46 +00:00
var xslArgs = new XsltArgumentList ( ) ;
2009-06-19 07:39:16 +00:00
2010-12-06 11:47:46 +00:00
foreach ( var extension in GetXsltExtensions ( ) )
2009-06-19 07:39:16 +00:00
{
string extensionNamespace = "urn:" + extension . Key ;
xslArgs . AddExtensionObject ( extensionNamespace , extension . Value ) ;
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoXsltExtension" ,
String . Format ( "Extension added: {0}, {1}" ,
extensionNamespace , extension . Value . GetType ( ) . Name ) ) ;
2009-06-19 07:39:16 +00:00
}
return xslArgs ;
}
private void addMacroXmlNode ( XmlDocument umbracoXML , XmlDocument macroXML , String macroPropertyAlias ,
String macroPropertyType , String macroPropertyValue )
{
XmlNode macroXmlNode = macroXML . CreateNode ( XmlNodeType . Element , macroPropertyAlias , string . Empty ) ;
2010-12-06 11:47:46 +00:00
var x = new XmlDocument ( ) ;
2009-06-19 07:39:16 +00:00
int currentID = - 1 ;
// If no value is passed, then use the current pageID as value
if ( macroPropertyValue = = string . Empty )
{
2011-12-20 07:44:43 -13:00
var umbPage = ( page ) HttpContext . Current . Items [ "umbPageObject" ] ;
2009-06-19 07:39:16 +00:00
if ( umbPage = = null )
return ;
currentID = umbPage . PageID ;
}
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" ,
"Xslt node adding search start (" + macroPropertyAlias + ",'" +
macroPropertyValue + "')" ) ;
2009-06-19 07:39:16 +00:00
switch ( macroPropertyType )
{
case "contentTree" :
XmlAttribute nodeID = macroXML . CreateAttribute ( "nodeID" ) ;
if ( macroPropertyValue ! = string . Empty )
nodeID . Value = macroPropertyValue ;
else
nodeID . Value = currentID . ToString ( ) ;
macroXmlNode . Attributes . SetNamedItem ( nodeID ) ;
// Get subs
try
{
macroXmlNode . AppendChild ( macroXML . ImportNode ( umbracoXML . GetElementById ( nodeID . Value ) , true ) ) ;
}
catch
{
break ;
}
break ;
case "contentCurrent" :
x . LoadXml ( "<nodes/>" ) ;
XmlNode currentNode ;
if ( macroPropertyValue ! = string . Empty )
currentNode = macroXML . ImportNode ( umbracoXML . GetElementById ( macroPropertyValue ) , true ) ;
else
currentNode = macroXML . ImportNode ( umbracoXML . GetElementById ( currentID . ToString ( ) ) , true ) ;
// remove all sub content nodes
foreach ( XmlNode n in currentNode . SelectNodes ( "./node" ) )
currentNode . RemoveChild ( n ) ;
macroXmlNode . AppendChild ( currentNode ) ;
break ;
case "contentSubs" :
x . LoadXml ( "<nodes/>" ) ;
if ( macroPropertyValue ! = string . Empty )
x . FirstChild . AppendChild ( x . ImportNode ( umbracoXML . GetElementById ( macroPropertyValue ) , true ) ) ;
else
x . FirstChild . AppendChild ( x . ImportNode ( umbracoXML . GetElementById ( currentID . ToString ( ) ) , true ) ) ;
macroXmlNode . InnerXml = transformMacroXML ( x , "macroGetSubs.xsl" ) ;
break ;
case "contentAll" :
x . ImportNode ( umbracoXML . DocumentElement . LastChild , true ) ;
break ;
case "contentRandom" :
XmlNode source = umbracoXML . GetElementById ( macroPropertyValue ) ;
if ( source ! = null )
{
XmlNodeList sourceList = source . SelectNodes ( "node" ) ;
if ( sourceList . Count > 0 )
{
int rndNumber ;
Random r = library . GetRandom ( ) ;
lock ( r )
{
rndNumber = r . Next ( sourceList . Count ) ;
}
XmlNode node = macroXML . ImportNode ( sourceList [ rndNumber ] , true ) ;
// remove all sub content nodes
foreach ( XmlNode n in node . SelectNodes ( "./node" ) )
node . RemoveChild ( n ) ;
macroXmlNode . AppendChild ( node ) ;
break ;
}
else
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro" ,
"Error adding random node - parent (" + macroPropertyValue +
") doesn't have children!" ) ;
2009-06-19 07:39:16 +00:00
}
else
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "umbracoMacro" ,
"Error adding random node - parent (" + macroPropertyValue +
") doesn't exists!" ) ;
2009-06-19 07:39:16 +00:00
break ;
case "mediaCurrent" :
2010-12-06 11:47:46 +00:00
var c = new Content ( int . Parse ( macroPropertyValue ) ) ;
2009-06-19 07:39:16 +00:00
macroXmlNode . AppendChild ( macroXML . ImportNode ( c . ToXml ( content . Instance . XmlContent , false ) , true ) ) ;
break ;
default :
2010-12-06 11:47:46 +00:00
macroXmlNode . InnerText = HttpContext . Current . Server . HtmlDecode ( macroPropertyValue ) ;
2009-06-19 07:39:16 +00:00
break ;
}
macroXML . FirstChild . AppendChild ( macroXmlNode ) ;
}
private string transformMacroXML ( XmlDocument xmlSource , string xslt_File )
{
2010-12-06 11:47:46 +00:00
var sb = new StringBuilder ( ) ;
var sw = new StringWriter ( sb ) ;
2009-06-19 07:39:16 +00:00
XslCompiledTransform result = getXslt ( xslt_File ) ;
//XmlDocument xslDoc = new XmlDocument();
result . Transform ( xmlSource . CreateNavigator ( ) , null , sw ) ;
if ( sw . ToString ( ) ! = string . Empty )
return sw . ToString ( ) ;
else
return string . Empty ;
}
2011-12-22 09:35:06 -01:00
public ScriptingMacroResult loadMacroScript ( MacroModel macro )
{
var retVal = new ScriptingMacroResult ( ) ;
TraceInfo ( "umbracoMacro" , "Loading IMacroEngine script" ) ;
string ret = String . Empty ;
IMacroEngine engine = null ;
if ( ! String . IsNullOrEmpty ( macro . ScriptCode ) )
{
engine = MacroEngineFactory . GetByExtension ( macro . ScriptLanguage ) ;
ret = engine . Execute (
macro ,
Node . GetCurrent ( ) ) ;
}
else
{
string path = IOHelper . MapPath ( SystemDirectories . MacroScripts + "/" + macro . ScriptName ) ;
engine = MacroEngineFactory . GetByFilename ( path ) ;
ret = engine . Execute ( macro , Node . GetCurrent ( ) ) ;
}
// if the macro engine supports success reporting and executing failed, then return an empty control so it's not cached
if ( engine is IMacroEngineResultStatus )
{
var result = engine as IMacroEngineResultStatus ;
if ( ! result . Success )
{
retVal . ResultException = result . ResultException ;
}
}
TraceInfo ( "umbracoMacro" , "Loading IMacroEngine script [done]" ) ;
retVal . Result = ret ;
return retVal ;
}
[Obsolete("Replaced with loadMacroScript", true)]
2011-11-10 08:07:16 -01:00
public DLRMacroResult loadMacroDLR ( MacroModel macro )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
var retVal = new DLRMacroResult ( ) ;
2011-01-10 12:23:26 -01:00
TraceInfo ( "umbracoMacro" , "Loading IMacroEngine script" ) ;
2010-12-06 11:47:46 +00:00
var ret = new LiteralControl ( ) ;
2011-11-10 08:07:16 -01:00
IMacroEngine engine = null ;
2011-01-12 07:57:21 -01:00
if ( ! String . IsNullOrEmpty ( macro . ScriptCode ) )
2009-06-19 07:39:16 +00:00
{
2011-11-10 08:07:16 -01:00
engine = MacroEngineFactory . GetByExtension ( macro . ScriptLanguage ) ;
2011-01-10 12:23:26 -01:00
ret . Text = engine . Execute (
macro ,
Node . GetCurrent ( ) ) ;
2009-06-19 07:39:16 +00:00
}
2011-01-10 12:23:26 -01:00
else
2009-06-19 07:39:16 +00:00
{
2011-02-28 13:03:09 -01:00
string path = IOHelper . MapPath ( SystemDirectories . MacroScripts + "/" + macro . ScriptName ) ;
2011-11-10 08:07:16 -01:00
engine = MacroEngineFactory . GetByFilename ( path ) ;
2011-01-10 12:23:26 -01:00
ret . Text = engine . Execute ( macro , Node . GetCurrent ( ) ) ;
2009-06-19 07:39:16 +00:00
}
2011-11-10 08:07:16 -01:00
// if the macro engine supports success reporting and executing failed, then return an empty control so it's not cached
if ( engine is IMacroEngineResultStatus )
{
var result = engine as IMacroEngineResultStatus ;
if ( ! result . Success )
{
retVal . ResultException = result . ResultException ;
}
}
2011-01-10 12:23:26 -01:00
TraceInfo ( "umbracoMacro" , "Loading IMacroEngine script [done]" ) ;
2011-11-10 08:07:16 -01:00
retVal . Control = ret ;
return retVal ;
2010-01-28 12:51:46 +00:00
}
2009-06-19 07:39:16 +00:00
/// <summary>
/// Loads a custom or webcontrol using reflection into the macro object
/// </summary>
/// <param name="fileName">The assembly to load from</param>
/// <param name="controlName">Name of the control</param>
/// <returns></returns>
/// <param name="attributes"></param>
2011-01-10 12:23:26 -01:00
public Control loadControl ( string fileName , string controlName , MacroModel model )
2009-06-19 07:39:16 +00:00
{
2011-01-10 12:23:26 -01:00
return loadControl ( fileName , controlName , model , null ) ;
2009-06-19 07:39:16 +00:00
}
/// <summary>
/// Loads a custom or webcontrol using reflection into the macro object
/// </summary>
/// <param name="fileName">The assembly to load from</param>
/// <param name="controlName">Name of the control</param>
/// <returns></returns>
/// <param name="attributes"></param>
/// <param name="umbPage"></param>
2011-01-10 12:23:26 -01:00
public Control loadControl ( string fileName , string controlName , MacroModel model , Hashtable pageElements )
2009-06-19 07:39:16 +00:00
{
Type type ;
Assembly asm ;
try
{
2010-01-28 12:51:46 +00:00
string currentAss = IOHelper . MapPath ( string . Format ( "{0}/{1}.dll" , SystemDirectories . Bin , fileName ) ) ;
2010-03-03 07:20:55 +00:00
2009-06-19 07:39:16 +00:00
if ( ! File . Exists ( currentAss ) )
return new LiteralControl ( "Unable to load user control because is does not exist: " + fileName ) ;
asm = Assembly . LoadFrom ( currentAss ) ;
2010-03-03 07:20:55 +00:00
2009-06-19 07:39:16 +00:00
if ( HttpContext . Current ! = null )
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" , "Assembly file " + currentAss + " LOADED!!" ) ;
2009-06-19 07:39:16 +00:00
}
catch
{
throw new ArgumentException ( string . Format ( "ASSEMBLY NOT LOADED PATH: {0} NOT FOUND!!" ,
2010-01-28 12:51:46 +00:00
IOHelper . MapPath ( SystemDirectories . Bin + "/" + fileName +
2010-12-06 11:47:46 +00:00
".dll" ) ) ) ;
2009-06-19 07:39:16 +00:00
}
if ( HttpContext . Current ! = null )
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( "umbracoMacro" ,
string . Format ( "Assembly Loaded from ({0}.dll)" , fileName ) ) ;
2009-06-19 07:39:16 +00:00
type = asm . GetType ( controlName ) ;
if ( type = = null )
return new LiteralControl ( string . Format ( "Unable to get type {0} from assembly {1}" ,
controlName , asm . FullName ) ) ;
2010-12-06 11:47:46 +00:00
var control = Activator . CreateInstance ( type ) as Control ;
2009-06-19 07:39:16 +00:00
if ( control = = null )
return new LiteralControl ( string . Format ( "Unable to create control {0} from assembly {1}" ,
controlName , asm . FullName ) ) ;
2011-01-07 01:23:09 +00:00
AddCurrentNodeToControl ( control , type ) ;
// Properties
2011-11-25 14:03:09 -01:00
updateControlProperties ( type , control , model ) ;
return control ;
}
private void updateControlProperties ( Type type , Control control , MacroModel model )
{
foreach ( MacroPropertyModel mp in model . Properties )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
PropertyInfo prop = type . GetProperty ( mp . Key ) ;
2009-06-19 07:39:16 +00:00
if ( prop = = null )
{
if ( HttpContext . Current ! = null )
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "macro" ,
string . Format (
"control property '{0}' doesn't exist or aren't accessible (public)" ,
mp . Key ) ) ;
2009-06-19 07:39:16 +00:00
continue ;
}
2011-11-25 14:03:09 -01:00
object propValue = mp . Value ;
2012-01-06 08:32:50 -01:00
bool propValueSet = false ;
2009-06-19 07:39:16 +00:00
// Special case for types of webControls.unit
2011-12-20 07:44:43 -13:00
if ( prop . PropertyType = = typeof ( Unit ) )
2012-01-06 08:32:50 -01:00
{
2009-06-19 07:39:16 +00:00
propValue = Unit . Parse ( propValue . ToString ( ) ) ;
2012-01-06 08:32:50 -01:00
propValueSet = true ;
}
2009-06-19 07:39:16 +00:00
else
{
2011-11-25 14:03:09 -01:00
try
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
if ( mp . CLRType = = null )
continue ;
2011-12-20 07:44:43 -13:00
var st = ( TypeCode ) Enum . Parse ( typeof ( TypeCode ) , mp . CLRType , true ) ;
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
// Special case for booleans
2011-12-20 07:44:43 -13:00
if ( prop . PropertyType = = typeof ( bool ) )
2011-11-25 14:03:09 -01:00
{
bool parseResult ;
if (
Boolean . TryParse (
propValue . ToString ( ) . Replace ( "1" , "true" ) . Replace ( "0" , "false" ) ,
out parseResult ) )
propValue = parseResult ;
else
propValue = false ;
2012-01-06 08:32:50 -01:00
propValueSet = true ;
2011-11-25 14:03:09 -01:00
}
else
2011-12-20 07:44:43 -13:00
{
string sPropValue = string . Format ( "{0}" , propValue ) ;
Type propType = prop . PropertyType ;
if ( ! string . IsNullOrWhiteSpace ( sPropValue ) )
{
try
{
propValue = Convert . ChangeType ( propValue , st ) ;
2012-01-06 08:32:50 -01:00
propValueSet = true ;
2011-12-20 07:44:43 -13:00
}
catch ( FormatException )
{
propValue = Convert . ChangeType ( propValue , propType ) ;
2012-01-06 08:32:50 -01:00
propValueSet = true ;
2011-12-20 07:44:43 -13:00
}
}
2012-01-06 08:32:50 -01:00
/ * NH 06 - 01 - 2012 : Remove the lines below as they would only get activated if the values are empty
else
{
if ( propType ! = null )
2011-12-20 07:44:43 -13:00
{
2012-01-06 08:32:50 -01:00
if ( propType . IsValueType )
{
propValue = Activator . CreateInstance ( propType ) ;
}
else
2011-12-20 07:44:43 -13:00
{
2012-01-06 08:32:50 -01:00
propValue = null ;
2011-12-20 07:44:43 -13:00
}
}
2012-01-06 08:32:50 -01:00
} * /
2011-12-20 07:44:43 -13:00
}
2009-06-19 07:39:16 +00:00
2011-11-25 14:03:09 -01:00
if ( GlobalSettings . DebugMode )
UmbracoContext . Current . Trace . Write ( "macro.loadControlProperties" ,
string . Format ( "Property added '{0}' with value '{1}'" ,
mp . Key ,
propValue ) ) ;
}
catch ( Exception PropException )
2009-06-19 07:39:16 +00:00
{
2011-11-25 14:03:09 -01:00
Log . Instance . AddException ( PropException ) ;
if ( GlobalSettings . DebugMode )
UmbracoContext . Current . Trace . Warn ( "macro.loadControlProperties" ,
string . Format (
"Error adding property '{0}' with value '{1}'" ,
mp . Key , propValue ) , PropException ) ;
2009-06-19 07:39:16 +00:00
}
}
2012-01-06 08:32:50 -01:00
// NH 06-01-2012: Only set value if it has content
if ( propValueSet )
prop . SetValue ( control , Convert . ChangeType ( propValue , prop . PropertyType ) , null ) ;
2009-06-19 07:39:16 +00:00
}
}
/// <summary>
/// Loads an usercontrol using reflection into the macro object
/// </summary>
/// <param name="fileName">Filename of the usercontrol - ie. ~wulff.ascx</param>
2011-01-07 01:23:09 +00:00
/// <param name="attributes">The attributes.</param>
/// <param name="pageElements">The page elements.</param>
2009-06-19 07:39:16 +00:00
/// <returns></returns>
2011-01-10 12:23:26 -01:00
public Control loadUserControl ( string fileName , MacroModel model , Hashtable pageElements )
2009-06-19 07:39:16 +00:00
{
Debug . Assert ( ! string . IsNullOrEmpty ( fileName ) , "fileName cannot be empty" ) ;
2011-01-10 12:23:26 -01:00
Debug . Assert ( model . Properties ! = null , "attributes cannot be null" ) ;
2009-06-19 07:39:16 +00:00
Debug . Assert ( pageElements ! = null , "pageElements cannot be null" ) ;
try
{
string userControlPath = @"~/" + fileName ;
2010-01-28 12:51:46 +00:00
if ( ! File . Exists ( IOHelper . MapPath ( userControlPath ) ) )
2009-06-19 07:39:16 +00:00
return new LiteralControl ( string . Format ( "UserControl {0} does not exist." , fileName ) ) ;
2011-12-20 07:44:43 -13:00
var oControl = ( UserControl ) new UserControl ( ) . LoadControl ( userControlPath ) ;
2009-06-19 07:39:16 +00:00
int slashIndex = fileName . LastIndexOf ( "/" ) + 1 ;
if ( slashIndex < 0 )
slashIndex = 0 ;
2011-01-10 12:23:26 -01:00
if ( ! String . IsNullOrEmpty ( model . MacroControlIdentifier ) )
oControl . ID = model . MacroControlIdentifier ;
2009-06-19 07:39:16 +00:00
else
oControl . ID =
string . Format ( "{0}_{1}" , fileName . Substring ( slashIndex , fileName . IndexOf ( ".ascx" ) - slashIndex ) ,
StateHelper . GetContextValue < int > ( macrosAddedKey ) ) ;
TraceInfo ( loadUserControlKey , string . Format ( "Usercontrol added with id '{0}'" , oControl . ID ) ) ;
Type type = oControl . GetType ( ) ;
if ( type = = null )
{
TraceWarn ( loadUserControlKey , "Unable to retrieve control type: " + fileName ) ;
return oControl ;
}
2011-01-07 01:23:09 +00:00
AddCurrentNodeToControl ( oControl , type ) ;
2011-11-25 14:03:09 -01:00
updateControlProperties ( type , oControl , model ) ;
2009-06-19 07:39:16 +00:00
return oControl ;
}
catch ( Exception e )
{
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( "macro" , string . Format ( "Error creating usercontrol ({0})" , fileName ) ,
e ) ;
2009-06-19 07:39:16 +00:00
return new LiteralControl (
string . Format (
"<div style=\"color: black; padding: 3px; border: 2px solid red\"><b style=\"color:red\">Error creating control ({0}).</b><br/> Maybe file doesn't exists or the usercontrol has a cache directive, which is not allowed! See the tracestack for more information!</div>" ,
fileName ) ) ;
}
}
2011-01-07 01:23:09 +00:00
private static void AddCurrentNodeToControl ( Control control , Type type )
{
2011-11-25 14:03:09 -01:00
PropertyInfo currentNodeProperty = type . GetProperty ( "CurrentNode" ) ;
if ( currentNodeProperty ! = null & & currentNodeProperty . CanWrite & &
2011-12-20 07:44:43 -13:00
currentNodeProperty . PropertyType . IsAssignableFrom ( typeof ( Node ) ) )
2011-01-07 01:23:09 +00:00
{
currentNodeProperty . SetValue ( control , Node . GetCurrent ( ) , null ) ;
}
currentNodeProperty = type . GetProperty ( "currentNode" ) ;
2011-11-25 14:03:09 -01:00
if ( currentNodeProperty ! = null & & currentNodeProperty . CanWrite & &
2011-12-20 07:44:43 -13:00
currentNodeProperty . PropertyType . IsAssignableFrom ( typeof ( Node ) ) )
2011-01-07 01:23:09 +00:00
{
currentNodeProperty . SetValue ( control , Node . GetCurrent ( ) , null ) ;
}
}
2009-06-19 07:39:16 +00:00
private void TraceInfo ( string category , string message )
{
if ( HttpContext . Current ! = null )
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Write ( category , message ) ;
2009-06-19 07:39:16 +00:00
}
private void TraceWarn ( string category , string message )
{
if ( HttpContext . Current ! = null )
2011-11-25 14:03:09 -01:00
UmbracoContext . Current . Trace . Warn ( category , message ) ;
2009-06-19 07:39:16 +00:00
}
public static string renderMacroStartTag ( Hashtable attributes , int pageId , Guid versionId )
{
2010-03-03 07:20:55 +00:00
string div = "<div " ;
2009-06-19 07:39:16 +00:00
IDictionaryEnumerator ide = attributes . GetEnumerator ( ) ;
while ( ide . MoveNext ( ) )
{
div + = string . Format ( "umb_{0}=\"{1}\" " , ide . Key , encodeMacroAttribute ( ide . Value . ToString ( ) ) ) ;
}
div + = "ismacro=\"true\" onresizestart=\"return false;\" umbVersionId=\"" + versionId +
"\" umbPageid=\"" +
pageId +
"\" title=\"This is rendered content from macro\" class=\"umbMacroHolder\"><!-- startUmbMacro -->" ;
return div ;
}
private static string encodeMacroAttribute ( string attributeContents )
{
// Replace linebreaks
attributeContents = attributeContents . Replace ( "\n" , "\\n" ) . Replace ( "\r" , "\\r" ) ;
// Replace quotes
2010-03-03 07:20:55 +00:00
attributeContents =
2009-06-19 07:39:16 +00:00
attributeContents . Replace ( "\"" , """ ) ;
// Replace tag start/ends
attributeContents =
attributeContents . Replace ( "<" , "<" ) . Replace ( ">" , ">" ) ;
return attributeContents ;
}
public static string renderMacroEndTag ( )
{
return "<!-- endUmbMacro --></div>" ;
}
public static string GetRenderedMacro ( int MacroId , page umbPage , Hashtable attributes , int pageId )
{
2011-11-25 14:03:09 -01:00
macro m = GetMacro ( MacroId ) ;
2009-06-19 07:39:16 +00:00
Control c = m . renderMacro ( attributes , umbPage . Elements , pageId ) ;
TextWriter writer = new StringWriter ( ) ;
2010-12-06 11:47:46 +00:00
var ht = new HtmlTextWriter ( writer ) ;
2009-06-19 07:39:16 +00:00
c . RenderControl ( ht ) ;
string result = writer . ToString ( ) ;
// remove hrefs
string pattern = "href=\"([^\"]*)\"" ;
MatchCollection hrefs =
Regex . Matches ( result , pattern , RegexOptions . IgnoreCase | RegexOptions . IgnorePatternWhitespace ) ;
foreach ( Match href in hrefs )
result = result . Replace ( href . Value , "href=\"javascript:void(0)\"" ) ;
return result ;
}
public static string MacroContentByHttp ( int PageID , Guid PageVersion , Hashtable attributes )
{
2010-12-06 11:47:46 +00:00
string tempAlias = ( attributes [ "macroalias" ] ! = null )
? attributes [ "macroalias" ] . ToString ( )
: attributes [ "macroAlias" ] . ToString ( ) ;
2011-11-25 14:03:09 -01:00
macro currentMacro = GetMacro ( tempAlias ) ;
2011-05-09 09:58:12 -02:00
if ( ! currentMacro . DontRenderInEditor )
2009-06-19 07:39:16 +00:00
{
string querystring = "umbPageId=" + PageID + "&umbVersionId=" + PageVersion ;
IDictionaryEnumerator ide = attributes . GetEnumerator ( ) ;
while ( ide . MoveNext ( ) )
querystring + = "&umb_" + ide . Key + "=" + HttpContext . Current . Server . UrlEncode ( ide . Value . ToString ( ) ) ;
// Create a new 'HttpWebRequest' Object to the mentioned URL.
string retVal = string . Empty ;
2011-05-09 09:58:12 -02:00
string protocol = GlobalSettings . UseSSL ? "https" : "http" ;
2011-11-25 14:03:09 -01:00
string url = string . Format ( "{0}://{1}:{2}{3}/macroResultWrapper.aspx?{4}" , protocol ,
HttpContext . Current . Request . ServerVariables [ "SERVER_NAME" ] ,
HttpContext . Current . Request . ServerVariables [ "SERVER_PORT" ] ,
IOHelper . ResolveUrl ( SystemDirectories . Umbraco ) , querystring ) ;
2009-06-19 07:39:16 +00:00
2011-12-20 07:44:43 -13:00
var myHttpWebRequest = ( HttpWebRequest ) WebRequest . Create ( url ) ;
2010-10-20 12:16:08 +00:00
2011-05-09 09:58:12 -02:00
// allows for validation of SSL conversations (to bypass SSL errors in debug mode!)
ServicePointManager . ServerCertificateValidationCallback + = ValidateRemoteCertificate ;
2010-10-20 12:16:08 +00:00
// propagate the user's context
2011-02-22 11:52:58 -01:00
// zb-00004 #29956 : refactor cookies names & handling
HttpCookie inCookie = StateHelper . Cookies . UserContext . RequestCookie ;
2010-12-06 11:47:46 +00:00
var cookie = new Cookie ( inCookie . Name , inCookie . Value , inCookie . Path ,
HttpContext . Current . Request . ServerVariables [ "SERVER_NAME" ] ) ;
2010-10-20 12:16:08 +00:00
myHttpWebRequest . CookieContainer = new CookieContainer ( ) ;
myHttpWebRequest . CookieContainer . Add ( cookie ) ;
2009-06-19 07:39:16 +00:00
// Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.
HttpWebResponse myHttpWebResponse = null ;
try
{
2011-12-20 07:44:43 -13:00
myHttpWebResponse = ( HttpWebResponse ) myHttpWebRequest . GetResponse ( ) ;
2009-06-19 07:39:16 +00:00
if ( myHttpWebResponse . StatusCode = = HttpStatusCode . OK )
{
Stream streamResponse = myHttpWebResponse . GetResponseStream ( ) ;
2010-12-06 11:47:46 +00:00
var streamRead = new StreamReader ( streamResponse ) ;
var readBuff = new Char [ 256 ] ;
2009-06-19 07:39:16 +00:00
int count = streamRead . Read ( readBuff , 0 , 256 ) ;
while ( count > 0 )
{
2010-12-06 11:47:46 +00:00
var outputData = new String ( readBuff , 0 , count ) ;
2009-06-19 07:39:16 +00:00
retVal + = outputData ;
count = streamRead . Read ( readBuff , 0 , 256 ) ;
}
// Close the Stream object.
streamResponse . Close ( ) ;
streamRead . Close ( ) ;
// Find the content of a form
string grabStart = "<!-- grab start -->" ;
string grabEnd = "<!-- grab end -->" ;
int grabStartPos = retVal . IndexOf ( grabStart ) + grabStart . Length ;
int grabEndPos = retVal . IndexOf ( grabEnd ) - grabStartPos ;
retVal = retVal . Substring ( grabStartPos , grabEndPos ) ;
}
else
2011-05-09 09:58:12 -02:00
retVal = showNoMacroContent ( currentMacro ) ;
2009-06-19 07:39:16 +00:00
// Release the HttpWebResponse Resource.
myHttpWebResponse . Close ( ) ;
}
2011-07-05 11:30:06 -02:00
catch ( Exception )
2009-06-19 07:39:16 +00:00
{
2011-05-09 09:58:12 -02:00
retVal = showNoMacroContent ( currentMacro ) ;
2009-06-19 07:39:16 +00:00
}
finally
{
// Release the HttpWebResponse Resource.
if ( myHttpWebResponse ! = null )
myHttpWebResponse . Close ( ) ;
}
return retVal . Replace ( "\n" , string . Empty ) . Replace ( "\r" , string . Empty ) ;
}
2011-05-09 09:58:12 -02:00
return showNoMacroContent ( currentMacro ) ;
}
private static string showNoMacroContent ( macro currentMacro )
{
2011-11-25 14:03:09 -01:00
return "<span style=\"color: green\"><strong>" + currentMacro . Name +
"</strong><br />No macro content available for WYSIWYG editing</span>" ;
2011-05-09 09:58:12 -02:00
}
private static bool ValidateRemoteCertificate (
2011-11-25 14:03:09 -01:00
object sender ,
X509Certificate certificate ,
X509Chain chain ,
SslPolicyErrors policyErrors
)
2011-05-09 09:58:12 -02:00
{
if ( GlobalSettings . DebugMode )
{
// allow any old dodgy certificate...
return true ;
}
2009-06-19 07:39:16 +00:00
else
2011-05-09 09:58:12 -02:00
{
return policyErrors = = SslPolicyErrors . None ;
}
2009-06-19 07:39:16 +00:00
}
/// <summary>
/// Adds the XSLT extension namespaces to the XSLT header using
/// {0} as the container for the namespace references and
/// {1} as the container for the exclude-result-prefixes
/// </summary>
/// <param name="xslt">The XSLT</param>
/// <returns></returns>
public static string AddXsltExtensionsToHeader ( string xslt )
{
2010-12-06 11:47:46 +00:00
var namespaceList = new StringBuilder ( ) ;
var namespaceDeclaractions = new StringBuilder ( ) ;
foreach ( var extension in GetXsltExtensions ( ) )
2009-06-19 07:39:16 +00:00
{
namespaceList . Append ( extension . Key ) . Append ( ' ' ) ;
namespaceDeclaractions . AppendFormat ( "xmlns:{0}=\"urn:{0}\" " , extension . Key ) ;
}
// parse xslt
xslt = xslt . Replace ( "{0}" , namespaceDeclaractions . ToString ( ) ) ;
xslt = xslt . Replace ( "{1}" , namespaceList . ToString ( ) ) ;
return xslt ;
}
2011-12-22 09:35:06 -01:00
[Obsolete("Please stop using these as they'll be removed in v4.8")]
public static bool TryGetColumnString ( IRecordsReader reader , string columnName , out string value )
{
if ( reader . ContainsField ( columnName ) & & ! reader . IsNull ( columnName ) )
{
value = reader . GetString ( columnName ) ;
return true ;
}
2012-01-06 08:32:50 -01:00
2011-12-22 09:35:06 -01:00
value = string . Empty ;
return false ;
}
[Obsolete("Please stop using these as they'll be removed in v4.8")]
public static bool TryGetColumnInt32 ( IRecordsReader reader , string columnName , out int value )
{
if ( reader . ContainsField ( columnName ) & & ! reader . IsNull ( columnName ) )
{
value = reader . GetInt ( columnName ) ;
return true ;
}
2012-01-06 08:32:50 -01:00
2011-12-22 09:35:06 -01:00
value = - 1 ;
return false ;
}
[Obsolete("Please stop using these as they'll be removed in v4.8")]
public static bool TryGetColumnBool ( IRecordsReader reader , string columnName , out bool value )
{
if ( reader . ContainsField ( columnName ) & & ! reader . IsNull ( columnName ) )
{
value = reader . GetBoolean ( columnName ) ;
return true ;
}
2012-01-06 08:32:50 -01:00
2011-12-22 09:35:06 -01:00
value = false ;
return false ;
}
2009-06-19 07:39:16 +00:00
}
2011-11-25 14:03:09 -01:00
2009-06-19 07:39:16 +00:00
public class MacroCacheContent
{
2010-12-06 11:47:46 +00:00
private readonly Control _control ;
private readonly string _id ;
public MacroCacheContent ( Control control , string ID )
{
_control = control ;
_id = ID ;
}
2009-06-19 07:39:16 +00:00
public string ID
{
get { return _id ; }
}
public Control Content
{
get { return _control ; }
}
}
public class macroCacheRefresh : ICacheRefresher
{
#region ICacheRefresher Members
public string Name
{
get
{
// TODO: Add templateCacheRefresh.Name getter implementation
return "Macro cache refresher" ;
}
}
public Guid UniqueIdentifier
{
get
{
// TODO: Add templateCacheRefresh.UniqueIdentifier getter implementation
return new Guid ( "7B1E683C-5F34-43dd-803D-9699EA1E98CA" ) ;
}
}
public void RefreshAll ( )
{
}
public void Refresh ( Guid Id )
{
// Doesn't do anything
}
void ICacheRefresher . Refresh ( int Id )
{
2011-11-25 14:03:09 -01:00
macro . GetMacro ( Id ) . removeFromCache ( ) ;
2009-06-19 07:39:16 +00:00
}
2010-03-03 07:20:55 +00:00
void ICacheRefresher . Remove ( int Id )
{
2011-11-25 14:03:09 -01:00
macro . GetMacro ( Id ) . removeFromCache ( ) ;
2009-06-19 07:39:16 +00:00
}
2010-12-06 11:47:46 +00:00
2009-06-19 07:39:16 +00:00
#endregion
}
2010-03-03 02:50:06 +00:00
/// <summary>
/// Allows App_Code XSLT extensions to be declared using the [XsltExtension] class attribute.
/// </summary>
/// <remarks>
/// An optional XML namespace can be specified using [XsltExtension("MyNamespace")].
/// </remarks>
[AttributeUsage(AttributeTargets.Class)]
2010-12-06 11:47:46 +00:00
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium, Unrestricted = false)]
2010-03-03 02:50:06 +00:00
public class XsltExtensionAttribute : Attribute
{
public XsltExtensionAttribute ( )
{
2010-12-06 11:47:46 +00:00
Namespace = String . Empty ;
2010-03-03 02:50:06 +00:00
}
2010-12-06 11:47:46 +00:00
2010-03-03 02:50:06 +00:00
public XsltExtensionAttribute ( string ns )
{
2010-12-06 11:47:46 +00:00
Namespace = ns ;
2010-03-03 02:50:06 +00:00
}
2010-12-06 11:47:46 +00:00
2010-03-03 02:50:06 +00:00
public string Namespace { get ; set ; }
2010-12-06 11:47:46 +00:00
public override string ToString ( )
{
return Namespace ;
}
}
2011-11-10 08:07:16 -01:00
2011-12-22 09:35:06 -01:00
public class ScriptingMacroResult
{
public ScriptingMacroResult ( )
{
}
public ScriptingMacroResult ( string result , Exception resultException )
{
Result = result ;
ResultException = resultException ;
}
public string Result { get ; set ; }
public Exception ResultException { get ; set ; }
}
[Obsolete("This has been replaced with ScriptingMacroResult instead")]
2011-11-10 08:07:16 -01:00
public class DLRMacroResult
{
public DLRMacroResult ( )
{
}
public DLRMacroResult ( Control control , Exception resultException )
{
2011-11-25 14:03:09 -01:00
Control = control ;
ResultException = resultException ;
2011-11-10 08:07:16 -01:00
}
2011-11-25 14:03:09 -01:00
public Control Control { get ; set ; }
public Exception ResultException { get ; set ; }
2011-11-10 08:07:16 -01:00
}
2009-06-19 07:39:16 +00:00
}