Passed
Push — develop ( fc793b...3984b9 )
by Andrew
06:39
created

SeoEvent::fieldLayouts()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 7
nop 1
dl 0
loc 20
rs 9.5222
c 0
b 0
f 0
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\seoelements;
13
14
use nystudio107\seomatic\Seomatic;
15
use nystudio107\seomatic\base\SeoElementInterface;
16
use nystudio107\seomatic\helpers\ArrayHelper;
17
use nystudio107\seomatic\helpers\Config as ConfigHelper;
18
use nystudio107\seomatic\models\MetaBundle;
19
20
use Craft;
21
use craft\base\ElementInterface;
22
use craft\base\Model;
23
use craft\elements\db\ElementQueryInterface;
24
use craft\models\Site;
25
26
use Solspace\Calendar\Calendar as CalendarPlugin;
0 ignored issues
show
Bug introduced by
The type Solspace\Calendar\Calendar was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Solspace\Calendar\Elements\Event;
0 ignored issues
show
Bug introduced by
The type Solspace\Calendar\Elements\Event was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Solspace\Calendar\Events\SaveModelEvent;
0 ignored issues
show
Bug introduced by
The type Solspace\Calendar\Events\SaveModelEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use Solspace\Calendar\Models\CalendarModel;
0 ignored issues
show
Bug introduced by
The type Solspace\Calendar\Models\CalendarModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use Solspace\Calendar\Services\CalendarsService;
0 ignored issues
show
Bug introduced by
The type Solspace\Calendar\Services\CalendarsService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
32
use yii\base\Event as BaseEvent;
33
34
/**
35
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
36
 * @package   Seomatic
37
 * @since     3.2.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
38
 */
0 ignored issues
show
Coding Style introduced by
Missing @license tag in class comment
Loading history...
39
class SeoEvent implements SeoElementInterface
40
{
41
    // Constants
42
    // =========================================================================
43
44
    const META_BUNDLE_TYPE = 'event';
45
    const ELEMENT_CLASSES = [
46
        Event::class,
47
    ];
48
    const REQUIRED_PLUGIN_HANDLE = 'calendar';
49
    const CONFIG_FILE_PATH = 'eventmeta/Bundle';
50
51
    // Public Static Methods
52
    // =========================================================================
53
54
    /**
55
     * Return the sourceBundleType for that this SeoElement handles
56
     *
57
     * @return string
58
     */
59
    public static function getMetaBundleType(): string
60
    {
61
        return self::META_BUNDLE_TYPE;
62
    }
63
64
    /**
65
     * Returns an array of the element classes that are handled by this SeoElement
66
     *
67
     * @return array
68
     */
69
    public static function getElementClasses(): array
70
    {
71
        return self::ELEMENT_CLASSES;
72
    }
73
74
    /**
75
     * Return the refHandle (e.g.: `entry` or `category`) for the SeoElement
76
     *
77
     * @return string
78
     */
79
    public static function getElementRefHandle(): string
80
    {
81
        return Event::refHandle() ?? 'event';
82
    }
83
84
    /**
85
     * Return the handle to a required plugin for this SeoElement type
86
     *
87
     * @return null|string
88
     */
89
    public static function getRequiredPluginHandle()
90
    {
91
        return self::REQUIRED_PLUGIN_HANDLE;
92
    }
93
94
    /**
95
     * Install any event handlers for this SeoElement type
96
     */
97
    public static function installEventHandlers()
98
    {
99
        $request = Craft::$app->getRequest();
100
101
        // Install for all non-console requests
102
        if (!$request->getIsConsoleRequest()) {
103
            // Handler: CalendarsService::EVENT_AFTER_SAVE
104
            BaseEvent::on(
105
                CalendarsService::class,
106
                CalendarsService::EVENT_AFTER_SAVE,
107
                function (SaveModelEvent $event) {
108
                    Craft::debug(
109
                        'CalendarsService::EVENT_AFTER_SAVE',
110
                        __METHOD__
111
                    );
112
                    /** @var CalendarModel $calendarModel */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
113
                    $calendarModel = $event->getModel();
114
                    if ($calendarModel !== null && $calendarModel->id !== null) {
115
                        Seomatic::$plugin->metaBundles->invalidateMetaBundleById(
116
                            SeoEvent::getMetaBundleType(),
117
                            $calendarModel->id,
118
                            $event->isNew()
119
                        );
120
                        // Create the meta bundles for this Event if it's new
121
                        if ($event->isNew()) {
122
                            SeoEvent::createContentMetaBundle($calendarModel);
123
                            Seomatic::$plugin->sitemaps->submitSitemapIndex();
124
                        }
125
                    }
126
                }
127
            );
128
            // Handler: CalendarsService::EVENT_AFTER_DELETE
129
            BaseEvent::on(
130
                CalendarsService::class,
131
                CalendarsService::EVENT_AFTER_DELETE,
132
                function (SaveModelEvent $event) {
133
                    Craft::debug(
134
                        'CalendarsService::EVENT_AFTER_DELETE',
135
                        __METHOD__
136
                    );
137
                    /** @var CalendarModel $calendarModel */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
138
                    $calendarModel = $event->getModel();
139
                    if ($calendarModel !== null && $calendarModel->id !== null) {
140
                        Seomatic::$plugin->metaBundles->invalidateMetaBundleById(
141
                            SeoEvent::getMetaBundleType(),
142
                            $calendarModel->id,
143
                            false
144
                        );
145
                        // Delete the meta bundles for this Event
146
                        Seomatic::$plugin->metaBundles->deleteMetaBundleBySourceId(
147
                            SeoEvent::getMetaBundleType(),
148
                            $calendarModel->id
149
                        );
150
                    }
151
                }
152
            );
153
        }
154
155
        // Install only for non-console site requests
156
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
157
        }
158
159
        // Install only for non-console Control Panel requests
160
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
161
        }
