0001: SET sql_mode = ? 0.0001s

0002: SHOW DATABASES LIKE 's2hubsql2' 0.0008s

0003: SHOW FULL TABLES WHERE Table_Type != 'VIEW' 0.0012s

0004: SHOW FULL FIELDS IN "Fluent_Domain" 0.0006s

0005: SHOW COLLATION LIKE 'utf8mb4_unicode_ci' 0.0002s

0006: SELECT DISTINCT "Fluent_Domain"."ClassName", "Fluent_Domain"."LastEdited", "Fluent_Domain"."Created", "Fluent_Domain"."Domain", "Fluent_Domain"."DefaultLocaleID", "Fluent_Domain"."ID", CASE WHEN "Fluent_Domain"."ClassName" IS NOT NULL THEN "Fluent_Domain"."ClassName" ELSE 'TractorCow\\Fluent\\Model\\Domain' END AS "RecordClassName" FROM "Fluent_Domain" 0.0001s

0007: SHOW FULL FIELDS IN "Fluent_Locale" 0.0005s

0008: SELECT DISTINCT "Fluent_Locale"."ClassName", "Fluent_Locale"."LastEdited", "Fluent_Locale"."Created", "Fluent_Locale"."Title", "Fluent_Locale"."Locale", "Fluent_Locale"."URLSegment", "Fluent_Locale"."IsGlobalDefault", "Fluent_Locale"."UseDefaultCode", "Fluent_Locale"."Sort", "Fluent_Locale"."DomainID", "Fluent_Locale"."ID", CASE WHEN "Fluent_Locale"."ClassName" IS NOT NULL THEN "Fluent_Locale"."ClassName" ELSE 'TractorCow\\Fluent\\Model\\Locale' END AS "RecordClassName" FROM "Fluent_Locale" ORDER BY "Fluent_Locale"."Sort" ASC, "Fluent_Locale"."Locale" ASC 0.0002s

