From 956d38098bac825a5c3137cb263bfe03769f1a42 Mon Sep 17 00:00:00 2001 From: "Hector D. Byrd" Date: Thu, 18 Jul 2024 22:25:09 +0300 Subject: [PATCH] chore: Add paged sitemap support to GQL --- src/gql/resolvers/SitemapResolver.php | 41 +++++++++++++++++++++------ src/helpers/Sitemap.php | 16 ++++++++++- src/models/SitemapIndexTemplate.php | 7 ++--- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/gql/resolvers/SitemapResolver.php b/src/gql/resolvers/SitemapResolver.php index e3b5be408..2f1947243 100644 --- a/src/gql/resolvers/SitemapResolver.php +++ b/src/gql/resolvers/SitemapResolver.php @@ -15,9 +15,12 @@ use GraphQL\Type\Definition\ResolveInfo; use nystudio107\seomatic\helpers\Gql as GqlHelper; use nystudio107\seomatic\helpers\PluginTemplate; +use nystudio107\seomatic\helpers\Sitemap; +use nystudio107\seomatic\models\MetaBundle; use nystudio107\seomatic\models\SitemapCustomTemplate; use nystudio107\seomatic\models\SitemapIndexTemplate; use nystudio107\seomatic\models\SitemapTemplate; +use nystudio107\seomatic\Seomatic; use yii\web\NotFoundHttpException; /** @@ -55,15 +58,18 @@ public static function getSitemaps($source, array $arguments, $context, ResolveI return []; } + $sitemapList = []; // If either of the source bundle arguments are present, get the sitemap if (!empty($arguments['sourceBundleType']) || !empty($arguments['sourceBundleHandle'])) { - $filename = self::createFilenameFromComponents($site->groupId, $arguments['sourceBundleType'] ?? '', $arguments['sourceBundleHandle'] ?? '', $siteId); + $filenames = self::createSitemapFilenamesFromComponents($site->groupId, $arguments['sourceBundleType'] ?? '', $arguments['sourceBundleHandle'] ?? '', $siteId); - return [ - self::getSitemapItemByFilename($filename), - ]; + foreach ($filenames as $filename) { + $sitemapList[] = self::getSitemapItemByFilename($filename); + } + + return $sitemapList; } - $sitemapList = []; + $sitemapIndexItems = [self::getSitemapIndexListEntry($siteId, $site->groupId)]; // Scrape each index for individual entries @@ -151,7 +157,7 @@ protected static function getSitemapIndexListEntry($siteId, $groupId): array */ protected static function getSitemapItemByFilename($filename) { - if (!preg_match('/sitemaps-(?P\d+)-(?P[\w\.*]+)-(?P[\w\.*]+)-(?P\d+)/i', $filename, $matches)) { + if (!preg_match('/sitemaps-(?P\d+)-(?P[\w\.*]+)-(?P[\w\.*]+)-(?P\d+)-sitemap(-p(?P\d+))?/i', $filename, $matches)) { return null; } @@ -173,8 +179,27 @@ protected static function getSitemapItemByFilename($filename) * @param int $siteId * @return string */ - protected static function createFilenameFromComponents(int $groupId, string $bundleType, string $bundleHandle, int $siteId): string + protected static function createSitemapFilenamesFromComponents(int $groupId, string $bundleType, string $bundleHandle, int $siteId): array { - return "sitemaps-$groupId-$bundleType-$bundleHandle-$siteId-sitemap.xml"; + $metaBundle = Seomatic::$plugin->metaBundles->getMetaBundleBySourceHandle($bundleType, $bundleHandle, $siteId); + if (!$metaBundle) { + return []; + } + + $pageSize = $metaBundle->metaSitemapVars->sitemapPageSize ?? null; + if (!$pageSize) { + return ["sitemaps-$groupId-$bundleType-$bundleHandle-$siteId-sitemap.xml"]; + } + + $seoElementClass = Seomatic::$plugin->seoElements->getSeoElementByMetaBundleType($metaBundle->sourceBundleType); + $totalElements = Sitemap::getTotalElementsInSitemap($seoElementClass, $metaBundle); + $pageCount = (!empty($pageSize) && $pageSize > 0) ? ceil($totalElements / $pageSize) : 1; + + $sitemapFilenames = []; + for ($page = 1; $page <= $pageCount; $page++) { + $sitemapFilenames[] = sprintf('sitemaps-%d-%s-%s-%d-sitemap-p%d.xml', $groupId, $bundleType, $bundleHandle, $siteId, $page); + } + + return $sitemapFilenames; } } diff --git a/src/helpers/Sitemap.php b/src/helpers/Sitemap.php index 602f03075..b71f8226a 100644 --- a/src/helpers/Sitemap.php +++ b/src/helpers/Sitemap.php @@ -617,7 +617,21 @@ protected static function assetFilesSitemapLink(Asset $asset, MetaBundle $metaBu } } - protected static function getElementListSitemap(array $elements) + /** + * Return the total number of elements in a sitemap, respecting metabundle settings. + * + * @param string $seoElementClass + * @param MetaBundle $metaBundle + * @return int|null + */ + public static function getTotalElementsInSitemap(string $seoElementClass, MetaBundle $metaBundle) { + $totalElements = $seoElementClass::sitemapElementsQuery($metaBundle)->count(); + + if ($metaBundle->metaSitemapVars->sitemapLimit && ($totalElements > $metaBundle->metaSitemapVars->sitemapLimit)) { + $totalElements = $metaBundle->metaSitemapVars->sitemapLimit; + } + + return $totalElements; } } diff --git a/src/models/SitemapIndexTemplate.php b/src/models/SitemapIndexTemplate.php index 6133f9d6c..9f82adbcc 100644 --- a/src/models/SitemapIndexTemplate.php +++ b/src/models/SitemapIndexTemplate.php @@ -19,6 +19,7 @@ use nystudio107\seomatic\events\RegisterSitemapsEvent; use nystudio107\seomatic\events\RegisterSitemapUrlsEvent; use nystudio107\seomatic\helpers\MetaValue as MetaValueHelper; +use nystudio107\seomatic\helpers\Sitemap; use nystudio107\seomatic\Seomatic; use yii\base\Event; use yii\caching\TagDependency; @@ -189,11 +190,7 @@ public function render(array $params = []): string $metaBundle->metaSitemapVars->sitemapLimit = null; } - $totalElements = $seoElement::sitemapElementsQuery($metaBundle)->count(); - - if ($metaBundle->metaSitemapVars->sitemapLimit && ($totalElements > $metaBundle->metaSitemapVars->sitemapLimit)) { - $totalElements = $metaBundle->metaSitemapVars->sitemapLimit; - } + $totalElements = Sitemap::getTotalElementsInSitemap($seoElement, $metaBundle); $pageSize = $metaBundle->metaSitemapVars->sitemapPageSize; $pageCount = (!empty($pageSize) && $pageSize > 0) ? ceil($totalElements / $pageSize) : 1;