internal IPublishedContent ConvertFromSearchResult(SearchResult searchResult) { //NOTE: Some fields will not be included if the config section for the internal index has been //mucked around with. It should index everything and so the index definition should simply be: // <IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Internal/" /> var values = new Dictionary <string, string>(searchResult.Fields); //we need to ensure some fields exist, because of the above issue if (!new [] { "template", "templateId" }.Any(values.ContainsKey)) { values.Add("template", 0.ToString()); } if (!new[] { "sortOrder" }.Any(values.ContainsKey)) { values.Add("sortOrder", 0.ToString()); } if (!new[] { "urlName" }.Any(values.ContainsKey)) { values.Add("urlName", ""); } if (!new[] { "nodeType" }.Any(values.ContainsKey)) { values.Add("nodeType", 0.ToString()); } if (!new[] { "creatorName" }.Any(values.ContainsKey)) { values.Add("creatorName", ""); } if (!new[] { "writerID" }.Any(values.ContainsKey)) { values.Add("writerID", 0.ToString()); } if (!new[] { "creatorID" }.Any(values.ContainsKey)) { values.Add("creatorID", 0.ToString()); } if (!new[] { "createDate" }.Any(values.ContainsKey)) { values.Add("createDate", default(DateTime).ToString("yyyy-MM-dd HH:mm:ss")); } if (!new[] { "level" }.Any(values.ContainsKey)) { values.Add("level", values["__Path"].Split(',').Length.ToString()); } var content = new DictionaryPublishedContent(values, d => d.ParentId != -1 //parent should be null if -1 ? GetUmbracoMedia(d.ParentId) : null, //callback to return the children of the current node d => GetChildrenMedia(d.Id), GetProperty, true); return(PublishedContentModelFactory.CreateModel(content)); }
internal IPublishedContent CreateFromCacheValues(CacheValues cacheValues) { var content = new DictionaryPublishedContent( cacheValues.Values, parentId => parentId < 0 ? null : GetUmbracoMedia(parentId), GetChildrenMedia, GetProperty, cacheValues.XPath, // though, outside of tests, that should be null cacheValues.FromExamine ); return(content.CreateModel()); }
/// <summary> /// We will need to first check if the document was loaded by Examine, if so we'll need to check if this property exists /// in the results, if it does not, then we'll have to revert to looking up in the db. /// </summary> /// <param name="dd"> </param> /// <param name="alias"></param> /// <returns></returns> private IPublishedProperty GetProperty(DictionaryPublishedContent dd, string alias) { if (dd.LoadedFromExamine) { //if this is from Examine, lets check if the alias does not exist on the document if (dd.Properties.All(x => x.PropertyTypeAlias != alias)) { //ok it doesn't exist, we might assume now that Examine didn't index this property because the index is not set up correctly //so before we go loading this from the database, we can check if the alias exists on the content type at all, this information //is cached so will be quicker to look up. if (dd.Properties.Any(x => x.PropertyTypeAlias == UmbracoContentIndexer.NodeTypeAliasFieldName)) { // so in dd.Properties, there is an IPublishedProperty with property type alias "__NodeTypeAlias" and // that special property would contain the node type alias, which we use to get "aliases & names". That // special property is going to be a PropertyResult (with Value == DataValue) and we // want its value in the most simple way = it is OK to use DataValue here. var aliasesAndNames = ContentType.GetAliasesAndNames(dd.Properties.First(x => x.PropertyTypeAlias.InvariantEquals(UmbracoContentIndexer.NodeTypeAliasFieldName)).DataValue.ToString()); if (aliasesAndNames != null) { if (!aliasesAndNames.ContainsKey(alias)) { //Ok, now we know it doesn't exist on this content type anyways return(null); } } } //if we've made it here, that means it does exist on the content type but not in examine, we'll need to query the db :( var media = global::umbraco.library.GetMedia(dd.Id, true); if (media != null && media.Current != null) { media.MoveNext(); var mediaDoc = ConvertFromXPathNavigator(media.Current); return(mediaDoc.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(alias))); } } } //We've made it here which means that the value is stored in the Examine index. //We are going to check for a special field however, that is because in some cases we store a 'Raw' //value in the index such as for xml/html. var rawValue = dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(UmbracoContentIndexer.RawFieldPrefix + alias)); return(rawValue ?? dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(alias))); }
/// <summary> /// We will need to first check if the document was loaded by Examine, if so we'll need to check if this property exists /// in the results, if it does not, then we'll have to revert to looking up in the db. /// </summary> /// <param name="dd"> </param> /// <param name="alias"></param> /// <returns></returns> private IPublishedProperty GetProperty(DictionaryPublishedContent dd, string alias) { //lets check if the alias does not exist on the document. //NOTE: Examine will not index empty values and we do not output empty XML Elements to the cache - either of these situations // would mean that the property is missing from the collection whether we are getting the value from Examine or from the library media cache. if (dd.Properties.All(x => x.PropertyTypeAlias.InvariantEquals(alias) == false)) { return(null); } if (dd.LoadedFromExamine) { //We are going to check for a special field however, that is because in some cases we store a 'Raw' //value in the index such as for xml/html. var rawValue = dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(UmbracoContentIndexer.RawFieldPrefix + alias)); return(rawValue ?? dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(alias))); } //if its not loaded from examine, then just return the property return(dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(alias))); }
internal IPublishedContent ConvertFromXPathNavigator(XPathNavigator xpath) { if (xpath == null) { throw new ArgumentNullException("xpath"); } var values = new Dictionary <string, string> { { "nodeName", xpath.GetAttribute("nodeName", "") } }; if (!UmbracoSettings.UseLegacyXmlSchema) { values.Add("nodeTypeAlias", xpath.Name); } var result = xpath.SelectChildren(XPathNodeType.Element); //add the attributes e.g. id, parentId etc if (result.Current != null && result.Current.HasAttributes) { if (result.Current.MoveToFirstAttribute()) { //checking for duplicate keys because of the 'nodeTypeAlias' might already be added above. if (!values.ContainsKey(result.Current.Name)) { values.Add(result.Current.Name, result.Current.Value); } while (result.Current.MoveToNextAttribute()) { if (!values.ContainsKey(result.Current.Name)) { values.Add(result.Current.Name, result.Current.Value); } } result.Current.MoveToParent(); } } //add the user props while (result.MoveNext()) { if (result.Current != null && !result.Current.HasAttributes) { string value = result.Current.Value; if (string.IsNullOrEmpty(value)) { if (result.Current.HasAttributes || result.Current.SelectChildren(XPathNodeType.Element).Count > 0) { value = result.Current.OuterXml; } } values.Add(result.Current.Name, value); } } var content = new DictionaryPublishedContent(values, d => d.ParentId != -1 //parent should be null if -1 ? GetUmbracoMedia(d.ParentId) : null, //callback to return the children of the current node based on the xml structure already found d => GetChildrenMedia(d.Id, xpath), GetProperty, false); return(PublishedContentModelFactory.CreateModel(content)); }