Adding the umbraco:image control, and the ImageUrl feature with a some generic ProviderFeature classes, to make it easier to implement future provider based features.

This commit is contained in:
Morten Bock
2012-11-21 07:13:31 -01:00
parent aba68720bb
commit 9e1c5e71e4
13 changed files with 313 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
using System.Configuration;
namespace Umbraco.Core.Configuration
{
public class ProviderFeatureSection : ConfigurationSection
{
private readonly ConfigurationProperty _defaultProvider = new ConfigurationProperty("defaultProvider", typeof(string), null);
private readonly ConfigurationProperty _providers = new ConfigurationProperty("providers", typeof(ProviderSettingsCollection), null);
private readonly ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();
public ProviderFeatureSection()
{
_properties.Add(_providers);
_properties.Add(_defaultProvider);
}
[ConfigurationProperty("defaultProvider")]
public string DefaultProvider
{
get { return (string)base[_defaultProvider]; }
set { base[_defaultProvider] = value; }
}
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get { return (ProviderSettingsCollection)base[_providers]; }
}
protected override ConfigurationPropertyCollection Properties
{
get { return _properties; }
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Configuration.Provider;
namespace Umbraco.Core
{
public class GenericProviderCollection<TProvider> : ProviderCollection where TProvider : ProviderBase
{
public override void Add(ProviderBase provider)
{
// make sure the provider supplied is not null
if (provider == null)
throw new ArgumentNullException("provider");
if (provider as TProvider == null)
{
string providerTypeName = typeof(TProvider).ToString();
throw new ArgumentException("Provider must implement provider type", providerTypeName);
}
base.Add(provider);
}
new public TProvider this[string name]
{
get
{
return (TProvider)base[name];
}
}
}
}

View File

@@ -0,0 +1,10 @@
using System.Configuration.Provider;
namespace Umbraco.Core.Media
{
public abstract class ImageUrlProviderBase : ProviderBase
{
public abstract string GetImageUrlFromMedia(int mediaId);
public abstract string GetImageUrlFromFileName(string specifiedSrc);
}
}

View File

@@ -0,0 +1,9 @@
using System.Web;
namespace Umbraco.Core.ObjectResolution
{
public interface IHttpContextFactory
{
HttpContextBase Context { get; }
}
}

View File

@@ -0,0 +1,12 @@
using System.Web;
namespace Umbraco.Core.ObjectResolution
{
public class WebHttpContextFactory : IHttpContextFactory
{
public HttpContextBase Context
{
get { return new HttpContextWrapper(HttpContext.Current); }
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Configuration;
using System.Configuration.Provider;
using System.Web.Configuration;
using Umbraco.Core.Configuration;
namespace Umbraco.Core
{
public abstract class ProviderFeature<TProvider> where TProvider : ProviderBase
{
private static bool _initialized;
private static object _lock = new object();
public static TProvider Provider { get; private set; }
public static GenericProviderCollection<TProvider> Providers { get; private set; }
protected static void Initialize(string sectionName)
{
if (!_initialized)
{
lock (_lock)
{
if (_initialized)
return;
var section = (ProviderFeatureSection) ConfigurationManager.GetSection(sectionName);
if (section == null)
throw new Exception(string.Format("{0} is not configured for this application", sectionName));
Providers = new GenericProviderCollection<TProvider>();
ProvidersHelper.InstantiateProviders(section.Providers, Providers, typeof (TProvider));
Provider = Providers[section.DefaultProvider];
_initialized = true;
}
}
}
}
}

View File

@@ -60,6 +60,7 @@
<Compile Include="Configuration\FileSystemProviderElement.cs" />
<Compile Include="Configuration\FileSystemProviderElementCollection.cs" />
<Compile Include="Configuration\FileSystemProvidersSection.cs" />
<Compile Include="Configuration\ProviderFeatureSection.cs" />
<Compile Include="CoreBootManager.cs" />
<Compile Include="DataTableExtensions.cs" />
<Compile Include="DictionaryExtensions.cs" />

View File

@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<ImageUrl defaultProvider="umbracoImageUrl">
<providers>
<clear/>
<add name="umbracoImageUrl" type="Umbraco.Web.Media.ImageUrlProviders.ImageUrlProvider, umbraco"/>
</providers>
</ImageUrl>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<ImageUrl defaultProvider="umbracoImageUrl">
<providers>
<clear/>
<add name="umbracoImageUrl" type="Umbraco.Web.Media.ImageUrlProviders.ImageUrlProvider, umbraco"/>
</providers>
</ImageUrl>

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections;
using System.Configuration;
using System.Globalization;
using System.Web;
using System.Web.Configuration;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Media;
using Umbraco.Core.ObjectResolution;
using umbraco;
namespace Umbraco.Web.Media
{
public class ImageUrl : ProviderFeature<ImageUrlProviderBase>
{
private static IHttpContextFactory _contextFactory;
static ImageUrl()
{
_contextFactory = new WebHttpContextFactory();
Initialize("ImageUrl");
}
public static string GetImageUrl(string specifiedSrc, string field, string provider, int? nodeId = null)
{
string url;
ImageUrlProviderBase p = GetProvider(provider);
string fieldValue = string.Empty;
if (!string.IsNullOrEmpty(field))
{
if(nodeId.HasValue)
{
var contentFromCache = GetContentFromCache(nodeId.GetValueOrDefault(), field);
if (contentFromCache != null)
{
fieldValue = contentFromCache.ToString();
}
else
{
page itemPage =new page(content.Instance.XmlContent.GetElementById(nodeId.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)));
var value = itemPage.Elements[field];
fieldValue = value != null ? value.ToString() : string.Empty;
}
}
else
{
var context = _contextFactory.Context;
Hashtable elements = context.Items["pageElements"] as Hashtable;
var value = elements[field];
fieldValue = value != null ? value.ToString() : string.Empty;
}
int mediaId;
if (int.TryParse(fieldValue, out mediaId))
{
//Fetch media
url = p.GetImageUrlFromMedia(mediaId);
}
else
{
//assume file path
url = p.GetImageUrlFromFileName(fieldValue);
}
}
else
{
url = p.GetImageUrlFromFileName(specifiedSrc);
}
return url;
}
private static ImageUrlProviderBase GetProvider(string provider)
{
return string.IsNullOrEmpty(provider) ?
Provider :
Providers[provider];
}
private static object GetContentFromCache(int nodeIdInt, string field)
{
object content = _contextFactory.Context.Cache[String.Format("contentItem{0}_{1}", nodeIdInt.ToString(CultureInfo.InvariantCulture), field)];
return content;
}
}
}

View File

@@ -0,0 +1,43 @@
using System.Xml.XPath;
using Umbraco.Core.Media;
using umbraco;
namespace Umbraco.Web.Media.ImageUrlProviders
{
public class ImageUrlProvider : ImageUrlProviderBase
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
//Get default values from the provider config here?
base.Initialize(name, config);
}
public override string GetImageUrlFromMedia(int mediaId)
{
string url = string.Empty;
var nodeIterator = library.GetMedia(mediaId, false);
if (nodeIterator.Current != null)
{
var filename = getProperty(nodeIterator, "umbracoFile");
var fileExtension = getProperty(nodeIterator, "umbracoExtension");
url = filename;
}
return url;
}
private static string getProperty(XPathNodeIterator nodeIterator, string fileProp)
{
string xpath = UmbracoSettings.UseLegacyXmlSchema
? string.Format(".//data[@alias = '{0}']", fileProp)
: string.Format(".//{0}", fileProp);
var file = nodeIterator.Current.SelectSingleNode(xpath).InnerXml;
return file;
}
public override string GetImageUrlFromFileName(string specifiedSrc)
{
return specifiedSrc + "?wheee=1234";
}
}
}

View File

@@ -354,6 +354,7 @@
<Compile Include="umbraco.presentation\umbraco\settings\editTemplate.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="umbraco.presentation\umbraco\templateControls\Image.cs" />
<Compile Include="umbraco.presentation\umbraco\uQuery\IGetProperty.cs" />
<Compile Include="UmbracoHelper.cs" />
<Compile Include="Mvc\ViewContextExtensions.cs" />

View File

@@ -0,0 +1,24 @@
using System.Web.UI;
using System.Web.UI.HtmlControls;
using Umbraco.Core.Media;
using Umbraco.Web.Media;
namespace umbraco.presentation.templateControls
{
public class Image : HtmlImage
{
public string NodeId { get; set; }
public string Field { get; set; }
public string Provider { get; set; }
protected override void Render(HtmlTextWriter writer)
{
int id;
bool hasid = int.TryParse(NodeId, out id);
int? nodeId = hasid ? id : (int?) null;
Src = ImageUrl.GetImageUrl(Src, Field, Provider, nodeId);
base.Render(writer);
}
}
}