Passed
Push — master ( 8a350c...281cf2 )
by Josh
03:42 queued 11s
created

BlockTypesController::actionIndex()   B

Complexity

Conditions 8
Paths 2

Size

Total Lines 63
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 63
rs 8.1954
c 0
b 0
f 0
cc 8
nc 2
nop 1

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
     * Loads the edit page for the global context.
45
     *
46
     * @param array $variables
47
     *
48
     * @return \yii\web\Response
49
     */
50
    public function actionIndex($variables = [])
51
    {
52
        $variables['matrixFields'] = Spoon::$plugin->fields->getMatrixFields();
53
54
        $variables['globalSpoonedBlockTypes'] = Spoon::$plugin->blockTypes->getByContext('global', 'fieldId', true);
55
56
        // If Super Table is installed get all of the ST fields and store by child field context
57
        $superTablePlugin = \Craft::$app->plugins->getPlugin('super-table');
58
        if ($superTablePlugin && $variables['matrixFields']) {
59
            $superTableService = new \verbb\supertable\services\SuperTableService();
0 ignored issues
show
Bug introduced by
The type verbb\supertable\services\SuperTableService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
60
61
            foreach ($variables['matrixFields'] as $matrixField) {
62
                if (strpos($matrixField->context, 'superTableBlockType') === 0) {
0 ignored issues
show
Bug introduced by
Accessing context on the interface craft\base\FieldInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
63
                    $parts = explode(':', $matrixField->context);
64
                    if (isset($parts[1])) {
65
66
                        $superTableBlockTypeId = Db::idByUid('{{%supertableblocktypes}}', $parts[1]);
67
68
                        /** @var \verbb\supertable\models\SuperTableBlockTypeModel $superTableBlockType */
69
                        $superTableBlockType = $superTableService->getBlockTypeById($superTableBlockTypeId);
70
71
                        /** @var \verbb\supertable\fields\SuperTableField $superTableField */
72
                        $superTableField = \Craft::$app->fields->getFieldById($superTableBlockType->fieldId);
73
74
                        $variables['superTableFields'][$matrixField->context] = [
75
                            'kind' => 'Super Table',
76
                            'field' => $superTableField,
77
                            'child' => false
78
                        ];
79
80
                        // If the context of _this_ field is inside a Matrix block ... then we need to do more inception
81
                        if (strpos($superTableField->context, 'matrixBlockType') === 0) {
82
                            $nestedParts = explode(':', $superTableField->context);
83
                            if (isset($nestedParts[1])) {
84
85
                                $matrixBlockTypeId = Db::idByUid('{{%matrixblocktypes}}', $nestedParts[1]);
86
87
                                /** @var craft\models\MatrixBlockType $matrixBlockType */
88
                                $matrixBlockType = \Craft::$app->matrix->getBlockTypeById($matrixBlockTypeId);
89
90
                                /** @var craft\fields\Matrix $globalField */
91
                                $globalField = \Craft::$app->fields->getFieldById($matrixBlockType->fieldId);
0 ignored issues
show
Bug introduced by
It seems like $matrixBlockType->fieldId can also be of type null; however, parameter $fieldId of craft\services\Fields::getFieldById() does only seem to accept integer, 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

91
                                $globalField = \Craft::$app->fields->getFieldById(/** @scrutinizer ignore-type */ $matrixBlockType->fieldId);
Loading history...
92
93
                                $variables['superTableFields'][$matrixField->context] = [
94
                                    'kind' => 'Matrix',
95
                                    'field' => $globalField,
96
                                    'child' => [
97
                                        'kind' => 'Super Table',
98
                                        'field' => $superTableField
99
                                    ]
100
                                ];
101
102
                            }
103
                        }
104
105
                    }
106
                }
107
            }
108
        }
109
110
        Spoon::$plugin->loader->configurator('#spoon-global-context-table', 'global');
111
112
        return $this->renderTemplate('spoon/edit-global-context', $variables);
113
    }
114
115
    /**
116
     * Saves a Spoon block type
117
     *
118
     * @return \yii\web\Response
119
     * @throws \yii\db\Exception
120
     * @throws \yii\web\BadRequestHttpException
121
     */
122
    public function actionSave()
