예제 #1
0
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            var context = web.Context as ClientContext;
            bool isSubSite = web.IsSubSite();
            var webCustomActions = web.GetCustomActions();
            var siteCustomActions = context.Site.GetCustomActions();

            var customActions = new CustomActions();
            foreach (var customAction in webCustomActions)
            {
                customActions.WebCustomActions.Add(CopyUserCustomAction(customAction));
            }
            
            // if this is a sub site then we're not creating entities for site collection scoped custom actions
            if (!isSubSite)
            {
                foreach (var customAction in siteCustomActions)
                {
                    customActions.SiteCustomActions.Add(CopyUserCustomAction(customAction));
                }
            }

            template.CustomActions = customActions;

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

            return template;
        }
예제 #2
0
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // if this is a sub site then we're not creating field entities.
            if (web.IsSubSite())
            {
                return template;
            }

            var existingFields = web.Fields;
            web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml));
            web.Context.ExecuteQueryRetry();


            foreach (var field in existingFields)
            {
                if (!BuiltInFieldId.Contains(field.Id))
                {
                    template.SiteFields.Add(new Field() { SchemaXml = field.SchemaXml });
                }
            }
            // 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;
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {

                web.Context.Load(web.RegionalSettings);
                web.Context.Load(web.RegionalSettings.TimeZone, tz => tz.Id);
                web.Context.ExecuteQueryRetry();

                Model.RegionalSettings settings = new Model.RegionalSettings();

                settings.AdjustHijriDays = web.RegionalSettings.AdjustHijriDays;
                settings.AlternateCalendarType = (CalendarType)web.RegionalSettings.AlternateCalendarType;
                settings.CalendarType = (CalendarType)web.RegionalSettings.CalendarType;
                settings.Collation = web.RegionalSettings.Collation;
                settings.FirstDayOfWeek = (DayOfWeek)web.RegionalSettings.FirstDayOfWeek;
                settings.FirstWeekOfYear = web.RegionalSettings.FirstWeekOfYear;
                settings.LocaleId = (int)web.RegionalSettings.LocaleId;
                settings.ShowWeeks = web.RegionalSettings.ShowWeeks;
                settings.Time24 = web.RegionalSettings.Time24;
                settings.TimeZone = web.RegionalSettings.TimeZone.Id;
                settings.WorkDayEndHour = (WorkHour)web.RegionalSettings.WorkDayEndHour;
                settings.WorkDays = web.RegionalSettings.WorkDays;
                settings.WorkDayStartHour = (WorkHour)web.RegionalSettings.WorkDayStartHour;

                template.RegionalSettings = settings;

                // We're not comparing regional settings with the value stored in the base template as base templates are always for the US locale (1033)
            }
            return template;
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var site = (web.Context as ClientContext).Site;
                try
                {
                    var siteSearchSettings = site.GetSearchConfiguration();

                    if (!String.IsNullOrEmpty(siteSearchSettings))
                    {
                        template.SiteSearchSettings = siteSearchSettings;
                    }

                    var webSearchSettings = web.GetSearchConfiguration();

                    if (!String.IsNullOrEmpty(webSearchSettings))
                    {
                        template.WebSearchSettings = webSearchSettings;
                    }
                }
                catch (ServerException)
                {
                    // The search service is not necessarily configured
                    // Swallow the exception
                }
            }
            return template;
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {

                web.Context.Load(web.RegionalSettings);
                web.Context.Load(web.RegionalSettings.TimeZone, tz => tz.Id);
                web.Context.ExecuteQueryRetry();

                Model.RegionalSettings settings = new Model.RegionalSettings();

                settings.AdjustHijriDays = web.RegionalSettings.AdjustHijriDays;
                settings.AlternateCalendarType = (CalendarType)web.RegionalSettings.AlternateCalendarType;
                settings.Collation = web.RegionalSettings.Collation;
                settings.FirstDayOfWeek = (DayOfWeek)web.RegionalSettings.FirstDayOfWeek;
                settings.FirstWeekOfYear = web.RegionalSettings.FirstWeekOfYear;
                settings.LocaleId = (int)web.RegionalSettings.LocaleId;
                settings.ShowWeeks = web.RegionalSettings.ShowWeeks;
                settings.Time24 = web.RegionalSettings.Time24;
                settings.TimeZone = web.RegionalSettings.TimeZone.Id;
                settings.WorkDayEndHour = (WorkHour)web.RegionalSettings.WorkDayEndHour;
                settings.WorkDays = web.RegionalSettings.WorkDays;
                settings.WorkDayStartHour = (WorkHour)web.RegionalSettings.WorkDayStartHour;

                template.RegionalSettings = settings;

                // 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;
        }
        internal void PersistFile(Web web, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string folderPath, string fileName, Boolean decodeFileName = false)
        {
            if (creationInfo.FileConnector != null)
            {
                SharePointConnector connector = new SharePointConnector(web.Context, web.Url, "dummy");

                Uri u = new Uri(web.Url);
                if (folderPath.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1)
                {
                    folderPath = folderPath.Replace(u.PathAndQuery, "");
                }

                using (Stream s = connector.GetFileStream(fileName, folderPath))
                {
                    if (s != null)
                    {
                        creationInfo.FileConnector.SaveFileStream(decodeFileName ? HttpUtility.UrlDecode(fileName) : fileName, s);
                    }
                }
            }
            else
            {
                WriteWarning("No connector present to persist homepage.", ProvisioningMessageType.Error);
                scope.LogError("No connector present to persist homepage");
            }
        }
예제 #7
0
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // if this is a sub site then we're not creating content type entities. 
            if (web.IsSubSite())
            {
                return template;
            }

            var cts = web.ContentTypes;
            web.Context.Load(cts);
            web.Context.ExecuteQueryRetry();

            foreach (var ct in cts)
            {
                if (!BuiltInContentTypeId.Contains(ct.StringId))
                {
                    template.ContentTypes.Add(new ContentType() { SchemaXml = ct.SchemaXml });
                }
            }

            // 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
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {

            // if this is a sub site then we're not creating security entities as by default security is inherited from the root site
            if (web.IsSubSite())
            {
                return template;
            }

            var ownerGroup = web.AssociatedOwnerGroup;
            var memberGroup = web.AssociatedMemberGroup;
            var visitorGroup = web.AssociatedVisitorGroup;

            web.Context.Load(ownerGroup, o => o.Users);
            web.Context.Load(memberGroup, o => o.Users);
            web.Context.Load(visitorGroup, o => o.Users);

            web.Context.ExecuteQueryRetry();

            var owners = ownerGroup.IsObjectPropertyInstantiated("Users") ? 
                ownerGroup.Users.AsEnumerable().Select(u => new User(){ Name = u.LoginName}).ToList() : 
                new List<User>();

            var members = memberGroup.IsObjectPropertyInstantiated("Users") ?
                memberGroup.Users.AsEnumerable().Select(u => new User() { Name = u.LoginName }).ToList() : 
                new List<User>();

            var visitors = visitorGroup.IsObjectPropertyInstantiated("Users") ?
                visitorGroup.Users.AsEnumerable().Select(u => new User() { Name = u.LoginName }).ToList() : 
                new List<User>();

            var siteSecurity = new SiteSecurity();
            siteSecurity.AdditionalOwners.AddRange(owners);
            siteSecurity.AdditionalMembers.AddRange(members);
            siteSecurity.AdditionalVisitors.AddRange(visitors);

            var allUsers = web.SiteUsers;
            web.Context.Load(allUsers, users => users.Include(u => u.LoginName, u => u.IsSiteAdmin));
            web.Context.ExecuteQueryRetry();

            var admins = new List<User>();
            foreach (var member in allUsers)
            {
                if (member.IsSiteAdmin)
                {
                    admins.Add(new User() {Name = member.LoginName});
                }
            }
            siteSecurity.AdditionalAdministrators.AddRange(admins);

            template.Security = siteSecurity;

            // 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;
        }
