예제 #1
0
 private StructuralNavigation GetCurrentStructuralNavigation(Web web, WebNavigationSettings navigationSettings, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(GetStructuralNavigation(web, navigationSettings, Enums.NavigationType.QuickLaunch, template, creationInfo));
 }
예제 #2
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(creationInfo.PersistMultiLanguageResources);
 }
예제 #3
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            if (template.Workflows == null)
            {
                template.Workflows = new Workflows();
            }

            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (creationInfo.FileConnector == null)
                {
                    scope.LogWarning("Cannot export Workflow definitions without a FileConnector.");
                }
                else
                {
                    // Pre-load useful properties
                    web.EnsureProperties(w => w.Id, w => w.ServerRelativeUrl, w => w.Url);

                    // Retrieve all the lists and libraries
                    var lists = web.Lists;
                    web.Context.Load(lists);
                    web.Context.ExecuteQueryRetry();

                    // Retrieve the workflow definitions (including unpublished ones)
                    Microsoft.SharePoint.Client.WorkflowServices.WorkflowDefinition[] definitions = null;

                    try
                    {
                        definitions = web.GetWorkflowDefinitions(false);
                    }
                    catch (ServerException)
                    {
                        // If there is no workflow service present in the farm this method will throw an error.
                        // Swallow the exception
                    }

                    if (definitions != null)
                    {
                        template.Workflows.WorkflowDefinitions.AddRange(
                            from d in definitions.AsEnumerable()
                            select new Model.WorkflowDefinition(d.Properties.TokenizeWorkflowDefinitionProperties(lists))
                        {
                            AssociationUrl          = d.AssociationUrl,
                            Description             = d.Description,
                            DisplayName             = d.DisplayName,
                            DraftVersion            = d.DraftVersion,
                            FormField               = d.FormField,
                            Id                      = d.Id,
                            InitiationUrl           = d.InitiationUrl,
                            Published               = d.Published,
                            RequiresAssociationForm = d.RequiresAssociationForm,
                            RequiresInitiationForm  = d.RequiresInitiationForm,
                            RestrictToScope         = (!String.IsNullOrEmpty(d.RestrictToScope) && Guid.Parse(d.RestrictToScope) != web.Id) ? WorkflowExtension.TokenizeListIdProperty(d.RestrictToScope, lists) : null,
                            RestrictToType          = !String.IsNullOrEmpty(d.RestrictToType) ? d.RestrictToType : "Universal",
                            XamlPath                = d.Xaml.SaveXamlToFile(d.Id, creationInfo.FileConnector, lists),
                        }
                            );

                        foreach (var d in definitions.AsEnumerable())
                        {
                            if (d.RequiresInitiationForm)
                            {
                                PersistWorkflowForm(web, template, creationInfo, scope, d.InitiationUrl);
                            }
                            if (d.RequiresAssociationForm)
                            {
                                PersistWorkflowForm(web, template, creationInfo, scope, d.AssociationUrl);
                            }
                        }
                    }

                    // Retrieve the workflow subscriptions
                    Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription[] subscriptions = null;

                    try
                    {
                        subscriptions = web.GetWorkflowSubscriptions();
                    }
                    catch (ServerException)
                    {
                        // If there is no workflow service present in the farm this method will throw an error.
                        // Swallow the exception
                    }

                    if (subscriptions != null)
                    {
                        template.Workflows.WorkflowSubscriptions.AddRange(
                            from s in subscriptions.AsEnumerable()
                            select new Model.WorkflowSubscription(s.PropertyDefinitions.TokenizeWorkflowSubscriptionProperties(lists))
                        {
                            DefinitionId  = s.DefinitionId,
                            Enabled       = s.Enabled,
                            EventSourceId = s.EventSourceId != web.Id ? WorkflowExtension.TokenizeListIdProperty(s.EventSourceId.ToString(), lists) : null,
                            EventTypes    = s.EventTypes.ToList(),
                            ManualStartBypassesActivationLimit = s.ManualStartBypassesActivationLimit,
                            Name   = s.Name,
                            ListId = s.EventSourceId != web.Id ? WorkflowExtension.TokenizeListIdProperty(s.EventSourceId.ToString(), lists) : null,
                            ParentContentTypeId = s.ParentContentTypeId,
                            StatusFieldName     = s.StatusFieldName,
                        }
                            );
                    }
                }
            }
            return(template);
        }