123
    {
124
        $this->requirePostRequest();
125
        $this->requireAcceptsJson();
126
127
        // This will be an array of Tab Names with Block Type IDs.
128
        // The order in which they appear is the order in which they should also
129
        // be returned in eventually, so we will just rely on the id to describe this
130
        // and make sure each time we are referencing a context that already exists to
131
        // delete the rows matching that context before proceeding with the save.
132
        $blockTypesPostData = Craft::$app->getRequest()->getParam('spoonedBlockTypes');
133
134
        $context = (string)Craft::$app->getRequest()->getParam('context');
135
        $fieldId = (integer)Craft::$app->getRequest()->getParam('fieldId');
136
137
        // Get any existing field layouts so we don’t lose them
138
        $fieldLayoutIds = Spoon::$plugin->blockTypes->getFieldLayoutIds($context, $fieldId);
139
140
141
        // Remove all current block types by context
142
        Spoon::$plugin->blockTypes->deleteByContext($context, $fieldId);
143
144
        // Loop over the data and save new rows for each block type / group combo
145
        $errors = 0;
146
        if (is_array($blockTypesPostData))
147
        {
148
            foreach ($blockTypesPostData as $groupName => $blockTypeIds)
149
            {
150
                foreach ($blockTypeIds as $blockTypeId)
151
                {
152
                    $spoonedBlockType = new BlockType();
153
                    $spoonedBlockType->fieldId           = $fieldId;
154
                    $spoonedBlockType->matrixBlockTypeId = $blockTypeId;
155
                    $spoonedBlockType->fieldLayoutId     = isset($fieldLayoutIds[$blockTypeId]) ? $fieldLayoutIds[$blockTypeId] : null;
156
                    $spoonedBlockType->groupName         = urldecode($groupName);
157
                    $spoonedBlockType->context           = $context;
158
159
                    if (!Spoon::$plugin->blockTypes->save($spoonedBlockType))
160
                    {
161
                        $errors++;
162
                    }
163
                }
164
            }
165
        }
166
167
        if ($errors > 0)
168
        {
169
            return $this->asJson([
170
                'success' => false
171
            ]);
172
        }
173
174
        return $this->asJson([
175
            'success' => true
176
        ]);
177
    }
178
179
    /**
180
     * Delete a set of Spoon block types for a given field and context
181
     *
182
     * @return \yii\web\Response
183
     * @throws \yii\db\Exception
184
     * @throws \yii\web\BadRequestHttpException
185
     */
186
    public function actionDelete()
187
    {
188
        $this->requirePostRequest();
189
        $this->requireAcceptsJson();
190
191
        $context = (string)Craft::$app->getRequest()->getParam('context');
192
        $fieldId = (integer)Craft::$app->getRequest()->getParam('fieldId');
193
194
        if (!Spoon::$plugin->blockTypes->deleteByContext($context, $fieldId))
195
        {
196
            $this->asJson([
197
                'success' => false
198
            ]);
199
        }
200
201
        return $this->asJson([
202
            'success' => true
203
        ]);
204
    }
205
206
    /**
207
     * Saves a field layout for a given Spoon block type
208
     *
209
     * @return bool|\yii\web\Response
210
     * @throws \angellco\spoon\errors\BlockTypeNotFoundException
211
     * @throws \yii\web\BadRequestHttpException
212
     */
213
    public function actionSaveFieldLayout()
214
    {
215
        $this->requirePostRequest();
216
        $this->requireAcceptsJson();
217
218
        $spoonedBlockTypeId = Craft::$app->getRequest()->getParam('spoonedBlockTypeId');
219
        $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...
220
221
        if ($spoonedBlockTypeId)
222
        {
223
            if (!$spoonedBlockType = Spoon::$plugin->blockTypes->getById($spoonedBlockTypeId)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $spoonedBlockType is correct as angellco\spoon\Spoon::pl...Id($spoonedBlockTypeId) targeting angellco\spoon\services\BlockTypes::getById() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
224
                return false;
225
            }
226
        } else
227
        {
228
            return false;
229
        }
230
231
        // Set the field layout on the model
232
        $postedFieldLayout = Craft::$app->getRequest()->getParam('blockTypeFieldLayouts');
233
        $assembledLayout = Craft::$app->fields->assembleLayout($postedFieldLayout);
0 ignored issues
show
Bug introduced by
It seems like $postedFieldLayout can also be of type null and 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

233
        $assembledLayout = Craft::$app->fields->assembleLayout(/** @scrutinizer ignore-type */ $postedFieldLayout);
Loading history...
234
        $spoonedBlockType->setFieldLayout($assembledLayout);
235
236
        // Save it
237
        if (!Spoon::$plugin->blockTypes->saveFieldLayout($spoonedBlockType))
0 ignored issues
show
Bug introduced by
$spoonedBlockType of type void is incompatible with the type angellco\spoon\models\BlockType expected by parameter $spoonedBlockType of angellco\spoon\services\...ypes::saveFieldLayout(). ( Ignorable by Annotation )

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

237
        if (!Spoon::$plugin->blockTypes->saveFieldLayout(/** @scrutinizer ignore-type */ $spoonedBlockType))
Loading history...
238
        {
239
            return $this->asJson([
240
                'success' => false
241
            ]);
242
        }
243
244
        return $this->asJson([
245
            'success' => true
246
        ]);
247
    }
248
249
}
250