nystudio107 /
craft-seomatic
| 1 | <?php |
||||||||||
| 2 | /** |
||||||||||
| 3 | * SEOmatic plugin for Craft CMS |
||||||||||
| 4 | * |
||||||||||
| 5 | * A turnkey SEO implementation for Craft CMS that is comprehensive, powerful, |
||||||||||
| 6 | * and flexible |
||||||||||
| 7 | * |
||||||||||
| 8 | * @link https://nystudio107.com |
||||||||||
| 9 | * @copyright Copyright (c) 2019 nystudio107 |
||||||||||
| 10 | */ |
||||||||||
| 11 | |||||||||||
| 12 | namespace nystudio107\seomatic\gql\resolvers; |
||||||||||
| 13 | |||||||||||
| 14 | use Craft; |
||||||||||
| 15 | use GraphQL\Type\Definition\ResolveInfo; |
||||||||||
| 16 | use nystudio107\seomatic\helpers\Gql as GqlHelper; |
||||||||||
| 17 | use nystudio107\seomatic\helpers\PluginTemplate; |
||||||||||
| 18 | use nystudio107\seomatic\helpers\Sitemap; |
||||||||||
| 19 | use nystudio107\seomatic\models\SitemapCustomTemplate; |
||||||||||
| 20 | use nystudio107\seomatic\models\SitemapIndexTemplate; |
||||||||||
| 21 | use nystudio107\seomatic\models\SitemapTemplate; |
||||||||||
| 22 | use nystudio107\seomatic\Seomatic; |
||||||||||
| 23 | use yii\web\NotFoundHttpException; |
||||||||||
| 24 | |||||||||||
| 25 | /** |
||||||||||
| 26 | * Class SitemapResolver |
||||||||||
| 27 | * |
||||||||||
| 28 | * @author nystudio107 |
||||||||||
| 29 | * @package Seomatic |
||||||||||
| 30 | * @since 3.4.18 |
||||||||||
| 31 | */ |
||||||||||
| 32 | class SitemapResolver |
||||||||||
| 33 | { |
||||||||||
| 34 | // Public Methods |
||||||||||
| 35 | // ========================================================================= |
||||||||||
| 36 | |||||||||||
| 37 | /** |
||||||||||
| 38 | * Get all the sitemaps. |
||||||||||
| 39 | */ |
||||||||||
| 40 | public static function getSitemaps($source, array $arguments, $context, ResolveInfo $resolveInfo) |
||||||||||
|
0 ignored issues
–
show
The parameter
$resolveInfo is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$context is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||||||||
| 41 | { |
||||||||||
| 42 | // If there's a filename provided, return the sitemap. |
||||||||||
| 43 | if (!empty($arguments['filename'])) { |
||||||||||
| 44 | return [ |
||||||||||
| 45 | self::getSitemapItemByFilename($arguments['filename']), |
||||||||||
| 46 | ]; |
||||||||||
| 47 | } |
||||||||||
| 48 | $siteId = GqlHelper::getSiteIdFromGqlArguments($arguments); |
||||||||||
| 49 | $site = Craft::$app->getSites()->getSiteById($siteId); |
||||||||||
| 50 | |||||||||||
| 51 | if (!$site) { |
||||||||||
| 52 | return []; |
||||||||||
| 53 | } |
||||||||||
| 54 | |||||||||||
| 55 | $sitemapList = []; |
||||||||||
| 56 | // If either of the source bundle arguments are present, get the sitemap |
||||||||||
| 57 | if (!empty($arguments['sourceBundleType']) || !empty($arguments['sourceBundleHandle'])) { |
||||||||||
| 58 | $filenames = self::createSitemapFilenamesFromComponents($site->groupId, $arguments['sourceBundleType'] ?? '', $arguments['sourceBundleHandle'] ?? '', $siteId); |
||||||||||
| 59 | |||||||||||
| 60 | foreach ($filenames as $filename) { |
||||||||||
| 61 | $sitemapList[] = self::getSitemapItemByFilename($filename); |
||||||||||
| 62 | } |
||||||||||
| 63 | |||||||||||
| 64 | return $sitemapList; |
||||||||||
| 65 | } |
||||||||||
| 66 | |||||||||||
| 67 | $sitemapIndexItems = [self::getSitemapIndexListEntry($siteId, $site->groupId)]; |
||||||||||
| 68 | |||||||||||
| 69 | $sitemapList = []; |
||||||||||
| 70 | // Scrape each index for individual entries |
||||||||||
| 71 | foreach ($sitemapIndexItems as $sitemapIndexItem) { |
||||||||||
| 72 | $contents = $sitemapIndexItem['contents']; |
||||||||||
| 73 | if (preg_match_all('/<loc>(.*?)<\/loc>/m', $contents, $matches)) { |
||||||||||
| 74 | foreach ($matches[1] as $url) { |
||||||||||
| 75 | $parts = explode('/', $url); |
||||||||||
| 76 | $filename = end($parts); |
||||||||||
| 77 | |||||||||||
| 78 | // Get individual sitemaps |
||||||||||
| 79 | $item = self::getSitemapItemByFilename($filename); |
||||||||||
| 80 | |||||||||||
| 81 | if ($item) { |
||||||||||
| 82 | $sitemapList[] = $item; |
||||||||||
| 83 | } |
||||||||||
| 84 | } |
||||||||||
| 85 | } |
||||||||||
| 86 | } |
||||||||||
| 87 | |||||||||||
| 88 | return $sitemapList; |
||||||||||
| 89 | } |
||||||||||
| 90 | |||||||||||
| 91 | /** |
||||||||||
| 92 | * Get all the sitemap index items by params. |
||||||||||
| 93 | * |
||||||||||
| 94 | * @return array |
||||||||||
| 95 | * @throws NotFoundHttpException |
||||||||||
| 96 | */ |
||||||||||
| 97 | public static function getSitemapIndexes($source, $arguments, $context, ResolveInfo $resolveInfo): array |
||||||||||
|
0 ignored issues
–
show
The parameter
$source is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$context is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$resolveInfo is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||||||||
| 98 | { |
||||||||||
| 99 | $siteId = GqlHelper::getSiteIdFromGqlArguments($arguments); |
||||||||||
| 100 | $groupId = Craft::$app->getSites()->getSiteById($siteId)->groupId; |
||||||||||
| 101 | |||||||||||
| 102 | $sitemapIndexListEntry = self::getSitemapIndexListEntry($siteId, $groupId); |
||||||||||
| 103 | |||||||||||
| 104 | return [ |
||||||||||
| 105 | $sitemapIndexListEntry, |
||||||||||
| 106 | ]; |
||||||||||
| 107 | } |
||||||||||
| 108 | |||||||||||
| 109 | /** |
||||||||||
| 110 | * @param $source |
||||||||||
| 111 | * @param $arguments |
||||||||||
| 112 | * @param $context |
||||||||||
| 113 | * @param ResolveInfo $resolveInfo |
||||||||||
| 114 | * @return array |
||||||||||
| 115 | */ |
||||||||||
| 116 | public static function getSitemapStyles($source, $arguments, $context, ResolveInfo $resolveInfo): array |
||||||||||
|
0 ignored issues
–
show
The parameter
$source is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$resolveInfo is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$context is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$arguments is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||||||||
| 117 | { |
||||||||||
| 118 | return [ |
||||||||||
| 119 | 'filename' => 'sitemap.xsl', |
||||||||||
| 120 | 'contents' => $xml = PluginTemplate::renderPluginTemplate('_frontend/pages/sitemap-styles.twig', []), |
||||||||||
|
0 ignored issues
–
show
|
|||||||||||
| 121 | ]; |
||||||||||
| 122 | } |
||||||||||
| 123 | |||||||||||
| 124 | /** |
||||||||||
| 125 | * @param $siteId |
||||||||||
| 126 | * @param $groupId |
||||||||||
| 127 | * @return array |
||||||||||
| 128 | * @throws NotFoundHttpException |
||||||||||
| 129 | */ |
||||||||||
| 130 | protected static function getSitemapIndexListEntry($siteId, $groupId): array |
||||||||||
| 131 | { |
||||||||||
| 132 | $sitemapIndex = SitemapIndexTemplate::create(); |
||||||||||
| 133 | $sitemapIndexItem = [ |
||||||||||
| 134 | 'filename' => $sitemapIndex->getFilename($groupId), |
||||||||||
| 135 | 'contents' => $sitemapIndex->render([ |
||||||||||
| 136 | 'siteId' => $siteId, |
||||||||||
| 137 | 'groupId' => $groupId, |
||||||||||
| 138 | ]), |
||||||||||
| 139 | ]; |
||||||||||
| 140 | |||||||||||
| 141 | return $sitemapIndexItem; |
||||||||||
| 142 | } |
||||||||||
| 143 | |||||||||||
| 144 | /** |
||||||||||
| 145 | * @param $filename |
||||||||||
| 146 | * @return array|null |
||||||||||
| 147 | * @throws NotFoundHttpException |
||||||||||
| 148 | */ |
||||||||||
| 149 | protected static function getSitemapItemByFilename($filename) |
||||||||||
| 150 | { |
||||||||||
| 151 | if (!preg_match('/sitemaps-(?P<groupId>\d+)-(?P<type>[\w\.*]+)-(?P<handle>[\w\.*]+)-(?P<siteId>\d+)-sitemap(-p(?P<page>\d+))?/i', $filename, $matches)) { |
||||||||||
| 152 | return null; |
||||||||||
| 153 | } |
||||||||||
| 154 | |||||||||||
| 155 | $isCustom = $matches['type'] == 'global' && $matches['handle'] == 'custom'; |
||||||||||
| 156 | $sitemap = $isCustom ? SitemapCustomTemplate::create() : SitemapTemplate::create(); |
||||||||||
| 157 | |||||||||||
| 158 | return [ |
||||||||||
| 159 | 'filename' => $filename, |
||||||||||
| 160 | 'contents' => $sitemap->render(array_merge($matches, ['immediately' => true])), |
||||||||||
| 161 | ]; |
||||||||||
| 162 | } |
||||||||||
| 163 | |||||||||||
| 164 | /** |
||||||||||
| 165 | * Construct the expected sitemap filename from the components |
||||||||||
| 166 | * |
||||||||||
| 167 | * @param int $groupId |
||||||||||
| 168 | * @param string $bundleType |
||||||||||
| 169 | * @param string $bundleHandle |
||||||||||
| 170 | * @param int $siteId |
||||||||||
| 171 | * @return array |
||||||||||
| 172 | */ |
||||||||||
| 173 | protected static function createSitemapFilenamesFromComponents(int $groupId, string $bundleType, string $bundleHandle, int $siteId): array |
||||||||||
| 174 | { |
||||||||||
| 175 | $metaBundle = Seomatic::$plugin->metaBundles->getMetaBundleBySourceHandle($bundleType, $bundleHandle, $siteId); |
||||||||||
| 176 | if (!$metaBundle) { |
||||||||||
| 177 | return []; |
||||||||||
| 178 | } |
||||||||||
| 179 | |||||||||||
| 180 | $pageSize = $metaBundle->metaSitemapVars->sitemapPageSize ?? null; |
||||||||||
| 181 | if (!$pageSize) { |
||||||||||
|
0 ignored issues
–
show
The expression
$pageSize of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
Loading history...
|
|||||||||||
| 182 | return ["sitemaps-$groupId-$bundleType-$bundleHandle-$siteId-sitemap.xml"]; |
||||||||||
| 183 | } |
||||||||||
| 184 | |||||||||||
| 185 | $sitemapFilenames = []; |
||||||||||
| 186 | $seoElement = Seomatic::$plugin->seoElements->getSeoElementByMetaBundleType($metaBundle->sourceBundleType); |
||||||||||
| 187 | if ($seoElement) { |
||||||||||
| 188 | $totalElements = Sitemap::getTotalElementsInSitemap($seoElement, $metaBundle); |
||||||||||
| 189 | $pageCount = $pageSize > 0 ? ceil($totalElements / $pageSize) : 1; |
||||||||||
| 190 | |||||||||||
| 191 | for ($page = 1; $page <= $pageCount; $page++) { |
||||||||||
| 192 | $sitemapFilenames[] = sprintf('sitemaps-%d-%s-%s-%d-sitemap-p%d.xml', $groupId, $bundleType, $bundleHandle, $siteId, $page); |
||||||||||
| 193 | } |
||||||||||
| 194 | } |
||||||||||
| 195 | |||||||||||
| 196 | return $sitemapFilenames; |
||||||||||
| 197 | } |
||||||||||
| 198 | } |
||||||||||
| 199 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.