1 | <?php |
||||||
2 | /** |
||||||
3 | * SEOmatic plugin for Craft CMS |
||||||
4 | * |
||||||
5 | * @link https://nystudio107.com/ |
||||||
6 | * @copyright Copyright (c) 2017 nystudio107 |
||||||
7 | * @license https://nystudio107.com/license |
||||||
8 | */ |
||||||
9 | |||||||
10 | namespace nystudio107\seomatic\fields; |
||||||
11 | |||||||
12 | use Craft; |
||||||
13 | use craft\base\Element; |
||||||
14 | use craft\base\ElementInterface; |
||||||
0 ignored issues
–
show
|
|||||||
15 | use craft\base\Field; |
||||||
16 | use craft\base\PreviewableFieldInterface; |
||||||
17 | use craft\elements\Asset; |
||||||
18 | use craft\helpers\Json; |
||||||
19 | use craft\helpers\StringHelper; |
||||||
20 | use nystudio107\seomatic\assetbundles\seomatic\SeomaticAsset; |
||||||
21 | use nystudio107\seomatic\helpers\ArrayHelper; |
||||||
22 | use nystudio107\seomatic\helpers\Config as ConfigHelper; |
||||||
23 | use nystudio107\seomatic\helpers\Field as FieldHelper; |
||||||
24 | use nystudio107\seomatic\helpers\Migration as MigrationHelper; |
||||||
25 | use nystudio107\seomatic\helpers\PullField as PullFieldHelper; |
||||||
26 | use nystudio107\seomatic\helpers\Schema as SchemaHelper; |
||||||
27 | use nystudio107\seomatic\models\MetaBundle; |
||||||
28 | use nystudio107\seomatic\seoelements\SeoEntry; |
||||||
29 | use nystudio107\seomatic\Seomatic; |
||||||
30 | use nystudio107\seomatic\services\MetaContainers; |
||||||
31 | use ReflectionClass; |
||||||
32 | use yii\base\InvalidConfigException; |
||||||
33 | use yii\caching\TagDependency; |
||||||
34 | use yii\db\Schema; |
||||||
35 | use function in_array; |
||||||
36 | use function is_array; |
||||||
37 | use function is_object; |
||||||
38 | use function is_string; |
||||||
39 | |||||||
40 | /** |
||||||
41 | * @author nystudio107 |
||||||
42 | * @package Seomatic |
||||||
43 | * @since 3.0.0 |
||||||
44 | */ |
||||||
45 | class SeoSettings extends Field implements PreviewableFieldInterface |
||||||
46 | { |
||||||
47 | // Constants |
||||||
48 | // ========================================================================= |
||||||
49 | |||||||
50 | public const CACHE_KEY = 'seomatic_fieldmeta_'; |
||||||
51 | |||||||
52 | public const BUNDLE_COMPARE_FIELDS = [ |
||||||
53 | 'metaGlobalVars', |
||||||
54 | ]; |
||||||
55 | |||||||
56 | // Public Properties |
||||||
57 | // ========================================================================= |
||||||
58 | |||||||
59 | /** |
||||||
60 | * @var string |
||||||
61 | */ |
||||||
62 | public $elementDisplayPreviewType = 'google'; |
||||||
63 | |||||||
64 | /** |
||||||
65 | * @var bool |
||||||
66 | */ |
||||||
67 | public $generalTabEnabled = true; |
||||||
68 | |||||||
69 | /** |
||||||
70 | * @var array |
||||||
71 | */ |
||||||
72 | public $generalEnabledFields = [ |
||||||
73 | 'seoTitle', |
||||||
74 | 'seoDescription', |
||||||
75 | 'seoImage', |
||||||
76 | ]; |
||||||
77 | |||||||
78 | /** |
||||||
79 | * @var bool |
||||||
80 | */ |
||||||
81 | public $twitterTabEnabled = false; |
||||||
82 | |||||||
83 | /** |
||||||
84 | * @var array |
||||||
85 | */ |
||||||
86 | public $twitterEnabledFields = []; |
||||||
87 | |||||||
88 | /** |
||||||
89 | * @var bool |
||||||
90 | */ |
||||||
91 | public $facebookTabEnabled = false; |
||||||
92 | |||||||
93 | /** |
||||||
94 | * @var array |
||||||
95 | */ |
||||||
96 | public $facebookEnabledFields = []; |
||||||
97 | |||||||
98 | /** |
||||||
99 | * @var bool |
||||||
100 | */ |
||||||
101 | public $sitemapTabEnabled = false; |
||||||
102 | |||||||
103 | /** |
||||||
104 | * @var array |
||||||
105 | */ |
||||||
106 | public $sitemapEnabledFields = []; |
||||||
107 | |||||||
108 | // Static Methods |
||||||
109 | // ========================================================================= |
||||||
110 | |||||||
111 | /** |
||||||
112 | * @inheritdoc |
||||||
113 | */ |
||||||
114 | public static function dbType(): array|string|null |
||||||
115 | { |
||||||
116 | return Schema::TYPE_TEXT; |
||||||
117 | } |
||||||
118 | |||||||
119 | /** |
||||||
120 | * @inheritdoc |
||||||
121 | */ |
||||||
122 | public static function displayName(): string |
||||||
123 | { |
||||||
124 | return Craft::t('seomatic', 'SEO Settings'); |
||||||
125 | } |
||||||
126 | |||||||
127 | /** |
||||||
128 | * @inheritdoc |
||||||
129 | */ |
||||||
130 | public static function icon(): string |
||||||
131 | { |
||||||
132 | return '@nystudio107/seomatic/icon-mask.svg'; |
||||||
133 | } |
||||||
134 | |||||||
135 | /** |
||||||
136 | * @inheritdoc |
||||||
137 | */ |
||||||
138 | public static function phpType(): string |
||||||
139 | { |
||||||
140 | return sprintf('\\%s', MetaBundle::class); |
||||||
141 | } |
||||||
142 | |||||||
143 | // Public Methods |
||||||
144 | // ========================================================================= |
||||||
145 | |||||||
146 | /** |
||||||
147 | * @inheritdoc |
||||||
148 | */ |
||||||
149 | public function rules(): array |
||||||
150 | { |
||||||
151 | $rules = parent::rules(); |
||||||
152 | $rules = array_merge($rules, [ |
||||||
153 | [ |
||||||
154 | [ |
||||||
155 | 'elementDisplayPreviewType', |
||||||
156 | ], |
||||||
157 | 'string', |
||||||
158 | ], |
||||||
159 | [ |
||||||
160 | [ |
||||||
161 | 'generalTabEnabled', |
||||||
162 | 'twitterTabEnabled', |
||||||
163 | 'facebookTabEnabled', |
||||||
164 | 'sitemapTabEnabled', |
||||||
165 | ], |
||||||
166 | 'boolean', |
||||||
167 | ], |
||||||
168 | [ |
||||||
169 | [ |
||||||
170 | 'generalEnabledFields', |
||||||
171 | 'twitterEnabledFields', |
||||||
172 | 'facebookEnabledFields', |
||||||
173 | 'sitemapEnabledFields', |
||||||
174 | ], |
||||||
175 | 'each', 'rule' => ['string'], |
||||||
176 | ], |
||||||
177 | |||||||
178 | ]); |
||||||
179 | |||||||
180 | return $rules; |
||||||
181 | } |
||||||
182 | |||||||
183 | /** |
||||||
184 | * @inheritdoc |
||||||
185 | * @since 2.0.0 |
||||||
186 | */ |
||||||
187 | public function useFieldset(): bool |
||||||
188 | { |
||||||
189 | return false; |
||||||
190 | } |
||||||
191 | |||||||
192 | /** |
||||||
193 | * @inheritdoc |
||||||
194 | */ |
||||||
195 | public function normalizeValue(mixed $value, ?ElementInterface $element = null): mixed |
||||||
196 | { |
||||||
197 | $config = []; |
||||||
198 | // Handle incoming values potentially being JSON, an array, or an object |
||||||
199 | if (!empty($value)) { |
||||||
200 | if (is_string($value)) { |
||||||
201 | // Decode any html entities |
||||||
202 | $value = html_entity_decode($value, ENT_NOQUOTES, 'UTF-8'); |
||||||
203 | $config = Json::decodeIfJson($value); |
||||||
204 | } |
||||||
205 | if (is_array($value)) { |
||||||
206 | $config = $value; |
||||||
207 | } |
||||||
208 | if (is_object($value) && $value instanceof MetaBundle) { |
||||||
209 | $config = $value->toArray(); |
||||||
210 | } |
||||||
211 | } else { |
||||||
212 | /** @var null|Element $element */ |
||||||
213 | $config = MigrationHelper::configFromSeomaticMeta( |
||||||
214 | $element, |
||||||
215 | MigrationHelper::FIELD_MIGRATION_CONTEXT |
||||||
216 | ); |
||||||
217 | } |
||||||
218 | // If the config isn't empty, do some processing on the values |
||||||
219 | if (!empty($config)) { |
||||||
220 | $elementName = ''; |
||||||
221 | /** @var Element $element */ |
||||||
222 | if ($element !== null) { |
||||||
223 | $reflector = new ReflectionClass($element); |
||||||
224 | $elementName = strtolower($reflector->getShortName()); |
||||||
225 | } |
||||||
226 | // Handle the pull fields |
||||||
227 | if (!empty($config['metaGlobalVars']) && !empty($config['metaBundleSettings'])) { |
||||||
228 | PullFieldHelper::parseTextSources( |
||||||
229 | $elementName, |
||||||
230 | $config['metaGlobalVars'], |
||||||
231 | $config['metaBundleSettings'] |
||||||
232 | ); |
||||||
233 | PullFieldHelper::parseImageSources( |
||||||
234 | $elementName, |
||||||
235 | $config['metaGlobalVars'], |
||||||
236 | $config['metaBundleSettings'], |
||||||
237 | null |
||||||
238 | ); |
||||||
239 | } |
||||||
240 | // Handle the mainEntityOfPage |
||||||
241 | $mainEntity = ''; |
||||||
242 | if (in_array('mainEntityOfPage', (array)$this->generalEnabledFields, false) && |
||||||
243 | !empty($config['metaBundleSettings'])) { |
||||||
244 | $mainEntity = SchemaHelper::getSpecificEntityType($config['metaBundleSettings'], true); |
||||||
245 | } |
||||||
246 | if (!empty($config['metaGlobalVars'])) { |
||||||
247 | /* @var array $config */ |
||||||
248 | $config['metaGlobalVars']['mainEntityOfPage'] = $mainEntity; |
||||||
249 | } |
||||||
250 | } |
||||||
251 | // Create a new meta bundle with propagated defaults |
||||||
252 | $metaBundleDefaults = ArrayHelper::merge( |
||||||
253 | ConfigHelper::getConfigFromFile('fieldmeta/Bundle'), |
||||||
254 | $config |
||||||
255 | ); |
||||||
256 | |||||||
257 | return MetaBundle::create($metaBundleDefaults); |
||||||
258 | } |
||||||
259 | |||||||
260 | /** |
||||||
261 | * @inheritdoc |
||||||
262 | */ |
||||||
263 | public function serializeValue(mixed $value, ?ElementInterface $element = null): mixed |
||||||
264 | { |
||||||
265 | $value = parent::serializeValue($value, $element); |
||||||
266 | if (!Craft::$app->getDb()->getSupportsMb4()) { |
||||||
267 | if (is_string($value)) { |
||||||
268 | // Encode any 4-byte UTF-8 characters. |
||||||
269 | $value = StringHelper::encodeMb4($value); |
||||||
270 | } |
||||||
271 | if (is_array($value)) { |
||||||
272 | array_walk_recursive($value, function(&$arrayValue, $arrayKey) { |
||||||
0 ignored issues
–
show
The parameter
$arrayKey is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
273 | if ($arrayValue !== null && is_string($arrayValue)) { |
||||||
274 | $arrayValue = StringHelper::encodeMb4($arrayValue); |
||||||
275 | } |
||||||
276 | }); |
||||||
277 | } |
||||||
278 | } |
||||||
279 | |||||||
280 | return $value; |
||||||
281 | } |
||||||
282 | |||||||
283 | /** |
||||||
284 | * @inheritdoc |
||||||
285 | */ |
||||||
286 | public function getSettingsHtml(): ?string |
||||||
287 | { |
||||||
288 | $variables = []; |
||||||
289 | $tagOptions = [ |
||||||
290 | 'depends' => [ |
||||||
291 | 'nystudio107\\seomatic\\assetbundles\\seomatic\\SeomaticAsset', |
||||||
292 | ], |
||||||
293 | ]; |
||||||
294 | // JS/CSS modules |
||||||
295 | try { |
||||||
296 | Seomatic::$view->registerAssetBundle(SeomaticAsset::class); |
||||||
0 ignored issues
–
show
The method
registerAssetBundle() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
297 | Seomatic::$plugin->vite->register('src/js/seomatic.js', false, $tagOptions, $tagOptions); |
||||||
298 | Seomatic::$plugin->vite->register('src/js/seomatic-meta.js', false, $tagOptions, $tagOptions); |
||||||
299 | } catch (InvalidConfigException $e) { |
||||||
300 | Craft::error($e->getMessage(), __METHOD__); |
||||||
301 | } |
||||||
302 | // Asset bundle |
||||||
303 | $variables['baseAssetsUrl'] = Craft::$app->assetManager->getPublishedUrl( |
||||||
304 | '@nystudio107/seomatic/web/assets/dist', |
||||||
305 | true |
||||||
0 ignored issues
–
show
The call to
yii\web\AssetManager::getPublishedUrl() has too many arguments starting with true .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
306 | ); |
||||||
307 | $variables['field'] = $this; |
||||||
308 | |||||||
309 | // Render the settings template |
||||||
310 | return Craft::$app->getView()->renderTemplate( |
||||||
311 | 'seomatic/_components/fields/SeoSettings_settings', |
||||||
312 | $variables |
||||||
313 | ); |
||||||
314 | } |
||||||
315 | |||||||
316 | /** |
||||||
317 | * @inheritdoc |
||||||
318 | */ |
||||||
319 | public function getInputHtml(mixed $value, ?ElementInterface $element = null): string |
||||||
320 | { |
||||||
321 | $variables = []; |
||||||
322 | // JS/CSS modules |
||||||
323 | $tagOptions = [ |
||||||
324 | 'depends' => [ |
||||||
325 | 'nystudio107\\seomatic\\assetbundles\\seomatic\\SeomaticAsset', |
||||||
326 | ], |
||||||
327 | ]; |
||||||
328 | // JS/CSS modules |
||||||
329 | try { |
||||||
330 | Seomatic::$view->registerAssetBundle(SeomaticAsset::class); |
||||||
331 | Seomatic::$plugin->vite->register('src/js/seomatic.js', false, $tagOptions, $tagOptions); |
||||||
332 | Seomatic::$plugin->vite->register('src/js/seomatic-meta.js', false, $tagOptions, $tagOptions); |
||||||
333 | } catch (InvalidConfigException $e) { |
||||||
334 | Craft::error($e->getMessage(), __METHOD__); |
||||||
335 | } |
||||||
336 | // Asset bundle |
||||||
337 | $variables['baseAssetsUrl'] = Craft::$app->assetManager->getPublishedUrl( |
||||||
338 | '@nystudio107/seomatic/web/assets/dist', |
||||||
339 | true |
||||||
0 ignored issues
–
show
The call to
yii\web\AssetManager::getPublishedUrl() has too many arguments starting with true .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
340 | ); |
||||||
341 | // Basic variables |
||||||
342 | $variables['name'] = $this->handle; |
||||||
343 | $variables['value'] = $value; |
||||||
344 | $variables['field'] = $this; |
||||||
345 | $variables['currentSourceBundleType'] = 'entry'; |
||||||
346 | $variables['entitySchemaPath'] = SchemaHelper::getEntityPath($value->metaBundleSettings); |
||||||
347 | |||||||
348 | // Get our id and namespace |
||||||
349 | $id = Craft::$app->getView()->formatInputId($this->handle); |
||||||
350 | $nameSpacedId = Craft::$app->getView()->namespaceInputId($id); |
||||||
351 | $variables['id'] = $id; |
||||||
352 | $variables['nameSpacedId'] = $nameSpacedId; |
||||||
353 | |||||||
354 | // Make sure the *Sources variables at least exist, for things like the QuickPost widget |
||||||
355 | $variables['textFieldSources'] = []; |
||||||
356 | $variables['assetFieldSources'] = []; |
||||||
357 | $variables['assetVolumeTextFieldSources'] = []; |
||||||
358 | $variables['userFieldSources'] = []; |
||||||
359 | // Pull field sources |
||||||
360 | if ($element !== null) { |
||||||
361 | /** @var Element $element */ |
||||||
362 | $this->setContentFieldSourceVariables($element, 'Entry', $variables); |
||||||
363 | } |
||||||
364 | |||||||
365 | /** @var MetaBundle $value */ |
||||||
366 | $variables['elementType'] = Asset::class; |
||||||
367 | |||||||
368 | $variables['parentBundles'] = []; |
||||||
369 | // Preview the containers so the preview is correct in the field |
||||||
370 | if ($element !== null && $element->uri !== null) { |
||||||
371 | Seomatic::$plugin->metaContainers->previewMetaContainers($element->uri, $element->siteId, true, true, $element); |
||||||
372 | $contentMeta = Seomatic::$plugin->metaBundles->getContentMetaBundleForElement($element); |
||||||
373 | $globalMeta = Seomatic::$plugin->metaBundles->getGlobalMetaBundle($element->siteId); |
||||||
374 | $variables['parentBundles'] = [$contentMeta, $globalMeta]; |
||||||
375 | } |
||||||
376 | |||||||
377 | // Render the input template |
||||||
378 | return Craft::$app->getView()->renderTemplate( |
||||||
379 | 'seomatic/_components/fields/SeoSettings_input', |
||||||
380 | $variables |
||||||
381 | ); |
||||||
382 | } |
||||||
383 | |||||||
384 | /** |
||||||
385 | * @inheritdoc |
||||||
386 | */ |
||||||
387 | public function getPreviewHtml(mixed $value, ElementInterface $element): string |
||||||
388 | { |
||||||
389 | $html = ''; |
||||||
390 | // Reset this each time to avoid caching issues |
||||||
391 | Seomatic::$previewingMetaContainers = false; |
||||||
392 | /** @var Element $element */ |
||||||
393 | if ($element !== null && $element->uri !== null) { |
||||||
394 | $siteId = $element->siteId; |
||||||
395 | $uri = $element->uri; |
||||||
396 | $cacheKey = self::CACHE_KEY . $uri . $siteId . $this->elementDisplayPreviewType; |
||||||
397 | $metaBundleSourceType = Seomatic::$plugin->seoElements->getMetaBundleTypeFromElement($element); |
||||||
398 | $seoElement = Seomatic::$plugin->seoElements->getSeoElementByMetaBundleType($metaBundleSourceType); |
||||||
399 | $metaBundleSourceType = SeoEntry::getMetaBundleType(); |
||||||
400 | $metaBundleSourceId = ''; |
||||||
401 | if ($seoElement !== null) { |
||||||
402 | $metaBundleSourceId = $seoElement::sourceIdFromElement($element); |
||||||
403 | } |
||||||
404 | $dependency = new TagDependency([ |
||||||
405 | 'tags' => [ |
||||||
406 | MetaContainers::GLOBAL_METACONTAINER_CACHE_TAG, |
||||||
407 | MetaContainers::METACONTAINER_CACHE_TAG . $metaBundleSourceId . $metaBundleSourceType . $siteId, |
||||||
408 | MetaContainers::METACONTAINER_CACHE_TAG . $uri . $siteId, |
||||||
409 | MetaContainers::METACONTAINER_CACHE_TAG . $metaBundleSourceId . $metaBundleSourceType, |
||||||
410 | ], |
||||||
411 | ]); |
||||||
412 | $cache = Craft::$app->getCache(); |
||||||
413 | $cacheDuration = null; |
||||||
414 | $html = $cache->getOrSet( |
||||||
415 | self::CACHE_KEY . $cacheKey, |
||||||
416 | function() use ($uri, $siteId, $element) { |
||||||
417 | Seomatic::$plugin->metaContainers->previewMetaContainers($uri, $siteId, true, true, $element); |
||||||
418 | $variables = [ |
||||||
419 | 'previewTypes' => [ |
||||||
420 | $this->elementDisplayPreviewType, |
||||||
421 | ], |
||||||
422 | 'previewElementId' => $element->id, |
||||||
423 | ]; |
||||||
424 | // Render our preview table template |
||||||
425 | if (Seomatic::$matchedElement) { |
||||||
426 | return Craft::$app->getView()->renderTemplate( |
||||||
427 | 'seomatic/_includes/table-preview.twig', |
||||||
428 | $variables |
||||||
429 | ); |
||||||
430 | } |
||||||
431 | |||||||
432 | return ''; |
||||||
433 | }, |
||||||
434 | $cacheDuration, |
||||||
435 | $dependency |
||||||
436 | ); |
||||||
437 | } |
||||||
438 | |||||||
439 | // Render the input template |
||||||
440 | return $html; |
||||||
441 | } |
||||||
442 | |||||||
443 | /** |
||||||
444 | * @inheritdoc |
||||||
445 | */ |
||||||
446 | public function previewPlaceholderHtml(mixed $value, ?ElementInterface $element): string |
||||||
447 | { |
||||||
448 | if ($element !== null) { |
||||||
449 | return $this->getPreviewHtml($value, $element); |
||||||
450 | } |
||||||
451 | |||||||
452 | return ''; |
||||||
453 | } |
||||||
454 | |||||||
455 | // Protected Methods |
||||||
456 | // ========================================================================= |
||||||
457 | |||||||
458 | /** |
||||||
459 | * @param Element $element |
||||||
460 | * @param string $groupName |
||||||
461 | * @param array $variables |
||||||
462 | */ |
||||||
463 | protected function setContentFieldSourceVariables( |
||||||
464 | Element $element, |
||||||
465 | string $groupName, |
||||||
466 | array &$variables, |
||||||
467 | ) { |
||||||
468 | $variables['textFieldSources'] = array_merge( |
||||||
469 | ['entryGroup' => ['optgroup' => $groupName . ' Fields'], 'title' => 'Title'], |
||||||
470 | FieldHelper::fieldsOfTypeFromElement( |
||||||
471 | $element, |
||||||
472 | FieldHelper::TEXT_FIELD_CLASS_KEY, |
||||||
473 | false |
||||||
474 | ) |
||||||
475 | ); |
||||||
476 | $variables['assetFieldSources'] = array_merge( |
||||||
477 | ['entryGroup' => ['optgroup' => $groupName . ' Fields']], |
||||||
478 | FieldHelper::fieldsOfTypeFromElement( |
||||||
479 | $element, |
||||||
480 | FieldHelper::ASSET_FIELD_CLASS_KEY, |
||||||
481 | false |
||||||
482 | ) |
||||||
483 | ); |
||||||
484 | $variables['assetVolumeTextFieldSources'] = array_merge( |
||||||
485 | ['entryGroup' => ['optgroup' => 'Asset Volume Fields'], 'title' => 'Title'], |
||||||
486 | FieldHelper::fieldsOfTypeFromAssetVolumes( |
||||||
487 | FieldHelper::TEXT_FIELD_CLASS_KEY, |
||||||
488 | false |
||||||
489 | ) |
||||||
490 | ); |
||||||
491 | $variables['userFieldSources'] = array_merge( |
||||||
492 | ['entryGroup' => ['optgroup' => 'User Fields']], |
||||||
493 | FieldHelper::fieldsOfTypeFromUsers( |
||||||
494 | FieldHelper::TEXT_FIELD_CLASS_KEY, |
||||||
495 | false |
||||||
496 | ) |
||||||
497 | ); |
||||||
498 | } |
||||||
499 | } |
||||||
500 |
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths