Merge branch 'v8hackathon-library-media-remove' of https://github.com/AnthonyCogworks/Umbraco-CMS into temp-2748
This commit is contained in:
@@ -52,9 +52,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
[ConfigurationProperty("PreviewBadge")]
|
||||
internal InnerTextConfigurationElement<string> PreviewBadge => GetOptionalTextElement("PreviewBadge", DefaultPreviewBadge);
|
||||
|
||||
[ConfigurationProperty("UmbracoLibraryCacheDuration")]
|
||||
internal InnerTextConfigurationElement<int> UmbracoLibraryCacheDuration => GetOptionalTextElement("UmbracoLibraryCacheDuration", 1800);
|
||||
|
||||
[ConfigurationProperty("MacroErrors")]
|
||||
internal InnerTextConfigurationElement<MacroErrorBehaviour> MacroErrors => GetOptionalTextElement("MacroErrors", MacroErrorBehaviour.Inline);
|
||||
|
||||
@@ -121,8 +118,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
string IContentSection.PreviewBadge => PreviewBadge;
|
||||
|
||||
int IContentSection.UmbracoLibraryCacheDuration => UmbracoLibraryCacheDuration;
|
||||
|
||||
MacroErrorBehaviour IContentSection.MacroErrorBehaviour => MacroErrors;
|
||||
|
||||
IEnumerable<string> IContentSection.DisallowedUploadFiles => DisallowedUploadFiles;
|
||||
|
||||
@@ -43,8 +43,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
string PreviewBadge { get; }
|
||||
|
||||
int UmbracoLibraryCacheDuration { get; }
|
||||
|
||||
MacroErrorBehaviour MacroErrorBehaviour { get; }
|
||||
|
||||
IEnumerable<string> DisallowedUploadFiles { get; }
|
||||
|
||||
@@ -147,11 +147,6 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
|
||||
Assert.IsTrue(SettingsSection.Content.PreviewBadge == @"<a id=""umbracoPreviewBadge"" style=""position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{0}/assets/img/preview-mode-badge.png') no-repeat;"" href=""{0}/endPreview.aspx?redir={1}""><span style=""display:none;"">In Preview Mode - click to end</span></a>");
|
||||
}
|
||||
[Test]
|
||||
public void UmbracoLibraryCacheDuration()
|
||||
{
|
||||
Assert.IsTrue(SettingsSection.Content.UmbracoLibraryCacheDuration == 1800);
|
||||
}
|
||||
[Test]
|
||||
public void ResolveUrlsFromTextString()
|
||||
{
|
||||
Assert.IsFalse(SettingsSection.Content.ResolveUrlsFromTextString);
|
||||
|
||||
@@ -77,10 +77,6 @@
|
||||
|
||||
<PreviewBadge><![CDATA[<a id="umbracoPreviewBadge" style="position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{0}/assets/img/preview-mode-badge.png') no-repeat;" href="{0}/endPreview.aspx?redir={1}"><span style="display:none;">In Preview Mode - click to end</span></a>]]></PreviewBadge>
|
||||
|
||||
<!-- Cache cycle of Media and Member data fetched from the umbraco.library methods -->
|
||||
<!-- In seconds. 0 will disable cache -->
|
||||
<UmbracoLibraryCacheDuration>1800</UmbracoLibraryCacheDuration>
|
||||
|
||||
<!-- How Umbraco should handle errors during macro execution. Can be one of the following values:
|
||||
- inline - show an inline error within the macro but allow the page to continue rendering. Historial Umbraco behaviour.
|
||||
- silent - Silently suppress the error and do not render the offending macro.
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using umbraco;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Tests.PublishedContent;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache.XmlPublishedCache;
|
||||
using LightInject;
|
||||
using Moq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Misc
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the legacy library class
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class LibraryTests : BaseWebTest
|
||||
{
|
||||
public override void SetUp()
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(
|
||||
new DataType(new VoidEditor(Mock.Of<ILogger>())) { Id = 1 });
|
||||
|
||||
var factory = new PublishedContentTypeFactory(Mock.Of<IPublishedModelFactory>(), new PropertyValueConverterCollection(Array.Empty<IPropertyValueConverter>()), dataTypeService);
|
||||
|
||||
// need to specify a custom callback for unit tests
|
||||
// AutoPublishedContentTypes generates properties automatically
|
||||
// when they are requested, but we must declare those that we
|
||||
// explicitely want to be here...
|
||||
|
||||
var propertyTypes = new[]
|
||||
{
|
||||
// AutoPublishedContentType will auto-generate other properties
|
||||
factory.CreatePropertyType("content", 1),
|
||||
};
|
||||
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = (alias) => type;
|
||||
Debug.Print("INIT LIB {0}",
|
||||
ContentTypesCache.Get(PublishedItemType.Content, "anything")
|
||||
.PropertyTypes.Count());
|
||||
|
||||
var umbracoContext = GetUmbracoContext("/test");
|
||||
Umbraco.Web.Composing.Current.UmbracoContextAccessor.UmbracoContext = umbracoContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets up resolvers before resolution is frozen
|
||||
/// </summary>
|
||||
protected override void Compose()
|
||||
{
|
||||
base.Compose();
|
||||
|
||||
// required so we can access property.Value
|
||||
if (Container.TryGetInstance<PropertyValueConverterCollectionBuilder>() == null)
|
||||
Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The old method, just using this to make sure we're returning the correct exact data as before.
|
||||
/// </summary>
|
||||
/// <param name="nodeId"></param>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
private string LegacyGetItem(int nodeId, string alias)
|
||||
{
|
||||
var cache = UmbracoContext.Current.ContentCache as PublishedContentCache;
|
||||
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
|
||||
var umbracoXML = cache.GetXml(UmbracoContext.Current.InPreviewMode);
|
||||
|
||||
string xpath = "./{0}";
|
||||
if (umbracoXML.GetElementById(nodeId.ToString()) != null)
|
||||
if (
|
||||
",id,parentID,level,writerID,template,sortOrder,createDate,updateDate,nodeName,writerName,path,"
|
||||
.
|
||||
IndexOf("," + alias + ",") > -1)
|
||||
return umbracoXML.GetElementById(nodeId.ToString()).Attributes.GetNamedItem(alias).Value;
|
||||
else if (
|
||||
umbracoXML.GetElementById(nodeId.ToString()).SelectSingleNode(string.Format(xpath, alias)) !=
|
||||
null)
|
||||
return
|
||||
umbracoXML.GetElementById(nodeId.ToString()).SelectSingleNode(string.Format(xpath, alias)).ChildNodes[0].
|
||||
Value; //.Value + "*";
|
||||
else
|
||||
return string.Empty;
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,6 @@ namespace Umbraco.Tests.TestHelpers
|
||||
settings.Setup(x => x.RequestHandler.AddTrailingSlash).Returns(true);
|
||||
settings.Setup(x => x.RequestHandler.UseDomainPrefixes).Returns(false);
|
||||
settings.Setup(x => x.RequestHandler.CharCollection).Returns(RequestHandlerElement.GetDefaultCharReplacements());
|
||||
settings.Setup(x => x.Content.UmbracoLibraryCacheDuration).Returns(1800);
|
||||
settings.Setup(x => x.WebRouting.UrlProviderMode).Returns("AutoLegacy");
|
||||
settings.Setup(x => x.Templates.DefaultRenderingEngine).Returns(RenderingEngine.Mvc);
|
||||
settings.Setup(x => x.Providers.DefaultBackOfficeUserProvider).Returns("UsersMembershipProvider");
|
||||
|
||||
@@ -78,9 +78,6 @@
|
||||
<![CDATA[<a id="umbracoPreviewBadge" style="position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{0}/assets/img/preview-mode-badge.png') no-repeat;" href="#" OnClick="javascript:window.top.location.href = '{0}/endPreview.aspx?redir={1}'"><span style="display:none;">In Preview Mode - click to end</span></a>
|
||||
]]></PreviewBadge>
|
||||
|
||||
<!-- Cache cycle of Media and Member data fetched from the umbraco.library methods -->
|
||||
<!-- In seconds. 0 will disable cache -->
|
||||
<UmbracoLibraryCacheDuration>1800</UmbracoLibraryCacheDuration>
|
||||
|
||||
<!-- Url Resolving ensures that all links works if you run Umbraco in virtual directories -->
|
||||
<!-- Setting this to true can increase render time for pages with a large number of links -->
|
||||
|
||||
@@ -493,69 +493,88 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
/// <returns></returns>
|
||||
private IEnumerable<IPublishedContent> GetChildrenMedia(int parentId, XPathNavigator xpath = null)
|
||||
{
|
||||
|
||||
//if there is no navigator, try examine first, then re-look it up
|
||||
if (xpath == null)
|
||||
if (xpath != null)
|
||||
{
|
||||
var searchProvider = GetSearchProviderSafe();
|
||||
return ToIPublishedContent(parentId, xpath);
|
||||
}
|
||||
|
||||
if (searchProvider != null)
|
||||
var searchProvider = GetSearchProviderSafe();
|
||||
|
||||
if (searchProvider != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
//first check in Examine as this is WAY faster
|
||||
var criteria = searchProvider.CreateCriteria("media");
|
||||
|
||||
var filter = criteria.ParentId(parentId).Not().Field(UmbracoExamineIndexer.IndexPathFieldName, "-1,-21,".MultipleCharacterWildcard());
|
||||
//the above filter will create a query like this, NOTE: That since the use of the wildcard, it automatically escapes it in Lucene.
|
||||
//+(+parentId:3113 -__Path:-1,-21,*) +__IndexType:media
|
||||
|
||||
// sort with the Sort field (updated for 8.0)
|
||||
var results = searchProvider.Search(
|
||||
filter.And().OrderBy(new SortableField("sortOrder", SortType.Int)).Compile());
|
||||
|
||||
if (results.Any())
|
||||
{
|
||||
//first check in Examine as this is WAY faster
|
||||
var criteria = searchProvider.CreateCriteria("media");
|
||||
|
||||
var filter = criteria.ParentId(parentId).Not().Field(UmbracoExamineIndexer.IndexPathFieldName, "-1,-21,".MultipleCharacterWildcard());
|
||||
//the above filter will create a query like this, NOTE: That since the use of the wildcard, it automatically escapes it in Lucene.
|
||||
//+(+parentId:3113 -__Path:-1,-21,*) +__IndexType:media
|
||||
|
||||
// sort with the Sort field (updated for 8.0)
|
||||
var results = searchProvider.Search(
|
||||
filter.And().OrderBy(new SortableField("sortOrder", SortType.Int)).Compile());
|
||||
|
||||
if (results.Any())
|
||||
// var medias = results.Select(ConvertFromSearchResult);
|
||||
var medias = results.Select(x =>
|
||||
{
|
||||
// var medias = results.Select(ConvertFromSearchResult);
|
||||
var medias = results.Select(x =>
|
||||
{
|
||||
int nid;
|
||||
if (int.TryParse(x["__NodeId"], out nid) == false && int.TryParse(x["NodeId"], out nid) == false)
|
||||
throw new Exception("Failed to extract NodeId from search result.");
|
||||
var cacheValues = GetCacheValues(nid, id => ConvertFromSearchResult(x));
|
||||
return CreateFromCacheValues(cacheValues);
|
||||
});
|
||||
int nid;
|
||||
if (int.TryParse(x["__NodeId"], out nid) == false && int.TryParse(x["NodeId"], out nid) == false)
|
||||
throw new Exception("Failed to extract NodeId from search result.");
|
||||
var cacheValues = GetCacheValues(nid, id => ConvertFromSearchResult(x));
|
||||
return CreateFromCacheValues(cacheValues);
|
||||
});
|
||||
|
||||
return medias;
|
||||
}
|
||||
|
||||
//if there's no result then return null. Previously we defaulted back to library.GetMedia below
|
||||
//but this will always get called for when we are getting descendents since many items won't have
|
||||
//children and then we are hitting the database again!
|
||||
//So instead we're going to rely on Examine to have the correct results like it should.
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
return medias;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
|
||||
//See this thread: http://examine.cdodeplex.com/discussions/264341
|
||||
//Catch the exception here for the time being, and just fallback to GetMedia
|
||||
}
|
||||
}
|
||||
|
||||
//falling back to get media
|
||||
|
||||
var media = library.GetMedia(parentId, true);
|
||||
if (media?.Current != null)
|
||||
{
|
||||
xpath = media.Current;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if there's no result then return null. Previously we defaulted back to library.GetMedia below
|
||||
//but this will always get called for when we are getting descendents since many items won't have
|
||||
//children and then we are hitting the database again!
|
||||
//So instead we're going to rely on Examine to have the correct results like it should.
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
|
||||
//See this thread: http://examine.cdodeplex.com/discussions/264341
|
||||
//Catch the exception here for the time being, and just fallback to GetMedia
|
||||
}
|
||||
}
|
||||
|
||||
//falling back to get media
|
||||
var media = Current.Services.MediaService.GetById(parentId);
|
||||
if (media == null)
|
||||
{
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
|
||||
var serialized = EntityXmlSerializer.Serialize(
|
||||
Current.Services.MediaService,
|
||||
Current.Services.DataTypeService,
|
||||
Current.Services.UserService,
|
||||
Current.Services.LocalizationService,
|
||||
Current.UrlSegmentProviders,
|
||||
media,
|
||||
true);
|
||||
|
||||
var mediaIterator = serialized.CreateNavigator().Select("/");
|
||||
|
||||
if (mediaIterator.Current == null)
|
||||
{
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
xpath = mediaIterator.Current;
|
||||
|
||||
return ToIPublishedContent(parentId, xpath);
|
||||
}
|
||||
|
||||
|
||||
internal IEnumerable<IPublishedContent> ToIPublishedContent(int parentId, XPathNavigator xpath)
|
||||
{
|
||||
var mediaList = new List<IPublishedContent>();
|
||||
|
||||
// this is so bad, really
|
||||
@@ -578,32 +597,10 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
mediaList.Add(CreateFromCacheValues(cacheValues));
|
||||
}
|
||||
|
||||
////The xpath might be the whole xpath including the current ones ancestors so we need to select the current node
|
||||
//var item = xpath.Select("//*[@id='" + parentId + "']");
|
||||
//if (item.Current == null)
|
||||
//{
|
||||
// return Enumerable.Empty<IPublishedContent>();
|
||||
//}
|
||||
//var children = item.Current.SelectChildren(XPathNodeType.Element);
|
||||
|
||||
//foreach(XPathNavigator x in children)
|
||||
//{
|
||||
// //NOTE: I'm not sure why this is here, it is from legacy code of ExamineBackedMedia, but
|
||||
// // will leave it here as it must have done something!
|
||||
// if (x.Name != "contents")
|
||||
// {
|
||||
// //make sure it's actually a node, not a property
|
||||
// if (!string.IsNullOrEmpty(x.GetAttribute("path", "")) &&
|
||||
// !string.IsNullOrEmpty(x.GetAttribute("id", "")))
|
||||
// {
|
||||
// mediaList.Add(ConvertFromXPathNavigator(x));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
return mediaList;
|
||||
}
|
||||
|
||||
|
||||
internal void Resync()
|
||||
{
|
||||
// clear recursive properties cached by XmlPublishedContent.GetProperty
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace umbraco
|
||||
{
|
||||
/// <summary>
|
||||
/// Function library for umbraco. Includes various helper-methods and methods to
|
||||
/// save and load data from umbraco.
|
||||
///
|
||||
/// Especially usefull in XSLT where any of these methods can be accesed using the umbraco.library name-space. Example:
|
||||
/// <xsl:value-of select="umbraco.library:NiceUrl(@id)"/>
|
||||
/// </summary>
|
||||
[Obsolete("v8.kill.kill")]
|
||||
public class library
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a media object as an xml object
|
||||
/// </summary>
|
||||
/// <param name="MediaId">The identifier of the media object to be returned</param>
|
||||
/// <param name="deep">If true, children of the media object is returned</param>
|
||||
/// <returns>An umbraco xml node of the media (same format as a document node)</returns>
|
||||
public static XPathNodeIterator GetMedia(int MediaId, bool deep)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration > 0)
|
||||
{
|
||||
var xml = Current.ApplicationCache.RuntimeCache.GetCacheItem<XElement>(
|
||||
$"{CacheKeys.MediaCacheKey}_{MediaId}_{deep}",
|
||||
timeout: TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration),
|
||||
getCacheItem: () => GetMediaDo(MediaId, deep).Item1);
|
||||
|
||||
if (xml != null)
|
||||
{
|
||||
//returning the root element of the Media item fixes the problem
|
||||
return xml.CreateNavigator().Select("/");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var xml = GetMediaDo(MediaId, deep).Item1;
|
||||
|
||||
//returning the root element of the Media item fixes the problem
|
||||
return xml.CreateNavigator().Select("/");
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Current.Logger.Error<library>("An error occurred looking up media", ex);
|
||||
}
|
||||
|
||||
Current.Logger.Debug<library>(() => $"No media result for id {MediaId}");
|
||||
|
||||
var errorXml = new XElement("error", string.Format("No media is maching '{0}'", MediaId));
|
||||
return errorXml.CreateNavigator().Select("/");
|
||||
}
|
||||
|
||||
|
||||
private static Tuple<XElement, string> GetMediaDo(int mediaId, bool deep)
|
||||
{
|
||||
var media = Current.Services.MediaService.GetById(mediaId);
|
||||
if (media == null) return null;
|
||||
|
||||
var serialized = EntityXmlSerializer.Serialize(
|
||||
Current.Services.MediaService,
|
||||
Current.Services.DataTypeService,
|
||||
Current.Services.UserService,
|
||||
Current.Services.LocalizationService,
|
||||
Current.UrlSegmentProviders,
|
||||
media,
|
||||
deep);
|
||||
return Tuple.Create(serialized, media.Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user