예제 #4
0
 public abstract ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo);
        public override ProvisioningHierarchy ExtractObjects(Tenant tenant, ProvisioningHierarchy hierarchy, ExtractConfiguration configuration)
        {
            ProvisioningHierarchy tenantTemplate     = new ProvisioningHierarchy();
            List <string>         siteCollectionUrls = configuration.Tenant.Sequence.SiteUrls;

            List <string> connectedSiteUrls = new List <string>();

            foreach (var siteCollectionUrl in siteCollectionUrls)
            {
                using (var siteContext = tenant.Context.Clone(siteCollectionUrl))
                {
                    if (configuration.Tenant.Sequence.IncludeJoinedSites && siteContext.Site.EnsureProperty(s => s.IsHubSite))
                    {
                        foreach (var hubsiteChildUrl in tenant.GetHubSiteChildUrls(siteContext.Site.EnsureProperty(s => s.Id)))
                        {
                            if (!connectedSiteUrls.Contains(hubsiteChildUrl) && !siteCollectionUrl.Contains(hubsiteChildUrl))
                            {
                                connectedSiteUrls.Add(hubsiteChildUrl);
                            }
                        }
                    }
                }
            }
            siteCollectionUrls.AddRange(connectedSiteUrls);

            ProvisioningSequence provisioningSequence = new ProvisioningSequence
            {
                ID = "TENANTSEQUENCE"
            };

            foreach (var siteCollectionUrl in siteCollectionUrls)
            {
                var siteProperties = tenant.GetSitePropertiesByUrl(siteCollectionUrl, true);

                tenant.Context.Load(siteProperties);
                tenant.Context.ExecuteQueryRetry();
                Model.SiteCollection siteCollection = null;
                using (var siteContext = tenant.Context.Clone(siteCollectionUrl))
                {
                    siteContext.Site.EnsureProperties(s => s.Id, s => s.ShareByEmailEnabled, s => s.Classification, s => s.GroupId);

                    var templateGuid = siteContext.Site.Id.ToString("N");
                    switch (siteProperties.Template)
                    {
                    case "SITEPAGEPUBLISHING#0":
                    {
                        siteCollection = new CommunicationSiteCollection
                        {
                            IsHubSite = siteProperties.IsHubSite
                        };
                        if (siteProperties.IsHubSite)
                        {
                            var hubsiteProperties = tenant.GetHubSitePropertiesByUrl(siteCollectionUrl);
                            tenant.Context.Load(hubsiteProperties);
                            tenant.Context.ExecuteQueryRetry();
                            siteCollection.HubSiteLogoUrl = hubsiteProperties.LogoUrl;
                            siteCollection.HubSiteTitle   = hubsiteProperties.Title;
                        }
                        siteCollection.Description = siteProperties.Description;
                        ((CommunicationSiteCollection)siteCollection).Language = (int)siteProperties.Lcid;
                        ((CommunicationSiteCollection)siteCollection).Owner    = siteProperties.OwnerEmail;
                        ((CommunicationSiteCollection)siteCollection).AllowFileSharingForGuestUsers = siteContext.Site.ShareByEmailEnabled;
                        if (!string.IsNullOrEmpty(siteContext.Site.Classification))
                        {
                            ((CommunicationSiteCollection)siteCollection).Classification = siteContext.Site.Classification;
                        }
                        tenantTemplate.Parameters.Add($"SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_URL", siteProperties.Url);
                        ((CommunicationSiteCollection)siteCollection).Url = $"{{parameter:SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_URL}}";
                        tenantTemplate.Parameters.Add($"SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_TITLE", siteProperties.Title);
                        siteCollection.Title = $"{{parameter:SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_TITLE}}";
                        break;
                    }

                    case "GROUP#0":
                    {
                        siteCollection = new TeamSiteCollection
                        {
                            IsHubSite = siteProperties.IsHubSite
                        };
                        if (siteProperties.IsHubSite)
                        {
                            var hubsiteProperties = tenant.GetHubSitePropertiesByUrl(siteCollectionUrl);
                            tenant.Context.Load(hubsiteProperties);
                            tenant.Context.ExecuteQueryRetry();
                            siteCollection.HubSiteLogoUrl = hubsiteProperties.LogoUrl;
                            siteCollection.HubSiteTitle   = hubsiteProperties.Title;
                        }
                        siteCollection.Description = siteProperties.Description;

                        var groupInfo = Sites.SiteCollection.GetGroupInfoByGroupIdAsync(siteContext, siteContext.Site.GroupId.ToString()).GetAwaiter().GetResult();

                        if (groupInfo != null)
                        {
                            tenantTemplate.Parameters.Add($"SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_ALIAS", Convert.ToString(groupInfo["alias"]));
                            ((TeamSiteCollection)siteCollection).Alias = $"{{parameter:SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_ALIAS}}";
                            if (groupInfo["classification"] != null)
                            {
                                ((TeamSiteCollection)siteCollection).Classification = Convert.ToString(groupInfo["classification"]);
                            }
                            ((TeamSiteCollection)siteCollection).IsPublic = Convert.ToBoolean(groupInfo["isPublic"]);
                        }

                        ((TeamSiteCollection)siteCollection).DisplayName = siteProperties.Title;
                        ((TeamSiteCollection)siteCollection).Language    = (int)siteProperties.Lcid;
                        ((TeamSiteCollection)siteCollection).HideTeamify = Sites.SiteCollection.IsTeamifyPromptHiddenAsync(siteContext).GetAwaiter().GetResult();

                        tenantTemplate.Parameters.Add($"SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_TITLE", siteProperties.Title);
                        siteCollection.Title = $"{{parameter:SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_TITLE}}";
                        break;
                    }

                    case "STS#3":
                    {
                        if (siteContext.Site.GroupId == Guid.Empty)
                        {
                            siteCollection = new TeamNoGroupSiteCollection
                            {
                                IsHubSite = siteProperties.IsHubSite
                            };
                            if (siteProperties.IsHubSite)
                            {
                                var hubsiteProperties = tenant.GetHubSitePropertiesByUrl(siteCollectionUrl);
                                tenant.Context.Load(hubsiteProperties);
                                tenant.Context.ExecuteQueryRetry();
                                siteCollection.HubSiteLogoUrl = hubsiteProperties.LogoUrl;
                                siteCollection.HubSiteTitle   = hubsiteProperties.Title;
                            }
                            siteCollection.Description = siteProperties.Description;
                            ((TeamNoGroupSiteCollection)siteCollection).Language   = (int)siteProperties.Lcid;
                            ((TeamNoGroupSiteCollection)siteCollection).Owner      = siteProperties.OwnerEmail;
                            ((TeamNoGroupSiteCollection)siteCollection).TimeZoneId = siteProperties.TimeZoneId;
                            tenantTemplate.Parameters.Add($"SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_URL", siteProperties.Url);
                            ((TeamNoGroupSiteCollection)siteCollection).Url = $"{{parameter:SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_URL}}";
                            tenantTemplate.Parameters.Add($"SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_TITLE", siteProperties.Title);
                            siteCollection.Title = $"{{parameter:SITECOLLECTION_{siteContext.Site.Id.ToString("N")}_TITLE}}";
                            break;
                        }
                        else
                        {
                            goto case "GROUP#0";
                        }
                    }
                    }
                    var siteTemplateCreationInfo = new ProvisioningTemplateCreationInformation(siteContext.Web);

                    // Retrieve the template for the site
                    if (configuration != null)
                    {
                        siteTemplateCreationInfo = configuration.ToCreationInformation(siteContext.Web);
                    }
                    var siteTemplate = siteContext.Web.GetProvisioningTemplate(siteTemplateCreationInfo);
                    siteTemplate.Id = $"TEMPLATE-{templateGuid}";
                    if (siteProperties.HubSiteId != null && siteProperties.HubSiteId != Guid.Empty && siteProperties.HubSiteId != siteContext.Site.Id && siteTemplate.WebSettings != null)
                    {
                        siteTemplate.WebSettings.HubSiteUrl = $"{{parameter:SITECOLLECTION_{siteProperties.HubSiteId.ToString("N")}_URL}}";
                    }
                    tenantTemplate.Templates.Add(siteTemplate);

                    siteCollection.Templates.Add(siteTemplate.Id);

                    if (siteProperties.WebsCount > 1 && configuration.Tenant.Sequence.IncludeSubsites)
                    {
                        var webs         = siteContext.Web.EnsureProperty(w => w.Webs);
                        int currentDepth = 1;
                        foreach (var subweb in webs)
                        {
                            siteCollection.Sites.Add(ParseSubsiteSequences(subweb, ref tenantTemplate, configuration, currentDepth, configuration.Tenant.Sequence.MaxSubsiteDepth));
                        }
                    }
                    provisioningSequence.SiteCollections.Add(siteCollection);
                }
            }

            tenantTemplate.Sequences.Add(provisioningSequence);

            PnPProvisioningContext.Current?.ParsedSiteUrls.Clear();
            PnPProvisioningContext.Current?.ParsedSiteUrls.AddRange(siteCollectionUrls);

            return(tenantTemplate);
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look);

                // Ensure that we have URL property loaded for web and site
                web.EnsureProperty(w => w.Url);
                Site site = (web.Context as ClientContext).Site;
                site.EnsureProperty(s => s.Url);

                SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy");
                // to get files from theme catalog we need a connector linked to the root site
                SharePointConnector spConnectorRoot;
                if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase))
                {
                    spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy");
                }
                else
                {
                    spConnectorRoot = spConnector;
                }

                // Check if we have composed look info in the property bag, if so, use that, otherwise try to detect the current composed look
                if (web.PropertyBagContainsKey("_PnP_ProvisioningTemplateComposedLookInfo"))
                {
                    scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Using_ComposedLookInfoFromPropertyBag);

                    try
                    {
                        var composedLook = JsonConvert.DeserializeObject <ComposedLook>(web.GetPropertyBagValueString("_PnP_ProvisioningTemplateComposedLookInfo", ""));
                        if (composedLook.Name == null)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_ComposedLookInfoFailedToDeserialize);
                            throw new JsonSerializationException();
                        }

                        composedLook.BackgroundFile = Tokenize(composedLook.BackgroundFile, web.Url);
                        composedLook.FontFile       = Tokenize(composedLook.FontFile, web.Url);
                        composedLook.ColorFile      = Tokenize(composedLook.ColorFile, web.Url);
                        template.ComposedLook       = composedLook;

                        if (!web.IsSubSite() && creationInfo != null &&
                            creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector);
                            // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment
                            TokenParser parser = new TokenParser(web, template);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.BackgroundFile), scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.ColorFile), scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.FontFile), scope);
                        }
                        // Create file entries for the custom theme files
                        if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile))
                        {
                            var f = GetComposedLookFile(template.ComposedLook.BackgroundFile);
                            f.Folder = Tokenize(f.Folder, web.Url);
                            template.Files.Add(f);
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile))
                        {
                            var f = GetComposedLookFile(template.ComposedLook.ColorFile);
                            f.Folder = Tokenize(f.Folder, web.Url);
                            template.Files.Add(f);
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.FontFile))
                        {
                            var f = GetComposedLookFile(template.ComposedLook.FontFile);
                            f.Folder = Tokenize(f.Folder, web.Url);
                            template.Files.Add(f);
                        }
                    }
                    catch (JsonSerializationException)
                    {
                        // cannot deserialize the object, fall back to composed look detection
                        template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot);
                    }
                }
                else
                {
                    template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot);
                }

                if (creationInfo != null && creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return(template);
        }