0009: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."URLSegment" = ?) AND ("SiteTree_Live"."ParentID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0003s

0010: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ParentID" = ?) AND ("SiteTree_Live"."URLSegment" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0003s

0011: SELECT DISTINCT "SiteConfig"."ClassName", "SiteConfig"."LastEdited", "SiteConfig"."Created", "SiteConfig"."GoogleAnalyticsAccountID", "SiteConfig"."GTMAccountID", "SiteConfig"."CookieIsActive", "SiteConfig"."ConsentNoticeDescription", "SiteConfig"."ConsentNoticeLearnMore", "SiteConfig"."ConsentModalTitle", "SiteConfig"."ConsentModalDescription", "SiteConfig"."ConsentModalPrivacyPolicyName", "SiteConfig"."ConsentModalPrivacyPolicyText", "SiteConfig"."AcceptAll", "SiteConfig"."AcceptSelected", "SiteConfig"."Decline", "SiteConfig"."OGSiteName", "SiteConfig"."TwitterHandle", "SiteConfig"."CreatorTwitterHandle", "SiteConfig"."FacebookAppID", "SiteConfig"."UseTitleAsMetaTitle", "SiteConfig"."SchemaOrganisationName", "SiteConfig"."Title", "SiteConfig"."Tagline", "SiteConfig"."CanViewType", "SiteConfig"."CanEditType", "SiteConfig"."CanCreateTopLevelType", "SiteConfig"."CookieLinkPrivacyID", "SiteConfig"."SchemaOrganisationImageID", "SiteConfig"."DefaultSocialImageID", "SiteConfig"."ID", CASE WHEN "SiteConfig"."ClassName" IS NOT NULL THEN "SiteConfig"."ClassName" ELSE 'SilverStripe\\SiteConfig\\SiteConfig' END AS "RecordClassName" FROM "SiteConfig" LIMIT 1 0.0003s

0012: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0002s

0013: SELECT DISTINCT "PublishDate" IS NULL AS "_SortColumn0", "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "BlogPost_Live"."PublishDate", "BlogPost_Live"."AuthorNames", "BlogPost_Live"."Summary", "BlogPost_Live"."ElementalAreaID", "BlogPost_Live"."FeaturedImageID", CASE WHEN "SiteTree_Live"."ClassName" IN ('SilverStripe\\CMS\\Model\\SiteTree', 'Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "SiteTree_Live"."Priority" WHEN "SiteTree_Live"."ClassName" IN ('Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "Page_Live"."Priority" ELSE NULL END AS "Priority", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" LEFT JOIN "BlogPost_Live" ON "BlogPost_Live"."ID" = "SiteTree_Live"."ID" LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID" WHERE ("SiteTree_Live"."ID" = ?) AND ("SiteTree_Live"."ClassName" IN (?, ?, ?)) AND ("PublishDate" < '2026-01-01 10:21:08') ORDER BY "_SortColumn0" DESC, "BlogPost_Live"."PublishDate" DESC LIMIT 1 0.0003s

0014: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "Page_Live"."MetaTitle", "Page_Live"."Canonical", "Page_Live"."Robots", "Page_Live"."ChangeFrequency", "Page_Live"."SitemapHide", "Page_Live"."HideSocial", "Page_Live"."OGtype", "Page_Live"."OGlocale", "Page_Live"."TwitterCard", "Page_Live"."SocialImageID", CASE WHEN "SiteTree_Live"."ClassName" IN ('SilverStripe\\CMS\\Model\\SiteTree', 'Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "SiteTree_Live"."Priority" WHEN "SiteTree_Live"."ClassName" IN ('Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "Page_Live"."Priority" ELSE NULL END AS "Priority", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName", "SiteTree_Live"."Sort" FROM "SiteTree_Live" LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID" INNER JOIN "BlogPost_Live" ON "SiteTree_Live"."ID" = "BlogPost_Live"."ID" WHERE ("SiteTree_Live"."ID" = ?) AND ("SiteTree_Live"."ClassName" IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0003s

0015: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "Blog_Live"."DefaultPostMetaTitle", "Blog_Live"."DefaultPostMetaDescription", "Blog_Live"."UseFeaturedAsSocialImage", "Blog_Live"."PostsPerPage", CASE WHEN "SiteTree_Live"."ClassName" IN ('SilverStripe\\Blog\\Model\\Blog', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder') THEN "Blog_Live"."ElementalAreaID" WHEN "SiteTree_Live"."ClassName" IN ('S2Hub\\Page\\CaseStudyHolder') THEN "CaseStudyHolder_Live"."ElementalAreaID" WHEN "SiteTree_Live"."ClassName" IN ('S2Hub\\Page\\SolutionHolder') THEN "SolutionHolder_Live"."ElementalAreaID" ELSE NULL END AS "ElementalAreaID", CASE WHEN "SiteTree_Live"."ClassName" IN ('SilverStripe\\CMS\\Model\\SiteTree', 'Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "SiteTree_Live"."Priority" WHEN "SiteTree_Live"."ClassName" IN ('Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "Page_Live"."Priority" ELSE NULL END AS "Priority", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName", "SiteTree_Live"."Sort" FROM "SiteTree_Live" LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID" LEFT JOIN "Blog_Live" ON "Blog_Live"."ID" = "SiteTree_Live"."ID" LEFT JOIN "CaseStudyHolder_Live" ON "CaseStudyHolder_Live"."ID" = "SiteTree_Live"."ID" LEFT JOIN "SolutionHolder_Live" ON "SolutionHolder_Live"."ID" = "SiteTree_Live"."ID" WHERE ("SiteTree_Live"."ID" = ?) AND ("SiteTree_Live"."ClassName" IN (?, ?, ?)) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0003s

0016: SELECT DISTINCT "SiteConfig"."ClassName", "SiteConfig"."LastEdited", "SiteConfig"."Created", "SiteConfig"."GoogleAnalyticsAccountID", "SiteConfig"."GTMAccountID", "SiteConfig"."CookieIsActive", "SiteConfig"."ConsentNoticeDescription", "SiteConfig"."ConsentNoticeLearnMore", "SiteConfig"."ConsentModalTitle", "SiteConfig"."ConsentModalDescription", "SiteConfig"."ConsentModalPrivacyPolicyName", "SiteConfig"."ConsentModalPrivacyPolicyText", "SiteConfig"."AcceptAll", "SiteConfig"."AcceptSelected", "SiteConfig"."Decline", "SiteConfig"."OGSiteName", "SiteConfig"."TwitterHandle", "SiteConfig"."CreatorTwitterHandle", "SiteConfig"."FacebookAppID", "SiteConfig"."UseTitleAsMetaTitle", "SiteConfig"."SchemaOrganisationName", "SiteConfig"."Title", "SiteConfig"."Tagline", "SiteConfig"."CanViewType", "SiteConfig"."CanEditType", "SiteConfig"."CanCreateTopLevelType", "SiteConfig"."CookieLinkPrivacyID", "SiteConfig"."SchemaOrganisationImageID", "SiteConfig"."DefaultSocialImageID", "SiteConfig"."ID", CASE WHEN "SiteConfig"."ClassName" IS NOT NULL THEN "SiteConfig"."ClassName" ELSE 'SilverStripe\\SiteConfig\\SiteConfig' END AS "RecordClassName" FROM "SiteConfig" LIMIT 1 0.0001s

0017: SELECT DISTINCT "File_Live"."ClassName", "File_Live"."LastEdited", "File_Live"."Created", "File_Live"."Version", "File_Live"."UserFormUpload", "File_Live"."CanViewType", "File_Live"."CanEditType", "File_Live"."Name", "File_Live"."Title", "File_Live"."ShowInSearch", "File_Live"."ParentID", "File_Live"."OwnerID", "File_Live"."FileHash", "File_Live"."FileFilename", "File_Live"."FileVariant", "File_Live"."ID", CASE WHEN "File_Live"."ClassName" IS NOT NULL THEN "File_Live"."ClassName" ELSE 'SilverStripe\\Assets\\File' END AS "RecordClassName" FROM "File_Live" WHERE ("File_Live"."ID" IS NULL) AND ("File_Live"."ClassName" IN (?)) ORDER BY "File_Live"."Name" ASC LIMIT 1 0.0002s

0018: SELECT DISTINCT "SeoHeadTag"."ClassName", "SeoHeadTag"."LastEdited", "SeoHeadTag"."Created", "SeoHeadTag"."Title", "SeoHeadTag"."Value", "SeoHeadTag"."Type", "SeoHeadTag"."PageID", "SeoHeadTag"."PageClass", "SeoHeadTag"."ID", CASE WHEN "SeoHeadTag"."ClassName" IS NOT NULL THEN "SeoHeadTag"."ClassName" ELSE 'CyberDuck\\SEO\\Model\\SeoHeadTag' END AS "RecordClassName" FROM "SeoHeadTag" INNER JOIN "Page_HeadTags" ON "Page_HeadTags"."SeoHeadTagID" = "SeoHeadTag"."ID" WHERE ("Page_HeadTags"."PageID" = ?) AND ("SeoHeadTag"."Type" = ?) ORDER BY "SeoHeadTag"."Title" ASC 0.0003s

0019: SELECT DISTINCT "SeoHeadTag"."ClassName", "SeoHeadTag"."LastEdited", "SeoHeadTag"."Created", "SeoHeadTag"."Title", "SeoHeadTag"."Value", "SeoHeadTag"."Type", "SeoHeadTag"."PageID", "SeoHeadTag"."PageClass", "SeoHeadTag"."ID", CASE WHEN "SeoHeadTag"."ClassName" IS NOT NULL THEN "SeoHeadTag"."ClassName" ELSE 'CyberDuck\\SEO\\Model\\SeoHeadTag' END AS "RecordClassName" FROM "SeoHeadTag" INNER JOIN "Page_HeadTags" ON "Page_HeadTags"."SeoHeadTagID" = "SeoHeadTag"."ID" WHERE ("Page_HeadTags"."PageID" = ?) AND ("SeoHeadTag"."Type" = ?) ORDER BY "SeoHeadTag"."Title" ASC 0.0002s

0020: SELECT DISTINCT "SeoHeadTag"."ClassName", "SeoHeadTag"."LastEdited", "SeoHeadTag"."Created", "SeoHeadTag"."Title", "SeoHeadTag"."Value", "SeoHeadTag"."Type", "SeoHeadTag"."PageID", "SeoHeadTag"."PageClass", "SeoHeadTag"."ID", CASE WHEN "SeoHeadTag"."ClassName" IS NOT NULL THEN "SeoHeadTag"."ClassName" ELSE 'CyberDuck\\SEO\\Model\\SeoHeadTag' END AS "RecordClassName" FROM "SeoHeadTag" INNER JOIN "Page_HeadTags" ON "Page_HeadTags"."SeoHeadTagID" = "SeoHeadTag"."ID" WHERE ("Page_HeadTags"."PageID" = ?) AND ("SeoHeadTag"."Type" = ?) ORDER BY "SeoHeadTag"."Title" ASC 0.0002s

0021: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ShowInMenus" = ?) AND ("SiteTree_Live"."ParentID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC 0.0003s

0022: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0023: SELECT DISTINCT "ElementalArea_Live"."ClassName", "ElementalArea_Live"."LastEdited", "ElementalArea_Live"."Created", "ElementalArea_Live"."Version", "ElementalArea_Live"."OwnerClassName", "ElementalArea_Live"."ID", CASE WHEN "ElementalArea_Live"."ClassName" IS NOT NULL THEN "ElementalArea_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\ElementalArea' END AS "RecordClassName" FROM "ElementalArea_Live" WHERE ("ElementalArea_Live"."ID" = ?) LIMIT 1 0.0002s

0024: SELECT DISTINCT "Element_Live"."ClassName", "Element_Live"."LastEdited", "Element_Live"."Created", "Element_Live"."AvailableGlobally", "Element_Live"."BubbleStyle", "Element_Live"."PreHeader", "Element_Live"."Version", "Element_Live"."Title", "Element_Live"."ShowTitle", "Element_Live"."Sort", "Element_Live"."ExtraClass", "Element_Live"."Style", "Element_Live"."ParentID", "Element_Live"."ID", CASE WHEN "Element_Live"."ClassName" IS NOT NULL THEN "Element_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\BaseElement' END AS "RecordClassName" FROM "Element_Live" WHERE ("Element_Live"."ParentID" = ?) ORDER BY "Element_Live"."Sort" ASC 0.0002s

0025: SELECT DISTINCT "ElementalArea_Live"."ClassName", "ElementalArea_Live"."LastEdited", "ElementalArea_Live"."Created", "ElementalArea_Live"."Version", "ElementalArea_Live"."OwnerClassName", "ElementalArea_Live"."ID", CASE WHEN "ElementalArea_Live"."ClassName" IS NOT NULL THEN "ElementalArea_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\ElementalArea' END AS "RecordClassName" FROM "ElementalArea_Live" WHERE ("ElementalArea_Live"."ID" = ?) LIMIT 1 0.0001s

0026: SELECT DISTINCT "PublishDate" IS NULL AS "_SortColumn0", "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", CASE WHEN "SiteTree_Live"."ClassName" IN ('SilverStripe\\CMS\\Model\\SiteTree', 'Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "SiteTree_Live"."Priority" WHEN "SiteTree_Live"."ClassName" IN ('Page', 'S2Hub\\Page\\Agencies', 'S2Hub\\Page\\BlockPage', 'SilverStripe\\ErrorPage\\ErrorPage', 'SilverStripe\\Blog\\Model\\Blog', 'SilverStripe\\Blog\\Model\\BlogPost', 'SilverStripe\\CMS\\Model\\RedirectorPage', 'SilverStripe\\CMS\\Model\\VirtualPage', 'SilverStripe\\UserForms\\Model\\UserDefinedForm', 'S2Hub\\Page\\CaseStudyHolder', 'S2Hub\\Page\\SolutionHolder', 'S2Hub\\Page\\CaseStudy', 'S2Hub\\Page\\Solution') THEN "Page_Live"."Priority" ELSE NULL END AS "Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "Page_Live"."MetaTitle", "Page_Live"."Canonical", "Page_Live"."Robots", "Page_Live"."ChangeFrequency", "Page_Live"."SitemapHide", "Page_Live"."HideSocial", "Page_Live"."OGtype", "Page_Live"."OGlocale", "Page_Live"."TwitterCard", "Page_Live"."SocialImageID", "BlogPost_Live"."PublishDate", "BlogPost_Live"."AuthorNames", "BlogPost_Live"."Summary", "BlogPost_Live"."ElementalAreaID", "BlogPost_Live"."FeaturedImageID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID" LEFT JOIN "BlogPost_Live" ON "BlogPost_Live"."ID" = "SiteTree_Live"."ID" WHERE ("BlogPost_Live"."ElementalAreaID" = ?) AND ("SiteTree_Live"."ClassName" = ?) AND ("SiteTree_Live"."ClassName" IN (?, ?, ?)) AND ("PublishDate" < '2026-01-01 10:21:08') ORDER BY "_SortColumn0" DESC, "BlogPost_Live"."PublishDate" DESC LIMIT 1 0.0009s

0027: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0028: SELECT DISTINCT "ElementalArea_Live"."ClassName", "ElementalArea_Live"."LastEdited", "ElementalArea_Live"."Created", "ElementalArea_Live"."Version", "ElementalArea_Live"."OwnerClassName", "ElementalArea_Live"."ID", CASE WHEN "ElementalArea_Live"."ClassName" IS NOT NULL THEN "ElementalArea_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\ElementalArea' END AS "RecordClassName" FROM "ElementalArea_Live" WHERE ("ElementalArea_Live"."ID" = ?) LIMIT 1 0.0001s

0029: SELECT DISTINCT "Element_Live"."ClassName", "Element_Live"."LastEdited", "Element_Live"."Created", "Element_Live"."AvailableGlobally", "Element_Live"."BubbleStyle", "Element_Live"."PreHeader", "Element_Live"."Version", "Element_Live"."Title", "Element_Live"."ShowTitle", "Element_Live"."Sort", "Element_Live"."ExtraClass", "Element_Live"."Style", "Element_Live"."ParentID", "Element_Live"."ID", CASE WHEN "Element_Live"."ClassName" IS NOT NULL THEN "Element_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\BaseElement' END AS "RecordClassName" FROM "Element_Live" WHERE ("Element_Live"."ParentID" = ?) ORDER BY "Element_Live"."Sort" ASC LIMIT 1 0.0002s

0030: SELECT DISTINCT "ElementalArea_Live"."ClassName", "ElementalArea_Live"."LastEdited", "ElementalArea_Live"."Created", "ElementalArea_Live"."Version", "ElementalArea_Live"."OwnerClassName", "ElementalArea_Live"."ID", CASE WHEN "ElementalArea_Live"."ClassName" IS NOT NULL THEN "ElementalArea_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\ElementalArea' END AS "RecordClassName" FROM "ElementalArea_Live" WHERE ("ElementalArea_Live"."ID" = ?) LIMIT 1 0.0001s

0031: SELECT DISTINCT "Element_Live"."ClassName", "Element_Live"."LastEdited", "Element_Live"."Created", "ElementMarkdownRemote_Live"."URL", "ElementMarkdownRemote_Live"."MarkdownDataID", "Element_Live"."ID", CASE WHEN "Element_Live"."ClassName" IS NOT NULL THEN "Element_Live"."ClassName" ELSE 'DNADesign\\Elemental\\Models\\BaseElement' END AS "RecordClassName", "Element_Live"."Sort" FROM "Element_Live" LEFT JOIN "ElementMarkdownRemote_Live" ON "ElementMarkdownRemote_Live"."ID" = "Element_Live"."ID" WHERE ("Element_Live"."ID" = ?) AND ("Element_Live"."ClassName" IN (?)) ORDER BY "Element_Live"."Sort" ASC LIMIT 1 0.0002s

0032: SELECT DISTINCT "RemoteMarkdownData"."ClassName", "RemoteMarkdownData"."LastEdited", "RemoteMarkdownData"."Created", "RemoteMarkdownData"."Markdown", "RemoteMarkdownData"."Content", "RemoteMarkdownData"."ID", CASE WHEN "RemoteMarkdownData"."ClassName" IS NOT NULL THEN "RemoteMarkdownData"."ClassName" ELSE 'Netwerkstatt\\RemoteMarkdown\\Model\\RemoteMarkdownData' END AS "RecordClassName" FROM "RemoteMarkdownData" WHERE ("RemoteMarkdownData"."ID" = ?) LIMIT 1 0.0002s

0033: SELECT DISTINCT "MenuSet"."ClassName", "MenuSet"."LastEdited", "MenuSet"."Created", "MenuSet"."Title", "MenuSet"."Slug", "MenuSet"."AllowChildren", "MenuSet"."ID", CASE WHEN "MenuSet"."ClassName" IS NOT NULL THEN "MenuSet"."ClassName" ELSE 'gorriecoe\\Menu\\Models\\MenuSet' END AS "RecordClassName" FROM "MenuSet" WHERE ("MenuSet"."Slug" = ?) LIMIT 1 0.0002s

0034: SELECT DISTINCT "Link"."ClassName", "Link"."LastEdited", "Link"."Created", "Link"."Anchor", "Link"."Title", "Link"."Type", "Link"."URL", "Link"."Email", "Link"."Phone", "Link"."OpenInNewWindow", "Link"."SelectedStyle", "Link"."SiteTreeID", "Link"."FileID", "MenuLink"."Sort", "MenuLink"."MenuSetID", "MenuLink"."ParentID", "Link"."ID", CASE WHEN "Link"."ClassName" IS NOT NULL THEN "Link"."ClassName" ELSE 'gorriecoe\\Link\\Models\\Link' END AS "RecordClassName" FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."MenuSetID" = ?) AND ("Link"."ClassName" IN (?)) ORDER BY "MenuLink"."Sort" ASC 0.0003s

0035: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0036: SELECT EXISTS(SELECT * FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."ParentID" = ?) AND ("Link"."ClassName" IN (?))) 0.0002s

0037: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0038: SELECT EXISTS(SELECT * FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."ParentID" = ?) AND ("Link"."ClassName" IN (?))) 0.0001s

0039: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0040: SELECT EXISTS(SELECT * FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."ParentID" = ?) AND ("Link"."ClassName" IN (?))) 0.0001s

0041: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0042: SELECT EXISTS(SELECT * FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."ParentID" = ?) AND ("Link"."ClassName" IN (?))) 0.0001s

0043: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0044: SELECT EXISTS(SELECT * FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."ParentID" = ?) AND ("Link"."ClassName" IN (?))) 0.0001s

