/// <summary> /// Given an Item, this will return the name of the Index that it will use to search on /// </summary> /// <returns>The Name of the Index</returns> /// <param name="item">The item which will be used to determine (based off the item path) which index will be used for the search</param> public static string GetContextIndex(Item item) { #if NET40 Contract.Requires(item.IsNotNull()); #else Assert.ArgumentNotNull(item, "item"); #endif string dbName = item.Database.Name; var itemPath = item.Paths.FullPath; //try to match with dbName RemoteSearchManager.Initialize(); foreach (var index in RemoteSearchManager.Indexes) { if (IsIndexMatch("/sitecore/search/remoteconfiguration/indexes/index[@id='" + (index as RemoteIndex).Name + "']", itemPath, dbName)) return (index as RemoteIndex).Name; } InMemorySearchManager.Initialize(); foreach (var index in InMemorySearchManager.Indexes) { if (IsIndexMatch("/sitecore/search/inmemoryconfiguration/indexes/index[@id='" + (index as InMemoryIndex).Name + "']", itemPath, dbName)) return (index as InMemoryIndex).Name; } foreach (var index in Sitecore.Search.SearchManager.Indexes) { if (IsIndexMatch("/sitecore/search/configuration/indexes/index[@id='" + index.Name + "']", itemPath, dbName)) return index.Name; } //try to match WITHOUT dbName foreach (var index in RemoteSearchManager.Indexes) { if (IsIndexMatch("/sitecore/search/remoteconfiguration/indexes/index[@id='" + (index as RemoteIndex).Name + "']", itemPath)) return (index as RemoteIndex).Name; } foreach (var index in InMemorySearchManager.Indexes) { if (IsIndexMatch("/sitecore/search/inmemoryconfiguration/indexes/index[@id='" + (index as InMemoryIndex).Name + "']", itemPath)) return (index as InMemoryIndex).Name; } foreach (var index in Sitecore.Search.SearchManager.Indexes) { if (IsIndexMatch("/sitecore/search/configuration/indexes/index[@id='" + index.Name + "']", itemPath)) return index.Name; } return "itembuckets_sitecore"; }
/// <summary> /// Determines if an item should be deleted on creation of a bucket /// </summary> /// <returns>True if deleting, False if not deleting</returns> /// <param name="item">Item that is being moved</param> private static bool ShouldDeleteInCreationOfBucket(Item item) { #if NET40 Contract.Requires(item.IsNotNull()); #else Assert.ArgumentNotNull(item, "item"); #endif return item.TemplateID.ToString().Equals(Constants.BucketFolder); }
/// <summary> /// The item that is passed to this method will now be made into a Bucket and all items under it will be automatically organised and hidden. /// </summary> /// <param name="item">The item that is being turned into a Bucket</param> /// <param name="callBack">Callback function that gets run once the Bucket Process has finised</param> public static void CreateBucket(Item item, Action<Item> callBack) { #if NET40 Contract.Requires(item.IsNotNull()); #else Assert.ArgumentNotNull(item, "item"); #endif var bucketableItems = item.Children.ToList().Where(child => child.Template.IsBucketTemplateCheck()); using(new EditContext(item, SecurityCheck.Disable)) { item.IsBucketItemCheckBox().Checked = true; } long count = 0; foreach (var child in bucketableItems) { if (Context.Job.IsNotNull()) { Context.Job.Status.Processed = count; } if (ShouldDeleteInCreationOfBucket(child)) { child.Children.ToList().ForEach(MakeIntoBucket); if (Context.Job.IsNotNull()) { Context.Job.Status.Messages.Add("Deleting item " + child.Paths.FullPath); } } else { MoveItemToDateFolder(item, child); if (Context.Job.IsNotNull()) { Context.Job.Status.Messages.Add("Moving item " + child.Paths.FullPath); } } count++; } using (new SecurityDisabler()) { item.GetChildren().ToList().ForEach(HideItem); } callBack(item); }
/// <summary> /// Searches the with parameter occurrence. /// </summary> /// <param name="startLocationItem">The start location item.</param> /// <param name="refinements">The refinements.</param> /// <param name="hitCount">The hit count.</param> /// <param name="relatedIds">The related ids.</param> /// <param name="indexName">Name of the index.</param> /// <param name="text">The text.</param> /// <param name="templates">The templates.</param> /// <param name="location">The location.</param> /// <param name="language">The language.</param> /// <param name="id">The id.</param> /// <param name="sortField">The sort field.</param> /// <param name="sortDirection">The sort direction.</param> /// <param name="itemName">Name of the item.</param> /// <param name="startDate">The start date.</param> /// <param name="endDate">The end date.</param> /// <param name="numberOfItemsToReturn">The number of items to return.</param> /// <param name="pageNumber">The page number.</param> /// <param name="customParametersOccurance">The custom parameters occurrence.</param> /// <returns></returns> public static IEnumerable<SitecoreItem> SearchWithParameterOccurance( Item startLocationItem, SafeDictionary<string> refinements, out int hitCount, string relatedIds = "", string indexName = "itembuckets_buckets", string text = "", string templates = "", string location = "", string language = "en", string id = "", string sortField = "", string sortDirection = "", string itemName = "", string startDate = "", string endDate = "", int numberOfItemsToReturn = 20, int pageNumber = 1, QueryOccurance customParametersOccurance = QueryOccurance.Must) { Contract.Requires(startLocationItem.IsNotNull()); using (var searcher = new IndexSearcher(indexName)) { DateRangeSearchParam dateSearchParam = GetFullParameters( startLocationItem, refinements, relatedIds, indexName = "itembuckets_buckets", text, templates, location, language, id, sortField, sortDirection, itemName, startDate, endDate, numberOfItemsToReturn, pageNumber, customParametersOccurance); if (dateSearchParam.IsNull()) { hitCount = 0; return new List<SitecoreItem>(); } return GetItemsFromSearcher(searcher, dateSearchParam, out hitCount); } }
/// <summary> /// Moves an Item to a Date Format Folder. Will create the folder based off the Date if the folder does not exist. /// </summary> /// <param name="topParent">Destination Folder</param> /// <param name="toMove">Item that is being moved</param> private static void MoveItemToDateFolder(Item topParent, Item toMove) { #if NET40 Contract.Requires(topParent.IsNotNull()); Contract.Requires(toMove.IsNotNull()); #else Assert.ArgumentNotNull(topParent, "topParent"); Assert.ArgumentNotNull(toMove, "toMove"); #endif foreach (var item in toMove.Children.ToList()) { MoveItemToDateFolder(topParent, item); } if (ShouldMoveToDateFolder(toMove)) { using (new EditContext(toMove, SecurityCheck.Disable)) { if (toMove.Fields["__BucketParentRef"].IsNotNull()) { toMove.Fields["__BucketParentRef"].Value = toMove.Parent.ID.ToString(); } } var destinationFolder = CreateAndReturnDateFolderDestination(topParent, toMove); var returnValue = ItemManager.MoveItem(toMove, destinationFolder); // TODO: This should be handled by MoveItem. Remove this check once Logging is placed into ItemManager code. if (!returnValue) { Log.Error("There has been an issue moving the item from " + toMove + " to " + destinationFolder, returnValue); } } else if (ShouldDeleteInCreationOfBucket(toMove)) { toMove.Delete(); } }
/// <summary> /// An extension of Item that allows you to launch a Search from an item /// </summary> /// <returns>List of Results of Type IEnumerable List of SitecoreItem (which implements IItem)</returns> /// <param name="startLocationItem">The start location of the search</param> /// <param name="hitCount">This will output the hitCount of the search</param> /// <param name="relatedIds">Pipe delimited string of Id to query by Links to and from items</param> /// <param name="indexName">Force query to run on a particular index</param> /// <param name="text">The raw text query</param> /// <param name="templates">Pipe delimited string of Id of Templates</param> /// <param name="location">Override the location of the search with an Id</param> /// <param name="language">Query by the two letter ISO country code</param> /// <param name="id">Query by ID</param> /// <param name="sortField">Sort query by field (must be in index)</param> /// <param name="sortDirection">Sort in either "asc" or "desc"</param> /// <param name="itemName">Query by item name</param> /// <param name="startDate">mm/dd/yyyy format of start date</param> /// <param name="endDate">mm/dd/yyyy format of end date</param> /// <param name="numberOfItemsToReturn">0-XXXXXX (The bigger this number is the less performant it will be)</param> /// <param name="pageNumber">Go directly to a Page of results</param> /// <example>BucketManager.Search(Sitecore.Context.Item, text: "Tim", templates: "TemplateGUID")</example> /// <example>BucketManager.Search(Sitecore.Context.Item, text: "Tim", templates: "TemplateGUID", sortField: "_name")</example> public static IEnumerable<SitecoreItem> Search(Item startLocationItem, out int hitCount, IEnumerable<Guid> relatedIds = null, string indexName = "itembuckets_buckets", string text = "", IEnumerable<Guid> templates = null, string location = "", string language = "en", string id = "", string sortField = "", string sortDirection = "", string itemName = "", string startDate = "", string endDate = "", int numberOfItemsToReturn = 20, int pageNumber = 1) { #if NET40 Contract.Requires(startLocationItem.IsNotNull()); #else Assert.ArgumentNotNull(startLocationItem, "startLocationItem"); #endif using (var searcher = new IndexSearcher(indexName)) { var culture = CultureInfo.CreateSpecificCulture("en-US"); var startDateOut = DateTime.Now; var endDateOut = DateTime.Now.AddDays(1); var startFlag = true; var endFlag = true; if (!DateTime.TryParse(startDate, culture, DateTimeStyles.None, out startDateOut)) { startDateOut = DateTime.Now; startFlag = false; } if (!DateTime.TryParse(endDate, culture, DateTimeStyles.None, out endDateOut)) { endDateOut = DateTime.Now.AddDays(1); endFlag = false; } if (startLocationItem.IsNull()) { Log.Warn("You are trying to run an Search on an item that has a start location of null", null); hitCount = 0; return new List<SitecoreItem>(); } var dateSearchParam = new DateRangeSearchParam { ItemName = itemName, FullTextQuery = text, RelatedIds = relatedIds, TemplateIds = templates, LocationIds = new [] {startLocationItem.ID.ToGuid()}, Language = language, ID = id, SortDirection = sortDirection, SortByField = sortField, PageSize = numberOfItemsToReturn, PageNumber = pageNumber }; if (startFlag || endFlag) { dateSearchParam.Ranges = new List<DateRangeSearchParam.DateRangeField> { new DateRangeSearchParam.DateRangeField( SearchFieldIDs.CreatedDate, startDateOut, endDateOut) { InclusiveStart = true, InclusiveEnd = true } }; } var keyValuePair = searcher.GetItems(dateSearchParam); hitCount = keyValuePair.Key; return keyValuePair.Value; } }
/// <summary> /// Creates a Date formatted Path to an item and then returns the item being created /// </summary> /// <returns>This will return the created Item</returns> /// <param name="topParent">Gets the root of where this item will be created</param> /// <param name="itemToMove">Determines the item that is moving</param> internal static Item CreateAndReturnDateFolderDestination(Item topParent, Item itemToMove) { #if NET40 Contract.Requires(topParent.IsNotNull()); Contract.Requires(itemToMove.IsNotNull()); #else Assert.ArgumentNotNull(topParent, "topParent"); Assert.ArgumentNotNull(itemToMove, "itemToMove"); #endif return CreateAndReturnDateFolderDestination(topParent, itemToMove.Statistics.Created); }
/// <summary> /// Given and item, it will determine if it lives within a Bucket Container /// </summary> /// <returns>If true then the item in question lives within a bucket and is hidden from the UI</returns> /// <param name="item">Item Id</param> /// <param name="database">Context Database</param> public static bool IsItemContainedWithinBucket(Item item, Database database) { Contract.Requires(item.IsNotNull()); Contract.Requires(database.IsNotNull()); return item.Axes.GetAncestors().Any(a => a.IsBucketItemCheck()); }
/// <summary> /// Creates a Date formatted Path to an item and then returns the item being created /// </summary> /// <returns>This will return the created Item</returns> /// <param name="topParent">Gets the root of where this item will be created</param> /// <param name="itemToMove">Determines the item that is moving</param> internal static Item CreateAndReturnDateFolderDestination(Item topParent, Item itemToMove) { Contract.Requires(topParent.IsNotNull()); Contract.Requires(itemToMove.IsNotNull()); return CreateAndReturnDateFolderDestination(topParent, itemToMove.Statistics.Created); }
/// <summary> /// Given an Item, this will return the name of the Index that it will use to search on /// </summary> /// <returns>The Name of the Index</returns> /// <param name="item">The item which will be used to determine (based off the item path) which index will be used for the search</param> public static string GetContextIndex(Item item) { Contract.Requires(item.IsNotNull()); if (item.IsNotNull()) { RemoteSearchManager.Initialize(); foreach (var index in from index in RemoteSearchManager.Indexes let indexConfigurationNode = Configuration.Factory.GetConfigNode( "/sitecore/search/remoteconfiguration/indexes/index[@id='" + (index as RemoteIndex).Name + "']/locations/ItemBucketSearch/Root") where indexConfigurationNode != null where item.Paths.FullPath.StartsWith(indexConfigurationNode.InnerText) select index) { return (index as RemoteIndex).Name; } InMemorySearchManager.Initialize(); foreach (var index in from index in InMemorySearchManager.Indexes let indexConfigurationNode = Configuration.Factory.GetConfigNode( "/sitecore/search/inmemoryconfiguration/indexes/index[@id='" + (index as InMemoryIndex).Name + "']/locations/ItemBucketSearch/Root") where indexConfigurationNode != null where item.Paths.FullPath.StartsWith(indexConfigurationNode.InnerText) select index) { return (index as InMemoryIndex).Name; } foreach (var index in from index in Sitecore.Search.SearchManager.Indexes let indexConfigurationNode = Configuration.Factory.GetConfigNode( "/sitecore/search/configuration/indexes/index[@id='" + index.Name + "']/locations/ItemBucketSearch/Root") where indexConfigurationNode != null where item.Paths.FullPath.StartsWith(indexConfigurationNode.InnerText) select index) { return index.Name; } } return "itembuckets_buckets"; }
/// <summary> /// Given an Item, this will determine if this Item is a Bucket Container /// </summary> /// <returns>Returns true if this item is a Bucket</returns> /// <param name="item">Item being checked to see if it is a bucket or not</param> public static bool IsBucket(Item item) { Contract.Requires(item.IsNotNull()); return item.IsBucketItemCheck(); }
/// <summary> /// Determines if an item should be deleted on creation of a bucket /// </summary> /// <returns>True if deleting, False if not deleting</returns> /// <param name="item">Item that is being moved</param> private static bool ShouldDeleteInCreationOfBucket(Item item) { Contract.Requires(item.IsNotNull()); return item.TemplateID.ToString().Equals(Constants.BucketFolder); }
/// <summary> /// Given a destination Item, this will create the structures on this item to host unstructured data /// </summary> /// <returns>This will return the destination parent Item that hosts the new Item</returns> /// <param name="topParent">Gets the root of where this item will be created</param> /// <param name="childItemCreationDateTime">Determins the folder that the item will be created within</param> internal static Item CreateAndReturnDateFolderDestination(Item topParent, DateTime childItemCreationDateTime) { Contract.Requires(topParent.IsNotNull()); Contract.Requires(childItemCreationDateTime.IsNotNull()); var database = topParent.Database; var dateFolder = childItemCreationDateTime.ToString(Config.BucketFolderPath); DateTimeFormatInfo dateTimeInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat; if (dateTimeInfo.DateSeparator != Constants.ContentPathSeperator) { Log.Info("ItemBuckets. DateTimeFormat inconsistency. Current date separator is " + dateTimeInfo.DateSeparator + " and time separator is " + dateTimeInfo.TimeSeparator + ". Relative path to folder is " + dateFolder, new object()); dateFolder = dateFolder.Replace(dateTimeInfo.DateSeparator, Constants.ContentPathSeperator).Replace(dateTimeInfo.TimeSeparator,Constants.ContentPathSeperator); } var destinationFolderPath = topParent.Paths.FullPath + Constants.ContentPathSeperator + dateFolder; Item destinationFolderItem; // TODO: Use the Path Cache to determine if the path exists instead of looking it up on the item everytime I create an item (will be noticed if programmatically adding items) if ((destinationFolderItem = database.GetItem(destinationFolderPath)).IsNull()) { var containerTemplate = database.Templates[new TemplateID(Config.ContainerTemplateId)]; destinationFolderItem = database.CreateItemPath(destinationFolderPath, containerTemplate, containerTemplate); } using (new SecurityDisabler()) { topParent.GetChildren().ToList().ForEach(HideItem); } Contract.Ensures(destinationFolderItem.IsNotNull()); return destinationFolderItem; }
/// <summary> /// Renders the list item as Html /// </summary> /// <param name="item"></param> /// <param name="itemId"></param> /// <param name="fieldId"></param> /// <param name="useFieldGutter"></param> /// <returns></returns> public override string Render(Item item, string itemId, string fieldId, bool useFieldGutter) { //defaults string icon = "/sitecore modules/shell/field suite/document_error.png"; //check item if (item.IsNull()) { return RenderItemNotFound(itemId, fieldId); } //disable items if the form is read only) if (ReadOnly) { ItemClick = string.Empty; ButtonClick = string.Empty; } string templateName = string.Empty; //set to items properties if (item.IsNotNull()) { icon = item.Appearance.Icon; TemplateItem template = item.Template; if (!string.IsNullOrEmpty(template.Name)) { templateName = template.Name; } } //check and retrieve parameters string imgElement = string.Empty; if (Parameters != null && Parameters.Count > 0) { imgElement = Parameters[0] as string; } string fieldGutterHtml = string.Empty; IFieldGutterProcessor fieldGutterProcessor = FieldGutterProcessorFactory.GetProcessor(); if (fieldGutterProcessor != null) { string html = fieldGutterProcessor.Process(new FieldGutterArgs(item, fieldId)); if (!string.IsNullOrEmpty(html)) { fieldGutterHtml = html; } } return string.Format(HtmlTemplate, item.ID, fieldGutterHtml, imgElement, templateName, Images.GetImage(icon, 0x10, 0x10, "absmiddle", "0px 4px 0px 0px", templateName), Text, HoverText, ItemClick, SelectedClass); }
/// <summary> /// Given an Item, this will determine if this Item is a Bucket Container /// </summary> /// <returns>Returns true if this item is a Bucket</returns> /// <param name="item">Item being checked to see if it is a bucket or not</param> public static bool IsBucket(Item item) { #if NET40 Contract.Requires(item.IsNotNull()); #else Assert.ArgumentNotNull(item, "item"); #endif return item.IsBucketItemCheck(); }
/// <summary> /// Hides an Item /// </summary> /// <param name="firstLevelChild">Gets the root of where this item will be created</param> private static void HideItem(Item firstLevelChild) { Contract.Requires(firstLevelChild.IsNotNull()); if (firstLevelChild.Template.IsBucketTemplateCheck() || firstLevelChild.TemplateID == Config.BucketTemplateId) { firstLevelChild.HideItem(); } }
/// <summary> /// Given and item, it will determine if it lives within a Bucket Container /// </summary> /// <returns>If true then the item in question lives within a bucket and is hidden from the UI</returns> /// <param name="item">Item Id</param> /// <param name="database">Context Database</param> public static bool IsItemContainedWithinBucket(Item item, Database database) { #if NET40 Contract.Requires(item.IsNotNull()); Contract.Requires(database.IsNotNull()); #else Assert.ArgumentNotNull(item, "item"); Assert.ArgumentNotNull(database, "database"); #endif return item.Axes.GetAncestors().Any(a => a.IsBucketItemCheck()); }
private string GetTemplateIconHtml(Item item, string fieldId) { string templateName = string.Empty; string imagePath = string.Empty; if (item.IsNotNull() && item.Template != null && !string.IsNullOrEmpty(item.Template.Icon)) { templateName = item.TemplateName; imagePath = Themes.MapTheme(item.Template.Icon); } else { imagePath = "/sitecore/images/blank.gif"; } string tempateIconPath = string.Format("<img width=\"16\" height=\"16\" border=\"0\" align=\"middle\" alt=\"{1}\" style=\"margin:0px 4px 0px 0px\" id=\"{2}_templateIconImg\" src=\"{0}\"/>", imagePath, templateName, fieldId); return string.Format("<div id=\"{1}_templateIconDiv\" class=\"droplinkTemplateIconItem\">{0}</div>", tempateIconPath, fieldId); }
/// <summary> /// Given a destination Item, this will create the structures on this item to host unstructured data /// </summary> /// <returns>This will return the destination parent Item that hosts the new Item</returns> /// <param name="topParent">Gets the root of where this item will be created</param> /// <param name="childItemCreationDateTime">Determins the folder that the item will be created within</param> internal static Item CreateAndReturnDateFolderDestination(Item topParent, DateTime childItemCreationDateTime) { #if NET40 Contract.Requires(topParent.IsNotNull()); Contract.Requires(childItemCreationDateTime.IsNotNull()); #else Assert.ArgumentNotNull(topParent, "topParent"); Assert.ArgumentNotNull(childItemCreationDateTime, "childItemCreationDateTime"); #endif var database = topParent.Database; var dateFolder = childItemCreationDateTime.ToString(Config.BucketFolderPath); var destinationFolderPath = topParent.Paths.FullPath + Constants.ContentPathSeperator + dateFolder; Item destinationFolderItem; // TODO: Use the Path Cache to determine if the path exists instead of looking it up on the item everytime I create an item (will be noticed if programmatically adding items) if ((destinationFolderItem = database.GetItem(destinationFolderPath)).IsNull()) { var containerTemplate = database.Templates[new TemplateID(Config.ContainerTemplateId)]; destinationFolderItem = database.CreateItemPath(destinationFolderPath, containerTemplate, containerTemplate); } using (new SecurityDisabler()) { topParent.GetChildren().ToList().ForEach(HideItem); } #if NET40 Contract.Ensures(destinationFolderItem.IsNotNull()); #else Assert.IsTrue(destinationFolderItem.IsNotNull(), "destinationFolderItem cannot be null"); #endif return destinationFolderItem; }
/// <summary> /// Hides an Item /// </summary> /// <param name="firstLevelChild">Gets the root of where this item will be created</param> private static void HideItem(Item firstLevelChild) { #if NET40 Contract.Requires(firstLevelChild.IsNotNull()); #else Assert.ArgumentNotNull(firstLevelChild, "firstLevelChild"); #endif if (firstLevelChild.Template.IsBucketTemplateCheck() || firstLevelChild.TemplateID == Config.BucketTemplateId) { firstLevelChild.HideItem(); } }
/// <summary> /// Turns an item into a Bucket /// </summary> /// <param name="item">Gets the root of where this item will be created</param> internal static void MakeIntoBucket(Item item) { #if NET40 Contract.Requires(item.IsNotNull()); #else Assert.ArgumentNotNull(item, "item"); #endif // TODO: Change to use Tail Recursion to save on CPU and memory foreach (var child in item.Children.ToList()) { if (ShouldDeleteInCreationOfBucket(child)) { child.Children.ToList().ForEach(MakeIntoBucket); } else { MoveItemToDateFolder(item, child); } } }
/// <summary> /// Moves the item to a Date Format Folder. Will create the folder based off the Date if the folder does not exist. /// </summary> /// <param name="topParent">Destination Folder</param> /// <param name="movedItemve">The item that is being moved.</param> private static void MoveItemToDateFolder(Item topParent, Item movedItem) { Contract.Requires(topParent.IsNotNull()); Contract.Requires(movedItem.IsNotNull()); foreach (Item item in movedItem.Children.ToList()) { MoveItemToDateFolder(topParent, item); } if (ShouldMoveToDateFolder(movedItem)) { using (new EditContext(movedItem, SecurityCheck.Disable)) { if (movedItem.Fields["__BucketParentRef"].IsNotNull()) { movedItem.Fields["__BucketParentRef"].Value = movedItem.Parent.ID.ToString(); } } Item destinationFolder = CreateAndReturnDateFolderDestination(topParent, movedItem); bool returnValue = ItemManager.MoveItem(movedItem, destinationFolder); // TODO: This should be handled by MoveItem. Remove this check once Logging is placed into ItemManager code. if (returnValue == false) { Log.Error("There has been an issue moving the item from " + movedItem + " to " + destinationFolder, returnValue); } } else if (ShouldDeleteInCreationOfBucket(movedItem)) { movedItem.Delete(); } }