Exemple #1
0
        public void ShouldRebasePathOfChildren()
        {
            var root = new FakeItem(children: new[] { new FakeItem() }, id: Guid.NewGuid());

            var rebase = new PathRebasingProxyItem(root, "/sitecore/new", Guid.NewGuid());

            rebase.GetChildren().First().Path.Should().Be("/sitecore/new/test item/test item");
            rebase.GetChildren().First().ParentId.Should().Be(root.Id);
        }
Exemple #2
0
        public void ShouldRebasePath()
        {
            var root = new FakeItem();
            var pid  = Guid.NewGuid();

            var rebase = new PathRebasingProxyItem(root, "/sitecore/new", pid);

            rebase.Path.Should().Be("/sitecore/new/test item");
            rebase.ParentId.Should().Be(pid);
        }
        public virtual void MoveItem(ItemDefinition itemDefinition, ItemDefinition destination, CallContext context)
        {
            if (DisableSerialization)
            {
                return;
            }

            Assert.ArgumentNotNull(itemDefinition, "itemDefinition");

            var sourceItem = GetSourceFromId(itemDefinition.ID, true); // we use cache here because we want the old path (no cache would have the new path); TpSync always has old path

            var oldPath = sourceItem.Path;                             // NOTE: we cap the path here, because Sitecore can change the item's path value as we're updating stuff.

            var destinationItem = GetSourceFromId(destination.ID);

            if (destinationItem == null)
            {
                return;                                      // can occur with TpSync on, when this isn't the configuration we're moving for the data store will return null
            }
            // rebase the path to the new destination path (this handles children too)
            var rebasedSourceItem = new PathRebasingProxyItem(sourceItem, destinationItem.Path, destinationItem.Id);

            if (!_predicate.Includes(rebasedSourceItem).IsIncluded)
            {
                // if the destination we are moving to is NOT included for serialization, we delete the existing item from serialization
                var existingItem = _targetDataStore.GetByPathAndId(sourceItem.Path, sourceItem.Id, sourceItem.DatabaseName);

                if (existingItem != null)
                {
                    _targetDataStore.Remove(existingItem);
                    _logger.MovedItemToNonIncludedLocation(_targetDataStore.FriendlyName, existingItem);
                }

                return;
            }

            // this allows us to filter out any excluded children by predicate when the data store moves children
            var predicatedItem = new PredicateFilteredItemData(rebasedSourceItem, _predicate);

            _targetDataStore.MoveOrRenameItem(predicatedItem, oldPath);
            _logger.MovedItem(_targetDataStore.FriendlyName, predicatedItem, destinationItem);
        }
Exemple #4
0
        /*
         * Moving an item involves:
         * - Get the item from the tree, delete
         * - If the new path is included in ANY tree
         *      - Get the serialized parent at the destination
         *      - Get the moved tree from Sitecore, save whole tree (NOTE: we had to update to final path in DP - what about children are those with old or new path?)
         *
         * Renaming an item involves:
         * - The same thing as moving an item
         */
        public virtual void MoveOrRenameItem(IItemData itemWithFinalPath, string oldPath)
        {
            // GET EXISTING ITEM WE'RE MOVING + DESCENDANT PATHS
            var oldPathTree = GetTreeForPath(oldPath, itemWithFinalPath.DatabaseName);
            Dictionary <string, IItemMetadata> oldPathItemAndDescendants;

            var oldPathItem = oldPathTree?.GetItemsByPath(oldPath).FirstOrDefault(item => item.Id == itemWithFinalPath.Id);

            if (oldPathItem != null)
            {
                oldPathItemAndDescendants = oldPathTree.GetDescendants(oldPathItem, false).ToDictionary(item => item.SerializedItemId);
                oldPathItemAndDescendants.Add(oldPathItem.SerializedItemId, oldPathItem);
            }
            else
            {
                oldPathItemAndDescendants = new Dictionary <string, IItemMetadata>();
            }

            // WRITE THE NEW MOVED/RENAMED ITEMS TO THE TREE (note: delete goes last because with TpSync we need the old items to read from)
            var newPathTree = GetTreeForPath(itemWithFinalPath.Path, itemWithFinalPath.DatabaseName);

            // force consistency of parent IDs and paths among child items before we serialize them
            var rebasedPathItem = new PathRebasingProxyItem(itemWithFinalPath);

            // add new tree, if it's included (if it's moving to a non included path we simply delete it and are done)
            if (newPathTree != null)
            {
                var saveQueue = new Queue <IItemData>();
                saveQueue.Enqueue(rebasedPathItem);

                while (saveQueue.Count > 0)
                {
                    var parent = saveQueue.Dequeue();

                    var tree = GetTreeForPath(parent.Path, parent.DatabaseName);

                    if (tree == null)
                    {
                        throw new InvalidOperationException("No trees contained the global path " + parent.Path);
                    }

                    using (new SfsDuplicateIdCheckingDisabler())
                    {
                        var savedPath = tree.Save(parent);

                        // if we saved an item that was a former child of the item we want to keep it when we're doing deletions
                        if (oldPathItemAndDescendants.ContainsKey(savedPath))
                        {
                            oldPathItemAndDescendants.Remove(savedPath);
                        }
                    }

                    var children = parent.GetChildren();

                    foreach (var child in children)
                    {
                        saveQueue.Enqueue(child);
                    }
                }
            }

            // in case an item was renamed by case or someone calls rename without renaming, we don't want to delete anything
            // 'cause that'd just delete the item, not move it :)
            if (oldPath.Equals(itemWithFinalPath.Path, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            // REMOVE EXISTING ITEMS (if any)
            // (excluding any items that we wrote to during the save phase above, e.g. loopback path items may not change during a move)
            if (oldPathTree != null)
            {
                var oldItems = oldPathItemAndDescendants
                               .Select(key => key.Value)
                               .OrderByDescending(item => item.Path)
                               .ToArray();

                foreach (var item in oldItems)
                {
                    oldPathTree.RemoveWithoutChildren(item);
                }
            }
        }