예제 #9
0
        /// <summary>
        /// Actual implementation of extracting configuration from existing site.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="creationInfo"></param>
        /// <returns></returns>
        internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo)
        {
            Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_StartExtraction);
            
            ProvisioningProgressDelegate progressDelegate = null;
            
            if (creationInfo != null)
            {
                progressDelegate = creationInfo.ProgressDelegate;
            }

            // Create empty object
            ProvisioningTemplate template = new ProvisioningTemplate();

            // Hookup connector, is handy when the generated template object is used to apply to another site
            template.Connector = creationInfo.FileConnector;

            List<ObjectHandlerBase> objectHandlers = new List<ObjectHandlerBase>();

            Debugger.Break();

            objectHandlers.Add(new ObjectSitePolicy());
            objectHandlers.Add(new ObjectSiteSecurity());
            objectHandlers.Add(new ObjectTermGroups());
            objectHandlers.Add(new ObjectField());
            objectHandlers.Add(new ObjectContentType());
            objectHandlers.Add(new ObjectListInstance());
            objectHandlers.Add(new ObjectCustomActions());
            objectHandlers.Add(new ObjectFeatures());
            objectHandlers.Add(new ObjectComposedLook());
            objectHandlers.Add(new ObjectFiles());
            objectHandlers.Add(new ObjectPages());
            objectHandlers.Add(new ObjectPublishingPageLayouts());
            objectHandlers.Add(new ObjectPublishingPages());
            objectHandlers.Add(new ObjectPropertyBagEntry());
            objectHandlers.Add(new ObjectRetrieveTemplateInfo());

            objectHandlers.Add(new ObjectExtensibilityProviders());
            objectHandlers.Add(new ObjectPersistTemplateInfo());

            int step = 1;

            var count = objectHandlers.Count(o => o.ReportProgress && o.WillExtract(web,template,creationInfo));

            foreach (var handler in objectHandlers)
            {
                if (handler.WillExtract(web, template, creationInfo))
                {
                    if (handler.ReportProgress && progressDelegate != null)
                    {
                        progressDelegate(handler.Name, step, count);
                        step++;
                    }
                    template = handler.CreateEntities(web, template, creationInfo);
                }
            }
            Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_FinishExtraction);
            return template;
        }
예제 #10
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     if (!_willExtract.HasValue)
     {
         _willExtract = false;
     }
     return _willExtract.Value;
 }
예제 #11
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var lists = this.GetListsWithPages(template);
                template.Pages = new PageCollection(template);

                var homePageUrl = web.GetHomePageRelativeUrl();
                foreach (var list in lists)
                {
                    try
                    {
                        List splist = web.Lists.GetById(list.ID);
                        web.Context.Load(splist);
                        web.Context.ExecuteQueryRetry();
                        if (!creationInfo.ExecutePreProvisionEvent<ListInstance, List>(Handlers.Pages, template, list, null))
                        {
                            continue;
                        }

                        var listItems = GetListPages(web, splist);
                        var fileItems = listItems.AsEnumerable().Where(x => x.IsFile());
                        foreach (ListItem item in fileItems)
                        {
                            try
                            {
                                IPageModelProvider provider = GetProvider(item, homePageUrl, web, parser);
                                if (null != provider)
                                {
                                    provider.AddPage(item, template);
                                }
                            }
                            catch (Exception ex)
                            {
                                var message = string.Format("Error in export page for list: {0}", list.ServerRelativeUrl);
                                scope.LogError(ex, message);
                            }
                        }

                        creationInfo.ExecutePostProvisionEvent<ListInstance, List>(Handlers.Pages, template, list, splist);
                    }
                    catch (Exception exception)
                    {
                        var message = string.Format("Error in export publishing page for list: {0}", list.ServerRelativeUrl);
                        scope.LogError(exception, message);
                    }
                }
                // Impossible to return all files in the site currently

                // 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;
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            if (creationInfo.PersistMultiLanguageResources)
            {
#if !SP2013
                template = UserResourceExtensions.SaveResourceValues(template, creationInfo);
#endif
            }
            return template;
        }
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // 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;
        }
예제 #14
0
        public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            if (!_willExtract.HasValue)
            {
                var sitePolicyEntity = web.GetAppliedSitePolicy();

                _willExtract = sitePolicyEntity != null;
            }
            return _willExtract.Value;
        }
예제 #15
0
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // if this is a sub site then we're not creating field entities.
            if (web.IsSubSite())
            {
                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));
            web.Context.ExecuteQueryRetry();


            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;
                        if (Guid.TryParse(listIdentifier, out listGuid))
                        {
                            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 we have version attribute. Remove if exists 
                    if (element.Attribute("Version") != null)
                    {
                        element.Attributes("Version").Remove();
                        fieldXml = element.ToString();
                    }
                    template.SiteFields.Add(new Field() { SchemaXml = fieldXml });
                }
            }
            // 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;
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Set default values for Template ID and Version
                template.Id = String.Format("TEMPLATE-{0:N}", Guid.NewGuid()).ToUpper();
                template.Version = 1;

                template.BaseSiteTemplate = web.GetBaseTemplateId();

                // Retrieve original Template ID and remove it from Property Bag Entries
                int provisioningTemplateIdIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateId"));
                if (provisioningTemplateIdIndex > -1)
                {
                    var templateId = template.PropertyBagEntries[provisioningTemplateIdIndex].Value;
                    if (!String.IsNullOrEmpty(templateId))
                    {
                        template.Id = templateId;
                    }
                    template.PropertyBagEntries.RemoveAt(provisioningTemplateIdIndex);
                }

                // Retrieve original Template Info and remove it from Property Bag Entries
                int provisioningTemplateInfoIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateInfo"));
                if (provisioningTemplateInfoIndex > -1)
                {
                    var jsonInfo = template.PropertyBagEntries[provisioningTemplateInfoIndex].Value;

                    if (jsonInfo != null)
                    {
                        ProvisioningTemplateInfo info = JsonConvert.DeserializeObject<ProvisioningTemplateInfo>(jsonInfo);

                        // Override any previously defined Template ID, Version, and SitePolicy
                        // with the one stored in the Template Info, if any
                        if (info != null)
                        {
                            if (!String.IsNullOrEmpty(info.TemplateId))
                            {
                                template.Id = info.TemplateId;
                            }
                            if (!String.IsNullOrEmpty(info.TemplateSitePolicy))
                            {
                                template.SitePolicy = info.TemplateSitePolicy;
                            }
                            if (info.TemplateVersion > 0)
                            {
                                template.Version = info.TemplateVersion;
                            }
                        }
                    }
                    template.PropertyBagEntries.RemoveAt(provisioningTemplateInfoIndex);
                }
            }
            return template;
        }
예제 #17
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {

            var sitePolicyEntity = web.GetAppliedSitePolicy();

            if (sitePolicyEntity != null)
            {
                template.SitePolicy = sitePolicyEntity.Name;
            }
            return template;
        }
예제 #18
0
        private void DumpTemplate(ClientContext ctx, string template, string subSiteTemplate = "", string saveAsTemplate = "")
        {
            Uri devSiteUrl = new Uri(ConfigurationManager.AppSettings["SPODevSiteUrl"]);
            string baseUrl = String.Format("{0}://{1}", devSiteUrl.Scheme, devSiteUrl.DnsSafeHost);

            string siteUrl = "";
            if (subSiteTemplate.Length > 0)
            {
                siteUrl = (String.Format("{1}/sites/template{0}/template{2}", template, baseUrl, subSiteTemplate));
            }
            else
            {
                siteUrl = (String.Format("{1}/sites/template{0}", template, baseUrl));
            }

            using (ClientContext cc = ctx.Clone(siteUrl))
            {
                // Specify null as base template since we do want "everything" in this case
                ProvisioningTemplateCreationInformation creationInfo = new ProvisioningTemplateCreationInformation(cc.Web);
                creationInfo.BaseTemplate = null;

                // Override the save name. Case is online site collection provisioned using blankinternetcontainer#0 which returns
                // blankinternet#0 as web template using CSOM/SSOM API
                if (saveAsTemplate.Length > 0)
                {
                    template = saveAsTemplate;
                }

                ProvisioningTemplate p = cc.Web.GetProvisioningTemplate(creationInfo);
                if (subSiteTemplate.Length > 0)
                {
                    p.Id = String.Format("{0}template", subSiteTemplate);
                }
                else
                {
                    p.Id = String.Format("{0}template", template);
                }

                // Cleanup before saving
                p.Security.AdditionalAdministrators.Clear();


                XMLFileSystemTemplateProvider provider = new XMLFileSystemTemplateProvider(".", "");
                if (subSiteTemplate.Length > 0)
                {
                    provider.SaveAs(p, String.Format("{0}Template.xml", subSiteTemplate));
                }
                else
                {
                    provider.SaveAs(p, String.Format("{0}Template.xml", template));
                }
            }
        }
 public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     using (var scope = new PnPMonitoredScope(this.Name))
     {
         // 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;
 }
