Issues (83)

src/Spoon.php (7 issues)

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;
12
13
use angellco\spoon\base\PluginTrait;
14
use angellco\spoon\helpers\ProjectConfig as ProjectConfigHelper;
15
use angellco\spoon\models\Settings;
16
use angellco\spoon\services\BlockTypes;
17
use angellco\spoon\services\Fields;
18
use angellco\spoon\services\Loader;
19
20
use Craft;
21
use craft\base\Plugin;
22
use craft\events\RebuildConfigEvent;
23
use craft\helpers\Db;
24
use craft\services\Plugins;
25
use craft\services\ProjectConfig;
26
27
use verbb\supertable\fields\SuperTableField;
0 ignored issues
show
The type verbb\supertable\fields\SuperTableField 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...
28
use verbb\supertable\models\SuperTableBlockTypeModel;
0 ignored issues
show
The type verbb\supertable\models\SuperTableBlockTypeModel 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...
29
use yii\base\Event;
30
use yii\base\InvalidConfigException;
31
use yii\web\Response;
32
33
/**
34
 * Craft plugins are very much like little applications in and of themselves. We’ve made
35
 * it as simple as we can, but the training wheels are off. A little prior knowledge is
36
 * going to be required to write a plugin.
37
 *
38
 * For the purposes of the plugin docs, we’re going to assume that you know PHP and SQL,
39
 * as well as some semi-advanced concepts like object-oriented programming and PHP namespaces.
40
 *
41
 * https://craftcms.com/docs/plugins/introduction
42
 *
43
 * @property BlockTypes     $blockTypes The block types component.
44
 * @property Fields         $fields     The fields component.
45
 * @property Loader         $loader     The loader component.
46
 * @property Response|mixed $settingsResponse
47
 * @method BlockTypes getBlockTypes() Returns the block types component.
48
 * @method Fields     getFields()     Returns the fields component.
49
 * @method Loader     getLoader()     Returns the loader component.
50
 * @method Settings   getSettings()   Returns the settings model.
51
 * @author    Angell & Co
52
 * @package   Spoon
53
 * @since     3.0.0
54
 */
