コード例 #1
0
        /// <summary>
        /// Gets the Page's Url Slug based on the given NodeID and Culture.  If Culture not found, then will prioritize the Site's Default Culture, then Cultures by alphabetical order.
        /// </summary>
        /// <param name="NodeID">The NodeID</param>
        /// <param name="DocumentCulture">The Document Culture, if not provided will use default Site's Culture.</param>
        /// <param name="SiteName">The Site Name, if not provided then will query the NodeID to find it's site.</param>
        /// <returns>The UrlSlug (with ~ prepended) or Null if page not found.</returns>
        public static string GetPageUrl(int NodeID, string DocumentCulture = null, string SiteName = null)
        {
            if (SiteName == null)
            {
                TreeNode Page = DocumentHelper.GetDocuments().WhereEquals("NodeID", NodeID).Columns("NodeSiteID").FirstOrDefault();
                if (Page != null)
                {
                    SiteName = SiteInfoProvider.GetSiteName(Page.NodeSiteID);
                }
                else
                {
                    // No page found, so won't find a Url Slug either
                    return(null);
                }
            }

            if (string.IsNullOrWhiteSpace(DocumentCulture))
            {
                DocumentCulture = CultureHelper.GetDefaultCultureCode(SiteName);
            }

            UrlSlugInfo UrlSlug = UrlSlugInfoProvider.GetUrlSlugs()
                                  .WhereEquals("UrlSlugNodeID", NodeID)
                                  .OrderBy($"case when UrlSlugCultureCode = '{SqlHelper.EscapeQuotes(DocumentCulture)}' then 0 else 1 end, case when UrlSlugCultureCode = '{CultureHelper.GetDefaultCultureCode(SiteName)}' then 0 else 1 end, UrlSlugCultureCode")
                                  .FirstOrDefault();

            return(UrlSlug != null ? "~" + UrlSlug.UrlSlug : null);
        }
コード例 #2
0
        public void SaveChanges(bool SaveChildren = true)
        {
            bool ShouldSaveChildren = SaveChildren || SavedAlready;

            // Add catch for uniqueness across url and site, no duplicates, how to handle?  revert to node alias path with or without document culture?
            if (!SavedAlready)
            {
                // Check itself for changes and save, then children
                foreach (NodeUrlSlug UrlSlug in UrlSlugs)
                {
                    if (UrlSlug.IsNewOrUpdated)
                    {
                        if (ValidationHelper.GetGuid(UrlSlug.ExistingNodeSlugGuid, Guid.Empty) != Guid.Empty)
                        {
                            // Now Update the Url Slug if it's not custom
                            var ExistingSlug = UrlSlugInfoProvider.GetUrlSlugInfo(UrlSlug.ExistingNodeSlugGuid);
                            if (!ExistingSlug.UrlSlugIsCustom)
                            {
                                ExistingSlug.UrlSlug = UrlSlug.UrlSlug;
                                UrlSlugInfoProvider.SetUrlSlugInfo(ExistingSlug);
                            }
                        }
                        else
                        {
                            // Check for existing Url Slug that matches the new Url
                            var MatchingUrlSlug = UrlSlugInfoProvider.GetUrlSlugs()
                                                  .WhereEquals("UrlSlug", UrlSlug.UrlSlug)
                                                  .WhereNotEquals("UrlSlugNodeID", NodeID)
                                                  .FirstOrDefault();
                            if (MatchingUrlSlug != null)
                            {
                                if (Settings.LogConflicts)
                                {
                                    var CurDoc          = DocumentHelper.GetDocument(NodeID, UrlSlug.CultureCode, new TreeProvider());
                                    var ExistingSlugDoc = DocumentHelper.GetDocument(MatchingUrlSlug.UrlSlugNodeID, MatchingUrlSlug.UrlSlugCultureCode, new TreeProvider());

                                    // Log Conflict
                                    EventLogProvider.LogEvent("W", "DynamicRouting", "UrlSlugConflict", eventDescription: string.Format("Cannot create a new Url Slug {0} for Document {1} [{2}] because it exists already for {3} [{4}]",
                                                                                                                                        UrlSlug.UrlSlug,
                                                                                                                                        CurDoc.NodeAliasPath,
                                                                                                                                        CurDoc.DocumentCulture,
                                                                                                                                        ExistingSlugDoc.NodeAliasPath,
                                                                                                                                        ExistingSlugDoc.DocumentCulture
                                                                                                                                        ));
                                }
                            }
                            else
                            {
                                var newSlug = new UrlSlugInfo()
                                {
                                    UrlSlug            = UrlSlug.UrlSlug,
                                    UrlSlugNodeID      = NodeID,
                                    UrlSlugCultureCode = UrlSlug.CultureCode,
                                    UrlSlugIsCustom    = false
                                };
                                UrlSlugInfoProvider.SetUrlSlugInfo(newSlug);
                            }
                        }
                    }
                }
                // Mark this as saved already
                SavedAlready = true;
            }

            // Now Call save children on children if they are built.
            if (ShouldSaveChildren)
            {
                foreach (NodeItem Child in Children)
                {
                    Child.SaveChanges();
                }
            }
        }