예제 #7
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Extract the Home Page
                web.EnsureProperties(w => w.RootFolder.WelcomePage, w => w.ServerRelativeUrl, w => w.Url);

                var homepageUrl = web.RootFolder.WelcomePage;
                if (string.IsNullOrEmpty(homepageUrl))
                {
                    homepageUrl = "Default.aspx";
                }
                var welcomePageUrl = UrlUtility.Combine(web.ServerRelativeUrl, homepageUrl);

                var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(welcomePageUrl));
                try
                {
                    var listItem = file.EnsureProperty(f => f.ListItemAllFields);
                    if (listItem != null)
                    {
                        if (listItem.FieldValues.ContainsKey("WikiField") && listItem.FieldValues["WikiField"] != null)
                        {
                            // 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.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(welcomePageUrl));

                            var limitedWPManager = homeFile.GetLimitedWebPartManager(PersonalizationScope.Shared);

                            web.Context.Load(limitedWPManager);

                            //var webParts = web.GetWebParts(welcomePageUrl);

                            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
                                    {
                                        var serverSideControlIdToSearchFor =
                                            $"g_{serverSideControlId.Replace("-", "_")}";

                                        var 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, welcomePageUrl));

                                        page.WebParts.Add(new 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, $"{{webpartid:{webPart.WebPart.Title}}}", RegexOptions.IgnoreCase);
                                    }
                                    catch (ServerException)
                                    {
                                        scope.LogWarning("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;
                        }
                        else if (listItem.FieldValues.ContainsKey("ClientSideApplicationId") && listItem.FieldValues["ClientSideApplicationId"] != null && listItem.FieldValues["ClientSideApplicationId"].ToString().ToLower() == "b6917cb1-93a0-4b97-a84d-7cf49975d4ec")
                        {
                            // this is a client side page, so let's skip it since it's handled by the Client Side Page contents handler
                        }
                        else
                        {
                            // Not a wikipage
                            template = GetFileContents(web, template, welcomePageUrl, creationInfo, scope);
                            if (template.WebSettings == null)
                            {
                                template.WebSettings = new WebSettings();
                            }
                            template.WebSettings.WelcomePage = homepageUrl;
                        }
                    }
                }
                catch (ServerException ex)
                {
                    //ignore this error. The default page is not a page but a list view.
                    if (ex.ServerErrorCode != -2146232832 && ex.HResult != -2146233088)
                    {
                        throw;
                    }
                    else
                    {
                        if (ex.HResult != -2146233088)
                        {
                            // Page does not belong to a list, extract the file as is
                            template = GetFileContents(web, template, welcomePageUrl, creationInfo, scope);
                            if (template.WebSettings == null)
                            {
                                template.WebSettings = new WebSettings();
                            }
                            template.WebSettings.WelcomePage = homepageUrl;
                        }
                    }
                }

                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return(template);
        }
예제 #8
0
        private bool PersistFile(Web web, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string serverRelativeUrl)
        {
            var success = false;

            if (creationInfo.PersistBrandingFiles)
            {
                if (creationInfo.FileConnector != null)
                {
                    if (UrlUtility.IsIisVirtualDirectory(serverRelativeUrl))
                    {
                        scope.LogWarning("File is not located in the content database. Not retrieving {0}", serverRelativeUrl);
                        return(success);
                    }

                    try
                    {
                        var    file     = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(serverRelativeUrl));
                        string fileName = string.Empty;
                        if (serverRelativeUrl.IndexOf("/") > -1)
                        {
                            fileName = serverRelativeUrl.Substring(serverRelativeUrl.LastIndexOf("/") + 1);
                        }
                        else
                        {
                            fileName = serverRelativeUrl;
                        }
                        web.Context.Load(file);
                        web.Context.ExecuteQueryRetry();
                        ClientResult <Stream> stream = file.OpenBinaryStream();
                        web.Context.ExecuteQueryRetry();

                        file.EnsureProperty(f => f.ServerRelativePath);
                        var baseUri    = new Uri(web.Url);
                        var fullUri    = new Uri(baseUri, file.ServerRelativePath.DecodedUrl);
                        var folderPath = Uri.UnescapeDataString(fullUri.Segments.Take(fullUri.Segments.Length - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/'));

                        // Configure the filename to use
                        fileName = Uri.UnescapeDataString(fullUri.Segments[fullUri.Segments.Length - 1]);

                        // Build up a site relative container URL...might end up empty as well
                        String container = Uri.UnescapeDataString(folderPath.Replace(web.ServerRelativeUrl, "")).Trim('/').Replace("/", "\\");

                        using (Stream memStream = new MemoryStream())
                        {
                            CopyStream(stream.Value, memStream);
                            memStream.Position = 0;
                            if (!string.IsNullOrEmpty(container))
                            {
                                creationInfo.FileConnector.SaveFileStream(fileName, container, memStream);
                            }
                            else
                            {
                                creationInfo.FileConnector.SaveFileStream(fileName, memStream);
                            }
                        }
                        success = true;
                    }
                    catch (ServerException ex1)
                    {
                        // If we are referring a file from a location outside of the current web or at a location where we cannot retrieve the file an exception is thrown. We swallow this exception.
                        if (ex1.ServerErrorCode != -2147024809)
                        {
                            throw;
                        }
                        else
                        {
                            scope.LogWarning("File is not necessarily located in the current web. Not retrieving {0}", serverRelativeUrl);
                        }
                    }
                }
                else
                {
                    WriteMessage("No connector present to persist footer logo.", ProvisioningMessageType.Error);
                    scope.LogError("No connector present to persist footer logo.");
                }
            }
            else
            {
                success = true;
            }
            return(success);
        }
예제 #9
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.EnsureProperties(w => w.FooterEnabled, w => w.ServerRelativeUrl, w => w.Url, w => w.Language);
                var defaultCulture = new CultureInfo((int)web.Language);

                var footer = new SiteFooter
                {
                    Enabled = web.FooterEnabled
                };
                var structureString = web.ExecuteGetAsync($"/_api/navigation/MenuState?menuNodeKey='{Constants.SITEFOOTER_NODEKEY}'", defaultCulture.Name).GetAwaiter().GetResult();
                var menuState       = JsonConvert.DeserializeObject <MenuState>(structureString);

                if (menuState.Nodes.Count > 0)
                {
                    // Find the title node
                    var titleNode = menuState.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_TITLENODEKEY);
                    if (titleNode != null)
                    {
                        var titleNodeNodes = titleNode.Nodes;
                        if (titleNodeNodes.Count > 0)
                        {
                            if (!string.IsNullOrEmpty(titleNodeNodes[0].SimpleUrl))
                            {
                                footer.Logo = Tokenize(titleNodeNodes[0].SimpleUrl, web.ServerRelativeUrl);
                            }
                            if (!string.IsNullOrEmpty(titleNodeNodes[0].Title))
                            {
                                if (creationInfo.PersistMultiLanguageResources)
                                {
                                    if (UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title", defaultCulture.LCID, titleNodeNodes[0].Title, creationInfo))
                                    {
                                        footer.Name = $"{{res:FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title}}";
                                    }
                                }
                                else
                                {
                                    footer.Name = titleNodeNodes[0].Title;
                                }
                            }
                        }
                    }
                    // find the logo node
                    if (string.IsNullOrEmpty(footer.Logo))
                    {
                        var logoNode = menuState.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_LOGONODEKEY);
                        if (logoNode != null)
                        {
                            footer.Logo = Tokenize(logoNode.SimpleUrl, web.ServerRelativeUrl);
                        }
                    }
                }
                // find the menu Nodes
                var menuNodesNode = menuState.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_MENUNODEKEY);
                if (menuNodesNode != null)
                {
                    foreach (var innerMenuNode in menuNodesNode.Nodes)
                    {
                        footer.FooterLinks.Add(ParseNodes(innerMenuNode, template, web.ServerRelativeUrl, creationInfo.PersistMultiLanguageResources, defaultCulture, menuNodesNode.Key, creationInfo));
                    }
                }
                if (creationInfo.ExtractConfiguration != null && creationInfo.ExtractConfiguration.SiteFooter != null && creationInfo.ExtractConfiguration.SiteFooter.RemoveExistingNodes)
                {
                    footer.RemoveExistingNodes = true;
                }

                if (creationInfo.PersistMultiLanguageResources)
                {
                    //get Titles for the rest of the Languages
                    foreach (var language in template.SupportedUILanguages.Where(c => c.LCID != defaultCulture.LCID))
                    {
                        var currentCulture     = new CultureInfo(language.LCID);
                        var structureStringMUI = web.ExecuteGetAsync($"/_api/navigation/MenuState?menuNodeKey='{Constants.SITEFOOTER_NODEKEY}'", currentCulture.Name).GetAwaiter().GetResult();
                        var menuStateMUI       = JsonConvert.DeserializeObject <MenuState>(structureStringMUI);

                        if (menuStateMUI.Nodes.Count > 0)
                        {
                            var titleNode = menuStateMUI.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_TITLENODEKEY);
                            if (titleNode != null)
                            {
                                var titleNodeNodes = titleNode.Nodes;
                                if (titleNodeNodes.Count > 0)
                                {
                                    if (!string.IsNullOrEmpty(titleNodeNodes[0].Title))
                                    {
                                        if (UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title", currentCulture.LCID, titleNodeNodes[0].Title, creationInfo))
                                        {
                                            footer.Name = $"{{res:FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title}}";
                                        }
                                    }
                                }
                            }
                        }
                        // find the menu Nodes

                        var menuNodesNodeMUI = menuStateMUI.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_MENUNODEKEY);
                        if (menuNodesNodeMUI != null)
                        {
                            foreach (var innerMenuNode in menuNodesNodeMUI.Nodes)
                            {
                                ParseNodesMUI(innerMenuNode, web.ServerRelativeUrl, currentCulture, menuNodesNode.Key, creationInfo);
                            }
                        }
                    }
                }

                template.Footer = footer;
                if (creationInfo.PersistBrandingFiles)
                {
                    // Extract site logo if property has been set and it's not dynamic image from _api URL
                    if (!string.IsNullOrEmpty(template.Footer.Logo) && (!template.Footer.Logo.ToLowerInvariant().Contains("_api/")))
                    {
                        // Convert to server relative URL if needed (can be set to FQDN URL of a file hosted in the site (e.g. for communication sites))
                        Uri    webUri = new Uri(web.Url);
                        string webUrl = $"{webUri.Scheme}://{webUri.DnsSafeHost}";
                        string footerLogoServerRelativeUrl = template.Footer.Logo.Replace(webUrl, "");

                        if (PersistFile(web, creationInfo, scope, footerLogoServerRelativeUrl))
                        {
                            template.Files.Add(GetTemplateFile(web, footerLogoServerRelativeUrl));
                        }
                    }
                    template.Footer.Logo = Tokenize(template.Footer.Logo, web.Url, web);
                    var files = template.Files.Distinct().ToList();
                    template.Files.Clear();
                    template.Files.AddRange(files);
                }
            }
            return(template);
        }
예제 #10
0
        internal static Model.NavigationNode ToDomainModelNavigationNode(this Microsoft.SharePoint.Client.NavigationNode node, Web web, bool PersistLanguage, CultureInfo currentCulture, ProvisioningTemplateCreationInformation creationInfo, int ParentNodeId = 0)
        {
            string nodeTitle = node.Title;

            if (PersistLanguage && !string.IsNullOrWhiteSpace(nodeTitle))
            {
                if (UserResourceExtensions.PersistResourceValue($"NavigationNode_{ParentNodeId}_{node.Id}_Title", currentCulture.LCID, nodeTitle, creationInfo))
                {
                    nodeTitle = $"{{res:NavigationNode_{ParentNodeId}_{node.Id}_Title}}";
                }
            }
            var result = new Model.NavigationNode
            {
                Title      = nodeTitle,
                IsExternal = node.IsExternal,
                Url        = web.ServerRelativeUrl != "/" ? node.Url.Replace(web.ServerRelativeUrl, "{site}") : $"{{site}}{node.Url}"
            };

            node.Context.Load(node.Children);
            var acceptLanguage = node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"];

            if (PersistLanguage)
            {
                node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = currentCulture.Name;
            }
            node.Context.ExecuteQueryRetry();

            result.NavigationNodes.AddRange(from n in node.Children.AsEnumerable()
                                            select n.ToDomainModelNavigationNode(web, PersistLanguage, currentCulture, creationInfo, node.Id));

            if (PersistLanguage)
            {
                node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = acceptLanguage;
            }
            return(result);
        }
예제 #11
0
        private void ParseNodesMUI(MenuNode node, string webServerRelativeUrl, CultureInfo currentCulture, string parentKey, ProvisioningTemplateCreationInformation creationInfo)
        {
            UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{parentKey}_{node.Key}_Title", currentCulture.LCID, node.Title, creationInfo);

            if (node.Nodes.Count > 0)
            {
                foreach (var childNode in node.Nodes)
                {
                    ParseNodesMUI(childNode, webServerRelativeUrl, currentCulture, node.Key, creationInfo);
                }
            }
        }
예제 #12
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(WebSupportsExtractNavigation(web));
 }
예제 #13
0
        private static StructuralNavigation GetStructuralNavigation(Web web, WebNavigationSettings navigationSettings, Enums.NavigationType navigationType, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // By default avoid removing existing nodes
            var result = new StructuralNavigation {
                RemoveExistingNodes = false
            };

            Microsoft.SharePoint.Client.NavigationNodeCollection sourceNodes = navigationType == Enums.NavigationType.QuickLaunch ?
                                                                               web.Navigation.QuickLaunch : navigationType == Enums.NavigationType.TopNavigationBar ? web.Navigation.TopNavigationBar : web.LoadSearchNavigation();

            if (sourceNodes == null)
            {
                return(result);
            }

            var clientContext = web.Context;

            clientContext.Load(web, w => w.ServerRelativeUrl, w => w.Language);
            clientContext.Load(sourceNodes);
            clientContext.ExecuteQueryRetry();
            var defaultCulture = new CultureInfo((int)web.Language);

            if (!sourceNodes.ServerObjectIsNull.Value)
            {
                result.NavigationNodes.AddRange(from n in sourceNodes.AsEnumerable()
                                                select n.ToDomainModelNavigationNode(web, creationInfo.PersistMultiLanguageResources, defaultCulture, creationInfo));

                if (creationInfo.PersistMultiLanguageResources)
                {
                    //need to get nodes and children for any other then default language
                    foreach (var language in template.SupportedUILanguages.Where(c => c.LCID != defaultCulture.LCID))
                    {
                        var currentCulture = new CultureInfo(language.LCID);
                        clientContext.Load(web, w => w.ServerRelativeUrl);
                        clientContext.Load(sourceNodes);
                        var acceptLanguage = clientContext.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"];
                        clientContext.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = currentCulture.Name;
                        clientContext.ExecuteQueryRetry();

                        if (!sourceNodes.ServerObjectIsNull.Value)
                        {
                            //we dont need to add to result - just extract Titles - to List as we need to
                            var alternateLang = (from n in sourceNodes.AsEnumerable()
                                                 select n.ToDomainModelNavigationNode(web, creationInfo.PersistMultiLanguageResources, currentCulture, creationInfo)).ToList();
                        }

                        clientContext.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = acceptLanguage;
                    }
                }
            }
            return(result);
        }
