/// <summary> /// Analyses a page /// </summary> /// <param name="cc">ClientContext instance used to retrieve page data</param> /// <returns>Duration of the page analysis</returns> public override TimeSpan Analyze(ClientContext cc) { try { base.Analyze(cc); Web web = cc.Web; cc.Web.EnsureProperties(p => p.WebTemplate, p => p.Configuration, p => p.Features); var homePageUrl = web.WelcomePage; if (string.IsNullOrEmpty(homePageUrl)) { // Will be case when the site home page is a web part page homePageUrl = "default.aspx"; } var listsToScan = web.GetListsToScan(); var sitePagesLibraries = listsToScan.Where(p => p.BaseTemplate == (int)ListTemplateType.WebPageLibrary); if (sitePagesLibraries.Count() > 0) { foreach (var sitePagesLibrary in sitePagesLibraries) { CamlQuery query = new CamlQuery { ViewXml = CAMLQueryByExtension }; var pages = sitePagesLibrary.GetItems(query); web.Context.Load(pages); web.Context.ExecuteQueryRetry(); if (pages.FirstOrDefault() != null) { DateTime start; bool forceCheckout = sitePagesLibrary.ForceCheckout; foreach (var page in pages) { string pageUrl = null; try { if (page.FieldValues.ContainsKey(Field_FileRefField) && !String.IsNullOrEmpty(page[Field_FileRefField].ToString())) { pageUrl = page[Field_FileRefField].ToString(); } else { //skip page continue; } start = DateTime.Now; PageScanResult pageResult = new PageScanResult() { SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, PageUrl = pageUrl, Library = sitePagesLibrary.RootFolder.ServerRelativeUrl, }; // Is this page the web's home page? if (pageUrl.EndsWith(homePageUrl, StringComparison.InvariantCultureIgnoreCase)) { pageResult.HomePage = true; } // Get the type of the page pageResult.PageType = page.PageType(); // Get page web parts var pageAnalysis = page.WebParts(this.ScanJob.PageTransformation); if (pageAnalysis != null) { pageResult.Layout = pageAnalysis.Item1.ToString().Replace("Wiki_", "").Replace("WebPart_", ""); pageResult.WebParts = pageAnalysis.Item2; } // Determine if this site contains a default "uncustomized" home page bool isUncustomizedHomePage = false; try { string pageName = ""; if (page.FieldValues.ContainsKey(Field_FileLeafRef) && !String.IsNullOrEmpty(page[Field_FileLeafRef].ToString())) { pageName = page[Field_FileLeafRef].ToString(); } if (pageResult.HomePage && web.WebTemplate == "STS" && web.Configuration == 0 && pageName.Equals("home.aspx", StringComparison.InvariantCultureIgnoreCase)) { bool homePageModernizationOptedOut = web.Features.Where(f => f.DefinitionId == FeatureId_Web_HomePage).Count() > 0; if (!homePageModernizationOptedOut) { bool siteWasGroupified = web.Features.Where(f => f.DefinitionId == FeatureId_Web_GroupHomepage).Count() > 0; if (!siteWasGroupified) { var wiki = page.FieldValues[Field_WikiField].ToString(); if (!string.IsNullOrEmpty(wiki)) { var isHtmlUncustomized = IsHtmlUncustomized(wiki); if (isHtmlUncustomized) { string pageType = GetPageWebPartInfo(pageResult.WebParts); if (pageType == TeamSiteDefaultWebParts) { page.ContentType.EnsureProperty(p => p.DisplayFormTemplateName); if (page.ContentType.DisplayFormTemplateName == "WikiEditForm") { isUncustomizedHomePage = true; } } } } } } } } catch (Exception ex) { // no point in failing the scan if something goes wrong here } finally { pageResult.UncustomizedHomePage = isUncustomizedHomePage; } // Get page change information pageResult.ModifiedAt = page.LastModifiedDateTime(); pageResult.ModifiedBy = page.LastModifiedBy(); // Grab this page from the search results to connect view information string fullPageUrl = $"https://{new Uri(this.SiteCollectionUrl).DnsSafeHost}{pageUrl}"; if (pageResult.HomePage) { fullPageUrl = this.SiteUrl; } if (!this.ScanJob.SkipUsageInformation && this.pageSearchResults != null) { var searchPage = this.pageSearchResults.Where(x => x.Values.Contains(fullPageUrl)).FirstOrDefault(); if (searchPage != null) { // Recent = last 14 days pageResult.ViewsRecent = searchPage["ViewsRecent"].ToInt32(); pageResult.ViewsRecentUniqueUsers = searchPage["ViewsRecentUniqueUsers"].ToInt32(); pageResult.ViewsLifeTime = searchPage["ViewsLifeTime"].ToInt32(); pageResult.ViewsLifeTimeUniqueUsers = searchPage["ViewsLifeTimeUniqueUsers"].ToInt32(); } } if (!this.ScanJob.PageScanResults.TryAdd(pageResult.PageUrl, pageResult)) { ScanError error = new ScanError() { Error = $"Could not add page scan result for {pageResult.PageUrl}", SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, Field1 = "PageAnalyzer", }; this.ScanJob.ScanErrors.Push(error); } var duration = new TimeSpan((DateTime.Now.Subtract(start).Ticks)); Console.WriteLine($"Scan of page {pageUrl} took {duration.Seconds} seconds"); } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, Field1 = "MainPageAnalyzerLoop", Field2 = ex.StackTrace, Field3 = pageUrl }; // Send error to telemetry to make scanner better if (this.ScanJob.ScannerTelemetry != null) { this.ScanJob.ScannerTelemetry.LogScanError(ex, error); } this.ScanJob.ScanErrors.Push(error); Console.WriteLine("Error for page {1}: {0}", ex.Message, pageUrl); } } } } } } finally { this.StopTime = DateTime.Now; } // return the duration of this scan return(new TimeSpan((this.StopTime.Subtract(this.StartTime).Ticks))); }
/// <summary> /// Analyses a page /// </summary> /// <param name="cc">ClientContext instance used to retrieve page data</param> /// <returns>Duration of the page analysis</returns> public override TimeSpan Analyze(ClientContext cc) { try { base.Analyze(cc); Web web = cc.Web; cc.Web.EnsureProperties(p => p.WebTemplate, p => p.Configuration, p => p.RootFolder); var homePageUrl = web.RootFolder.WelcomePage; var listsToScan = web.GetListsToScan(); var sitePagesLibraries = listsToScan.Where(p => p.BaseTemplate == (int)ListTemplateType.WebPageLibrary); if (sitePagesLibraries.Count() > 0) { foreach (var sitePagesLibrary in sitePagesLibraries) { CamlQuery query = new CamlQuery { ViewXml = CAMLQueryByExtension }; var pages = sitePagesLibrary.GetItems(query); web.Context.Load(pages); web.Context.ExecuteQueryRetry(); if (pages.FirstOrDefault() != null) { DateTime start; bool forceCheckout = sitePagesLibrary.ForceCheckout; foreach (var page in pages) { string pageUrl = null; try { if (page.FieldValues.ContainsKey(FileRefField) && !String.IsNullOrEmpty(page[FileRefField].ToString())) { pageUrl = page[FileRefField].ToString(); } else { //skip page continue; } start = DateTime.Now; PageScanResult pageResult = new PageScanResult() { SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, PageUrl = pageUrl, Library = sitePagesLibrary.RootFolder.ServerRelativeUrl, }; // Is this page the web's home page? if (pageUrl.EndsWith(homePageUrl, StringComparison.InvariantCultureIgnoreCase)) { pageResult.HomePage = true; } // Get the type of the page pageResult.PageType = page.PageType(); // Get page web parts var pageAnalysis = page.WebParts(this.ScanJob.PageTransformation); if (pageAnalysis != null) { pageResult.Layout = pageAnalysis.Item1.ToString().Replace("Wiki_", "").Replace("WebPart_", ""); pageResult.WebParts = pageAnalysis.Item2; } // Get page change information pageResult.ModifiedAt = page.LastModifiedDateTime(); pageResult.ModifiedBy = page.LastModifiedBy(); // Grab this page from the search results to connect view information string fullPageUrl = $"https://{new Uri(this.SiteCollectionUrl).DnsSafeHost}{pageUrl}"; if (pageResult.HomePage) { fullPageUrl = this.SiteUrl; } var searchPage = this.pageSearchResults.Where(x => x.Values.Contains(fullPageUrl)).FirstOrDefault(); if (searchPage != null) { // Recent = last 14 days pageResult.ViewsRecent = searchPage["ViewsRecent"].ToInt32(); pageResult.ViewsRecentUniqueUsers = searchPage["ViewsRecentUniqueUsers"].ToInt32(); pageResult.ViewsLifeTime = searchPage["ViewsLifeTime"].ToInt32(); pageResult.ViewsLifeTimeUniqueUsers = searchPage["ViewsLifeTimeUniqueUsers"].ToInt32(); } if (!this.ScanJob.PageScanResults.TryAdd(pageResult.PageUrl, pageResult)) { ScanError error = new ScanError() { Error = $"Could not add page scan result for {pageResult.PageUrl}", SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, Field1 = "PageAnalyzer", }; this.ScanJob.ScanErrors.Push(error); } var duration = new TimeSpan((DateTime.Now.Subtract(start).Ticks)); Console.WriteLine($"Scan of page {pageUrl} took {duration.Seconds} seconds"); } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, Field1 = "MainPageAnalyzerLoop", Field2 = ex.StackTrace, Field3 = pageUrl }; this.ScanJob.ScanErrors.Push(error); Console.WriteLine("Error for page {1}: {0}", ex.Message, pageUrl); } } } } } } finally { this.StopTime = DateTime.Now; } // return the duration of this scan return(new TimeSpan((this.StopTime.Subtract(this.StartTime).Ticks))); }
/// <summary> /// Analyses a page /// </summary> /// <param name="cc">ClientContext instance used to retrieve page data</param> /// <returns>Duration of the page analysis</returns> public override TimeSpan Analyze(ClientContext cc) { try { base.Analyze(cc); Site site = cc.Site; site.EnsureProperties(p => p.Features); Web web = cc.Web; cc.Web.EnsureProperties(p => p.WebTemplate, p => p.Configuration, p => p.Features, p => p.Language, p => p.CustomMasterUrl, p => p.MasterUrl); var homePageUrl = web.WelcomePage; if (string.IsNullOrEmpty(homePageUrl)) { // Will be case when the site home page is a web part page homePageUrl = "default.aspx"; } var listsToScan = web.GetListsToScan(); var sitePagesLibraries = listsToScan.Where(p => p.BaseTemplate == (int)ListTemplateType.WebPageLibrary); if (sitePagesLibraries.Count() > 0) { foreach (var sitePagesLibrary in sitePagesLibraries) { CamlQuery query = new CamlQuery { ViewXml = CAMLQueryByExtension }; var pages = sitePagesLibrary.GetItems(query); web.Context.Load(pages); web.Context.ExecuteQueryRetry(); if (pages.FirstOrDefault() != null) { DateTime start; bool forceCheckout = sitePagesLibrary.ForceCheckout; foreach (var page in pages) { string pageUrl = null; try { if (page.FieldValues.ContainsKey(Field_FileRefField) && !String.IsNullOrEmpty(page[Field_FileRefField].ToString())) { pageUrl = page[Field_FileRefField].ToString(); // In home page only mode we only continue if this page is the site's home page if (Options.IsHomePageOnly(this.ScanJob.Mode) && !pageUrl.EndsWith(homePageUrl, StringComparison.InvariantCultureIgnoreCase)) { continue; } } else { //skip page continue; } start = DateTime.Now; PageScanResult pageResult = new PageScanResult() { SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, PageUrl = pageUrl, Library = sitePagesLibrary.RootFolder.ServerRelativeUrl, }; // Is this page the web's home page? if (pageUrl.EndsWith(homePageUrl, StringComparison.InvariantCultureIgnoreCase)) { pageResult.HomePage = true; } // Get the type of the page pageResult.PageType = page.PageType(); // Get page web parts var pageAnalysis = page.WebParts(this.ScanJob.PageTransformation); if (pageAnalysis != null) { pageResult.Layout = pageAnalysis.Item1.ToString().Replace("Wiki_", "").Replace("WebPart_", ""); pageResult.WebParts = pageAnalysis.Item2; } // Determine if this site contains a default "uncustomized" home page bool isUncustomizedHomePage = false; bool canModernizeHomePageWorked = false; try { var canModernizeHomepage = web.CanModernizeHomepage; web.Context.Load(canModernizeHomepage); web.Context.ExecuteQueryRetry(); isUncustomizedHomePage = canModernizeHomepage.CanModernizeHomepage; canModernizeHomePageWorked = true; pageResult.UncustomizedHomePage = isUncustomizedHomePage; } catch (Exception ex) { } // If for some reason the API did not work, then let's fall back to the old approach if (!canModernizeHomePageWorked) { try { string pageName = ""; if (page.FieldValues.ContainsKey(Field_FileLeafRef) && !String.IsNullOrEmpty(page[Field_FileLeafRef].ToString())) { pageName = page[Field_FileLeafRef].ToString(); } if (pageResult.HomePage && web.WebTemplate == "STS" && web.Configuration == 0) { bool publishingWebFeatureEnabled = web.Features.Where(f => f.DefinitionId == WebAnalyzer.FeatureId_Web_Publishing).Count() > 0; bool publishingSiteFeatureEnabled = site.Features.Where(f => f.DefinitionId == SiteAnalyzer.FeatureId_Site_Publishing).Count() > 0; bool homePageModernizationOptedOut = web.Features.Where(f => f.DefinitionId == FeatureId_Web_HomePage).Count() > 0; if (!homePageModernizationOptedOut && !publishingSiteFeatureEnabled && !publishingWebFeatureEnabled) { bool siteWasGroupified = web.Features.Where(f => f.DefinitionId == FeatureId_Web_GroupHomepage).Count() > 0; if (!siteWasGroupified) { // Check for master page url if (web.MasterUrl.EndsWith("_catalogs/masterpage/seattle.master", StringComparison.InvariantCultureIgnoreCase)) { // Check for home page name, only "default sts#0 home pages" should be considered, so // home.aspx or the translated versions var homePageName = this.ScanJob.Store.Get <string>(this.ScanJob.StoreOptions.GetKey(keyWikiHomePageName)); if (homePageName == null) { ClientResult <string> result = Microsoft.SharePoint.Client.Utilities.Utility.GetLocalizedString(web.Context, "$Resources:WikiPageHomePageName", "core", (int)web.Language); web.Context.ExecuteQueryRetry(); homePageName = $"{new Regex(@"['´`]").Replace(result.Value, "")}.aspx"; this.ScanJob.Store.Set <string>(this.ScanJob.StoreOptions.GetKey(keyWikiHomePageName), homePageName, this.ScanJob.StoreOptions.EntryOptions); } if (pageName.Equals(homePageName, StringComparison.InvariantCultureIgnoreCase)) { var wiki = page.FieldValues[Field_WikiField].ToString(); if (!string.IsNullOrEmpty(wiki)) { var isHtmlUncustomized = IsHtmlUncustomized(wiki); if (isHtmlUncustomized) { string pageType = GetPageWebPartInfo(pageResult.WebParts); if (pageType == TeamSiteDefaultWebParts) { page.ContentType.EnsureProperty(p => p.DisplayFormTemplateName); if (page.ContentType.DisplayFormTemplateName == "WikiEditForm") { isUncustomizedHomePage = true; } } } } } } } } } } catch (Exception ex) { // no point in failing the scan if something goes wrong here } finally { pageResult.UncustomizedHomePage = isUncustomizedHomePage; } } // Get page change information pageResult.ModifiedAt = page.LastModifiedDateTime(); pageResult.ModifiedBy = page.LastModifiedBy(); // Grab this page from the search results to connect view information string fullPageUrl = $"https://{new Uri(this.SiteCollectionUrl).DnsSafeHost}{pageUrl}"; if (pageResult.HomePage) { fullPageUrl = this.SiteUrl; } if (!this.ScanJob.SkipUsageInformation && this.pageSearchResults != null) { var searchPage = this.pageSearchResults.Where(x => x.Values.Contains(fullPageUrl)).FirstOrDefault(); if (searchPage != null) { // Recent = last 14 days pageResult.ViewsRecent = searchPage["ViewsRecent"].ToInt32(); pageResult.ViewsRecentUniqueUsers = searchPage["ViewsRecentUniqueUsers"].ToInt32(); pageResult.ViewsLifeTime = searchPage["ViewsLifeTime"].ToInt32(); pageResult.ViewsLifeTimeUniqueUsers = searchPage["ViewsLifeTimeUniqueUsers"].ToInt32(); } } if (!this.ScanJob.PageScanResults.TryAdd(pageResult.PageUrl, pageResult)) { ScanError error = new ScanError() { Error = $"Could not add page scan result for {pageResult.PageUrl}", SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, Field1 = "PageAnalyzer", }; this.ScanJob.ScanErrors.Push(error); } var duration = new TimeSpan((DateTime.Now.Subtract(start).Ticks)); } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = this.SiteCollectionUrl, SiteURL = this.SiteUrl, Field1 = "MainPageAnalyzerLoop", Field2 = ex.StackTrace, Field3 = pageUrl }; // Send error to telemetry to make scanner better if (this.ScanJob.ScannerTelemetry != null) { this.ScanJob.ScannerTelemetry.LogScanError(ex, error); } this.ScanJob.ScanErrors.Push(error); } } } } } } finally { this.StopTime = DateTime.Now; } // return the duration of this scan return(new TimeSpan((this.StopTime.Subtract(this.StartTime).Ticks))); }