예제 #1
0
        /// <summary>
        /// Moves an <see cref="IContent"/> object to a new location by changing its parent id.
        /// </summary>
        /// <remarks>
        /// If the <see cref="IContent"/> object is already published it will be
        /// published after being moved to its new location. Otherwise it'll just
        /// be saved with a new parent id.
        /// </remarks>
        /// <param name="content">The <see cref="IContent"/> to move</param>
        /// <param name="parentId">Id of the Content's new Parent</param>
        /// <param name="userId">Optional Id of the User moving the Content</param>
        public void Move(IContent content, int parentId, int userId = 0)
        {
            using (new WriteLock(Locker))
            {
                //This ensures that the correct method is called if this method is used to Move to recycle bin.
                if (parentId == -20)
                {
                    MoveToRecycleBin(content, userId);
                    return;
                }

                if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IContent>(content, parentId), this))
                    return;

                content.WriterId = userId;
                if (parentId == -1)
                {
                    content.Path = string.Concat("-1,", content.Id);
                    content.Level = 1;
                }
                else
                {
                    var parent = GetById(parentId);
                    content.Path = string.Concat(parent.Path, ",", content.Id);
                    content.Level = parent.Level + 1;
                }


                //If Content is being moved away from Recycle Bin, its state should be un-trashed
                if (content.Trashed && parentId != -20)
                {
                    content.ChangeTrashedState(false, parentId);
                }
                else
                {
                    content.ParentId = parentId;
                }

                //If Content is published, it should be (re)published from its new location
                if (content.Published)
                {
                    //If Content is Publishable its saved and published
                    //otherwise we save the content without changing the publish state, and generate new xml because the Path, Level and Parent has changed.
                    if (IsPublishable(content))
                    {
                        SaveAndPublish(content, userId);
                    }
                    else
                    {
                        Save(content, false, userId, true);

                        using (var uow = _uowProvider.GetUnitOfWork())
                        {
                            var xml = content.ToXml();
                            var poco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) };
                            var exists =
                                uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = content.Id }) !=
                                null;
                            int result = exists
                                             ? uow.Database.Update(poco)
                                             : Convert.ToInt32(uow.Database.Insert(poco));
                        }
                    }
                }
                else
                {
                    Save(content, userId);
                }

                //Ensure that Path and Level is updated on children
                var children = GetChildren(content.Id);
                if (children.Any())
                {
                    foreach (var child in children)
                    {
                        Move(child, content.Id, userId);
                    }
                }

                Moved.RaiseEvent(new MoveEventArgs<IContent>(content, false, parentId), this);

                Audit.Add(AuditTypes.Move, "Move Content performed by user", userId, content.Id);
            }
        }
예제 #2
0
        /// <summary>
        /// Deletes an <see cref="IContent"/> object by moving it to the Recycle Bin
        /// </summary>
        /// <remarks>Move an item to the Recycle Bin will result in the item being unpublished</remarks>
        /// <param name="content">The <see cref="IContent"/> to delete</param>
        /// <param name="userId">Optional Id of the User deleting the Content</param>
        public void MoveToRecycleBin(IContent content, int userId = 0)
        {
            using (new WriteLock(Locker))
            {
                if (Trashing.IsRaisedEventCancelled(new MoveEventArgs<IContent>(content, -20), this))
                    return;

                //Make sure that published content is unpublished before being moved to the Recycle Bin
                if (HasPublishedVersion(content.Id))
                {
                    UnPublish(content, userId);
                }

                //Unpublish descendents of the content item that is being moved to trash
                var descendants = GetDescendants(content).OrderBy(x => x.Level).ToList();
                foreach (var descendant in descendants)
                {
                    UnPublish(descendant, userId);
                }

                var uow = _uowProvider.GetUnitOfWork();
                using (var repository = _repositoryFactory.CreateContentRepository(uow))
                {
                    content.WriterId = userId;
                    content.ChangeTrashedState(true);
                    repository.AddOrUpdate(content);

                    //Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
                    foreach (var descendant in descendants)
                    {
                        descendant.WriterId = userId;
                        descendant.ChangeTrashedState(true, descendant.ParentId);
                        repository.AddOrUpdate(descendant);
                    }

                    uow.Commit();
                }

                Trashed.RaiseEvent(new MoveEventArgs<IContent>(content, false, -20), this);

                Audit.Add(AuditTypes.Move, "Move Content to Recycle Bin performed by user", userId, content.Id);
            }
        }