예제 #14
0
        private ManagedNavigation GetManagedNavigation(Web web, WebNavigationSettings navigationSettings, Boolean currentNavigation, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            var result = new ManagedNavigation
            {
                TermStoreId = currentNavigation ? navigationSettings.CurrentNavigation.TermStoreId.ToString() : navigationSettings.GlobalNavigation.TermStoreId.ToString(),
                TermSetId   = currentNavigation ? navigationSettings.CurrentNavigation.TermSetId.ToString() : navigationSettings.GlobalNavigation.TermSetId.ToString(),
            };

            // Apply any token replacement for taxonomy IDs
            TokenizeManagedNavigationTaxonomyIds(web, result);

            return(result);
        }
예제 #15
0
        private void ExtractMasterPagesAndPageLayouts(Web web, ProvisioningTemplate template, PnPMonitoredScope scope, ProvisioningTemplateCreationInformation creationInfo)
        {
            web.EnsureProperty(w => w.Url);
            String webApplicationUrl = GetWebApplicationUrl(web.Url);

            if (!String.IsNullOrEmpty(webApplicationUrl))
            {
                // Get the Publishing Feature reference template
                ProvisioningTemplate publishingFeatureTemplate = GetPublishingFeatureBaseTemplate();

                // Get a reference to the root folder of the master page gallery
                var gallery = web.GetCatalog(116);
                web.Context.Load(gallery, g => g.RootFolder);
                web.Context.ExecuteQueryRetry();

                var masterPageGalleryFolder = gallery.RootFolder;

                // Load the files in the master page gallery
                web.Context.Load(masterPageGalleryFolder.Files);
                web.Context.ExecuteQueryRetry();


                var sourceFiles = GetFiles(masterPageGalleryFolder).Where(
                    f => f.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) ||
                    f.Name.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase) ||
                    f.Name.EndsWith(".master", StringComparison.InvariantCultureIgnoreCase));

                /*var sourceFiles = masterPageGalleryFolder.Files.AsEnumerable().Where(
                 *  f => f.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) ||
                 *  f.Name.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase) ||
                 *  f.Name.EndsWith(".master", StringComparison.InvariantCultureIgnoreCase));
                 */

                foreach (var file in sourceFiles)
                {
                    var listItem = file.EnsureProperty(f => f.ListItemAllFields);

                    if (!listItem.ServerObjectIsNull())
                    {
                        listItem.ContentType.EnsureProperties(ct => ct.Id, ct => ct.StringId);

                        // Check if the content type is of type Master Page or Page Layout
                        if (listItem.ContentType.StringId.StartsWith(MASTER_PAGE_CONTENT_TYPE_ID) ||
                            listItem.ContentType.StringId.StartsWith(PAGE_LAYOUT_CONTENT_TYPE_ID) ||
                            listItem.ContentType.StringId.StartsWith(ASP_NET_MASTER_PAGE_CONTENT_TYPE_ID) ||
                            listItem.ContentType.StringId.StartsWith(HTML_PAGE_LAYOUT_CONTENT_TYPE_ID))
                        {
                            // Skip any .ASPX or .MASTER file related to an .HTML designer file
                            if ((file.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) &&
                                 sourceFiles.Any(f => f.Name.Equals(file.Name.ToLower().Replace(".aspx", ".html"),
                                                                    StringComparison.InvariantCultureIgnoreCase))) ||
                                (file.Name.EndsWith(".master", StringComparison.InvariantCultureIgnoreCase) &&
                                 sourceFiles.Any(f => f.Name.Equals(file.Name.ToLower().Replace(".master", ".html"),
                                                                    StringComparison.InvariantCultureIgnoreCase))))
                            {
                                continue;
                            }

                            // If the file is a custom one, and not one native
                            // and coming out from the publishing feature
                            if (creationInfo.IncludeNativePublishingFiles ||
                                !IsPublishingFeatureNativeFile(publishingFeatureTemplate, file.Name))
                            {
                                var fullUri = new Uri(UrlUtility.Combine(webApplicationUrl, file.ServerRelativeUrl));

                                var folderPath = fullUri.Segments.Take(fullUri.Segments.Length - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/');
                                var fileName   = fullUri.Segments[fullUri.Segments.Length - 1];

                                web.EnsureProperty(w => web.ServerRelativeUrl);
                                file.EnsureProperty(f => f.Level);

                                var containerPath = folderPath.StartsWith(web.ServerRelativeUrl) && web.ServerRelativeUrl != "/" ? folderPath.Substring(web.ServerRelativeUrl.Length) : folderPath;
                                var container     = Uri.UnescapeDataString(containerPath).Trim('/').Replace("/", "\\");

                                var publishingFile = new Model.File()
                                {
                                    Folder    = Tokenize(folderPath, web.Url),
                                    Src       = !string.IsNullOrEmpty(container) ? $"{container}\\{Uri.UnescapeDataString(fileName)}" : Uri.UnescapeDataString(fileName),
                                    Overwrite = true,
                                    Level     = (Model.FileLevel)Enum.Parse(typeof(Model.FileLevel), file.Level.ToString())
                                };

                                // Add field values to file
                                RetrieveFieldValues(web, file, publishingFile);

                                // Add the file to the template
                                template.Files.Add(publishingFile);

                                // Persist file using connector, if needed
                                if (creationInfo.PersistPublishingFiles)
                                {
                                    PersistFile(web, creationInfo, scope, folderPath, fileName, true);
                                }

                                if (listItem.ContentType.StringId.StartsWith(MASTER_PAGE_CONTENT_TYPE_ID))
                                {
                                    scope.LogWarning($@"The file ""{file.Name}"" is a custom MasterPage. Accordingly to the PnP Guidance (http://aka.ms/o365pnpguidancemasterpages) you should try to avoid using custom MasterPages.");
                                }
                            }
                            else
                            {
                                scope.LogWarning($@"Skipping file ""{file.Name}"" because it is native in the publishing feature.");
                            }
                        }
                    }
                }
            }
        }
