Ejemplo n.º 1
0
        /// <summary>
        /// This constructor should be called when a Node is updated, passing the NodeID and it's parent.  This is a starting point
        /// </summary>
        /// <param name="ParentNodeID">The Parent Node id, this will be the primary root of the NodeItem Build</param>
        /// <param name="Settings">The Node Item Builder Settings</param>
        /// <param name="UseCurrentVersion">If the current version of the document should be used, should only be true if doing a Conflict check and not saving.</param>
        public NodeItem(int PageNodeID, NodeItemBuilderSettings Settings, bool UseCurrentVersion = false)
        {
            if (Settings.BuildSiblings)
            {
                // Start with Parent and build children, and children of the PageNodeID
                NodeID = DocumentHelper.GetDocuments().WhereEquals("NodeID", PageNodeID).CombineWithAnyCulture().FirstOrDefault().NodeParentID;
                if (NodeID <= 0)
                {
                    NodeID = PageNodeID;
                }
            }
            else
            {
                // Start with the node, and only build itself and it's children children.
                NodeID = PageNodeID;
            }

            TreeNode Node = DocumentHelper.GetDocuments().WhereEquals("NodeID", NodeID).CombineWithAnyCulture().FirstOrDefault();

            Parent        = null;
            UrlSlugs      = new List <NodeUrlSlug>();
            IsContainer   = Node.IsCoupled;
            ClassName     = Node.ClassName;
            Children      = new List <NodeItem>();
            ChildrenBuilt = true;
            this.Settings = Settings;

            // Builds the slugs for itself
            BuildUrlSlugs(UseCurrentVersion);

            // This will possibly be something other than -1 only on the initial node based on settings.
            AlsoBuildNodeID = Settings.BuildSiblings ? PageNodeID : -1;
        }
        /// <summary>
        /// Rebuilds the Routes for the given Node, optionally allows for settings to be passed
        /// </summary>
        /// <param name="NodeID">The NodeID</param>
        /// <param name="Settings">The Node Item Build Settings, if null will create settings based on the Node itself.</param>
        private static void RebuildRoutesByNode(int NodeID, NodeItemBuilderSettings Settings = null)
        {
            // If settings are not set, then get settings based on the given Node
            if (Settings == null)
            {
                // Get Site from Node
                TreeNode Page = DocumentHelper.GetDocuments()
                                .WhereEquals("NodeID", NodeID)
                                .Columns("NodeSiteID")
                                .FirstOrDefault();

                // Get Settings based on the Page itself
                Settings = GetNodeItemBuilderSettings(Page.NodeAliasPath, GetSite(Page.NodeSiteID).SiteName, true, false);
            }

            // Build and save
            NodeItem GivenNodeItem = new NodeItem(NodeID, Settings);

            if (ErrorOnConflict())
            {
                // If error on conflict, everything MUST be done syncly.
                GivenNodeItem.BuildChildren();
                if (GivenNodeItem.ConflictsExist())
                {
                    throw new UrlSlugCollisionException("Conflict Exists, aborting save");
                }
                // Save changes
                GivenNodeItem.SaveChanges();
            }
            else
            {
                // Do rest asyncly.
                QueueUpUrlSlugGeneration(GivenNodeItem);
            }
        }
        /// <summary>
        /// Rebuilds all URL Routes for nodes which use this class across all sites.
        /// </summary>
        /// <param name="ClassName">The Class Name</param>
        public static void RebuildRoutesByClass(string ClassName)
        {
            DataClassInfo Class = GetClass(ClassName);

            foreach (string SiteName in SiteInfoProvider.GetSites().Select(x => x.SiteName))
            {
                // Get NodeItemBuilderSettings
                NodeItemBuilderSettings BuilderSettings = GetNodeItemBuilderSettings(SiteName, true, true, true, true, true);

                // Build all, gather nodes of any Node that is of this type of class, check for updates.
                List <int> NodeIDs = DocumentHelper.GetDocuments()
                                     .WhereEquals("NodeClassID", Class.ClassID)
                                     .OnSite(new SiteInfoIdentifier(SiteName))
                                     .CombineWithDefaultCulture()
                                     .Distinct()
                                     .Columns("NodeID")
                                     .OrderBy("NodeLevel, NodeOrder")
                                     .Select(x => x.NodeID)
                                     .ToList();

                // Check all parent nodes for changes
                foreach (int NodeID in NodeIDs)
                {
                    RebuildRoutesByNode(NodeID, BuilderSettings);
                }
            }
        }
        /// <summary>
        /// Rebuilds all URL Routes on the given Site
        /// </summary>
        /// <param name="SiteName">The Site name</param>
        public static void RebuildRoutesBySite(string SiteName)
        {
            //EventLogProvider.LogInformation("DynamicRouteTesting", "SyncBuildStart", eventDescription: DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
            // Get NodeItemBuilderSettings
            NodeItemBuilderSettings BuilderSettings = GetNodeItemBuilderSettings(SiteName, true, true, true, true, true);

            // Get root NodeID
            TreeNode RootNode = DocumentHelper.GetDocument(new NodeSelectionParameters()
            {
                AliasPath = "/",
                SiteName  = SiteName
            }, new TreeProvider());

            // Rebuild NodeItem tree structure, this will only affect the initial node syncly.
            NodeItem RootNodeItem = new NodeItem(RootNode.NodeID, BuilderSettings);

            if (ErrorOnConflict())
            {
                // If error on conflict, everything MUST be done syncly.
                RootNodeItem.BuildChildren();
                if (RootNodeItem.ConflictsExist())
                {
                    throw new UrlSlugCollisionException("Conflict Exists, aborting save");
                }
                // Save changes
                RootNodeItem.SaveChanges();
            }
            else
            {
                // Do rest asyncly.
                QueueUpUrlSlugGeneration(RootNodeItem);
            }
            //EventLogProvider.LogInformation("DynamicRouteTesting", "SyncBuildEnd", eventDescription: DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
        }
        /// <summary>
        /// Rebuilds all URL Routes for nodes which use this class across all sites.
        /// </summary>
        /// <param name="ClassName">The Class Name</param>
        public static void RebuildRoutesByClass(string ClassName)
        {
            DataClassInfo Class = GetClass(ClassName);

            foreach (string SiteName in SiteInfoProvider.GetSites().Select(x => x.SiteName))
            {
                // Get NodeItemBuilderSettings, will be searching all children in case of changes.
                NodeItemBuilderSettings BuilderSettings = GetNodeItemBuilderSettings(SiteName, true, true, true, true, true);

                BuilderSettings.CheckQueueImmediately = false;

                // Build all, gather nodes of any Node that is of this type of class, check for updates.
                List <string> NodeAliasPathsToRemove = new List <string>();
                List <string> NodeAliasPaths         = DocumentHelper.GetDocuments()
                                                       .WhereEquals("NodeClassID", Class.ClassID)
                                                       .OnSite(new SiteInfoIdentifier(SiteName))
                                                       .CombineWithDefaultCulture()
                                                       .Distinct()
                                                       .PublishedVersion()
                                                       .Columns("NodeAliasPath, NodeLevel, NodeOrder")
                                                       .OrderBy("NodeLevel, NodeOrder")
                                                       .Result.Tables[0].Rows.Cast <DataRow>().Select(x => (string)x["NodeAliasPath"]).ToList();

                // Remove any NodeAliasPaths that are a descendent of a parent item, as they will be ran when the parent is checked.
                NodeAliasPaths.ForEach(x =>
                {
                    NodeAliasPathsToRemove.AddRange(NodeAliasPaths.Where(y => y.Contains(x) && x != y));
                });
                NodeAliasPaths = NodeAliasPaths.Except(NodeAliasPathsToRemove).ToList();

                // Now convert NodeAliasPaths into NodeIDs
                List <int> NodeIDs = DocumentHelper.GetDocuments()
                                     .WhereEquals("NodeClassID", Class.ClassID)
                                     .WhereIn("NodeAliasPath", NodeAliasPaths)
                                     .OnSite(new SiteInfoIdentifier(SiteName))
                                     .CombineWithDefaultCulture()
                                     .Distinct()
                                     .PublishedVersion()
                                     .Columns("NodeID, NodeLevel, NodeOrder")
                                     .OrderBy("NodeLevel, NodeOrder")
                                     .Result.Tables[0].Rows.Cast <DataRow>().Select(x => (int)x["NodeID"]).ToList();

                // Check all parent nodes for changes
                foreach (int NodeID in NodeIDs)
                {
                    RebuildRoutesByNode(NodeID, BuilderSettings);
                }

                // Now check queue to run tasks
                CheckUrlSlugGenerationQueue();
            }
        }
        /// <summary>
        /// Rebuilds the Routes for the given Node, optionally allows for settings to be passed
        /// </summary>
        /// <param name="NodeID">The NodeID</param>
        /// <param name="Settings">The Node Item Build Settings, if null will create settings based on the Node itself.</param>
        private static void RebuildRoutesByNode(int NodeID, NodeItemBuilderSettings Settings = null, bool CheckConflictOnly = false)
        {
            // If settings are not set, then get settings based on the given Node
            string NodeAliasPath = "";

            if (Settings == null)
            {
                // Get Site from Node
                TreeNode Page = DocumentHelper.GetDocuments()
                                .WhereEquals("NodeID", NodeID)
                                .Columns("NodeSiteID, NodeAliasPath")
                                .CombineWithAnyCulture()
                                .FirstOrDefault();
                NodeAliasPath = Page.NodeAliasPath;
                // Get Settings based on the Page itself
                Settings = GetNodeItemBuilderSettings(Page.NodeAliasPath, GetSite(Page.NodeSiteID).SiteName, true, false);
            }

            // Build and save
            NodeItem GivenNodeItem = new NodeItem(NodeID, Settings, CheckConflictOnly);

            if (ErrorOnConflict() || CheckConflictOnly)
            {
                // If error on conflict, everything MUST be done syncly.
                GivenNodeItem.BuildChildren();
                if (GivenNodeItem.ConflictsExist())
                {
                    string Error = $"Could not save document at {NodeAliasPath} due to a conflict in the generated route:\n\r {string.Join("\n\r", GivenNodeItem.GetConflictItems())}";
                    EventLogProvider.LogEvent("E", "DynamicRouting", "Conflict Exists", eventDescription: Error);
                    throw new UrlSlugCollisionException($"{Error} aborting save");
                }
                // Save changes if not only checking conflict
                if (CheckConflictOnly)
                {
                    return;
                }
                GivenNodeItem.SaveChanges();
            }
            else
            {
                // Save main one
                GivenNodeItem.SaveChanges(false);

                // Do rest asyncly.
                QueueUpUrlSlugGeneration(GivenNodeItem, Settings.CheckQueueImmediately);
            }
        }
        /// <summary>
        /// Rebuilds the node and all child node
        /// </summary>
        /// <param name="NodeID">The Node ID</param>
        public static void RebuildSubtreeRoutesByNode(int NodeID)
        {
            // Set up settings
            // Get Site from Node
            TreeNode Page = DocumentHelper.GetDocuments()
                            .WhereEquals("NodeID", NodeID)
                            .Columns("NodeSiteID")
                            .FirstOrDefault();

            // Get Settings based on the Page itself
            NodeItemBuilderSettings Settings = GetNodeItemBuilderSettings(Page.NodeAliasPath, GetSite(Page.NodeSiteID).SiteName, true, false);

            // Check all descendents
            Settings.BuildDescendents   = true;
            Settings.CheckingForUpdates = false;

            RebuildRoutesByNode(NodeID, Settings);
        }
