Пример #1
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);
        }
Пример #2
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);
                }
            }
        }
Пример #3
0
        private CustomAction CopyUserCustomAction(UserCustomAction userCustomAction, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template)
        {
            var customAction = new CustomAction();

            customAction.Description      = userCustomAction.Description;
            customAction.Enabled          = true;
            customAction.Group            = userCustomAction.Group;
            customAction.ImageUrl         = userCustomAction.ImageUrl;
            customAction.Location         = userCustomAction.Location;
            customAction.Name             = userCustomAction.Name;
            customAction.Rights           = userCustomAction.Rights;
            customAction.ScriptBlock      = userCustomAction.ScriptBlock;
            customAction.ScriptSrc        = userCustomAction.ScriptSrc;
            customAction.Sequence         = userCustomAction.Sequence;
            customAction.Title            = userCustomAction.Title;
            customAction.Url              = userCustomAction.Url;
            customAction.RegistrationId   = userCustomAction.RegistrationId;
            customAction.RegistrationType = userCustomAction.RegistrationType;

#if !ONPREMISES
            customAction.ClientSideComponentId         = userCustomAction.ClientSideComponentId;
            customAction.ClientSideComponentProperties = userCustomAction.ClientSideComponentProperties;
#endif

            customAction.CommandUIExtension = !System.String.IsNullOrEmpty(userCustomAction.CommandUIExtension) ?
                                              XElement.Parse(userCustomAction.CommandUIExtension) : null;

#if !ONPREMISES
            if (creationInfo.PersistMultiLanguageResources)
            {
                var resourceKey = userCustomAction.Name.Replace(" ", "_");

                if (UserResourceExtensions.PersistResourceValue(userCustomAction.TitleResource, $"CustomAction_{resourceKey}_Title", template, creationInfo))
                {
                    var customActionTitle = $"{{res:CustomAction_{resourceKey}_Title}}";
                    customAction.Title = customActionTitle;
                }
                if (UserResourceExtensions.PersistResourceValue(userCustomAction.DescriptionResource, $"CustomAction_{resourceKey}_Description", template, creationInfo))
                {
                    var customActionDescription = $"{{res:CustomAction_{resourceKey}_Description}}";
                    customAction.Description = customActionDescription;
                }
            }
#endif
            return(customAction);
        }
        private static CustomAction CopyUserCustomAction(UserCustomAction userCustomAction, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template)
        {
            var customAction = new CustomAction
            {
                Description                   = userCustomAction.Description,
                Enabled                       = true,
                Group                         = userCustomAction.Group,
                ImageUrl                      = userCustomAction.ImageUrl,
                Location                      = userCustomAction.Location,
                Name                          = userCustomAction.Name,
                Rights                        = userCustomAction.Rights,
                ScriptBlock                   = userCustomAction.ScriptBlock,
                ScriptSrc                     = userCustomAction.ScriptSrc,
                Sequence                      = userCustomAction.Sequence,
                Title                         = userCustomAction.Title,
                Url                           = userCustomAction.Url,
                RegistrationId                = userCustomAction.RegistrationId,
                RegistrationType              = userCustomAction.RegistrationType,
                ClientSideComponentId         = userCustomAction.ClientSideComponentId,
                ClientSideComponentProperties = userCustomAction.ClientSideComponentProperties,
                CommandUIExtension            = !System.String.IsNullOrEmpty(userCustomAction.CommandUIExtension) ?
                                                XElement.Parse(userCustomAction.CommandUIExtension) : null
            };


            if (creationInfo.PersistMultiLanguageResources)
            {
                var resourceKey = userCustomAction.Name.Replace(" ", "_");

                if (UserResourceExtensions.PersistResourceValue(userCustomAction.TitleResource, $"CustomAction_{resourceKey}_Title", template, creationInfo))
                {
                    var customActionTitle = $"{{res:CustomAction_{resourceKey}_Title}}";
                    customAction.Title = customActionTitle;
                }
                if (!string.IsNullOrWhiteSpace(userCustomAction.Description) && UserResourceExtensions.PersistResourceValue(userCustomAction.DescriptionResource, $"CustomAction_{resourceKey}_Description", template, creationInfo))
                {
                    var customActionDescription = $"{{res:CustomAction_{resourceKey}_Description}}";
                    customAction.Description = customActionDescription;
                }
            }

            return(customAction);
        }
