Passed
Push — v3 ( 5261ad...9137a8 )
by Andrew
32:26 queued 04:55
created

RedirectsController::actionDeleteRedirects()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
c 0
b 0
f 0
dl 0
loc 22
rs 9.8333
cc 4
nc 6
nop 0
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/
9
 * @copyright Copyright (c) 2018 nystudio107
10
 */
11
12
namespace nystudio107\retour\controllers;
13
14
use nystudio107\retour\Retour;
15
use nystudio107\retour\assetbundles\retour\RetourAsset;
16
use nystudio107\retour\assetbundles\retour\RetourRedirectsAsset;
17
use nystudio107\retour\helpers\MultiSite as MultiSiteHelper;
18
use nystudio107\retour\helpers\Permission as PermissionHelper;
19
use nystudio107\retour\models\StaticRedirects as StaticRedirectsModel;
20
21
use Craft;
22
use craft\web\Controller;
23
use craft\helpers\UrlHelper;
24
25
use yii\base\InvalidConfigException;
26
use yii\web\NotFoundHttpException;
27
use yii\web\Response;
28
29
/**
30
 * @author    nystudio107
31
 * @package   Retour
32
 * @since     3.0.0
33
 */
34
class RedirectsController extends Controller
35
{
36
    // Constants
37
    // =========================================================================
38
39
    const DOCUMENTATION_URL = 'https://github.com/nystudio107/craft-retour/';
40
41
    // Protected Properties
42
    // =========================================================================
43
44
    protected $allowAnonymous = [];
45
46
    // Public Methods
47
    // =========================================================================
48
49
    /**
50
     * Show the redirects table
51
     *
52
     * @param string|null $siteHandle
53
     *
54
     * @return Response
55
     * @throws \yii\web\ForbiddenHttpException
56
     * @throws \yii\web\NotFoundHttpException
57
     */
58
    public function actionRedirects(string $siteHandle = null): Response
59
    {
60
        $variables = [];
61
        PermissionHelper::controllerPermissionCheck('retour:redirects');
62
        // Get the site to edit
63
        $siteId = MultiSiteHelper::getSiteIdFromHandle($siteHandle);
64
        $pluginName = Retour::$settings->pluginName;
65
        $templateTitle = Craft::t('retour', 'Redirects');
66
        $view = Craft::$app->getView();
67
        // Asset bundle
68
        try {
69
            $view->registerAssetBundle(RetourRedirectsAsset::class);
70
        } catch (InvalidConfigException $e) {
71
            Craft::error($e->getMessage(), __METHOD__);
72
        }
73
        $variables['baseAssetsUrl'] = Craft::$app->assetManager->getPublishedUrl(
74
            '@nystudio107/retour/assetbundles/retour/dist',
75
            true
76
        );
77
        // Enabled sites
78
        MultiSiteHelper::setMultiSiteVariables($siteHandle, $siteId, $variables);
79
        $variables['controllerHandle'] = 'redirects';
80
81
        // Basic variables
82
        $variables['fullPageForm'] = false;
83
        $variables['docsUrl'] = self::DOCUMENTATION_URL;
84
        $variables['pluginName'] = $pluginName;
85
        $variables['title'] = $templateTitle;
86
        $siteHandleUri = Craft::$app->isMultiSite ? '/'.$siteHandle : '';
87
        $variables['crumbs'] = [
88
            [
89
                'label' => $pluginName,
90
                'url' => UrlHelper::cpUrl('retour'),
91
            ],
92
            [
93
                'label' => $templateTitle,
94
                'url' => UrlHelper::cpUrl('retour/redirects'.$siteHandleUri),
95
            ],
96
        ];
97
        $variables['docTitle'] = "{$pluginName} - {$templateTitle}";
98
        $variables['selectedSubnavItem'] = 'redirects';
99
100
        // Render the template
101
        return $this->renderTemplate('retour/redirects/index', $variables);
102
    }
103
104
    /**
105
     * Edit the redirect
106
     *
107
     * @param int                       $redirectId
108
     * @param string                    $defaultUrl
109
     * @param int                       $siteId
110
     * @param null|StaticRedirectsModel $redirect
111
     *
112
     * @return Response
113
     * @throws NotFoundHttpException
114
     * @throws \yii\web\ForbiddenHttpException
115
     */
116
    public function actionEditRedirect(
117
        int $redirectId = 0,
118
        string $defaultUrl = '',
119
        int $siteId = 0,
120
        StaticRedirectsModel $redirect = null
121
    ): Response {
122
        $variables = [];
123
        PermissionHelper::controllerPermissionCheck('retour:redirects');
124
125
        // Load in the redirect
126
        if ($redirectId === 0) {
127
            $redirect = new StaticRedirectsModel([
128
                'id' => 0,
129
                'siteId' => $siteId,
130
                'redirectSrcUrl' => urldecode($defaultUrl),
131
            ]);
132
        }
133
        if ($redirect === null) {
134
            $redirectConfig = Retour::$plugin->redirects->getRedirectById($redirectId);
135
            if ($redirectConfig === null) {
136
                $redirectConfig = [];
137
                Craft::error(
138
                    Craft::t(
139
                        'retour',
140
                        "Couldn't load redirect id {id}",
141
                        ['id' => $redirectId]
142
                    ),
143
                    __METHOD__
144
                );
145
            }
146
            $redirect = new StaticRedirectsModel($redirectConfig);
147
        }
148
        $redirect->validate();
149
        // Ensure the user has permissions to edit this redirect
150
        $sites = Craft::$app->getSites();
151
        if ($redirect->siteId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $redirect->siteId of type integer|null is loosely compared to true; 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...
152
            $site = $sites->getSiteById($redirect->siteId);
153
            if ($site) {
154
                MultiSiteHelper::requirePermission('editSite:'.$site->uid);
155
            }
156
        }
157
        if ($siteId) {
158
            $site = $sites->getSiteById($siteId);
159
            if ($site) {
160
                MultiSiteHelper::requirePermission('editSite:'.$site->uid);
161
            }
162
        }
163
        $pluginName = Retour::$settings->pluginName;
164
        $templateTitle = Craft::t('retour', 'Edit Redirect');
165
        $view = Craft::$app->getView();
166
        // Asset bundle
167
        try {
168
            $view->registerAssetBundle(RetourAsset::class);
169
        } catch (InvalidConfigException $e) {
170
            Craft::error($e->getMessage(), __METHOD__);
171
        }
172
        $variables['baseAssetsUrl'] = Craft::$app->assetManager->getPublishedUrl(
173
            '@nystudio107/retour/assetbundles/retour/dist',
174
            true
175
        );
176
        // Sites menu
177
        MultiSiteHelper::setSitesMenuVariables($variables);
178
        $variables['controllerHandle'] = 'redirects';
179
180
        // Basic variables
181
        $variables['fullPageForm'] = true;
182
        $variables['docsUrl'] = self::DOCUMENTATION_URL;
183
        $variables['pluginName'] = $pluginName;
184
        $variables['title'] = $templateTitle;
185
        $variables['crumbs'] = [
186
            [
187
                'label' => $pluginName,
188
                'url' => UrlHelper::cpUrl('retour'),
189
            ],
190
            [
191
                'label' => 'Redirects',
192
                'url' => UrlHelper::cpUrl('retour/redirects'),
193
            ],
194
            [
195
                'label' => $templateTitle,
196
                'url' => UrlHelper::cpUrl('retour/edit-redirect/'.$redirectId),
197
            ],
198
        ];
199
        $variables['docTitle'] = "{$pluginName} - Redirects - {$templateTitle}";
200
        $variables['selectedSubnavItem'] = 'redirects';
201
        $variables['redirect'] = $redirect;
202
203
        // Render the template
204
        return $this->renderTemplate('retour/redirects/_edit', $variables);
205
    }
206
207
    /**
208
     * @return null|Response
209
     * @throws \craft\errors\MissingComponentException
210
     * @throws \yii\web\ForbiddenHttpException
211
     */
212
    public function actionDeleteRedirects()
213
    {
214
        PermissionHelper::controllerPermissionCheck('retour:redirects');
215
        $request = Craft::$app->getRequest();
216
        $redirectIds = $request->getRequiredBodyParam('redirectIds');
217
        $stickyError = false;
218
        foreach ($redirectIds as $redirectId) {
219
            if (!Retour::$plugin->redirects->deleteRedirectById($redirectId)) {
220
                $stickyError = true;
221
            }
222
        }
223
        Retour::$plugin->clearAllCaches();
224
        // Handle any cumulative errors
225
        if (!$stickyError) {
226
            // Clear the caches and continue on
227
            Craft::$app->getSession()->setNotice(Craft::t('retour', 'Retour edirects deleted.'));
228
229
            return $this->redirect('retour/redirects');
230
        }
231
        Craft::$app->getSession()->setError(Craft::t('retour', "Couldn't delete redirect."));
232
233
        return null;
234
    }
235
236
    /**
237
     * Save the redirect
238
     *
239
     * @return null|Response
240
     * @throws \craft\errors\MissingComponentException
241
     * @throws \yii\web\BadRequestHttpException
242
     * @throws \yii\web\ForbiddenHttpException
243
     * @throws NotFoundHttpException
244
     */
245
    public function actionSaveRedirect()
246
    {
247
        PermissionHelper::controllerPermissionCheck('retour:redirects');
248
        $this->requirePostRequest();
249
        /** @var StaticRedirectsModel $redirect */
250
        $redirectConfig = Craft::$app->getRequest()->getRequiredBodyParam('redirectConfig');
251
        if ($redirectConfig === null) {
252
            throw new NotFoundHttpException('Redirect not found');
253
        }
254
        $redirectConfig['id'] = (int)$redirectConfig['id'];
255
        $redirect = new StaticRedirectsModel($redirectConfig);
0 ignored issues
show
Bug introduced by
It seems like $redirectConfig can also be of type string; however, parameter $config of nystudio107\retour\model...edirects::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

255
        $redirect = new StaticRedirectsModel(/** @scrutinizer ignore-type */ $redirectConfig);
Loading history...
256
        // Make sure the redirect validates
257
        if (!$redirect->validate()) {
258
            Craft::$app->getSession()->setError(Craft::t('app', "Couldn't save redirect settings."));
259
            // Send the redirect back to the template
260
            Craft::$app->getUrlManager()->setRouteParams([
261
                'redirect' => $redirect,
262
            ]);
263
264
            return null;
265
        }
266
        // Save the redirect
267
        $redirectConfig = $redirect->getAttributes();
268
        Retour::$plugin->redirects->saveRedirect($redirectConfig);
269
        // Handle the case where the redirect wasn't saved because it'd create a redirect loop
270
        $testRedirectConfig = Retour::$plugin->redirects->getRedirectByRedirectSrcUrl(
271
            $redirectConfig['redirectSrcUrl'],
272
            $redirectConfig['siteId']
273
        );
274
        if ($testRedirectConfig === null) {
275
            Craft::$app->getSession()->setError(Craft::t('app', "Couldn't save redirect settings because it'd create a redirect loop."));
276
            // Send the redirect back to the template
277
            Craft::$app->getUrlManager()->setRouteParams([
278
                'redirect' => $redirect,
279
            ]);
280
281
            return null;
282
        }
283
        // Clear the caches and continue on
284
        Retour::$plugin->clearAllCaches();
285
        Craft::$app->getSession()->setNotice(Craft::t('retour', 'Redirect settings saved.'));
286
287
        return $this->redirectToPostedUrl();
288
    }
289
}
290