Passed
Push — v3 ( 11cdfe...6c8e4b )
by Andrew
23:08 queued 17s
created

createSitemapFilenamesFromComponents()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
eloc 14
c 0
b 0
f 0
dl 0
loc 24
ccs 0
cts 15
cp 0
rs 9.2222
cc 6
nc 5
nop 4
crap 42
1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS 3.x
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
     * @param $source
39
     * @param array $arguments
40
     * @param $context
41
     * @param ResolveInfo $resolveInfo
42
     * @return array|array[]|null[]
43
     * @throws NotFoundHttpException
44
     */
45
    public static function getSitemaps($source, array $arguments, $context, ResolveInfo $resolveInfo)
0 ignored issues
show
Unused Code introduced by
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 ignore-unused  annotation

45
    public static function getSitemaps(/** @scrutinizer ignore-unused */ $source, array $arguments, $context, ResolveInfo $resolveInfo)

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...
Unused Code introduced by
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 ignore-unused  annotation

45
    public static function getSitemaps($source, array $arguments, $context, /** @scrutinizer ignore-unused */ ResolveInfo $resolveInfo)

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...
Unused Code introduced by
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 ignore-unused  annotation

45
    public static function getSitemaps($source, array $arguments, /** @scrutinizer ignore-unused */ $context, ResolveInfo $resolveInfo)

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...
46
    {
47
        // If there's a filename provided, return the sitemap.
48
        if (!empty($arguments['filename'])) {
49
            return [
50
                self::getSitemapItemByFilename($arguments['filename']),
51
            ];
52
        }
53
        $siteId = GqlHelper::getSiteIdFromGqlArguments($arguments);
54
        $site = Craft::$app->getSites()->getSiteById($siteId);
55
56
        if (!$site) {
57
            return [];
58
        }
59
60
        $sitemapList = [];
61
        // If either of the source bundle arguments are present, get the sitemap
62
        if (!empty($arguments['sourceBundleType']) || !empty($arguments['sourceBundleHandle'])) {
63
            $filenames = self::createSitemapFilenamesFromComponents($site->groupId, $arguments['sourceBundleType'] ?? '', $arguments['sourceBundleHandle'] ?? '', $siteId);
64
65
            foreach ($filenames as $filename) {
66
                $sitemapList[] = self::getSitemapItemByFilename($filename);
67
            }
68
69
            return $sitemapList;
70
        }
71
72
        $sitemapIndexItems = [self::getSitemapIndexListEntry($siteId, $site->groupId)];
73
74
        // Scrape each index for individual entries
75
        foreach ($sitemapIndexItems as $sitemapIndexItem) {
76
            $contents = $sitemapIndexItem['contents'];
77
            if (preg_match_all('/<loc>(.*?)<\/loc>/m', $contents, $matches)) {
78
                foreach ($matches[1] as $url) {
79
                    $parts = explode('/', $url);
80
                    $filename = end($parts);
81
82
                    // Get individual sitemaps
83
                    $item = self::getSitemapItemByFilename($filename);
84
85
                    if ($item) {
86
                        $sitemapList[] = $item;
87
                    }
88
                }
89
            }
90
        }
91
92
        return $sitemapList;
93
    }
94
95
    /**
96
     * @param $source
97
     * @param $arguments
98
     * @param $context
99
     * @param ResolveInfo $resolveInfo
100
     * @return array[]
101
     * @throws NotFoundHttpException
102
     */
103
    public static function getSitemapIndexes($source, $arguments, $context, ResolveInfo $resolveInfo): array
0 ignored issues
show
Unused Code introduced by
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 ignore-unused  annotation

103
    public static function getSitemapIndexes(/** @scrutinizer ignore-unused */ $source, $arguments, $context, ResolveInfo $resolveInfo): array

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...
Unused Code introduced by
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 ignore-unused  annotation

103
    public static function getSitemapIndexes($source, $arguments, $context, /** @scrutinizer ignore-unused */ ResolveInfo $resolveInfo): array

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...
Unused Code introduced by
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 ignore-unused  annotation

103
    public static function getSitemapIndexes($source, $arguments, /** @scrutinizer ignore-unused */ $context, ResolveInfo $resolveInfo): array

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...
104
    {
105
        $siteId = GqlHelper::getSiteIdFromGqlArguments($arguments);
106
        $groupId = Craft::$app->getSites()->getSiteById($siteId)->groupId;
107
108
        $sitemapIndexListEntry = self::getSitemapIndexListEntry($siteId, $groupId);
109
110
        return [
111
            $sitemapIndexListEntry,
112
        ];
113
    }
114
115
    /**
116
     * @param $source
117
     * @param $arguments
118
     * @param $context
119
     * @param ResolveInfo $resolveInfo
120
     * @return array
121
     */
