This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php declare (strict_types = 1); |
||
2 | |||
3 | namespace Limoncello\Flute\Package; |
||
4 | |||
5 | use Limoncello\Common\Reflection\ClassIsTrait; |
||
6 | use Limoncello\Contracts\Application\ApplicationConfigurationInterface as A; |
||
7 | use Limoncello\Contracts\Settings\Packages\FluteSettingsInterface; |
||
8 | use Limoncello\Flute\Contracts\Schema\SchemaInterface; |
||
9 | use Limoncello\Flute\Contracts\Validation\FormRulesInterface; |
||
10 | use Limoncello\Flute\Contracts\Validation\JsonApiDataRulesInterface; |
||
11 | use Limoncello\Flute\Contracts\Validation\JsonApiQueryRulesInterface; |
||
12 | use Limoncello\Flute\Validation\Form\Execution\FormRulesSerializer; |
||
13 | use Limoncello\Flute\Validation\JsonApi\Execution\JsonApiDataRulesSerializer; |
||
14 | use Limoncello\Flute\Validation\JsonApi\Execution\JsonApiQueryRulesSerializer; |
||
15 | use Limoncello\Flute\Validation\JsonApi\Rules\DefaultQueryValidationRules; |
||
16 | use Limoncello\Validation\Execution\BlockSerializer; |
||
17 | use Neomerx\JsonApi\Exceptions\JsonApiException; |
||
18 | use ReflectionException; |
||
19 | use function array_flip; |
||
20 | use function array_key_exists; |
||
21 | use function assert; |
||
22 | use function glob; |
||
23 | use function is_string; |
||
24 | |||
25 | /** |
||
26 | * @package Limoncello\Flute |
||
27 | */ |
||
28 | abstract class FluteSettings implements FluteSettingsInterface |
||
29 | { |
||
30 | use ClassIsTrait; |
||
31 | |||
32 | /** |
||
33 | * Default page size. |
||
34 | */ |
||
35 | public const DEFAULT_PAGE_SIZE = 10; |
||
36 | |||
37 | /** |
||
38 | * Default page size. |
||
39 | */ |
||
40 | public const DEFAULT_MAX_PAGE_SIZE = 30; |
||
41 | |||
42 | /** |
||
43 | * Default JSON API version. |
||
44 | */ |
||
45 | public const DEFAULT_JSON_API_VERSION = '1.0'; |
||
46 | |||
47 | /** Serialized validation data index */ |
||
48 | protected const JSON_API_DATA_VALIDATION_RULES_SERIALIZED = 0; |
||
49 | |||
50 | /** Serialized validation data index */ |
||
51 | protected const JSON_API_QUERIES_VALIDATION_RULES_SERIALIZED = self::JSON_API_DATA_VALIDATION_RULES_SERIALIZED + 1; |
||
52 | |||
53 | /** |
||
54 | * @param array $appConfig |
||
55 | 32 | * |
|
56 | * @return array |
||
57 | 32 | * |
|
58 | * @throws ReflectionException |
||
59 | 32 | */ |
|
60 | 32 | final public function get(array $appConfig): array |
|
61 | { |
||
62 | 32 | $defaults = $this->getSettings(); |
|
63 | 32 | ||
64 | 32 | $defaults[static::KEY_ROUTES_FOLDER] = $appConfig[A::KEY_ROUTES_FOLDER]; |
|
65 | 32 | $defaults[static::KEY_WEB_CONTROLLERS_FOLDER] = $appConfig[A::KEY_WEB_CONTROLLERS_FOLDER]; |
|
66 | 32 | ||
67 | 32 | $apiFolder = $defaults[static::KEY_API_FOLDER] ?? null; |
|
68 | 32 | $valRulesFolder = $defaults[static::KEY_JSON_VALIDATION_RULES_FOLDER] ?? null; |
|
69 | 32 | $jsonCtrlFolder = $defaults[static::KEY_JSON_CONTROLLERS_FOLDER] ?? null; |
|
70 | 32 | $schemasFolder = $defaults[static::KEY_SCHEMAS_FOLDER] ?? null; |
|
71 | 32 | $schemasFileMask = $defaults[static::KEY_SCHEMAS_FILE_MASK] ?? null; |
|
72 | 32 | $jsonDataValFolder = $defaults[static::KEY_JSON_VALIDATORS_FOLDER] ?? null; |
|
73 | $jsonDataValFileMask = $defaults[static::KEY_JSON_VALIDATORS_FILE_MASK] ?? null; |
||
74 | 32 | $formsValFolder = $defaults[static::KEY_FORM_VALIDATORS_FOLDER] ?? null; |
|
75 | 32 | $formsValFileMask = $defaults[static::KEY_FORM_VALIDATORS_FILE_MASK] ?? null; |
|
76 | 32 | $jsonQueryValFolder = $defaults[static::KEY_QUERY_VALIDATORS_FOLDER] ?? null; |
|
77 | $jsonQueryValFileMask = $defaults[static::KEY_QUERY_VALIDATORS_FILE_MASK] ?? null; |
||
78 | 32 | ||
79 | 32 | assert( |
|
80 | 32 | $apiFolder !== null && empty(glob($apiFolder)) === false, |
|
81 | "Invalid API folder `$apiFolder`." |
||
82 | 32 | ); |
|
83 | 32 | assert( |
|
84 | 32 | $valRulesFolder !== null && empty(glob($valRulesFolder)) === false, |
|
85 | "Invalid validation rules folder `$valRulesFolder`." |
||
86 | 32 | ); |
|
87 | 32 | assert( |
|
88 | 32 | $jsonCtrlFolder !== null && empty(glob($jsonCtrlFolder)) === false, |
|
89 | "Invalid JSON API controllers' folder `$jsonCtrlFolder`." |
||
90 | 32 | ); |
|
91 | 32 | assert( |
|
92 | 32 | $schemasFolder !== null && empty(glob($schemasFolder)) === false, |
|
93 | 32 | "Invalid Schemas folder `$schemasFolder`." |
|
94 | ); |
||
95 | 32 | assert(empty($schemasFileMask) === false, "Invalid Schemas file mask `$schemasFileMask`."); |
|
96 | 32 | assert( |
|
97 | 32 | $jsonDataValFolder !== null && empty(glob($jsonDataValFolder)) === false, |
|
98 | 32 | "Invalid JSON Validators folder `$jsonDataValFolder`." |
|
99 | ); |
||
100 | 32 | assert(empty($jsonDataValFileMask) === false, "Invalid JSON Validators file mask `$jsonDataValFileMask`."); |
|
101 | 32 | assert( |
|
102 | 32 | $formsValFolder !== null && empty(glob($formsValFolder)) === false, |
|
103 | 32 | "Invalid Forms Validators folder `$formsValFolder`." |
|
104 | ); |
||
105 | 32 | assert(empty($formsValFileMask) === false, "Invalid Forms Validators file mask `$formsValFileMask`."); |
|
106 | assert( |
||
107 | 32 | $jsonQueryValFolder !== null && empty(glob($jsonQueryValFolder)) === false, |
|
108 | 32 | "Invalid Query Validators folder `$jsonQueryValFolder`." |
|
109 | 32 | ); |
|
110 | 32 | assert(empty($jsonQueryValFileMask) === false, "Invalid Query Validators file mask `$jsonQueryValFileMask`."); |
|
111 | |||
112 | 32 | $schemasPath = $schemasFolder . DIRECTORY_SEPARATOR . $schemasFileMask; |
|
113 | $jsonDataValPath = $jsonDataValFolder . DIRECTORY_SEPARATOR . $jsonDataValFileMask; |
||
114 | 32 | $formsValidatorsPath = $formsValFolder . DIRECTORY_SEPARATOR . $formsValFileMask; |
|
115 | 32 | $jsonQueryValPath = $jsonQueryValFolder . DIRECTORY_SEPARATOR . $jsonQueryValFileMask; |
|
116 | |||
117 | 32 | $requireUniqueTypes = $defaults[static::KEY_SCHEMAS_REQUIRE_UNIQUE_TYPES] ?? true; |
|
118 | |||
119 | $doNotLogExceptions = $defaults[static::KEY_DO_NOT_LOG_EXCEPTIONS_LIST] ?? []; |
||
120 | 32 | unset($defaults[static::KEY_DO_NOT_LOG_EXCEPTIONS_LIST]); |
|
121 | |||
122 | 32 | [$modelToSchemaMap, $typeToSchemaMap] = $this->createSchemaMapping($schemasPath, $requireUniqueTypes); |
|
0 ignored issues
–
show
The variable
$typeToSchemaMap does not exist. Did you forget to declare it?
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug. ![]() |
|||
123 | 32 | ||
124 | return $defaults + [ |
||
125 | 32 | static::KEY_DO_NOT_LOG_EXCEPTIONS_LIST__AS_KEYS => array_flip($doNotLogExceptions), |
|
126 | 32 | ||
127 | static::KEY_MODEL_TO_SCHEMA_MAP => $modelToSchemaMap, |
||
128 | 32 | static::KEY_TYPE_TO_SCHEMA_MAP => $typeToSchemaMap, |
|
129 | 32 | ||
130 | static::KEY_JSON_VALIDATION_RULE_SETS_DATA => |
||
131 | $this->serializeJsonValidationRules($jsonDataValPath, $jsonQueryValPath), |
||
132 | |||
133 | static::KEY_ATTRIBUTE_VALIDATION_RULE_SETS_DATA => |
||
134 | $this->serializeFormValidationRules($formsValidatorsPath), |
||
135 | ]; |
||
136 | 32 | } |
|
137 | |||
138 | 32 | /** |
|
139 | * @return array |
||
140 | */ |
||
141 | 32 | protected function getSettings(): array |
|
142 | 32 | { |
|
143 | 32 | $jsonOptions = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES; |
|
144 | 32 | ||
145 | 32 | return [ |
|
146 | 32 | static::KEY_SCHEMAS_REQUIRE_UNIQUE_TYPES => true, |
|
147 | 32 | static::KEY_SCHEMAS_FILE_MASK => '*.php', |
|
148 | 32 | static::KEY_JSON_VALIDATORS_FILE_MASK => '*.php', |
|
149 | 32 | static::KEY_FORM_VALIDATORS_FILE_MASK => '*.php', |
|
150 | 32 | static::KEY_QUERY_VALIDATORS_FILE_MASK => '*.php', |
|
151 | 32 | static::KEY_THROWABLE_TO_JSON_API_EXCEPTION_CONVERTER => null, |
|
152 | 32 | static::KEY_HTTP_CODE_FOR_UNEXPECTED_THROWABLE => 500, |
|
153 | 32 | static::KEY_DEFAULT_PAGING_SIZE => static::DEFAULT_PAGE_SIZE, |
|
154 | 32 | static::KEY_MAX_PAGING_SIZE => static::DEFAULT_MAX_PAGE_SIZE, |
|
155 | static::KEY_JSON_ENCODE_OPTIONS => $jsonOptions, |
||
156 | 32 | static::KEY_JSON_ENCODE_DEPTH => 512, |
|
157 | static::KEY_IS_SHOW_VERSION => false, |
||
158 | static::KEY_META => null, |
||
159 | static::KEY_URI_PREFIX => '', |
||
160 | |||
161 | static::KEY_DO_NOT_LOG_EXCEPTIONS_LIST => [ |
||
162 | JsonApiException::class, |
||
163 | ], |
||
164 | ]; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * @param string $schemasPath |
||
169 | * @param bool $requireUniqueTypes |
||
170 | 32 | * |
|
171 | * @return array |
||
172 | 32 | * |
|
173 | 32 | * @throws ReflectionException |
|
174 | 32 | */ |
|
175 | 32 | private function createSchemaMapping(string $schemasPath, bool $requireUniqueTypes): array |
|
176 | { |
||
177 | $modelMap = []; |
||
178 | 32 | $typeMap = []; |
|
179 | 32 | foreach ($this->selectClasses($schemasPath, SchemaInterface::class) as $schemaClass) { |
|
180 | assert(static::classImplements($schemaClass, SchemaInterface::class)); |
||
181 | 32 | ||
182 | 32 | /** @var SchemaInterface $schemaClass */ |
|
183 | $modelClass = $schemaClass::MODEL; |
||
184 | $resourceType = $schemaClass::TYPE; |
||
185 | |||
186 | assert(is_string($modelClass) === true && empty($modelClass) === false); |
||
187 | assert(is_string($resourceType) === true && empty($resourceType) === false); |
||
188 | 32 | ||
189 | 32 | // By default it checks that all Schemas have unique resource types. That's a legit case |
|
190 | 32 | // to have multiple Schemas for a same resource type however it's more likely that developer |
|
191 | // just forgot to set a unique one. If you do need multiple Schemas for a resource feel free |
||
192 | 32 | // to set to turn off this check. |
|
193 | assert( |
||
194 | 32 | $requireUniqueTypes === false || array_key_exists($resourceType, $typeMap) === false, |
|
195 | "Are you sure it's not an error to use resource type `$resourceType` more than once?" |
||
196 | ); |
||
197 | 32 | $typeMap[$resourceType] = $schemaClass; |
|
198 | |||
199 | $modelMap[$modelClass] = $schemaClass; |
||
200 | } |
||
201 | |||
202 | return [$modelMap, $typeMap]; |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * @param string $rulesPath |
||
207 | * @param string $queriesValPath |
||
208 | 32 | * |
|
209 | * @return array |
||
210 | * |
||
211 | 32 | * @throws ReflectionException |
|
212 | 32 | */ |
|
213 | 32 | private function serializeJsonValidationRules(string $rulesPath, string $queriesValPath): array |
|
214 | { |
||
215 | // JSON API data validation rules |
||
216 | $dataSerializer = new JsonApiDataRulesSerializer(new BlockSerializer()); |
||
217 | 32 | foreach ($this->selectClasses($rulesPath, JsonApiDataRulesInterface::class) as $rulesClass) { |
|
218 | $dataSerializer->addRulesFromClass($rulesClass); |
||
219 | 32 | } |
|
220 | |||
221 | 32 | // JSON API query validation rules |
|
222 | 32 | $querySerializer = new JsonApiQueryRulesSerializer(new BlockSerializer()); |
|
223 | // Add predefined rules for queries... |
||
224 | $querySerializer->addRulesFromClass(DefaultQueryValidationRules::class); |
||
225 | // ... and add user defined ones. |
||
226 | 32 | foreach ($this->selectClasses($queriesValPath, JsonApiQueryRulesInterface::class) as $rulesClass) { |
|
227 | 32 | $querySerializer->addRulesFromClass($rulesClass); |
|
228 | } |
||
229 | |||
230 | return [ |
||
231 | static::JSON_API_DATA_VALIDATION_RULES_SERIALIZED => $dataSerializer->getData(), |
||
232 | static::JSON_API_QUERIES_VALIDATION_RULES_SERIALIZED => $querySerializer->getData(), |
||
233 | ]; |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * @param string $formsValPath |
||
238 | 32 | * |
|
239 | * @return array |
||
240 | 32 | * |
|
241 | * @throws ReflectionException |
||
242 | 32 | */ |
|
243 | 32 | private function serializeFormValidationRules(string $formsValPath): array |
|
244 | { |
||
245 | $serializer = new FormRulesSerializer(new BlockSerializer()); |
||
246 | 32 | ||
247 | foreach ($this->selectClasses($formsValPath, FormRulesInterface::class) as $rulesClass) { |
||
248 | $serializer->addRulesFromClass($rulesClass); |
||
249 | } |
||
250 | |||
251 | return $serializer->getData(); |
||
252 | } |
||
253 | |||
254 | // serialization above makes some assumptions about format of returned data |
||
255 | // the methods below help to deal with the data encapsulation |
||
256 | |||
257 | 14 | /** |
|
258 | * @param array $fluteSettings |
||
259 | 14 | * |
|
260 | 14 | * @return array |
|
261 | */ |
||
262 | 14 | public static function getJsonDataSerializedRules(array $fluteSettings): array |
|
263 | { |
||
264 | $serializedRulesKey = static::KEY_JSON_VALIDATION_RULE_SETS_DATA; |
||
265 | $dataSubKey = static::JSON_API_DATA_VALIDATION_RULES_SERIALIZED; |
||
266 | |||
267 | return $fluteSettings[$serializedRulesKey][$dataSubKey]; |
||
268 | } |
||
269 | |||
270 | 23 | /** |
|
271 | * @param array $fluteSettings |
||
272 | 23 | * |
|
273 | 23 | * @return array |
|
274 | */ |
||
275 | 23 | public static function getJsonQuerySerializedRules(array $fluteSettings): array |
|
276 | { |
||
277 | $serializedRulesKey = static::KEY_JSON_VALIDATION_RULE_SETS_DATA; |
||
278 | $dataSubKey = static::JSON_API_QUERIES_VALIDATION_RULES_SERIALIZED; |
||
279 | |||
280 | return $fluteSettings[$serializedRulesKey][$dataSubKey]; |
||
281 | } |
||
282 | |||
283 | 1 | /** |
|
284 | * @param array $fluteSettings |
||
285 | 1 | * |
|
286 | * @return array |
||
287 | */ |
||
288 | public static function getFormSerializedRules(array $fluteSettings): array |
||
289 | { |
||
290 | return $fluteSettings[static::KEY_ATTRIBUTE_VALIDATION_RULE_SETS_DATA]; |
||
291 | } |
||
292 | } |
||
293 |
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.