/// <summary>
        /// Instantiates the function processor. Also loads the defined add-ons
        /// </summary>
        /// <param name="page">Client side page for which we're executing the functions/selectors as part of the mapping</param>
        /// <param name="pageTransformation">Webpart mapping information</param>
        public FunctionProcessor(ClientContext sourceClientContext, ClientSidePage page, PageTransformation pageTransformation, BaseTransformationInformation baseTransformationInformation, IList <ILogObserver> logObservers = null)
        {
            this.page = page;
            this.pageTransformation = pageTransformation;

            //Register any existing observers
            if (logObservers != null)
            {
                foreach (var observer in logObservers)
                {
                    base.RegisterObserver(observer);
                }
            }

            // instantiate default built in functions class
            this.addOnTypes       = new List <AddOnType>();
            this.builtInFunctions = Activator.CreateInstance(typeof(BuiltIn), baseTransformationInformation, this.page.Context, sourceClientContext, this.page, base.RegisteredLogObservers);

            // instantiate the custom function classes (if there are)
            foreach (var addOn in this.pageTransformation.AddOns)
            {
                try
                {
                    string path = "";
                    if (addOn.Assembly.Contains("\\") && System.IO.File.Exists(addOn.Assembly))
                    {
                        path = addOn.Assembly;
                    }
                    else
                    {
                        path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, addOn.Assembly);
                    }

                    var assembly   = Assembly.LoadFile(path);
                    var customType = assembly.GetType(addOn.Type);
                    var instance   = Activator.CreateInstance(customType, this.page.Context);

                    this.addOnTypes.Add(new AddOnType()
                    {
                        Name     = addOn.Name,
                        Assembly = assembly,
                        Instance = instance,
                        Type     = customType,
                    });
                }
                catch (Exception ex)
                {
                    LogError(LogStrings.Error_FailedToInitiateCustomFunctionClasses, LogStrings.Heading_FunctionProcessor, ex);
                    throw;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a page transformator instance
        /// </summary>
        /// <param name="sourceClientContext">ClientContext of the site holding the page</param>
        /// <param name="targetClientContext">ClientContext of the site that will receive the modernized page</param>
        /// <param name="pageTransformationModel">Page transformation model</param>
        public DelvePageTransformator(ClientContext sourceClientContext, ClientContext targetClientContext, PageTransformation pageTransformationModel)
        {
            this.sourceClientContext = sourceClientContext;
            this.targetClientContext = targetClientContext;

            this.version       = GetVersion();
            this.pageTelemetry = new PageTelemetry(version);

            this.pageTransformation = pageTransformationModel;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Instantiates a web part page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public WebPartPage(ListItem page, PageTransformation pageTransformation) : base(page, pageTransformation)
 {
 }
Ejemplo n.º 4
0
 public WikiPage(ListItem page, PageTransformation pageTransformation) : base(page, pageTransformation)
 {
     this.parser = new HtmlParser();
 }
        /// <summary>
        /// Instantiates the content transformator
        /// </summary>
        /// <param name="page">Client side page that will be updates</param>
        /// <param name="pageTransformation">Transformation information</param>
        public ContentTransformator(ClientContext sourceClientContext, ClientSidePage page, PageTransformation pageTransformation, Dictionary <string, string> mappingProperties, IList <ILogObserver> logObservers = null) : base()
        {
            //Register any existing observers
            if (logObservers != null)
            {
                foreach (var observer in logObservers)
                {
                    base.RegisterObserver(observer);
                }
            }

            this.page = page ?? throw new ArgumentException("Page cannot be null");
            this.pageTransformation = pageTransformation ?? throw new ArgumentException("pageTransformation cannot be null");
            this.globalTokens       = CreateGlobalTokenList(page.Context, mappingProperties);
            this.functionProcessor  = new FunctionProcessor(sourceClientContext, this.page, this.pageTransformation, base.RegisteredLogObservers);

            this.sourceClientContext = sourceClientContext;
            this.isCrossSiteTransfer = IsCrossSiteTransfer();
        }
        /// <summary>
        /// Page scan results log
        /// </summary>
        /// <param name="scannedSites">Scanned sites</param>
        /// <param name="scannedWebs">Scanned webs</param>
        /// <param name="pageScanResults">Scanned page results</param>
        /// <param name="pageTransformation">Page transformation data</param>
        public void LogPageScan(int scannedSites, int scannedWebs, ConcurrentDictionary <string, PageScanResult> pageScanResults, PageTransformation pageTransformation)
        {
            if (this.telemetryClient == null)
            {
                return;
            }

            try
            {
                Dictionary <string, string> properties = new Dictionary <string, string>();
                Dictionary <string, double> metrics    = new Dictionary <string, double>();

                // Populate properties

                // Page transformation engine version
                properties.Add(EngineVersion, this.version);
                properties.Add(PagesResults.Sites.ToString(), scannedSites.ToString());
                properties.Add(PagesResults.Webs.ToString(), scannedWebs.ToString());
                properties.Add(PagesResults.Pages.ToString(), pageScanResults.Count.ToString());
                // Azure AD tenant
                properties.Add(AADTenantId, this.aadTenantId.ToString());

                // Send the event
                this.telemetryClient.TrackEvent(TelemetryEvents.Pages.ToString(), properties, metrics);

                this.telemetryClient.GetMetric($"Pages.{PagesResults.Sites.ToString()}").TrackValue(scannedSites);
                this.telemetryClient.GetMetric($"Pages.{PagesResults.Webs.ToString()}").TrackValue(scannedWebs);
                this.telemetryClient.GetMetric($"Pages.{PagesResults.Pages.ToString()}").TrackValue(pageScanResults.Count);

                Metric pageType         = this.telemetryClient.GetMetric($"Pages.{PagesResults.PageType.ToString()}", "Pages.PageType");
                Metric pageLayout       = this.telemetryClient.GetMetric($"Pages.{PagesResults.PageLayout.ToString()}", "Pages.PageLayout");
                Metric isHomePage       = this.telemetryClient.GetMetric($"Pages.{PagesResults.IsHomePage.ToString()}", "Pages.IsHomePage");
                Metric webPartMapping   = this.telemetryClient.GetMetric($"Pages.{PagesResults.WebPartMapping.ToString()}", "Pages.WebPartMapping");
                Metric unMappedWebParts = this.telemetryClient.GetMetric($"Pages.{PagesResults.UnMappedWebParts.ToString()}", "Pages.UnMappedWebParts");

                foreach (var item in pageScanResults)
                {
                    WriteMetric(pageType, item.Value.PageType);
                    WriteMetric(pageLayout, item.Value.Layout);
                    WriteMetric(isHomePage, item.Value.HomePage);

                    if (item.Value.WebParts != null)
                    {
                        int           webPartsOnPage       = item.Value.WebParts.Count();
                        int           webPartsOnPageMapped = 0;
                        List <string> nonMappedWebParts    = new List <string>();
                        foreach (var webPart in item.Value.WebParts.OrderBy(p => p.Row).ThenBy(p => p.Column).ThenBy(p => p.Order))
                        {
                            var found = pageTransformation.WebParts.Where(p => p.Type.Equals(webPart.Type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                            if (found != null && found.Mappings != null)
                            {
                                webPartsOnPageMapped++;
                            }
                            else
                            {
                                var t = webPart.Type.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0];
                                if (!nonMappedWebParts.Contains(t))
                                {
                                    nonMappedWebParts.Add(t);
                                }
                            }
                        }

                        WriteMetric(webPartMapping, String.Format("{0:0}", (((double)webPartsOnPageMapped / (double)webPartsOnPage) * 100)));
                        foreach (var w in nonMappedWebParts)
                        {
                            WriteMetric(unMappedWebParts, w);
                        }
                    }
                }
            }
            catch
            {
                // Eat all exceptions
            }
            finally
            {
                this.telemetryClient.Flush();
            }
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Instantiates a wiki page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public WikiPage(ListItem page, PageTransformation pageTransformation) : base(page, null, pageTransformation)
 {
 }
        protected override void ExecuteCmdlet()
        {
            //Fix loading of modernization framework
            FixLocalAssemblyResolving();

            // Load the page to transform
            Identity.Library = this.Library;
            Identity.Folder  = this.Folder;

            ListItem page = null;

            if (this.PublishingPage)
            {
                this.ClientContext.Web.EnsureProperty(p => p.ServerRelativeUrl);
                page = Identity.GetPage(this.ClientContext.Web, CacheManager.Instance.GetPublishingPagesLibraryName(this.ClientContext));
            }
            else
            {
                if (this.Folder == null || !this.Folder.Equals(rootFolder, StringComparison.InvariantCultureIgnoreCase))
                {
                    page = Identity.GetPage(this.ClientContext.Web, "sitepages");
                }
            }

            if (page == null && !this.Folder.Equals(rootFolder, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new Exception($"Page '{Identity?.Name}' does not exist");
            }

            // Publishing specific validation
            if (this.PublishingPage && string.IsNullOrEmpty(this.TargetWebUrl) && TargetConnection == null)
            {
                throw new Exception($"Publishing page transformation is only supported when transformating into another site collection. Use the -TargetWebUrl to specify a modern target site.");
            }

            // Load transformation models
            PageTransformation webPartMappingModel = null;

            if (string.IsNullOrEmpty(this.WebPartMappingFile))
            {
                // Load xml mapping data
                XmlSerializer xmlMapping = new XmlSerializer(typeof(PageTransformation));

                // Load the default one from resources into a model, no need for persisting this file
                string webpartMappingFileContents = WebPartMappingLoader.LoadFile("SharePointPnP.PowerShell.Commands.ClientSidePages.webpartmapping.xml");

                using (var stream = GenerateStreamFromString(webpartMappingFileContents))
                {
                    webPartMappingModel = (PageTransformation)xmlMapping.Deserialize(stream);
                }

                this.WriteVerbose("Using embedded webpartmapping file. Use Export-PnPClientSidePageMapping to get that file in case you want to base your version of the embedded version.");
            }

            // Validate webpartmappingfile
            if (!string.IsNullOrEmpty(this.WebPartMappingFile))
            {
                if (!System.IO.File.Exists(this.WebPartMappingFile))
                {
                    throw new Exception($"Provided webpartmapping file {this.WebPartMappingFile} does not exist");
                }
            }

            if (this.PublishingPage && !string.IsNullOrEmpty(this.PageLayoutMapping) && !System.IO.File.Exists(this.PageLayoutMapping))
            {
                throw new Exception($"Provided pagelayout mapping file {this.PageLayoutMapping} does not exist");
            }

            // Create target client context (when needed)
            ClientContext targetContext = null;

            if (TargetConnection == null)
            {
                if (!string.IsNullOrEmpty(TargetWebUrl))
                {
                    targetContext = this.ClientContext.Clone(TargetWebUrl);
                }
            }
            else
            {
                targetContext = TargetConnection.Context;
            }


            // Create transformator instance
            PageTransformator           pageTransformator           = null;
            PublishingPageTransformator publishingPageTransformator = null;

            if (!string.IsNullOrEmpty(this.WebPartMappingFile))
            {
                // Using custom web part mapping file
                if (this.PublishingPage)
                {
                    if (!string.IsNullOrEmpty(this.PageLayoutMapping))
                    {
                        // Using custom page layout mapping file + default one (they're merged together)
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, this.WebPartMappingFile, this.PageLayoutMapping);
                    }
                    else
                    {
                        // Using default page layout mapping file
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, this.WebPartMappingFile, null);
                    }
                }
                else
                {
                    // Use web part mapping file
                    pageTransformator = new PageTransformator(this.ClientContext, targetContext, this.WebPartMappingFile);
                }
            }
            else
            {
                // Using default web part mapping file
                if (this.PublishingPage)
                {
                    if (!string.IsNullOrEmpty(this.PageLayoutMapping))
                    {
                        // Load and validate the custom mapping file
                        PageLayoutManager pageLayoutManager = new PageLayoutManager();
                        var pageLayoutMappingModel          = pageLayoutManager.LoadPageLayoutMappingFile(this.PageLayoutMapping);

                        // Using custom page layout mapping file + default one (they're merged together)
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, webPartMappingModel, pageLayoutMappingModel);
                    }
                    else
                    {
                        // Using default page layout mapping file
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, webPartMappingModel, null);
                    }
                }
                else
                {
                    // Use web part mapping model loaded from embedded mapping file
                    pageTransformator = new PageTransformator(this.ClientContext, targetContext, webPartMappingModel);
                }
            }

            // Setup logging
            if (this.LogType == ClientSidePageTransformatorLogType.File)
            {
                if (this.PublishingPage)
                {
                    publishingPageTransformator.RegisterObserver(new MarkdownObserver(folder: this.LogFolder, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
                else
                {
                    pageTransformator.RegisterObserver(new MarkdownObserver(folder: this.LogFolder, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
            }
            else if (this.LogType == ClientSidePageTransformatorLogType.SharePoint)
            {
                if (this.PublishingPage)
                {
                    publishingPageTransformator.RegisterObserver(new MarkdownToSharePointObserver(targetContext ?? this.ClientContext, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
                else
                {
                    pageTransformator.RegisterObserver(new MarkdownToSharePointObserver(targetContext ?? this.ClientContext, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
            }

            // Clear the client side component cache
            if (this.ClearCache)
            {
                CacheManager.Instance.ClearAllCaches();
            }

            string serverRelativeClientPageUrl = "";

            if (this.PublishingPage)
            {
                // Setup Transformation information
                PublishingPageTransformationInformation pti = new PublishingPageTransformationInformation(page)
                {
                    Overwrite = this.Overwrite,
                    KeepPageSpecificPermissions = !this.SkipItemLevelPermissionCopyToClientSidePage,
                    PublishCreatedPage          = !this.DontPublish,
                    DisablePageComments         = this.DisablePageComments,
                    TargetPageName = this.PublishingTargetPageName,
                    SkipUrlRewrite = this.SkipUrlRewriting,
                    UrlMappingFile = this.UrlMappingFile,
                };

                // Set mapping properties
                pti.MappingProperties["SummaryLinksToQuickLinks"] = (!SummaryLinksToHtml).ToString().ToLower();
                pti.MappingProperties["UseCommunityScriptEditor"] = UseCommunityScriptEditor.ToString().ToLower();

                serverRelativeClientPageUrl = publishingPageTransformator.Transform(pti);
            }
            else
            {
                Microsoft.SharePoint.Client.File fileToModernize = null;
                if (this.Folder != null && this.Folder.Equals(rootFolder, StringComparison.InvariantCultureIgnoreCase))
                {
                    // Load the page file from the site root folder
                    var webServerRelativeUrl = this.ClientContext.Web.EnsureProperty(p => p.ServerRelativeUrl);
                    fileToModernize = this.ClientContext.Web.GetFileByServerRelativeUrl($"{webServerRelativeUrl}/{this.Identity.Name}");
                    this.ClientContext.Load(fileToModernize);
                    this.ClientContext.ExecuteQueryRetry();
                }

                // Setup Transformation information
                PageTransformationInformation pti = new PageTransformationInformation(page)
                {
                    SourceFile = fileToModernize,
                    Overwrite  = this.Overwrite,
                    TargetPageTakesSourcePageName      = this.TakeSourcePageName,
                    ReplaceHomePageWithDefaultHomePage = this.ReplaceHomePageWithDefault,
                    KeepPageSpecificPermissions        = !this.SkipItemLevelPermissionCopyToClientSidePage,
                    CopyPageMetadata               = this.CopyPageMetadata,
                    PublishCreatedPage             = !this.DontPublish,
                    DisablePageComments            = this.DisablePageComments,
                    SkipUrlRewrite                 = this.SkipUrlRewriting,
                    UrlMappingFile                 = this.UrlMappingFile,
                    ModernizationCenterInformation = new ModernizationCenterInformation()
                    {
                        AddPageAcceptBanner = this.AddPageAcceptBanner
                    },
                };

                // Set mapping properties
                pti.MappingProperties["SummaryLinksToQuickLinks"] = (!SummaryLinksToHtml).ToString().ToLower();
                pti.MappingProperties["UseCommunityScriptEditor"] = UseCommunityScriptEditor.ToString().ToLower();

                serverRelativeClientPageUrl = pageTransformator.Transform(pti);
            }

            // Flush log
            if (this.LogType != ClientSidePageTransformatorLogType.None)
            {
                if (!this.LogSkipFlush)
                {
                    if (this.PublishingPage)
                    {
                        publishingPageTransformator.FlushObservers();
                    }
                    else
                    {
                        pageTransformator.FlushObservers();
                    }
                }
            }

            // Output the server relative url to the newly created page
            if (!string.IsNullOrEmpty(serverRelativeClientPageUrl))
            {
                WriteObject(serverRelativeClientPageUrl);
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Instantiates the content transformator
 /// </summary>
 /// <param name="page">Client side page that will be updates</param>
 /// <param name="pageTransformation">Transformation information</param>
 public ContentTransformator(ClientContext sourceClientContext, ClientSidePage page, PageTransformation pageTransformation, Dictionary <string, string> mappingProperties)
 {
     this.page = page ?? throw new ArgumentException("Page cannot be null");
     this.pageTransformation  = pageTransformation ?? throw new ArgumentException("pageTransformation cannot be null");
     this.globalTokens        = CreateGlobalTokenList(page.Context, mappingProperties);
     this.functionProcessor   = new FunctionProcessor(sourceClientContext, this.page, this.pageTransformation);
     this.sourceClientContext = sourceClientContext;
     this.isCrossSiteTransfer = IsCrossSiteTransfer();
 }
 /// <summary>
 /// Instantiates a web part page object for on-premises environments
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageFile">File holding the page (for pages living outside of a library)</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public WebPartPageOnPremises(ListItem page, File pageFile, PageTransformation pageTransformation, IList <ILogObserver> logObservers = null) : base(page, pageFile, pageTransformation, logObservers)
 {
 }
 /// <summary>
 /// Instantiates a publishing page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public PublishingPage(ListItem page, PageTransformation pageTransformation, PublishingPageTransformation publishingPageTransformation, IList <ILogObserver> logObservers = null) : base(page, pageTransformation, logObservers)
 {
     this.publishingPageTransformation = publishingPageTransformation;
     this.functionProcessor            = new PublishingFunctionProcessor(page, cc, null, this.publishingPageTransformation, base.RegisteredLogObservers);
 }
 /// <summary>
 /// Instantiates a publishing page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public PublishingPage(ListItem page, PageTransformation pageTransformation, IList <ILogObserver> logObservers = null) : base(page, pageTransformation, logObservers)
 {
     // no PublishingPageTransformation specified, fall back to default
     this.publishingPageTransformation = new PageLayoutManager(cc, base.RegisteredLogObservers).LoadDefaultPageLayoutMappingFile();
     this.functionProcessor            = new PublishingFunctionProcessor(page, cc, null, this.publishingPageTransformation, base.RegisteredLogObservers);
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Creates a page transformator instance
 /// </summary>
 /// <param name="sourceClientContext">ClientContext of the site holding the page</param>
 /// <param name="pageTransformationModel">Page transformation model</param>
 public DelvePageTransformator(ClientContext sourceClientContext, PageTransformation pageTransformationModel) : this(sourceClientContext, null, pageTransformationModel)
 {
 }
        public PublishingPageTransformator(ClientContext sourceClientContext, ClientContext targetClientContext, PageTransformation pageTransformationModel, PublishingPageTransformation customPublishingPageTransformationModel)
        {
#if DEBUG && MEASURE
            InitMeasurement();
#endif

            this.sourceClientContext = sourceClientContext ?? throw new ArgumentException("sourceClientContext must be provided.");
            this.targetClientContext = targetClientContext ?? throw new ArgumentException("targetClientContext must be provided.");;

            this.version           = GetVersion();
            this.pageTelemetry     = new PageTelemetry(version);
            this.pageLayoutManager = new PageLayoutManager(base.RegisteredLogObservers);

            this.pageTransformation = pageTransformationModel;

            // Load the page layout mapping data
            this.publishingPageTransformation = this.pageLayoutManager.LoadDefaultPageLayoutMappingFile();

            // Merge these custom layout mappings with the default ones
            if (customPublishingPageTransformationModel != null)
            {
                this.publishingPageTransformation = this.pageLayoutManager.MergePageLayoutMappingFiles(this.publishingPageTransformation, customPublishingPageTransformationModel);
            }
        }
        /// <summary>
        /// Instantiates the content transformator
        /// </summary>
        /// <param name="sourceClientContext"></param>
        /// <param name="targetClientContext"></param>
        /// <param name="page">Client side page that will be updates</param>
        /// <param name="pageTransformation">Transformation information</param>
        /// <param name="transformationInformation"></param>
        /// <param name="logObservers"></param>
        public ContentTransformator(ClientContext sourceClientContext, ClientContext targetClientContext, PnPCore.IPage page, PageTransformation pageTransformation, BaseTransformationInformation transformationInformation, IList <ILogObserver> logObservers = null) : base()
        {
            //Register any existing observers
            if (logObservers != null)
            {
                foreach (var observer in logObservers)
                {
                    base.RegisterObserver(observer);
                }
            }

            this.page = page ?? throw new ArgumentException("Page cannot be null");
            this.pageTransformation        = pageTransformation ?? throw new ArgumentException("pageTransformation cannot be null");
            this.globalTokens              = CreateGlobalTokenList(targetClientContext, transformationInformation.MappingProperties);
            this.functionProcessor         = new FunctionProcessor(sourceClientContext, targetClientContext, this.page, this.pageTransformation, transformationInformation, base.RegisteredLogObservers);
            this.transformationInformation = transformationInformation;

            this.sourceClientContext = sourceClientContext;
            this.targetClientContext = targetClientContext;
            this.isCrossSiteTransfer = IsCrossSiteTransfer();
        }
 /// <summary>
 /// Instantiates a publishing page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public PublishingPage(ListItem page, PageTransformation pageTransformation) : base(page, pageTransformation)
 {
 }
Ejemplo n.º 17
0
 public ContentTransformator(ClientSidePage page, PageTransformation pageTransformation)
 {
     this.page = page ?? throw new ArgumentException("Page cannot be null");
     this.pageTransformation = pageTransformation ?? throw new ArgumentException("pageTransformation cannot be null");
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Instantiates a web part page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public DelvePage(ListItem page, PageTransformation pageTransformation, IList <ILogObserver> logObservers = null) : base(page, null, pageTransformation, logObservers)
 {
 }
        /// <summary>
        /// Instantiates the function processor. Also loads the defined add-ons
        /// </summary>
        /// <param name="page">Client side page for which we're executing the functions/selectors as part of the mapping</param>
        /// <param name="pageTransformation">Webpart mapping information</param>
        public FunctionProcessor(ClientContext sourceClientContext, ClientSidePage page, PageTransformation pageTransformation)
        {
            this.page = page;
            this.pageTransformation = pageTransformation;

            // instantiate default built in functions class
            this.addOnTypes       = new List <AddOnType>();
            this.builtInFunctions = Activator.CreateInstance(typeof(BuiltIn), this.page.Context, sourceClientContext, this.page);

            // instantiate the custom function classes (if there are)
            foreach (var addOn in this.pageTransformation.AddOns)
            {
                try
                {
                    string path = "";
                    if (addOn.Assembly.Contains("\\") && System.IO.File.Exists(addOn.Assembly))
                    {
                        path = addOn.Assembly;
                    }
                    else
                    {
                        path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, addOn.Assembly);
                    }

                    var assembly   = Assembly.LoadFile(path);
                    var customType = assembly.GetType(addOn.Type);
                    var instance   = Activator.CreateInstance(customType, this.page.Context);

                    this.addOnTypes.Add(new AddOnType()
                    {
                        Name     = addOn.Name,
                        Assembly = assembly,
                        Instance = instance,
                        Type     = customType,
                    });
                }
                catch (Exception ex)
                {
                    // TODO: Add logging
                    throw;
                }
            }
        }
        /// <summary>
        /// Gets the web part information from the page
        /// </summary>
        /// <param name="item">Page list item</param>
        /// <param name="pageTransformation">PageTransformation model loaded from XML</param>
        /// <returns>Page layout + collection of web parts on the page</returns>
        public static Tuple <PageLayout, List <WebPartEntity> > WebParts(this ListItem item, PageTransformation pageTransformation)
        {
            string pageType = item.PageType();

            if (pageType.Equals("WikiPage", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new WikiPage(item, pageTransformation).Analyze());
            }
            else if (pageType.Equals("WebPartPage", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new WebPartPage(item, null, pageTransformation).Analyze());
            }
            else if (pageType.Equals("PublishingPage", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new PublishingPage(item, pageTransformation, null).Analyze(null));
            }

            return(null);
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Instantiates a web part page object for on-premises environments
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageFile">File holding the page (for pages living outside of a library)</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public WebPartPageOnPremises(ListItem page, File pageFile, PageTransformation pageTransformation) : base(page, pageFile, pageTransformation)
 {
 }
        /// <summary>
        /// Log publishing portal scan
        /// </summary>
        /// <param name="publishingSiteScanResults">Scanned publishing portals</param>
        /// <param name="publishingWebScanResults">Scanned publishing webs</param>
        /// <param name="publishingPageScanResults">Scanned publishing pages</param>
        /// <param name="pageTransformation">Page transformation data</param>
        public void LogPublishingScan(Dictionary <string, PublishingSiteScanResult> publishingSiteScanResults,
                                      ConcurrentDictionary <string, PublishingWebScanResult> publishingWebScanResults,
                                      ConcurrentDictionary <string, PublishingPageScanResult> publishingPageScanResults,
                                      PageTransformation pageTransformation)
        {
            if (this.telemetryClient == null)
            {
                return;
            }

            try
            {
                // Prepare event data
                Dictionary <string, string> properties = new Dictionary <string, string>();
                Dictionary <string, double> metrics    = new Dictionary <string, double>();

                // Populate properties

                // Page transformation engine version
                properties.Add(EngineVersion, this.version);
                properties.Add(PublishingResults.Sites.ToString(), publishingSiteScanResults.Count.ToString());
                properties.Add(PublishingResults.Webs.ToString(), publishingWebScanResults.Count.ToString());
                properties.Add(PublishingResults.Pages.ToString(), (publishingSiteScanResults != null ? publishingPageScanResults.Count : 0).ToString());
                // Azure AD tenant
                properties.Add(AADTenantId, this.aadTenantId.ToString());

                // Send the event
                this.telemetryClient.TrackEvent(TelemetryEvents.PublishingPortals.ToString(), properties, metrics);

                this.telemetryClient.GetMetric($"Publishing.{PublishingResults.Sites.ToString()}").TrackValue(publishingSiteScanResults.Count);
                this.telemetryClient.GetMetric($"Publishing.{PublishingResults.Webs.ToString()}").TrackValue(publishingWebScanResults.Count);
                this.telemetryClient.GetMetric($"Publishing.{PublishingResults.Pages.ToString()}").TrackValue(publishingSiteScanResults != null ? publishingPageScanResults.Count : 0);

                Metric siteLevel                     = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.SiteLevel.ToString()}", "Publishing.SiteLevel");
                Metric complexity                    = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.Complexity.ToString()}", "Publishing.Complexity");
                Metric webTemplates                  = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.WebTemplates.ToString()}", "Publishing.WebTemplates");
                Metric globalNavigation              = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.GlobalNavigation.ToString()}", "Publishing.GlobalNavigation");
                Metric currentNavigation             = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.CurrentNavigation.ToString()}", "Publishing.CurrentNavigation");
                Metric customSiteMasterPage          = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.CustomSiteMasterPage.ToString()}", "Publishing.CustomSiteMasterPage");
                Metric customSystemMasterPage        = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.CustomSystemMasterPage.ToString()}", "Publishing.CustomSystemMasterPage");
                Metric alternateCSS                  = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.AlternateCSS.ToString()}", "Publishing.AlternateCSS");
                Metric incompatibleUserCustomActions = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.IncompatibleUserCustomActions.ToString()}", "Publishing.IncompatibleUserCustomActions");
                Metric customPageLayouts             = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.CustomPageLayouts.ToString()}", "Publishing.CustomPageLayouts");
                Metric pageApproval                  = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.PageApproval.ToString()}", "Publishing.PageApproval");
                Metric pageApprovalWorkflow          = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.PageApprovalWorkflow.ToString()}", "Publishing.PageApprovalWorkflow");
                Metric scheduledPublishing           = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.ScheduledPublishing.ToString()}", "Publishing.ScheduledPublishing");
                Metric audienceTargeting             = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.AudienceTargeting.ToString()}", "Publishing.AudienceTargeting");
                Metric languages                     = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.Languages.ToString()}", "Publishing.Languages");
                Metric variationLabels               = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.VariationLabels.ToString()}", "Publishing.VariationLabels");
                Metric webPartMapping                = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.WebPartMapping.ToString()}", "Publishing.WebPartMapping");
                Metric unMappedWebParts              = this.telemetryClient.GetMetric($"Publishing.{PublishingResults.UnMappedWebParts.ToString()}", "Publishing.UnMappedWebParts");


                // The metrics automatically aggregate and only send once a minute to app insights...so this approach does not result in extra traffic
                foreach (var item in publishingWebScanResults)
                {
                    WriteMetric(siteLevel, item.Value.Level);
                    WriteMetric(complexity, item.Value.WebClassification.ToString());
                    WriteMetric(webTemplates, item.Value.WebTemplate);
                    WriteMetric(globalNavigation, item.Value.GlobalNavigationType);
                    WriteMetric(currentNavigation, item.Value.CurrentNavigationType);
                    WriteMetric(customSiteMasterPage, string.IsNullOrEmpty(item.Value.SiteMasterPage) ? true.ToString() : false.ToString());
                    WriteMetric(customSystemMasterPage, string.IsNullOrEmpty(item.Value.SystemMasterPage) ? true.ToString() : false.ToString());
                    WriteMetric(alternateCSS, string.IsNullOrEmpty(item.Value.AlternateCSS) ? true.ToString() : false.ToString());
                    WriteMetric(incompatibleUserCustomActions, item.Value.UserCustomActions);
                    WriteMetric(pageApproval, item.Value.LibraryEnableModeration);
                    WriteMetric(pageApprovalWorkflow, item.Value.LibraryApprovalWorkflowDefined);
                    WriteMetric(scheduledPublishing, item.Value.LibraryItemScheduling);
                    WriteMetric(languages, item.Value.Language);
                    WriteMetric(variationLabels, item.Value.VariationSourceLabel);
                }

                if (publishingSiteScanResults != null)
                {
                    foreach (var item in publishingPageScanResults)
                    {
                        WriteMetric(customPageLayouts, item.Value.PageLayoutWasCustomized);
                        WriteMetric(audienceTargeting, (item.Value.SecurityGroupAudiences != null && item.Value.SecurityGroupAudiences.Count > 0) ||
                                    (item.Value.SharePointGroupAudiences != null && item.Value.SharePointGroupAudiences.Count > 0) ||
                                    (item.Value.GlobalAudiences != null && item.Value.GlobalAudiences.Count > 0));

                        if (item.Value.WebParts != null)
                        {
                            int           webPartsOnPage       = item.Value.WebParts.Count();
                            int           webPartsOnPageMapped = 0;
                            List <string> nonMappedWebParts    = new List <string>();
                            foreach (var webPart in item.Value.WebParts.OrderBy(p => p.Row).ThenBy(p => p.Column).ThenBy(p => p.Order))
                            {
                                var found = pageTransformation.WebParts.Where(p => p.Type.Equals(webPart.Type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                                if (found != null && found.Mappings != null)
                                {
                                    webPartsOnPageMapped++;
                                }
                                else
                                {
                                    var t = webPart.Type.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0];
                                    if (!nonMappedWebParts.Contains(t))
                                    {
                                        nonMappedWebParts.Add(t);
                                    }
                                }
                            }

                            WriteMetric(webPartMapping, String.Format("{0:0}", (((double)webPartsOnPageMapped / (double)webPartsOnPage) * 100)));
                            foreach (var w in nonMappedWebParts)
                            {
                                WriteMetric(unMappedWebParts, w);
                            }
                        }
                    }
                }
            }
            catch
            {
                // Eat all exceptions
            }
            finally
            {
                this.telemetryClient.Flush();
            }
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Creates a page transformator instance
 /// </summary>
 /// <param name="clientContext">ClientContext of the site holding the page</param>
 /// <param name="pageTransformationModel">Page transformation model</param>
 public PageTransformator(ClientContext clientContext, PageTransformation pageTransformationModel)
 {
     this.clientContext      = clientContext;
     this.pageTransformation = pageTransformationModel;
 }
 public TestBasePage(ListItem item, File file, PageTransformation pt, IList <ILogObserver> logObservers) : base(item, file, pt, logObservers)
 {
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Instantiates a publishing page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public PublishingPageOnPremises(ListItem page, PageTransformation pageTransformation, BaseTransformationInformation baseTransformationInformation, IList <ILogObserver> logObservers = null) : base(page, pageTransformation, baseTransformationInformation, logObservers)
 {
 }
        /// <summary>
        /// Grab the number of sites that need to be scanned...will be needed to show progress when we're having a long run
        /// </summary>
        /// <param name="addedSites">List of sites found to scan</param>
        /// <returns>Updated list of sites to scan</returns>
        public override List <string> ResolveAddedSites(List <string> addedSites)
        {
            var sites = base.ResolveAddedSites(addedSites);

            this.SitesToScan = sites.Count;

            //Perform global initialization tasks, things you only want to do once per run
            if (sites.Count > 0)
            {
                try
                {
                    using (ClientContext cc = this.CreateClientContext(sites[0]))
                    {
                        // The everyone except external users claim is different per tenant, so grab the correct value
                        this.EveryoneExceptExternalUsersClaim = cc.Web.GetEveryoneExceptExternalUsersClaim();
                    }
                }
                catch (Exception)
                {
                    // Catch exceptions here, typical case is if the used site collection was locked. Do one more try with the root site
                    var uri = new Uri(sites[0]);
                    using (ClientContext cc = this.CreateClientContext($"{uri.Scheme}://{uri.DnsSafeHost}/"))
                    {
                        // The everyone except external users claim is different per tenant, so grab the correct value
                        this.EveryoneExceptExternalUsersClaim = cc.Web.GetEveryoneExceptExternalUsersClaim();
                    }
                }
            }

            // Setup tenant context
            string tenantAdmin = "";

            if (!string.IsNullOrEmpty(this.TenantAdminSite))
            {
                tenantAdmin = this.TenantAdminSite;
            }
            else
            {
                if (string.IsNullOrEmpty(this.Tenant))
                {
                    this.Tenant = new Uri(addedSites[0]).DnsSafeHost.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[0];
                }

                tenantAdmin = $"https://{this.Tenant}-admin.sharepoint.com";
            }

            this.Realm = GetRealmFromTargetUrl(new Uri(tenantAdmin));
            using (ClientContext ccAdmin = this.CreateClientContext(tenantAdmin))
            {
                this.SPOTenant = new Tenant(ccAdmin);
            }

            // Load xml mapping data
            XmlSerializer xmlMapping = new XmlSerializer(typeof(PageTransformation));

            using (var stream = new FileStream("webpartmapping.xml", FileMode.Open))
            {
                this.PageTransformation = (PageTransformation)xmlMapping.Deserialize(stream);
            }

            return(sites);
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Instantiates a publishing page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public PublishingPageOnPremises(ListItem page, PageTransformation pageTransformation, PublishingPageTransformation publishingPageTransformation, BaseTransformationInformation baseTransformationInformation, ClientContext targetContext = null, IList <ILogObserver> logObservers = null) : base(page, pageTransformation, publishingPageTransformation, baseTransformationInformation, targetContext, logObservers)
 {
 }
Ejemplo n.º 28
0
        protected override void ExecuteCmdlet()
        {
            //Fix loading of modernization framework
            FixLocalAssemblyResolving();

            // Load the page to transform
            Identity.Library       = this.Library;
            Identity.Folder        = this.Folder;
            Identity.BlogPage      = this.BlogPage;
            Identity.DelveBlogPage = this.DelveBlogPage;

            if ((this.PublishingPage && this.BlogPage) ||
                (this.PublishingPage && this.DelveBlogPage) ||
                (this.BlogPage && this.DelveBlogPage))
            {
                throw new Exception($"The page is either a blog page, a publishing page or a Delve blog page. Setting PublishingPage, BlogPage and DelveBlogPage to true is not valid.");
            }

            ListItem page = null;

            if (this.PublishingPage)
            {
                page = Identity.GetPage(this.ClientContext.Web, CacheManager.Instance.GetPublishingPagesLibraryName(this.ClientContext));
            }
            else if (this.BlogPage)
            {
                // Blogs don't live in other libraries or sub folders
                Identity.Library = null;
                Identity.Folder  = null;
                page             = Identity.GetPage(this.ClientContext.Web, CacheManager.Instance.GetBlogListName(this.ClientContext));
            }
            else if (this.DelveBlogPage)
            {
                // Blogs don't live in other libraries or sub folders
                Identity.Library = null;
                Identity.Folder  = null;
                page             = Identity.GetPage(this.ClientContext.Web, "pPg");
            }
            else
            {
                if (this.Folder == null || !this.Folder.Equals(rootFolder, StringComparison.InvariantCultureIgnoreCase))
                {
                    page = Identity.GetPage(this.ClientContext.Web, "sitepages");
                }
            }

            if (page == null && (Folder == null || !this.Folder.Equals(rootFolder, StringComparison.InvariantCultureIgnoreCase)))
            {
                throw new Exception($"Page '{Identity?.Name}' does not exist");
            }

            // Publishing specific validation
            if (this.PublishingPage && string.IsNullOrEmpty(this.TargetWebUrl) && TargetConnection == null)
            {
                throw new Exception($"Publishing page transformation is only supported when transformating into another site collection. Use the -TargetWebUrl to specify a modern target site.");
            }

            // Blog specific validation
            if ((this.BlogPage || this.DelveBlogPage) && string.IsNullOrEmpty(this.TargetWebUrl) && TargetConnection == null)
            {
                throw new Exception($"Blog and Delve blog page transformation is only supported when transformating into another site collection. Use the -TargetWebUrl to specify a modern target site.");
            }

            // Load transformation models
            PageTransformation webPartMappingModel = null;

            if (string.IsNullOrEmpty(this.WebPartMappingFile))
            {
                webPartMappingModel = PageTransformator.LoadDefaultWebPartMapping();
                this.WriteVerbose("Using embedded webpartmapping file. Use Export-PnPClientSidePageMapping to get that file in case you want to base your version of the embedded version.");
            }

            // Validate webpartmappingfile
            if (!string.IsNullOrEmpty(this.WebPartMappingFile))
            {
                if (!System.IO.File.Exists(this.WebPartMappingFile))
                {
                    throw new Exception($"Provided webpartmapping file {this.WebPartMappingFile} does not exist");
                }
            }

            if (this.PublishingPage && !string.IsNullOrEmpty(this.PageLayoutMapping) && !System.IO.File.Exists(this.PageLayoutMapping))
            {
                throw new Exception($"Provided pagelayout mapping file {this.PageLayoutMapping} does not exist");
            }

            bool crossSiteTransformation = TargetConnection != null || !string.IsNullOrEmpty(TargetWebUrl);

            // Create target client context (when needed)
            ClientContext targetContext = null;

            if (TargetConnection == null)
            {
                if (!string.IsNullOrEmpty(TargetWebUrl))
                {
                    targetContext = this.ClientContext.Clone(TargetWebUrl);
                }
            }
            else
            {
                targetContext = TargetConnection.Context;
            }


            // Create transformator instance
            PageTransformator           pageTransformator           = null;
            PublishingPageTransformator publishingPageTransformator = null;

            if (!string.IsNullOrEmpty(this.WebPartMappingFile))
            {
                // Using custom web part mapping file
                if (this.PublishingPage)
                {
                    if (!string.IsNullOrEmpty(this.PageLayoutMapping))
                    {
                        // Using custom page layout mapping file + default one (they're merged together)
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, this.WebPartMappingFile, this.PageLayoutMapping);
                    }
                    else
                    {
                        // Using default page layout mapping file
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, this.WebPartMappingFile, null);
                    }
                }
                else
                {
                    // Use web part mapping file
                    pageTransformator = new PageTransformator(this.ClientContext, targetContext, this.WebPartMappingFile);
                }
            }
            else
            {
                // Using default web part mapping file
                if (this.PublishingPage)
                {
                    if (!string.IsNullOrEmpty(this.PageLayoutMapping))
                    {
                        // Load and validate the custom mapping file
                        PageLayoutManager pageLayoutManager = new PageLayoutManager();
                        var pageLayoutMappingModel          = pageLayoutManager.LoadPageLayoutMappingFile(this.PageLayoutMapping);

                        // Using custom page layout mapping file + default one (they're merged together)
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, webPartMappingModel, pageLayoutMappingModel);
                    }
                    else
                    {
                        // Using default page layout mapping file
                        publishingPageTransformator = new PublishingPageTransformator(this.ClientContext, targetContext, webPartMappingModel, null);
                    }
                }
                else
                {
                    // Use web part mapping model loaded from embedded mapping file
                    pageTransformator = new PageTransformator(this.ClientContext, targetContext, webPartMappingModel);
                }
            }

            // Setup logging
            if (this.LogType == PageTransformatorLogType.File)
            {
                if (this.PublishingPage)
                {
                    publishingPageTransformator.RegisterObserver(new MarkdownObserver(folder: this.LogFolder, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
                else
                {
                    pageTransformator.RegisterObserver(new MarkdownObserver(folder: this.LogFolder, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
            }
            else if (this.LogType == PageTransformatorLogType.SharePoint)
            {
                if (this.PublishingPage)
                {
                    publishingPageTransformator.RegisterObserver(new MarkdownToSharePointObserver(targetContext ?? this.ClientContext, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
                else
                {
                    pageTransformator.RegisterObserver(new MarkdownToSharePointObserver(targetContext ?? this.ClientContext, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
                }
            }
            else if (this.LogType == PageTransformatorLogType.Console)
            {
                if (this.PublishingPage)
                {
                    publishingPageTransformator.RegisterObserver(new ConsoleObserver(includeDebugEntries: this.LogVerbose));
                }
                else
                {
                    pageTransformator.RegisterObserver(new ConsoleObserver(includeDebugEntries: this.LogVerbose));
                }
            }

            // Clear the client side component cache
            if (this.ClearCache)
            {
                CacheManager.Instance.ClearAllCaches();
            }

            string serverRelativeClientPageUrl = "";

            if (this.PublishingPage)
            {
                // Setup Transformation information
                PublishingPageTransformationInformation pti = new PublishingPageTransformationInformation(page)
                {
                    Overwrite = this.Overwrite,
                    KeepPageSpecificPermissions             = !this.SkipItemLevelPermissionCopyToClientSidePage,
                    PublishCreatedPage                      = !this.DontPublish,
                    KeepPageCreationModificationInformation = this.KeepPageCreationModificationInformation,
                    PostAsNews                             = this.PostAsNews,
                    DisablePageComments                    = this.DisablePageComments,
                    TargetPageName                         = !string.IsNullOrEmpty(this.PublishingTargetPageName) ? this.PublishingTargetPageName : this.TargetPageName,
                    SkipUrlRewrite                         = this.SkipUrlRewriting,
                    SkipDefaultUrlRewrite                  = this.SkipDefaultUrlRewriting,
                    UrlMappingFile                         = this.UrlMappingFile,
                    AddTableListImageAsImageWebPart        = this.AddTableListImageAsImageWebPart,
                    SkipUserMapping                        = this.SkipUserMapping,
                    UserMappingFile                        = this.UserMappingFile,
                    LDAPConnectionString                   = this.LDAPConnectionString,
                    TargetPageFolder                       = this.TargetPageFolder,
                    TargetPageFolderOverridesDefaultFolder = this.TargetPageFolderOverridesDefaultFolder,
                    TermMappingFile                        = TermMappingFile,
                    SkipTermStoreMapping                   = SkipTermStoreMapping,
                    RemoveEmptySectionsAndColumns          = this.RemoveEmptySectionsAndColumns,
                    SkipHiddenWebParts                     = this.SkipHiddenWebParts,
                };

                // Set mapping properties
                pti.MappingProperties["SummaryLinksToQuickLinks"] = (!SummaryLinksToHtml).ToString().ToLower();
                pti.MappingProperties["UseCommunityScriptEditor"] = UseCommunityScriptEditor.ToString().ToLower();

                try
                {
                    serverRelativeClientPageUrl = publishingPageTransformator.Transform(pti);
                }
                finally
                {
                    // Flush log
                    if (this.LogType != PageTransformatorLogType.None && this.LogType != PageTransformatorLogType.Console && !this.LogSkipFlush)
                    {
                        publishingPageTransformator.FlushObservers();
                    }
                }
            }
            else
            {
                Microsoft.SharePoint.Client.File fileToModernize = null;
                if (this.Folder != null && this.Folder.Equals(rootFolder, StringComparison.InvariantCultureIgnoreCase))
                {
                    // Load the page file from the site root folder
                    var webServerRelativeUrl = this.ClientContext.Web.EnsureProperty(p => p.ServerRelativeUrl);
                    fileToModernize = this.ClientContext.Web.GetFileByServerRelativeUrl($"{webServerRelativeUrl}/{this.Identity.Name}");
                    this.ClientContext.Load(fileToModernize);
                    this.ClientContext.ExecuteQueryRetry();
                }

                // Setup Transformation information
                PageTransformationInformation pti = new PageTransformationInformation(page)
                {
                    SourceFile = fileToModernize,
                    Overwrite  = this.Overwrite,
                    TargetPageTakesSourcePageName      = this.TakeSourcePageName,
                    ReplaceHomePageWithDefaultHomePage = this.ReplaceHomePageWithDefault,
                    KeepPageSpecificPermissions        = !this.SkipItemLevelPermissionCopyToClientSidePage,
                    CopyPageMetadata   = this.CopyPageMetadata,
                    PublishCreatedPage = !this.DontPublish,
                    KeepPageCreationModificationInformation = this.KeepPageCreationModificationInformation,
                    SetAuthorInPageHeader                  = this.SetAuthorInPageHeader,
                    PostAsNews                             = this.PostAsNews,
                    DisablePageComments                    = this.DisablePageComments,
                    TargetPageName                         = crossSiteTransformation ? this.TargetPageName : "",
                    SkipUrlRewrite                         = this.SkipUrlRewriting,
                    SkipDefaultUrlRewrite                  = this.SkipDefaultUrlRewriting,
                    UrlMappingFile                         = this.UrlMappingFile,
                    AddTableListImageAsImageWebPart        = this.AddTableListImageAsImageWebPart,
                    SkipUserMapping                        = this.SkipUserMapping,
                    UserMappingFile                        = this.UserMappingFile,
                    LDAPConnectionString                   = this.LDAPConnectionString,
                    TargetPageFolder                       = this.TargetPageFolder,
                    TargetPageFolderOverridesDefaultFolder = this.TargetPageFolderOverridesDefaultFolder,
                    ModernizationCenterInformation         = new ModernizationCenterInformation()
                    {
                        AddPageAcceptBanner = this.AddPageAcceptBanner
                    },
                    TermMappingFile               = TermMappingFile,
                    SkipTermStoreMapping          = SkipTermStoreMapping,
                    RemoveEmptySectionsAndColumns = this.RemoveEmptySectionsAndColumns,
                    SkipHiddenWebParts            = this.SkipHiddenWebParts,
                };

                // Set mapping properties
                pti.MappingProperties["SummaryLinksToQuickLinks"] = (!SummaryLinksToHtml).ToString().ToLower();
                pti.MappingProperties["UseCommunityScriptEditor"] = UseCommunityScriptEditor.ToString().ToLower();

                try
                {
                    serverRelativeClientPageUrl = pageTransformator.Transform(pti);
                }
                finally
                {
                    // Flush log
                    if (this.LogType != PageTransformatorLogType.None && this.LogType != PageTransformatorLogType.Console && !this.LogSkipFlush)
                    {
                        pageTransformator.FlushObservers();
                    }
                }
            }

            // Output the server relative url to the newly created page
            if (!string.IsNullOrEmpty(serverRelativeClientPageUrl))
            {
                WriteObject(serverRelativeClientPageUrl);
            }
        }
 /// <summary>
 /// Instantiates a publishing page object
 /// </summary>
 /// <param name="page">ListItem holding the page to analyze</param>
 /// <param name="pageTransformation">Page transformation information</param>
 public PublishingPage(ListItem page, PageTransformation pageTransformation, PublishingPageTransformation publishingPageTransformation, BaseTransformationInformation baseTransformationInformation, ClientContext targetContext = null, IList <ILogObserver> logObservers = null) : base(page, pageTransformation, logObservers)
 {
     this.publishingPageTransformation = publishingPageTransformation;
     this.functionProcessor            = new PublishingFunctionProcessor(page, cc, targetContext, this.publishingPageTransformation, baseTransformationInformation, base.RegisteredLogObservers);
 }