コード例 #3
0
ファイル: NodeData.cs プロジェクト: liamgold/DynamicRouting
        /// <summary>
        /// Saves any inserts, updates or deletes to the database
        /// </summary>
        /// <param name="SaveChildren">If the children should be saved as well.</param>
        public void SaveChanges(bool SaveChildren = true)
        {
            bool ShouldSaveChildren = SaveChildren || SavedAlready;

            // Add catch for uniqueness across url and site, no duplicates, how to handle?  revert to node alias path with or without document culture?
            if (!SavedAlready)
            {
                // Check itself for changes and save, then children
                foreach (NodeUrlSlug UrlSlug in UrlSlugs)
                {
                    // Handle Deletes
                    if (UrlSlug.Delete)
                    {
                        UrlSlugInfoProvider.DeleteUrlSlugInfo(UrlSlug.ExistingNodeSlugGuid);
                        continue;
                    }
                    if (UrlSlug.IsNewOrUpdated)
                    {
                        // Check for existing Url Slug that matches the new Url
                        var MatchingUrlSlug = UrlSlugInfoProvider.GetUrlSlugs()
                                              .WhereEquals("UrlSlug", UrlSlug.UrlSlug)
                                              .WhereNotEquals("UrlSlugNodeID", NodeID)
                                              .Where($"UrlSlugNodeID in (Select NodeID from CMS_Tree where NodeSiteID = {UrlSlug.SiteID})")
                                              .FirstOrDefault();
                        if (MatchingUrlSlug != null)
                        {
                            if (DynamicRouteInternalHelper.AppendPostFixOnConflict())
                            {
                                bool ExistingFound = true;
                                int  AppendCount   = 0;
                                // Loop till no match found
                                while (ExistingFound)
                                {
                                    string PreviousAppendex = $"-({AppendCount})";
                                    AppendCount++;
                                    string NewAppendex = $"-({AppendCount})";
                                    if (UrlSlug.UrlSlug.Contains(PreviousAppendex))
                                    {
                                        UrlSlug.UrlSlug = UrlSlug.UrlSlug.Replace(PreviousAppendex, NewAppendex);
                                    }
                                    else
                                    {
                                        UrlSlug.UrlSlug += NewAppendex;
                                    }
                                    ExistingFound = UrlSlugInfoProvider.GetUrlSlugs()
                                                    .WhereEquals("UrlSlug", UrlSlug.UrlSlug)
                                                    .WhereNotEquals("UrlSlugNodeID", NodeID)
                                                    .Where($"UrlSlugNodeID in (Select NodeID from CMS_Tree where NodeSiteID = {UrlSlug.SiteID})")
                                                    .FirstOrDefault() != null;
                                }
                            }
                            else
                            {
                                // Technically should never hit this as the action should have either been cancelled or logged with an error
                                throw new Exception("Conflict Found on Save and Url Slug Conflict Behavior Setting is not 'Append Post Fix' so could not complete action.");
                            }
                        }

                        if (ValidationHelper.GetGuid(UrlSlug.ExistingNodeSlugGuid, Guid.Empty) != Guid.Empty)
                        {
                            // Now Update the Url Slug if it's not custom
                            var ExistingSlug = UrlSlugInfoProvider.GetUrlSlugInfo(UrlSlug.ExistingNodeSlugGuid);
                            if (!ExistingSlug.UrlSlugIsCustom)
                            {
                                ExistingSlug.UrlSlug = UrlSlug.UrlSlug;
                                UrlSlugInfoProvider.SetUrlSlugInfo(ExistingSlug);
                            }
                        }
                        else
                        {
                            var newSlug = new UrlSlugInfo()
                            {
                                UrlSlug            = UrlSlug.UrlSlug,
                                UrlSlugNodeID      = NodeID,
                                UrlSlugCultureCode = UrlSlug.CultureCode,
                                UrlSlugIsCustom    = false
                            };
                            UrlSlugInfoProvider.SetUrlSlugInfo(newSlug);
                        }
                    }
                }
                // Mark this as saved already
                SavedAlready = true;
            }

            // Now Call save children on children if they are built.
            if (ShouldSaveChildren)
            {
                foreach (NodeItem Child in Children)
                {
                    Child.SaveChanges();
                }
            }
        }
