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.

GraphQLEndpointPostType::getPostTypeLabels()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 9
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\PostTypes;
6
7
use WP_Post;
8
use PoP\ComponentModel\State\ApplicationState;
9
use GraphQLAPI\GraphQLAPI\General\RequestParams;
10
use GraphQLAPI\GraphQLAPI\ComponentConfiguration;
11
use GraphQLAPI\GraphQLAPI\Blocks\EndpointOptionsBlock;
12
use GraphQLAPI\GraphQLAPI\Facades\ModuleRegistryFacade;
13
use GraphQLAPI\GraphQLAPI\Taxonomies\GraphQLQueryTaxonomy;
14
use GraphQLByPoP\GraphQLClientsForWP\Clients\AbstractClient;
15
use GraphQLAPI\GraphQLAPI\Clients\CustomEndpointVoyagerClient;
16
use GraphQLAPI\GraphQLAPI\Clients\CustomEndpointGraphiQLClient;
17
use PoP\ComponentModel\Facades\Instances\InstanceManagerFacade;
18
use GraphQLByPoP\GraphQLRequest\Execution\QueryExecutionHelpers;
19
use GraphQLAPI\GraphQLAPI\Blocks\AbstractQueryExecutionOptionsBlock;
20
use GraphQLAPI\GraphQLAPI\PostTypes\AbstractGraphQLQueryExecutionPostType;
21
use GraphQLAPI\GraphQLAPI\ModuleResolvers\ClientFunctionalityModuleResolver;
22
23
class GraphQLEndpointPostType extends AbstractGraphQLQueryExecutionPostType
24
{
25
    /**
26
     * Custom Post Type name
27
     */
28
    public const POST_TYPE = 'graphql-endpoint';
29
30
    /**
31
     * Custom Post Type name
32
     */
33
    protected function getPostType(): string
34
    {
35
        return self::POST_TYPE;
36
    }
37
38
    /**
39
     * Access endpoints under /graphql, or wherever it is configured to
40
     */
41
    protected function getSlugBase(): ?string
42
    {
43
        return ComponentConfiguration::getCustomEndpointSlugBase();
44
    }
45
46
    /**
47
     * Custom post type name
48
     */
49
    public function getPostTypeName(): string
50
    {
51
        return \__('GraphQL endpoint', 'graphql-api');
52
    }
53
54
    /**
55
     * Custom Post Type plural name
56
     *
57
     * @param bool $uppercase Indicate if the name must be uppercase (for starting a sentence) or, otherwise, lowercase
58
     */
59
    protected function getPostTypePluralNames(bool $uppercase): string
60
    {
61
        return \__('GraphQL endpoints', 'graphql-api');
62
    }
63
64
    /**
65
     * Labels for registering the post type
66
     *
67
     * @param string $name_uc Singular name uppercase
68
     * @param string $names_uc Plural name uppercase
69
     * @param string $names_lc Plural name lowercase
70
     * @return array<string, string>
71
     */
72
    protected function getPostTypeLabels(string $name_uc, string $names_uc, string $names_lc): array
73
    {
74
        /**
75
         * Because the name is too long, shorten it for the admin menu only
76
         */
77
        return array_merge(
78
            parent::getPostTypeLabels($name_uc, $names_uc, $names_lc),
79
            array(
80
                'all_items' => \__('Custom Endpoints', 'graphql-api'),
81
            )
82
        );
83
    }
84
85
    /**
86
     * The Query is publicly accessible, and the permalink must be configurable
87
     */
88
    protected function isPublic(): bool
89
    {
90
        return true;
91
    }
92
93
    /**
94
     * Taxonomies
95
     *
96
     * @return string[]
97
     */
98
    protected function getTaxonomies(): array
99
    {
100
        return [
101
            GraphQLQueryTaxonomy::TAXONOMY_CATEGORY,
102
        ];
103
    }
104
105
    /**
106
     * Hierarchical
107
     */
108
    protected function isHierarchical(): bool
109
    {
110
        return true;
111
    }
112
113
    /**
114
     * Gutenberg templates to lock down the Custom Post Type to
115
     *
116
     * @return array<array> Every element is an array with template name in first pos, and attributes then
117
     */
118
    protected function getGutenbergTemplate(): array
119
    {
120
        $template = parent::getGutenbergTemplate();
121
122
        $instanceManager = InstanceManagerFacade::getInstance();
123
        /**
124
         * @var EndpointOptionsBlock
125
         */
126
        $endpointOptionsBlock = $instanceManager->getInstance(EndpointOptionsBlock::class);
127
        $template[] = [$endpointOptionsBlock->getBlockFullName()];
128
        return $template;
129
    }
130
131
    /**
132
     * Indicates if to lock the Gutenberg templates
133
     */
134
    protected function lockGutenbergTemplate(): bool
135
    {
136
        return true;
137
    }
138
139
    /**
140
     * Indicate if the excerpt must be used as the CPT's description and rendered when rendering the post
141
     */
142
    public function usePostExcerptAsDescription(): bool
143
    {
144
        return true;
145
    }
146
147
    /**
148
     * Label to show on the "execute" action in the CPT table
149
     */
150
    protected function getExecuteActionLabel(): string
151
    {
152
        return __('View endpoint', 'graphql-api');
153
    }
154
155
    /**
156
     * Provide the query to execute and its variables
157
     *
158
     * @return mixed[] Array of 2 elements: [query, variables]
159
     */
160
    protected function getGraphQLQueryAndVariables(?WP_Post $graphQLQueryPost): array
161
    {
162
        /**
163
         * Extract the query from the BODY through standard GraphQL endpoint execution
164
         */
165
        return QueryExecutionHelpers::extractRequestedGraphQLQueryPayload();
166
    }
167
168
    protected function getQueryExecutionOptionsBlock(): AbstractQueryExecutionOptionsBlock
169
    {
170
        $instanceManager = InstanceManagerFacade::getInstance();
171
        /**
172
         * @var EndpointOptionsBlock
173
         */
174
        $block = $instanceManager->getInstance(EndpointOptionsBlock::class);
175
        return $block;
176
    }
177
178
    /**
179
     * Indicates if we executing the GraphQL query (`true`) or visualizing the query source (`false`)
180
     * It returns always `true`, unless passing ?view=source in the single post URL
181
     */
182
    protected function isGraphQLQueryExecution(): bool
183
    {
184
        return !in_array(
185
            $_REQUEST[RequestParams::VIEW] ?? null,
186
            [
187
                RequestParams::VIEW_GRAPHIQL,
188
                RequestParams::VIEW_SCHEMA,
189
                RequestParams::VIEW_SOURCE,
190
            ]
191
        );
192
    }
193
194
    /**
195
     * Set the hook to expose the GraphiQL/Voyager clients
196
     */
197
    protected function doSomethingElse(): void
198
    {
199
        if (($_REQUEST[RequestParams::VIEW] ?? null) == RequestParams::VIEW_SOURCE) {
200
            parent::doSomethingElse();
201
        } else {
202
            /**
203
             * Execute at the very last, because Component::boot is executed also on hook "wp",
204
             * and there is useNamespacing set
205
             */
206
            \add_action(
207
                'wp',
208
                [$this, 'maybePrintClient'],
209
                PHP_INT_MAX
210
            );
211
        }
212
    }
213
    /**
214
     * Expose the GraphiQL/Voyager clients
215
     */
216
    public function maybePrintClient(): void
217
    {
218
        $vars = ApplicationState::getVars();
219
        $customPost = $vars['routing-state']['queried-object'];
220
        // Make sure there is a post (eg: it has not been deleted)
221
        if ($customPost === null) {
222
            return;
223
        }
224
        $view = $_REQUEST[RequestParams::VIEW] ?? '';
225
        // Read from the configuration if to expose the GraphiQL/Voyager client
226
        if (
227
            (
228
                $view == RequestParams::VIEW_GRAPHIQL
229
                && $this->isGraphiQLEnabled($customPost)
230
            )
231
            || (
232
                $view == RequestParams::VIEW_SCHEMA
233
                && $this->isVoyagerEnabled($customPost)
234
            )
235
        ) {
236
            // Print the HTML directly from the client
237
            $clientClasses = [
238
                RequestParams::VIEW_GRAPHIQL => CustomEndpointGraphiQLClient::class,
239
                RequestParams::VIEW_SCHEMA => CustomEndpointVoyagerClient::class,
240
            ];
241
            $instanceManager = InstanceManagerFacade::getInstance();
242
            /**
243
             * @var AbstractClient
244
             */
245
            $client = $instanceManager->getInstance($clientClasses[$view]);
246
            echo $client->getClientHTML();
247
            die;
248
        }
249
    }
250
251
    /**
252
     * Read the options block and check the value of attribute "isGraphiQLEnabled"
253
     *
254
     * @param WP_Post|int $postOrID
255
     */
256
    protected function isGraphiQLEnabled($postOrID): bool
257
    {
258
        // Check if disabled by module
259
        $moduleRegistry = ModuleRegistryFacade::getInstance();
260
        if (!$moduleRegistry->isModuleEnabled(ClientFunctionalityModuleResolver::GRAPHIQL_FOR_CUSTOM_ENDPOINTS)) {
261
            return false;
262
        }
263
264
        // If the endpoint is disabled, then also disable this client
265
        if (!$this->isEnabled($postOrID)) {
266
            return false;
267
        }
268
269
        // `true` is the default option in Gutenberg, so it's not saved to the DB!
270
        return $this->isOptionsBlockValueOn(
271
            $postOrID,
272
            EndpointOptionsBlock::ATTRIBUTE_NAME_IS_GRAPHIQL_ENABLED,
273
            true
274
        );
275
    }
276
277
    /**
278
     * Read the options block and check the value of attribute "isVoyagerEnabled"
279
     *
280
     * @param WP_Post|int $postOrID
281
     */
282
    protected function isVoyagerEnabled($postOrID): bool
283
    {
284
        // Check if disabled by module
285
        $moduleRegistry = ModuleRegistryFacade::getInstance();
286
        if (!$moduleRegistry->isModuleEnabled(ClientFunctionalityModuleResolver::INTERACTIVE_SCHEMA_FOR_CUSTOM_ENDPOINTS)) {
287
            return false;
288
        }
289
290
        // If the endpoint is disabled, then also disable this client
291
        if (!$this->isEnabled($postOrID)) {
292
            return false;
293
        }
294
295
        // `true` is the default option in Gutenberg, so it's not saved to the DB!
296
        return $this->isOptionsBlockValueOn(
297
            $postOrID,
298
            EndpointOptionsBlock::ATTRIBUTE_NAME_IS_VOYAGER_ENABLED,
299
            true
300
        );
301
    }
302
303
    /**
304
     * Get actions to add for this CPT
305
     *
306
     * @param WP_Post $post
307
     * @return array<string, string>
308
     */
309
    protected function getPostTypeTableActions($post): array
310
    {
311
        $actions = parent::getPostTypeTableActions($post);
312
313
        /**
314
         * If neither GraphiQL or Voyager are enabled, then already return
315
         */
316
        $isGraphiQLEnabled = $this->isGraphiQLEnabled($post);
317
        $isVoyagerEnabled = $this->isVoyagerEnabled($post);
318
        if (!$isGraphiQLEnabled && !$isVoyagerEnabled) {
319
            return $actions;
320
        }
321
322
        $title = \_draft_or_post_title();
323
        $permalink = \get_permalink($post->ID);
324
        /**
325
         * Attach the GraphiQL/Voyager clients
326
         */
327
        return array_merge(
328
            $actions,
329
            // If GraphiQL enabled, add the "GraphiQL" action
330
            $isGraphiQLEnabled ? [
331
                'graphiql' => sprintf(
332
                    '<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
333
                    \add_query_arg(
334
                        RequestParams::VIEW,
335
                        RequestParams::VIEW_GRAPHIQL,
336
                        $permalink
337
                    ),
338
                    /* translators: %s: Post title. */
339
                    \esc_attr(\sprintf(\__('GraphiQL &#8220;%s&#8221;'), $title)),
340
                    __('GraphiQL', 'graphql-api')
341
                ),
342
            ] : [],
343
            // If Voyager enabled, add the "Schema" action
344
            $isVoyagerEnabled ? [
345
                'schema' => sprintf(
346
                    '<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
347
                    \add_query_arg(
348
                        RequestParams::VIEW,
349
                        RequestParams::VIEW_SCHEMA,
350
                        $permalink
351
                    ),
352
                    /* translators: %s: Post title. */
353
                    \esc_attr(\sprintf(\__('Schema &#8220;%s&#8221;'), $title)),
354
                    __('Interactive schema', 'graphql-api')
355
                )
356
            ] : []
357
        );
358
    }
359
}
360