Пример #5
0
        internal static Model.NavigationNode ToDomainModelNavigationNode(this Microsoft.SharePoint.Client.NavigationNode node, Web web, bool PersistLanguage, CultureInfo currentCulture, int ParentNodeId = 0)
        {
            string nodeTitle = node.Title;

#if !SP2013
            if (PersistLanguage && !string.IsNullOrWhiteSpace(nodeTitle))
            {
                if (UserResourceExtensions.PersistResourceValue($"NavigationNode_{ParentNodeId}_{node.Id}_Title", currentCulture.LCID, nodeTitle))
                {
                    nodeTitle = $"{{res:NavigationNode_{ParentNodeId}_{node.Id}_Title}}";
                }
            }
#endif
            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);
#if !SP2013
            var acceptLanguage = node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"];
            if (PersistLanguage)
            {
                node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = currentCulture.Name;
            }
#endif
            node.Context.ExecuteQueryRetry();

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

#if !SP2013
            if (PersistLanguage)
            {
                node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = acceptLanguage;
            }
#endif
            return(result);
        }
Пример #6
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating field entities.
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns);
                    return(template);
                }

                var existingFields = web.Fields;
                web.Context.Load(web, w => w.ServerRelativeUrl);
                web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title));
                web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title));
                web.Context.ExecuteQueryRetry();

                var taxTextFieldsToMoveUp      = new List <Guid>();
                var calculatedFieldsToMoveDown = new List <Guid>();

                var currentFieldIndex    = 0;
                var fieldsToProcessCount = existingFields.Count;
                foreach (var field in existingFields)
                {
                    currentFieldIndex++;
                    WriteMessage($"Field|{field.InternalName}|{currentFieldIndex}|{fieldsToProcessCount}", ProvisioningMessageType.Progress);
                    if (!BuiltInFieldId.Contains(field.Id))
                    {
                        var      fieldXml = field.SchemaXml;
                        XElement element  = XElement.Parse(fieldXml);

                        // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths
                        var listIdentifier = element.Attribute("List") != null?element.Attribute("List").Value : null;

                        if (!string.IsNullOrEmpty(listIdentifier))
                        {
                            //var listGuid = Guid.Empty;
                            fieldXml = ParseFieldSchema(fieldXml, web.Lists);
                            element  = XElement.Parse(fieldXml);
                            //if (Guid.TryParse(listIdentifier, out listGuid))
                            //{
                            //    fieldXml = ParseListSchema(fieldXml, web.Lists);
                            //if (newfieldXml == fieldXml)
                            //{
                            //    var list = web.Lists.GetById(listGuid);
                            //    web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl);
                            //    web.Context.ExecuteQueryRetry();

                            //    var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/');
                            //    element.Attribute("List").SetValue(listUrl);
                            //    fieldXml = element.ToString();
                            //}
                            //}
                        }

                        // Check if the field is of type TaxonomyField
                        if (field.TypeAsString.StartsWith("TaxonomyField"))
                        {
                            var taxField = (TaxonomyField)field;
                            web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id);
                            web.Context.ExecuteQueryRetry();
                            taxTextFieldsToMoveUp.Add(taxField.TextField);

                            fieldXml = TokenizeTaxonomyField(web, element);
                        }

                        // Check if we have version attribute. Remove if exists
                        if (element.Attribute("Version") != null)
                        {
                            element.Attributes("Version").Remove();
                            fieldXml = element.ToString();
                        }
                        if (element.Attribute("Type").Value == "Calculated")
                        {
                            fieldXml = TokenizeFieldFormula(web.Fields, (FieldCalculated)field, fieldXml);
                            calculatedFieldsToMoveDown.Add(field.Id);
                        }
                        if (creationInfo.PersistMultiLanguageResources)
                        {
#if !SP2013
                            // only persist language values for fields we actually will keep...no point in spending time on this is we clean the field afterwards
                            bool persistLanguages = true;
                            if (creationInfo.BaseTemplate != null)
                            {
                                int index = creationInfo.BaseTemplate.SiteFields.FindIndex(f => Guid.Parse(XElement.Parse(f.SchemaXml).Attribute("ID").Value).Equals(field.Id));

                                if (index > -1)
                                {
                                    persistLanguages = false;
                                }
                            }

                            if (persistLanguages)
                            {
                                var fieldElement      = XElement.Parse(fieldXml);
                                var escapedFieldTitle = field.Title.Replace(" ", "_");
                                if (UserResourceExtensions.PersistResourceValue(field.TitleResource, $"Field_{escapedFieldTitle}_DisplayName", template, creationInfo))
                                {
                                    var fieldTitle = $"{{res:Field_{escapedFieldTitle}_DisplayName}}";
                                    fieldElement.SetAttributeValue("DisplayName", fieldTitle);
                                }
                                if (UserResourceExtensions.PersistResourceValue(field.DescriptionResource, $"Field_{escapedFieldTitle}_Description", template, creationInfo))
                                {
                                    var fieldDescription = $"{{res:Field_{escapedFieldTitle}_Description}}";
                                    fieldElement.SetAttributeValue("Description", fieldDescription);
                                }

                                fieldXml = fieldElement.ToString();
                            }
#endif
                        }

                        template.SiteFields.Add(new Field()
                        {
                            SchemaXml = fieldXml
                        });
                    }
                }
                // move hidden taxonomy text fields to the top of the list
                foreach (var textFieldId in taxTextFieldsToMoveUp)
                {
                    var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.Insert(0, field);
                }
                // move calculated fields to the bottom of the list
                // this will not be sufficient in the case of a calculated field is referencing another calculated field
                foreach (var calculatedFieldId in calculatedFieldsToMoveDown)
                {
                    var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(calculatedFieldId));
                    template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(calculatedFieldId));
                    template.SiteFields.Add(field);
                }
                // 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);
                }
            }
            WriteMessage($"Done processing fields", ProvisioningMessageType.Completed);

            return(template);
        }