Ejemplo n.º 8
0
        public NodeItem(NodeItem parent, TreeNode Node, NodeItemBuilderSettings Settings, bool BuildChildren = false)
        {
            NodeID        = Node.NodeID;
            Parent        = parent;
            UrlSlugs      = new List <NodeUrlSlug>();
            Children      = new List <NodeItem>();
            IsContainer   = Node.IsCoupled;
            ClassName     = Node.ClassName;
            this.Settings = Settings;

            // Build it's slugs
            BuildUrlSlugs();

            // If build children, or settings to build descendents, or if an update was found, build children
            if (BuildChildren || Settings.BuildDescendents || HasUpdates)
            {
                this.BuildChildren();
            }
        }
        /// <summary>
        /// Rebuilds all URL Routes on the given Site
        /// </summary>
        /// <param name="SiteName">The Site name</param>
        public static void RebuildRoutesBySite(string SiteName)
        {
            //EventLogProvider.LogInformation("DynamicRouteTesting", "SyncBuildStart", eventDescription: DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
            // Get NodeItemBuilderSettings
            NodeItemBuilderSettings BuilderSettings = GetNodeItemBuilderSettings(SiteName, true, true, true, true, true);

            // Get root NodeID
            TreeNode RootNode = DocumentHelper.GetDocuments()
                                .Path("/", PathTypeEnum.Single)
                                .OnSite(SiteName)
                                .CombineWithAnyCulture()
                                .FirstOrDefault();

            // Rebuild NodeItem tree structure, this will only affect the initial node syncly.
            NodeItem RootNodeItem = new NodeItem(RootNode.NodeID, BuilderSettings);

            if (ErrorOnConflict())
            {
                // If error on conflict, everything MUST be done syncly.
                RootNodeItem.BuildChildren();
                if (RootNodeItem.ConflictsExist())
                {
                    EventLogProvider.LogEvent("E", "DynamicRouting", "Conflict Exists", eventDescription: $"Could not rebuild the site {SiteName}'s routes due to a conflict in the generated routes.");
                    throw new UrlSlugCollisionException("Conflict Exists, aborting save");
                }
                // Save changes
                RootNodeItem.SaveChanges();
            }
            else
            {
                // Save itself and then queue up rest
                RootNodeItem.SaveChanges(false);
                // Do rest asyncly.
                QueueUpUrlSlugGeneration(RootNodeItem, BuilderSettings.CheckQueueImmediately);
            }
            //EventLogProvider.LogInformation("DynamicRouteTesting", "SyncBuildEnd", eventDescription: DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
        }