예제 #20
0
        public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            if (!_willExtract.HasValue)
            {
                var context = web.Context as ClientContext;
                var webCustomActions = web.GetCustomActions();
                var siteCustomActions = context.Site.GetCustomActions();

                _willExtract = webCustomActions.Any() || siteCustomActions.Any();
            }
            return _willExtract.Value;
        }
예제 #21
0
        public void CanCreateComposedLooks()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                // Load the base template which will be used for the comparison work
                var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = ctx.Web.GetBaseTemplate() };

                var template = new ProvisioningTemplate();
                template = new ObjectComposedLook().ExtractObjects(ctx.Web, template, creationInfo);
                Assert.IsInstanceOfType(template.ComposedLook, typeof(Core.Framework.Provisioning.Model.ComposedLook));
            }
        }
        /// <summary>
        /// Method to Invoke Custom Extraction Handlers. 
        /// </summary>
        /// <remarks>
        /// Ensure the ClientContext is not disposed in the custom provider.
        /// </remarks>
        /// <param name="ctx">Authenticated ClientContext that is passed to the custom provider.</param>
        /// <param name="handler">A custom Extensibility Provisioning Provider</param>
        /// <param name="template">ProvisioningTemplate that is passed to the custom provider</param>
        /// <param name="creationInformation">The Provisioning Template creation information object</param>
        /// <param name="scope">The PnPMonitoredScope of the current step in the pipeline</param>
        /// <exception cref="ExtensiblityPipelineException"></exception>
        /// <exception cref="ArgumentException">Provider.Assembly or Provider.Type is NullOrWhiteSpace></exception>
        /// <exception cref="ArgumentNullException">ClientContext is Null></exception>
        public ProvisioningTemplate ExecuteExtensibilityExtractionCallOut(ClientContext ctx, ExtensibilityHandler handler, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope)
        {
            var _loggingSource = "OfficeDevPnP.Core.Framework.Provisioning.Extensibility.ExtensibilityManager.ExecuteCallout";

            if (ctx == null)
                throw new ArgumentNullException(CoreResources.Provisioning_Extensibility_Pipeline_ClientCtxNull);

            if (string.IsNullOrWhiteSpace(handler.Assembly))
                throw new ArgumentException(CoreResources.Provisioning_Extensibility_Pipeline_Missing_AssemblyName);

            if (string.IsNullOrWhiteSpace(handler.Type))
                throw new ArgumentException(CoreResources.Provisioning_Extensibility_Pipeline_Missing_TypeName);

            ProvisioningTemplate parsedTemplate = null;

            try
            {

                var _instance = GetProviderInstance(handler);
                if (_instance is IProvisioningExtensibilityHandler)
                {
                    Log.Info(_loggingSource,
                        CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation,
                        handler.Assembly,
                        handler.Type);

                    parsedTemplate = (_instance as IProvisioningExtensibilityHandler).Extract(ctx, template, creationInformation, scope, handler.Configuration);

                    Log.Info(_loggingSource,
                        CoreResources.Provisioning_Extensibility_Pipeline_Success,
                        handler.Assembly,
                        handler.Type);
                }
                else
                {
                    parsedTemplate = template;
                }
            }
            catch (Exception ex)
            {
                string _message = string.Format(
                    CoreResources.Provisioning_Extensibility_Pipeline_Exception,
                    handler.Assembly,
                    handler.Type,
                    ex);
                Log.Error(_loggingSource, _message);
                throw new ExtensiblityPipelineException(_message, ex);

            }

            return parsedTemplate;
        }
        public void CanCreateEntities()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                // Load the base template which will be used for the comparison work
                var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = ctx.Web.GetBaseTemplate() };

                var template = new ProvisioningTemplate();
                template = new ObjectSiteSecurity().ExtractObjects(ctx.Web, template, creationInfo);

                Assert.IsTrue(template.Security.AdditionalAdministrators.Any());
            }
        }
예제 #24
0
        public void CanCreateEntities()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                // Load the base template which will be used for the comparison work
                var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = ctx.Web.GetBaseTemplate() };

                var template = new ProvisioningTemplate();
                template = new ObjectPropertyBagEntry().CreateEntities(ctx.Web, template, creationInfo);

                Assert.IsTrue(template.PropertyBagEntries.Any());
            }
        }
예제 #25
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var sitePolicyEntity = web.GetAppliedSitePolicy();

                if (sitePolicyEntity != null)
                {
                    template.SitePolicy = sitePolicyEntity.Name;
                }
            }
            return template;
        }
        public void CanCreateEntities()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                // Load the base template which will be used for the comparison work
                var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = ctx.Web.GetBaseTemplate() };

                var template = new ProvisioningTemplate();
                template = new ObjectCustomActions().ExtractObjects(ctx.Web, template, creationInfo);

                Assert.IsInstanceOfType(template.CustomActions, typeof(CustomActions));
            }
        }
        public void Web1605SearchSettingsTest()
        {
            using (var cc = TestCommon.CreateClientContext(centralSubSiteUrl))
            {
                ProvisioningTemplateCreationInformation ptci = new ProvisioningTemplateCreationInformation(cc.Web);
                ptci.IncludeSearchConfiguration = true;
                ptci.HandlersToProcess = Handlers.SearchSettings;

                var result = TestProvisioningTemplate(cc, "searchsettings_web_1605_add.xml", Handlers.SearchSettings, null, ptci);
                SearchSettingValidator sv = new SearchSettingValidator();
                Assert.IsTrue(sv.Validate(result.SourceTemplate.WebSearchSettings, result.TargetTemplate.WebSearchSettings));
            }
        }
예제 #28
0
        public void SiteCollectionSecurityTest()
        {
            using (var cc = TestCommon.CreateClientContext(centralSiteCollectionUrl))
            {
                ProvisioningTemplateCreationInformation ptci = new ProvisioningTemplateCreationInformation(cc.Web);
                ptci.IncludeSiteGroups = true;
                ptci.HandlersToProcess = Handlers.SiteSecurity;

                var result = TestProvisioningTemplate(cc, "security_add.xml", Handlers.SiteSecurity,null,ptci);
                SecurityValidator sv= new SecurityValidator();
                Assert.IsTrue(sv.Validate(result.SourceTemplate.Security, result.TargetTemplate.Security,result.TargetTokenParser,cc));
            }
        }
예제 #29
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Pages))
            {
                // Impossible to return all files in the site currently

                // 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;
        }
예제 #30
0
        public void CanCreateEntities()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                // Load the base template which will be used for the comparison work
                var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = ctx.Web.GetBaseTemplate() };

                var template = new ProvisioningTemplate();
                template = new ObjectField().ExtractObjects(ctx.Web, template, creationInfo);

                Assert.IsTrue(template.SiteFields.Any());
                Assert.IsInstanceOfType(template.SiteFields, typeof(List<Core.Framework.Provisioning.Model.Field>));
            }
        }
예제 #31
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // if this is a sub site then we're not creating field entities.
            if (web.IsSubSite())
            {
                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));
            web.Context.ExecuteQueryRetry();

            var taxTextFieldsToRemove = 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;
                        if (Guid.TryParse(listIdentifier, out listGuid))
                        {
                            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();
                        taxTextFieldsToRemove.Add(taxField.TextField);
                    }
                    // Check if we have version attribute. Remove if exists
                    if (element.Attribute("Version") != null)
                    {
                        element.Attributes("Version").Remove();
                        fieldXml = element.ToString();
                    }
                    template.SiteFields.Add(new Field()
                    {
                        SchemaXml = fieldXml
                    });
                }
            }
            // Remove hidden taxonomy text fields
            foreach (var textFieldId in taxTextFieldsToRemove)
            {
                template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
            }
            // 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);
        }
예제 #32
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.GetFileByServerRelativeUrl(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();

                        var baseUri    = new Uri(web.Url);
                        var fullUri    = new Uri(baseUri, file.ServerRelativeUrl);
                        var folderPath = HttpUtility.UrlDecode(fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/'));

                        // Configure the filename to use
                        fileName = HttpUtility.UrlDecode(fullUri.Segments[fullUri.Segments.Count() - 1]);

                        // Build up a site relative container URL...might end up empty as well
                        String container = HttpUtility.UrlDecode(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 homepage.", ProvisioningMessageType.Error);
                    scope.LogError("No connector present to persist homepage");
                }
            }
            else
            {
                success = true;
            }
            return(success);
        }