162
    }
163
164
    /**
165
     * Return an ElementQuery for the sitemap elements for the given MetaBundle
166
     *
167
     * @param MetaBundle $metaBundle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
168
     *
169
     * @return ElementQueryInterface
170
     */
171
    public static function sitemapElementsQuery(MetaBundle $metaBundle): ElementQueryInterface
172
    {
173
        $query = Event::find()
174
            ->setCalendar($metaBundle->sourceHandle)
175
            ->siteId($metaBundle->sourceSiteId)
176
            ->limit($metaBundle->metaSitemapVars->sitemapLimit)
177
            ->enabledForSite(true);
178
179
        return $query;
180
    }
181
182
    /**
183
     * Return an ElementInterface for the sitemap alt element for the given MetaBundle
184
     * and Element ID
185
     *
186
     * @param MetaBundle $metaBundle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
187
     * @param int        $elementId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
188
     * @param int        $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
189
     *
190
     * @return null|ElementInterface
191
     */
192
    public static function sitemapAltElement(
193
        MetaBundle $metaBundle,
194
        int $elementId,
195
        int $siteId
196
    ): ElementInterface {
197
        return Event::find()
198
            ->id($elementId)
199
            ->siteId($siteId)
200
            ->limit(1)
201
            ->enabledForSite(true)
202
            ->one();
203
    }
204
205
    /**
206
     * Return a preview URI for a given $sourceHandle and $siteId
207
     * This just returns the first element
208
     *
209
     * @param string    $sourceHandle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter type; 4 found
Loading history...
210
     * @param int|null  $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
211
     *
212
     * @return string|null
213
     */
214
    public static function previewUri(string $sourceHandle, $siteId)
215
    {
216
        $uri = null;
217
        $element = Event::find()
218
            ->setCalendar($sourceHandle)
219
            ->siteId($siteId)
220
            ->one();
221
        if ($element) {
222
            $uri = $element->uri;
223
        }
224
225
        return $uri;
226
    }
227
228
    /**
229
     * Return an array of FieldLayouts from the $sourceHandle
230
     *
231
     * @param string $sourceHandle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
232
     *
233
     * @return array
234
     */
235
    public static function fieldLayouts(string $sourceHandle): array
236
    {
237
        $layouts = [];
238
        $calendar = CalendarPlugin::getInstance();
239
        if ($calendar !== null) {
240
            $layoutId = null;
241
            try {
242
                $calendarModel = $calendar->calendars->getCalendarByHandle($sourceHandle);
243
                if ($calendarModel) {
244
                    $layoutId = $calendarModel->fieldLayoutId;
245
                }
246
            } catch (\Exception $e) {
247
                $layoutId = null;
248
            }
249
            if ($layoutId) {
250
                $layouts[] = Craft::$app->getFields()->getLayoutById($layoutId);
251
            }
252
        }
253
254
        return $layouts;
255
    }
256
257
    /**
258
     * Return the source model of the given $sourceId
259
     *
260
     * @param int $sourceId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
261
     *
262
     * @return CalendarModel|null
263
     */