コード例 #4
0
ファイル: NodeData.cs プロジェクト: liamgold/DynamicRouting
        /// <summary>
        /// Generates the Url slugs for itself, first pulling any Custom Url Slugs, then rendering all culture codes outlined in the settings
        /// <paramref name="UseCurrentVersion">If true, then will look to the current version of the document, used only in Checking for conflicts to block publishing</paramref>
        /// </summary>
        public void BuildUrlSlugs(bool UseCurrentVersion = false)
        {
            // Temp replace Method version with Normal version
            string Pattern = Regex.Replace(DynamicRouteInternalHelper.GetClass(ClassName).ClassURLPattern, "ParentUrl\\(\\)", "ParentUrl", RegexOptions.IgnoreCase);

            // if no pattern, then default to node alias path, this way any child with a ParentUrl will still have a value.
            if (string.IsNullOrWhiteSpace(Pattern))
            {
                Pattern = "{% NodeAliasPath %}";
            }

            var SlugQuery = UrlSlugInfoProvider.GetUrlSlugs()
                            .Source(x => x.Join(new QuerySourceTable("CMS_Tree", null, new string[] { }), new WhereCondition("NodeID = UrlSlugNodeID"), JoinTypeEnum.Inner))
                            .Columns(new string[] { "UrlSlugID", "UrlSlugGuid", "UrlSlugLastModified", "UrlSlug", "UrlSlugNodeID", "UrlSlugCultureCode", "UrlSlugIsCustom", "NodeSiteID" })
                            .WhereEquals("UrlSlugNodeID", NodeID);

            // If not checking for updates (rebuild), then the only ones we want to keep are the Custom Url Slugs.
            if (!Settings.CheckingForUpdates)
            {
                SlugQuery.WhereEquals("UrlSlugIsCustom", true);
            }

            // Import the existing Slugs (Custom if not checking for imports, or all of them)
            foreach (UrlSlugInfo ExistingSlug in SlugQuery)
            {
                UrlSlugs.Add(new NodeUrlSlug()
                {
                    SiteID               = ExistingSlug.GetIntegerValue("NodeSiteID", 1),
                    IsCustom             = ExistingSlug.UrlSlugIsCustom,
                    IsDefault            = ExistingSlug.UrlSlugCultureCode.Equals(Settings.DefaultCultureCode, StringComparison.InvariantCultureIgnoreCase),
                    CultureCode          = ExistingSlug.UrlSlugCultureCode,
                    UrlSlug              = ExistingSlug.UrlSlug,
                    ExistingNodeSlugGuid = ExistingSlug.UrlSlugGuid
                });
            }

            // Go through any cultures that do not have custom slugs already, these are the cultures that need to be rebuilt
            foreach (string CultureCode in Settings.CultureCodes.Where(culture => !UrlSlugs.Exists(slug => slug.IsCustom && slug.CultureCode.Equals(culture, StringComparison.InvariantCultureIgnoreCase))))
            {
                var CultureResolver = Settings.BaseResolver.CreateChild();
                CultureResolver.SetAnonymousSourceData(new object[] { DynamicRouteInternalHelper.GetCulture(CultureCode) });

                bool IsDefaultCulture = CultureCode.Equals(Settings.DefaultCultureCode, StringComparison.InvariantCultureIgnoreCase);

                // Get actual Document, if it's the default culture, it MUST return some document, no matter what.
                var DocQuery = DocumentHelper.GetDocuments(ClassName)
                               .WhereEquals("NodeID", NodeID)
                               .Culture(CultureCode)
                               .CombineWithDefaultCulture(IsDefaultCulture || Settings.GenerateIfCultureDoesntExist);

                if (UseCurrentVersion)
                {
                    DocQuery.LatestVersion(true).Published(false);
                }
                else
                {
                    DocQuery.PublishedVersion(true);
                }

                TreeNode Document = DocQuery.FirstOrDefault();
                // If the Document is either Null because there is no Default Culture, then get any document
                // and set the culture code if the current Culture checking is either the default culture (required)
                // or is another culture but should be generated due to the GenerateIfCultureDoesntExist setting
                if (Document == null && (IsDefaultCulture || Settings.GenerateIfCultureDoesntExist))
                {
                    var AnyCultureDocQuery = DocumentHelper.GetDocuments(ClassName)
                                             .WhereEquals("NodeID", NodeID)
                                             .CombineWithAnyCulture();
                    if (UseCurrentVersion)
                    {
                        AnyCultureDocQuery.LatestVersion(true).Published(false);
                    }
                    else
                    {
                        AnyCultureDocQuery.PublishedVersion(true);
                    }
                    Document = AnyCultureDocQuery.FirstOrDefault();
                    Document.DocumentCulture = CultureCode;
                }

                if (Document != null)
                {
                    // Add Document values and ParentUrl
                    var DocResolver = CultureResolver.CreateChild();
                    DocResolver.SetAnonymousSourceData(new object[] { Document });
                    if (Parent == null)
                    {
                        // Look up parent Url Slug
                        UrlSlugInfo ParentSlug = UrlSlugInfoProvider.GetUrlSlugs()
                                                 .WhereEquals("UrlSlugNodeID", Document.NodeParentID)
                                                 .OrderBy($"case when UrlSlugCultureCode = '{CultureCode}' then 0 else 1 end, case when UrlSlugCultureCode = '{Settings.DefaultCultureCode}' then 0 else 1 end, UrlSlugCultureCode")
                                                 .FirstOrDefault();
                        if (ParentSlug != null)
                        {
                            DocResolver.SetNamedSourceData("ParentUrl", ParentSlug.UrlSlug);
                        }
                        else
                        {
                            DocResolver.SetNamedSourceData("ParentUrl", "");
                        }
                    }
                    else
                    {
                        DocResolver.SetNamedSourceData("ParentUrl", Parent.GetUrlSlug(CultureCode));
                    }

                    var NodeSlug = new NodeUrlSlug()
                    {
                        SiteID      = Document.NodeSiteID,
                        CultureCode = CultureCode,
                        IsCustom    = false,
                        IsDefault   = IsDefaultCulture,
                        UrlSlug     = DynamicRouteInternalHelper.GetCleanUrl(DocResolver.ResolveMacros(Pattern), Settings.SiteName),
                    };

                    // If checking for updates, need to flag that an update was found
                    if (Settings.CheckingForUpdates)
                    {
                        var ExistingSlug = UrlSlugs.Where(x => x.CultureCode.Equals(CultureCode, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        if (ExistingSlug != null)
                        {
                            // Update the existing UrlSlug only if it is different and not custom
                            if (!ExistingSlug.UrlSlug.Equals(NodeSlug.UrlSlug))
                            {
                                ExistingSlug.IsNewOrUpdated  = true;
                                ExistingSlug.PreviousUrlSlug = ExistingSlug.UrlSlug;
                                ExistingSlug.UrlSlug         = NodeSlug.UrlSlug;
                            }
                        }
                        else
                        {
                            // No Slug exists for this culture, add.
                            NodeSlug.IsNewOrUpdated = true;
                            UrlSlugs.Add(NodeSlug);
                        }
                    }
                    else
                    {
                        // Not checking for updates to just adding node slug.
                        NodeSlug.IsNewOrUpdated = true;
                        UrlSlugs.Add(NodeSlug);
                    }
                }
                else if (!Settings.GenerateIfCultureDoesntExist && !IsDefaultCulture)
                {
                    // If document no longer exists but a Url slug exists, set this slug to be deleted.
                    var SlugToDelete = UrlSlugs.Where(x => x.ExistingNodeSlugGuid != null && x.CultureCode.Equals(CultureCode, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                    if (SlugToDelete != null)
                    {
                        SlugToDelete.Delete = true;
                    }
                }
            }
        }