예제 #33
0
        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();

            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();

                        siteCollection.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();
                        siteCollection.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();
                            siteCollection.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);
        }
예제 #34
0
        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);
        }
예제 #35
0
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // Load object if not there
            bool executeQueryNeeded = false;

            if (!web.IsPropertyAvailable("Url"))
            {
                web.Context.Load(web, w => w.Url);
                executeQueryNeeded = true;
            }
            if (!web.IsPropertyAvailable("MasterUrl"))
            {
                web.Context.Load(web, w => w.MasterUrl);
                executeQueryNeeded = true;
            }
#if !CLIENTSDKV15
            if (!web.IsPropertyAvailable("AlternateCssUrl"))
            {
                web.Context.Load(web, w => w.AlternateCssUrl);
                executeQueryNeeded = true;
            }
            if (!web.IsPropertyAvailable("SiteLogoUrl"))
            {
                web.Context.Load(web, w => w.SiteLogoUrl);
                executeQueryNeeded = true;
            }
#endif
            if (executeQueryNeeded)
            {
                web.Context.ExecuteQuery();
            }

            // Information coming from the site
            template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url);
#if !CLIENTSDKV15
            template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url);
            template.ComposedLook.SiteLogo     = Tokenize(web.SiteLogoUrl, web.Url);
#else
            template.ComposedLook.AlternateCSS = null;
            template.ComposedLook.SiteLogo     = null;
#endif
            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;

                if (theme.IsCustomComposedLook)
                {
                    if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null)
                    {
                        Site site = (web.Context as ClientContext).Site;
                        if (!site.IsObjectPropertyInstantiated("Url"))
                        {
                            web.Context.Load(site);
                            web.Context.ExecuteQueryRetry();
                        }

                        // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment
                        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;
                        }

                        // Download the theme/branding specific files
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font);
                    }

                    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));

                    // Create file entries for the custom theme files
                    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 (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo))
                    {
                        template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo));
                    }

                    // 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);
        }
예제 #36
0
 private ManagedNavigation GetGlobalManagedNavigation(Web web, WebNavigationSettings navigationSettings, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(GetManagedNavigation(web, navigationSettings, false, template, creationInfo));
 }
예제 #37
0
        public override Model.ProvisioningTemplate ExtractObjects(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (creationInfo.IncludeSiteCollectionTermGroup || creationInfo.IncludeAllTermGroups)
                {
                    // Find the site collection termgroup, if any
                    TaxonomySession session   = TaxonomySession.GetTaxonomySession(web.Context);
                    var             termStore = session.GetDefaultSiteCollectionTermStore();
                    web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage, t => t.OrphanedTermsTermSet);
                    web.Context.ExecuteQueryRetry();

                    var orphanedTermsTermSetId = termStore.OrphanedTermsTermSet.Id;
                    if (termStore.ServerObjectIsNull.Value)
                    {
                        termStore = session.GetDefaultKeywordsTermStore();
                        web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage);
                        web.Context.ExecuteQueryRetry();
                    }

                    var propertyBagKey = string.Format("SiteCollectionGroupId{0}", termStore.Id);

                    // Ensure to grab the property from the rootweb
                    var site = (web.Context as ClientContext).Site;
                    web.Context.Load(site, s => s.RootWeb);
                    web.Context.ExecuteQueryRetry();

                    var siteCollectionTermGroupId = site.RootWeb.GetPropertyBagValueString(propertyBagKey, "");

                    Guid termGroupGuid;
                    Guid.TryParse(siteCollectionTermGroupId, out termGroupGuid);

                    List <TermGroup> termGroups = new List <TermGroup>();
                    if (creationInfo.IncludeAllTermGroups)
                    {
                        web.Context.Load(termStore.Groups, groups => groups.Include(tg => tg.Name,
                                                                                    tg => tg.Id,
                                                                                    tg => tg.Description,
                                                                                    tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder)));
                        web.Context.ExecuteQueryRetry();
                        termGroups = termStore.Groups.ToList();
                    }
                    else
                    {
                        if (termGroupGuid != Guid.Empty)
                        {
                            var termGroup = termStore.GetGroup(termGroupGuid);
                            web.Context.Load(termGroup,
                                             tg => tg.Name,
                                             tg => tg.Id,
                                             tg => tg.Description,
                                             tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.Description, ts => ts.CustomSortOrder));

                            web.Context.ExecuteQueryRetry();

                            termGroups = new List <TermGroup>()
                            {
                                termGroup
                            };
                        }
                    }

                    foreach (var termGroup in termGroups)
                    {
                        Boolean isSiteCollectionTermGroup = termGroupGuid != Guid.Empty && termGroup.Id == termGroupGuid;

                        var modelTermGroup = new Model.TermGroup
                        {
                            Name                    = isSiteCollectionTermGroup ? "{sitecollectiontermgroupname}" : termGroup.Name,
                            Id                      = isSiteCollectionTermGroup ? Guid.Empty : termGroup.Id,
                            Description             = termGroup.Description,
                            SiteCollectionTermGroup = isSiteCollectionTermGroup
                        };

#if !ONPREMISES
                        // If we need to include TermGroups security
                        if (creationInfo.IncludeTermGroupsSecurity)
                        {
                            termGroup.EnsureProperties(tg => tg.ContributorPrincipalNames, tg => tg.GroupManagerPrincipalNames);

                            // Extract the TermGroup contributors
                            modelTermGroup.Contributors.AddRange(
                                from c in termGroup.ContributorPrincipalNames
                                select new Model.User {
                                Name = c
                            });

                            // Extract the TermGroup managers
                            modelTermGroup.Managers.AddRange(
                                from m in termGroup.GroupManagerPrincipalNames
                                select new Model.User {
                                Name = m
                            });
                        }
#endif

                        web.EnsureProperty(w => w.Url);

                        foreach (var termSet in termGroup.TermSets)
                        {
                            // Do not include the orphan term set
                            if (termSet.Id == orphanedTermsTermSetId)
                            {
                                continue;
                            }

                            // Extract all other term sets
                            var modelTermSet = new Model.TermSet();
                            modelTermSet.Name = termSet.Name;
                            if (!isSiteCollectionTermGroup)
                            {
                                modelTermSet.Id = termSet.Id;
                            }
                            modelTermSet.IsAvailableForTagging = termSet.IsAvailableForTagging;
                            modelTermSet.IsOpenForTermCreation = termSet.IsOpenForTermCreation;
                            modelTermSet.Description           = termSet.Description;
                            modelTermSet.Terms.AddRange(GetTerms <TermSet>(web.Context, termSet, termStore.DefaultLanguage, isSiteCollectionTermGroup));
                            foreach (var property in termSet.CustomProperties)
                            {
                                if (property.Key.Equals("_Sys_Nav_AttachedWeb_SiteId", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    modelTermSet.Properties.Add(property.Key, "{sitecollectionid}");
                                }
                                else if (property.Key.Equals("_Sys_Nav_AttachedWeb_WebId", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    modelTermSet.Properties.Add(property.Key, "{siteid}");
                                }
                                else
                                {
                                    modelTermSet.Properties.Add(property.Key, Tokenize(property.Value, web.Url, web));
                                }
                            }
                            modelTermGroup.TermSets.Add(modelTermSet);
                        }

                        template.TermGroups.Add(modelTermGroup);
                    }
                }
            }
            return(template);
        }
예제 #38
0
 public override Model.ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(template);
 }
