/* * <ContentRedactions> * <add Regex="Production" Placeholder="EnvironmentName" ReplaceWith="Local" /> * </ContentRedactions> */ // Add a set of redactions public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "ContentRedactions", StringComparison.OrdinalIgnoreCase) && !String.Equals(recipeContext.RecipeStep.Name, "Redactions", StringComparison.OrdinalIgnoreCase)) //this check is for legacy reasons { return; } _realtimeFeedbackService.Info(T("Starting 'Content Redactions' step")); var redactions = recipeContext.RecipeStep.Step.Descendants().Where(f => f.Name == "add"); foreach (var redaction in redactions) { var placeholder = redaction.Attribute("Placeholder").Value; var regex = redaction.Attribute("Regex").Value; var replaceWith = redaction.Attribute("ReplaceWith").Value; _realtimeFeedbackService.Info(T("Adding content redaction {0} to match regex {1} and relace with {2}", placeholder, regex, replaceWith)); _textRedactionService.AddRedaction(new RedactionRecord { Placeholder = placeholder, Regex = regex, ReplaceWith = replaceWith, }); } _realtimeFeedbackService.Info(T("Step 'Content Redactions' has finished")); recipeContext.Executed = true; }
/* * <RunContentMigrations /> */ //Run any pending content migrations public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "RunContentMigrations", StringComparison.OrdinalIgnoreCase)) { return; } _realtimeFeedbackService.Info(T("Starting 'Run Content Migrations' step")); _contentMigrationManager.ExecutePendingMigrations(); _realtimeFeedbackService.Info(T("Step 'Run Content Migrations' has finished")); recipeContext.Executed = true; }
/* * <CurrentTheme name="MySuperTheme" /> */ //Enable any features that are in the list, disable features that aren't in the list public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "CurrentTheme", StringComparison.OrdinalIgnoreCase)) { return; } _realtimeFeedbackService.Info(T("Entering the 'Current Theme' step")); var themeToEnable = recipeContext.RecipeStep.Step.Attribute("id").Value; _realtimeFeedbackService.Info(T("Setting the current theme to {0}", themeToEnable)); _siteThemeService.SetSiteTheme(themeToEnable); _realtimeFeedbackService.Info(T("The current theme has been set to {0}", themeToEnable)); recipeContext.Executed = true; }
/* * <Delete> * <Content Id="123456789" /> * <Layer Name="Mobile Homepage" /> */ //delete content and layers public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "Delete", StringComparison.OrdinalIgnoreCase)) { return; } _realtimeFeedbackService.Info(T("Entering the 'Delete' step. This step will remove content as specified")); var items = recipeContext.RecipeStep.Step.Descendants().ToList(); foreach (var item in items) { switch (item.Name.ToString().ToLowerInvariant()) //to consider: we could inject in a collection of interfaces to handle these items to allow for extensibility { case "content": var identifier = item.Attribute("Id").Value; var content = _contentManager.Query <IdentityPart, IdentityPartRecord>().Where(c => c.Identifier == identifier).List().FirstOrDefault(); if (content != null) { _realtimeFeedbackService.Info(T("Removing content item '{0}'", content.ContentItem.GetContentName())); _contentManager.Remove(content.ContentItem); } break; case "layer": var name = item.Attribute("Name").Value; var layer = _contentManager.Query <LayerPart, LayerPartRecord>().Where(l => l.Name == name).List().FirstOrDefault(); if (layer != null) { _realtimeFeedbackService.Info(T("Removing layer '{0}'", layer.ContentItem.GetContentName())); _contentManager.Remove(layer.ContentItem); } break; } } _realtimeFeedbackService.Info(T("The 'Delete' step is finished; it removed {0} content items.", items.Count())); recipeContext.Executed = true; }
/* * <RedactedSiteSettings> * <SiteSettingsPart PageSize="30" /> * <CommentSettingsPart ModerateComments="true" /> * </RedactedSiteSettings> */ // Set site and part settings. public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "RedactedSiteSettings", StringComparison.OrdinalIgnoreCase)) { return; } _realtimeFeedbackService.Info(T("Entering the 'Redacted Site Settings' step")); var site = _siteService.GetSiteSettings(); foreach (var element in recipeContext.RecipeStep.Step.Elements()) { var partName = XmlConvert.DecodeName(element.Name.LocalName); foreach (var contentPart in site.ContentItem.Parts) { if (!String.Equals(contentPart.PartDefinition.Name, partName, StringComparison.OrdinalIgnoreCase)) { continue; } foreach (var attribute in element.Attributes()) { SetSetting(attribute, contentPart); } } } _realtimeFeedbackService.Info(T("Site settings have been updated")); recipeContext.Executed = true; }
/* <ContentTrim> * <ContentTypes> * <add type="page"/> * <add type="widget"/> * </ContentTypes> * <ContentToKeep> * <add identifier="123456789"/> * <add identifier="321654897"/> * </ContentType> * </ContentTrim> */ public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "ContentTrim", StringComparison.OrdinalIgnoreCase)) { return; } _realtimeFeedbackService.Info(T("Entering the 'Content Trim' step")); var contentTypesElement = recipeContext.RecipeStep.Step.Descendants("ContentTypes").FirstOrDefault(); var contentToKeepElement = recipeContext.RecipeStep.Step.Descendants("ContentToKeep").FirstOrDefault(); if (contentTypesElement == null) { _realtimeFeedbackService.Error(T("Could not execute the Content Trim step as there was no 'ContentTypes' element in the step")); return; } if (contentToKeepElement == null) { _realtimeFeedbackService.Error(T("Could not execute the Content Trim step as there was no 'ContentToKeep' element in the step")); return; } var contentTypes = contentTypesElement.Descendants("add").Select(e => e.Attribute("type").Value).ToList(); _realtimeFeedbackService.Info(T("The following content types will be synced:")); foreach (var contentType in contentTypes) { _realtimeFeedbackService.Info(T(contentType)); } var contentToKeep = contentToKeepElement.Descendants("add").Select(e => e.Attribute("identifier").Value).ToList(); _realtimeFeedbackService.Info(T("Identified {0} pieces of content from the remote site", contentTypes.Count())); var contentItems = _contentManager.Query <IdentityPart, IdentityPartRecord>(contentTypes.ToArray()).Where(c => !contentToKeep.Contains(c.Identifier)).List().ToList(); _realtimeFeedbackService.Info(T("Identified {0} pieces of content that exist in the local site, but not in the remote site. This content will be removed.", contentItems.Count())); foreach (var contentItem in contentItems) { _realtimeFeedbackService.Info(T("Removing {0} '{2}' (ID: {1})", contentItem.ContentItem.ContentType, contentItem.ContentItem.Id, contentItem.ContentItem.GetContentName())); _contentManager.Remove(contentItem.ContentItem); } _realtimeFeedbackService.Info(T("The 'Content Trim' step has successfully executed")); recipeContext.Executed = true; }
/* * <ExecutedDataMigrations> * <Migration Name="~/Modules/CJP.ContentSync/ContentMigrations/CJP.ContentSync/TestMigration1" /> */ //Save any migrations that are in the list, delete migrations that aren't in the list public void ExecuteRecipeStep(RecipeContext recipeContext) { if (!String.Equals(recipeContext.RecipeStep.Name, "ExecutedDataMigrations", StringComparison.OrdinalIgnoreCase)) { return; } _realtimeFeedbackService.Info(T("Entering the 'Executed Data Migrations' step. This step will reset the local record of content migrations to the state of the remote server")); var migrations = recipeContext.RecipeStep.Step.Descendants(); var migrationNames = migrations.Where(f => f.Name == "Migration").Select(f => f.Attribute("Name").Value).ToList(); _realtimeFeedbackService.Info(T("Found {0} migrations that have ran remotely:", migrationNames.Count())); foreach (var migrationName in migrationNames) { _realtimeFeedbackService.Info(T(migrationName)); } var locallyRanMigrations = _contentMigrationStateService.GetExecutedMigrations().ToList(); _realtimeFeedbackService.Info(T("Found {0} migrations that have ran locally:", locallyRanMigrations.Count())); foreach (var migrationName in locallyRanMigrations) { _realtimeFeedbackService.Info(T(migrationName)); } foreach (var migration in locallyRanMigrations.Where(m => !migrationNames.Contains(m))) {//migrations that have been executed locally, but not in the recipe that is being executed _realtimeFeedbackService.Info(T("Marking migration '{0}' as pending", migration)); _contentMigrationStateService.MarkMigrationAsPending(migration); } foreach (var migrationToAdd in migrationNames.Where(m => !locallyRanMigrations.Contains(m))) { _realtimeFeedbackService.Info(T("Marking migration '{0}' as executed", migrationToAdd)); _contentMigrationStateService.MarkMigrationAsExecuted(migrationToAdd); } _realtimeFeedbackService.Info(T("The 'Executed Data Migrations' step is finished")); recipeContext.Executed = true; }