264
    public static function sourceModelFromId(int $sourceId)
265
    {
266
        $calendarModel = null;
267
        $calendar = CalendarPlugin::getInstance();
268
        if ($calendar !== null) {
269
            $calendarModel = $calendar->calendars->getCalendarById($sourceId);
270
        }
271
272
        return $calendarModel;
273
    }
274
275
    /**
276
     * Return the source model of the given $sourceId
277
     *
278
     * @param string $sourceHandle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
279
     *
280
     * @return CalendarModel|null
281
     */
282
    public static function sourceModelFromHandle(string $sourceHandle)
283
    {
284
        $calendarModel = null;
285
        $calendar = CalendarPlugin::getInstance();
286
        if ($calendar !== null) {
287
            $calendarModel = $calendar->calendars->getCalendarByHandle($sourceHandle);
288
        }
289
290
        return $calendarModel;
291
    }
292
293
    /**
294
     * Return the most recently updated Element from a given source model
295
     *
296
     * @param Model $sourceModel
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
297
     * @param int   $sourceSiteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
298
     *
299
     * @return ElementInterface
300
     */
301
    public static function mostRecentElement(Model $sourceModel, int $sourceSiteId): ElementInterface
302
    {
303
        /** @var CalendarModel $sourceModel */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
304
        return Event::find()
305
            ->setCalendar($sourceModel->handle)
306
            ->siteId($sourceSiteId)
307
            ->limit(1)
308
            ->orderBy(['elements.dateUpdated' => SORT_DESC])
309
            ->one();
310
    }
311
312
    /**
313
     * Return the path to the config file directory
314
     *
315
     * @return string
316
     */
317
    public static function configFilePath(): string
318
    {
319
        return self::CONFIG_FILE_PATH;
320
    }
321
322
    /**
323
     * Return a meta bundle config array for the given $sourceModel
324
     *
325
     * @param Model $sourceModel
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
326
     *
327
     * @return array
328
     */
329
    public static function metaBundleConfig(Model $sourceModel): array
330
    {
331
        /** @var CalendarModel $sourceModel */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
332
        return ArrayHelper::merge(
333
            ConfigHelper::getConfigFromFile(self::configFilePath()),
334
            [
335
                'sourceId' => $sourceModel->id,
336
                'sourceName' => $sourceModel->name,
337
                'sourceHandle' => $sourceModel->handle,
338
            ]
339
        );
340
    }
341
342
    /**
343
     * Return the source id from the $element
344
     *
345
     * @param ElementInterface $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
346
     *
347
     * @return int|null
348
     */
349
    public static function sourceIdFromElement(ElementInterface $element)
350
    {
351
        /** @var Event $element */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
352
        return $element->calendarId;
353
    }
354
355
    /**
356
     * Return the source handle from the $element
357
     *
358
     * @param ElementInterface $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
359
     *
360
     * @return string|null
361
     */
362
    public static function sourceHandleFromElement(ElementInterface $element)
363
    {
364
        $sourceHandle = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $sourceHandle is dead and can be removed.
Loading history...
365
        /** @var Event $element */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
366
        try {
367
            $sourceHandle = $element->getCalendar()->handle;
368
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
369
        }
370
371
        return $sourceHandle;
372
    }
373
374
    /**
375
     * Create a MetaBundle in the db for each site, from the passed in $sourceModel
376
     *
377
     * @param Model $sourceModel
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
378
     */
379
    public static function createContentMetaBundle(Model $sourceModel)
380
    {
381
        /** @var CalendarModel $sourceModel */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
382
        $sites = Craft::$app->getSites()->getAllSites();
383
        /** @var Site $site */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
384
        foreach ($sites as $site) {
385
            $seoElement = self::class;
386
            /** @var SeoElementInterface $seoElement */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
387
            Seomatic::$plugin->metaBundles->createMetaBundleFromSeoElement($seoElement, $sourceModel, $site->id);
388
        }
389
    }
390
391
    /**
392
     * Create all the MetaBundles in the db for this Seo Element
393
     */
394
    public static function createAllContentMetaBundles()
395
    {
396
        $calendar = CalendarPlugin::getInstance();
397
        if ($calendar !== null) {
398
            // Get all of the calendars with URLs
399
            $calendarModels = $calendar->calendars->getAllCalendars();
400
            foreach ($calendarModels as $calendarModel) {
401
                self::createContentMetaBundle($calendarModel);
402
            }
403
        }
404
    }
405
}
406