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.

AccessControlGraphQLQueryConfigurator   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 63
dl 0
loc 155
ccs 0
cts 40
cp 0
rs 10
c 1
b 0
f 0
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getACLRuleBlockModule() 0 4 1
A getACLRuleBlockNameClasses() 0 5 1
A getACLRuleBlockNameModules() 0 17 3
B executeSchemaConfiguration() 0 89 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQLAPI\GraphQLAPI\SchemaConfigurators;
6
7
use PoP\ComponentModel\Misc\GeneralUtils;
8
use GraphQLAPI\GraphQLAPI\Blocks\AbstractBlock;
9
use GraphQLAPI\GraphQLAPI\General\BlockHelpers;
10
use GraphQLAPI\GraphQLAPI\Blocks\AccessControlBlock;
11
use GraphQLAPI\GraphQLAPI\Blocks\AbstractControlBlock;
12
use GraphQLAPI\GraphQLAPI\Facades\ModuleRegistryFacade;
13
use PoP\AccessControl\Facades\AccessControlManagerFacade;
14
use PoP\ComponentModel\Facades\Instances\InstanceManagerFacade;
15
use GraphQLAPI\GraphQLAPI\ModuleResolvers\AccessControlFunctionalityModuleResolver;
16
use GraphQLAPI\GraphQLAPI\Blocks\AccessControlRuleBlocks\AbstractAccessControlRuleBlock;
17
18
class AccessControlGraphQLQueryConfigurator extends AbstractIndividualControlGraphQLQueryConfigurator
19
{
20
    public const HOOK_ACL_RULE_BLOCK_CLASS_MODULES = __CLASS__ . ':acl-url-block-class:modules';
21
22
    /**
23
     * @var array<string, string>|null
24
     */
25
    protected ?array $aclRuleBlockNameModules = null;
26
27
    // protected function doInit(): void
28
    // {
29
    //     $this->setAccessControlList();
30
    // }
31
32
    /**
33
     * Obtain the modules enabling/disabling each ACL rule block, through a hook
34
     *
35
     * @return array<string, string> Pairings of blockClass => module
36
     */
37
    protected function getACLRuleBlockNameClasses(): array
38
    {
39
        return \apply_filters(
40
            self::HOOK_ACL_RULE_BLOCK_CLASS_MODULES,
41
            []
42
        );
43
    }
44
45
    /**
46
     * Obtain the modules enabling/disabling each ACL rule block, through a hook
47
     *
48
     * @return array<string, string>
49
     */
50
    protected function getACLRuleBlockNameModules(): array
51
    {
52
        // Lazy load
53
        if (is_null($this->aclRuleBlockNameModules)) {
54
            // Obtain the block names from the block classes
55
            $instanceManager = InstanceManagerFacade::getInstance();
56
            $aclRuleBlockClassModules = $this->getACLRuleBlockNameClasses();
57
            $this->aclRuleBlockNameModules = [];
58
            foreach ($aclRuleBlockClassModules as $blockClass => $module) {
59
                /**
60
                 * @var AbstractBlock
61
                 */
62
                $block = $instanceManager->getInstance($blockClass);
63
                $this->aclRuleBlockNameModules[$block->getBlockFullName()] = $module;
64
            }
65
        }
66
        return $this->aclRuleBlockNameModules;
67
    }
68
69
    /**
70
     * Obtain the module enabling/disabling a certain ACL rule block
71
     */
72
    protected function getACLRuleBlockModule(string $blockName): ?string
73
    {
74
        $aclRuleBlockNameModules = $this->getACLRuleBlockNameModules();
75
        return $aclRuleBlockNameModules[$blockName];
76
    }
77
78
    /**
79
     * Extract the access control items defined in the CPT,
80
     * and inject them into the service as to take effect in the current GraphQL query
81
     *
82
     * @return void
83
     */
84
    public function executeSchemaConfiguration(int $aclPostID): void
85
    {
86
        // Only if the module is not disabled
87
        $moduleRegistry = ModuleRegistryFacade::getInstance();
88
        if (!$moduleRegistry->isModuleEnabled(AccessControlFunctionalityModuleResolver::ACCESS_CONTROL)) {
89
            return;
90
        }
91
92
        $instanceManager = InstanceManagerFacade::getInstance();
93
        /**
94
         * @var AccessControlBlock
95
         */
96
        $block = $instanceManager->getInstance(AccessControlBlock::class);
97
        $aclBlockItems = BlockHelpers::getBlocksOfTypeFromCustomPost(
98
            $aclPostID,
99
            $block
100
        );
101
        $accessControlManager = AccessControlManagerFacade::getInstance();
102
        // The "Access Control" type contains the fields/directives
103
        foreach ($aclBlockItems as $aclBlockItem) {
104
            // The rule to apply is contained inside the nested blocks
105
            if ($aclBlockItemNestedBlocks = $aclBlockItem['innerBlocks']) {
106
                // Filter out the rules not enabled by module
107
                if (
108
                    $aclBlockItemNestedBlocks = array_filter(
109
                        $aclBlockItemNestedBlocks,
110
                        function ($block) use ($moduleRegistry) {
111
                            // If it has a corresponding module, check if it is enabled
112
                            if ($module = $this->getACLRuleBlockModule($block['blockName'])) {
113
                                return $moduleRegistry->isModuleEnabled($module);
114
                            }
115
                            // Otherwise it's always enabled
116
                            return true;
117
                        }
118
                    )
119
                ) {
120
                    $aclBlockItemTypeFields = $aclBlockItem['attrs'][AbstractControlBlock::ATTRIBUTE_NAME_TYPE_FIELDS] ?? [];
121
                    $aclBlockItemDirectives = $aclBlockItem['attrs'][AbstractControlBlock::ATTRIBUTE_NAME_DIRECTIVES] ?? [];
122
123
                    // The value can be NULL, then it's the default mode
124
                    // In that case do nothing, since the default mode is already injected into GraphQL by PoP
125
                    $schemaMode = $aclBlockItem['attrs'][AccessControlBlock::ATTRIBUTE_NAME_SCHEMA_MODE] ?? null;
126
127
                    // Iterate all the nested blocks
128
                    foreach ($aclBlockItemNestedBlocks as $aclBlockItemNestedBlock) {
129
                        if ($accessControlGroup = $aclBlockItemNestedBlock['attrs'][AbstractAccessControlRuleBlock::ATTRIBUTE_NAME_ACCESS_CONTROL_GROUP] ?? null) {
130
                            // The value can be NULL, it depends on the actual nestedBlock
131
                            // (eg: Disable access doesn't have any, while Disable by role has the list of roles)
132
                            $value = $aclBlockItemNestedBlock['attrs'][AbstractAccessControlRuleBlock::ATTRIBUTE_NAME_VALUE] ?? null;
133
134
                            // Extract the saved fields
135
                            if (
136
                                $entriesForFields = GeneralUtils::arrayFlatten(
137
                                    array_map(
138
                                        function ($selectedField) use ($value, $schemaMode) {
139
                                            return $this->getIndividualControlEntriesFromField(
140
                                                $selectedField,
141
                                                $value,
142
                                                $schemaMode
143
                                            );
144
                                        },
145
                                        $aclBlockItemTypeFields
146
                                    )
147
                                )
148
                            ) {
149
                                $accessControlManager->addEntriesForFields(
150
                                    $accessControlGroup,
151
                                    $entriesForFields
152
                                );
153
                            }
154
155
                            // Extract the saved directives
156
                            if (
157
                                $entriesForDirectives = GeneralUtils::arrayFlatten(array_filter(
158
                                    array_map(
159
                                        function ($selectedDirective) use ($value, $schemaMode) {
160
                                            return $this->getIndividualControlEntriesFromDirective(
161
                                                $selectedDirective,
162
                                                $value,
163
                                                $schemaMode
164
                                            );
165
                                        },
166
                                        $aclBlockItemDirectives
167
                                    )
168
                                ))
169
                            ) {
170
                                $accessControlManager->addEntriesForDirectives(
171
                                    $accessControlGroup,
172
                                    $entriesForDirectives
173
                                );
174
                            }
175
                        }
176
                    }
177
                }
178
            }
179
        }
180
    }
181
}
182