public Attempt<OperationResult?> DeleteContainer(int containerId, int userId = Cms.Core.Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateCoreScope()) { var container = _dataTypeContainerRepository.Get(containerId); if (container == null) return OperationResult.Attempt.NoOperation(evtMsgs); // 'container' here does not know about its children, so we need // to get it again from the entity repository, as a light entity var entity = _entityRepository.Get(container.Id); if (entity?.HasChildren ?? false) { scope.Complete(); return Attempt.Fail(new OperationResult(OperationResultType.FailedCannot, evtMsgs)); } var deletingEntityContainerNotification = new EntityContainerDeletingNotification(container, evtMsgs); if (scope.Notifications.PublishCancelable(deletingEntityContainerNotification)) { scope.Complete(); return Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, evtMsgs)); } _dataTypeContainerRepository.Delete(container); scope.Notifications.Publish(new EntityContainerDeletedNotification(container, evtMsgs).WithStateFrom(deletingEntityContainerNotification)); scope.Complete(); } // TODO: Audit trail ? return OperationResult.Attempt.Succeed(evtMsgs); }
/// <summary> /// Saves an <see cref="IMacro"/> /// </summary> /// <param name="macro"><see cref="IMacro"/> to save</param> /// <param name="userId">Optional Id of the user deleting the macro</param> public void Save(IMacro macro, int userId = Cms.Core.Constants.Security.SuperUserId) { using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); var savingNotification = new MacroSavingNotification(macro, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; } if (string.IsNullOrWhiteSpace(macro.Name)) { throw new ArgumentException("Cannot save macro with empty name."); } _macroRepository.Save(macro); scope.Notifications.Publish(new MacroSavedNotification(macro, eventMessages).WithStateFrom(savingNotification)); Audit(AuditType.Save, userId, -1); scope.Complete(); } }
/// <summary> /// Deletes or disables a User /// </summary> /// <param name="user"><see cref="IUser" /> to delete</param> /// <param name="deletePermanently"><c>True</c> to permanently delete the user, <c>False</c> to disable the user</param> public void Delete(IUser user, bool deletePermanently) { if (deletePermanently == false) { Delete(user); } else { EventMessages evtMsgs = EventMessagesFactory.Get(); using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { var deletingNotification = new UserDeletingNotification(user, evtMsgs); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; } _userRepository.Delete(user); scope.Notifications.Publish( new UserDeletedNotification(user, evtMsgs).WithStateFrom(deletingNotification)); scope.Complete(); } } }
public Attempt<OperationResult<OperationResultType, EntityContainer>?> RenameContainer(int id, string name, int userId = Cms.Core.Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateCoreScope()) { try { var container = _dataTypeContainerRepository.Get(id); //throw if null, this will be caught by the catch and a failed returned if (container == null) throw new InvalidOperationException("No container found with id " + id); container.Name = name; var renamingEntityContainerNotification = new EntityContainerRenamingNotification(container, evtMsgs); if (scope.Notifications.PublishCancelable(renamingEntityContainerNotification)) { scope.Complete(); return OperationResult.Attempt.Cancel(evtMsgs, container); } _dataTypeContainerRepository.Save(container); scope.Complete(); scope.Notifications.Publish(new EntityContainerRenamedNotification(container, evtMsgs).WithStateFrom(renamingEntityContainerNotification)); return OperationResult.Attempt.Succeed(OperationResultType.Success, evtMsgs, container); } catch (Exception ex) { return OperationResult.Attempt.Fail<EntityContainer>(evtMsgs, ex); } } }
/// <inheritdoc /> public void DeleteStylesheet(string path, int userId = Constants.Security.SuperUserId) { using (IScope scope = ScopeProvider.CreateScope()) { IStylesheet stylesheet = _stylesheetRepository.Get(path); if (stylesheet == null) { scope.Complete(); return; } EventMessages eventMessages = EventMessagesFactory.Get(); var deletingNotification = new StylesheetDeletingNotification(stylesheet, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; // causes rollback } _stylesheetRepository.Delete(stylesheet); scope.Notifications.Publish(new StylesheetDeletedNotification(stylesheet, eventMessages).WithStateFrom(deletingNotification)); Audit(AuditType.Delete, userId, -1, "Stylesheet"); scope.Complete(); } }
/// <summary> /// Saves a collection of <see cref="Template" /> objects /// </summary> /// <param name="templates">List of <see cref="Template" /> to save</param> /// <param name="userId">Optional id of the user</param> public void SaveTemplate(IEnumerable <ITemplate> templates, int userId = Constants.Security.SuperUserId) { ITemplate[] templatesA = templates.ToArray(); using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); var savingNotification = new TemplateSavingNotification(templatesA, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; } foreach (ITemplate template in templatesA) { _templateRepository.Save(template); } scope.Notifications.Publish( new TemplateSavedNotification(templatesA, eventMessages).WithStateFrom(savingNotification)); Audit(AuditType.Save, userId, -1, UmbracoObjectTypes.Template.GetName()); scope.Complete(); } }
public Attempt <OperationStatus> SaveContainer(EntityContainer container, int userId = 0) { var evtMsgs = EventMessagesFactory.Get(); if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid) { var ex = new InvalidOperationException("Not a " + Constants.ObjectTypes.DataTypeGuid + " container."); return(OperationStatus.Exception(evtMsgs, ex)); } if (container.HasIdentity && container.IsPropertyDirty("ParentId")) { var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead."); return(OperationStatus.Exception(evtMsgs, ex)); } using (var uow = UowProvider.GetUnitOfWork()) { if (uow.Events.DispatchCancelable(SavingContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs))) { return(OperationStatus.Cancelled(evtMsgs)); } var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid); repo.AddOrUpdate(container); uow.Commit(); uow.Events.Dispatch(SavedContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs)); } //TODO: Audit trail ? return(OperationStatus.Success(evtMsgs)); }
public Attempt <OperationStatus> DeleteContainer(int containerId, int userId = 0) { var evtMsgs = EventMessagesFactory.Get(); using (var uow = UowProvider.GetUnitOfWork()) { var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid); var container = repo.Get(containerId); if (container == null) { return(OperationStatus.NoOperation(evtMsgs)); } if (uow.Events.DispatchCancelable(DeletingContainer, this, new DeleteEventArgs <EntityContainer>(container, evtMsgs))) { uow.Commit(); return(Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs))); } repo.Delete(container); uow.Commit(); uow.Events.Dispatch(DeletedContainer, this, new DeleteEventArgs <EntityContainer>(container, evtMsgs)); return(OperationStatus.Success(evtMsgs)); //TODO: Audit trail ? } }
public Attempt <OperationResult <OperationResultType, EntityContainer> > CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) { try { var container = new EntityContainer(Constants.ObjectTypes.DataType) { Name = name, ParentId = parentId, CreatorId = userId }; if (scope.Events.DispatchCancelable(SavingContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs))) { scope.Complete(); return(OperationResult.Attempt.Cancel(evtMsgs, container)); } _dataTypeContainerRepository.Save(container); scope.Complete(); scope.Events.Dispatch(SavedContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs)); // TODO: Audit trail ? return(OperationResult.Attempt.Succeed(evtMsgs, container)); } catch (Exception ex) { return(OperationResult.Attempt.Fail <EntityContainer>(evtMsgs, ex)); } } }
public Attempt <OperationResult <OperationResultType, EntityContainer> > RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) { try { var container = _dataTypeContainerRepository.Get(id); //throw if null, this will be caught by the catch and a failed returned if (container == null) { throw new InvalidOperationException("No container found with id " + id); } container.Name = name; _dataTypeContainerRepository.Save(container); scope.Complete(); // TODO: triggering SavedContainer with a different name?! scope.Events.Dispatch(SavedContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs), "RenamedContainer"); return(OperationResult.Attempt.Succeed(OperationResultType.Success, evtMsgs, container)); } catch (Exception ex) { return(OperationResult.Attempt.Fail <EntityContainer>(evtMsgs, ex)); } } }
public Attempt <OperationResult> SaveContainer(EntityContainer container, int userId = 0) { var evtMsgs = EventMessagesFactory.Get(); if (container.ContainedObjectType != Constants.ObjectTypes.DataType) { var ex = new InvalidOperationException("Not a " + Constants.ObjectTypes.DataType + " container."); return(OperationResult.Attempt.Fail(evtMsgs, ex)); } if (container.HasIdentity && container.IsPropertyDirty("ParentId")) { var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead."); return(OperationResult.Attempt.Fail(evtMsgs, ex)); } using (var scope = ScopeProvider.CreateScope()) { if (scope.Events.DispatchCancelable(SavingContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs))) { scope.Complete(); return(OperationResult.Attempt.Cancel(evtMsgs)); } _dataTypeContainerRepository.Save(container); scope.Events.Dispatch(SavedContainer, this, new SaveEventArgs <EntityContainer>(container, evtMsgs)); scope.Complete(); } //TODO: Audit trail ? return(OperationResult.Attempt.Succeed(evtMsgs)); }
private Attempt <IPartialView?> SavePartialView(IPartialView partialView, PartialViewType partialViewType, int?userId = null) { using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); var savingNotification = new PartialViewSavingNotification(partialView, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return(Attempt <IPartialView?> .Fail()); } userId ??= Constants.Security.SuperUserId; IPartialViewRepository repository = GetPartialViewRepository(partialViewType); repository.Save(partialView); Audit(AuditType.Save, userId.Value, -1, partialViewType.ToString()); scope.Notifications.Publish( new PartialViewSavedNotification(partialView, eventMessages).WithStateFrom(savingNotification)); scope.Complete(); } return(Attempt.Succeed(partialView)); }
/// <summary> /// Deletes a <see cref="ILanguage" /> by removing it (but not its usages) from the db /// </summary> /// <param name="language"><see cref="ILanguage" /> to delete</param> /// <param name="userId">Optional id of the user deleting the language</param> public void Delete(ILanguage language, int userId = Constants.Security.SuperUserId) { using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { // write-lock languages to guard against race conds when dealing with default language scope.WriteLock(Constants.Locks.Languages); EventMessages eventMessages = EventMessagesFactory.Get(); var deletingLanguageNotification = new LanguageDeletingNotification(language, eventMessages); if (scope.Notifications.PublishCancelable(deletingLanguageNotification)) { scope.Complete(); return; } // NOTE: Other than the fall-back language, there aren't any other constraints in the db, so possible references aren't deleted _languageRepository.Delete(language); scope.Notifications.Publish( new LanguageDeletedNotification(language, eventMessages).WithStateFrom(deletingLanguageNotification)); Audit(AuditType.Delete, "Delete Language", userId, language.Id, UmbracoObjectTypes.Language.GetName()); scope.Complete(); } }
/// <inheritdoc /> public void SaveStylesheet(IStylesheet?stylesheet, int?userId = null) { if (stylesheet is null) { return; } using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); var savingNotification = new StylesheetSavingNotification(stylesheet, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; } userId ??= Constants.Security.SuperUserId; _stylesheetRepository.Save(stylesheet); scope.Notifications.Publish(new StylesheetSavedNotification(stylesheet, eventMessages).WithStateFrom(savingNotification)); Audit(AuditType.Save, userId.Value, -1, "Stylesheet"); scope.Complete(); } }
/// <summary> /// Saves a <see cref="Template"/> /// </summary> /// <param name="template"><see cref="Template"/> to save</param> /// <param name="userId"></param> public void SaveTemplate(ITemplate template, int userId = Constants.Security.SuperUserId) { if (template == null) { throw new ArgumentNullException(nameof(template)); } if (string.IsNullOrWhiteSpace(template.Name) || template.Name.Length > 255) { throw new InvalidOperationException("Name cannot be null, empty, contain only white-space characters or be more than 255 characters in length."); } using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); var savingNotification = new TemplateSavingNotification(template, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; } _templateRepository.Save(template); scope.Notifications.Publish(new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingNotification)); Audit(AuditType.Save, userId, template.Id, UmbracoObjectTypes.Template.GetName()); scope.Complete(); } }
/// <summary> /// Deletes a template by its alias /// </summary> /// <param name="alias">Alias of the <see cref="ITemplate"/> to delete</param> /// <param name="userId"></param> public void DeleteTemplate(string alias, int userId = Constants.Security.SuperUserId) { using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { ITemplate?template = _templateRepository.Get(alias); if (template == null) { scope.Complete(); return; } EventMessages eventMessages = EventMessagesFactory.Get(); var deletingNotification = new TemplateDeletingNotification(template, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; } _templateRepository.Delete(template); scope.Notifications.Publish(new TemplateDeletedNotification(template, eventMessages).WithStateFrom(deletingNotification)); Audit(AuditType.Delete, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template)); scope.Complete(); } }
/// <summary> /// Removes a rule /// </summary> /// <param name="content"></param> /// <param name="ruleType"></param> /// <param name="ruleValue"></param> public Attempt <OperationResult> RemoveRule(IContent content, string ruleType, string ruleValue) { var evtMsgs = EventMessagesFactory.Get(); PublicAccessEntry entry; using (var scope = ScopeProvider.CreateScope()) { entry = _publicAccessRepository.GetMany().FirstOrDefault(x => x.ProtectedNodeId == content.Id); if (entry == null) { return(Attempt <OperationResult> .Fail()); // causes rollback // causes rollback } var existingRule = entry.Rules.FirstOrDefault(x => x.RuleType == ruleType && x.RuleValue == ruleValue); if (existingRule == null) { return(Attempt <OperationResult> .Fail()); // causes rollback // causes rollback } entry.RemoveRule(existingRule); var savingNotifiation = new PublicAccessEntrySavingNotification(entry, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); return(OperationResult.Attempt.Cancel(evtMsgs)); } _publicAccessRepository.Save(entry); scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return(OperationResult.Attempt.Succeed(evtMsgs)); }
/// <inheritdoc /> public void DeleteScript(string path, int?userId = null) { using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { IScript?script = _scriptRepository.Get(path); if (script == null) { scope.Complete(); return; } EventMessages eventMessages = EventMessagesFactory.Get(); var deletingNotification = new ScriptDeletingNotification(script, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; } userId ??= Constants.Security.SuperUserId; _scriptRepository.Delete(script); scope.Notifications.Publish(new ScriptDeletedNotification(script, eventMessages).WithStateFrom(deletingNotification)); Audit(AuditType.Delete, userId.Value, -1, "Script"); scope.Complete(); } }
/// <summary> /// Saves a collection of <see cref="IDataType"/> /// </summary> /// <param name="dataTypeDefinitions"><see cref="IDataType"/> to save</param> /// <param name="userId">Id of the user issuing the save</param> public void Save(IEnumerable <IDataType> dataTypeDefinitions, int userId) { var evtMsgs = EventMessagesFactory.Get(); var dataTypeDefinitionsA = dataTypeDefinitions.ToArray(); using (var scope = ScopeProvider.CreateScope()) { var savingDataTypeNotification = new DataTypeSavingNotification(dataTypeDefinitions, evtMsgs); if (scope.Notifications.PublishCancelable(savingDataTypeNotification)) { scope.Complete(); return; } foreach (var dataTypeDefinition in dataTypeDefinitionsA) { dataTypeDefinition.CreatorId = userId; _dataTypeRepository.Save(dataTypeDefinition); } scope.Notifications.Publish(new DataTypeSavedNotification(dataTypeDefinitions, evtMsgs).WithStateFrom(savingDataTypeNotification)); Audit(AuditType.Save, userId, -1); scope.Complete(); } }
/// <inheritdoc /> public IRelation Relate(int parentId, int childId, IRelationType relationType) { // Ensure that the RelationType has an identity before using it to relate two entities if (relationType.HasIdentity == false) { Save(relationType); } //TODO: We don't check if this exists first, it will throw some sort of data integrity exception if it already exists, is that ok? var relation = new Relation(parentId, childId, relationType); using (IScope scope = ScopeProvider.CreateScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); var savingNotification = new RelationSavingNotification(relation, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return(relation); // TODO: returning sth that does not exist here?! } _relationRepository.Save(relation); scope.Notifications.Publish(new RelationSavedNotification(relation, eventMessages).WithStateFrom(savingNotification)); scope.Complete(); return(relation); } }
/// <summary> /// Saves an <see cref="IDataType"/> /// </summary> /// <param name="dataType"><see cref="IDataType"/> to save</param> /// <param name="userId">Id of the user issuing the save</param> public void Save(IDataType dataType, int userId = Cms.Core.Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); dataType.CreatorId = userId; using (var scope = ScopeProvider.CreateScope()) { var saveEventArgs = new SaveEventArgs <IDataType>(dataType); var savingDataTypeNotification = new DataTypeSavingNotification(dataType, evtMsgs); if (scope.Notifications.PublishCancelable(savingDataTypeNotification)) { scope.Complete(); return; } if (string.IsNullOrWhiteSpace(dataType.Name)) { throw new ArgumentException("Cannot save datatype with empty name."); } if (dataType.Name != null && dataType.Name.Length > 255) { throw new InvalidOperationException("Name cannot be more than 255 characters in length."); } _dataTypeRepository.Save(dataType); scope.Notifications.Publish(new DataTypeSavedNotification(dataType, evtMsgs).WithStateFrom(savingDataTypeNotification)); Audit(AuditType.Save, userId, dataType.Id); scope.Complete(); } }
public Attempt <OperationResult> SaveContainer(EntityContainer container, int userId = Cms.Core.Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); if (container.ContainedObjectType != Cms.Core.Constants.ObjectTypes.DataType) { var ex = new InvalidOperationException("Not a " + Cms.Core.Constants.ObjectTypes.DataType + " container."); return(OperationResult.Attempt.Fail(evtMsgs, ex)); } if (container.HasIdentity && container.IsPropertyDirty("ParentId")) { var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead."); return(OperationResult.Attempt.Fail(evtMsgs, ex)); } using (var scope = ScopeProvider.CreateScope()) { var savingEntityContainerNotification = new EntityContainerSavingNotification(container, evtMsgs); if (scope.Notifications.PublishCancelable(savingEntityContainerNotification)) { scope.Complete(); return(OperationResult.Attempt.Cancel(evtMsgs)); } _dataTypeContainerRepository.Save(container); scope.Notifications.Publish(new EntityContainerSavedNotification(container, evtMsgs).WithStateFrom(savingEntityContainerNotification)); scope.Complete(); } // TODO: Audit trail ? return(OperationResult.Attempt.Succeed(evtMsgs)); }
/// <summary> /// Removes a rule /// </summary> /// <param name="content"></param> /// <param name="ruleType"></param> /// <param name="ruleValue"></param> public Attempt <OperationResult> RemoveRule(IContent content, string ruleType, string ruleValue) { var evtMsgs = EventMessagesFactory.Get(); PublicAccessEntry entry; using (var scope = ScopeProvider.CreateScope()) { entry = _publicAccessRepository.GetMany().FirstOrDefault(x => x.ProtectedNodeId == content.Id); if (entry == null) { return(Attempt <OperationResult> .Fail()); // causes rollback // causes rollback } var existingRule = entry.Rules.FirstOrDefault(x => x.RuleType == ruleType && x.RuleValue == ruleValue); if (existingRule == null) { return(Attempt <OperationResult> .Fail()); // causes rollback // causes rollback } entry.RemoveRule(existingRule); var saveEventArgs = new SaveEventArgs <PublicAccessEntry>(entry, evtMsgs); if (scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) { scope.Complete(); return(OperationResult.Attempt.Cancel(evtMsgs)); } _publicAccessRepository.Save(entry); scope.Complete(); saveEventArgs.CanCancel = false; scope.Events.Dispatch(Saved, this, saveEventArgs); } return(OperationResult.Attempt.Succeed(evtMsgs)); }
private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int?userId = null) { using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { IPartialViewRepository repository = GetPartialViewRepository(partialViewType); IPartialView? partialView = repository.Get(path); if (partialView == null) { scope.Complete(); return(true); } EventMessages eventMessages = EventMessagesFactory.Get(); var deletingNotification = new PartialViewDeletingNotification(partialView, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return(false); } userId ??= Constants.Security.SuperUserId; repository.Delete(partialView); scope.Notifications.Publish(new PartialViewDeletedNotification(partialView, eventMessages).WithStateFrom(deletingNotification)); Audit(AuditType.Delete, userId.Value, -1, partialViewType.ToString()); scope.Complete(); } return(true); }
public void Save(TItem?item, int userId = Cms.Core.Constants.Security.SuperUserId) { if (item is null) { return; } using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); SavingNotification <TItem> savingNotification = GetSavingNotification(item, eventMessages); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; } if (string.IsNullOrWhiteSpace(item.Name)) { throw new ArgumentException("Cannot save item with empty name."); } if (item.Name != null && item.Name.Length > 255) { throw new InvalidOperationException("Name cannot be more than 255 characters in length."); } scope.WriteLock(WriteLockIds); // validate the DAG transform, within the lock ValidateLocked(item); // throws if invalid item.CreatorId = userId; if (item.Description == string.Empty) { item.Description = null; } Repository.Save(item); // also updates content/media/member items // figure out impacted content types ContentTypeChange <TItem>[] changes = ComposeContentTypeChanges(item).ToArray(); // Publish this in scope, see comment at GetContentTypeRefreshedNotification for more info. _eventAggregator.Publish(GetContentTypeRefreshedNotification(changes, eventMessages)); scope.Notifications.Publish(GetContentTypeChangedNotification(changes, eventMessages)); SavedNotification <TItem> savedNotification = GetSavedNotification(item, eventMessages); savedNotification.WithStateFrom(savingNotification); scope.Notifications.Publish(savedNotification); Audit(AuditType.Save, userId, item.Id); scope.Complete(); } }
public void Delete(IEnumerable <TItem> items, int userId = Cms.Core.Constants.Security.SuperUserId) { TItem[] itemsA = items.ToArray(); using (IScope scope = ScopeProvider.CreateScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); DeletingNotification <TItem> deletingNotification = GetDeletingNotification(itemsA, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; } scope.WriteLock(WriteLockIds); // all descendants are going to be deleted TItem[] allDescendantsAndSelf = itemsA.SelectMany(xx => GetDescendants(xx.Id, true)) .DistinctBy(x => x.Id) .ToArray(); TItem[] deleted = allDescendantsAndSelf; // all impacted (through composition) probably lose some properties // don't try to be too clever here, just report them all // do this before anything is deleted TItem[] changed = allDescendantsAndSelf.SelectMany(x => GetComposedOf(x.Id)) .Distinct() .Except(allDescendantsAndSelf) .ToArray(); // delete content DeleteItemsOfTypes(allDescendantsAndSelf.Select(x => x.Id)); // finally delete the content types // (see notes in overload) foreach (TItem item in itemsA) { Repository.Delete(item); } ContentTypeChange <TItem>[] changes = allDescendantsAndSelf.Select(x => new ContentTypeChange <TItem>(x, ContentTypeChangeTypes.Remove)) .Concat(changed.Select(x => new ContentTypeChange <TItem>(x, ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther))) .ToArray(); // Publish this in scope, see comment at GetContentTypeRefreshedNotification for more info. _eventAggregator.Publish(GetContentTypeRefreshedNotification(changes, eventMessages)); scope.Notifications.Publish(GetContentTypeChangedNotification(changes, eventMessages)); DeletedNotification <TItem> deletedNotification = GetDeletedNotification(deleted.DistinctBy(x => x.Id), eventMessages); deletedNotification.WithStateFrom(deletingNotification); scope.Notifications.Publish(deletedNotification); Audit(AuditType.Delete, userId, -1); scope.Complete(); } }
/// <summary> /// Saves a UserGroup /// </summary> /// <param name="userGroup">UserGroup to save</param> /// <param name="userIds"> /// If null than no changes are made to the users who are assigned to this group, however if a value is passed in /// than all users will be removed from this group and only these users will be added /// </param> /// Default is /// <c>True</c> /// otherwise set to /// <c>False</c> /// to not raise events /// </param> public void Save(IUserGroup userGroup, int[]?userIds = null) { EventMessages evtMsgs = EventMessagesFactory.Get(); using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { // we need to figure out which users have been added / removed, for audit purposes var empty = new IUser[0]; IUser[] addedUsers = empty; IUser[] removedUsers = empty; if (userIds != null) { IUser[] groupUsers = userGroup.HasIdentity ? _userRepository.GetAllInGroup(userGroup.Id).ToArray() : empty; var xGroupUsers = groupUsers.ToDictionary(x => x.Id, x => x); var groupIds = groupUsers.Select(x => x.Id).ToArray(); IEnumerable <int> addedUserIds = userIds.Except(groupIds); addedUsers = addedUserIds.Count() > 0 ? _userRepository.GetMany(addedUserIds.ToArray()).Where(x => x.Id != 0).ToArray() : new IUser[] { }; removedUsers = groupIds.Except(userIds).Select(x => xGroupUsers[x]).Where(x => x.Id != 0).ToArray(); } var userGroupWithUsers = new UserGroupWithUsers(userGroup, addedUsers, removedUsers); // this is the default/expected notification for the IUserGroup entity being saved var savingNotification = new UserGroupSavingNotification(userGroup, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; } // this is an additional notification for special auditing var savingUserGroupWithUsersNotification = new UserGroupWithUsersSavingNotification(userGroupWithUsers, evtMsgs); if (scope.Notifications.PublishCancelable(savingUserGroupWithUsersNotification)) { scope.Complete(); return; } _userGroupRepository.AddOrUpdateGroupWithUsers(userGroup, userIds); scope.Notifications.Publish( new UserGroupSavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification)); scope.Notifications.Publish( new UserGroupWithUsersSavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom( savingUserGroupWithUsersNotification)); scope.Complete(); } }
/// <summary> /// Creates a template for a content type /// </summary> /// <param name="contentTypeAlias"></param> /// <param name="contentTypeName"></param> /// <param name="userId"></param> /// <returns> /// The template created /// </returns> public Attempt <OperationResult <OperationResultType, ITemplate> > CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId) { var template = new Template(contentTypeName, //NOTE: We are NOT passing in the content type alias here, we want to use it's name since we don't // want to save template file names as camelCase, the Template ctor will clean the alias as // `alias.ToCleanString(CleanStringType.UnderscoreAlias)` which has been the default. // This fixes: http://issues.umbraco.org/issue/U4-7953 contentTypeName); var evtMsgs = EventMessagesFactory.Get(); // TODO: This isn't pretty because we we're required to maintain backwards compatibility so we could not change // the event args here. The other option is to create a different event with different event // args specifically for this method... which also isn't pretty. So fix this in v8! var additionalData = new Dictionary <string, object> { { "CreateTemplateForContentType", true }, { "ContentTypeAlias", contentTypeAlias }, }; if (contentTypeAlias != null && contentTypeAlias.Length > 255) { throw new InvalidOperationException("Name cannot be more than 255 characters in length."); } // check that the template hasn't been created on disk before creating the content type // if it exists, set the new template content to the existing file content string content = GetViewContent(contentTypeAlias); if (content != null) { template.Content = content; } using (var scope = ScopeProvider.CreateScope()) { var saveEventArgs = new SaveEventArgs <ITemplate>(template, true, evtMsgs, additionalData); if (scope.Events.DispatchCancelable(SavingTemplate, this, saveEventArgs)) { scope.Complete(); return(OperationResult.Attempt.Fail <OperationResultType, ITemplate>(OperationResultType.FailedCancelledByEvent, evtMsgs, template)); } _templateRepository.Save(template); saveEventArgs.CanCancel = false; scope.Events.Dispatch(SavedTemplate, this, saveEventArgs); Audit(AuditType.Save, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template)); scope.Complete(); } return(OperationResult.Attempt.Succeed <OperationResultType, ITemplate>(OperationResultType.Success, evtMsgs, template)); }
public Attempt <OperationResult <MoveOperationStatusType, TItem> > Copy(TItem copying, int containerId) { var evtMsgs = EventMessagesFactory.Get(); TItem copy; using (var scope = ScopeProvider.CreateScope()) { scope.WriteLock(WriteLockIds); try { if (containerId > 0) { var container = _containerRepository.Get(containerId); if (container == null) { throw new DataOperationException <MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound); // causes rollback } } var alias = Repository.GetUniqueAlias(copying.Alias); // this is illegal //var copyingb = (ContentTypeCompositionBase) copying; // but we *know* it has to be a ContentTypeCompositionBase anyways var copyingb = (ContentTypeCompositionBase)(object)copying; copy = (TItem)(object)copyingb.DeepCloneWithResetIdentities(alias); copy.Name = copy.Name + " (copy)"; // might not be unique // if it has a parent, and the parent is a content type, unplug composition // all other compositions remain in place in the copied content type if (copy.ParentId > 0) { var parent = Repository.Get(copy.ParentId); if (parent != null) { copy.RemoveContentType(parent.Alias); } } copy.ParentId = containerId; Repository.Save(copy); scope.Complete(); } catch (DataOperationException <MoveOperationStatusType> ex) { return(OperationResult.Attempt.Fail <MoveOperationStatusType, TItem>(ex.Operation, evtMsgs)); // causes rollback } } return(OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs, copy)); }
/// <summary> /// Creates and persists a Member /// </summary> /// <remarks> /// Using this method will persist the Member object before its returned /// meaning that it will have an Id available (unlike the CreateMember method) /// </remarks> /// <param name="username">Username of the Member to create</param> /// <param name="email">Email of the Member to create</param> /// <param name="passwordValue"> /// This value should be the encoded/encrypted/hashed value for the password that will be /// stored in the database /// </param> /// <param name="isApproved">Is the user approved</param> /// <returns> /// <see cref="IUser" /> /// </returns> private IUser CreateUserWithIdentity(string username, string email, string passwordValue, bool isApproved = true) { if (username == null) { throw new ArgumentNullException(nameof(username)); } if (string.IsNullOrWhiteSpace(username)) { throw new ArgumentException( "Value can't be empty or consist only of white-space characters.", nameof(username)); } EventMessages evtMsgs = EventMessagesFactory.Get(); // TODO: PUT lock here!! User user; using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { var loginExists = _userRepository.ExistsByLogin(username); if (loginExists) { throw new ArgumentException("Login already exists"); // causes rollback } user = new User(_globalSettings) { Email = email, Language = _globalSettings.DefaultUILanguage, Name = username, RawPasswordValue = passwordValue, Username = username, IsLockedOut = false, IsApproved = isApproved, }; var savingNotification = new UserSavingNotification(user, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return(user); } _userRepository.Save(user); scope.Notifications.Publish(new UserSavedNotification(user, evtMsgs).WithStateFrom(savingNotification)); scope.Complete(); } return(user); }