예제 #39
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                GlobalNavigationType  globalNavigationType;
                CurrentNavigationType currentNavigationType;

                if (!WebSupportsExtractNavigation(web))
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing);
                    return(template);
                }

                // Retrieve the current web navigation settings
                var navigationSettings = new WebNavigationSettings(web.Context, web);
                navigationSettings.EnsureProperties(ns => ns.AddNewPagesToNavigation, ns => ns.CreateFriendlyUrlsForNewPages,
                                                    ns => ns.CurrentNavigation, ns => ns.GlobalNavigation);

                switch (navigationSettings.GlobalNavigation.Source)
                {
                case StandardNavigationSource.InheritFromParentWeb:
                    // Global Navigation is Inherited
                    globalNavigationType = GlobalNavigationType.Inherit;
                    break;

                case StandardNavigationSource.TaxonomyProvider:
                    // Global Navigation is Managed
                    globalNavigationType = GlobalNavigationType.Managed;
                    break;

                case StandardNavigationSource.PortalProvider:
                default:
                    // Global Navigation is Structural
                    globalNavigationType = GlobalNavigationType.Structural;
                    break;
                }

                switch (navigationSettings.CurrentNavigation.Source)
                {
                case StandardNavigationSource.InheritFromParentWeb:
                    // Current Navigation is Inherited
                    currentNavigationType = CurrentNavigationType.Inherit;
                    break;

                case StandardNavigationSource.TaxonomyProvider:
                    // Current Navigation is Managed
                    currentNavigationType = CurrentNavigationType.Managed;
                    break;

                case StandardNavigationSource.PortalProvider:
                default:
                    // Current Navigation is Structural
                    if (AreSiblingsEnabledForCurrentStructuralNavigation(web))
                    {
                        currentNavigationType = CurrentNavigationType.Structural;
                    }
                    else
                    {
                        currentNavigationType = CurrentNavigationType.StructuralLocal;
                    }
                    break;
                }

                var navigationEntity = new Model.Navigation(new GlobalNavigation(globalNavigationType,
                                                                                 globalNavigationType == GlobalNavigationType.Structural ? GetGlobalStructuralNavigation(web, navigationSettings, template, creationInfo) : null,
                                                                                 globalNavigationType == GlobalNavigationType.Managed ? GetGlobalManagedNavigation(web, navigationSettings, template, creationInfo) : null),
                                                            new CurrentNavigation(currentNavigationType,
                                                                                  currentNavigationType == CurrentNavigationType.Structural | currentNavigationType == CurrentNavigationType.StructuralLocal ? GetCurrentStructuralNavigation(web, navigationSettings, template, creationInfo) : null,
                                                                                  currentNavigationType == CurrentNavigationType.Managed ? GetCurrentManagedNavigation(web, navigationSettings, template, creationInfo) : null)
                                                            );

                navigationEntity.AddNewPagesToNavigation       = navigationSettings.AddNewPagesToNavigation;
                navigationEntity.CreateFriendlyUrlsForNewPages = navigationSettings.CreateFriendlyUrlsForNewPages;

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

            return(template);
        }
예제 #40
0
        public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // if this is a sub site then we're not creating security entities as by default security is inherited from the root site
            if (web.IsSubSite())
            {
                return(template);
            }

            var ownerGroup   = web.AssociatedOwnerGroup;
            var memberGroup  = web.AssociatedMemberGroup;
            var visitorGroup = web.AssociatedVisitorGroup;

            web.Context.ExecuteQueryRetry();

            if (!ownerGroup.ServerObjectIsNull.Value)
            {
                web.Context.Load(ownerGroup, o => o.Users);
            }
            if (!memberGroup.ServerObjectIsNull.Value)
            {
                web.Context.Load(memberGroup, o => o.Users);
            }
            if (!visitorGroup.ServerObjectIsNull.Value)
            {
                web.Context.Load(visitorGroup, o => o.Users);
            }
            web.Context.ExecuteQueryRetry();

            var owners   = new List <User>();
            var members  = new List <User>();
            var visitors = new List <User>();

            if (!ownerGroup.ServerObjectIsNull.Value)
            {
                foreach (var member in ownerGroup.Users)
                {
                    owners.Add(new User()
                    {
                        Name = member.LoginName
                    });
                }
            }
            if (!memberGroup.ServerObjectIsNull.Value)
            {
                foreach (var member in memberGroup.Users)
                {
                    members.Add(new User()
                    {
                        Name = member.LoginName
                    });
                }
            }
            if (!visitorGroup.ServerObjectIsNull.Value)
            {
                foreach (var member in visitorGroup.Users)
                {
                    visitors.Add(new User()
                    {
                        Name = member.LoginName
                    });
                }
            }
            var siteSecurity = new SiteSecurity();

            siteSecurity.AdditionalOwners.AddRange(owners);
            siteSecurity.AdditionalMembers.AddRange(members);
            siteSecurity.AdditionalVisitors.AddRange(visitors);

            var query = from user in web.SiteUsers
                        where user.IsSiteAdmin
                        select user;
            var allUsers = web.Context.LoadQuery(query);

            web.Context.ExecuteQueryRetry();

            var admins = new List <User>();

            foreach (var member in allUsers)
            {
                admins.Add(new User()
                {
                    Name = member.LoginName
                });
            }
            siteSecurity.AdditionalAdministrators.AddRange(admins);

            template.Security = siteSecurity;

            // 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);
        }
예제 #41
0
 public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     //using (var scope = new PnPMonitoredScope(this.Name))
     //{ }
     return(template);
 }
예제 #42
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Set default values for Template ID and Version
                template.Id      = String.Format("TEMPLATE-{0:N}", Guid.NewGuid()).ToUpper();
                template.Version = 1;

                // Retrieve original Template ID and remove it from Property Bag Entries
                int provisioningTemplateIdIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateId"));
                if (provisioningTemplateIdIndex > -1)
                {
                    var templateId = template.PropertyBagEntries[provisioningTemplateIdIndex].Value;
                    if (!String.IsNullOrEmpty(templateId))
                    {
                        template.Id = templateId;
                    }
                    template.PropertyBagEntries.RemoveAt(provisioningTemplateIdIndex);
                }

                // Retrieve original Template Info and remove it from Property Bag Entries
                int provisioningTemplateInfoIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateInfo"));
                if (provisioningTemplateInfoIndex > -1)
                {
                    var jsonInfo = template.PropertyBagEntries[provisioningTemplateInfoIndex].Value;

                    if (jsonInfo != null)
                    {
                        ProvisioningTemplateInfo info = JsonConvert.DeserializeObject <ProvisioningTemplateInfo>(jsonInfo);

                        // Override any previously defined Template ID, Version, and SitePolicy
                        // with the one stored in the Template Info, if any
                        if (info != null)
                        {
                            if (!String.IsNullOrEmpty(info.TemplateId))
                            {
                                template.Id = info.TemplateId;
                            }
                            if (!String.IsNullOrEmpty(info.TemplateSitePolicy))
                            {
                                template.SitePolicy = info.TemplateSitePolicy;
                            }
                            if (info.TemplateVersion > 0)
                            {
                                template.Version = info.TemplateVersion;
                            }
                        }
                    }
                    template.PropertyBagEntries.RemoveAt(provisioningTemplateInfoIndex);
                }
            }
            return(template);
        }
예제 #43
0
 public override bool WillExtract(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     if (!_willExtract.HasValue)
     {
         _willExtract = creationInfo.IncludeSiteCollectionTermGroup || creationInfo.IncludeAllTermGroups;
     }
     return(_willExtract.Value);
 }
        private ProvisioningTemplate GetFileContents(Web web, ProvisioningTemplate template, string pageUrl, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope)
        {
            var fullUri = new Uri(UrlUtility.Combine(new Uri(web.Url).GetLeftPart(UriPartial.Authority), pageUrl));

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

            var webParts = web.GetWebParts(pageUrl);

            var file = web.GetFileByServerRelativeUrl(pageUrl);

            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, pageUrl));

                Model.WebPart newWp = new Model.WebPart()
                {
                    Title    = webPart.WebPart.Title,
                    Row      = (uint)webPart.WebPart.ZoneIndex,
                    Order    = (uint)webPart.WebPart.ZoneIndex,
                    Contents = webPartxml
                };
#if !SP2016
                // As long as we've no CSOM library that has the ZoneID we can't use the version check as things don't compile...
                if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION))
                {
                    newWp.Zone = webPart.ZoneId;
                }
#endif
                homeFile.WebParts.Add(newWp);
            }
            template.Files.Add(homeFile);

            // Persist file using connector
            if (creationInfo.PersistBrandingFiles)
            {
                PersistFile(web, creationInfo, scope, folderPath, fileName);
            }
            return(template);
        }
