BlockTypesController::actionSaveFieldLayout()   B
last analyzed

Complexity

Conditions 8
Paths 8

Size

Total Lines 52
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 27
c 0
b 0
f 0
nc 8
nop 0
dl 0
loc 52
rs 8.4444

How to fix   Long Method   

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
 * Spoon plugin for Craft CMS 3.x
4
 *
5
 * Enhance Matrix
6
 *
7
 * @link      https://angell.io
8
 * @copyright Copyright (c) 2018 Angell & Co
9
 */
10
11
namespace angellco\spoon\controllers;
12
13
use angellco\spoon\models\BlockType;
14
use angellco\spoon\Spoon;
15
16
use Craft;
17
use craft\helpers\Db;
18
use craft\web\Controller;
19
20
/**
21
 * BlockTypes Controller
22
 *
23
 * @author    Angell & Co
24
 * @package   Spoon
25
 * @since     3.0.0
26
 */
27
class BlockTypesController extends Controller
28
{
29
30
    // Protected Properties
31
    // =========================================================================
32
33
    /**
34
     * @var    bool|array Allows anonymous access to this controller's actions.
35
     *         The actions must be in 'kebab-case'
36
     * @access protected
37
     */
38
    protected $allowAnonymous = false;
39
40
    // Public Methods
41
    // =========================================================================
42
43
    /**
44
     * Saves a Spoon block type
45
     *
46
     * @return \yii\web\Response
47
     * @throws \yii\db\Exception
48
     * @throws \yii\web\BadRequestHttpException
49
     */
50
    public function actionSave()
51
    {
52
        $this->requirePostRequest();
53
        $this->requireAcceptsJson();
54
55
        // This will be an array of Tab Names with Block Type IDs.
56
        // The order in which they appear is the order in which they should also
57
        // be returned in eventually, so we will just rely on the id to describe this
58
        // and make sure each time we are referencing a context that already exists to
59
        // delete the rows matching that context before proceeding with the save.
60
        $blockTypesPostData = Craft::$app->getRequest()->getParam('spoonedBlockTypes');
61
62
        $context = (string)Craft::$app->getRequest()->getParam('context');
63
        $fieldId = (integer)Craft::$app->getRequest()->getParam('fieldId');
64
65
        // Get any existing field layouts so we don’t lose them
66
        $fieldLayoutIds = Spoon::$plugin->blockTypes->getFieldLayoutIds($context, $fieldId);
67
68
        // Remove all current block types by context
69
        Spoon::$plugin->blockTypes->deleteByContext($context, $fieldId);
70
71
        // Loop over the data and save new rows for each block type / group combo
72
        $errors = 0;
73
        if (is_array($blockTypesPostData))
74
        {
75
            $groupSortOrder = 1;
76
            foreach ($blockTypesPostData as $groupName => $blockTypeIds)
77
            {
78
                $sortOrder = 1;
79
                foreach ($blockTypeIds as $blockTypeId)
80
                {
81
                    $spoonedBlockType = new BlockType();
82
                    $spoonedBlockType->fieldId           = $fieldId;
83
                    $spoonedBlockType->matrixBlockTypeId = $blockTypeId;
84
                    $spoonedBlockType->fieldLayoutId     = isset($fieldLayoutIds[$blockTypeId]) ? $fieldLayoutIds[$blockTypeId] : null;
85
                    $spoonedBlockType->groupName         = urldecode($groupName);
86
                    $spoonedBlockType->context           = $context;
87
                    $spoonedBlockType->groupSortOrder    = $groupSortOrder;
88
                    $spoonedBlockType->sortOrder         = $sortOrder;
89
90
                    if (!Spoon::$plugin->blockTypes->save($spoonedBlockType))
91
                    {
92
                        $errors++;
93
                    }
94
95
                    $sortOrder++;
96
                }
97
                $groupSortOrder++;
98
            }
99
        }
100
101
        if ($errors > 0)
102
        {
103
            return $this->asJson([
104
                'success' => false
105
            ]);
106
        }
107
108
        return $this->asJson([
109
            'success' => true
110
        ]);
111
    }
112
113
    /**
114
     * Delete a set of Spoon block types for a given field and context
115
     *
116
     * @return \yii\web\Response
117
     * @throws \yii\db\Exception
118
     * @throws \yii\web\BadRequestHttpException
119
     */
120
    public function actionDelete()
121
    {
122
        $this->requirePostRequest();
123
        $this->requireAcceptsJson();
124
125
        $context = (string)Craft::$app->getRequest()->getParam('context');
126
        $fieldId = (integer)Craft::$app->getRequest()->getParam('fieldId');
127
128
        if (!Spoon::$plugin->blockTypes->deleteByContext($context, $fieldId))
129
        {
130
            $this->asJson([
131
                'success' => false
132
            ]);
133
        }
134
135
        return $this->asJson([
136
            'success' => true
137
        ]);
138
    }
139
140
    /**
141
     * Saves a field layout for a given Spoon block type
142
     *
143
     * @return bool|\yii\web\Response
144
     * @throws \angellco\spoon\errors\BlockTypeNotFoundException
145
     * @throws \yii\web\BadRequestHttpException
146
     */
147
    public function actionSaveFieldLayout()
148
    {
149
        $this->requirePostRequest();
150
        $this->requireAcceptsJson();
151
152
        $spoonedBlockTypeId = Craft::$app->getRequest()->getParam('spoonedBlockTypeId');
153
        $blockTypeFieldLayouts = Craft::$app->getRequest()->getParam('blockTypeFieldLayouts');
0 ignored issues
show
Unused Code introduced by
The assignment to $blockTypeFieldLayouts is dead and can be removed.
Loading history...
154
155
        if ($spoonedBlockTypeId) {
156
            if (!$spoonedBlockType = Spoon::$plugin->blockTypes->getById($spoonedBlockTypeId)) {
157
                return false;
158
            }
159
        } else {
160
            return false;
161
        }
162
163
        // Set the field layout on the model
164
        $postedFieldLayout = Craft::$app->getRequest()->getParam('blockTypeFieldLayouts');
165
166
        // Check if we have one
167
        if ($postedFieldLayout) {
168
            $assembledLayout = Craft::$app->fields->assembleLayout($postedFieldLayout);
0 ignored issues
show
Bug introduced by
It seems like $postedFieldLayout can also be of type string; however, parameter $postedFieldLayout of craft\services\Fields::assembleLayout() 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

168
            $assembledLayout = Craft::$app->fields->assembleLayout(/** @scrutinizer ignore-type */ $postedFieldLayout);
Loading history...
169
            $spoonedBlockType->setFieldLayout($assembledLayout);
0 ignored issues
show
Bug introduced by
The method setFieldLayout() does not exist on angellco\spoon\models\BlockType. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

169
            $spoonedBlockType->/** @scrutinizer ignore-call */ 
170
                               setFieldLayout($assembledLayout);
Loading history...
170
171
            // Save it
172
            if (!Spoon::$plugin->blockTypes->saveFieldLayout($spoonedBlockType)) {
173
                return $this->asJson([
174
                    'success' => false
175
                ]);
176
            }
177
        } else if ($spoonedBlockType->fieldLayoutId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $spoonedBlockType->fieldLayoutId 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...
178
179
            // We don’t have a new field layout, so remove the old one if there is one
180
            $oldFieldLayoutId = $spoonedBlockType->fieldLayoutId;
181
            if (!Craft::$app->fields->deleteLayoutById($oldFieldLayoutId)) {
182
                return $this->asJson([
183
                    'success' => false
184
                ]);
185
            }
186
187
            // Also null the col on our block type row
188
            $spoonedBlockType->fieldLayoutId = null;
189
            if (!Spoon::$plugin->blockTypes->save($spoonedBlockType)) {
190
                return $this->asJson([
191
                    'success' => false
192
                ]);
193
            }
194
195
        }
196
197
        return $this->asJson([
198
            'success' => true
199
        ]);
200
    }
201
202
}
203