0045: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0046: SELECT EXISTS(SELECT * FROM "Link" LEFT JOIN "MenuLink" ON "MenuLink"."ID" = "Link"."ID" WHERE ("MenuLink"."ParentID" = ?) AND ("Link"."ClassName" IN (?))) 0.0001s

0047: SELECT "Version" FROM "SiteTree" WHERE "ID" = ? 0.0002s

0048: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0049: SELECT DISTINCT "SiteTree"."ClassName", "SiteTree"."LastEdited", "SiteTree"."Created", "SiteTree"."Priority", "SiteTree"."CanViewType", "SiteTree"."CanEditType", "SiteTree"."Version", "SiteTree"."URLSegment", "SiteTree"."Title", "SiteTree"."MenuTitle", "SiteTree"."Content", "SiteTree"."MetaDescription", "SiteTree"."ExtraMeta", "SiteTree"."ShowInMenus", "SiteTree"."ShowInSearch", "SiteTree"."Sort", "SiteTree"."HasBrokenFile", "SiteTree"."HasBrokenLink", "SiteTree"."ReportClass", "SiteTree"."ParentID", "SiteTree"."ID", CASE WHEN "SiteTree"."ClassName" IS NOT NULL THEN "SiteTree"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree" WHERE ("SiteTree"."ID" = ?) ORDER BY "SiteTree"."Sort" ASC LIMIT 1 0.0002s

