GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

AbstractBlock::getBlockDependencies()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQLAPI\GraphQLAPI\Blocks;
6
7
use Error;
8
use GraphQLAPI\GraphQLAPI\General\GeneralUtils;
9
use GraphQLAPI\GraphQLAPI\General\EditorHelpers;
10
use GraphQLAPI\GraphQLAPI\Security\UserAuthorization;
11
use GraphQLAPI\GraphQLAPI\BlockCategories\AbstractBlockCategory;
12
use GraphQLAPI\GraphQLAPI\EditorScripts\HasDocumentationScriptTrait;
13
14
/**
15
 * Base class for a Gutenberg block, within a multi-block plugin.
16
 * The JS/CSS assets for each block is contained in folder {pluginDir}/blocks/{blockName}, and follows
17
 * the architecture from @wordpress/create-block package
18
 *
19
 * @see https://developer.wordpress.org/block-editor/packages/packages-create-block/
20
 * (this package provides the scaffolding for a single-block plugin,
21
 * so the plugin .php file is ignored registering a single block is ignored, and everything else is used)
22
 */
23
abstract class AbstractBlock
24
{
25
    use HasDocumentationScriptTrait;
26
27
    /**
28
     * Execute this function to initialize the block
29
     *
30
     * @return void
31
     */
32
    public function initialize(): void
33
    {
34
        \add_action('init', [$this, 'initBlock']);
35
    }
36
37
    /**
38
     * Plugin dir
39
     *
40
     * @return string
41
     */
42
    abstract protected function getPluginDir(): string;
43
    /**
44
     * Plugin URL
45
     *
46
     * @return string
47
     */
48
    abstract protected function getPluginURL(): string;
49
    /**
50
     * Block namespace
51
     *
52
     * @return string
53
     */
54
    abstract protected function getBlockNamespace(): string;
55
    /**
56
     * Block name
57
     *
58
     * @return string
59
     */
60
    abstract protected function getBlockName(): string;
61
62
    /**
63
     * If the block is dynamic, it will return the server-side HTML through function `renderBlock`
64
     */
65
    protected function isDynamicBlock(): bool
66
    {
67
        return false;
68
    }
69
    /**
70
     * Produce the HTML for dynamic blocks
71
     *
72
     * @param array<string, mixed> $attributes
73
     */
74
    public function renderBlock(array $attributes, string $content): string
75
    {
76
        return '';
77
    }
78
    /**
79
     * Do not output the content, and show an error message to the visitor
80
     */
81
    public function renderUnauthorizedAccess(): string
82
    {
83
        return sprintf(
84
            '<p>%s</p>',
85
            \__('You are not authorized to see this content', 'graphql-api')
86
        );
87
    }
88
    /**
89
     * Register index.css
90
     *
91
     * @return boolean
92
     */
93
    protected function registerEditorCSS(): bool
94
    {
95
        return false;
96
    }
97
    /**
98
     * Register style-index.css
99
     *
100
     * @return boolean
101
     */
102
    protected function registerCommonStyleCSS(): bool
103
    {
104
        return false;
105
    }
106
    /**
107
     * The block full name: namespace/blockName
108
     *
109
     * @return string
110
     */
111
    final public function getBlockFullName(): string
112
    {
113
        return sprintf(
114
            '%s/%s',
115
            $this->getBlockNamespace(),
116
            $this->getBlockName()
117
        );
118
    }
119
    /**
120
     * Block registration name: namespace-blockName
121
     *
122
     * @return string
123
     */
124
    final protected function getBlockRegistrationName(): string
125
    {
126
        return sprintf(
127
            '%s-%s',
128
            $this->getBlockNamespace(),
129
            $this->getBlockName()
130
        );
131
    }
132
    /**
133
     * Block registration name: namespace-blockName
134
     *
135
     * @return string
136
     */
137
    final protected function getBlockLocalizationName(): string
138
    {
139
        return GeneralUtils::dashesToCamelCase($this->getBlockRegistrationName());
140
    }
141
    /**
142
     * Block class name: wp-block-namespace-blockName
143
     *
144
     * @return string
145
     */
146
    protected function getBlockClassName(): string
147
    {
148
        return sprintf(
149
            'wp-block-%s',
150
            $this->getBlockRegistrationName()
151
        );
152
    }
153
154
    /**
155
     * Block align class
156
     */
157
    public function getAlignClass(): string
158
    {
159
        return 'aligncenter';
160
    }
161
162
    /**
163
     * Pass localized data to the block
164
     *
165
     * @return array<string, mixed>
166
     */
167
    protected function getLocalizedData(): array
168
    {
169
        return $this->getDocsLocalizedData();
170
    }
171
172
    /**
173
     * Where is the block stored
174
     *
175
     * @return string
176
     */
177
    protected function getBlockDirURL(): string
178
    {
179
        return $this->getPluginURL() . '/blocks/' . $this->getBlockName() . '/';
180
    }
181
182
    /**
183
     * Where is the block stored
184
     *
185
     * @return string
186
     */
187
    protected function getBlockDir(): string
188
    {
189
        return $this->getPluginDir() . '/blocks/' . $this->getBlockName();
190
    }
191
192
    protected function getBlockCategory(): ?AbstractBlockCategory
193
    {
194
        return null;
195
    }
196
197
    /**
198
     * Post types for which to register the script
199
     *
200
     * @return string[]
201
     */
202
    protected function getAllowedPostTypes(): array
203
    {
204
        if ($blockCategory = $this->getBlockCategory()) {
205
            return $blockCategory->getPostTypes();
206
        }
207
        return [];
208
    }
209
210
    /**
211
     * Dependencies to load before the block
212
     *
213
     * @return string[]
214
     */
215
    protected function getBlockDependencies(): array
216
    {
217
        return [];
218
    }
219
220
    /**
221
     * Docs are bundled as chunks by webpack, and loaded lazily
222
     * The `publicPath` property for `config.output` must be provided
223
     * pointing to the generated chunks folder, otherwise it is
224
     * by default resolved as /wp-admin/..., producing a 404.
225
     *
226
     * The public path will be set under global variable `__webpack_public_path__` in JS
227
     *
228
     * @see https://v4.webpack.js.org/guides/public-path/#on-the-fly
229
     */
230
    protected function getScriptPublicPath(): string
231
    {
232
        return $this->getBlockDirURL() . 'build/';
233
    }
234
235
    /**
236
     * Registers all block assets so that they can be enqueued through the block editor
237
     * in the corresponding context.
238
     *
239
     * @see https://developer.wordpress.org/block-editor/tutorials/block-tutorial/applying-styles-with-stylesheets/
240
     */
241
    public function initBlock(): void
242
    {
243
        /**
244
         * In the admin, if the block belongs to a category, and the category works only under certain CPTs,
245
         * then register the block only if we are on any of those CPTs.
246
         * Otherwise, the block would be registered but the category is not,
247
         * printing error console such as:
248
         * > The block "graphql-api/schema-configuration" must have a registered category.
249
         */
250
        if (\is_admin()) {
251
            if ($postTypes = $this->getAllowedPostTypes()) {
252
                if (!in_array(EditorHelpers::getEditingPostType(), $postTypes)) {
253
                    return;
254
                }
255
            }
256
        }
257
258
        $dir = $this->getBlockDir();
259
        $blockFullName = $this->getBlockFullName();
260
261
        $script_asset_path = "$dir/build/index.asset.php";
262
        if (!file_exists($script_asset_path)) {
263
            throw new Error(
264
                sprintf(
265
                    \__('You need to run `npm start` or `npm run build` for the "%s" block first.', 'graphql-api'),
266
                    $blockFullName
267
                )
268
            );
269
        }
270
271
        $url = $this->getBlockDirURL();
272
        $blockRegistrationName = $this->getBlockRegistrationName();
273
        $blockConfiguration = [];
274
275
        // Load the block scripts and styles
276
        $index_js     = 'build/index.js';
277
        $script_asset = require($script_asset_path);
278
        $scriptRegistrationName = $blockRegistrationName . '-block-editor';
279
        \wp_register_script(
280
            $scriptRegistrationName,
281
            $url . $index_js,
282
            array_merge(
283
                $script_asset['dependencies'],
284
                $this->getBlockDependencies()
285
            ),
286
            $script_asset['version']
287
        );
288
        $blockConfiguration['editor_script'] = $blockRegistrationName . '-block-editor';
289
290
        /**
291
         * Register editor CSS file
292
         */
293
        if ($this->registerEditorCSS()) {
294
            $editor_css = 'build/index.css';
295
            \wp_register_style(
296
                $blockRegistrationName . '-block-editor',
297
                $url . $editor_css,
298
                array(),
299
                // Cast object so PHPStan doesn't throw error
300
                (string)filemtime("$dir/$editor_css")
301
            );
302
            $blockConfiguration['editor_style'] = $blockRegistrationName . '-block-editor';
303
        }
304
305
        /**
306
         * Register client/editor CSS file
307
         */
308
        if ($this->registerCommonStyleCSS()) {
309
            $style_css = 'build/style-index.css';
310
            \wp_register_style(
311
                $blockRegistrationName . '-block',
312
                $url . $style_css,
313
                array(),
314
                // Cast object so PHPStan doesn't throw error
315
                (string)filemtime("$dir/$style_css")
316
            );
317
            $blockConfiguration['style'] = $blockRegistrationName . '-block';
318
        }
319
320
        /**
321
         * Register callback function for dynamic block
322
         */
323
        if ($this->isDynamicBlock()) {
324
            /**
325
             * Show only if the user has the right permission
326
             */
327
            if (UserAuthorization::canAccessSchemaEditor()) {
328
                $blockConfiguration['render_callback'] = [$this, 'renderBlock'];
329
            } else {
330
                $blockConfiguration['render_callback'] = [$this, 'renderUnauthorizedAccess'];
331
            }
332
        }
333
334
        /**
335
         * Localize the script with custom data
336
         * Execute on hook "wp_print_scripts" and not now,
337
         * because `getLocalizedData` might call EndpointHelpers::getAdminGraphQLEndpoint(),
338
         * which calls ComponentModelComponentConfiguration::namespaceTypesAndInterfaces(),
339
         * which is initialized during "wp"
340
         */
341
        \add_action('wp_print_scripts', function () use ($scriptRegistrationName) {
342
            if ($localizedData = $this->getLocalizedData()) {
343
                \wp_localize_script(
344
                    $scriptRegistrationName,
345
                    $this->getBlockLocalizationName(),
346
                    $localizedData
347
                );
348
            }
349
        });
350
351
        \register_block_type($blockFullName, $blockConfiguration);
352
353
        /**
354
         * Register the documentation (from under folder "docs/"), for the locale and the default language
355
         * @todo Maybe uncomment for webpack v5, to not duplicate the content of the docs inside build/index.js
356
         * @see https://github.com/GraphQLAPI/graphql-api-for-wp/issues/1
357
         */
358
        // $this->initDocumentationScripts();
359
    }
360
361
    /**
362
     * Register the documentation (from under folder "docs/"), for the locale and the default language
363
     */
364
    protected function initDocumentationScripts(): void
365
    {
366
        $dir = $this->getBlockDir();
367
        $script_asset_path = "$dir/build/index.asset.php";
368
        $url = $this->getBlockDirURL();
369
        $script_asset = require($script_asset_path);
370
        $blockRegistrationName = $this->getBlockRegistrationName();
371
        $scriptRegistrationName = $blockRegistrationName . '-block-editor';
372
373
        $this->registerDocumentationScripts($scriptRegistrationName, $url, $script_asset['dependencies'], $script_asset['version']);
374
    }
375
}
376