Пример #7
0
        private IEnumerable <ContentType> GetEntities(Web web, PnPMonitoredScope scope, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template)
        {
            var cts = web.ContentTypes;

            web.Context.Load(cts, ctCollection => ctCollection.IncludeWithDefaultProperties(ct => ct.FieldLinks));
            web.Context.ExecuteQueryRetry();

            if (cts.Count > 0 && web.IsSubSite())
            {
                WriteMessage("We discovered content types in this subweb. While technically possible, we recommend moving these content types to the root site collection. Consider excluding them from this template.", ProvisioningMessageType.Warning);
            }
            List <ContentType> ctsToReturn = new List <ContentType>();
            var currentCtIndex             = 0;

            foreach (var ct in cts)
            {
                currentCtIndex++;
                WriteMessage($"Content Type|{ct.Name}|{currentCtIndex}|{cts.Count()}", ProvisioningMessageType.Progress);

                if (!BuiltInContentTypeId.Contains(ct.StringId) &&
                    (creationInfo.ContentTypeGroupsToInclude.Count == 0 || creationInfo.ContentTypeGroupsToInclude.Contains(ct.Group)))
                {
                    string ctDocumentTemplate = null;
                    if (!string.IsNullOrEmpty(ct.DocumentTemplate))
                    {
                        if (!ct.DocumentTemplate.StartsWith("_cts/"))
                        {
                            ctDocumentTemplate = ct.DocumentTemplate;
                        }
                    }

                    var newCT = new ContentType(
                        ct.StringId,
                        ct.Name,
                        ct.Description,
                        ct.Group,
                        ct.Sealed,
                        ct.Hidden,
                        ct.ReadOnly,
                        ctDocumentTemplate,
                        false,
                        (from fieldLink in ct.FieldLinks.AsEnumerable <FieldLink>()
                         select new FieldRef(fieldLink.Name)
                    {
                        Id = fieldLink.Id,
                        Hidden = fieldLink.Hidden,
                        Required = fieldLink.Required,
                    })
                        )
                    {
                        DisplayFormUrl = ct.DisplayFormUrl,
                        EditFormUrl    = ct.EditFormUrl,
                        NewFormUrl     = ct.NewFormUrl,
                    };

                    if (creationInfo.PersistMultiLanguageResources)
                    {
#if !SP2013
                        // only persist language values for content types we actually will keep...no point in spending time on this is we clean the field afterwards
                        var persistLanguages = true;
                        if (creationInfo.BaseTemplate != null)
                        {
                            int index = creationInfo.BaseTemplate.ContentTypes.FindIndex(c => c.Id.Equals(ct.StringId));

                            if (index > -1)
                            {
                                persistLanguages = false;
                            }
                        }

                        if (persistLanguages)
                        {
                            var escapedCTName = ct.Name.Replace(" ", "_");
                            if (UserResourceExtensions.PersistResourceValue(ct.NameResource, $"ContentType_{escapedCTName}_Title", template, creationInfo))
                            {
                                newCT.Name = $"{{res:ContentType_{escapedCTName}_Title}}";
                            }
                            if (UserResourceExtensions.PersistResourceValue(ct.DescriptionResource, $"ContentType_{escapedCTName}_Description", template, creationInfo))
                            {
                                newCT.Description = $"{{res:ContentType_{escapedCTName}_Description}}";
                            }
                        }
#endif
                    }

                    // If the Content Type is a DocumentSet
                    if (Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.IsChildOfDocumentSetContentType(web.Context, ct).Value ||
                        ct.StringId.StartsWith(BuiltInContentTypeId.DocumentSet)) // TODO: This is kind of an hack... we should find a better solution ...
                    {
                        Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate =
                            Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, ct);

                        // Retrieve the Document Set
                        web.Context.Load(documentSetTemplate,
                                         t => t.AllowedContentTypes,
                                         t => t.DefaultDocuments,
                                         t => t.SharedFields,
                                         t => t.WelcomePageFields);
                        web.Context.ExecuteQueryRetry();

                        newCT.DocumentSetTemplate = new DocumentSetTemplate(
                            null, // TODO: WelcomePage not yet supported
                            (from allowedCT in documentSetTemplate.AllowedContentTypes.AsEnumerable()
                             select allowedCT.StringValue).ToArray(),
                            (from defaultDocument in documentSetTemplate.DefaultDocuments.AsEnumerable()
                             select new DefaultDocument
                        {
                            ContentTypeId = defaultDocument.ContentTypeId.StringValue,
                            Name = defaultDocument.Name,
                            FileSourcePath = String.Empty,      // TODO: How can we extract the proper file?!
                        }).ToArray(),
                            (from sharedField in documentSetTemplate.SharedFields.AsEnumerable()
                             select sharedField.Id).ToArray(),
                            (from welcomePageField in documentSetTemplate.WelcomePageFields.AsEnumerable()
                             select welcomePageField.Id).ToArray()
                            );
                    }

                    ctsToReturn.Add(newCT);
                }
            }
            WriteMessage("Done processing Content Types", ProvisioningMessageType.Completed);
            return(ctsToReturn);
        }
