Reasons::initAjaxRequest()   D
last analyzed

Complexity

Conditions 19
Paths 18

Size

Total Lines 82
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 19
eloc 46
c 4
b 0
f 0
nc 18
nop 0
dl 0
loc 82
rs 4.5166

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
 * Reasons plugin for Craft CMS 3.x
4
 *
5
 * Adds conditionals to field layouts.
6
 *
7
 * @link      https://vaersaagod.no
8
 * @copyright Copyright (c) 2020 Mats Mikkel Rummelhoff
9
 */
10
11
namespace mmikkel\reasons;
12
13
use craft\web\Application;
14
use mmikkel\reasons\assetbundles\reasons\ReasonsAssetBundle;
15
use mmikkel\reasons\services\ReasonsService;
16
17
use Craft;
18
use craft\base\Plugin;
19
use craft\elements\Asset;
20
use craft\elements\Category;
21
use craft\elements\Entry;
22
use craft\elements\GlobalSet;
23
use craft\elements\Tag;
24
use craft\elements\User;
25
use craft\events\ConfigEvent;
26
use craft\events\FieldLayoutEvent;
27
use craft\events\PluginEvent;
28
use craft\events\TemplateEvent;
29
use craft\services\Fields;
30
use craft\services\Plugins;
31
use craft\services\ProjectConfig;
32
use craft\web\View;
33
34
use yii\base\Event;
35
use yii\base\InvalidConfigException;
36
37
/**
38
 * Class Reasons
39
 *
40
 * @author    Mats Mikkel Rummelhoff
41
 * @package   Reasons
42
 * @since     2.0.0
43
 *
44
 * @property  ReasonsService $reasons
45
 */
