public Dictionary <Guid, int> SaveMany([FromUri] int appId, [FromBody] List <BundleWithHeader <EntityWithLanguages> > items, [FromUri] bool partOfPage = false) { // log and do security check Log.Add($"save many started with a#{appId}, i⋮{items.Count}, partOfPage:{partOfPage}"); var appReadForSecurityCheckOnly = new AppRuntime(appId, true, Log); #region check if it's an update, and do more security checks - shared with UiController.Save // basic permission checks var permCheck = new Security.Security(BlockBuilder, Log) .DoPreSaveSecurityCheck(appId, items); var foundItems = items.Where(i => i.EntityId != 0 && i.EntityGuid != Guid.Empty) .Select(i => i.EntityGuid != Guid.Empty ? appReadForSecurityCheckOnly.Entities.Get(i.EntityGuid) // prefer guid access if available : appReadForSecurityCheckOnly.Entities.Get(i.EntityId) // otherwise id ); if (foundItems.Any(i => i != null) && !permCheck.EnsureAll(GrantSets.UpdateSomething, out var exception)) { throw exception; } #endregion return(new DnnPublishing(BlockBuilder, Log) .SaveWithinDnnPagePublishingAndUpdateParent(appId, items, partOfPage, forceSaveAsDraft => SaveOldFormatKeepTillReplaced(appId, items, partOfPage, forceSaveAsDraft), permCheck)); }
public Dictionary <Guid, int> Save([FromBody] AllInOne package, int appId, bool partOfPage) { Log.Add($"save started with a#{appId}, i⋮{package.Items.Count}, partOfPage:{partOfPage}"); var validator = new SaveDataValidator(package, Log); // perform some basic validation checks if (!validator.ContainsOnlyExpectedNodes(out var exp)) { throw exp; } // todo: unsure about this - thought I should check contentblockappid in group-header, because this is where it should be saved! //var contextAppId = appId; //var targetAppId = package.Items.First().Header.Group.ContentBlockAppId; //if (targetAppId != 0) //{ // Log.Add($"detected content-block app to use: {targetAppId}; in context of app {contextAppId}"); // appId = targetAppId; //} var appMan = new AppManager(appId, Log); var appRead = appMan.Read; var ser = new JsonSerializer(appRead.AppState, Log) { // Since we're importing directly into this app, we would prefer local content-types PreferLocalAppTypes = true }; validator.PrepareForEntityChecks(appRead); #region check if it's an update, and do more security checks then - shared with EntitiesController.Save // basic permission checks var permCheck = new Security.Security(BlockBuilder, Log) .DoPreSaveSecurityCheck(appId, package.Items); var foundItems = package.Items.Where(i => i.EntityId != 0 && i.EntityGuid != Guid.Empty) .Select(i => i.EntityGuid != Guid.Empty ? appRead.Entities.Get(i.EntityGuid) // prefer guid access if available : appRead.Entities.Get(i.EntityId) // otherwise id ); if (foundItems.Any(i => i != null) && !permCheck.EnsureAll(GrantSets.UpdateSomething, out var exception)) { throw exception; } #endregion var items = package.Items.Select(i => { var ent = ser.Deserialize(i.Entity, false, false) as Entity; var index = package.Items.IndexOf(i); // index is helpful in case of errors if (!validator.EntityIsOk(index, ent, out exp)) { throw exp; } if (!validator.IfUpdateValidateAndCorrectIds(index, ent, out exp)) { throw exp; } ent.IsPublished = package.IsPublished; ent.PlaceDraftInBranch = package.DraftShouldBranch; // new in 11.01 if (i.Header.ListHas()) { // Check if Add was true, and fix if it had already been saved (EntityId != 0) // the entityId is reset by the validator if it turns out to be an update // todo: verify use - maybe it's to set before we save, as maybe afterwards it's always != 0? var add = i.Header.ListAdd(); i.Header.Add = add; if (ent.EntityId > 0 && add) { i.Header.Add = false; } //i.Header.ReallyAddBecauseAlreadyVerified = i.Header.Add; } return(new BundleWithHeader <IEntity> { Header = i.Header, Entity = ent }); }) .ToList(); Log.Add("items to save generated, all data tests passed"); return(new DnnPublishing(BlockBuilder, Log) .SaveWithinDnnPagePublishingAndUpdateParent(appId, items, partOfPage, forceSaveAsDraft => DoSave(appMan, items, forceSaveAsDraft), permCheck)); }