0050: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

0051: SELECT DISTINCT "SiteTree_Live"."ClassName", "SiteTree_Live"."LastEdited", "SiteTree_Live"."Created", "SiteTree_Live"."Priority", "SiteTree_Live"."CanViewType", "SiteTree_Live"."CanEditType", "SiteTree_Live"."Version", "SiteTree_Live"."URLSegment", "SiteTree_Live"."Title", "SiteTree_Live"."MenuTitle", "SiteTree_Live"."Content", "SiteTree_Live"."MetaDescription", "SiteTree_Live"."ExtraMeta", "SiteTree_Live"."ShowInMenus", "SiteTree_Live"."ShowInSearch", "SiteTree_Live"."Sort", "SiteTree_Live"."HasBrokenFile", "SiteTree_Live"."HasBrokenLink", "SiteTree_Live"."ReportClass", "SiteTree_Live"."ParentID", "SiteTree_Live"."ID", CASE WHEN "SiteTree_Live"."ClassName" IS NOT NULL THEN "SiteTree_Live"."ClassName" ELSE 'SilverStripe\\CMS\\Model\\SiteTree' END AS "RecordClassName" FROM "SiteTree_Live" WHERE ("SiteTree_Live"."ID" = ?) ORDER BY "SiteTree_Live"."Sort" ASC LIMIT 1 0.0001s