예제 #45
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var clientSidePageContentsHelper = new ClientSidePageContentsHelper();

                // Extract the Home Page
                web.EnsureProperties(w => w.RootFolder.WelcomePage, w => w.ServerRelativeUrl, w => w.Url);
                var homePageUrl = web.RootFolder.WelcomePage;

                // Get pages library
                List sitePagesLibrary = null;
                try
                {
                    ListCollection listCollection = web.Lists;
                    listCollection.EnsureProperties(coll => coll.Include(li => li.BaseTemplate, li => li.RootFolder));
                    sitePagesLibrary = listCollection.Where(p => p.BaseTemplate == (int)ListTemplateType.WebPageLibrary).FirstOrDefault();
                }
                catch
                {
                    // fall back in case of exception when the site has been incorrectly provisioned which can cause access issues on lists/libraries.
                    sitePagesLibrary = web.Lists.GetByTitle("Site Pages");
                    sitePagesLibrary.EnsureProperties(l => l.BaseTemplate, l => l.RootFolder);
                }

                if (sitePagesLibrary != null)
                {
                    var baseUrl = $"{sitePagesLibrary.RootFolder.ServerRelativeUrl}/";

                    var templateFolderName   = OfficeDevPnP.Core.Pages.ClientSidePage.DefaultTemplatesFolder;// string.Empty;
                    var templateFolderString = sitePagesLibrary.GetPropertyBagValueString(TemplatesFolderGuid, null);
                    Guid.TryParse(templateFolderString, out Guid templateFolderGuid);
                    if (templateFolderGuid != Guid.Empty)
                    {
                        try
                        {
                            var templateFolder = ((ClientContext)sitePagesLibrary.Context).Web.GetFolderById(templateFolderGuid);
                            templateFolderName = templateFolder.EnsureProperty(f => f.Name);
                        }
                        catch
                        {
                            //eat it and continue with default name
                        }
                    }
                    CamlQuery query = new CamlQuery
                    {
                        ViewXml = CAMLQueryByExtension
                    };
                    var pages = sitePagesLibrary.GetItems(query);
                    web.Context.Load(pages);
                    web.Context.ExecuteQueryRetry();
                    if (pages.FirstOrDefault() != null)
                    {
                        // Prep a list of pages to export allowing us hanlde translations
                        List <PageToExport> pagesToExport = new List <PageToExport>();
                        foreach (var page in pages)
                        {
                            PageToExport pageToExport = new PageToExport()
                            {
                                ListItem            = page,
                                IsTranslation       = false,
                                TranslatedLanguages = null,
                            };

                            // If multi-lingual is enabled these fields will be available on the SitePages library
                            if (page.FieldValues.ContainsKey(SPIsTranslation) && page[SPIsTranslation] != null && !string.IsNullOrEmpty(page[SPIsTranslation].ToString()))
                            {
                                if (bool.TryParse(page[SPIsTranslation].ToString(), out bool isTranslation))
                                {
                                    pageToExport.IsTranslation = isTranslation;
                                }
                            }

                            if (page.FieldValues.ContainsKey(PageIDField) && page[PageIDField] != null && !string.IsNullOrEmpty(page[PageIDField].ToString()))
                            {
                                pageToExport.PageId = Guid.Parse(page[PageIDField].ToString());
                            }

                            if (page.FieldValues.ContainsKey(SPTranslationSourceItemId) && page[SPTranslationSourceItemId] != null && !string.IsNullOrEmpty(page[SPTranslationSourceItemId].ToString()))
                            {
                                pageToExport.SourcePageId = Guid.Parse(page[SPTranslationSourceItemId].ToString());
                            }

                            if (page.FieldValues.ContainsKey(SPTranslationLanguage) && page[SPTranslationLanguage] != null && !string.IsNullOrEmpty(page[SPTranslationLanguage].ToString()))
                            {
                                pageToExport.Language = page[SPTranslationLanguage].ToString();
                            }

                            if (page.FieldValues.ContainsKey(SPTranslatedLanguages) && page[SPTranslatedLanguages] != null && !string.IsNullOrEmpty(page[SPTranslatedLanguages].ToString()))
                            {
                                pageToExport.TranslatedLanguages = new List <string>(page[SPTranslatedLanguages] as string[]);
                            }

                            string pageUrl  = null;
                            string pageName = "";
                            if (page.FieldValues.ContainsKey(FileRefField) && !String.IsNullOrEmpty(page[FileRefField].ToString()))
                            {
                                pageUrl  = page[FileRefField].ToString();
                                pageName = page[FileLeafRefField].ToString();
                            }
                            else
                            {
                                //skip page
                                continue;
                            }

                            var isTemplate = false;
                            // Is this page a template?
                            if (pageUrl.IndexOf($"/{templateFolderName}/", StringComparison.InvariantCultureIgnoreCase) > -1)
                            {
                                isTemplate = true;
                            }
                            // Is this page the web's home page?
                            bool isHomePage = false;
                            if (pageUrl.EndsWith(homePageUrl, StringComparison.InvariantCultureIgnoreCase))
                            {
                                isHomePage = true;
                            }

                            // Get the name of the page, including the folder name
                            pageName = Regex.Replace(pageUrl, baseUrl, "", RegexOptions.IgnoreCase);

                            pageToExport.IsHomePage = isHomePage;
                            pageToExport.IsTemplate = isTemplate;
                            pageToExport.PageName   = pageName;
                            pageToExport.PageUrl    = pageUrl;
                            pagesToExport.Add(pageToExport);
                        }

                        // Populate SourcePageName to make it easier to hookup translations at export time
                        foreach (var page in pagesToExport.Where(p => p.IsTranslation))
                        {
                            var sourcePage = pagesToExport.Where(p => p.PageId == page.SourcePageId).FirstOrDefault();
                            if (sourcePage != null)
                            {
                                page.SourcePageName = sourcePage.PageName;
                            }
                        }

                        var currentPageIndex = 1;
                        foreach (var page in pagesToExport.OrderBy(p => p.IsTranslation))
                        {
                            if (creationInfo.IncludeAllClientSidePages || page.IsHomePage)
                            {
                                // Is this a client side page?
                                if (FieldExistsAndUsed(page.ListItem, ClientSideApplicationId) && page.ListItem[ClientSideApplicationId].ToString().Equals(FeatureId_Web_ModernPage.ToString(), StringComparison.InvariantCultureIgnoreCase))
                                {
                                    WriteSubProgress("ClientSidePage", !string.IsNullOrWhiteSpace(page.PageName) ? page.PageName : page.PageUrl, currentPageIndex, pages.Count);
                                    // extract the page using the OOB logic
                                    clientSidePageContentsHelper.ExtractClientSidePage(web, template, creationInfo, scope, page);
                                }
                            }
                            currentPageIndex++;
                        }
                    }
                }

                // 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);
        }
예제 #46
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.EnsureProperty(w => w.Id);

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

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

                    // 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)
                    {
#if ONPREMISES
                        template.Workflows.WorkflowSubscriptions.AddRange(
                            from s in subscriptions
                            select new Model.WorkflowSubscription(s.PropertyDefinitions.TokenizeWorkflowSubscriptionProperties(lists))
                        {
                            DefinitionId  = s.DefinitionId,
                            Enabled       = s.Enabled,
                            EventSourceId = s.EventSourceId != web.Id ? String.Format("{{listid:{0}}}", lists.First(l => l.Id == s.EventSourceId).Title) : null,
                            EventTypes    = s.EventTypes.ToList(),
                            ManualStartBypassesActivationLimit = s.ManualStartBypassesActivationLimit,
                            Name            = s.Name,
                            ListId          = s.EventSourceId != web.Id ? String.Format("{{listid:{0}}}", lists.First(l => l.Id == s.EventSourceId).Title) : null,
                            StatusFieldName = s.StatusFieldName,
                        }
                            );
#else
                        template.Workflows.WorkflowSubscriptions.AddRange(
                            from s in subscriptions
                            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,
                        }
                            );
#endif
                    }
                }
            }
            return(template);
        }
예제 #47
0
        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);
        }
예제 #48
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var auditSettings = new AuditSettings();

                var site = (web.Context as ClientContext).Site;

                site.EnsureProperties(s => s.Audit, s => s.AuditLogTrimmingRetention, s => s.TrimAuditLog);

                var siteAuditSettings = site.Audit;

                bool include = false;
                if (siteAuditSettings.AuditFlags != auditSettings.AuditFlags)
                {
                    include = true;
                    auditSettings.AuditFlags = siteAuditSettings.AuditFlags;
                }

                if (site.AuditLogTrimmingRetention != auditSettings.AuditLogTrimmingRetention)
                {
                    include = true;
                    auditSettings.AuditLogTrimmingRetention = site.AuditLogTrimmingRetention;
                }

                if (site.TrimAuditLog != auditSettings.TrimAuditLog)
                {
                    include = true;
                    auditSettings.TrimAuditLog = site.TrimAuditLog;
                }

                if (include)
                {
                    // If a base template is specified then use that one to "cleanup" the generated template model
                    if (creationInfo.BaseTemplate != null)
                    {
                        if (!auditSettings.Equals(creationInfo.BaseTemplate.AuditSettings))
                        {
                            template.AuditSettings = auditSettings;
                        }
                    }
                    else
                    {
                        template.AuditSettings = auditSettings;
                    }
                }
            }
            return(template);
        }
