Passed
Push — v3 ( 0d1d42...e1dcac )
by Andrew
32:56 queued 25:33
created

Events::handleElementUriChange()   C

Complexity

Conditions 12
Paths 62

Size

Total Lines 69
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 49
c 2
b 0
f 0
dl 0
loc 69
ccs 0
cts 62
cp 0
rs 6.9666
cc 12
nc 62
nop 1
crap 156

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
     *     Events::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
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
63
     * @var array A list of element ids that have their redirects already created
64
     */
65
    protected $elementsWithCreatedRedirects = [];
66
67
    // Public Methods
68
    // =========================================================================
69
70
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
71
     * @param $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
72
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
73
    public function stashElementUris($element)
74
    {
75
        // Stash the old URLs by element id, and do so only once,
76
        // in case we are called more than once per request
77
        if (empty($this->oldElementUris[$element->id])) {
78
            $this->oldElementUris[$element->id] = $this->getAllElementUris($element);
79
        }
80
    }
81
82
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
83
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
84
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
85
    public function handleElementUriChange(Element $element)
86
    {
87
        if (array_key_exists($element->id, $this->elementsWithCreatedRedirects)) {
88
            return;
89
        }
90
        $this->elementsWithCreatedRedirects[] = $element->id;
91
92
        $uris = $this->getAllElementUris($element);
93
        if (!empty($this->oldElementUris[$element->id])) {
94
            $oldElementUris = $this->oldElementUris[$element->id];
95
            foreach ($uris as $siteId => $newUri) {
96
                if (!empty($oldElementUris[$siteId])) {
97
                    $oldUri = $oldElementUris[$siteId];
98
                    Craft::debug(
99
                        Craft::t(
100
                            'retour',
101
                            'Comparing old: {oldUri} to new: {newUri}',
102
                            ['oldUri' => print_r($oldUri, true), 'newUri' => print_r($newUri, true)]
103
                        ),
104
                        __METHOD__
105
                    );
106
                    // Handle the siteId
107
                    $redirectSiteId = null;
108
                    if (Craft::$app->getIsMultiSite()) {
109
                        $redirectSiteId = $siteId;
110
                    }
111
                    // Make sure the URIs are not the same
112
                    if (strcmp($oldUri, $newUri) !== 0) {
113
                        // Handle trailing slash config setting
114
                        if (Craft::$app->config->general->addTrailingSlashesToUrls) {
115
                            $oldUri = rtrim($oldUri, '/') . '/';
116
                            $newUri = rtrim($newUri, '/') . '/';
117
                        }
118
                        // Handle the URL match type
119
                        if (Retour::$settings->uriChangeRedirectSrcMatch === 'fullurl') {
120
                            try {
121
                                if ($redirectSiteId !== null) {
122
                                    $redirectSiteId = (int)$redirectSiteId;
123
                                }
124
                                $oldUri = \craft\helpers\UrlHelper::siteUrl($oldUri, null, null, $redirectSiteId);
125
                                $newUri = UrlHelper::siteUrl($newUri, null, null, $redirectSiteId);
126
                            } catch (Exception $e) {
127
                                // That's fine
128
                            }
129
                        }
130
                        $redirectConfig = [
131
                            'id' => 0,
132
                            'redirectMatchType' => 'exactmatch',
133
                            'redirectHttpCode' => 301,
134
                            'redirectSrcMatch' => Retour::$settings->uriChangeRedirectSrcMatch,
135
                            'redirectSrcUrl' => $oldUri,
136
                            'redirectDestUrl' => $newUri,
137
                            'siteId' => $redirectSiteId,
138
                        ];
139
                        // Trigger a 'beforeSaveEntryRedirect' event
140
                        $isNew = (int)$redirectConfig['id'] === 0;
141
                        $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...
142
                            'isNew' => $isNew,
143
                            'legacyUrl' => $redirectConfig['redirectSrcUrl'],
144
                            'destinationUrl' => $redirectConfig['redirectDestUrl'],
145
                            'matchType' => $redirectConfig['redirectSrcMatch'],
146
                            'redirectType' => $redirectConfig['redirectHttpCode'],
147
                            'siteId' => $redirectConfig['siteId'],
148
                        ]);
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...
149
                        $this->trigger(self::EVENT_BEFORE_SAVE_ENTRY_REDIRECT, $event);
150
                        if (!$event->isValid) {
151
                            return;
152
                        }
153
                        Retour::$plugin->redirects->saveRedirect($redirectConfig);
154
                    }
155
                }
156
            }
157
        }
158
    }
159
160
    /**
161
     * Get the URIs for each site for the element
162
     *
163
     * @param Element $element
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
164
     *
165
     * @return array
166
     */
167
    protected function getAllElementUris(Element $element): array
168
    {
169
        $uris = [];
170
        if (!Retour::$craft32 || !ElementHelper::isDraftOrRevision($element)) {
171
            $sites = Craft::$app->getSites()->getAllSites();
172
            foreach ($sites as $site) {
173
                $uri = Craft::$app->getElements()->getElementUriForSite($element->id, $site->id);
174
                if ($uri !== null) {
175
                    $uris[$site->id] = $uri;
176
                }
177
            }
178
        }
179
180
        Craft::debug(
181
            Craft::t(
182
                'retour',
183
                'Getting Element URIs: {uris}',
184
                ['uris' => print_r($uris, true)]
185
            ),
186
            __METHOD__
187
        );
188
189
        return $uris;
190
    }
191
}
192