55
class Spoon extends Plugin
56
{
57
    // Traits
58
    // =========================================================================
59
60
    use PluginTrait;
61
62
    // Public Properties
63
    // =========================================================================
64
65
    /**
66
     * @inheritdoc
67
     */
68
    public $schemaVersion = '3.5.0';
69
70
    /**
71
     * @inheritdoc
72
     */
73
    public $hasCpSettings = true;
74
75
    // Public Methods
76
    // =========================================================================
77
78
    /**
79
     * Set our $plugin static property to this class so that it can be accessed via
80
     * Spoon::$plugin
81
     *
82
     * Called after the plugin class is instantiated; do any one-time initialization
83
     * here such as hooks and events.
84
     *
85
     * If you have a '/vendor/autoload.php' file, it will be loaded for you automatically;
86
     * you do not need to load it in your init() method.
87
     *
88
     */
89
    public function init()
90
    {
91
        parent::init();
92
93
        self::$plugin = $this;
94
95
        $this->_setPluginComponents();
96
97
        // Wait until all the plugins have loaded before running the loader
98
        Event::on(
99
            Plugins::class,
100
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
101
            function() {
102
                if ($this->isInstalled && !Craft::$app->plugins->doesPluginRequireDatabaseUpdate($this)) {
103
                    $this->loader->run();
104
                }
105
            }
106
        );
107
108
        // Project config listeners
109
        Craft::$app->projectConfig
110
            ->onAdd(BlockTypes::CONFIG_BLOCKTYPE_KEY.'.{uid}', [$this->getBlockTypes(), 'handleChangedBlockType'])
111
            ->onUpdate(BlockTypes::CONFIG_BLOCKTYPE_KEY.'.{uid}', [$this->getBlockTypes(), 'handleChangedBlockType'])
112
            ->onRemove(BlockTypes::CONFIG_BLOCKTYPE_KEY.'.{uid}', [$this->getBlockTypes(), 'handleDeletedBlockType']);
113
114
        // Project config rebuild listener
115
        Event::on(ProjectConfig::class, ProjectConfig::EVENT_REBUILD, function(RebuildConfigEvent $e) {
116
            $e->config[BlockTypes::CONFIG_BLOCKTYPE_KEY] = ProjectConfigHelper::rebuildProjectConfig();
117
        });
118
119
        // Log on load for debugging
120
        Craft::info(
121
            Craft::t(
122
                'spoon',
123
                '{name} plugin loaded',
124
                ['name' => $this->name]
125
            ),
126
            __METHOD__
127
        );
128
    }
129
130
    /**
131
     * Loads the edit page for the global context.
132
     *
133
     * @return mixed|Response
134
     * @throws InvalidConfigException
135
     */
136
    public function getSettingsResponse()
137
    {
138
        $variables['matrixFields'] = $this->fields->getMatrixFields();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$variables was never initialized. Although not strictly required by PHP, it is generally a good practice to add $variables = array(); before regardless.
Loading history...
139
140
        $variables['globalSpoonedBlockTypes'] = $this->blockTypes->getByContext('global', 'fieldId', true);
141
142
        // If Super Table is installed get all of the ST fields and store by child field context
143
        $superTablePlugin = Craft::$app->plugins->getPlugin('super-table');
144
        if ($superTablePlugin && $variables['matrixFields']) {
145
            $superTableService = new \verbb\supertable\services\SuperTableService();
0 ignored issues
show
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...
146
147
            foreach ($variables['matrixFields'] as $matrixField) {
148
                if (strpos($matrixField->context, 'superTableBlockType') === 0) {
149
                    $parts = explode(':', $matrixField->context);
150
                    if (isset($parts[1])) {
151
152
                        $superTableBlockTypeId = Db::idByUid('{{%supertableblocktypes}}', $parts[1]);
153
154
                        if ($superTableBlockTypeId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $superTableBlockTypeId 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...
155
                            /** @var SuperTableBlockTypeModel $superTableBlockType */
156
                            $superTableBlockType = $superTableService->getBlockTypeById($superTableBlockTypeId);
157
158
                            /** @var SuperTableField $superTableField */
159
                            $superTableField = Craft::$app->fields->getFieldById($superTableBlockType->fieldId);
160
161
                            $variables['superTableFields'][$matrixField->context] = [
162
                                'kind' => 'Super Table',
163
                                'field' => $superTableField,
164
                                'child' => false
165
                            ];
166
167
                            // If the context of _this_ field is inside a Matrix block ... then we need to do more inception
168
                            if (strpos($superTableField->context, 'matrixBlockType') === 0) {
169
                                $nestedParts = explode(':', $superTableField->context);
170
                                if (isset($nestedParts[1])) {
171
172
                                    $matrixBlockTypeId = Db::idByUid('{{%matrixblocktypes}}', $nestedParts[1]);
173
174
                                    if ($matrixBlockTypeId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matrixBlockTypeId 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...
175
                                        /** @var craft\models\MatrixBlockType $matrixBlockType */
176
                                        $matrixBlockType = Craft::$app->matrix->getBlockTypeById($matrixBlockTypeId);
177
178
                                        /** @var craft\fields\Matrix $globalField */
179
                                        $globalField = Craft::$app->fields->getFieldById($matrixBlockType->fieldId);
0 ignored issues
show
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

179
                                        $globalField = Craft::$app->fields->getFieldById(/** @scrutinizer ignore-type */ $matrixBlockType->fieldId);
Loading history...
180
181
                                        $variables['superTableFields'][$matrixField->context] = [
182
                                            'kind' => 'Matrix',
183
                                            'field' => $globalField,
184
                                            'child' => [
185
                                                'kind' => 'Super Table',
186
                                                'field' => $superTableField
187
                                            ]
188
                                        ];
189
                                    }
190
                                }
191
                            }
192
                        }
193
                    }
194
                }
195
            }
196
        }
197
198
        $this->getLoader()->configurator('#spoon-global-context-table', 'global');
199
200
        return Craft::$app->controller->renderTemplate('spoon/edit-global-context', $variables);
201
    }
202
203
    // Protected Methods
204
    // =========================================================================
205
206
    /**
207
     * @inheritdoc
208
     */
209
    protected function createSettingsModel()
210
    {
211
        return new Settings();
212
    }
213
214
    /**
215
     * @inheritdoc
216
     */
217
    protected function afterUninstall()
218
    {
219
        // After uninstall drop project config keys
220
        $projectConfig = Craft::$app->getProjectConfig();
221
        $projectConfig->muteEvents = true;
222
        $projectConfig->remove(BlockTypes::CONFIG_BLOCKTYPE_KEY);
223
        $projectConfig->muteEvents = false;
224
    }
225
226
}
227