예제 #49
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))
                {
                    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);
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.Context.Load(web, w => w.SupportedUILanguageIds);
                web.Context.ExecuteQueryRetry();

                SupportedUILanguageCollection supportedUILanguageCollection = new SupportedUILanguageCollection(template);
                foreach (var id in web.SupportedUILanguageIds)
                {
                    supportedUILanguageCollection.Add(new SupportedUILanguage()
                    {
                        LCID = id
                    });
                }

                if (creationInfo.BaseTemplate != null)
                {
                    if (!creationInfo.BaseTemplate.SupportedUILanguages.Equals(supportedUILanguageCollection))
                    {
                        template.SupportedUILanguages = supportedUILanguageCollection;
                    }
                }
                else
                {
                    template.SupportedUILanguages = supportedUILanguageCollection;
                }
            }

            return(template);
        }
예제 #51
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            // Impossible to return all files in the site currently

            // 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);
        }
예제 #52
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.EnsureProperties(
#if !ONPREMISES
                    w => w.NoCrawl,
                    w => w.CommentsOnSitePagesDisabled,
#endif
                    //w => w.Title,
                    //w => w.Description,
                    w => w.MasterUrl,
                    w => w.CustomMasterUrl,
                    w => w.SiteLogoUrl,
                    w => w.RequestAccessEmail,
                    w => w.RootFolder,
                    w => w.AlternateCssUrl,
                    w => w.ServerRelativeUrl,
                    w => w.Url);

                var webSettings = new WebSettings();
#if !ONPREMISES
                webSettings.NoCrawl = web.NoCrawl;
                webSettings.CommentsOnSitePagesDisabled = web.CommentsOnSitePagesDisabled;
#endif
                // We're not extracting Title and Description
                //webSettings.Title = Tokenize(web.Title, web.Url);
                //webSettings.Description = Tokenize(web.Description, web.Url);
                webSettings.MasterPageUrl       = Tokenize(web.MasterUrl, web.Url);
                webSettings.CustomMasterPageUrl = Tokenize(web.CustomMasterUrl, web.Url);
                webSettings.SiteLogo            = TokenizeHost(web, Tokenize(web.SiteLogoUrl, web.Url));
                // Notice. No tokenization needed for the welcome page, it's always relative for the site
                webSettings.WelcomePage        = web.RootFolder.WelcomePage;
                webSettings.AlternateCSS       = Tokenize(web.AlternateCssUrl, web.Url);
                webSettings.RequestAccessEmail = web.RequestAccessEmail;

                if (creationInfo.PersistBrandingFiles)
                {
                    if (!string.IsNullOrEmpty(web.MasterUrl))
                    {
                        var masterUrl = web.MasterUrl.ToLower();
                        if (!masterUrl.EndsWith("default.master") && !masterUrl.EndsWith("custom.master") && !masterUrl.EndsWith("v4.master") && !masterUrl.EndsWith("seattle.master") && !masterUrl.EndsWith("oslo.master"))
                        {
                            if (PersistFile(web, creationInfo, scope, web.MasterUrl))
                            {
                                template.Files.Add(GetTemplateFile(web, web.MasterUrl));
                            }
                        }
                    }
                    if (!string.IsNullOrEmpty(web.CustomMasterUrl))
                    {
                        var customMasterUrl = web.CustomMasterUrl.ToLower();
                        if (!customMasterUrl.EndsWith("default.master") && !customMasterUrl.EndsWith("custom.master") && !customMasterUrl.EndsWith("v4.master") && !customMasterUrl.EndsWith("seattle.master") && !customMasterUrl.EndsWith("oslo.master"))
                        {
                            if (PersistFile(web, creationInfo, scope, web.CustomMasterUrl))
                            {
                                template.Files.Add(GetTemplateFile(web, web.CustomMasterUrl));
                            }
                        }
                    }
                    // Extract site logo if property has been set and it's not dynamic image from _api URL
                    if (!string.IsNullOrEmpty(web.SiteLogoUrl) && (!web.SiteLogoUrl.ToLowerInvariant().Contains("_api/")))
                    {
                        // Convert to server relative URL if needed (web.SiteLogoUrl 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 siteLogoServerRelativeUrl = web.SiteLogoUrl.Replace(webUrl, "");

                        if (PersistFile(web, creationInfo, scope, siteLogoServerRelativeUrl))
                        {
                            template.Files.Add(GetTemplateFile(web, siteLogoServerRelativeUrl));
                        }
                    }
                    if (!string.IsNullOrEmpty(web.AlternateCssUrl))
                    {
                        if (PersistFile(web, creationInfo, scope, web.AlternateCssUrl))
                        {
                            template.Files.Add(GetTemplateFile(web, web.AlternateCssUrl));
                        }
                    }
                    var files = template.Files.Distinct().ToList();
                    template.Files.Clear();
                    template.Files.AddRange(files);
                }

                if (!creationInfo.PersistBrandingFiles)
                {
                    if (creationInfo.BaseTemplate != null)
                    {
                        if (!webSettings.Equals(creationInfo.BaseTemplate.WebSettings))
                        {
                            template.WebSettings = webSettings;
                        }
                    }
                    else
                    {
                        template.WebSettings = webSettings;
                    }
                }
                else
                {
                    template.WebSettings = webSettings;
                }
            }
            return(template);
        }