예제 #16
0
        private SiteFooterLink ParseNodes(MenuNode node, ProvisioningTemplate template, string webServerRelativeUrl, bool persistLanguage, CultureInfo currentCulture, string parentKey, ProvisioningTemplateCreationInformation creationInfo)
        {
            var link = new SiteFooterLink();

            if (persistLanguage)
            {
                if (UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{parentKey}_{node.Key}_Title", currentCulture.LCID, node.Title, creationInfo))
                {
                    link.DisplayName = $"{{res:FooterNavigationNode_{parentKey}_{node.Key}_Title}}";
                }
            }
            else
            {
                link.DisplayName = node.Title;
            }

            link.Url = Tokenize(node.SimpleUrl, webServerRelativeUrl);

            if (node.Nodes.Count > 0)
            {
                link.FooterLinks = new SiteFooterLinkCollection(template);
                foreach (var childNode in node.Nodes)
                {
                    link.FooterLinks.Add(ParseNodes(childNode, template, webServerRelativeUrl, persistLanguage, currentCulture, node.Key, creationInfo));
                }
            }
            return(link);
        }
        private ProvisioningTemplate DetectComposedLook(Web web, ProvisioningTemplate template,
                                                        ProvisioningTemplateCreationInformation creationInfo,
                                                        PnPMonitoredScope scope, SharePointConnector spConnector,
                                                        SharePointConnector spConnectorRoot)
        {
            var theme = web.GetCurrentComposedLook();

            if (theme != null)
            {
                if (creationInfo != null)
                {
                    // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any
                    creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl");
                }

                template.ComposedLook.Name =
                    theme.Name != null ? theme.Name : String.Empty;

                if (theme.IsCustomComposedLook)
                {
                    // Set the URL pointers to files
                    template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url));
                    template.ComposedLook.ColorFile      = FixFileUrl(Tokenize(theme.Theme, web.Url));
                    template.ComposedLook.FontFile       = FixFileUrl(Tokenize(theme.Font, web.Url));

                    // Download files if this is root site, since theme files are only stored there
                    if (!web.IsSubSite() && creationInfo != null &&
                        creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector);
                        // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment
                        // Download the theme/branding specific files
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope);
                    }

                    // Create file entries for the custom theme files, but only if it's a root site
                    // If it's root site we do not extract or set theme files, since those are in the root of the site collection
                    if (!web.IsSubSite())
                    {
                        if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.FontFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile));
                        }
                    }
                    // If a base template is specified then use that one to "cleanup" the generated template model
                    if (creationInfo != null && creationInfo.BaseTemplate != null)
                    {
                        template = CleanupEntities(template, creationInfo.BaseTemplate);
                    }
                }
                else
                {
                    template.ComposedLook.BackgroundFile = "";
                    template.ComposedLook.ColorFile      = "";
                    template.ComposedLook.FontFile       = "";
                }
            }
            else
            {
                template.ComposedLook = null;
            }

            return(template);
        }
예제 #18
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (new PnPMonitoredScope(this.Name))
            {
                web.EnsureProperties(w => w.HeaderEmphasis, w => w.HeaderLayout, w => w.MegaMenuEnabled);

                var header = new SiteHeader
                {
                    MenuStyle = web.MegaMenuEnabled ? SiteHeaderMenuStyle.MegaMenu : SiteHeaderMenuStyle.Cascading
                };

                switch (web.HeaderLayout)
                {
                case HeaderLayoutType.Compact:
                {
                    header.Layout = SiteHeaderLayout.Compact;
                    break;
                }

                case HeaderLayoutType.Minimal:
                {
                    header.Layout = SiteHeaderLayout.Minimal;
                    break;
                }

                case HeaderLayoutType.Extended:
                {
                    header.Layout = SiteHeaderLayout.Extended;
                    break;
                }

                default:
                {
                    header.Layout = SiteHeaderLayout.Standard;
                    break;
                }
                }

                if (Enum.TryParse(web.HeaderEmphasis.ToString(), out Emphasis backgroundEmphasis))
                {
                    header.BackgroundEmphasis = backgroundEmphasis;
                }

                template.Header = header;
            }

            return(template);
        }
예제 #19
0
        private ProvisioningTemplate GetFileContents(Web web, ProvisioningTemplate template, string welcomePageUrl, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope)
        {
            var homepageUrl = web.RootFolder.WelcomePage;

            if (string.IsNullOrEmpty(homepageUrl))
            {
                homepageUrl = "Default.aspx";
            }

            var fullUri = new Uri(UrlUtility.Combine(web.Url, homepageUrl));

            var folderPath = fullUri.Segments.Take(fullUri.Segments.Length - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/');
            var fileName   = fullUri.Segments[fullUri.Segments.Length - 1];

            var webParts = web.GetWebParts(welcomePageUrl);

            var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(welcomePageUrl));

            file.EnsureProperty(f => f.Level);

            var containerPath = folderPath.StartsWith(web.ServerRelativeUrl) && web.ServerRelativeUrl != "/"
                ? folderPath.Substring(web.ServerRelativeUrl.Length)
                : folderPath;
            var container = containerPath.Trim('/').Replace("%20", " ").Replace("/", "\\");

            var homeFile = new Model.File()
            {
                Folder    = Tokenize(folderPath, web.Url),
                Src       = !string.IsNullOrEmpty(container) ? $"{container}\\{fileName}" : fileName,
                Overwrite = true,
                Level     = (Model.FileLevel)Enum.Parse(typeof(Model.FileLevel), file.Level.ToString())
            };

            // 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, welcomePageUrl));

                Model.WebPart newWp = new Model.WebPart()
                {
                    Title    = webPart.WebPart.Title,
                    Row      = (uint)webPart.WebPart.ZoneIndex,
                    Order    = (uint)webPart.WebPart.ZoneIndex,
                    Contents = webPartxml,
                    Zone     = webPart.ZoneId
                };

                homeFile.WebParts.Add(newWp);
            }
            template.Files.Add(homeFile);

            // Persist file using connector
            if (creationInfo.PersistBrandingFiles)
            {
                PersistFile(web, creationInfo, scope, folderPath, fileName);
            }
            return(template);
        }