Пример #8
0
        private IEnumerable <ContentType> GetEntities(Web web, PnPMonitoredScope scope, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template)
        {
            var cts = web.ContentTypes;

            web.Context.Load(cts, ctCollection => ctCollection.IncludeWithDefaultProperties(ct => ct.FieldLinks));
            web.Context.ExecuteQueryRetry();

            List <ContentType> ctsToReturn = new List <ContentType>();

            foreach (var ct in cts)
            {
                if (!BuiltInContentTypeId.Contains(ct.StringId))
                {
                    ContentType newCT = new ContentType
                                            (ct.StringId,
                                            ct.Name,
                                            ct.Description,
                                            ct.Group,
                                            ct.Sealed,
                                            ct.Hidden,
                                            ct.ReadOnly,
                                            ct.DocumentTemplate,
                                            false,
                                            (from fieldLink in ct.FieldLinks.AsEnumerable <FieldLink>()
                                             select new FieldRef(fieldLink.Name)
                    {
                        Id = fieldLink.Id,
                        Hidden = fieldLink.Hidden,
                        Required = fieldLink.Required,
                    })
                                            )
                    {
                        DisplayFormUrl = ct.DisplayFormUrl,
                        EditFormUrl    = ct.EditFormUrl,
                        NewFormUrl     = ct.NewFormUrl,
                    };

                    if (creationInfo.PersistMultiLanguageResources)
                    {
#if !SP2013
                        if (UserResourceExtensions.PersistResourceValue(ct.NameResource, string.Format("ContentType_{0}_Title", ct.Name.Replace(" ", "_")), template, creationInfo))
                        {
                            newCT.Name = string.Format("{{res:ContentType_{0}_Title}}", ct.Name.Replace(" ", "_"));
                        }
                        if (UserResourceExtensions.PersistResourceValue(ct.DescriptionResource, string.Format("ContentType_{0}_Description", ct.Name.Replace(" ", "_")), template, creationInfo))
                        {
                            newCT.Description = string.Format("{{res:ContentType_{0}_Description}}", ct.Name.Replace(" ", "_"));
                        }
#endif
                    }

                    // If the Content Type is a DocumentSet
                    if (Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.IsChildOfDocumentSetContentType(web.Context, ct).Value ||
                        ct.StringId.StartsWith(BuiltInContentTypeId.DocumentSet)) // TODO: This is kind of an hack... we should find a better solution ...
                    {
                        Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate =
                            Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, ct);

                        // Retrieve the Document Set
                        web.Context.Load(documentSetTemplate,
                                         t => t.AllowedContentTypes,
                                         t => t.DefaultDocuments,
                                         t => t.SharedFields,
                                         t => t.WelcomePageFields);
                        web.Context.ExecuteQueryRetry();

                        newCT.DocumentSetTemplate = new DocumentSetTemplate(
                            null, // TODO: WelcomePage not yet supported
                            (from allowedCT in documentSetTemplate.AllowedContentTypes.AsEnumerable()
                             select allowedCT.StringValue).ToArray(),
                            (from defaultDocument in documentSetTemplate.DefaultDocuments.AsEnumerable()
                             select new DefaultDocument
                        {
                            ContentTypeId = defaultDocument.ContentTypeId.StringValue,
                            Name = defaultDocument.Name,
                            FileSourcePath = String.Empty,      // TODO: How can we extract the proper file?!
                        }).ToArray(),
                            (from sharedField in documentSetTemplate.SharedFields.AsEnumerable()
                             select sharedField.Id).ToArray(),
                            (from welcomePageField in documentSetTemplate.WelcomePageFields.AsEnumerable()
                             select welcomePageField.Id).ToArray()
                            );
                    }

                    ctsToReturn.Add(newCT);
                }
            }
            return(ctsToReturn);
        }