122
    public static function getSitemapStyles($source, $arguments, $context, ResolveInfo $resolveInfo): array
0 ignored issues
show
Unused Code introduced by
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 ignore-unused  annotation

122
    public static function getSitemapStyles(/** @scrutinizer ignore-unused */ $source, $arguments, $context, ResolveInfo $resolveInfo): array

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...
Unused Code introduced by
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 ignore-unused  annotation

122
    public static function getSitemapStyles($source, /** @scrutinizer ignore-unused */ $arguments, $context, ResolveInfo $resolveInfo): array

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...
Unused Code introduced by
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 ignore-unused  annotation

122
    public static function getSitemapStyles($source, $arguments, $context, /** @scrutinizer ignore-unused */ ResolveInfo $resolveInfo): array

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...
Unused Code introduced by
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 ignore-unused  annotation

122
    public static function getSitemapStyles($source, $arguments, /** @scrutinizer ignore-unused */ $context, ResolveInfo $resolveInfo): array

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...
123
    {
124
        return [
125
            'filename' => 'sitemap.xsl',
126
            'contents' => $xml = PluginTemplate::renderPluginTemplate('_frontend/pages/sitemap-styles.twig', []),
0 ignored issues
show
Unused Code introduced by
The assignment to $xml is dead and can be removed.
Loading history...
127
        ];
128
    }
129
130
    /**
131
     * @param $siteId
132
     * @param $groupId
133
     * @return array
134
     * @throws NotFoundHttpException
135
     */
136
    protected static function getSitemapIndexListEntry($siteId, $groupId): array
137
    {
138
        $sitemapIndex = SitemapIndexTemplate::create();
139
        if ($sitemapIndex) {
0 ignored issues
show
introduced by
$sitemapIndex is of type nystudio107\seomatic\models\SitemapIndexTemplate, thus it always evaluated to true.
Loading history...
140
            return [
141
                'filename' => $sitemapIndex->getFilename($groupId),
142
                'contents' => $sitemapIndex->render([
143
                    'siteId' => $siteId,
144
                    'groupId' => $groupId,
145
                ]),
146
            ];
147
        }
148
149
        return [];
150
    }
151
152
    /**
153
     * @param $filename
154
     * @return array|null
155
     * @throws NotFoundHttpException
156
     */
157
    protected static function getSitemapItemByFilename($filename)
158
    {
159
        if (!preg_match('/sitemaps-(?P<groupId>\d+)-(?P<type>[\w\.*]+)-(?P<handle>[\w\.*]+)-(?P<siteId>\d+)-sitemap(-p(?P<page>\d+))?/i', $filename, $matches)) {
160
            return null;
161
        }
162
163
        $isCustom = $matches['type'] == 'global' && $matches['handle'] == 'custom';
164
        $sitemap = $isCustom ? SitemapCustomTemplate::create() : SitemapTemplate::create();
165
166
        return [
167
            'filename' => $filename,
168
            'contents' => $sitemap->render(array_merge($matches, ['immediately' => true])),
169
        ];
170
    }
171
172
    /**
173
     * Construct the expected sitemap filename from the components
174
     *
175
     * @param int $groupId
176
     * @param string $bundleType
177
     * @param string $bundleHandle
178
     * @param int $siteId
179
     * @return array
180
     */
181
    protected static function createSitemapFilenamesFromComponents(int $groupId, string $bundleType, string $bundleHandle, int $siteId): array
182
    {
183
        $metaBundle = Seomatic::$plugin->metaBundles->getMetaBundleBySourceHandle($bundleType, $bundleHandle, $siteId);
184
        if (!$metaBundle) {
185
            return [];
186
        }
187
188
        $pageSize = $metaBundle->metaSitemapVars->sitemapPageSize ?? null;
189
        if (!$pageSize) {
0 ignored issues
show
Bug Best Practice introduced by
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 ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

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...
190
            return ["sitemaps-$groupId-$bundleType-$bundleHandle-$siteId-sitemap.xml"];
191
        }
192
193
        $sitemapFilenames = [];
194
        $seoElement = Seomatic::$plugin->seoElements->getSeoElementByMetaBundleType($metaBundle->sourceBundleType);
195
        if ($seoElement) {
196
            $totalElements = Sitemap::getTotalElementsInSitemap($seoElement, $metaBundle);
197
            $pageCount = $pageSize > 0 ? ceil($totalElements / $pageSize) : 1;
198
199
            for ($page = 1; $page <= $pageCount; $page++) {
200
                $sitemapFilenames[] = sprintf('sitemaps-%d-%s-%s-%d-sitemap-p%d.xml', $groupId, $bundleType, $bundleHandle, $siteId, $page);
201
            }
202
        }
203
204
        return $sitemapFilenames;
205
    }
206
}
207