Passed
Push — develop ( 9e1ae0...eca734 )
by Andrew
08:01
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 craft\base\Element;
15
use craft\helpers\ElementHelper;
16
use nystudio107\retour\events\RedirectEvent;
17
use nystudio107\retour\Retour;
18
use nystudio107\retour\helpers\UrlHelper;
19
20
use Craft;
21
use craft\base\Component;
22
use yii\base\Exception;
23
24
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
25
 * @author    nystudio107
0 ignored issues
show
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...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
26
 * @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...
27
 * @since     3.1.64
0 ignored issues
show
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
28
 */
0 ignored issues
show
Coding Style introduced by
Missing @link tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @category tag in class comment
Loading history...
29
class Events extends Component
30
{
31
    // Constants
32
    // =========================================================================
33
34
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
35
     * @event RedirectEvent The event that is triggered before an Entry redirect is automatically
36
     * saved when an Entry's URI is changed (assuming the **Create Entry Redirects** setting is enabled).
37
     * You may set [[RedirectEvent::isValid]] to `false` to prevent the redirect from getting saved.
38
     *
39
     * ```php
40
     * use nystudio107\retour\services\Events;
41
     * use nystudio107\retour\events\RedirectEvent;
42
     *
43
     * Event::on(Events::class,
44
     *     Redirects::EVENT_BEFORE_SAVE_ENTRY_REDIRECT,
45
     *     function(RedirectEvent $event) {
46
     *         // potentially set $event->isValid;
47
     *     }
48
     * );
49
     * ```
50
     */
51
    const EVENT_BEFORE_SAVE_ENTRY_REDIRECT = 'beforeSaveEntryRedirect';
52
53
    // Public Properties
54
    // =========================================================================
55
56
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
57
     * @var array The URIs for the element before it was saved
58
     */
59
    public $oldElementUris = [];
60
61
    // Public Methods
62
    // =========================================================================
63
64
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
65
     * @param $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
66
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
67
    public function stashElementUris($element)
68
    {
69
        // Stash the old URLs by element id, and do so only once,
70
        // in case we are called more than once per request
71
        if (empty($this->oldElementUris[$element->id])) {
72
            $this->oldElementUris[$element->id] = $this->getAllElementUris($element);
73
        }
74
    }
75
76
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
77
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
78
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
79
    public function handleElementUriChange(Element $element)
80
    {
81
        $uris = $this->getAllElementUris($element);
82
        if (!empty($this->oldElementUris[$element->id])) {
83
            $oldElementUris = $this->oldElementUris[$element->id];
84
            foreach ($uris as $siteId => $newUri) {
85
                if (!empty($oldElementUris[$siteId])) {
86
                    $oldUri = $oldElementUris[$siteId];
87
                    Craft::debug(
88
                        Craft::t(
89
                            'retour',
90
                            'Comparing old: {oldUri} to new: {newUri}',
91
                            ['oldUri' => print_r($oldUri, true), 'newUri' => print_r($newUri, true)]
92
                        ),
93
                        __METHOD__
94
                    );
95
                    // Handle the siteId
96
                    $redirectSiteId = null;
97
                    if (Craft::$app->getIsMultiSite()) {
98
                        $redirectSiteId = $siteId;
99
                    }
100
                    // Make sure the URIs are not the same
101
                    if (strcmp($oldUri, $newUri) !== 0) {
102
                        // Handle trailing slash config setting
103
                        if (Craft::$app->config->general->addTrailingSlashesToUrls) {
104
                            $oldUri = rtrim($oldUri, '/') . '/';
105
                            $newUri = rtrim($newUri, '/') . '/';
106
                        }
107
                        // Handle the URL match type
108
                        if (Retour::$settings->uriChangeRedirectSrcMatch === 'fullurl') {
109
                            try {
110
                                if ($redirectSiteId !== null) {
111
                                    $redirectSiteId = (int)$redirectSiteId;
112
                                }
113
                                $oldUri = \craft\helpers\UrlHelper::siteUrl($oldUri, null, null, $redirectSiteId);
114
                                $newUri = UrlHelper::siteUrl($newUri, null, null, $redirectSiteId);
115
                            } catch (Exception $e) {
116
                                // That's fine
117
                            }
118
                        }
119
                        $redirectConfig = [
120
                            'id' => 0,
121
                            'redirectMatchType' => 'exactmatch',
122
                            'redirectHttpCode' => 301,
123
                            'redirectSrcMatch' => Retour::$settings->uriChangeRedirectSrcMatch,
124
                            'redirectSrcUrl' => $oldUri,
125
                            'redirectDestUrl' => $newUri,
126
                            'siteId' => $redirectSiteId,
127
                        ];
128
                        // Trigger a 'beforeSaveEntryRedirect' event
129
                        $isNew = (int)$redirectConfig['id'] === 0;
130
                        $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...
131
                            'isNew' => $isNew,
132
                            'legacyUrl' => $redirectConfig['redirectSrcUrlParsed'],
133
                            'destinationUrl' => $redirectConfig['redirectDestUrl'],
134
                            'matchType' => $redirectConfig['redirectSrcMatch'],
135
                            'redirectType' => $redirectConfig['redirectHttpCode'],
136
                            'siteId' => $redirectConfig['siteId'],
137
                        ]);
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...
138
                        $this->trigger(self::EVENT_BEFORE_SAVE_ENTRY_REDIRECT, $event);
139
                        if (!$event->isValid) {
140
                            return;
141
                        }
142
                        Retour::$plugin->redirects->saveRedirect($redirectConfig);
143
                    }
144
                }
145
            }
146
        }
147
    }
148
149
    /**
150
     * Get the URIs for each site for the element
151
     *
152
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
153
     *
154
     * @return array
155
     */
156
    protected function getAllElementUris(Element $element): array
157
    {
158
        $uris = [];
159
        if (!Retour::$craft32 || !ElementHelper::isDraftOrRevision($element)) {
160
            $sites = Craft::$app->getSites()->getAllSites();
161
            foreach ($sites as $site) {
162
                $uri = Craft::$app->getElements()->getElementUriForSite($element->id, $site->id);
163
                if ($uri !== null) {
164
                    $uris[$site->id] = $uri;
165
                }
166
            }
167
        }
168
169
        Craft::debug(
170
            Craft::t(
171
                'retour',
172
                'Getting Element URIs: {uris}',
173
                ['uris' => print_r($uris, true)]
174
            ),
175
            __METHOD__
176
        );
177
178
        return $uris;
179
    }
180
}
181