public static ProvisioningTemplate SaveResourceValues(ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { var tempFolder = System.IO.Path.GetTempPath(); var languages = ResourceTokens.Select(t => t.Item2).Distinct(); foreach (int language in languages) { var culture = new CultureInfo(language); var resourceFileName = System.IO.Path.Combine(tempFolder, string.Format("{0}.{1}.resx", creationInfo.ResourceFilePrefix, culture.Name)); if (System.IO.File.Exists(resourceFileName)) { // Read existing entries, if any using (ResXResourceReader resxReader = new ResXResourceReader(resourceFileName)) { foreach (DictionaryEntry entry in resxReader) { // find if token is already there var existingToken = ResourceTokens.FirstOrDefault(t => t.Item1 == entry.Key.ToString() && t.Item2 == language); if (existingToken == null) { ResourceTokens.Add(new Tuple<string, int, string>(entry.Key.ToString(), language, entry.Value as string)); } } } } // Create new resource file using (ResXResourceWriter resx = new ResXResourceWriter(resourceFileName)) { foreach (var token in ResourceTokens.Where(t => t.Item2 == language)) { resx.AddResource(token.Item1, token.Item3); } } template.Localizations.Add(new Localization() { LCID = language, Name = culture.NativeName, ResourceFile = string.Format("{0}.{1}.resx", creationInfo.ResourceFilePrefix, culture.Name) }); // Persist the file using the connector using (FileStream stream = System.IO.File.Open(resourceFileName, FileMode.Open)) { creationInfo.FileConnector.SaveFileStream(string.Format("{0}.{1}.resx", creationInfo.ResourceFilePrefix, culture.Name), stream); } // remove the temp resx file System.IO.File.Delete(resourceFileName); } return template; }
private void IncludePageHeaderImageInExport(Web web, string imageServerRelativeUrl, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope) { try { if (!imageServerRelativeUrl.StartsWith("/_LAYOUTS", StringComparison.OrdinalIgnoreCase)) { var pageHeaderImage = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(imageServerRelativeUrl)); web.Context.Load(pageHeaderImage, p => p.Level, p => p.ServerRelativeUrl); web.Context.ExecuteQueryRetry(); LoadAndAddPageImage(web, pageHeaderImage, template, creationInfo, scope); } } catch (Exception ex) { // Eat possible exceptions as header images may point to locations outside of the current site (other site collections, _layouts, CDN's, internet) } }
/// <summary> /// Can be used to extract custom provisioning template from existing site. The extracted template /// will be compared with the default base template. /// </summary> /// <param name="web">Web to get template from</param> /// <param name="creationInfo">Specifies additional settings and/or properties</param> /// <returns>ProvisioningTemplate object with generated values from existing site</returns> public static ProvisioningTemplate GetProvisioningTemplate(this Web web, ProvisioningTemplateCreationInformation creationInfo) { return(new SiteToTemplateConversion().GetRemoteTemplate(web, creationInfo)); }
private void ExtractTemplate(XMLPnPSchemaVersion schema, string path, string packageName, ExtractConfiguration configuration) { SelectedWeb.EnsureProperty(w => w.Url); ProvisioningTemplateCreationInformation creationInformation = null; if (configuration != null) { creationInformation = configuration.ToCreationInformation(SelectedWeb); } else { creationInformation = new ProvisioningTemplateCreationInformation(SelectedWeb); } if (MyInvocation.BoundParameters.ContainsKey("Handlers")) { creationInformation.HandlersToProcess = Handlers; } if (MyInvocation.BoundParameters.ContainsKey("ExcludeHandlers")) { foreach (var handler in (Handlers[])Enum.GetValues(typeof(Handlers))) { if (!ExcludeHandlers.Has(handler) && handler != Handlers.All) { Handlers = Handlers | handler; } } creationInformation.HandlersToProcess = Handlers; } var extension = ""; if (packageName != null) { if (packageName.IndexOf(".", StringComparison.Ordinal) > -1) { extension = packageName.Substring(packageName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); } else { packageName += ".pnp"; extension = ".pnp"; } } var fileSystemConnector = new FileSystemConnector(path, ""); if (extension == ".pnp") { creationInformation.FileConnector = new OpenXMLConnector(packageName, fileSystemConnector); } else { creationInformation.FileConnector = fileSystemConnector; } #pragma warning disable 618 if (MyInvocation.BoundParameters.ContainsKey(nameof(PersistBrandingFiles)) || MyInvocation.BoundParameters.ContainsKey(nameof(PersistComposedLookFiles))) { creationInformation.PersistBrandingFiles = PersistBrandingFiles || PersistComposedLookFiles; } #pragma warning restore 618 creationInformation.PersistPublishingFiles = PersistPublishingFiles; creationInformation.IncludeNativePublishingFiles = IncludeNativePublishingFiles; if (MyInvocation.BoundParameters.ContainsKey(nameof(IncludeSiteGroups))) { creationInformation.IncludeSiteGroups = IncludeSiteGroups; } creationInformation.IncludeTermGroupsSecurity = IncludeTermGroupsSecurity; creationInformation.IncludeSearchConfiguration = IncludeSearchConfiguration; if (MyInvocation.BoundParameters.ContainsKey(nameof(IncludeHiddenLists))) { creationInformation.IncludeHiddenLists = IncludeHiddenLists; } #if !SP2013 && !SP2016 if (MyInvocation.BoundParameters.ContainsKey(nameof(IncludeAllClientSidePages))) { creationInformation.IncludeAllClientSidePages = IncludeAllClientSidePages; } #endif creationInformation.SkipVersionCheck = SkipVersionCheck; if (MyInvocation.BoundParameters.ContainsKey(nameof(ContentTypeGroups)) && ContentTypeGroups != null) { creationInformation.ContentTypeGroupsToInclude = ContentTypeGroups.ToList(); } #if !SP2013 creationInformation.PersistMultiLanguageResources = PersistMultiLanguageResources; if (extension == ".pnp") { // if file is of pnp format, persist all files creationInformation.PersistBrandingFiles = true; creationInformation.PersistPublishingFiles = true; creationInformation.PersistMultiLanguageResources = true; } if (!string.IsNullOrEmpty(ResourceFilePrefix)) { creationInformation.ResourceFilePrefix = ResourceFilePrefix; } else { if (Out != null) { FileInfo fileInfo = new FileInfo(Out); var prefix = fileInfo.Name; // strip extension, if there is any var indexOfLastDot = prefix.LastIndexOf(".", StringComparison.Ordinal); if (indexOfLastDot > -1) { prefix = prefix.Substring(0, indexOfLastDot); } creationInformation.ResourceFilePrefix = prefix; } } #endif if (ExtensibilityHandlers != null) { creationInformation.ExtensibilityHandlers = ExtensibilityHandlers.ToList(); } #pragma warning disable CS0618 // Type or member is obsolete if (NoBaseTemplate) { creationInformation.BaseTemplate = null; } else { creationInformation.BaseTemplate = SelectedWeb.GetBaseTemplate(); } #pragma warning restore CS0618 // Type or member is obsolete creationInformation.ProgressDelegate = (message, step, total) => { var percentage = Convert.ToInt32((100 / Convert.ToDouble(total)) * Convert.ToDouble(step)); WriteProgress(new ProgressRecord(0, $"Extracting Template from {SelectedWeb.Url}", message) { PercentComplete = percentage }); WriteProgress(new ProgressRecord(1, " ", " ") { RecordType = ProgressRecordType.Completed }); }; creationInformation.MessagesDelegate = (message, type) => { switch (type) { case ProvisioningMessageType.Warning: { WriteWarning(message); break; } case ProvisioningMessageType.Progress: { var activity = message; if (message.IndexOf("|") > -1) { var messageSplitted = message.Split('|'); if (messageSplitted.Length == 4) { var current = double.Parse(messageSplitted[2]); var total = double.Parse(messageSplitted[3]); subProgressRecord.RecordType = ProgressRecordType.Processing; subProgressRecord.Activity = messageSplitted[0]; subProgressRecord.StatusDescription = messageSplitted[1]; subProgressRecord.PercentComplete = Convert.ToInt32((100 / total) * current); WriteProgress(subProgressRecord); } else { subProgressRecord.Activity = "Processing"; subProgressRecord.RecordType = ProgressRecordType.Processing; subProgressRecord.StatusDescription = activity; subProgressRecord.PercentComplete = 0; WriteProgress(subProgressRecord); } } else { subProgressRecord.Activity = "Processing"; subProgressRecord.RecordType = ProgressRecordType.Processing; subProgressRecord.StatusDescription = activity; subProgressRecord.PercentComplete = 0; WriteProgress(subProgressRecord); } break; } case ProvisioningMessageType.Completed: { WriteProgress(new ProgressRecord(1, message, " ") { RecordType = ProgressRecordType.Completed }); break; } } }; if (IncludeAllTermGroups) { creationInformation.IncludeAllTermGroups = true; } else { if (IncludeSiteCollectionTermGroup) { creationInformation.IncludeSiteCollectionTermGroup = true; } } if (MyInvocation.BoundParameters.ContainsKey(nameof(ExcludeContentTypesFromSyndication))) { creationInformation.IncludeContentTypesFromSyndication = !ExcludeContentTypesFromSyndication.ToBool(); } if (ListsToExtract != null && ListsToExtract.Count > 0) { creationInformation.ListsToExtract.AddRange(ListsToExtract); } var template = SelectedWeb.GetProvisioningTemplate(creationInformation); // Set metadata for template, if any SetTemplateMetadata(template, TemplateDisplayName, TemplateImagePreviewUrl, TemplateProperties); if (!OutputInstance) { ITemplateFormatter formatter = null; switch (schema) { case XMLPnPSchemaVersion.LATEST: { formatter = XMLPnPSchemaFormatter.LatestFormatter; break; } case XMLPnPSchemaVersion.V201503: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_03); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201505: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_05); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201508: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_08); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201512: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_12); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201605: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2016_05); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201705: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2017_05); break; } case XMLPnPSchemaVersion.V201801: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2018_01); break; } case XMLPnPSchemaVersion.V201805: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2018_05); break; } case XMLPnPSchemaVersion.V201807: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2018_07); break; } case XMLPnPSchemaVersion.V201903: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2019_03); break; } case XMLPnPSchemaVersion.V201909: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2019_09); break; } } if (extension == ".pnp") { IsolatedStorage.InitializeIsolatedStorage(); XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider( creationInformation.FileConnector as OpenXMLConnector); var templateFileName = packageName.Substring(0, packageName.LastIndexOf(".", StringComparison.Ordinal)) + ".xml"; provider.SaveAs(template, templateFileName, formatter, TemplateProviderExtensions); } else { if (Out != null) { XMLTemplateProvider provider = new XMLFileSystemTemplateProvider(path, ""); provider.SaveAs(template, Path.Combine(path, packageName), formatter, TemplateProviderExtensions); } else { var outputStream = formatter.ToFormattedTemplate(template); var reader = new StreamReader(outputStream); WriteObject(reader.ReadToEnd()); } } } else { WriteObject(template); } }
public static ProvisioningTemplate SaveResourceValues(ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { var tempFolder = Path.GetTempPath(); List <Tuple <string, int, string> > resourceTokens = creationInfo.ResourceTokens; IEnumerable <int> languages = resourceTokens.Select(t => t.Item2).Distinct(); foreach (int language in languages) { var culture = new CultureInfo(language); var resourceFileName = Path.Combine(tempFolder, $"{creationInfo.ResourceFilePrefix}.{culture.Name}.resx"); if (System.IO.File.Exists(resourceFileName)) { // Read existing entries, if any #if !NETSTANDARD2_0 using (ResXResourceReader resxReader = new ResXResourceReader(resourceFileName)) #else using (ResourceReader resxReader = new ResourceReader(resourceFileName)) #endif { foreach (DictionaryEntry entry in resxReader) { // find if token is already there var existingToken = resourceTokens.FirstOrDefault(t => t.Item1 == entry.Key.ToString() && t.Item2 == language); if (existingToken == null) { resourceTokens.Add(new Tuple <string, int, string>(entry.Key.ToString(), language, entry.Value as string)); } } } } // Create new resource file #if !NETSTANDARD2_0 using (ResXResourceWriter resx = new ResXResourceWriter(resourceFileName)) #else using (ResourceWriter resx = new ResourceWriter(resourceFileName)) #endif { foreach (var token in resourceTokens.Where(t => t.Item2 == language)) { resx.AddResource(token.Item1, token.Item3); } } template.Localizations.Add(new Localization() { LCID = language, Name = culture.NativeName, ResourceFile = $"{creationInfo.ResourceFilePrefix}.{culture.Name}.resx" }); // Persist the file using the connector using (FileStream stream = System.IO.File.Open(resourceFileName, FileMode.Open)) { creationInfo.FileConnector.SaveFileStream($"{creationInfo.ResourceFilePrefix}.{culture.Name}.resx", stream); } // remove the temp resx file System.IO.File.Delete(resourceFileName); } return(template); }
public static bool PersistResourceValue(string token, int lcid, string title, ProvisioningTemplateCreationInformation creationInfo) { bool returnValue = false; if (!string.IsNullOrWhiteSpace(title)) { returnValue = true; creationInfo.ResourceTokens.Add(new Tuple <string, int, string>(token, lcid, title)); } return(returnValue); }
private ProvisioningTemplate GetFileContents(Web web, ProvisioningTemplate template, string pageFullUrl, ProvisioningTemplateCreationInformation creationInfo, string pageUrl) { try { var fullUri = new Uri(UrlUtility.Combine(web.Url, pageUrl)); var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1) .ToArray() .Aggregate((i, x) => i + x) .TrimEnd('/'); var fileName = fullUri.Segments[fullUri.Segments.Count() - 1]; var webParts = web.GetWebParts(pageFullUrl); var file = web.GetFileByServerRelativeUrl(pageFullUrl); var homeFile = new OfficeDevPnP.Core.Framework.Provisioning.Model.File() { Folder = Tokenize(folderPath, web.Url), Src = fileName, Overwrite = true, }; // Add field values to file RetrieveFieldValues(web, file, homeFile); // Add WebParts to file foreach (var webPart in webParts) { var webPartxml = TokenizeWebPartXml(web, web.GetWebPartXml(webPart.Id, pageFullUrl)); OfficeDevPnP.Core.Framework.Provisioning.Model.WebPart newWp = new OfficeDevPnP.Core.Framework. Provisioning.Model.WebPart() { Title = webPart.WebPart.Title, Row = (uint)webPart.WebPart.ZoneIndex, Order = (uint)webPart.WebPart.ZoneIndex, Contents = webPartxml }; #if !SP2016 // As long as we've no CSOM library that has the ZoneID we can't use the version check as things don't compile... if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { newWp.Zone = webPart.ZoneId; } #endif homeFile.WebParts.Add(newWp); } template.Files.Add(homeFile); // Persist file using connector if (creationInfo.PersistBrandingFiles) { PersistFile(web, creationInfo, folderPath, fileName); } return(template); } catch (Exception ex) { throw ex; } }
/// <summary> /// Converts the Configuration to a ProvisioningTemplateCreationInformation object for backwards compatibility /// </summary> /// <param name="web"></param> /// <returns></returns> public ProvisioningTemplateCreationInformation ToCreationInformation(Web web) { var ci = new ProvisioningTemplateCreationInformation(web) { ExtractConfiguration = this, PersistBrandingFiles = PersistAssetFiles, PersistPublishingFiles = PersistAssetFiles, BaseTemplate = web.GetBaseTemplate(), FileConnector = this.FileConnector, IncludeAllClientSidePages = this.Pages.IncludeAllClientSidePages, IncludeHiddenLists = this.Lists.IncludeHiddenLists, IncludeSiteGroups = this.SiteSecurity.IncludeSiteGroups, ContentTypeGroupsToInclude = this.ContentTypes.Groups, IncludeContentTypesFromSyndication = !this.ContentTypes.ExcludeFromSyndication, IncludeTermGroupsSecurity = this.Taxonomy.IncludeSecurity, IncludeSiteCollectionTermGroup = this.Taxonomy.IncludeSiteCollectionTermGroup, IncludeSearchConfiguration = this.SearchSettings.Include, IncludeAllTermGroups = this.Taxonomy.IncludeAllTermGroups, ExtensibilityHandlers = this.Extensibility.Handlers }; ci.IncludeAllTermGroups = this.Taxonomy.IncludeAllTermGroups; ci.IncludeNativePublishingFiles = this.Publishing.IncludeNativePublishingFiles; ci.ListsToExtract = this.Lists != null && this.Lists.Lists.Any() ? this.Lists.Lists.Select(l => l.Title).ToList() : null; ci.PersistMultiLanguageResources = this.MultiLanguage.PersistResources; ci.PersistPublishingFiles = this.Publishing.Persist; ci.ResourceFilePrefix = this.MultiLanguage.ResourceFilePrefix; if (Handlers.Any()) { ci.HandlersToProcess = Model.Handlers.None; foreach (var handler in Handlers) { Model.Handlers handlerEnumValue = Model.Handlers.None; switch (handler) { case ConfigurationHandler.Pages: handlerEnumValue = Model.Handlers.PageContents; break; case ConfigurationHandler.Taxonomy: handlerEnumValue = Model.Handlers.TermGroups; break; default: handlerEnumValue = (Model.Handlers)Enum.Parse(typeof(Model.Handlers), handler.ToString()); break; } ci.HandlersToProcess |= handlerEnumValue; } } else { ci.HandlersToProcess = Model.Handlers.All; } if (this.ProgressDelegate != null) { ci.ProgressDelegate = (message, step, total) => { ProgressDelegate(message, step, total); }; } if (this.MessagesDelegate != null) { ci.MessagesDelegate = (message, type) => { MessagesDelegate(message, type); }; } return(ci); }
private void SaveProvisioningTemplateInternal(ClientContext context, GetProvisioningTemplateJob job, Boolean globalRepository = true) { // Fix the job filename if it is missing the .pnp extension if (!job.FileName.ToLower().EndsWith(".pnp")) { job.FileName += ".pnp"; } // Get the Access Token from the current context //var accessToken = "Bearer " + context.GetAccessToken(); var accessToken = context.GetAccessToken(); Console.WriteLine("Bearer " + accessToken); // Get a reference to the target web site Web web = context.Web; context.Load(web, w => w.Url, w => w.ServerRelativeUrl); context.ExecuteQueryRetry(); // Prepare the support variables ClientContext repositoryContext = null; Web repositoryWeb = null; // Define whether we need to use the global infrastructural repository or the local one if (globalRepository) { // Get a reference to the global repository web site and context repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext( PnPPartnerPackSettings.InfrastructureSiteUrl); } else { // Get a reference to the local repository web site and context repositoryContext = web.Context.GetSiteCollectionContext(); } using (repositoryContext) { repositoryWeb = repositoryContext.Site.RootWeb; repositoryContext.Load(repositoryWeb, w => w.Url); repositoryContext.ExecuteQueryRetry(); // Configure the XML SharePoint provider for the Infrastructural Site Collection XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider(job.FileName, new SharePointConnector(repositoryContext, repositoryWeb.Url, PnPPartnerPackConstants.PnPProvisioningTemplates)); ProvisioningTemplateCreationInformation ptci = new ProvisioningTemplateCreationInformation(web); ptci.FileConnector = provider.Connector; ptci.IncludeAllTermGroups = job.IncludeAllTermGroups; ptci.IncludeSearchConfiguration = job.IncludeSearchConfiguration; ptci.IncludeSiteCollectionTermGroup = job.IncludeSiteCollectionTermGroup; ptci.IncludeSiteGroups = job.IncludeSiteGroups; ptci.PersistBrandingFiles = job.PersistComposedLookFiles; // We do intentionally remove taxonomies and search, which are not supported // in the AppOnly Authorization model // For further details, see the PnP Partner Pack documentation ptci.HandlersToProcess ^= Handlers.TermGroups; ptci.HandlersToProcess ^= Handlers.SearchSettings; // Extract the current template ProvisioningTemplate templateToSave = web.GetProvisioningTemplate(ptci); templateToSave.Description = job.Description; templateToSave.DisplayName = job.Title; if (job.PersistComposedLookFiles) { // Create Theme Entity object ThemeEntity themeEntity = web.GetCurrentComposedLook(); foreach (var p in themeEntity.GetType().GetProperties().Where(p => p.GetGetMethod().GetParameters().Count() == 0)) { string propName = p.Name; string propValue = Convert.ToString(p.GetValue(themeEntity, null)); if (propName == "Theme") { propName = "ColorFile"; } else if (propName == "Font") { propName = "FontFile"; } else if (propName == "BackgroundImage") { propValue = "PlaceHolderValue"; } else if (propName == "Name" && String.IsNullOrEmpty(propValue)) { propValue = "CustomTheme"; } string fileName = propValue.Substring(propValue.LastIndexOf("/") + 1); string relativeURL = propValue.Substring(0, propValue.LastIndexOf("/") + 1); // Update template Files if (propName != "Name" && propName != "IsCustomComposedLook" && !String.IsNullOrEmpty(propValue)) { var property = templateToSave.ComposedLook.GetType().GetProperty(propName); try { string folderPath = ""; Stream fileStream = null; if (propName == "BackgroundImage") { if (job.templateBackgroundImgFile != null) { folderPath = "{site}/SiteAssets"; fileName = job.FileName.ToLower().Replace(".pnp", ".png"); fileStream = job.templateBackgroundImgFile.ToStream(); Console.WriteLine("fileName: " + fileName); Console.WriteLine("fileStream: " + fileStream); templateToSave.ComposedLook.BackgroundFile = String.Format("{{sitecollection}}/SiteAssets/{0}", fileName); } } else if (propName.Contains("MasterPage")) { folderPath = "{masterpagecatalog}"; var strUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}{2}')/$value", web.Url, web.ServerRelativeUrl, propValue); fileStream = HttpHelper.MakeGetRequestForStream(strUrl, "application/octet-stream", accessToken); property.SetValue(templateToSave.ComposedLook, String.Format("{{masterpagecatalog}}/{0}", fileName), new object[] { }); } else { folderPath = "{themecatalog}/15"; var strUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}{2}')/$value", web.Url, web.ServerRelativeUrl, propValue); fileStream = HttpHelper.MakeGetRequestForStream(strUrl, "application/octet-stream", accessToken); property.SetValue(templateToSave.ComposedLook, String.Format("{{themecatalog}}/15/{0}", fileName), new object[] { }); } Console.WriteLine("Saving files: {0}, {1}", fileName, fileStream); provider.Connector.SaveFileStream(fileName, fileStream); Console.WriteLine("File Paths: {0}, {1}", fileName, folderPath); templateToSave.Files.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.File { Src = fileName, Folder = folderPath, Overwrite = true, }); Console.WriteLine("Files saved: {0}, {1}", fileName, folderPath); } catch (Exception ex) { Console.WriteLine(ex); } } else if (propName == "Name") { var property = templateToSave.ComposedLook.GetType().GetProperty(propName); property.SetValue(templateToSave.ComposedLook, fileName, new object[] { }); } } if (job.templateAltCSSFile != null) { //TODO: Add handling for native Alternate CSS //web.AlternateCssUrl; string folderPath = "{site}/SiteAssets"; string fileName = job.FileName.ToLower().Replace(".pnp", ".css"); Stream fileStream = job.templateAltCSSFile.ToStream(); provider.Connector.SaveFileStream(fileName, fileStream); templateToSave.WebSettings = new WebSettings { AlternateCSS = String.Format("{{sitecollection}}/SiteAssets/{0}", fileName), }; Console.WriteLine("File Paths: {0}, {1}", fileName, folderPath); templateToSave.Files.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.File { Src = fileName, Folder = folderPath, Overwrite = true, }); } } // Save template image preview in folder Microsoft.SharePoint.Client.Folder templatesFolder = repositoryWeb.GetFolderByServerRelativeUrl(PnPPartnerPackConstants.PnPProvisioningTemplates); repositoryContext.Load(templatesFolder, f => f.ServerRelativeUrl, f => f.Name); repositoryContext.ExecuteQueryRetry(); // If there is a preview image if (job.TemplateImageFile != null) { // Determine the preview image file name String previewImageFileName = job.FileName.ToLower().Replace(".pnp", "_preview.png"); // Save the preview image inside the Open XML package provider.Connector.SaveFileStream(previewImageFileName, job.TemplateImageFile.ToStream()); // And store URL in the XML file templateToSave.ImagePreviewUrl = String.Format("{0}{1}/{2}/{3}/{4}", repositoryWeb.Url.ToLower().StartsWith("https") ? "pnps" : "pnp", repositoryWeb.Url.Substring(repositoryWeb.Url.IndexOf("://")), templatesFolder.Name, job.FileName, previewImageFileName); } // And save it on the file system provider.SaveAs(templateToSave, job.FileName.ToLower().Replace(".pnp", ".xml")); Microsoft.SharePoint.Client.File templateFile = templatesFolder.GetFile(job.FileName); ListItem item = templateFile.ListItemAllFields; item[PnPPartnerPackConstants.ContentTypeIdField] = PnPPartnerPackConstants.PnPProvisioningTemplateContentTypeId; item[PnPPartnerPackConstants.TitleField] = job.Title; item[PnPPartnerPackConstants.PnPProvisioningTemplateScope] = job.Scope.ToString(); item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] = job.SourceSiteUrl; item.Update(); repositoryContext.ExecuteQueryRetry(); } }
public ProvisioningTemplate Extract(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope, string configurationData) { webExtract = ctx.Web; ctx.Load(webExtract); ctx.ExecuteQueryRetry(); //Save Template extractTemplate = template; string libraryName = "SitePages"; //Load list foreach (ListInstance templateList in extractTemplate.Lists) { if (templateList.Url.ToString().Contains(libraryName)) { //Load all ModernPage to copy List sourceList = webExtract.GetListByUrl(templateList.Url.ToString()); ListItemCollection modernPagesToMigrate = sourceList.GetItems(CamlQuery.CreateAllItemsQuery()); webExtract.Context.Load(modernPagesToMigrate, pages => pages.Include(page => page.DisplayName)); webExtract.Context.ExecuteQueryRetry(); var fieldColl = sourceList.Fields; webExtract.Context.Load(fieldColl); webExtract.Context.ExecuteQuery(); //Load items foreach (ListItem page in modernPagesToMigrate) { webExtract.Context.Load(page); webExtract.Context.ExecuteQueryRetry(); webExtract.Context.Load(page.File); webExtract.Context.ExecuteQueryRetry(); // Ignore the Home Page webExtract.EnsureProperties(w => w.RootFolder.WelcomePage, w => w.ServerRelativeUrl, w => w.Url); string homePageUrl = string.Empty; var homepageName = string.Empty; try { homePageUrl = webExtract.RootFolder.WelcomePage; homepageName = System.IO.Path.GetFileName(webExtract.RootFolder.WelcomePage); } catch (Exception e) { if (string.IsNullOrEmpty(homePageUrl)) { homepageName = "Home.aspx"; } } string pageUrl = page.File.ServerRelativeUrl.Substring(page.File.ServerRelativeUrl.IndexOf(libraryName)); if (homepageName != page.File.Name && page["ContentTypeId"].ToString().StartsWith(BuiltInContentTypeId.ModernArticlePage)) { // Extract Modern Page new ClientSidePageContentsHelper().ExtractClientSidePage(webExtract, extractTemplate, creationInformation, scope, pageUrl, page.File.Name, false); } } } } return(extractTemplate); }
public TestProvisioningTemplateResult TestProvisioningTemplate(ClientContext cc, string templateName, Handlers handlersToProcess = Handlers.All, ProvisioningTemplateApplyingInformation ptai = null, ProvisioningTemplateCreationInformation ptci = null) { try { // Read the template from XML and apply it XMLTemplateProvider provider = new XMLFileSystemTemplateProvider(string.Format(@"{0}\..\..\Framework\Functional", AppDomain.CurrentDomain.BaseDirectory), "Templates"); ProvisioningTemplate sourceTemplate = provider.GetTemplate(templateName); if (ptai == null) { ptai = new ProvisioningTemplateApplyingInformation(); ptai.HandlersToProcess = handlersToProcess; } if (ptai.ProgressDelegate == null) { ptai.ProgressDelegate = delegate(String message, Int32 progress, Int32 total) { Console.WriteLine("Applying template - {0}/{1} - {2}", progress, total, message); }; } sourceTemplate.Connector = provider.Connector; TokenParser sourceTokenParser = new TokenParser(cc.Web, sourceTemplate); cc.Web.ApplyProvisioningTemplate(sourceTemplate, ptai); // Read the site we applied the template to if (ptci == null) { ptci = new ProvisioningTemplateCreationInformation(cc.Web); ptci.HandlersToProcess = handlersToProcess; } if (ptci.ProgressDelegate == null) { ptci.ProgressDelegate = delegate(String message, Int32 progress, Int32 total) { Console.WriteLine("Getting template - {0}/{1} - {2}", progress, total, message); }; } ProvisioningTemplate targetTemplate = cc.Web.GetProvisioningTemplate(ptci); return(new TestProvisioningTemplateResult() { SourceTemplate = sourceTemplate, SourceTokenParser = sourceTokenParser, TargetTemplate = targetTemplate, TargetTokenParser = new TokenParser(cc.Web, targetTemplate), }); } catch (Exception ex) { Console.WriteLine(ex.ToDetailedString()); throw; } }
private void ExtractTemplate(XMLPnPSchemaVersion schema, string path, string packageName) { SelectedWeb.EnsureProperty(w => w.Url); var creationInformation = new ProvisioningTemplateCreationInformation(SelectedWeb); creationInformation.HandlersToProcess = Handlers.Lists; var extension = ""; if (packageName != null) { if (packageName.IndexOf(".", StringComparison.Ordinal) > -1) { extension = packageName.Substring(packageName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); } else { packageName += ".pnp"; extension = ".pnp"; } } var fileSystemConnector = new FileSystemConnector(path, ""); if (extension == ".pnp") { creationInformation.FileConnector = new OpenXMLConnector(packageName, fileSystemConnector); } else { creationInformation.FileConnector = fileSystemConnector; } creationInformation.ProgressDelegate = (message, step, total) => { var percentage = Convert.ToInt32((100 / Convert.ToDouble(total)) * Convert.ToDouble(step)); WriteProgress(new ProgressRecord(0, $"Extracting Template from {SelectedWeb.Url}", message) { PercentComplete = percentage }); }; creationInformation.MessagesDelegate = (message, type) => { switch (type) { case ProvisioningMessageType.Warning: { WriteWarning(message); break; } case ProvisioningMessageType.Progress: { var activity = message; if (message.IndexOf("|") > -1) { var messageSplitted = message.Split('|'); if (messageSplitted.Length == 4) { var current = double.Parse(messageSplitted[2]); var total = double.Parse(messageSplitted[3]); subProgressRecord.RecordType = ProgressRecordType.Processing; subProgressRecord.Activity = messageSplitted[0]; subProgressRecord.StatusDescription = messageSplitted[1]; subProgressRecord.PercentComplete = Convert.ToInt32((100 / total) * current); WriteProgress(subProgressRecord); } else { subProgressRecord.Activity = "Processing"; subProgressRecord.RecordType = ProgressRecordType.Processing; subProgressRecord.StatusDescription = activity; subProgressRecord.PercentComplete = 0; WriteProgress(subProgressRecord); } } else { subProgressRecord.Activity = "Processing"; subProgressRecord.RecordType = ProgressRecordType.Processing; subProgressRecord.StatusDescription = activity; subProgressRecord.PercentComplete = 0; WriteProgress(subProgressRecord); } break; } case ProvisioningMessageType.Completed: { WriteProgress(new ProgressRecord(1, message, " ") { RecordType = ProgressRecordType.Completed }); break; } } }; if (List != null && List.Count > 0) { creationInformation.ListsToExtract.AddRange(List); } var template = SelectedWeb.GetProvisioningTemplate(creationInformation); if (!OutputInstance) { ITemplateFormatter formatter = null; switch (schema) { case XMLPnPSchemaVersion.LATEST: { formatter = XMLPnPSchemaFormatter.LatestFormatter; break; } case XMLPnPSchemaVersion.V201503: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_03); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201505: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_05); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201508: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_08); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201512: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_12); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201605: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2016_05); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201705: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2017_05); break; } case XMLPnPSchemaVersion.V201801: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2018_01); break; } case XMLPnPSchemaVersion.V201805: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2018_05); break; } case XMLPnPSchemaVersion.V201807: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2018_07); break; } case XMLPnPSchemaVersion.V201903: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2019_03); break; } case XMLPnPSchemaVersion.V201909: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2019_09); break; } } if (extension == ".pnp") { IsolatedStorage.InitializeIsolatedStorage(); XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider( creationInformation.FileConnector as OpenXMLConnector); var templateFileName = packageName.Substring(0, packageName.LastIndexOf(".", StringComparison.Ordinal)) + ".xml"; provider.SaveAs(template, templateFileName, formatter, null); } else { if (Out != null) { XMLTemplateProvider provider = new XMLFileSystemTemplateProvider(path, ""); provider.SaveAs(template, Path.Combine(path, packageName), formatter, null); } else { var outputStream = formatter.ToFormattedTemplate(template); var reader = new StreamReader(outputStream); WriteObject(reader.ReadToEnd()); } } } else { WriteObject(template); } }
private string GetProvisioningTemplateXML(XMLPnPSchemaVersion schema, string path) { SelectedWeb.EnsureProperty(w => w.Url); var creationInformation = new ProvisioningTemplateCreationInformation(SelectedWeb); if (this.MyInvocation.BoundParameters.ContainsKey("Handlers")) { creationInformation.HandlersToProcess = Handlers; } if (this.MyInvocation.BoundParameters.ContainsKey("ExcludeHandlers")) { foreach (var handler in (OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers[])Enum.GetValues(typeof(Handlers))) { if (!ExcludeHandlers.Has(handler) && handler != Handlers.All) { Handlers = Handlers | handler; } } creationInformation.HandlersToProcess = Handlers; } creationInformation.PersistBrandingFiles = PersistBrandingFiles || PersistComposedLookFiles; creationInformation.PersistPublishingFiles = PersistPublishingFiles; creationInformation.IncludeNativePublishingFiles = IncludeNativePublishingFiles; creationInformation.IncludeSiteGroups = IncludeSiteGroups; if (ExtensibilityHandlers != null) { creationInformation.ExtensibilityHandlers = ExtensibilityHandlers.ToList <ExtensibilityHandler>(); } creationInformation.FileConnector = new FileSystemConnector(path, ""); #pragma warning disable CS0618 // Type or member is obsolete if (NoBaseTemplate) { creationInformation.BaseTemplate = null; } else { creationInformation.BaseTemplate = this.SelectedWeb.GetBaseTemplate(); } #pragma warning restore CS0618 // Type or member is obsolete creationInformation.ProgressDelegate = (message, step, total) => { WriteProgress(new ProgressRecord(0, string.Format("Extracting Template from {0}", SelectedWeb.Url), message) { PercentComplete = (100 / total) * step }); }; creationInformation.MessagesDelegate = (message, type) => { if (type == ProvisioningMessageType.Warning) { WriteWarning(message); } }; if (IncludeAllTermGroups) { creationInformation.IncludeAllTermGroups = true; } else { if (IncludeSiteCollectionTermGroup) { creationInformation.IncludeSiteCollectionTermGroup = true; } } var template = SelectedWeb.GetProvisioningTemplate(creationInformation); ITemplateFormatter formatter = null; switch (schema) { case XMLPnPSchemaVersion.LATEST: { formatter = XMLPnPSchemaFormatter.LatestFormatter; break; } case XMLPnPSchemaVersion.V201503: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_03); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201505: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_05); break; } case XMLPnPSchemaVersion.V201508: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_08); break; } case XMLPnPSchemaVersion.V201512: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_12); break; } } var _outputStream = formatter.ToFormattedTemplate(template); StreamReader reader = new StreamReader(_outputStream); return(reader.ReadToEnd()); }
/// <summary> /// Method to Invoke Custom Extraction Handlers. /// </summary> /// <remarks> /// Ensure the ClientContext is not disposed in the custom provider. /// </remarks> /// <param name="ctx">Authenticated ClientContext that is passed to the custom provider.</param> /// <param name="handler">A custom Extensibility Provisioning Provider</param> /// <param name="template">ProvisioningTemplate that is passed to the custom provider</param> /// <param name="creationInformation">The Provisioning Template creation information object</param> /// <param name="scope">The PnPMonitoredScope of the current step in the pipeline</param> /// <exception cref="ExtensiblityPipelineException"></exception> /// <exception cref="ArgumentException">Provider.Assembly or Provider.Type is NullOrWhiteSpace></exception> /// <exception cref="ArgumentNullException">ClientContext is Null></exception> public ProvisioningTemplate ExecuteExtensibilityExtractionCallOut(ClientContext ctx, ExtensibilityHandler handler, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope) { var _loggingSource = "OfficeDevPnP.Core.Framework.Provisioning.Extensibility.ExtensibilityManager.ExecuteCallout"; if (ctx == null) { throw new ArgumentNullException(CoreResources.Provisioning_Extensibility_Pipeline_ClientCtxNull); } if (string.IsNullOrWhiteSpace(handler.Assembly)) { throw new ArgumentException(CoreResources.Provisioning_Extensibility_Pipeline_Missing_AssemblyName); } if (string.IsNullOrWhiteSpace(handler.Type)) { throw new ArgumentException(CoreResources.Provisioning_Extensibility_Pipeline_Missing_TypeName); } ProvisioningTemplate parsedTemplate = null; try { var _instance = GetProviderInstance(handler); if (_instance is IProvisioningExtensibilityHandler) { Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation, handler.Assembly, handler.Type); parsedTemplate = (_instance as IProvisioningExtensibilityHandler).Extract(ctx, template, creationInformation, scope, handler.Configuration); Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Success, handler.Assembly, handler.Type); } else { parsedTemplate = template; } } catch (Exception ex) { string _message = string.Format( CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); Log.Error(_loggingSource, _message); throw new ExtensiblityPipelineException(_message, ex); } return(parsedTemplate); }
public static bool PersistResourceValue(UserResource userResource, string token, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { bool returnValue = false; foreach (var language in template.SupportedUILanguages) { var culture = new CultureInfo(language.LCID); var value = userResource.GetValueForUICulture(culture.Name); userResource.Context.ExecuteQueryRetry(); if (!string.IsNullOrEmpty(value.Value)) { returnValue = true; ResourceTokens.Add(new Tuple<string, int, string>(token, language.LCID, value.Value)); } } return returnValue; }
public void ExtractItemPathValues(ListItem item, Dictionary<string, string> dataRowValues, ProvisioningTemplateCreationInformation creationInfo, out string fileSrc) { fileSrc = null; string dir = item[FIELD_ItemDir] as string; var dirListRel = ""; if (!string.IsNullOrEmpty(dir) && dir.StartsWith(m_listServerRelativeUrl, StringComparison.OrdinalIgnoreCase)) { dirListRel = dir.Substring(m_listServerRelativeUrl.Length).Trim('/'); if (!string.IsNullOrEmpty(dirListRel)) { dataRowValues[FIELD_ItemDir] = dirListRel; } if (item.FileSystemObjectType == FileSystemObjectType.Folder) { dataRowValues[FIELD_ItemType] = FIELD_ItemType_FolderValue; dataRowValues[FIELD_ItemName] = item[FIELD_ItemName] as string; } else if (item.FileSystemObjectType == FileSystemObjectType.File) { string fileName = item[FIELD_ItemName] as string; if (!string.IsNullOrEmpty(fileName) && ( this.List.BaseType == BaseType.DocumentLibrary )) { string fileRelUrl = TokenParser.CombineUrl(m_listServerRelativeUrl, TokenParser.CombineUrl(dirListRel, fileName)).TrimStart('/'); fileSrc = DownloadFile(fileRelUrl, item, creationInfo); if (!string.IsNullOrEmpty(fileSrc)) { dataRowValues[FIELD_ItemName] = fileName; dataRowValues[FIELD_ItemType] = FIELD_ItemType_FileValue; } } } } }
public ProvisioningTemplate Extract(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope, string configurationData) { var web = ctx.Web; #region Extract all client side pages var clientSidePageContentsHelper = new ClientSidePageContentsHelper(); // Extract the Home Page web.EnsureProperties(w => w.RootFolder.WelcomePage, w => w.ServerRelativeUrl, w => w.Url); var homePageUrl = web.RootFolder.WelcomePage; // Get pages library ListCollection listCollection = web.Lists; listCollection.EnsureProperties(coll => coll.Include(li => li.BaseTemplate, li => li.RootFolder)); var sitePagesLibrary = listCollection.Where(p => p.BaseTemplate == (int)ListTemplateType.WebPageLibrary).FirstOrDefault(); if (sitePagesLibrary != null) { CamlQuery query = new CamlQuery { ViewXml = CAMLQueryByExtension }; var pages = sitePagesLibrary.GetItems(query); web.Context.Load(pages); web.Context.ExecuteQueryRetry(); if (pages.FirstOrDefault() != null) { foreach (var page in pages) { string pageUrl = null; string pageName = ""; if (page.FieldValues.ContainsKey(FileRefField) && !String.IsNullOrEmpty(page[FileRefField].ToString())) { pageUrl = page[FileRefField].ToString(); pageName = page[FileLeafRefField].ToString(); } else { //skip page continue; } // Is this page the web's home page? bool isHomePage = false; if (pageUrl.EndsWith(homePageUrl, StringComparison.InvariantCultureIgnoreCase)) { isHomePage = true; } // Is this a client side page? if (FieldExistsAndUsed(page, ClientSideApplicationId) && page[ClientSideApplicationId].ToString().Equals(FeatureId_Web_ModernPage.ToString(), StringComparison.InvariantCultureIgnoreCase)) { // extract the page using the OOB logic clientSidePageContentsHelper.ExtractClientSidePage(web, template, creationInformation, scope, pageUrl, pageName, isHomePage); } } } } #endregion #region Cleanup template // Mark all pages as overwrite foreach (var page in template.ClientSidePages) { page.Overwrite = true; } // Drop all lists except FaqList and Site Assets foreach (var list in template.Lists.ToList()) { if (!(list.Url.Equals("Lists/FAQList", StringComparison.CurrentCultureIgnoreCase) || list.Url.Equals("SiteAssets", StringComparison.CurrentCultureIgnoreCase))) { template.Lists.Remove(list); } } // Mark all files to be published in target foreach (var file in template.Files) { file.Level = OfficeDevPnP.Core.Framework.Provisioning.Model.FileLevel.Published; } // Export the FAQ list items try { var faqTemplateList = template.Lists.Where(p => p.Url.Equals("Lists/FAQList", StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault(); if (faqTemplateList != null) { var faqList = web.GetListByUrl("Lists/FAQList"); ListItemCollection faqListItems = faqList.GetItems(CamlQuery.CreateAllItemsQuery()); web.Context.Load(faqListItems, f => f.Include(item => item["Title"], item => item["Product"], item => item["Section_x0020_Header"], item => item["Answer"], item => item["Visible"], item => item["SortOrder"])); web.Context.ExecuteQueryRetry(); foreach (ListItem faq in faqListItems) { var faqValues = new Dictionary <string, string>(); faqValues.Add("Title", FieldExistsAndUsed(faq, "Title") ? faq["Title"].ToString() : ""); faqValues.Add("Product", FieldExistsAndUsed(faq, "Product") ? faq["Product"].ToString() : ""); faqValues.Add("Section_x0020_Header", FieldExistsAndUsed(faq, "Section_x0020_Header") ? faq["Section_x0020_Header"].ToString() : ""); faqValues.Add("Answer", FieldExistsAndUsed(faq, "Answer") ? TokenizeField(web, faq["Answer"].ToString()) : ""); faqValues.Add("Visible", FieldExistsAndUsed(faq, "Visible") ? faq["Visible"].ToString() : ""); faqValues.Add("SortOrder", FieldExistsAndUsed(faq, "SortOrder") ? faq["SortOrder"].ToString() : ""); faqTemplateList.DataRows.Add(new DataRow(faqValues, faq["Title"].ToString())); } // Configure data rows faqTemplateList.DataRows.KeyColumn = "Title"; faqTemplateList.DataRows.UpdateBehavior = UpdateBehavior.Overwrite; } } catch (Exception ex) { scope.LogError("Something went wrong with the extraction of the list items. Error {0}", ex.Message); } #endregion return(template); }
public async Task CanExportAndImportAssociatedGroupsProperlyInNewNoScriptSite() { if (TestCommon.AppOnlyTesting()) { Assert.Inconclusive("Site creation requires owner, so this will not yet work in app-only"); } this.CheckAndExcludeTestNotSupportedForAppOnlyTestting(); var newCommSiteUrl = ""; var newSiteTitle = "Comm Site Test - Groups"; var loginName = ""; ProvisioningTemplate template; using (var clientContext = TestCommon.CreateClientContext()) { // get the template from real site as this produced the template that lead to too many groups being created which lead to #2127 var creationInfo = new ProvisioningTemplateCreationInformation(clientContext.Web) { HandlersToProcess = Handlers.SiteSecurity }; template = clientContext.Web.GetProvisioningTemplate(); var user = clientContext.Web.CurrentUser; clientContext.Load(user); clientContext.ExecuteQueryRetry(); loginName = user.LoginName; template.Security.AdditionalMembers.Add(new User() { Name = loginName }); template.Security.AdditionalOwners.Add(new User() { Name = loginName }); template.Security.AdditionalVisitors.Add(new User() { Name = loginName }); newCommSiteUrl = await CreateCommunicationSite(clientContext, newSiteTitle); } try { using (var ctx = TestCommon.CreateClientContext(newCommSiteUrl)) { Web web = ctx.Web; var parser = new TokenParser(ctx.Web, template); new ObjectSiteSecurity().ProvisionObjects(web, template, parser, new ProvisioningTemplateApplyingInformation()); ctx.Load(web, w => w.SiteGroups, w => w.AssociatedOwnerGroup.Users, w => w.AssociatedOwnerGroup.Title, w => w.AssociatedMemberGroup.Users, w => w.AssociatedMemberGroup.Title, w => w.AssociatedVisitorGroup.Users, w => w.AssociatedVisitorGroup.Title); ctx.ExecuteQueryRetry(); Assert.AreEqual(3, web.SiteGroups.Count, "Unexpected number of groups found"); Assert.AreEqual(1, web.AssociatedVisitorGroup.Users.Count(u => u.LoginName == loginName)); Assert.AreEqual(1, web.AssociatedMemberGroup.Users.Count(u => u.LoginName == loginName)); Assert.AreEqual(1, web.AssociatedOwnerGroup.Users.Count(u => u.LoginName == loginName)); Assert.AreEqual(newSiteTitle + " Visitors", web.AssociatedVisitorGroup.Title); Assert.AreEqual(newSiteTitle + " Members", web.AssociatedMemberGroup.Title); Assert.AreEqual(newSiteTitle + " Owners", web.AssociatedOwnerGroup.Title); } } finally { using (var clientContext = TestCommon.CreateTenantClientContext()) { var tenant = new Tenant(clientContext); tenant.DeleteSiteCollection(newCommSiteUrl, false); } } }
/// <summary> /// Method to Invoke Custom Extraction Handlers. /// </summary> /// <remarks> /// Ensure the ClientContext is not disposed in the custom provider. /// </remarks> /// <param name="ctx">Authenticated ClientContext that is passed to the custom provider.</param> /// <param name="handler">A custom Extensibility Provisioning Provider</param> /// <param name="template">ProvisioningTemplate that is passed to the custom provider</param> /// <param name="creationInformation">The Provisioning Template creation information object</param> /// <param name="scope">The PnPMonitoredScope of the current step in the pipeline</param> /// <exception cref="ExtensiblityPipelineException"></exception> /// <exception cref="ArgumentException">Provider.Assembly or Provider.Type is NullOrWhiteSpace></exception> /// <exception cref="ArgumentNullException">ClientContext is Null></exception> public ProvisioningTemplate ExecuteExtensibilityExtractionCallOut(ClientContext ctx, ExtensibilityHandler handler, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope) { var _loggingSource = "PnP.Framework.Provisioning.Extensibility.ExtensibilityManager.ExecuteCallout"; if (ctx == null) { throw new ArgumentNullException(nameof(ctx), CoreResources.Provisioning_Extensibility_Pipeline_ClientCtxNull); } if (string.IsNullOrWhiteSpace(handler.Assembly)) { throw new ArgumentException(String.Format("{0}.{1}", nameof(handler), nameof(handler.Assembly)), CoreResources.Provisioning_Extensibility_Pipeline_Missing_AssemblyName); } if (string.IsNullOrWhiteSpace(handler.Type)) { throw new ArgumentException(String.Format("{0}.{1}", nameof(handler), nameof(handler.Type)), CoreResources.Provisioning_Extensibility_Pipeline_Missing_TypeName); } ProvisioningTemplate parsedTemplate = null; try { var _instance = GetProviderInstance(handler); if (_instance is IProvisioningExtensibilityHandler) { Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation, handler.Assembly, handler.Type); parsedTemplate = (_instance as IProvisioningExtensibilityHandler).Extract(ctx, template, creationInformation, scope, handler.Configuration); Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Success, handler.Assembly, handler.Type); } else if (_instance != null && !(_instance is IProvisioningExtensibilityTokenProvider)) { throw new ArgumentOutOfRangeException(nameof(handler), string.Format(CoreResources.Provisioning_Extensibility_Invalid_Handler_Implementation, this.GetType().Assembly.GetName().Version.ToString(), handler.Assembly, handler.Type)); } else { parsedTemplate = template; } } catch (Exception ex) { Log.Error(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); string _message = string.Format( CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); throw new ExtensiblityPipelineException(_message, ex); } return(parsedTemplate); }
private void GetPage(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, string pageUrl) { try { var pageFullUrl = UrlUtility.Combine(web.ServerRelativeUrl, pageUrl); var file = web.GetFileByServerRelativeUrl(pageFullUrl); web.Context.Load(file, f => f.Name, f => f.CheckOutType, f => f.ListItemAllFields.ParentList.ForceCheckout, f => f.Level); web.Context.ExecuteQueryRetry(); FileLevel fileLevel = file.Level; var checkedOut = CheckOutIfNeeded(web, file); try { var listItem = file.EnsureProperty(f => f.ListItemAllFields); if (listItem != null) { if (listItem.FieldValues.ContainsKey("WikiField")) { #region Wiki page var fullUri = new Uri(UrlUtility.Combine(web.Url, web.RootFolder.WelcomePage)); var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1) .ToArray() .Aggregate((i, x) => i + x) .TrimEnd('/'); var fileName = fullUri.Segments[fullUri.Segments.Count() - 1]; var homeFile = web.GetFileByServerRelativeUrl(pageFullUrl); LimitedWebPartManager limitedWPManager = homeFile.GetLimitedWebPartManager(PersonalizationScope.Shared); web.Context.Load(limitedWPManager); var webParts = web.GetWebParts(pageFullUrl); var page = new Page() { Layout = WikiPageLayout.Custom, Overwrite = true, Url = Tokenize(fullUri.PathAndQuery, web.Url), }; var pageContents = listItem.FieldValues["WikiField"].ToString(); Regex regexClientIds = new Regex(@"id=\""div_(?<ControlId>(\w|\-)+)"); if (regexClientIds.IsMatch(pageContents)) { foreach (Match webPartMatch in regexClientIds.Matches(pageContents)) { String serverSideControlId = webPartMatch.Groups["ControlId"].Value; try { String serverSideControlIdToSearchFor = String.Format("g_{0}", serverSideControlId.Replace("-", "_")); WebPartDefinition webPart = limitedWPManager.WebParts.GetByControlId(serverSideControlIdToSearchFor); web.Context.Load(webPart, wp => wp.Id, wp => wp.WebPart.Title, wp => wp.WebPart.ZoneIndex ); web.Context.ExecuteQueryRetry(); var webPartxml = TokenizeWebPartXml(web, web.GetWebPartXml(webPart.Id, pageFullUrl)); page.WebParts.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.WebPart() { Title = webPart.WebPart.Title, Contents = webPartxml, Order = (uint)webPart.WebPart.ZoneIndex, Row = 1, // By default we will create a onecolumn layout, add the webpart to it, and later replace the wikifield on the page to position the webparts correctly. Column = 1 // By default we will create a onecolumn layout, add the webpart to it, and later replace the wikifield on the page to position the webparts correctly. }); pageContents = Regex.Replace(pageContents, serverSideControlId, string.Format("{{webpartid:{0}}}", webPart.WebPart.Title), RegexOptions.IgnoreCase); } catch (ServerException) { Console.WriteLine( "Found a WebPart ID which is not available on the server-side. ID: {0}", serverSideControlId); } } } page.Fields.Add("WikiField", pageContents); template.Pages.Add(page); // Set the homepage if (template.WebSettings == null) { template.WebSettings = new WebSettings(); } //template.WebSettings.WelcomePage = homepageUrl; #endregion } else { if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { // Not a wikipage template = GetFileContents(web, template, pageFullUrl, creationInfo, pageUrl); } else { Console.WriteLine( string.Format( "Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION), ProvisioningMessageType.Warning); Console.WriteLine( "Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION); } } } } catch (ServerException ex) { if (ex.ServerErrorCode != -2146232832) { throw; } else { if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { // Page does not belong to a list, extract the file as is template = GetFileContents(web, template, pageFullUrl, creationInfo, pageUrl); } else { Console.WriteLine( string.Format( "Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION), ProvisioningMessageType.Warning); Console.WriteLine( "Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION); } } } switch (fileLevel) { case Microsoft.SharePoint.Client.FileLevel.Published: { file.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Published); break; } case Microsoft.SharePoint.Client.FileLevel.Draft: { file.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Draft); break; } default: { if (checkedOut) { file.CheckIn("", CheckinType.MajorCheckIn); web.Context.ExecuteQueryRetry(); } break; } } } catch (Exception ex) { throw ex; } }
internal void WebPropertyBagAdding(string url) { using (var cc = TestCommon.CreateClientContext(url)) { bool isNoScriptSite = cc.Web.IsNoScriptSite(); // Ensure we can test clean DeleteWebProperties(cc); // Add web properties var result = TestProvisioningTemplate(cc, "propertybag_add.xml", Handlers.PropertyBagEntries); if (!isNoScriptSite) { PropertyBagValidator pv = new PropertyBagValidator(); Assert.IsTrue(pv.Validate(result.SourceTemplate.PropertyBagEntries, result.TargetTemplate.PropertyBagEntries, result.SourceTokenParser)); } // Update web properties var result2 = TestProvisioningTemplate(cc, "propertybag_delta_1.xml", Handlers.PropertyBagEntries); if (!isNoScriptSite) { PropertyBagValidator pv2 = new PropertyBagValidator(); pv2.ValidateEvent += Pv2_ValidateEvent; Assert.IsTrue(pv2.Validate(result2.SourceTemplate.PropertyBagEntries, result2.TargetTemplate.PropertyBagEntries, result2.SourceTokenParser)); } // Update system properties: run 1 is without specifying the override flag...no updates should happen ProvisioningTemplateApplyingInformation ptai3 = new ProvisioningTemplateApplyingInformation { OverwriteSystemPropertyBagValues = false, //=default HandlersToProcess = Handlers.PropertyBagEntries }; // Set base template to null to ensure all properties are fetched by the engine ProvisioningTemplateCreationInformation ptci3 = new ProvisioningTemplateCreationInformation(cc.Web) { BaseTemplate = null, HandlersToProcess = Handlers.PropertyBagEntries }; var result3 = TestProvisioningTemplate(cc, "propertybag_delta_2.xml", Handlers.PropertyBagEntries, ptai3, ptci3); if (!isNoScriptSite) { PropertyBagValidator pv3 = new PropertyBagValidator(); pv3.ValidateEvent += Pv3_ValidateEvent; Assert.IsTrue(pv3.Validate(result3.SourceTemplate.PropertyBagEntries, result3.TargetTemplate.PropertyBagEntries, result3.SourceTokenParser)); } // Update system properties: run 2 is with specifying the override flag...updates should happen if the overwrite flag was set to true ProvisioningTemplateApplyingInformation ptai4 = new ProvisioningTemplateApplyingInformation { // Set system overwrite flag OverwriteSystemPropertyBagValues = true, HandlersToProcess = Handlers.PropertyBagEntries }; // Set base template to null to ensure all properties are fetched by the engine ProvisioningTemplateCreationInformation ptci4 = new ProvisioningTemplateCreationInformation(cc.Web) { BaseTemplate = null, HandlersToProcess = Handlers.PropertyBagEntries }; var result4 = TestProvisioningTemplate(cc, "propertybag_delta_2.xml", Handlers.PropertyBagEntries, ptai4, ptci4); if (!isNoScriptSite) { PropertyBagValidator pv4 = new PropertyBagValidator(); pv4.ValidateEvent += Pv2_ValidateEvent; Assert.IsTrue(pv4.Validate(result4.SourceTemplate.PropertyBagEntries, result4.TargetTemplate.PropertyBagEntries, result4.SourceTokenParser)); } } }
public static bool PersistResourceValue(List siteList, Guid viewId, string token, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { bool returnValue = false; var clientContext = siteList.Context; List <Tuple <string, int, string> > resourceTokens = creationInfo.ResourceTokens; foreach (var language in template.SupportedUILanguages) { var currentView = siteList.GetViewById(viewId); clientContext.Load(currentView, cc => cc.Title); var acceptLanguage = clientContext.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"]; clientContext.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = new CultureInfo(language.LCID).Name; clientContext.ExecuteQueryRetry(); if (!string.IsNullOrWhiteSpace(currentView.Title)) { returnValue = true; resourceTokens.Add(new Tuple <string, int, string>(token, language.LCID, currentView.Title)); } clientContext.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = acceptLanguage; } return(returnValue); }
private void ProcessBaseTemplates(List <BaseTemplate> templates, bool deleteSites, bool createSites) { using (var tenantCtx = TestCommon.CreateTenantClientContext()) { tenantCtx.RequestTimeout = Timeout.Infinite; Tenant tenant = new Tenant(tenantCtx); #if !ONPREMISES if (deleteSites) { // First delete all template site collections when in SPO foreach (var template in templates) { string siteUrl = GetSiteUrl(template); try { Console.WriteLine("Deleting existing site {0}", siteUrl); if (template.IsGroup) { // Do nothing for the time being since we don't allow group deletion using app-only context } else { tenant.DeleteSiteCollection(siteUrl, false); } } catch { } } } if (createSites) { // Create site collections foreach (var template in templates) { string siteUrl = GetSiteUrl(template); Console.WriteLine("Creating site {0}", siteUrl); if (template.IsGroup) { // Do nothing for the time being since we don't allow group creation using app-only context } else { bool siteExists = false; if (template.SubSiteTemplate.Length > 0) { siteExists = tenant.SiteExists(siteUrl); } if (!siteExists) { tenant.CreateSiteCollection(new Entities.SiteEntity() { Lcid = 1033, TimeZoneId = 4, SiteOwnerLogin = (TestCommon.Credentials as SharePointOnlineCredentials).UserName, Title = "Template Site", Template = template.Template, Url = siteUrl, }, true, true); } if (template.SubSiteTemplate.Length > 0) { using (ClientContext ctx = TestCommon.CreateClientContext()) { using (var sitecolCtx = ctx.Clone(siteUrl)) { sitecolCtx.Web.Webs.Add(new WebCreationInformation() { Title = string.Format("template{0}", template.SubSiteTemplate), Language = 1033, Url = string.Format("template{0}", template.SubSiteTemplate.Replace("#", "")), UseSamePermissionsAsParentSite = true }); sitecolCtx.ExecuteQueryRetry(); } } } } } } #endif } // Export the base templates using (ClientContext ctx = TestCommon.CreateClientContext()) { foreach (var template in templates) { string siteUrl = GetSiteUrl(template, false); // Export the base templates using (ClientContext cc = ctx.Clone(siteUrl)) { cc.RequestTimeout = Timeout.Infinite; // Specify null as base template since we do want "everything" in this case ProvisioningTemplateCreationInformation creationInfo = new ProvisioningTemplateCreationInformation(cc.Web); creationInfo.BaseTemplate = null; // Do not extract the home page for the base templates creationInfo.HandlersToProcess ^= Handlers.PageContents; // Override the save name. Case is online site collection provisioned using blankinternetcontainer#0 which returns // blankinternet#0 as web template using CSOM/SSOM API string templateName = template.Template; if (template.SaveAsTemplate.Length > 0) { templateName = template.SaveAsTemplate; } ProvisioningTemplate p = cc.Web.GetProvisioningTemplate(creationInfo); if (template.SubSiteTemplate.Length > 0) { p.Id = String.Format("{0}template", template.SubSiteTemplate.Replace("#", "")); } else { p.Id = String.Format("{0}template", templateName.Replace("#", "")); } // Cleanup before saving p.Security.AdditionalAdministrators.Clear(); // persist the template using the XML provider XMLFileSystemTemplateProvider provider = new XMLFileSystemTemplateProvider(".", ""); if (template.SubSiteTemplate.Length > 0) { provider.SaveAs(p, String.Format("{0}Template.xml", template.SubSiteTemplate.Replace("#", ""))); } else { provider.SaveAs(p, String.Format("{0}Template.xml", templateName.Replace("#", ""))); } } } } }
public static bool PersistResourceValue(UserResource userResource, string token, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { bool returnValue = false; List <Tuple <string, int, string> > resourceTokens = creationInfo.ResourceTokens; foreach (var language in template.SupportedUILanguages) { var culture = new CultureInfo(language.LCID); var value = userResource.GetValueForUICulture(culture.Name); userResource.Context.ExecuteQueryRetry(); if (!string.IsNullOrEmpty(value.Value)) { returnValue = true; resourceTokens.Add(new Tuple <string, int, string>(token, language.LCID, value.Value)); } } return(returnValue); }
public void CanProvisionObjects() { var template = new ProvisioningTemplate(); TermGroup termGroup = new TermGroup(_termGroupGuid, "TestProvisioningGroup", null); List <TermSet> termSets = new List <TermSet>(); TermSet termSet = new TermSet(_termSetGuid, "TestProvisioningTermSet", null, true, false, null, null); List <Term> terms = new List <Term>(); var term1 = new Term(Guid.NewGuid(), "TestProvisioningTerm 1", null, null, null, null, null); term1.Properties.Add("TestProp1", "Test Value 1"); term1.LocalProperties.Add("TestLocalProp1", "Test Value 1"); term1.Labels.Add(new TermLabel() { Language = 1033, Value = "Testing" }); term1.Terms.Add(new Term(Guid.NewGuid(), "Sub Term 1", null, null, null, null, null)); terms.Add(term1); terms.Add(new Term(Guid.NewGuid(), "TestProvisioningTerm 2", null, null, null, null, null)); termSet.Terms.AddRange(terms); termSets.Add(termSet); termGroup.TermSets.AddRange(termSets); template.TermGroups.Add(termGroup); using (var ctx = TestCommon.CreateClientContext()) { var parser = new TokenParser(ctx.Web, template); new ObjectTermGroups().ProvisionObjects(ctx.Web, template, parser, new ProvisioningTemplateApplyingInformation()); TaxonomySession session = TaxonomySession.GetTaxonomySession(ctx); var store = session.GetDefaultKeywordsTermStore(); var group = store.GetGroup(_termGroupGuid); var set = store.GetTermSet(_termSetGuid); ctx.Load(group); ctx.Load(set, s => s.Terms); ctx.ExecuteQueryRetry(); Assert.IsInstanceOfType(group, typeof(Microsoft.SharePoint.Client.Taxonomy.TermGroup)); Assert.IsInstanceOfType(set, typeof(Microsoft.SharePoint.Client.Taxonomy.TermSet)); Assert.IsTrue(set.Terms.Count == 2); var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = ctx.Web.GetBaseTemplate() }; var template2 = new ProvisioningTemplate(); template2 = new ObjectTermGroups().ExtractObjects(ctx.Web, template, creationInfo); Assert.IsTrue(template.TermGroups.Any()); Assert.IsInstanceOfType(template.TermGroups, typeof(Core.Framework.Provisioning.Model.TermGroupCollection)); } }
/// <summary> /// Extracts a client side page /// </summary> /// <param name="web">Web to extract the page from</param> /// <param name="template">Current provisioning template that will hold the extracted page</param> /// <param name="creationInfo">ProvisioningTemplateCreationInformation passed into the provisioning engine</param> /// <param name="scope">Scope used for logging</param> /// <param name="pageUrl">Url of the page to extract</param> /// <param name="pageName">Name of the page to extract</param> /// <param name="isHomePage">Is this a home page?</param> /// <param name="isTemplate">Is this a template?</param> public void ExtractClientSidePage(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string pageUrl, string pageName, bool isHomePage, bool isTemplate = false) { try { var pageToExtract = web.LoadClientSidePage(pageName); if (pageToExtract.Sections.Count == 0 && pageToExtract.Controls.Count == 0 && isHomePage) { // This is default home page which was not customized...and as such there's no page definition stored in the list item. We don't need to extact this page. scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ClientSidePageContents_DefaultHomePage); } else { // Get the page content type string pageContentTypeId = pageToExtract.PageListItem[ContentTypeIdField].ToString(); if (!string.IsNullOrEmpty(pageContentTypeId)) { pageContentTypeId = GetParentIdValue(pageContentTypeId); } // Create the page var extractedPageInstance = new ClientSidePage() { PageName = pageName, PromoteAsNewsArticle = false, PromoteAsTemplate = isTemplate, Overwrite = true, Publish = true, Layout = pageToExtract.LayoutType.ToString(), EnableComments = !pageToExtract.CommentsDisabled, Title = pageToExtract.PageTitle, ContentTypeID = !pageContentTypeId.Equals(BuiltInContentTypeId.ModernArticlePage, StringComparison.InvariantCultureIgnoreCase) ? pageContentTypeId : null, }; if (pageToExtract.PageHeader != null) { var extractedHeader = new ClientSidePageHeader() { Type = (ClientSidePageHeaderType)Enum.Parse(typeof(Pages.ClientSidePageHeaderType), pageToExtract.PageHeader.Type.ToString()), ServerRelativeImageUrl = TokenizeJsonControlData(web, pageToExtract.PageHeader.ImageServerRelativeUrl), TranslateX = pageToExtract.PageHeader.TranslateX, TranslateY = pageToExtract.PageHeader.TranslateY, LayoutType = (ClientSidePageHeaderLayoutType)Enum.Parse(typeof(Pages.ClientSidePageHeaderLayoutType), pageToExtract.PageHeader.LayoutType.ToString()), TextAlignment = (ClientSidePageHeaderTextAlignment)Enum.Parse(typeof(Pages.ClientSidePageHeaderTitleAlignment), pageToExtract.PageHeader.TextAlignment.ToString()), ShowTopicHeader = pageToExtract.PageHeader.ShowTopicHeader, ShowPublishDate = pageToExtract.PageHeader.ShowPublishDate, TopicHeader = pageToExtract.PageHeader.TopicHeader, AlternativeText = pageToExtract.PageHeader.AlternativeText, Authors = pageToExtract.PageHeader.Authors, AuthorByLine = pageToExtract.PageHeader.AuthorByLine, AuthorByLineId = pageToExtract.PageHeader.AuthorByLineId, }; extractedPageInstance.Header = extractedHeader; } // Add the sections foreach (var section in pageToExtract.Sections) { // Set order var sectionInstance = new CanvasSection() { Order = section.Order, BackgroundEmphasis = (BackgroundEmphasis)section.ZoneEmphasis, }; // Set section type switch (section.Type) { case Pages.CanvasSectionTemplate.OneColumn: sectionInstance.Type = CanvasSectionType.OneColumn; break; case Pages.CanvasSectionTemplate.TwoColumn: sectionInstance.Type = CanvasSectionType.TwoColumn; break; case Pages.CanvasSectionTemplate.TwoColumnLeft: sectionInstance.Type = CanvasSectionType.TwoColumnLeft; break; case Pages.CanvasSectionTemplate.TwoColumnRight: sectionInstance.Type = CanvasSectionType.TwoColumnRight; break; case Pages.CanvasSectionTemplate.ThreeColumn: sectionInstance.Type = CanvasSectionType.ThreeColumn; break; case Pages.CanvasSectionTemplate.OneColumnFullWidth: sectionInstance.Type = CanvasSectionType.OneColumnFullWidth; break; default: sectionInstance.Type = CanvasSectionType.OneColumn; break; } // Add controls to section foreach (var column in section.Columns) { foreach (var control in column.Controls) { // Create control CanvasControl controlInstance = new CanvasControl() { Column = column.Order, ControlId = control.InstanceId, Order = control.Order, }; // Set control type if (control.Type == typeof(Pages.ClientSideText)) { controlInstance.Type = WebPartType.Text; // Set text content controlInstance.ControlProperties = new System.Collections.Generic.Dictionary <string, string>(1) { { "Text", TokenizeJsonTextData(web, (control as Pages.ClientSideText).Text) } }; } else { // set ControlId to webpart id controlInstance.ControlId = Guid.Parse((control as Pages.ClientSideWebPart).WebPartId); var webPartType = Pages.ClientSidePage.NameToClientSideWebPartEnum((control as Pages.ClientSideWebPart).WebPartId); switch (webPartType) { case Pages.DefaultClientSideWebParts.ContentRollup: controlInstance.Type = WebPartType.ContentRollup; break; case Pages.DefaultClientSideWebParts.BingMap: controlInstance.Type = WebPartType.BingMap; break; case Pages.DefaultClientSideWebParts.ContentEmbed: controlInstance.Type = WebPartType.ContentEmbed; break; case Pages.DefaultClientSideWebParts.DocumentEmbed: controlInstance.Type = WebPartType.DocumentEmbed; break; case Pages.DefaultClientSideWebParts.Image: controlInstance.Type = WebPartType.Image; break; case Pages.DefaultClientSideWebParts.ImageGallery: controlInstance.Type = WebPartType.ImageGallery; break; case Pages.DefaultClientSideWebParts.LinkPreview: controlInstance.Type = WebPartType.LinkPreview; break; case Pages.DefaultClientSideWebParts.NewsFeed: controlInstance.Type = WebPartType.NewsFeed; break; case Pages.DefaultClientSideWebParts.NewsReel: controlInstance.Type = WebPartType.NewsReel; break; case Pages.DefaultClientSideWebParts.PowerBIReportEmbed: controlInstance.Type = WebPartType.PowerBIReportEmbed; break; case Pages.DefaultClientSideWebParts.QuickChart: controlInstance.Type = WebPartType.QuickChart; break; case Pages.DefaultClientSideWebParts.SiteActivity: controlInstance.Type = WebPartType.SiteActivity; break; case Pages.DefaultClientSideWebParts.VideoEmbed: controlInstance.Type = WebPartType.VideoEmbed; break; case Pages.DefaultClientSideWebParts.YammerEmbed: controlInstance.Type = WebPartType.YammerEmbed; break; case Pages.DefaultClientSideWebParts.Events: controlInstance.Type = WebPartType.Events; break; case Pages.DefaultClientSideWebParts.GroupCalendar: controlInstance.Type = WebPartType.GroupCalendar; break; case Pages.DefaultClientSideWebParts.Hero: controlInstance.Type = WebPartType.Hero; break; case Pages.DefaultClientSideWebParts.List: controlInstance.Type = WebPartType.List; break; case Pages.DefaultClientSideWebParts.PageTitle: controlInstance.Type = WebPartType.PageTitle; break; case Pages.DefaultClientSideWebParts.People: controlInstance.Type = WebPartType.People; break; case Pages.DefaultClientSideWebParts.QuickLinks: controlInstance.Type = WebPartType.QuickLinks; break; case Pages.DefaultClientSideWebParts.CustomMessageRegion: controlInstance.Type = WebPartType.CustomMessageRegion; break; case Pages.DefaultClientSideWebParts.Divider: controlInstance.Type = WebPartType.Divider; break; case Pages.DefaultClientSideWebParts.MicrosoftForms: controlInstance.Type = WebPartType.MicrosoftForms; break; case Pages.DefaultClientSideWebParts.Spacer: controlInstance.Type = WebPartType.Spacer; break; case Pages.DefaultClientSideWebParts.ClientWebPart: controlInstance.Type = WebPartType.ClientWebPart; break; case Pages.DefaultClientSideWebParts.ThirdParty: controlInstance.Type = WebPartType.Custom; break; default: controlInstance.Type = WebPartType.Custom; break; } string jsonControlData = "\"id\": \"" + (control as Pages.ClientSideWebPart).WebPartId + "\", \"instanceId\": \"" + (control as Pages.ClientSideWebPart).InstanceId + "\", \"title\": \"" + (control as Pages.ClientSideWebPart).Title + "\", \"description\": \"" + (control as Pages.ClientSideWebPart).Description + "\", \"dataVersion\": \"" + (control as Pages.ClientSideWebPart).DataVersion + "\", \"properties\": " + (control as Pages.ClientSideWebPart).PropertiesJson + ""; // set the control properties if ((control as Pages.ClientSideWebPart).ServerProcessedContent != null) { // If we have serverProcessedContent then also export that one, it's important as some controls depend on this information to be present string serverProcessedContent = (control as Pages.ClientSideWebPart).ServerProcessedContent.ToString(Formatting.None); jsonControlData = jsonControlData + ", \"serverProcessedContent\": " + serverProcessedContent + ""; } if ((control as Pages.ClientSideWebPart).DynamicDataPaths != null) { // If we have serverProcessedContent then also export that one, it's important as some controls depend on this information to be present string dynamicDataPaths = (control as Pages.ClientSideWebPart).DynamicDataPaths.ToString(Formatting.None); jsonControlData = jsonControlData + ", \"dynamicDataPaths\": " + dynamicDataPaths + ""; } if ((control as Pages.ClientSideWebPart).DynamicDataValues != null) { // If we have serverProcessedContent then also export that one, it's important as some controls depend on this information to be present string dynamicDataValues = (control as Pages.ClientSideWebPart).DynamicDataValues.ToString(Formatting.None); jsonControlData = jsonControlData + ", \"dynamicDataValues\": " + dynamicDataValues + ""; } controlInstance.JsonControlData = "{" + jsonControlData + "}"; // Tokenize the JsonControlData controlInstance.JsonControlData = TokenizeJsonControlData(web, controlInstance.JsonControlData); // Export relevant files if this flag is set if (creationInfo.PersistBrandingFiles) { List <Guid> fileGuids = new List <Guid>(); Dictionary <string, string> exportedFiles = new Dictionary <string, string>(); Dictionary <string, string> exportedPages = new Dictionary <string, string>(); // grab all the guids in the already tokenized json and check try to get them as a file string guidPattern = "\"[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}\""; Regex regexClientIds = new Regex(guidPattern); if (regexClientIds.IsMatch(controlInstance.JsonControlData)) { foreach (Match guidMatch in regexClientIds.Matches(controlInstance.JsonControlData)) { Guid uniqueId; if (Guid.TryParse(guidMatch.Value.Trim("\"".ToCharArray()), out uniqueId)) { fileGuids.Add(uniqueId); } } } // grab all the encoded guids in the already tokenized json and check try to get them as a file guidPattern = "=[a-fA-F0-9]{8}%2D([a-fA-F0-9]{4}%2D){3}[a-fA-F0-9]{12}"; regexClientIds = new Regex(guidPattern); if (regexClientIds.IsMatch(controlInstance.JsonControlData)) { foreach (Match guidMatch in regexClientIds.Matches(controlInstance.JsonControlData)) { Guid uniqueId; if (Guid.TryParse(guidMatch.Value.TrimStart("=".ToCharArray()), out uniqueId)) { fileGuids.Add(uniqueId); } } } // Iterate over the found guids to see if they're exportable files foreach (var uniqueId in fileGuids) { try { if (!exportedFiles.ContainsKey(uniqueId.ToString())) { // Try to see if this is a file var file = web.GetFileById(uniqueId); web.Context.Load(file, f => f.Level, f => f.ServerRelativeUrl); web.Context.ExecuteQueryRetry(); // If we got here it's a file, let's grab the file's path and name var baseUri = new Uri(web.Url); var fullUri = new Uri(baseUri, file.ServerRelativeUrl); var folderPath = HttpUtility.UrlDecode(fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/')); var fileName = HttpUtility.UrlDecode(fullUri.Segments[fullUri.Segments.Count() - 1]); // Don't export aspx files as some web parts refer to other client side pages --> pages have to be either exported as well or already exist in the target site if (!fileName.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase)) { var templateFolderPath = folderPath.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()); // Avoid duplicate file entries var fileAlreadyExported = template.Files.Where(p => p.Folder.Equals(templateFolderPath, StringComparison.CurrentCultureIgnoreCase) && p.Src.Equals(fileName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault(); if (fileAlreadyExported == null) { // Add a File to the template template.Files.Add(new Model.File() { Folder = templateFolderPath, Src = $"{templateFolderPath}/{fileName}", Overwrite = true, Level = (Model.FileLevel)Enum.Parse(typeof(Model.FileLevel), file.Level.ToString()) }); // Export the file PersistFile(web, creationInfo, scope, folderPath, fileName); // Keep track of the exported file path and it's UniqueId exportedFiles.Add(uniqueId.ToString(), file.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray())); } } else { if (!exportedPages.ContainsKey(uniqueId.ToString())) { exportedPages.Add(uniqueId.ToString(), file.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray())); } } } } catch (Exception ex) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePageContents_ErrorDuringFileExport, ex.Message); } } // Tokenize based on the found files, use a different token for encoded guids do we can later on replace by a new encoded guid foreach (var exportedFile in exportedFiles) { controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedFile.Key.Replace("-", "%2D"), $"{{fileuniqueidencoded:{exportedFile.Value}}}", RegexOptions.IgnoreCase); controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedFile.Key, $"{{fileuniqueid:{exportedFile.Value}}}", RegexOptions.IgnoreCase); } foreach (var exportedPage in exportedPages) { controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedPage.Key.Replace("-", "%2D"), $"{{pageuniqueidencoded:{exportedPage.Value}}}", RegexOptions.IgnoreCase); controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedPage.Key, $"{{pageuniqueid:{exportedPage.Value}}}", RegexOptions.IgnoreCase); } } } // add control to section sectionInstance.Controls.Add(controlInstance); } } extractedPageInstance.Sections.Add(sectionInstance); } // Renumber the sections...when editing modern homepages you can end up with section with order 0.5 or 0.75...let's ensure we render section as of 1 int sectionOrder = 1; foreach (var sectionInstance in extractedPageInstance.Sections) { sectionInstance.Order = sectionOrder; sectionOrder++; } // Add the page to the template template.ClientSidePages.Add(extractedPageInstance); // Set the homepage if (isHomePage) { if (template.WebSettings == null) { template.WebSettings = new WebSettings(); } if (pageUrl.StartsWith(web.ServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase)) { template.WebSettings.WelcomePage = pageUrl.Replace(web.ServerRelativeUrl + "/", ""); } else { template.WebSettings.WelcomePage = pageUrl; } } } } catch (ArgumentException ex) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePageContents_NoValidPage, ex.Message); } }
public List<DataRow> ExtractItems( ProvisioningTemplateCreationInformation creationInfo, TokenParser parser, PnPMonitoredScope scope) { List<DataRow> dataRows = new List<DataRow>(); bool isPageLib = (List.BaseTemplate == (int)ListTemplateType.WebPageLibrary) || (List.BaseTemplate == (int)ListTemplateType.HomePageLibrary) || (List.BaseTemplate == (int)ListTemplateType.PublishingPages); CamlQuery query = isPageLib ? CamlQuery.CreateAllFoldersQuery() : CamlQuery.CreateAllItemsQuery(); query.DatesInUtc = true; ListItemCollection items = this.List.GetItems(query); this.Context.Load(items, col => col.IncludeWithDefaultProperties(i => i.HasUniqueRoleAssignments)); this.Context.Load(this.List.Fields); this.Context.Load(this.List, l=> l.RootFolder.ServerRelativeUrl, l=> l.BaseType); this.Context.ExecuteQueryRetry(); ItemPathProvider itemPathProvider = new ItemPathProvider(this.List, this.Web); List<Field> fields = GetListContentSerializableFields(true); foreach (ListItem item in items) { try { Dictionary<string, string> values = new Dictionary<string, string>(); foreach (Field field in fields) { if (CanFieldContentBeIncluded(field, true)) { string str = ""; object value = null; ; try { value = item[field.InternalName]; } catch (Exception ex) { scope.LogWarning(ex, "Failed to read item field value. List:{0}, Item ID:{1}, Field: {2}", this.List.Title, item.Id, field.InternalName); } if (null != value) { try { FieldValueProvider provider = GetFieldValueProvider(field, this.Web); str = provider.GetValidatedValue(value); } catch (Exception ex) { scope.LogWarning(ex, "Failed to serialize item field value. List:{0}, Item ID:{1}, Field: {2}", this.List.Title, item.Id, field.InternalName); } if (!string.IsNullOrEmpty(str)) { values.Add(field.InternalName, str); } } } } string fileSrc; itemPathProvider.ExtractItemPathValues(item, values, creationInfo, out fileSrc); if (values.Any()) { ObjectSecurity security = null; if (item.HasUniqueRoleAssignments) { try { security = item.GetSecurity(parser); security.ClearSubscopes = true; } catch (Exception ex) { scope.LogWarning(ex, "Failed to get item security. Item ID: {0}, List: '{1}'.", item.Id, this.List.Title); } } DataRow row = new DataRow(values, security, fileSrc); dataRows.Add(row); } } catch (Exception ex) { scope.LogError(ex, "Failed to save item in template. Item ID: {0}, List: '{1}'.", item.Id, this.List.Title); } } return dataRows; }
/// <summary> /// Extracts a client side page /// </summary> /// <param name="web">Web to extract the page from</param> /// <param name="template">Current provisioning template that will hold the extracted page</param> /// <param name="creationInfo">ProvisioningTemplateCreationInformation passed into the provisioning engine</param> /// <param name="scope">Scope used for logging</param> /// <param name="page">page to be exported</param> public void ExtractClientSidePage(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, PageToExport page) { bool excludeAuthorInformation = false; if (creationInfo.ExtractConfiguration != null && creationInfo.ExtractConfiguration.Pages != null) { excludeAuthorInformation = creationInfo.ExtractConfiguration.Pages.ExcludeAuthorInformation; } try { List <string> errorneousOrNonImageFileGuids = new List <string>(); var pageToExtract = web.LoadClientSidePage(page.PageName); if (pageToExtract.Sections.Count == 0 && pageToExtract.Controls.Count == 0 && page.IsHomePage) { // This is default home page which was not customized...and as such there's no page definition stored in the list item. We don't need to extact this page. scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ClientSidePageContents_DefaultHomePage); } else { // Get the page content type string pageContentTypeId = pageToExtract.PageListItem[ContentTypeIdField].ToString(); if (!string.IsNullOrEmpty(pageContentTypeId)) { pageContentTypeId = GetParentIdValue(pageContentTypeId); } int promotedState = 0; if (pageToExtract.PageListItem[OfficeDevPnP.Core.Pages.ClientSidePage.PromotedStateField] != null) { int.TryParse(pageToExtract.PageListItem[OfficeDevPnP.Core.Pages.ClientSidePage.PromotedStateField].ToString(), out promotedState); } var isNews = pageToExtract.LayoutType != Pages.ClientSidePageLayoutType.Home && promotedState == (int)Pages.PromotedState.Promoted; // Create the page; BaseClientSidePage extractedPageInstance; if (page.IsTranslation) { extractedPageInstance = new TranslatedClientSidePage(); (extractedPageInstance as TranslatedClientSidePage).PageName = page.PageName; } else { extractedPageInstance = new ClientSidePage(); (extractedPageInstance as ClientSidePage).PageName = page.PageName; } extractedPageInstance.PromoteAsNewsArticle = isNews; extractedPageInstance.PromoteAsTemplate = page.IsTemplate; extractedPageInstance.Overwrite = true; extractedPageInstance.Publish = true; extractedPageInstance.Layout = pageToExtract.LayoutType.ToString(); extractedPageInstance.EnableComments = !pageToExtract.CommentsDisabled; extractedPageInstance.Title = pageToExtract.PageTitle; extractedPageInstance.ContentTypeID = !pageContentTypeId.Equals(BuiltInContentTypeId.ModernArticlePage, StringComparison.InvariantCultureIgnoreCase) ? pageContentTypeId : null; extractedPageInstance.ThumbnailUrl = pageToExtract.ThumbnailUrl != null?TokenizeJsonControlData(web, pageToExtract.ThumbnailUrl) : ""; if (pageToExtract.PageHeader != null) { var extractedHeader = new ClientSidePageHeader() { Type = (ClientSidePageHeaderType)Enum.Parse(typeof(Pages.ClientSidePageHeaderType), pageToExtract.PageHeader.Type.ToString()), ServerRelativeImageUrl = TokenizeJsonControlData(web, pageToExtract.PageHeader.ImageServerRelativeUrl), TranslateX = pageToExtract.PageHeader.TranslateX, TranslateY = pageToExtract.PageHeader.TranslateY, LayoutType = (ClientSidePageHeaderLayoutType)Enum.Parse(typeof(Pages.ClientSidePageHeaderLayoutType), pageToExtract.PageHeader.LayoutType.ToString()), #if !SP2019 TextAlignment = (ClientSidePageHeaderTextAlignment)Enum.Parse(typeof(Pages.ClientSidePageHeaderTitleAlignment), pageToExtract.PageHeader.TextAlignment.ToString()), ShowTopicHeader = pageToExtract.PageHeader.ShowTopicHeader, ShowPublishDate = pageToExtract.PageHeader.ShowPublishDate, TopicHeader = pageToExtract.PageHeader.TopicHeader, AlternativeText = pageToExtract.PageHeader.AlternativeText, Authors = !excludeAuthorInformation ? pageToExtract.PageHeader.Authors : "", AuthorByLine = !excludeAuthorInformation ? pageToExtract.PageHeader.AuthorByLine : "", AuthorByLineId = !excludeAuthorInformation ? pageToExtract.PageHeader.AuthorByLineId : -1 #endif }; extractedPageInstance.Header = extractedHeader; // Add the page header image to template if that was requested if (creationInfo.PersistBrandingFiles && !string.IsNullOrEmpty(pageToExtract.PageHeader.ImageServerRelativeUrl)) { IncludePageHeaderImageInExport(web, pageToExtract.PageHeader.ImageServerRelativeUrl, template, creationInfo, scope); } } // define reusable RegEx pre-compiled objects string guidPattern = "\"{?[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}}?\""; Regex regexGuidPattern = new Regex(guidPattern, RegexOptions.Compiled); string guidPatternEncoded = "=[a-fA-F0-9]{8}(?:%2D|-)([a-fA-F0-9]{4}(?:%2D|-)){3}[a-fA-F0-9]{12}"; Regex regexGuidPatternEncoded = new Regex(guidPatternEncoded, RegexOptions.Compiled); string guidPatternNoDashes = "[a-fA-F0-9]{32}"; Regex regexGuidPatternNoDashes = new Regex(guidPatternNoDashes, RegexOptions.Compiled); string siteAssetUrlsPattern = "(?:\")(?<AssetUrl>[\\w|\\.|\\/|:|-]*\\/SiteAssets\\/SitePages\\/[\\w|\\.|\\/|:|-]*)(?:\")"; // OLD RegEx with Catastrophic Backtracking: @".*""(.*?/SiteAssets/SitePages/.+?)"".*"; Regex regexSiteAssetUrls = new Regex(siteAssetUrlsPattern, RegexOptions.Compiled); if (creationInfo.PersistBrandingFiles && !string.IsNullOrEmpty(extractedPageInstance.ThumbnailUrl)) { var thumbnailFileIds = new List <Guid>(); CollectImageFilesFromGenericGuids(regexGuidPatternNoDashes, null, extractedPageInstance.ThumbnailUrl, thumbnailFileIds); if (thumbnailFileIds.Count == 1) { var file = web.GetFileById(thumbnailFileIds[0]); web.Context.Load(file, f => f.Level, f => f.ServerRelativeUrl, f => f.UniqueId); web.Context.ExecuteQueryRetry(); // Item1 = was file added to the template // Item2 = file name (if file found) var imageAddedTuple = LoadAndAddPageImage(web, file, template, creationInfo, scope); if (imageAddedTuple.Item1) { extractedPageInstance.ThumbnailUrl = Regex.Replace(extractedPageInstance.ThumbnailUrl, file.UniqueId.ToString("N"), $"{{fileuniqueid:{file.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray())}}}"); } } } // Add the sections foreach (var section in pageToExtract.Sections) { // Set order var sectionInstance = new CanvasSection() { Order = section.Order, BackgroundEmphasis = (Emphasis)section.ZoneEmphasis, }; if (section.VerticalSectionColumn != null) { sectionInstance.VerticalSectionEmphasis = (Emphasis)section.VerticalSectionColumn.VerticalSectionEmphasis; } // Set section type switch (section.Type) { case Pages.CanvasSectionTemplate.OneColumn: sectionInstance.Type = CanvasSectionType.OneColumn; break; case Pages.CanvasSectionTemplate.TwoColumn: sectionInstance.Type = CanvasSectionType.TwoColumn; break; case Pages.CanvasSectionTemplate.TwoColumnLeft: sectionInstance.Type = CanvasSectionType.TwoColumnLeft; break; case Pages.CanvasSectionTemplate.TwoColumnRight: sectionInstance.Type = CanvasSectionType.TwoColumnRight; break; case Pages.CanvasSectionTemplate.ThreeColumn: sectionInstance.Type = CanvasSectionType.ThreeColumn; break; case Pages.CanvasSectionTemplate.OneColumnFullWidth: sectionInstance.Type = CanvasSectionType.OneColumnFullWidth; break; #if !SP2019 case Pages.CanvasSectionTemplate.OneColumnVerticalSection: sectionInstance.Type = CanvasSectionType.OneColumnVerticalSection; break; case Pages.CanvasSectionTemplate.TwoColumnVerticalSection: sectionInstance.Type = CanvasSectionType.TwoColumnVerticalSection; break; case Pages.CanvasSectionTemplate.TwoColumnLeftVerticalSection: sectionInstance.Type = CanvasSectionType.TwoColumnLeftVerticalSection; break; case Pages.CanvasSectionTemplate.TwoColumnRightVerticalSection: sectionInstance.Type = CanvasSectionType.TwoColumnRightVerticalSection; break; case Pages.CanvasSectionTemplate.ThreeColumnVerticalSection: sectionInstance.Type = CanvasSectionType.ThreeColumnVerticalSection; break; #endif default: sectionInstance.Type = CanvasSectionType.OneColumn; break; } // Add controls to section foreach (var column in section.Columns) { foreach (var control in column.Controls) { // Create control CanvasControl controlInstance = new CanvasControl() { Column = column.IsVerticalSectionColumn ? section.Columns.IndexOf(column) + 1 : column.Order, ControlId = control.InstanceId, Order = control.Order, }; // Set control type if (control.Type == typeof(Pages.ClientSideText)) { controlInstance.Type = WebPartType.Text; // Set text content controlInstance.ControlProperties = new System.Collections.Generic.Dictionary <string, string>(1) { { "Text", TokenizeJsonTextData(web, (control as Pages.ClientSideText).Text) } }; } else { // set ControlId to webpart id controlInstance.ControlId = Guid.Parse((control as Pages.ClientSideWebPart).WebPartId); var webPartType = Pages.ClientSidePage.NameToClientSideWebPartEnum((control as Pages.ClientSideWebPart).WebPartId); switch (webPartType) { case Pages.DefaultClientSideWebParts.ContentRollup: controlInstance.Type = WebPartType.ContentRollup; break; #if !SP2019 case Pages.DefaultClientSideWebParts.BingMap: controlInstance.Type = WebPartType.BingMap; break; case Pages.DefaultClientSideWebParts.Button: controlInstance.Type = WebPartType.Button; break; case Pages.DefaultClientSideWebParts.CallToAction: controlInstance.Type = WebPartType.CallToAction; break; case Pages.DefaultClientSideWebParts.News: controlInstance.Type = WebPartType.News; break; case Pages.DefaultClientSideWebParts.PowerBIReportEmbed: controlInstance.Type = WebPartType.PowerBIReportEmbed; break; case Pages.DefaultClientSideWebParts.Sites: controlInstance.Type = WebPartType.Sites; break; case Pages.DefaultClientSideWebParts.GroupCalendar: controlInstance.Type = WebPartType.GroupCalendar; break; case Pages.DefaultClientSideWebParts.MicrosoftForms: controlInstance.Type = WebPartType.MicrosoftForms; break; case Pages.DefaultClientSideWebParts.ClientWebPart: controlInstance.Type = WebPartType.ClientWebPart; break; #endif case Pages.DefaultClientSideWebParts.ContentEmbed: controlInstance.Type = WebPartType.ContentEmbed; break; case Pages.DefaultClientSideWebParts.DocumentEmbed: controlInstance.Type = WebPartType.DocumentEmbed; break; case Pages.DefaultClientSideWebParts.Image: controlInstance.Type = WebPartType.Image; break; case Pages.DefaultClientSideWebParts.ImageGallery: controlInstance.Type = WebPartType.ImageGallery; break; case Pages.DefaultClientSideWebParts.LinkPreview: controlInstance.Type = WebPartType.LinkPreview; break; case Pages.DefaultClientSideWebParts.NewsFeed: controlInstance.Type = WebPartType.NewsFeed; break; case Pages.DefaultClientSideWebParts.NewsReel: controlInstance.Type = WebPartType.NewsReel; break; case Pages.DefaultClientSideWebParts.QuickChart: controlInstance.Type = WebPartType.QuickChart; break; case Pages.DefaultClientSideWebParts.SiteActivity: controlInstance.Type = WebPartType.SiteActivity; break; case Pages.DefaultClientSideWebParts.VideoEmbed: controlInstance.Type = WebPartType.VideoEmbed; break; case Pages.DefaultClientSideWebParts.YammerEmbed: controlInstance.Type = WebPartType.YammerEmbed; break; case Pages.DefaultClientSideWebParts.Events: controlInstance.Type = WebPartType.Events; break; case Pages.DefaultClientSideWebParts.Hero: controlInstance.Type = WebPartType.Hero; break; case Pages.DefaultClientSideWebParts.List: controlInstance.Type = WebPartType.List; break; case Pages.DefaultClientSideWebParts.PageTitle: controlInstance.Type = WebPartType.PageTitle; break; case Pages.DefaultClientSideWebParts.People: controlInstance.Type = WebPartType.People; break; case Pages.DefaultClientSideWebParts.QuickLinks: controlInstance.Type = WebPartType.QuickLinks; break; case Pages.DefaultClientSideWebParts.CustomMessageRegion: controlInstance.Type = WebPartType.CustomMessageRegion; break; case Pages.DefaultClientSideWebParts.Divider: controlInstance.Type = WebPartType.Divider; break; case Pages.DefaultClientSideWebParts.Spacer: controlInstance.Type = WebPartType.Spacer; break; case Pages.DefaultClientSideWebParts.ThirdParty: controlInstance.Type = WebPartType.Custom; break; default: controlInstance.Type = WebPartType.Custom; break; } if (excludeAuthorInformation) { #if !SP2019 if (webPartType == Pages.DefaultClientSideWebParts.News) { var properties = (control as Pages.ClientSideWebPart).Properties; var authorTokens = properties.SelectTokens("$..author").ToList(); foreach (var authorToken in authorTokens) { authorToken.Parent.Remove(); } var authorAccountNameTokens = properties.SelectTokens("$..authorAccountName").ToList(); foreach (var authorAccountNameToken in authorAccountNameTokens) { authorAccountNameToken.Parent.Remove(); } (control as Pages.ClientSideWebPart).PropertiesJson = properties.ToString(); } #endif } string jsonControlData = "\"id\": \"" + (control as Pages.ClientSideWebPart).WebPartId + "\", \"instanceId\": \"" + (control as Pages.ClientSideWebPart).InstanceId + "\", \"title\": " + JsonConvert.ToString((control as Pages.ClientSideWebPart).Title) + ", \"description\": " + JsonConvert.ToString((control as Pages.ClientSideWebPart).Description) + ", \"dataVersion\": \"" + (control as Pages.ClientSideWebPart).DataVersion + "\", \"properties\": " + (control as Pages.ClientSideWebPart).PropertiesJson + ""; // set the control properties if ((control as Pages.ClientSideWebPart).ServerProcessedContent != null) { // If we have serverProcessedContent then also export that one, it's important as some controls depend on this information to be present string serverProcessedContent = (control as Pages.ClientSideWebPart).ServerProcessedContent.ToString(Formatting.None); jsonControlData = jsonControlData + ", \"serverProcessedContent\": " + serverProcessedContent + ""; } if ((control as Pages.ClientSideWebPart).DynamicDataPaths != null) { // If we have serverProcessedContent then also export that one, it's important as some controls depend on this information to be present string dynamicDataPaths = (control as Pages.ClientSideWebPart).DynamicDataPaths.ToString(Formatting.None); jsonControlData = jsonControlData + ", \"dynamicDataPaths\": " + dynamicDataPaths + ""; } if ((control as Pages.ClientSideWebPart).DynamicDataValues != null) { // If we have serverProcessedContent then also export that one, it's important as some controls depend on this information to be present string dynamicDataValues = (control as Pages.ClientSideWebPart).DynamicDataValues.ToString(Formatting.None); jsonControlData = jsonControlData + ", \"dynamicDataValues\": " + dynamicDataValues + ""; } controlInstance.JsonControlData = "{" + jsonControlData + "}"; var untokenizedJsonControlData = controlInstance.JsonControlData; // Tokenize the JsonControlData controlInstance.JsonControlData = TokenizeJsonControlData(web, controlInstance.JsonControlData); // Export relevant files if this flag is set if (creationInfo.PersistBrandingFiles) { List <Guid> fileGuids = new List <Guid>(); Dictionary <string, string> exportedFiles = new Dictionary <string, string>(); Dictionary <string, string> exportedPages = new Dictionary <string, string>(); CollectSiteAssetImageFiles(regexSiteAssetUrls, web, untokenizedJsonControlData, fileGuids); CollectImageFilesFromGenericGuids(regexGuidPattern, regexGuidPatternEncoded, untokenizedJsonControlData, fileGuids); // Iterate over the found guids to see if they're exportable files foreach (var uniqueId in fileGuids) { try { if (!exportedFiles.ContainsKey(uniqueId.ToString()) && !errorneousOrNonImageFileGuids.Contains(uniqueId.ToString())) { // Try to see if this is a file var file = web.GetFileById(uniqueId); web.Context.Load(file, f => f.Level, f => f.ServerRelativeUrl); web.Context.ExecuteQueryRetry(); // Item1 = was file added to the template // Item2 = file name (if file found) var imageAddedTuple = LoadAndAddPageImage(web, file, template, creationInfo, scope); if (!string.IsNullOrEmpty(imageAddedTuple.Item2)) { if (!imageAddedTuple.Item2.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase)) { if (imageAddedTuple.Item1) { // Keep track of the exported file path and it's UniqueId exportedFiles.Add(uniqueId.ToString(), file.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray())); } } else { if (!exportedPages.ContainsKey(uniqueId.ToString())) { exportedPages.Add(uniqueId.ToString(), file.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray())); } } } } } catch (Exception ex) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePageContents_ErrorDuringFileExport, ex.Message); errorneousOrNonImageFileGuids.Add(uniqueId.ToString()); } } // Tokenize based on the found files, use a different token for encoded guids do we can later on replace by a new encoded guid foreach (var exportedFile in exportedFiles) { controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedFile.Key.Replace("-", "%2D"), $"{{fileuniqueidencoded:{exportedFile.Value}}}", RegexOptions.IgnoreCase); controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedFile.Key, $"{{fileuniqueid:{exportedFile.Value}}}", RegexOptions.IgnoreCase); } foreach (var exportedPage in exportedPages) { controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedPage.Key.Replace("-", "%2D"), $"{{pageuniqueidencoded:{exportedPage.Value}}}", RegexOptions.IgnoreCase); controlInstance.JsonControlData = Regex.Replace(controlInstance.JsonControlData, exportedPage.Key, $"{{pageuniqueid:{exportedPage.Value}}}", RegexOptions.IgnoreCase); } } } // add control to section sectionInstance.Controls.Add(controlInstance); } } extractedPageInstance.Sections.Add(sectionInstance); } // Renumber the sections...when editing modern homepages you can end up with section with order 0.5 or 0.75...let's ensure we render section as of 1 int sectionOrder = 1; foreach (var sectionInstance in extractedPageInstance.Sections) { sectionInstance.Order = sectionOrder; sectionOrder++; } #if !SP2019 // Spaces support if (pageToExtract.LayoutType == Pages.ClientSidePageLayoutType.Spaces && !string.IsNullOrEmpty(pageToExtract.SpaceContent)) { extractedPageInstance.FieldValues.Add(Pages.ClientSidePage.SpaceContentField, pageToExtract.SpaceContent); } #endif // Add the page to the template if (page.IsTranslation) { var parentPage = template.ClientSidePages.Where(p => p.PageName == page.SourcePageName).FirstOrDefault(); if (parentPage != null) { var translatedPageInstance = (TranslatedClientSidePage)extractedPageInstance; translatedPageInstance.LCID = new CultureInfo(page.Language).LCID; parentPage.Translations.Add(translatedPageInstance); } } else { var clientSidePageInstance = (ClientSidePage)extractedPageInstance; if (page.TranslatedLanguages != null && page.TranslatedLanguages.Count > 0) { clientSidePageInstance.CreateTranslations = true; clientSidePageInstance.LCID = Convert.ToInt32(web.EnsureProperty(p => p.Language)); } template.ClientSidePages.Add(clientSidePageInstance); } // Set the homepage if (page.IsHomePage) { if (template.WebSettings == null) { template.WebSettings = new WebSettings(); } if (page.PageUrl.StartsWith(web.ServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase)) { template.WebSettings.WelcomePage = page.PageUrl.Replace(web.ServerRelativeUrl + "/", ""); } else { template.WebSettings.WelcomePage = page.PageUrl; } } } } catch (ArgumentException ex) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePageContents_NoValidPage, ex.Message); } }
private void ExtractTemplate(XMLPnPSchemaVersion schema, string path, string packageName) { SelectedWeb.EnsureProperty(w => w.Url); var creationInformation = new ProvisioningTemplateCreationInformation(SelectedWeb); if (this.MyInvocation.BoundParameters.ContainsKey("Handlers")) { creationInformation.HandlersToProcess = Handlers; } if (this.MyInvocation.BoundParameters.ContainsKey("ExcludeHandlers")) { foreach (var handler in (OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers[])Enum.GetValues(typeof(Handlers))) { if (!ExcludeHandlers.Has(handler) && handler != Handlers.All) { Handlers = Handlers | handler; } } creationInformation.HandlersToProcess = Handlers; } var extension = ""; if (packageName != null) { if (packageName.IndexOf(".") > -1) { extension = packageName.Substring(packageName.LastIndexOf(".")).ToLower(); } else { packageName += ".pnp"; extension = ".pnp"; } } if (extension == ".pnp") { var fileSystemConnector = new FileSystemConnector(path, ""); creationInformation.FileConnector = new OpenXMLConnector(packageName, fileSystemConnector); } #pragma warning disable 618 creationInformation.PersistBrandingFiles = PersistBrandingFiles || PersistComposedLookFiles; #pragma warning restore 618 creationInformation.PersistPublishingFiles = PersistPublishingFiles; creationInformation.IncludeNativePublishingFiles = IncludeNativePublishingFiles; creationInformation.IncludeSiteGroups = IncludeSiteGroups; #if !SP2013 creationInformation.PersistMultiLanguageResources = PersistMultiLanguageResources; if (!string.IsNullOrEmpty(ResourceFilePrefix)) { creationInformation.ResourceFilePrefix = ResourceFilePrefix; } else { if (Out != null) { FileInfo fileInfo = new FileInfo(Out); var prefix = fileInfo.Name.Substring(0, fileInfo.Name.LastIndexOf(".")); creationInformation.ResourceFilePrefix = prefix; } } #endif if (ExtensibilityHandlers != null) { creationInformation.ExtensibilityHandlers = ExtensibilityHandlers.ToList <ExtensibilityHandler>(); } #pragma warning disable CS0618 // Type or member is obsolete if (NoBaseTemplate) { creationInformation.BaseTemplate = null; } else { creationInformation.BaseTemplate = this.SelectedWeb.GetBaseTemplate(); } #pragma warning restore CS0618 // Type or member is obsolete creationInformation.ProgressDelegate = (message, step, total) => { WriteProgress(new ProgressRecord(0, string.Format("Extracting Template from {0}", SelectedWeb.Url), message) { PercentComplete = (100 / total) * step }); }; creationInformation.MessagesDelegate = (message, type) => { if (type == ProvisioningMessageType.Warning) { WriteWarning(message); } }; if (IncludeAllTermGroups) { creationInformation.IncludeAllTermGroups = true; } else { if (IncludeSiteCollectionTermGroup) { creationInformation.IncludeSiteCollectionTermGroup = true; } } var template = SelectedWeb.GetProvisioningTemplate(creationInformation); ITemplateFormatter formatter = null; switch (schema) { case XMLPnPSchemaVersion.LATEST: { formatter = XMLPnPSchemaFormatter.LatestFormatter; break; } case XMLPnPSchemaVersion.V201503: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_03); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201505: { #pragma warning disable CS0618 // Type or member is obsolete formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_05); #pragma warning restore CS0618 // Type or member is obsolete break; } case XMLPnPSchemaVersion.V201508: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_08); break; } case XMLPnPSchemaVersion.V201512: { formatter = XMLPnPSchemaFormatter.GetSpecificFormatter(XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_12); break; } } if (extension == ".pnp") { XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider( creationInformation.FileConnector as OpenXMLConnector); var templateFileName = packageName.Substring(0, packageName.LastIndexOf(".")) + ".xml"; provider.SaveAs(template, templateFileName, formatter); } else { var _outputStream = formatter.ToFormattedTemplate(template); StreamReader reader = new StreamReader(_outputStream); if (Out != null) { File.WriteAllText(Path.Combine(path, packageName), reader.ReadToEnd(), Encoding); } else { WriteObject(reader.ReadToEnd()); } } }
private Tuple <bool, string> LoadAndAddPageImage(Web web, Microsoft.SharePoint.Client.File pageImage, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope) { var baseUri = new Uri(web.Url); var fullUri = new Uri(baseUri, pageImage.ServerRelativeUrl); var folderPath = HttpUtility.UrlDecode(fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/')); var fileName = HttpUtility.UrlDecode(fullUri.Segments[fullUri.Segments.Count() - 1]); if (!fileName.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase)) { var templateFolderPath = folderPath.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()); // Avoid duplicate file entries var fileAlreadyExported = template.Files.Where(p => p.Folder.Equals(templateFolderPath, StringComparison.CurrentCultureIgnoreCase) && p.Src.Equals(fileName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault(); if (fileAlreadyExported == null) { // Add a File to the template template.Files.Add(new Model.File() { Folder = templateFolderPath, Src = $"{templateFolderPath}/{fileName}", Overwrite = true, Level = (Model.FileLevel)Enum.Parse(typeof(Model.FileLevel), pageImage.Level.ToString()) }); // Export the file PersistFile(web, creationInfo, scope, folderPath, fileName); return(new Tuple <bool, string>(true, fileName)); } } return(new Tuple <bool, string>(false, fileName)); }
protected override void ExecuteCmdlet() { // var template = new ProvisioningTemplate(); var templateCi = new ProvisioningTemplateCreationInformation(ClientContext.Web) { IncludeAllTermGroups = true }; templateCi.HandlersToProcess = Handlers.TermGroups; var template = ClientContext.Web.GetProvisioningTemplate(templateCi); if (ParameterSpecified(nameof(Identity))) { if (Identity.Id != Guid.Empty) { template.TermGroups.RemoveAll(t => t.Id != Identity.Id); } else if (Identity.Name != string.Empty) { template.TermGroups.RemoveAll(t => t.Name != Identity.Name); } } var outputStream = XMLPnPSchemaFormatter.LatestFormatter.ToFormattedTemplate(template); var reader = new StreamReader(outputStream); var fullxml = reader.ReadToEnd(); var xml = string.Empty; if (!FullTemplate) { var document = XDocument.Parse(fullxml); XNamespace pnp = document.Root.GetNamespaceOfPrefix("pnp"); var termGroupsElement = document.Root.Descendants(pnp + "TermGroups").FirstOrDefault(); if (termGroupsElement != null) { xml = termGroupsElement.ToString(); } } else { xml = fullxml; } if (!string.IsNullOrEmpty(Out)) { if (!Path.IsPathRooted(Out)) { Out = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Out); } if (File.Exists(Out)) { if (Force || ShouldContinue(string.Format(Resources.File0ExistsOverwrite, Out), Resources.Confirm)) { File.WriteAllText(Out, xml, Encoding); } } else { File.WriteAllText(Out, xml, Encoding); } } else { WriteObject(xml); } }
private void DumpTemplate(ClientContext ctx, string template, string subSiteTemplate = "", string saveAsTemplate = "") { Uri devSiteUrl = new Uri(ConfigurationManager.AppSettings["SPODevSiteUrl"]); string baseUrl = String.Format("{0}://{1}", devSiteUrl.Scheme, devSiteUrl.DnsSafeHost); string siteUrl = ""; if (subSiteTemplate.Length > 0) { siteUrl = string.Format("{1}/sites/template{0}/template{2}", template.Replace("#", ""), baseUrl, subSiteTemplate.Replace("#", "")); #if !CLIENTSDKV15 var siteCollectionUrl = string.Format("{1}/sites/template{0}", template.Replace("#", ""), baseUrl); CreateSiteCollection(template, siteCollectionUrl); using (var sitecolCtx = ctx.Clone(siteCollectionUrl)) { sitecolCtx.Web.Webs.Add(new WebCreationInformation() { Title = string.Format("template{0}", subSiteTemplate), Language = 1033, Url = string.Format("template{0}", subSiteTemplate.Replace("#", "")), UseSamePermissionsAsParentSite = true }); sitecolCtx.ExecuteQueryRetry(); } #endif } else { siteUrl = string.Format("{1}/sites/template{0}", template.Replace("#", ""), baseUrl); #if !CLIENTSDKV15 CreateSiteCollection(template, siteUrl); #endif } using (ClientContext cc = ctx.Clone(siteUrl)) { // Specify null as base template since we do want "everything" in this case ProvisioningTemplateCreationInformation creationInfo = new ProvisioningTemplateCreationInformation(cc.Web); creationInfo.BaseTemplate = null; // Override the save name. Case is online site collection provisioned using blankinternetcontainer#0 which returns // blankinternet#0 as web template using CSOM/SSOM API if (saveAsTemplate.Length > 0) { template = saveAsTemplate; } ProvisioningTemplate p = cc.Web.GetProvisioningTemplate(creationInfo); if (subSiteTemplate.Length > 0) { p.Id = String.Format("{0}template", subSiteTemplate.Replace("#", "")); } else { p.Id = String.Format("{0}template", template.Replace("#", "")); } // Cleanup before saving p.Security.AdditionalAdministrators.Clear(); XMLFileSystemTemplateProvider provider = new XMLFileSystemTemplateProvider(".", ""); if (subSiteTemplate.Length > 0) { provider.SaveAs(p, String.Format("{0}Template.xml", subSiteTemplate.Replace("#", ""))); } else { provider.SaveAs(p, String.Format("{0}Template.xml", template.Replace("#", ""))); } #if !CLIENTSDKV15 using (var tenantCtx = TestCommon.CreateTenantClientContext()) { Tenant tenant = new Tenant(tenantCtx); Console.WriteLine("Deleting new site {0}", string.Format("{1}/sites/template{0}", template.Replace("#", ""), baseUrl)); tenant.DeleteSiteCollection(siteUrl, false); } #endif } }
protected override void ExecuteCmdlet() { var template = new ProvisioningTemplate(); var templateCi = new ProvisioningTemplateCreationInformation(ClientContext.Web) { IncludeAllTermGroups = true }; template = new ObjectTermGroups().CreateEntities(ClientContext.Web, template, templateCi); template.Security = null; template.Features = null; template.CustomActions = null; template.ComposedLook = null; if (this.MyInvocation.BoundParameters.ContainsKey("Identity")) { if (Identity.Id != Guid.Empty) { template.TermGroups.RemoveAll(t => t.Id != Identity.Id); } else if (Identity.Name != string.Empty) { template.TermGroups.RemoveAll(t => t.Name != Identity.Name); } } var outputStream = XMLPnPSchemaFormatter.LatestFormatter.ToFormattedTemplate(template); var reader = new StreamReader(outputStream); var fullxml = reader.ReadToEnd(); var xml = string.Empty; if (!FullTemplate) { var document = XDocument.Parse(fullxml); XNamespace pnp = XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_2015_05; var termGroupsElement = document.Root.Descendants(pnp + "TermGroups").FirstOrDefault(); if (termGroupsElement != null) { xml = termGroupsElement.ToString(); } } else { xml = fullxml; } if (!string.IsNullOrEmpty(Out)) { if (!Path.IsPathRooted(Out)) { Out = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Out); } if (File.Exists(Out)) { if (Force || ShouldContinue(string.Format(Resources.File0ExistsOverwrite, Out), Resources.Confirm)) { File.WriteAllText(Out, xml, Encoding); } } else { File.WriteAllText(Out, xml, Encoding); } } else { WriteObject(xml); } }
private string DownloadFile(string fileServerRelativeURL, ListItem item, ProvisioningTemplateCreationInformation creationInfo) { string src = ""; if (null != creationInfo.FileConnector) { ClientResult<Stream> streamResult = item.File.OpenBinaryStream(); this.Context.ExecuteQueryRetry(); using (Stream stream = streamResult.Value) { creationInfo.FileConnector.SaveFileStream(fileServerRelativeURL, streamResult.Value); src = Path.Combine(creationInfo.FileConnector.GetConnectionString(), Path.GetDirectoryName(fileServerRelativeURL), Path.GetFileName(fileServerRelativeURL)); } } return src; }
public static ExtractConfiguration FromCreationInformation(ProvisioningTemplateCreationInformation information) { var config = new ExtractConfiguration { BaseTemplate = information.BaseTemplate }; config.ContentTypes.Groups = information.ContentTypeGroupsToInclude; config.Extensibility.Handlers = information.ExtensibilityHandlers; config.FileConnector = information.FileConnector; if (information.HandlersToProcess == Model.Handlers.All) { config.Handlers = new List <ConfigurationHandler>(); } else { foreach (var handler in (Handlers[])Enum.GetValues(typeof(Handlers))) { if (information.HandlersToProcess.HasFlag(handler)) { if (Enum.TryParse <ConfigurationHandler>(handler.ToString(), out ConfigurationHandler configurationHandler)) { config.Handlers.Add(configurationHandler); } } } } config.Pages.IncludeAllClientSidePages = information.IncludeAllClientSidePages; config.Taxonomy.IncludeAllTermGroups = information.IncludeAllTermGroups; config.Taxonomy.IncludeSiteCollectionTermGroup = information.IncludeSiteCollectionTermGroup; config.SiteSecurity.IncludeSiteGroups = information.IncludeSiteGroups; config.Taxonomy.IncludeSecurity = information.IncludeTermGroupsSecurity; if (information.ListsToExtract != null && information.ListsToExtract.Any()) { foreach (var list in information.ListsToExtract) { config.Lists.Lists.Add(new Configuration.Lists.Lists.ExtractListsListsConfiguration() { Title = list }); } } if (information.MessagesDelegate != null) { config.MessagesDelegate = (message, type) => { information.MessagesDelegate(message, type); }; } config.PersistAssetFiles = information.PersistBrandingFiles || information.PersistPublishingFiles; config.MultiLanguage.PersistResources = information.PersistMultiLanguageResources; if (information.ProgressDelegate != null) { config.ProgressDelegate = (message, step, total) => { information.ProgressDelegate(message, step, total); }; } config.PropertyBag.ValuesToPreserve = information.PropertyBagPropertiesToPreserve; config.MultiLanguage.ResourceFilePrefix = information.ResourceFilePrefix; config.Publishing.Persist = information.PersistPublishingFiles; config.Publishing.IncludeNativePublishingFiles = information.IncludeNativePublishingFiles; config.SearchSettings.Include = information.IncludeSearchConfiguration; return(config); }