Validate ORM relations in Silverstripe

How to validate ORM relations in Silverstripe

Sometimes, the defined relations in our model can be incorrect. That's normal and we're just developers. Well, even AI-devs like ChatGPT or Copilot can make mistakes, not just us. That's where all those testing and validation tools are invaluable.

Silverstripe Framework comes with a tool called RelationValidationService that checks if the relationships are set up correctly in both directions. It's run on every dev/build. That's good. But unfortunately, you have to configure it a little bit, and then it may shout out a long red list when running dev/build?flush.

Common mistakes in relations

Like in real life, even if you think your relations are fine, they could be more perfect. It's always worth improving relations, so what are the common mistakes for Silverstripe ORM relations?

Relation to an unknown class or relation is no DataObject

Well, this is easy to spot. Dev/build will break and you're forced to fix it.

Back relation is missing

Common for has_one to e.g. Image. Technically it works, but for Silverstripe it's better to know what's the relation back, even if you don't use it in your code. Who knows, maybe a future developer (read: you) want's to crate a task that checks if an image is used somewhere or if the image can be deleted, then the relation back can be used.

Relation is not in the expected format

Sometimes, Silverstripe expects you to write ClassName.RelationName. to fully understand your relations.

Back relation is ambiguous

The back relations of a has_many is a has_one. And if, for some reason, the other class has two has_ones to the original class, we all get confused, not only Silverstripe`s ORM.

RelationValidationService's Configuration

In order to switch on RelationValidationService on every dev/build, you need to configure the namespaces of the DataObjects you want to be validated, and you need to enable output by default.

---
Only:
  environment: 'dev'
---

SilverStripe\Dev\Validation\RelationValidationService:
  output_enabled: true
  allow_rules:
    myNamespace: MyCompany

Then you see a bunch of errors, can go through your code and adjust the relation namings, e.g. convert

    public static array $has_many = [
        'PhotoGalleryImages' => PhotoGalleryImage::class
    ];

to

    public static array $has_many = [
        'PhotoGalleryImages' => PhotoGalleryImage::class. '.Album'
    ];

if the relation back is called "Album".

For third party DataObjects you refer to, you can use yaml config to add relations back, e.g.:

SilverStripe\Assets\Image:
  belongs_to:
    Event: MyProject\Model\Event.Image
    Notification: MyProject\Model\Notification.Image

I think this tool should be switched on by default in dev environments. In an ideal world you hook it to your unit tests to get warnings as soon as possible.

More information about RelationValidationService , e.g. how it can be included in unit tests, can be found in the documentation.