46
class Reasons extends Plugin
47
{
48
49
    /**
50
     * @var string
51
     */
52
    public $schemaVersion = '2.1.1';
53
54
    /**
55
     * @var bool
56
     */
57
    public $hasCpSettings = false;
58
59
    /**
60
     * @var bool
61
     */
62
    public $hasCpSection = false;
63
64
    // Public Methods
65
    // =========================================================================
66
67
    /**
68
     * @inheritdoc
69
     */
70
    public function init()
71
    {
72
        parent::init();
73
74
        $this->setComponents([
75
            'reasons' => ReasonsService::class,
76
        ]);
77
78
        Event::on(
79
            Plugins::class,
80
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
81
            function (PluginEvent $event) {
82
                if ($event->plugin === $this) {
83
                    $this->reasons->clearCache();
84
                }
85
            }
86
        );
87
88
        Event::on(
89
            Plugins::class,
90
            Plugins::EVENT_AFTER_UNINSTALL_PLUGIN,
91
            function (PluginEvent $event) {
92
                if ($event->plugin === $this) {
93
                    $this->reasons->clearCache();
94
                    Craft::$app->getProjectConfig()->remove('reasons_conditionals');
95
                }
96
            }
97
        );
98
99
        // Save or delete conditionals when field layout is saved
100
        Event::on(
101
            Fields::class,
102
            Fields::EVENT_AFTER_SAVE_FIELD_LAYOUT,
103
            function (FieldLayoutEvent $event) {
104
                if (Craft::$app->getRequest()->getIsConsoleRequest()) {
105
                    return;
106
                }
107
                $fieldLayout = $event->layout;
108
                if (!$fieldLayout) {
109
                    return;
110
                }
111
                $conditionals = Craft::$app->getRequest()->getBodyParam('_reasons', null);
112
                if ($conditionals === null) {
113
                    return;
114
                }
115
                try {
116
                    if ($conditionals) {
117
                        $this->reasons->saveFieldLayoutConditionals($fieldLayout, $conditionals);
118
                    } else {
119
                        $this->reasons->deleteFieldLayoutConditionals($fieldLayout);
120
                    }
121
                } catch (\Throwable $e) {
122
                    Craft::error($e->getMessage(), __METHOD__);
123
                    if (Craft::$app->getConfig()->getGeneral()->devMode) {
124
                        throw $e;
125
                    }
126
                }
127
            }
128
        );
129
130
        // Delete conditionals when field layouts are deleted
131
        Event::on(
132
            Fields::class,
133
            Fields::EVENT_AFTER_DELETE_FIELD_LAYOUT,
134
            function (FieldLayoutEvent $event) {
135
                $fieldLayout = $event->layout;
136
                if (!$fieldLayout) {
137
                    return;
138
                }
139
                $this->reasons->deleteFieldLayoutConditionals($fieldLayout);
140
            }
141
        );
142
143
        // Clear data caches when fields are saved
144
        Event::on(
145
            Fields::class,
146
            Fields::EVENT_AFTER_SAVE_FIELD,
147
            [$this->reasons, 'clearCache']
148
        );
149
150
        // Clear data caches when fields are deleted
151
        Event::on(
152
            Fields::class,
153
            Fields::EVENT_AFTER_DELETE_FIELD,
154
            [$this->reasons, 'clearCache']
155
        );
156
157
        // Support Project Config rebuild
158
        Event::on(
159
            ProjectConfig::class,
160
            ProjectConfig::EVENT_REBUILD,
161
            [$this->reasons, 'onProjectConfigRebuild']
162
        );
163
164
        // Listen for appropriate Project Config changes
165
        Craft::$app->getProjectConfig()
166
            ->onAdd('reasons_conditionals.{uid}', [$this->reasons, 'onProjectConfigChange'])
167
            ->onUpdate('reasons_conditionals.{uid}', [$this->reasons, 'onProjectConfigChange'])
168
            ->onRemove('reasons_conditionals.{uid}', [$this->reasons, 'onProjectConfigDelete']);
169
170
        // Queue up asset bundle or handle AJAX action requests
171
        Event::on(
172
            Application::class,
173
            Application::EVENT_INIT,
174
            [$this, 'initReasons']
175
        );
176
177
    }
178
179
    /**
180
     * @return void
181
     */
182
    public function initReasons()
183
    {
184
185
        $request = Craft::$app->getRequest();
186
187
        /** @var User $user */
188
        $user = Craft::$app->getUser()->getIdentity();
189
190
        if ($request->getIsConsoleRequest() || !$request->getIsCpRequest() || $request->getIsSiteRequest() || $request->getIsLoginRequest() || !$user || !$user->can('accessCp')) {
191
            return;
192
        }
193
194
        $isAjax = $request->getIsAjax() || $request->getAcceptsJson();
195
        if ($isAjax) {
196
            $this->initAjaxRequest();
197
        } else {
198
            $this->registerAssetBundle();
199
        }
200
201
    }
202
203
    // Protected Methods
204
    // =========================================================================
205
206
    /**
207
     * @return void
208
     */
209
    protected function registerAssetBundle()
210
    {
211
        // Register asset bundle
212
        Event::on(
213
            View::class,
214
            View::EVENT_BEFORE_RENDER_TEMPLATE,
215
            function (/** @scrutinizer ignore-unused */ TemplateEvent $event) {
216
                try {
217
                    Craft::$app->getView()->registerAssetBundle(ReasonsAssetBundle::class);
218
                } catch (InvalidConfigException $e) {
219
                    Craft::error(
220
                        'Error registering AssetBundle - ' . $e->getMessage(),
221
                        __METHOD__
222
                    );
223
                }
224
            }
225
        );
226
    }
227
228
    /**
229
     * @return void
230
     */
231
    protected function initAjaxRequest()
232
    {
233
234
        $request = Craft::$app->getRequest();
235
        if (!$request->getIsPost() || !$request->getIsActionRequest()) {
236
            return;
237
        }
238
239
        $actionSegments = $request->getActionSegments();
240
        $actionSegment = $actionSegments[\count($actionSegments) - 1] ?? null;
241
242
        if (!$actionSegment) {
243
            return;
244
        }
245
246
        if ($actionSegment === 'switch-entry-type') {
247
            Craft::$app->getView()->registerJs('Craft.ReasonsPlugin.initPrimaryForm();');
248
            return;
249
        }
250
251
        if ($actionSegment === 'get-editor-html') {
252
253
            $conditionalsKey = null;
254
            $elementId = (int)$request->getBodyParam('elementId');
255
256
            if (!$elementId) {
257
258
                // Probably a new element
259
                $attributes = $request->getBodyParam('attributes', []);
260
                $elementType = $request->getBodyParam('elementType');
261
262
                if ($elementType === Entry::class && $typeId = ($attributes['typeId'] ?? null)) {
263
                    $conditionalsKey = "entryType:$typeId";
264
                } else if ($elementType === Category::class && $groupId = ($attributes['groupId'] ?? null)) {
265
                    $conditionalsKey = "categoryGroup:$groupId";
266
                }
267
268
                if (!$conditionalsKey) {
269
                    return;
270
                }
271
272
            } else if ($element = Craft::$app->getElements()->getElementById($elementId)) {
273
274
                $elementType = \get_class($element);
275
276
                switch ($elementType) {
277
                    case Entry::class:
278
                        /** @var Entry $element */
279
                        $conditionalsKey = "entryType:{$element->typeId}";
280
                        break;
281
282
                    case GlobalSet::class:
283
                        /** @var GlobalSet $element */
284
                        $conditionalsKey = "globalSet:{$element->id}";
285
                        break;
286
287
                    case Asset::class:
288
                        /** @var Asset $element */
289
                        $conditionalsKey = "assetSource:{$element->volumeId}";
290
                        break;
291
292
                    case Category::class:
293
                        /** @var Category $element */
294
                        $conditionalsKey = "categoryGroup:{$element->groupId}";
295
                        break;
296
297
                    case Tag::class:
298
                        /** @var Tag $element */
299
                        $conditionalsKey = "tagGroup:{$element->groupId}";
300
                        break;
301
302
                    case User::class:
303
                        $conditionalsKey = "users";
304
                        break;
305
306
                    default:
307
                        return;
308
309
                }
310
            }
311
312
            Craft::$app->getView()->registerJs("Craft.ReasonsPlugin.initElementEditor('{$conditionalsKey}');");
313
314
        }
315
316
    }
317
318
}
319