private List <Element> GetElements(List <KeyValuePair <PageLocaleState, IPage> > pages, bool rootPages) { //ElementDragAndDropInfo dragAndDropInfo = new ElementDragAndDropInfo(typeof(IPage)); //dragAndDropInfo.AddDropType(typeof(IPage)); //dragAndDropInfo.SupportsIndexedPosition = true; string editPageLabel = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.EditPage"); string editPageToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.EditPageToolTip"); string localizePageLabel = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.LocalizePage"); string localizePageToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.LocalizePageToolTip"); string addNewPageLabel = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.AddSubPage"); string addNewPageToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.AddSubPageToolTip"); string deletePageLabel = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.Delete"); string deletePageToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", "PageElementProvider.DeleteToolTip"); string urlMappingName = null; if (UserSettings.ForeignLocaleCultureInfo != null) { urlMappingName = DataLocalizationFacade.GetCultureTitle(UserSettings.ForeignLocaleCultureInfo); } var elements = new Element[pages.Count]; ParallelFacade.For("PageElementProvider. Getting elements", 0, pages.Count, i => { var kvp = pages[i]; IPage page = kvp.Value; EntityToken entityToken = page.GetDataEntityToken(); var dragAndDropInfo = new ElementDragAndDropInfo(typeof(IPage)); dragAndDropInfo.AddDropType(typeof(IPage)); dragAndDropInfo.SupportsIndexedPosition = true; var element = new Element(_context.CreateElementHandle(entityToken), MakeVisualData(page, kvp.Key, urlMappingName, rootPages), dragAndDropInfo); element.PropertyBag.Add("Uri", "~/page({0})".FormatWith(page.Id)); element.PropertyBag.Add("ElementType", "application/x-composite-page"); element.PropertyBag.Add("DataId", page.Id.ToString()); if (kvp.Key == PageLocaleState.Own) { // Normal actions element.AddAction(new ElementAction(new ActionHandle(new ProxyDataActionToken(ActionIdentifier.Edit, EditPermissionTypes))) { VisualData = new ActionVisualizedData { Label = editPageLabel, ToolTip = editPageToolTip, Icon = PageElementProvider.EditPage, Disabled = false, ActionLocation = new ActionLocation { ActionType = ActionType.Edit, IsInFolder = false, IsInToolbar = true, ActionGroup = PrimaryActionGroup } } }); element.AddAction(new ElementAction(new ActionHandle(new ProxyDataActionToken(ActionIdentifier.Add, AddPermissionTypes))) { VisualData = new ActionVisualizedData { Label = addNewPageLabel, ToolTip = addNewPageToolTip, Icon = PageElementProvider.AddPage, Disabled = false, ActionLocation = new ActionLocation { ActionType = ActionType.Add, IsInFolder = false, IsInToolbar = true, ActionGroup = PrimaryActionGroup } } }); element.AddAction(new ElementAction(new ActionHandle(new ProxyDataActionToken(ActionIdentifier.Delete, DeletePermissionTypes))) { VisualData = new ActionVisualizedData { Label = deletePageLabel, ToolTip = deletePageToolTip, Icon = DeletePage, Disabled = false, ActionLocation = new ActionLocation { ActionType = ActionType.Delete, IsInFolder = false, IsInToolbar = true, ActionGroup = PrimaryActionGroup } } }); _pageAssociatedHelper.AttachElementActions(element, page); } else if (kvp.Key == PageLocaleState.ForeignActive) { // Localized actions bool addAction = false; Guid parentId = page.GetParentId(); if (parentId == Guid.Empty) { addAction = true; } else { using (new DataScope(DataScopeIdentifier.Administrated, UserSettings.ActiveLocaleCultureInfo)) { bool exists = DataFacade.GetData <IPage>(f => f.Id == parentId).Any(); if (exists) { addAction = true; } } } if (addAction) { element.AddAction(new ElementAction(new ActionHandle(new WorkflowActionToken(WorkflowFacade.GetWorkflowType("Composite.Plugins.Elements.ElementProviders.PageElementProvider.LocalizePageWorkflow"), LocalizePermissionTypes))) { VisualData = new ActionVisualizedData { Label = localizePageLabel, ToolTip = localizePageToolTip, Icon = PageElementProvider.LocalizePage, Disabled = false, ActionLocation = new ActionLocation { ActionType = ActionType.Edit, IsInFolder = false, IsInToolbar = true, ActionGroup = PrimaryActionGroup } } }); } } elements[i] = element; }); return(new List <Element>(elements)); }
public bool BuildBrokenLinksReport(XElement infoDocumentRoot) { using (new DataScope(PublicationScope.Published)) { bool noInvalidLinksFound = true; // Get all pages present in the console List <IPage> actionRequiredPages = DataFacade.GetData <IPage>().ToList(); // Check security for each page (does the user have access - no need to bother the user with pages they do not have access to) UserToken userToken = UserValidationFacade.GetUserToken(); var userPermissions = PermissionTypeFacade.GetUserPermissionDefinitions(userToken.Username).ToList(); var userGroupPermissions = PermissionTypeFacade.GetUserGroupPermissionDefinitions(userToken.Username).ToList(); // Loop all pages and remove the ones the user has no access to actionRequiredPages = actionRequiredPages.Where(page => PermissionTypeFacade.GetCurrentPermissionTypes(userToken, page.GetDataEntityToken(), userPermissions, userGroupPermissions) .Contains(PermissionType.Read)).ToList(); var pageIdsWithAccessTo = new HashSet <Guid>(actionRequiredPages.Select(p => p.Id)); var allSitemapElements = PageStructureInfo.GetSiteMap().DescendantsAndSelf(); var relevantElements = allSitemapElements.Where(f => pageIdsWithAccessTo.Contains(new Guid(f.Attribute("Id").Value))); var minimalTree = relevantElements.AncestorsAndSelf().Where(f => f.Name.LocalName == "Page").Distinct().ToList(); var reportElements = new Hashtable <Guid, XElement>(); var linksToCheck = new List <LinkToCheck>(); // Rendering all the C1 pages and collecting links foreach (XElement pageElement in minimalTree) { Guid pageId = new Guid(pageElement.Attribute("Id").Value); IPage page = PageManager.GetPageById(pageId); Verify.IsNotNull(page, "Failed to get the page"); string pageTitle = pageElement.Attribute("MenuTitle") != null ? pageElement.Attribute("MenuTitle").Value : pageElement.Attribute("Title").Value; var resultPageElement = new XElement(PageElementName, new XAttribute("Id", pageId), new XAttribute("Title", pageTitle)); reportElements[pageId] = resultPageElement; string htmlDocument, errorCode; string url = pageElement.Attribute("URL").Value; string pageServerUrl = null; if (url.StartsWith("http://") || (url.StartsWith("https://"))) { pageServerUrl = new UrlBuilder(url).ServerUrl; if (pageServerUrl == string.Empty) { pageServerUrl = url; /* Bug in versions < C1 4.0 beta 2 */ } } pageServerUrl = pageServerUrl ?? _serverUrl; PageRenderingResult result = RenderPage(url, out htmlDocument, out errorCode); if (result == PageRenderingResult.Failed) { resultPageElement.Add(GetRenderingErrorNode(errorCode)); continue; } if (result == PageRenderingResult.Redirect || result == PageRenderingResult.NotFound) { continue; } XDocument document; try { document = XDocument.Parse(htmlDocument); } catch (Exception) { resultPageElement.Add(GetRenderingErrorNode(Localization.BrokenLinkReport_NotValidXhml)); continue; } linksToCheck.AddRange(CollectLinksToCheck(document, resultPageElement, url, pageServerUrl)); } linksToCheck = linksToCheck.OrderBy(o => Guid.NewGuid()).ToList(); // Shuffling links // Checking external and internall links in parrallel tasks - one per hostname var linksGroupedByHostname = linksToCheck.Where(l => l.RequestValidationInfo != null) .GroupBy(link => link.RequestValidationInfo.Hostname).ToList(); ParallelFacade.ForEach(linksGroupedByHostname, linkGroup => { foreach (var linkToCheck in linkGroup) { linkToCheck.BrokenLinkType = ValidateByRequest(linkToCheck.RequestValidationInfo); // linkToCheck.RequestValidationInfo = null; } }); // Having 100 tasks running in parallel would fill the app pool and make the site unresponsive foreach (var link in linksToCheck) { if (!link.BrokenLinkType.HasValue) { Log.LogWarning(LogTitle, "Incorrectly processed link: " + link.Href); link.BrokenLinkType = BrokenLinkType.Relative; } BrokenLinkType brokenLinkType = link.BrokenLinkType.Value; if (brokenLinkType == BrokenLinkType.None) { continue; } var brokenLinkDescriptionElement = DescribeBrokenLink(link.LinkNode, link.Href, brokenLinkType); link.ReportPageNode.Add(brokenLinkDescriptionElement); noInvalidLinksFound = false; } BuildReportTreeRec(infoDocumentRoot, Guid.Empty, reportElements); return(noInvalidLinksFound); } }