Пример #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
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating field entities.
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns);
                    return(template);
                }

                var existingFields = web.Fields;
                web.Context.Load(web, w => w.ServerRelativeUrl);
                web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title));
                web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title));
                web.Context.ExecuteQueryRetry();

                var taxTextFieldsToMoveUp = new List <Guid>();

                foreach (var field in existingFields)
                {
                    if (!BuiltInFieldId.Contains(field.Id))
                    {
                        var      fieldXml = field.SchemaXml;
                        XElement element  = XElement.Parse(fieldXml);

                        // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths
                        var listIdentifier = element.Attribute("List") != null?element.Attribute("List").Value : null;

                        if (!string.IsNullOrEmpty(listIdentifier))
                        {
                            var listGuid = Guid.Empty;
                            fieldXml = ParseFieldSchema(fieldXml, web.Lists);
                            element  = XElement.Parse(fieldXml);
                            //if (Guid.TryParse(listIdentifier, out listGuid))
                            //{
                            //    fieldXml = ParseListSchema(fieldXml, web.Lists);
                            //if (newfieldXml == fieldXml)
                            //{
                            //    var list = web.Lists.GetById(listGuid);
                            //    web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl);
                            //    web.Context.ExecuteQueryRetry();

                            //    var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/');
                            //    element.Attribute("List").SetValue(listUrl);
                            //    fieldXml = element.ToString();
                            //}
                            //}
                        }

                        // Check if the field is of type TaxonomyField
                        if (field.TypeAsString.StartsWith("TaxonomyField"))
                        {
                            var taxField = (TaxonomyField)field;
                            web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id);
                            web.Context.ExecuteQueryRetry();
                            taxTextFieldsToMoveUp.Add(taxField.TextField);

                            fieldXml = TokenizeTaxonomyField(web, element);
                        }

                        // Check if we have version attribute. Remove if exists
                        if (element.Attribute("Version") != null)
                        {
                            element.Attributes("Version").Remove();
                            fieldXml = element.ToString();
                        }
                        if (element.Attribute("Type").Value == "Calculated")
                        {
                            fieldXml = TokenizeFieldFormula(fieldXml);
                        }
                        if (creationInfo.PersistMultiLanguageResources)
                        {
#if !SP2013
                            var fieldElement = XElement.Parse(fieldXml);
                            if (UserResourceExtensions.PersistResourceValue(field.TitleResource, string.Format("Field_{0}_DisplayName", field.Title.Replace(" ", "_")), template, creationInfo))
                            {
                                var fieldTitle = string.Format("{{res:Field_{0}_DisplayName}}", field.Title.Replace(" ", "_"));
                                fieldElement.SetAttributeValue("DisplayName", fieldTitle);
                            }
                            if (UserResourceExtensions.PersistResourceValue(field.DescriptionResource, string.Format("Field_{0}_Description", field.Title.Replace(" ", "_")), template, creationInfo))
                            {
                                var fieldDescription = string.Format("{{res:Field_{0}_Description}}", field.Title.Replace(" ", "_"));
                                fieldElement.SetAttributeValue("Description", fieldDescription);
                            }

                            fieldXml = fieldElement.ToString();
#endif
                        }

                        template.SiteFields.Add(new Field()
                        {
                            SchemaXml = fieldXml
                        });
                    }
                }
                // move hidden taxonomy text fields to the top of the list
                foreach (var textFieldId in taxTextFieldsToMoveUp)
                {
                    var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.Insert(0, field);
                }
                // 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);
        }