Passed
Push — v3 ( 53e94e...6511ed )
by Andrew
40:04 queued 16:36
created

Events::getAllElementUris()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 23
ccs 0
cts 21
cp 0
rs 9.4888
cc 5
nc 2
nop 1
crap 30
1
<?php
2
/**
3
 * Retour plugin for Craft CMS 3.x
4
 *
5
 * Retour allows you to intelligently redirect legacy URLs, so that you don't
6
 * lose SEO value when rebuilding & restructuring a website
7
 *
8
 * @link      https://nystudio107.com/
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
9
 * @copyright Copyright (c) 2018 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
10
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
11
12
namespace nystudio107\retour\services;
13
14
use nystudio107\retour\events\RedirectEvent;
15
use nystudio107\retour\Retour;
16
use nystudio107\retour\helpers\UrlHelper;
17
18
use Craft;
19
use craft\base\Component;
20
use craft\base\Element;
21
use craft\helpers\ElementHelper;
22
23
use yii\base\Exception;
24
25
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
26
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Coding Style introduced by
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
27
 * @package   Retour
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
28
 * @since     3.1.64
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
29
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
30
class Events extends Component
31
{
32
    // Constants
33
    // =========================================================================
34
35
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
36
     * @event RedirectEvent The event that is triggered before an Entry redirect is automatically
37
     * saved when an Entry's URI is changed (assuming the **Create Entry Redirects** setting is enabled).
38
     * You may set [[RedirectEvent::isValid]] to `false` to prevent the redirect from getting saved.
39
     *
40
     * ```php
41
     * use nystudio107\retour\services\Events;
42
     * use nystudio107\retour\events\RedirectEvent;
43
     *
44
     * Event::on(Events::class,
45
     *     Redirects::EVENT_BEFORE_SAVE_ENTRY_REDIRECT,
46
     *     function(RedirectEvent $event) {
47
     *         // potentially set $event->isValid;
48
     *     }
49
     * );
50
     * ```
51
     */
52
    const EVENT_BEFORE_SAVE_ENTRY_REDIRECT = 'beforeSaveEntryRedirect';
53
54
    // Public Properties
55
    // =========================================================================
56
57
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
58
     * @var array The URIs for the element before it was saved
59
     */
60
    public $oldElementUris = [];
61
62
    // Public Methods
63
    // =========================================================================
64
65
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
66
     * @param $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
67
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
68
    public function stashElementUris($element)
69
    {
70
        // Stash the old URLs by element id, and do so only once,
71
        // in case we are called more than once per request
72
        if (empty($this->oldElementUris[$element->id])) {
73
            $this->oldElementUris[$element->id] = $this->getAllElementUris($element);
74
        }
75
    }
76
77
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
78
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
79
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
80
    public function handleElementUriChange(Element $element)
81
    {
82
        $uris = $this->getAllElementUris($element);
83
        if (!empty($this->oldElementUris[$element->id])) {
84
            $oldElementUris = $this->oldElementUris[$element->id];
85
            foreach ($uris as $siteId => $newUri) {
86
                if (!empty($oldElementUris[$siteId])) {
87
                    $oldUri = $oldElementUris[$siteId];
88
                    Craft::debug(
89
                        Craft::t(
90
                            'retour',
91
                            'Comparing old: {oldUri} to new: {newUri}',
92
                            ['oldUri' => print_r($oldUri, true), 'newUri' => print_r($newUri, true)]
93
                        ),
94
                        __METHOD__
95
                    );
96
                    // Handle the siteId
97
                    $redirectSiteId = null;
98
                    if (Craft::$app->getIsMultiSite()) {
99
                        $redirectSiteId = $siteId;
100
                    }
101
                    // Make sure the URIs are not the same
102
                    if (strcmp($oldUri, $newUri) !== 0) {
103
                        // Handle trailing slash config setting
104
                        if (Craft::$app->config->general->addTrailingSlashesToUrls) {
105
                            $oldUri = rtrim($oldUri, '/') . '/';
106
                            $newUri = rtrim($newUri, '/') . '/';
107
                        }
108
                        // Handle the URL match type
109
                        if (Retour::$settings->uriChangeRedirectSrcMatch === 'fullurl') {
110
                            try {
111
                                if ($redirectSiteId !== null) {
112
                                    $redirectSiteId = (int)$redirectSiteId;
113
                                }
114
                                $oldUri = \craft\helpers\UrlHelper::siteUrl($oldUri, null, null, $redirectSiteId);
115
                                $newUri = UrlHelper::siteUrl($newUri, null, null, $redirectSiteId);
116
                            } catch (Exception $e) {
117
                                // That's fine
118
                            }
119
                        }
120
                        $redirectConfig = [
121
                            'id' => 0,
122
                            'redirectMatchType' => 'exactmatch',
123
                            'redirectHttpCode' => 301,
124
                            'redirectSrcMatch' => Retour::$settings->uriChangeRedirectSrcMatch,
125
                            'redirectSrcUrl' => $oldUri,
126
                            'redirectDestUrl' => $newUri,
127
                            'siteId' => $redirectSiteId,
128
                        ];
129
                        // Trigger a 'beforeSaveEntryRedirect' event
130
                        $isNew = (int)$redirectConfig['id'] === 0;
131
                        $event = new RedirectEvent([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
132
                            'isNew' => $isNew,
133
                            'legacyUrl' => $redirectConfig['redirectSrcUrlParsed'],
134
                            'destinationUrl' => $redirectConfig['redirectDestUrl'],
135
                            'matchType' => $redirectConfig['redirectSrcMatch'],
136
                            'redirectType' => $redirectConfig['redirectHttpCode'],
137
                            'siteId' => $redirectConfig['siteId'],
138
                        ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
139
                        $this->trigger(self::EVENT_BEFORE_SAVE_ENTRY_REDIRECT, $event);
140
                        if (!$event->isValid) {
141
                            return;
142
                        }
143
                        Retour::$plugin->redirects->saveRedirect($redirectConfig);
144
                    }
145
                }
146
            }
147
        }
148
    }
149
150
    /**
151
     * Get the URIs for each site for the element
152
     *
153
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
154
     *
155
     * @return array
156
     */
157
    protected function getAllElementUris(Element $element): array
158
    {
159
        $uris = [];
160
        if (!Retour::$craft32 || !ElementHelper::isDraftOrRevision($element)) {
161
            $sites = Craft::$app->getSites()->getAllSites();
162
            foreach ($sites as $site) {
163
                $uri = Craft::$app->getElements()->getElementUriForSite($element->id, $site->id);
164
                if ($uri !== null) {
165
                    $uris[$site->id] = $uri;
166
                }
167
            }
168
        }
169
170
        Craft::debug(
171
            Craft::t(
172
                'retour',
173
                'Getting Element URIs: {uris}',
174
                ['uris' => print_r($uris, true)]
175
            ),
176
            __METHOD__
177
        );
178
179
        return $uris;
180
    }
181
}
182