예제 #53
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                template.ContentTypes.AddRange(GetEntities(web, scope, creationInfo, template));

                // 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, scope);
                }
            }
            return(template);
        }
        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);

                List pagesLibrary = web.GetPagesLibrary();
                var  items        = pagesLibrary.GetItems(CamlQuery.CreateAllItemsQuery());
                web.Context.Load(items, i => i.Include(it => it.DisplayName, it => it.File));
                web.Context.ExecuteQuery();

                foreach (ListItem listItem in items)
                {
                    try
                    {
                        //var listItem = file.EnsureProperty(f => f.ListItemAllFields);
                        if (listItem != null)
                        {
                            File file = listItem.File;
                            if (listItem.FieldValues.ContainsKey("WikiField") && listItem.FieldValues["WikiField"] != null)
                            {
                                // Wiki page
                                var fullUri    = new Uri(UrlUtility.Combine(new Uri(web.Url).GetLeftPart(UriPartial.Authority), file.ServerRelativeUrl));
                                var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/');

                                LimitedWebPartManager limitedWPManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);

                                web.Context.Load(limitedWPManager);

                                var webParts = web.GetWebParts(file.ServerRelativeUrl);

                                var page = new Page()
                                {
                                    Layout    = WikiPageLayout.Custom,
                                    Overwrite = true,
                                    Url       = Tokenize(fullUri.PathAndQuery, web.Url),
                                };
                                var pageContents = listItem.FieldValues["WikiField"].ToString();

                                Regex regexClientIds = new Regex(@"id=\""div_(?<ControlId>(\w|\-)+)");
                                if (regexClientIds.IsMatch(pageContents))
                                {
                                    foreach (Match webPartMatch in regexClientIds.Matches(pageContents))
                                    {
                                        String serverSideControlId = webPartMatch.Groups["ControlId"].Value;

                                        try
                                        {
                                            String serverSideControlIdToSearchFor = String.Format("g_{0}",
                                                                                                  serverSideControlId.Replace("-", "_"));

                                            WebPartDefinition webPart = limitedWPManager.WebParts.GetByControlId(serverSideControlIdToSearchFor);
                                            web.Context.Load(webPart,
                                                             wp => wp.Id,
                                                             wp => wp.WebPart.Title,
                                                             wp => wp.WebPart.ZoneIndex
                                                             );
                                            web.Context.ExecuteQueryRetry();

                                            var webPartxml = TokenizeWebPartXml(web, web.GetWebPartXml(webPart.Id, file.ServerRelativeUrl));

                                            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, string.Format("{{webpartid:{0}}}", 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 (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION))
                                {
                                    // Not a wikipage
                                    template = GetFileContents(web, template, file.ServerRelativeUrl, creationInfo, scope);
                                    if (template.WebSettings == null)
                                    {
                                        template.WebSettings = new WebSettings();
                                    }
                                    template.WebSettings.WelcomePage = homepageUrl;
                                }
                                else
                                {
                                    WriteMessage(string.Format("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION), ProvisioningMessageType.Warning);
                                    scope.LogWarning("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION);
                                }
                            }
                        }
                    }
                    catch (ServerException ex)
                    {
                        if (ex.ServerErrorCode != -2146232832)
                        {
                            throw;
                        }
                        else
                        {
                            if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION))
                            {
                                // Page does not belong to a list, extract the file as is
                                template = GetFileContents(web, template, welcomePageUrl, creationInfo, scope);
                                if (template.WebSettings == null)
                                {
                                    template.WebSettings = new WebSettings();
                                }
                                template.WebSettings.WelcomePage = homepageUrl;
                            }
                            else
                            {
                                WriteMessage(string.Format("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION), ProvisioningMessageType.Warning);
                                scope.LogWarning("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION);
                            }
                        }
                    }
                }

                // 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);
        }
예제 #55
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // The ALM API do not support the local Site Collection App Catalog
                // Thus, so far we skip the AppCatalog section
                // NOOP

                // Process the collection of Apps installed in the current Site Collection
                var appCatalogUri = web.GetAppCatalog();
                if (appCatalogUri != null)
                {
                    var manager = new AppManager(web.Context as ClientContext);

                    var siteApps = manager.GetAvailable()?.Where(a => a.InstalledVersion != null)?.ToList();
                    if (siteApps != null && siteApps.Count > 0)
                    {
                        foreach (var app in siteApps)
                        {
                            template.ApplicationLifecycleManagement.Apps.Add(new Model.App
                            {
                                AppId  = app.Id.ToString(),
                                Action = AppAction.Install,
                            });
                        }
                    }
                }
            }
            return(template);
        }
예제 #56
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(!web.IsSubSite());
 }
        /// <summary>
        /// Actual implementation of extracting configuration from existing site.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="creationInfo"></param>
        /// <returns></returns>
        internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Extraction))
            {
                ProvisioningProgressDelegate progressDelegate = null;
                ProvisioningMessagesDelegate messagesDelegate = null;
                if (creationInfo != null)
                {
                    if (creationInfo.BaseTemplate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_Base_template_available___0_, creationInfo.BaseTemplate.Id);
                    }
                    progressDelegate = creationInfo.ProgressDelegate;
                    if (creationInfo.ProgressDelegate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_ProgressDelegate_registered);
                    }
                    messagesDelegate = creationInfo.MessagesDelegate;
                    if (creationInfo.MessagesDelegate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_MessagesDelegate_registered);
                    }
                    if (creationInfo.IncludeAllTermGroups)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeAllTermGroups_is_set_to_true);
                    }
                    if (creationInfo.IncludeSiteCollectionTermGroup)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeSiteCollectionTermGroup_is_set_to_true);
                    }
                    if (creationInfo.PersistBrandingFiles)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_PersistBrandingFiles_is_set_to_true);
                    }
                }
                else
                {
                    // When no provisioning info was passed then we want to execute all handlers
                    creationInfo = new ProvisioningTemplateCreationInformation(web);
                    creationInfo.HandlersToProcess = Handlers.All;
                }

                // Create empty object
                ProvisioningTemplate template = new ProvisioningTemplate();

                // Hookup connector, is handy when the generated template object is used to apply to another site
                template.Connector = creationInfo.FileConnector;

                List <ObjectHandlerBase> objectHandlers = new List <ObjectHandlerBase>();

                if (creationInfo.HandlersToProcess.HasFlag(Handlers.RegionalSettings))
                {
                    objectHandlers.Add(new ObjectRegionalSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SupportedUILanguages))
                {
                    objectHandlers.Add(new ObjectSupportedUILanguages());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.AuditSettings))
                {
                    objectHandlers.Add(new ObjectAuditSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SitePolicy))
                {
                    objectHandlers.Add(new ObjectSitePolicy());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SiteSecurity))
                {
                    objectHandlers.Add(new ObjectSiteSecurity());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.TermGroups))
                {
                    objectHandlers.Add(new ObjectTermGroups());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Fields))
                {
                    objectHandlers.Add(new ObjectField(FieldAndListProvisioningStepHelper.Step.Export));
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ContentTypes))
                {
                    objectHandlers.Add(new ObjectContentType(FieldAndListProvisioningStepHelper.Step.Export));
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Lists))
                {
                    objectHandlers.Add(new ObjectListInstance(FieldAndListProvisioningStepHelper.Step.Export));
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.CustomActions))
                {
                    objectHandlers.Add(new ObjectCustomActions());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Features))
                {
                    objectHandlers.Add(new ObjectFeatures());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ComposedLook))
                {
                    objectHandlers.Add(new ObjectComposedLook());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SearchSettings))
                {
                    objectHandlers.Add(new ObjectSearchSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Files))
                {
                    objectHandlers.Add(new ObjectFiles());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Pages))
                {
                    objectHandlers.Add(new ObjectPages());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.PageContents))
                {
                    objectHandlers.Add(new ObjectPageContents());
                }
#if !ONPREMISES
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.PageContents))
                {
                    objectHandlers.Add(new ObjectClientSidePageContents());
                }
#endif
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.PropertyBagEntries))
                {
                    objectHandlers.Add(new ObjectPropertyBagEntry());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Publishing))
                {
                    objectHandlers.Add(new ObjectPublishing());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Workflows))
                {
                    objectHandlers.Add(new ObjectWorkflows());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.WebSettings))
                {
                    objectHandlers.Add(new ObjectWebSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Navigation))
                {
                    objectHandlers.Add(new ObjectNavigation());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ImageRenditions))
                {
                    objectHandlers.Add(new ObjectImageRenditions());
                }
                objectHandlers.Add(new ObjectLocalization()); // Always add this one, check is done in the handler
#if !ONPREMISES
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Tenant))
                {
                    objectHandlers.Add(new ObjectTenant());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ApplicationLifecycleManagement))
                {
                    objectHandlers.Add(new ObjectApplicationLifecycleManagement());
                }
#endif
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ExtensibilityProviders))
                {
                    objectHandlers.Add(new ObjectExtensibilityHandlers());
                }

                objectHandlers.Add(new ObjectRetrieveTemplateInfo());

                int step = 1;

                var count = objectHandlers.Count(o => o.ReportProgress && o.WillExtract(web, template, creationInfo));

                web.EnsureProperty(w => w.Url);

                foreach (var handler in objectHandlers)
                {
                    if (handler.WillExtract(web, template, creationInfo))
                    {
                        if (messagesDelegate != null)
                        {
                            handler.MessagesDelegate = messagesDelegate;
                        }
                        if (handler.ReportProgress && progressDelegate != null)
                        {
                            progressDelegate(handler.Name, step, count);
                            step++;
                        }

                        using (var handlerContext = web.Context.Clone(web.Url))
                        {
                            template = handler.ExtractObjects(handlerContext.Web, template, creationInfo);
                        }
                    }
                }

                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;
                bool isSubSite    = web.IsSubSite();
                var  webFeatures  = web.Features;
                var  siteFeatures = context.Site.Features;

                context.Load(webFeatures, fs => fs.Include(f => f.DefinitionId));
                if (!isSubSite)
                {
                    context.Load(siteFeatures, fs => fs.Include(f => f.DefinitionId));
                }
                context.ExecuteQueryRetry();

                var features = new Features();
                foreach (var feature in webFeatures)
                {
                    features.WebFeatures.Add(new Feature()
                    {
                        Deactivate = false, Id = feature.DefinitionId
                    });
                }

                // if this is a sub site then we're not creating  site collection scoped feature entities
                if (!isSubSite)
                {
                    foreach (var feature in siteFeatures)
                    {
                        features.SiteFeatures.Add(new Feature()
                        {
                            Deactivate = false, Id = feature.DefinitionId
                        });
                    }
                }

                template.Features = features;

                // 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, isSubSite);
                }
            }
            return(template);
        }
예제 #59
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     return(false);
 }
예제 #60
0
 public override bool WillExtract(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     // By default we don't extract the packages
     return(false);
 }