예제 #20
0
 public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     using (var scope = new PnPMonitoredScope(this.Name))
     {
         var context = web.Context as ClientContext;
         foreach (var handler in creationInfo.ExtensibilityHandlers)
         {
             if (handler.Enabled)
             {
                 try
                 {
                     scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, handler.Assembly);
                     template = _extManager.ExecuteExtensibilityExtractionCallOut(context, handler, template, creationInfo, scope);
                 }
                 catch (Exception ex)
                 {
                     scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace);
                     throw;
                 }
             }
         }
     }
     return(template);
 }
예제 #21
0
 public abstract bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo);
예제 #22
0
        private ProvisioningTemplate CleanupEntities(ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            ProvisioningTemplate baseTemplate = creationInfo.BaseTemplate;

            foreach (var propertyBagEntry in baseTemplate.PropertyBagEntries)
            {
                int index = template.PropertyBagEntries.FindIndex(f => f.Key.Equals(propertyBagEntry.Key));

                if (index > -1)
                {
                    template.PropertyBagEntries.RemoveAt(index);
                }
            }

            // Scan for "system" properties that should be removed as well. Below list contains
            // prefixes of properties that will be dropped
            List <string> systemPropertyBagEntriesExclusions = new List <string>(new string[]
            {
                "_",
                "vti_",
                "dlc_",
                "ecm_",
                "profileschemaversion",
                "DesignPreview"
            });

            // Below property prefixes indicate properties that never can be dropped
            List <string> systemPropertyBagEntriesInclusions = new List <string>(new string[]
            {
                "_PnP_"
            });

            systemPropertyBagEntriesInclusions.AddRange(creationInfo.PropertyBagPropertiesToPreserve);

            var entriesToDelete = new List <PropertyBagEntry>();

            // Prepare the list of property bag entries that will be dropped
            foreach (var property in systemPropertyBagEntriesExclusions)
            {
                var results = from prop in template.PropertyBagEntries
                              where prop.Key.StartsWith(property, StringComparison.OrdinalIgnoreCase)
                              select prop;
                entriesToDelete.AddRange(results);
            }

            // Remove the property bag entries that we want to forcifully keep
            foreach (var property in systemPropertyBagEntriesInclusions)
            {
                var results = from prop in entriesToDelete
                              where prop.Key.StartsWith(property, StringComparison.OrdinalIgnoreCase)
                              select prop;
                // Drop the found elements from the delete list
                entriesToDelete = new List <PropertyBagEntry>(SymmetricExcept <PropertyBagEntry>(results, entriesToDelete));
            }

            // Delete the resulting list of property bag entries
            foreach (var property in entriesToDelete)
            {
                template.PropertyBagEntries.Remove(property);
            }

            return(template);
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                // We extract the Image Renditions if and only if the Publishing feature is enabled
                if (web.IsFeatureActive(Constants.FeatureId_Web_Publishing))
                {
                    // This Object Handler will be invoked after the Publishing handler
                    // Thus, we should have the Publishing property assigned in the template
                    if (template.Publishing == null)
                    {
                        // And if not, we create it
                        template.Publishing = new Publishing();
                    }

                    var renditions = SiteImageRenditions.GetRenditions(context);
                    context.ExecuteQueryRetry();

                    foreach (var r in renditions)
                    {
                        template.Publishing.ImageRenditions.Add(new Model.ImageRendition
                        {
                            Name   = r.Name,
                            Height = r.Height,
                            Width  = r.Width,
                        });
                    }
                }
            }
            return(template);
        }
예제 #24
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.Context.Load(web, w => w.AllProperties, w => w.ServerRelativeUrl);
                web.Context.ExecuteQueryRetry();

                var entries = new List <PropertyBagEntry>();

                var indexedProperties = web.GetIndexedPropertyBagKeys().ToList();
                foreach (var propbagEntry in web.AllProperties.FieldValues)
                {
                    var indexed = indexedProperties.Contains(propbagEntry.Key);
                    entries.Add(new PropertyBagEntry()
                    {
                        Key = propbagEntry.Key, Value = propbagEntry.Value.ToString(), Indexed = indexed
                    });
                }

                template.PropertyBagEntries.Clear();
                template.PropertyBagEntries.AddRange(entries);

                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo);
                }

                foreach (PropertyBagEntry propbagEntry in template.PropertyBagEntries)
                {
                    propbagEntry.Value = Tokenize(propbagEntry.Value, web.ServerRelativeUrl);
                }
            }
            return(template);
        }
예제 #25
0
 public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     if (creationInfo.PersistMultiLanguageResources)
     {
         template = UserResourceExtensions.SaveResourceValues(template, creationInfo);
     }
     return(template);
 }
예제 #26
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (web.IsFeatureActive(Constants.FeatureId_Web_Publishing))
                {
                    web.EnsureProperty(w => w.Language);
                    var webTemplates = web.GetAvailableWebTemplates(web.Language, false);
                    web.Context.Load(webTemplates, wts => wts.Include(wt => wt.Name, wt => wt.Lcid));
                    web.Context.ExecuteQueryRetry();
                    Publishing publishing = new Publishing();
                    publishing.AvailableWebTemplates.AddRange(webTemplates.AsEnumerable <WebTemplate>().Select(wt => new AvailableWebTemplate()
                    {
                        TemplateName = wt.Name, LanguageCode = (int)wt.Lcid
                    }));
                    publishing.AutoCheckRequirements = AutoCheckRequirementsOptions.MakeCompliant;
                    publishing.DesignPackage         = null;
                    publishing.PageLayouts.AddRange(GetAvailablePageLayouts(web));
                    template.Publishing = publishing;

                    ExtractMasterPagesAndPageLayouts(web, template, scope, creationInfo);
                }
            }
            return(template);
        }
예제 #27
0
 public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(template);
 }
예제 #28
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(web.IsFeatureActive(Constants.FeatureId_Web_Publishing));
 }
예제 #29
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(true);
 }
예제 #30
0
 private ManagedNavigation GetCurrentManagedNavigation(Web web, WebNavigationSettings navigationSettings, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(GetManagedNavigation(web, navigationSettings, true, template, creationInfo));
 }