From 459775ddffd63fd76d07d88526ef218af698c9df Mon Sep 17 00:00:00 2001 From: Andreas Schempp Date: Mon, 12 Feb 2024 14:45:17 +0100 Subject: [PATCH] Added build-tools a fix code style --- composer.json | 7 +- contao/config/config.php | 4 +- contao/dca/tl_undo.php | 4 +- contao/languages/de/default.php | 46 +-- contao/languages/en/default.php | 46 +-- contao/languages/pl/default.php | 20 +- ecs.php | 16 - src/AjaxReloadManager.php | 14 +- src/Attribute/DoctrineOrmUndo.php | 2 + src/Attribute/DoctrineOrmVersion.php | 8 +- src/DcaRelationsManager.php | 44 +-- src/DoctrineOrmHelper.php | 14 +- src/Event/UndoEvent.php | 17 +- src/EventListener/AjaxReloadListener.php | 14 +- .../DcaAjaxOperationsListener.php | 23 +- .../DcaDateRangeFilterListener.php | 37 +- src/EventListener/DcaRelationsListener.php | 2 +- src/EventListener/DoctrineOrmListener.php | 13 +- src/EventListener/InsertTagsListener.php | 40 +- src/Form/Form.php | 215 ++++++----- src/Form/Validator/MandatoryOn.php | 2 +- src/Formatter.php | 20 +- src/Model/DcaRelationsModel.php | 20 +- src/StringParser.php | 10 +- src/UndoManager.php | 16 +- src/UrlParser.php | 11 +- src/Util/ArrayPosition.php | 18 +- src/Util/Pagination.php | 11 +- tests/CodefogHasteBundleTest.php | 2 + tests/Fixtures/DataContainer.php | 3 +- tests/Fixtures/Entity.php | 15 +- tests/Fixtures/FormTextField.php | 9 +- tests/Fixtures/Input.php | 6 +- tests/Fixtures/Model.php | 2 + tests/Fixtures/PageModel.php | 6 +- tests/Fixtures/System.php | 2 + tests/Fixtures/Widget.php | 3 + tests/Form/FormTest.php | 44 +-- tests/StringParserTest.php | 7 +- tests/UrlParserTest.php | 16 +- tests/Util/ArrayPositionTest.php | 78 ++-- tests/bootstrap.php | 14 +- tools/ecs/composer.json | 10 - tools/ecs/composer.lock | 356 ------------------ 44 files changed, 446 insertions(+), 821 deletions(-) delete mode 100644 ecs.php delete mode 100644 tools/ecs/composer.json delete mode 100644 tools/ecs/composer.lock diff --git a/composer.json b/composer.json index 2875df2e..29e9b484 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "require-dev": { "contao/manager-plugin": "^2.0", "phpunit/phpunit": "^9.5", - "terminal42/dc_multilingual": "^4.0" + "terminal42/dc_multilingual": "^4.0", + "terminal42/contao-build-tools": "dev-main" }, "conflict": { "contao/manager-plugin": "<2.0 || >=3.0" @@ -47,13 +48,11 @@ "config": { "allow-plugins": { "contao-components/installer": true, - "contao-community-alliance/composer-plugin": true, "contao/manager-plugin": true, - "php-http/discovery": true + "php-http/discovery": false } }, "scripts": { - "cs-fixer": "tools/ecs/vendor/bin/ecs check src/ --fix --ansi", "unit-tests": "@php vendor/bin/phpunit --colors=always" } } diff --git a/contao/config/config.php b/contao/config/config.php index f5f64b60..362ba672 100644 --- a/contao/config/config.php +++ b/contao/config/config.php @@ -1,4 +1,6 @@ - * @license http://opensource.org/licenses/lgpl-3.0.html - */ - - -/** +/* * Errors */ $GLOBALS['TL_LANG']['ERR']['numberInputNotAllowed'] = 'Bitte geben Sie eine valide Zahl ein (e.g. 5\'000, 5.00, 5,00, 5\'000.00)'; -/** +/* * Miscellaneous */ -$GLOBALS['TL_LANG']['HST']['advanced_filter'] = 'Erweiterte Filter:'; -$GLOBALS['TL_LANG']['HST']['advanced_search'] = 'Suche in "%s":'; +$GLOBALS['TL_LANG']['HST']['advanced_filter'] = 'Erweiterte Filter:'; +$GLOBALS['TL_LANG']['HST']['advanced_search'] = 'Suche in "%s":'; -/** +/* * Weight Units * http://www.metric-conversions.org/weight/weight-conversions.htm */ -$GLOBALS['TL_LANG']['WGT']['mg'] = array('Milligramm (mg)', 'Eine Masseinheit; entspricht 1 Tausendstel Gramm.'); -$GLOBALS['TL_LANG']['WGT']['g'] = array('Gramm (g)', 'Eine Masseinheit; entspricht 1 Tausendstel Kilogramm.'); -$GLOBALS['TL_LANG']['WGT']['kg'] = array('Kilogramm (kg)', 'Ein Kilogramm entspricht 1\'000 Gramm oder 2.2 Pfund; Entspricht dem Gewicht von einem Liter Wasser.'); -$GLOBALS['TL_LANG']['WGT']['t'] = array('Tonne (t)', 'Eine Tonne entspricht 1\'000 Kilogramm, oder 2,204.6 Pfund.'); -$GLOBALS['TL_LANG']['WGT']['ct'] = array('Karat (ct)', 'Das metrische Karat ist eine Masseinheit für die Masse von Edelsteinen. 1 metrisches Karat = 0,2 g = 2 · 10−4 kg.'); -$GLOBALS['TL_LANG']['WGT']['oz'] = array('Unze (oz)', 'Entspricht einem Sechzehntel eines Pfunds oder 28.35 Gramm.'); -$GLOBALS['TL_LANG']['WGT']['lb'] = array('Pfund (lb)', 'Eine Masseinheit; entspricht 16 Unzen'); -$GLOBALS['TL_LANG']['WGT']['st'] = array('Stone (st)', 'Ein britische Masseinheit; Entspricht 14 Pfund.'); -$GLOBALS['TL_LANG']['WGT']['grain'] = array('Grain', 'Eine Masseinheit; entspricht 1/7000 Pfund bzw. einem Troy Grain oder 64.799 Milligramm.'); +$GLOBALS['TL_LANG']['WGT']['mg'] = ['Milligramm (mg)', 'Eine Masseinheit; entspricht 1 Tausendstel Gramm.']; +$GLOBALS['TL_LANG']['WGT']['g'] = ['Gramm (g)', 'Eine Masseinheit; entspricht 1 Tausendstel Kilogramm.']; +$GLOBALS['TL_LANG']['WGT']['kg'] = ['Kilogramm (kg)', 'Ein Kilogramm entspricht 1\'000 Gramm oder 2.2 Pfund; Entspricht dem Gewicht von einem Liter Wasser.']; +$GLOBALS['TL_LANG']['WGT']['t'] = ['Tonne (t)', 'Eine Tonne entspricht 1\'000 Kilogramm, oder 2,204.6 Pfund.']; +$GLOBALS['TL_LANG']['WGT']['ct'] = ['Karat (ct)', 'Das metrische Karat ist eine Masseinheit für die Masse von Edelsteinen. 1 metrisches Karat = 0,2 g = 2 · 10−4 kg.']; +$GLOBALS['TL_LANG']['WGT']['oz'] = ['Unze (oz)', 'Entspricht einem Sechzehntel eines Pfunds oder 28.35 Gramm.']; +$GLOBALS['TL_LANG']['WGT']['lb'] = ['Pfund (lb)', 'Eine Masseinheit; entspricht 16 Unzen']; +$GLOBALS['TL_LANG']['WGT']['st'] = ['Stone (st)', 'Ein britische Masseinheit; Entspricht 14 Pfund.']; +$GLOBALS['TL_LANG']['WGT']['grain'] = ['Grain', 'Eine Masseinheit; entspricht 1/7000 Pfund bzw. einem Troy Grain oder 64.799 Milligramm.']; diff --git a/contao/languages/en/default.php b/contao/languages/en/default.php index ab9f3985..7bfa9011 100644 --- a/contao/languages/en/default.php +++ b/contao/languages/en/default.php @@ -1,46 +1,28 @@ - * @license http://opensource.org/licenses/lgpl-3.0.html - */ - - -/** +/* * Errors */ $GLOBALS['TL_LANG']['ERR']['numberInputNotAllowed'] = 'Enter a valid number (e.g. 5\'000, 5.00, 5,00, 5\'000.00)'; $GLOBALS['TL_LANG']['ERR']['minFileSize'] = 'The minimum size for file uploads is %s'; $GLOBALS['TL_LANG']['ERR']['maxFileSize'] = 'The maximum size for file uploads is %s'; -/** +/* * Miscellaneous */ -$GLOBALS['TL_LANG']['HST']['advanced_filter'] = 'Advanced filter:'; -$GLOBALS['TL_LANG']['HST']['advanced_search'] = 'Search in "%s":'; +$GLOBALS['TL_LANG']['HST']['advanced_filter'] = 'Advanced filter:'; +$GLOBALS['TL_LANG']['HST']['advanced_search'] = 'Search in "%s":'; -/** +/* * Weight Units * http://www.metric-conversions.org/weight/weight-conversions.htm */ -$GLOBALS['TL_LANG']['WGT']['mg'] = array('Milligram (mg)', 'A unit of mass equal to one-thousandth of a gram.'); -$GLOBALS['TL_LANG']['WGT']['g'] = array('Gram (g)', 'A metric unit of weight equal to one thousandth of a kilogram.'); -$GLOBALS['TL_LANG']['WGT']['kg'] = array('Kilogram (kg)', 'One kilogram is equivalent to 1,000 grams or 2.2 pounds; the mass of a liter of water.'); -$GLOBALS['TL_LANG']['WGT']['t'] = array('Metric Ton (t)', 'A unit of weight equal to 1,000 kilograms, or 2,204.6 pounds.'); -$GLOBALS['TL_LANG']['WGT']['ct'] = array('Carats (ct)', 'A measure of weight used for gemstones. One carat is equal to 1/5 of a gram (200 milligrams). Note that karat with a "K" is a measure of the purity of a gold alloy.'); -$GLOBALS['TL_LANG']['WGT']['oz'] = array('Ounce (oz)', 'A unit of weight equal to one sixteenth of a pound or 28.35 grams.'); -$GLOBALS['TL_LANG']['WGT']['lb'] = array('Pound (lb)', 'A unit of mass equal to 16 ounces'); -$GLOBALS['TL_LANG']['WGT']['st'] = array('Stone (st)', 'A British measurement of mass that equals fourteen pounds.'); -$GLOBALS['TL_LANG']['WGT']['grain'] = array('Grain', '1/7000 pound; equals a troy grain or 64.799 milligrams.'); +$GLOBALS['TL_LANG']['WGT']['mg'] = ['Milligram (mg)', 'A unit of mass equal to one-thousandth of a gram.']; +$GLOBALS['TL_LANG']['WGT']['g'] = ['Gram (g)', 'A metric unit of weight equal to one thousandth of a kilogram.']; +$GLOBALS['TL_LANG']['WGT']['kg'] = ['Kilogram (kg)', 'One kilogram is equivalent to 1,000 grams or 2.2 pounds; the mass of a liter of water.']; +$GLOBALS['TL_LANG']['WGT']['t'] = ['Metric Ton (t)', 'A unit of weight equal to 1,000 kilograms, or 2,204.6 pounds.']; +$GLOBALS['TL_LANG']['WGT']['ct'] = ['Carats (ct)', 'A measure of weight used for gemstones. One carat is equal to 1/5 of a gram (200 milligrams). Note that karat with a "K" is a measure of the purity of a gold alloy.']; +$GLOBALS['TL_LANG']['WGT']['oz'] = ['Ounce (oz)', 'A unit of weight equal to one sixteenth of a pound or 28.35 grams.']; +$GLOBALS['TL_LANG']['WGT']['lb'] = ['Pound (lb)', 'A unit of mass equal to 16 ounces']; +$GLOBALS['TL_LANG']['WGT']['st'] = ['Stone (st)', 'A British measurement of mass that equals fourteen pounds.']; +$GLOBALS['TL_LANG']['WGT']['grain'] = ['Grain', '1/7000 pound; equals a troy grain or 64.799 milligrams.']; diff --git a/contao/languages/pl/default.php b/contao/languages/pl/default.php index 7292b605..1bbb0efd 100644 --- a/contao/languages/pl/default.php +++ b/contao/languages/pl/default.php @@ -1,24 +1,6 @@ - * @license http://opensource.org/licenses/lgpl-3.0.html - */ - - -/** +/* * Miscellaneous */ $GLOBALS['TL_LANG']['HST']['advanced_filter'] = 'Zaawansowany filtr:'; diff --git a/ecs.php b/ecs.php deleted file mode 100644 index 8af1a0f2..00000000 --- a/ecs.php +++ /dev/null @@ -1,16 +0,0 @@ -import(__DIR__.'/tools/ecs/vendor/contao/easy-coding-standard/config/self.php'); - - $parameters = $containerConfigurator->parameters(); - $parameters->set(Option::SKIP, [ - HeaderCommentFixer::class => null, - ]); -}; diff --git a/src/AjaxReloadManager.php b/src/AjaxReloadManager.php index 6351752b..fdc7912b 100644 --- a/src/AjaxReloadManager.php +++ b/src/AjaxReloadManager.php @@ -12,9 +12,11 @@ class AjaxReloadManager implements ResetInterface { public const TYPE_CONTENT = 'ce'; + public const TYPE_MODULE = 'fmd'; private array $buffers = []; + private array $listeners = []; /** @@ -58,7 +60,7 @@ public function updateBuffer(string $type, int $id, string $buffer, bool $isAjax } if (\count($events) > 0) { - $buffer = static::addDataAttributes($buffer, $uniqid, $events, $isAjax); + $buffer = $this->addDataAttributes($buffer, $uniqid, $events, $isAjax); } return $buffer; @@ -75,7 +77,7 @@ public function hasListeners(): bool /** * Get the response. */ - public function getResponse(): ?Response + public function getResponse(): Response|null { if (0 === \count($this->buffers)) { return null; @@ -154,7 +156,7 @@ static function ($matches) use (&$events) { return ''; }, - $buffer + $buffer, ); // Remove the HTML comments on AJAX request, so they don't appear doubled in the DOM @@ -166,11 +168,11 @@ static function ($matches) use (&$events) { $buffer = preg_replace( '/<([^>!]+)>/', sprintf('<$1 data-haste-ajax-id="%s" data-haste-ajax-listeners="%s">', $uniqid, implode(' ', array_unique($events))), - $buffer, - 1 + (string) $buffer, + 1, ); // Trim the buffer to avoid JS break - return trim($buffer); + return trim((string) $buffer); } } diff --git a/src/Attribute/DoctrineOrmUndo.php b/src/Attribute/DoctrineOrmUndo.php index 09e32186..4c4c4f3c 100644 --- a/src/Attribute/DoctrineOrmUndo.php +++ b/src/Attribute/DoctrineOrmUndo.php @@ -1,5 +1,7 @@ table]['searchField']; if (isset($GLOBALS['TL_DCA'][$relatedTable]['fields'][$fld]['foreignKey'])) { - [$t, $f] = explode('.', $GLOBALS['TL_DCA'][$relatedTable]['fields'][$fld]['foreignKey']); + [$t, $f] = explode('.', (string) $GLOBALS['TL_DCA'][$relatedTable]['fields'][$fld]['foreignKey']); $procedure[] = '('.sprintf($strPattern, $fld).' OR '.sprintf($strPattern, "(SELECT $f FROM $t WHERE $t.id={$relatedTable}.$fld)").')'; $values[] = $sessionData['haste_search'][$dc->table]['searchValue']; } else { @@ -622,7 +623,7 @@ public function addRelationFilters(DataContainer $dc): string $vv = $options_callback[$vv]; } elseif (isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['foreignKey'])) { // Replace the ID with the foreign key - $key = explode('.', $GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['foreignKey'], 2); + $key = explode('.', (string) $GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['foreignKey'], 2); $parent = $this->connection->fetchOne('SELECT '.$key[1].' FROM '.$key[0].' WHERE id=?', [$vv]); @@ -642,7 +643,7 @@ public function addRelationFilters(DataContainer $dc): string } // No empty options allowed - if (!\strlen($option_label)) { + if (!\strlen((string) $option_label)) { $option_label = $vv ?: '-'; } @@ -697,7 +698,7 @@ public function addRelationSearch(DataContainer $dc): string // Store search value in the current session if ('tl_filters' === Input::post('FORM_SUBMIT')) { $fieldName = Input::post('tl_field_'.$field, true); - $keyword = ltrim(Input::postRaw('tl_value_'.$field), '*'); + $keyword = ltrim((string) Input::postRaw('tl_value_'.$field), '*'); if ($fieldName && !\in_array($fieldName, $relatedSearchFields, true)) { $fieldName = ''; @@ -708,7 +709,7 @@ public function addRelationSearch(DataContainer $dc): string if ($fieldName && $keyword) { try { $this->connection->fetchOne('SELECT id FROM '.$relTable.' WHERE '.$fieldName.' REGEXP ? LIMIT 1', [$keyword]); - } catch (\Exception $e) { + } catch (\Exception) { $keyword = ''; } } @@ -748,7 +749,7 @@ public function addRelationSearch(DataContainer $dc): string /** * Get the relation of particular field in the table. */ - public function getRelation(string $table, string $fieldName): ?array + public function getRelation(string $table, string $fieldName): array|null { Controller::loadDataContainer($table); @@ -762,7 +763,7 @@ public function getRelation(string $table, string $fieldName): ?array // Load from entity if (isset($fieldConfig['entity'])) { - if ($this->entityManager === null) { + if (null === $this->entityManager) { throw new \RuntimeException(sprintf('The entity has been defined in the relation for %s.%s, but there is no entity manager service!', $table, $fieldName)); } @@ -794,7 +795,8 @@ public function getRelation(string $table, string $fieldName): ?array 'skipInstall' => true, ]; - // Set the table name directly in the relation of DCA field, so the DcaExtractor will not complain about incomplete relation + // Set the table name directly in the relation of DCA field, so the DcaExtractor + // will not complain about incomplete relation if (!isset($fieldConfig['table'])) { $GLOBALS['TL_DCA'][$table]['fields'][$fieldName]['relation']['table'] = $relation['related_table']; } @@ -814,16 +816,16 @@ public function getRelation(string $table, string $fieldName): ?array $relation['reference_field'] = $fieldConfig['referenceColumn'] ?? (str_replace('tl_', '', $table).'_'.$relation['reference']); $relation['reference_sql'] = $fieldConfig['referenceSql'] ?? ['type' => Types::INTEGER, 'unsigned' => true, 'default' => 0]; - if (!is_array($relation['reference_sql'])) { + if (!\is_array($relation['reference_sql'])) { throw new \RuntimeException('The relation key "referenceSql" must be an array!'); } // Related table data $relation['related_table'] = $fieldConfig['table']; - $relation['related_field'] = $fieldConfig['fieldColumn'] ?? (str_replace('tl_', '', $fieldConfig['table']).'_'.$relation['field']); + $relation['related_field'] = $fieldConfig['fieldColumn'] ?? (str_replace('tl_', '', (string) $fieldConfig['table']).'_'.$relation['field']); $relation['related_sql'] = $fieldConfig['fieldSql'] ?? ['type' => Types::INTEGER, 'unsigned' => true, 'default' => 0]; - if (!is_array($relation['related_sql'])) { + if (!\is_array($relation['related_sql'])) { throw new \RuntimeException('The relation key "fieldSql" must be an array!'); } diff --git a/src/DoctrineOrmHelper.php b/src/DoctrineOrmHelper.php index 5e066b70..7c5fa687 100644 --- a/src/DoctrineOrmHelper.php +++ b/src/DoctrineOrmHelper.php @@ -1,5 +1,7 @@ + */ private array $entityVersions = []; public function __construct( @@ -24,8 +28,8 @@ public function __construct( private readonly DcaRelationsManager $dcaRelationsManager, private readonly RouterInterface $router, private readonly Security $security, - ) - {} + ) { + } /** * Add the entity related values. @@ -84,7 +88,7 @@ public function createObjectVersion(ObjectManager $objectManager, object $entity } // Set the edit URL, if any - if (count($editRouteParams) > 0) { + if (\count($editRouteParams) > 0) { $editRouteParams['id'] ??= '%s'; $editRouteParams['act'] ??= 'edit'; $editRouteParams['rt'] ??= '1'; @@ -137,6 +141,6 @@ public function storeObjectUndo(ObjectManager $objectManager, object $entity): v */ private function getEntityUniqueId(object $entity): string { - return get_class($entity) . '::' . spl_object_id($entity); + return $entity::class.'::'.spl_object_id($entity); } } diff --git a/src/Event/UndoEvent.php b/src/Event/UndoEvent.php index 67247e46..79265c5a 100644 --- a/src/Event/UndoEvent.php +++ b/src/Event/UndoEvent.php @@ -10,17 +10,12 @@ class UndoEvent extends Event { public const NAME = 'haste.undo'; - private array $hasteData; - private int $id; - private string $table; - private array $row; - - public function __construct(array $hasteData, int $id, string $table, array $row) - { - $this->hasteData = $hasteData; - $this->id = $id; - $this->table = $table; - $this->row = $row; + public function __construct( + private array $hasteData, + private int $id, + private string $table, + private array $row, + ) { } public function getHasteData(): array diff --git a/src/EventListener/AjaxReloadListener.php b/src/EventListener/AjaxReloadListener.php index 34e47880..c52342dc 100644 --- a/src/EventListener/AjaxReloadListener.php +++ b/src/EventListener/AjaxReloadListener.php @@ -14,8 +14,11 @@ class AjaxReloadListener { - public function __construct(private readonly AjaxReloadManager $manager, private readonly Packages $packages, private readonly RequestStack $requestStack,) - { + public function __construct( + private readonly AjaxReloadManager $manager, + private readonly Packages $packages, + private readonly RequestStack $requestStack, + ) { } #[AsHook('getContentElement')] @@ -70,10 +73,11 @@ public function onModifyFrontendPage(string $buffer, string $template): string $buffer = str_replace( '', sprintf('', $this->packages->getUrl('ajax-reload.js', 'codefog_haste')), - $buffer + $buffer, ); - // Make sure the request is not cached by the browser alongside with the initial request + // Make sure the request is not cached by the browser alongside with the + // initial request $request->headers->set('Vary', 'Haste-Ajax-Reload'); } } @@ -84,7 +88,7 @@ public function onModifyFrontendPage(string $buffer, string $template): string /** * Get the event from the current request. */ - private function getEventFromCurrentRequest(): ?string + private function getEventFromCurrentRequest(): string|null { $request = $this->requestStack->getCurrentRequest(); diff --git a/src/EventListener/DcaAjaxOperationsListener.php b/src/EventListener/DcaAjaxOperationsListener.php index b58263ac..bb8824ec 100644 --- a/src/EventListener/DcaAjaxOperationsListener.php +++ b/src/EventListener/DcaAjaxOperationsListener.php @@ -34,8 +34,7 @@ public function __construct( private readonly ScopeMatcher $scopeMatcher, private readonly Security $security, private readonly ContaoCsrfTokenManager $tokenManager, - ) - { + ) { } #[AsHook('executePostActions')] @@ -124,11 +123,13 @@ public function onLoadDataContainer(string $table): void // Add the JavaScript $GLOBALS['TL_JAVASCRIPT'][] = $this->packages->getUrl('dca-ajax-operations.js', 'codefog_haste'); - // Add default button callback to display the correct initial state but only add it if not already present + // Add default button callback to display the correct initial state but only add + // it if not already present if (!isset($settings['button_callback'])) { $operation['button_callback'] = $this->getDefaultButtonCallback($name, $table, $settings['haste_ajax_operation']); - // Make sure an icon is set to prevent DC_Table errors (set to '' as the button_callback will return the correct icon) + // Make sure an icon is set to prevent DC_Table errors (set to '' as the + // button_callback will return the correct icon) $operation['icon'] = ''; // Add the onclick attribute @@ -140,7 +141,7 @@ public function onLoadDataContainer(string $table): void /** * Adds the "onclick" attribute to the operation DCA. */ - private function addOnClickAttribute(array & $operation): void + private function addOnClickAttribute(array &$operation): void { $clickEventString = 'return Haste.toggleAjaxOperation(this, %s);'; @@ -148,8 +149,8 @@ private function addOnClickAttribute(array & $operation): void $operation['attributes'] = sprintf('onclick="%s"', $clickEventString); } else { // onclick attribute already present - if (str_contains($operation['attributes'], 'onclick="')) { - $operation['attributes'] = str_replace('onclick="', 'onclick="'.$clickEventString, $operation['attributes']); + if (str_contains((string) $operation['attributes'], 'onclick="')) { + $operation['attributes'] = str_replace('onclick="', 'onclick="'.$clickEventString, (string) $operation['attributes']); } else { $operation['attributes'] = $clickEventString.$operation['attributes']; } @@ -233,7 +234,7 @@ private function getDefaultButtonCallback(string $name, string $table, array $se Backend::addToUrl($href), StringUtil::specialchars($title), $attributes, - Image::getHtml($icon, $label) + Image::getHtml($icon, $label), ); }; } @@ -241,15 +242,15 @@ private function getDefaultButtonCallback(string $name, string $table, array $se /** * Get the versioning edit URL. */ - private function getVersionEditUrl(int $id, string $operation): ?string + private function getVersionEditUrl(int $id, string $operation): string|null { if ('toggle' !== $operation) { return null; } $url = Environment::get('requestUri'); - $url = preg_replace('/&(amp;)?id=[^&]+/', '', $url); + $url = preg_replace('/&(amp;)?id=[^&]+/', '', (string) $url); - return $url . sprintf('&act=edit&id=%s&rt=%s', $id, $this->tokenManager->getDefaultTokenValue()); + return $url.sprintf('&act=edit&id=%s&rt=%s', $id, $this->tokenManager->getDefaultTokenValue()); } } diff --git a/src/EventListener/DcaDateRangeFilterListener.php b/src/EventListener/DcaDateRangeFilterListener.php index ba4f93e8..45cee749 100644 --- a/src/EventListener/DcaDateRangeFilterListener.php +++ b/src/EventListener/DcaDateRangeFilterListener.php @@ -22,8 +22,11 @@ class DcaDateRangeFilterListener { protected array $fieldsToFilter = []; - public function __construct(private readonly Connection $connection, private readonly RequestStack $requestStack, private readonly ScopeMatcher $scopeMatcher,) - { + public function __construct( + private readonly Connection $connection, + private readonly RequestStack $requestStack, + private readonly ScopeMatcher $scopeMatcher, + ) { } #[AsHook('loadDataContainer')] @@ -42,7 +45,7 @@ public function onLoadDataContainer(string $table): void } if (\count($this->fieldsToFilter) > 0) { - $GLOBALS['TL_DCA'][$table]['list']['sorting']['panelLayout'] = preg_replace('/filter/', 'haste_dateRangeFilter;filter', $GLOBALS['TL_DCA'][$table]['list']['sorting']['panelLayout'], 1); + $GLOBALS['TL_DCA'][$table]['list']['sorting']['panelLayout'] = preg_replace('/filter/', 'haste_dateRangeFilter;filter', (string) $GLOBALS['TL_DCA'][$table]['list']['sorting']['panelLayout'], 1); $GLOBALS['TL_DCA'][$table]['list']['sorting']['panel_callback']['haste_dateRangeFilter'] = [static::class, 'onPanelCallback']; $GLOBALS['TL_DCA'][$table]['config']['onload_callback'][] = [static::class, 'onLoadCallback']; } @@ -97,13 +100,13 @@ public function onPanelCallback(DataContainer $dc): string $return .= $this->createDatepickerInputField( 'haste_dateRangeFilter_'.$field.'_from', $session['filter'][$filter][$key]['from'], - $GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['eval']['rgxp'] ?? '' + $GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['eval']['rgxp'] ?? '', ); $return .= $this->createDatepickerInputField( 'haste_dateRangeFilter_'.$field.'_to', $session['filter'][$filter][$key]['to'], - $GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['eval']['rgxp'] ?? '' + $GLOBALS['TL_DCA'][$dc->table]['fields'][$field]['eval']['rgxp'] ?? '', ); $return .= ''; @@ -183,7 +186,7 @@ private function fetchValidRecordIds(DataContainer $dc, string $field, int $from /** * Validates user input and turns it into a tstamp if it's valid. */ - private function validateAndGetTstamp(string $value, string $rgxp, bool $from = true): ?int + private function validateAndGetTstamp(string $value, string $rgxp, bool $from = true): int|null { $method = 'is'.ucfirst($rgxp); @@ -200,7 +203,7 @@ private function validateAndGetTstamp(string $value, string $rgxp, bool $from = try { $date = new Date($value, Date::getFormatFromRgxp($rgxp)); - } catch (\OutOfBoundsException $e) { + } catch (\OutOfBoundsException) { return null; } @@ -216,19 +219,11 @@ private function createDatepickerInputField(string $name, string $value, string { $format = Date::formatToJs(Config::get($rgxp.'Format')); - switch ($rgxp) { - case 'datim': - $time = ",\n timePicker:true"; - break; - - case 'time': - $time = ",\n pickOnly:\"time\""; - break; - - default: - $time = ''; - break; - } + $time = match ($rgxp) { + 'datim' => ",\n timePicker:true", + 'time' => ",\n pickOnly:\"time\"", + default => '', + }; return sprintf( ' @@ -257,7 +252,7 @@ private function createDatepickerInputField(string $name, string $value, string $format, $time, $GLOBALS['TL_LANG']['MSC']['weekOffset'] ?? '', - $GLOBALS['TL_LANG']['MSC']['titleFormat'] ?? '' + $GLOBALS['TL_LANG']['MSC']['titleFormat'] ?? '', ); } } diff --git a/src/EventListener/DcaRelationsListener.php b/src/EventListener/DcaRelationsListener.php index faced1ed..087989b8 100644 --- a/src/EventListener/DcaRelationsListener.php +++ b/src/EventListener/DcaRelationsListener.php @@ -11,7 +11,7 @@ class DcaRelationsListener { - public function __construct(private readonly DcaRelationsManager $dcaRelations,) + public function __construct(private readonly DcaRelationsManager $dcaRelations) { } diff --git a/src/EventListener/DoctrineOrmListener.php b/src/EventListener/DoctrineOrmListener.php index cf914e55..4b61612d 100644 --- a/src/EventListener/DoctrineOrmListener.php +++ b/src/EventListener/DoctrineOrmListener.php @@ -1,5 +1,7 @@ getObjectManager()->getClassMetadata(get_class($args->getObject()))->getAssociationNames(); + $relatedFields = $args->getObjectManager()->getClassMetadata($args->getObject()::class)->getAssociationNames(); foreach ($relatedFields as $relatedField) { $this->helper->updateRelatedValues($args->getObjectManager(), $args->getObject(), $relatedField); @@ -61,7 +64,7 @@ private function handlePostUpdateRelations(LifecycleEventArgs $args): void private function handlePreRemoveUndo(LifecycleEventArgs $args): void { - if ($this->getAttribute($args->getObject(), DoctrineOrmUndo::class) === null) { + if (null === $this->getAttribute($args->getObject(), DoctrineOrmUndo::class)) { return; } @@ -85,14 +88,14 @@ private function handlePreUpdateVersions(LifecycleEventArgs $args): void private function handlePostUpdateVersions(LifecycleEventArgs $args): void { - if ($this->getAttribute($args->getObject(), DoctrineOrmVersion::class) === null) { + if (null === $this->getAttribute($args->getObject(), DoctrineOrmVersion::class)) { return; } $this->helper->saveObjectVersion($args->getObject()); } - private function getAttribute(object $object, string $attribute): ?\ReflectionAttribute + private function getAttribute(object $object, string $attribute): \ReflectionAttribute|null { $reflection = new \ReflectionClass($object); $reflectionAttributes = $reflection->getAttributes($attribute); diff --git a/src/EventListener/InsertTagsListener.php b/src/EventListener/InsertTagsListener.php index 2d8889ed..90359dc1 100644 --- a/src/EventListener/InsertTagsListener.php +++ b/src/EventListener/InsertTagsListener.php @@ -14,7 +14,7 @@ #[AsHook('replaceInsertTags')] class InsertTagsListener { - public function __construct(private readonly Formatter $formatter,) + public function __construct(private readonly Formatter $formatter) { } @@ -22,30 +22,16 @@ public function __invoke(string $tag): mixed { $chunks = StringUtil::trimsplit('::', $tag); - switch ($chunks[0]) { - case 'convert_dateformat': - return $this->replaceConvertedDateFormat($chunks); - - case 'dca_label': - return $this->replaceDcaLabel($chunks); - - case 'dca_value': - return $this->replaceDcaValue($chunks); - - case 'formatted_datetime': - return $this->replaceFormattedDateTime($chunks); - - case 'rand': - return 3 === \count($chunks) ? random_int((int) $chunks[1], (int) $chunks[2]) : mt_rand(); - - case 'flag': - return (string) $chunks[1]; - - case 'options_label': - return $this->replaceOptionsLabel($chunks); - } - - return false; + return match ($chunks[0]) { + 'convert_dateformat' => $this->replaceConvertedDateFormat($chunks), + 'dca_label' => $this->replaceDcaLabel($chunks), + 'dca_value' => $this->replaceDcaValue($chunks), + 'formatted_datetime' => $this->replaceFormattedDateTime($chunks), + 'rand' => 3 === \count($chunks) ? random_int((int) $chunks[1], (int) $chunks[2]) : mt_rand(), + 'flag' => (string) $chunks[1], + 'options_label' => $this->replaceOptionsLabel($chunks), + default => false, + }; } /** @@ -84,7 +70,7 @@ private function replaceConvertedDateFormat(array $chunks): string|false try { $date = new Date($chunks[1], $determineFormat($chunks[2])); - } catch (\OutOfBoundsException $e) { + } catch (\OutOfBoundsException) { return false; } @@ -110,7 +96,7 @@ private function replaceFormattedDateTime(array $chunks): string // Support strtotime() if (!is_numeric($timestamp)) { - $timestamp = strtotime($timestamp); + $timestamp = strtotime((string) $timestamp); } $strFormat = $chunks[2]; diff --git a/src/Form/Form.php b/src/Form/Form.php index a49784ee..03d5242f 100644 --- a/src/Form/Form.php +++ b/src/Form/Form.php @@ -31,19 +31,31 @@ class Form { public const STATE_CLEAN = 0; + public const STATE_DIRTY = 1; protected string $formId = ''; + protected string $httpMethod = ''; + protected string $action = ''; + protected string $enctype = 'application/x-www-form-urlencoded'; + protected bool $isSubmitted = false; + protected bool $hasUploads = false; + protected object|null $boundEntity = null; + protected PropertyAccessor|null $propertyAccessor = null; + protected Model|null $boundModel = null; + protected array $validators = []; + protected int $currentState = self::STATE_CLEAN; + protected bool $isValid = true; /** @@ -68,7 +80,7 @@ class Form */ protected $inputCallback; - public function __construct(string $formId, string $httpMethod, callable $submitCheckCallback = null) + public function __construct(string $formId, string $httpMethod, callable|null $submitCheckCallback = null) { if (is_numeric($formId)) { throw new \InvalidArgumentException('You cannot use a numeric form id.'); @@ -86,9 +98,10 @@ public function __construct(string $formId, string $httpMethod, callable $submit } $this->httpMethod = $httpMethod; - $this->isSubmitted = is_callable($submitCheckCallback) ? $submitCheckCallback($this) : true; + $this->isSubmitted = \is_callable($submitCheckCallback) ? $submitCheckCallback($this) : true; - // The form action can be set using several helper methods but by default it's just pointing to the current page + // The form action can be set using several helper methods but by default it's + // just pointing to the current page $this->action = Environment::get('requestUri'); } @@ -141,7 +154,7 @@ public function getCurrentState(): int return $this->currentState; } - public function getBoundEntity(): ?object + public function getBoundEntity(): object|null { return $this->boundEntity; } @@ -149,7 +162,7 @@ public function getBoundEntity(): ?object /** * Binds a Doctrine entity to the form. If there is data, haste form will add the present values as default values. */ - public function setBoundEntity(object $boundEntity, PropertyAccessor $propertyAccessor = null): self + public function setBoundEntity(object $boundEntity, PropertyAccessor|null $propertyAccessor = null): self { $this->boundEntity = $boundEntity; $this->propertyAccessor = $propertyAccessor ?? new PropertyAccessor(); @@ -157,7 +170,7 @@ public function setBoundEntity(object $boundEntity, PropertyAccessor $propertyAc return $this; } - public function getBoundModel(): ?Model + public function getBoundModel(): Model|null { return $this->boundModel; } @@ -201,7 +214,7 @@ public function setActionFromPageId(int $id): self /** * Set a callback to fetch the widget input instead of using getPost(). */ - public function setInputCallback(callable $callback = null): self + public function setInputCallback(callable|null $callback = null): self { $this->inputCallback = $callback; @@ -315,7 +328,7 @@ public function generateNoValidateAttribute(): string /** * Adds a form field. */ - public function addFormField(string $fieldName, array $fieldConfig, ArrayPosition $position = null): self + public function addFormField(string $fieldName, array $fieldConfig, ArrayPosition|null $position = null): self { $this->checkFormFieldNameIsValid($fieldName); @@ -336,7 +349,8 @@ public function addFormField(string $fieldName, array $fieldConfig, ArrayPositio // Try to load the default value from bound Entity if (!($fieldConfig['ignoreEntityValue'] ?? false) && null !== $this->boundEntity) { - // If the field is a relation, store the value in the helper which will be processed by Doctrine events later on + // If the field is a relation, store the value in the helper which will be + // processed by Doctrine events later on if (($fieldConfig['relation']['type'] ?? null) === 'haste-ManyToMany') { $entityId = $this->boundEntity->getId(); @@ -384,20 +398,20 @@ static function (mixed $value) use ($rgxp) { } return $value; - } + }, ); } // If the field is a relation, remove the default load/save callbacks if (!($fieldConfig['ignoreEntityValue'] ?? false) && null !== $this->boundEntity && ($fieldConfig['relation']['type'] ?? null) === 'haste-ManyToMany') { // Remove the load callbacks - if (is_array($fieldConfig['load_callback'] ?? null)) { - $fieldConfig['load_callback'] = array_values(array_filter($fieldConfig['load_callback'], fn (array $callback) => $callback[0] !== DcaRelationsManager::class)); + if (\is_array($fieldConfig['load_callback'] ?? null)) { + $fieldConfig['load_callback'] = array_values(array_filter($fieldConfig['load_callback'], static fn (array $callback) => DcaRelationsManager::class !== $callback[0])); } // Remove the save callbacks - if (is_array($fieldConfig['save_callback'] ?? null)) { - $fieldConfig['save_callback'] = array_values(array_filter($fieldConfig['save_callback'], fn (array $callback) => $callback[0] !== DcaRelationsManager::class)); + if (\is_array($fieldConfig['save_callback'] ?? null)) { + $fieldConfig['save_callback'] = array_values(array_filter($fieldConfig['save_callback'], static fn (array $callback) => DcaRelationsManager::class !== $callback[0])); } } @@ -417,7 +431,7 @@ function (mixed $value, Widget $widget) use ($fieldConfig, $fieldName) { } return $value; - } + }, ); } @@ -432,7 +446,8 @@ function (mixed $value, Widget $widget) use ($fieldConfig, $fieldName) { // Reset the ID to the field name $fieldConfig['id'] = $fieldName; - // Remove the label if it was not set – Contao will set it to field name if it's not present + // Remove the label if it was not set – Contao will set it to field name if + // it's not present if (!isset($label) || !$label) { $fieldConfig['label'] = ''; } @@ -465,55 +480,10 @@ function (mixed $value, Widget $widget) use ($fieldConfig, $fieldName) { return $this; } - /** - * Create the data container mock. - */ - private function createDataContainerMock(mixed $value, string $field, string $name): DataContainer - { - return new class($this->getBoundModel(), $value, $field, $name) extends DataContainer { - public function __construct($model, $value, $field, $name) - { - $this->id = $model ? $model->id : 0; - $this->table = $model ? $model::getTable() : ''; - $this->value = $value; - $this->field = $field; - $this->inputName = $name; - $this->activeRecord = $model; // BC - - parent::__construct(); - } - - public function getCurrentRecord(int|string $id = null, string $table = null): ?array - { - if (!$id) { - return null; - } - - $record = $this->Database - ->prepare("SELECT * FROM $table WHERE id=?") - ->limit(1) - ->execute($id) - ; - - return $record->numRows ? $record->row() : null; - } - - public function getPalette() - { - // noop - } - - protected function save($varValue) - { - // noop - } - }; - } - /** * Add multiple form fields. */ - public function addFormFields(array $formFields, ArrayPosition $position = null): self + public function addFormFields(array $formFields, ArrayPosition|null $position = null): self { if (null !== $position && (ArrayPosition::FIRST === $position->position() || ArrayPosition::BEFORE === $position->position())) { $formFields = array_reverse($formFields, true); @@ -554,14 +524,18 @@ public function addContaoHiddenFields(): self /** * Helper method to easily add a captcha field. */ - public function addCaptchaFormField(string $fieldName = 'captcha', ArrayPosition $position = null): self + public function addCaptchaFormField(string $fieldName = 'captcha', ArrayPosition|null $position = null): self { - $this->addFormField($fieldName, [ - 'name' => $fieldName.'_'.$this->formId, // make sure they're unique on a page - 'label' => &$GLOBALS['TL_LANG']['MSC']['securityQuestion'], - 'inputType' => 'captcha', - 'eval' => ['mandatory' => true], - ], $position); + $this->addFormField( + $fieldName, + [ + 'name' => $fieldName.'_'.$this->formId, // make sure they're unique on a page + 'label' => &$GLOBALS['TL_LANG']['MSC']['securityQuestion'], + 'inputType' => 'captcha', + 'eval' => ['mandatory' => true], + ], + $position, + ); return $this; } @@ -569,13 +543,17 @@ public function addCaptchaFormField(string $fieldName = 'captcha', ArrayPosition /** * Helper method to easily add a submit field. */ - public function addSubmitFormField(string $label, string $fieldName = 'submit', ArrayPosition $position = null): self + public function addSubmitFormField(string $label, string $fieldName = 'submit', ArrayPosition|null $position = null): self { - $this->addFormField($fieldName, [ - 'name' => $fieldName, - 'label' => $label, - 'inputType' => 'submit', - ], $position); + $this->addFormField( + $fieldName, + [ + 'name' => $fieldName, + 'label' => $label, + 'inputType' => 'submit', + ], + $position, + ); return $this; } @@ -583,7 +561,7 @@ public function addSubmitFormField(string $label, string $fieldName = 'submit', /** * Add form fields from a back end DCA. */ - public function addFieldsFromDca(string $table, callable $callback = null): self + public function addFieldsFromDca(string $table, callable|null $callback = null): self { System::loadLanguageFile($table); Controller::loadDataContainer($table); @@ -619,14 +597,15 @@ public function skipFieldsWithoutInputType(string $fieldName, array $fieldConfig /** * Add form fields from a back end form generator form ID. */ - public function addFieldsFromFormGenerator(int $formId, callable $callback = null): self + public function addFieldsFromFormGenerator(int $formId, callable|null $callback = null): self { if (($objFields = FormFieldModel::findPublishedByPid($formId)) === null) { throw new \InvalidArgumentException('Form ID "'.$formId.'" does not exist or has no published fields.'); } while ($objFields->next()) { - // make sure "name" is set because not all form fields do need it and it would thus overwrite the array indexes + // make sure "name" is set because not all form fields do need it and it would + // thus overwrite the array indexes $fieldName = $objFields->name ?: 'field_'.$objFields->id; $this->checkFormFieldNameIsValid($fieldName); @@ -653,7 +632,7 @@ public function addFieldsFromFormGenerator(int $formId, callable $callback = nul /** * Adds a form field from the form generator without trying to convert a DCA configuration. */ - public function addFieldFromFormGenerator(string $fieldName, array $fieldConfig, ArrayPosition $position = null): self + public function addFieldFromFormGenerator(string $fieldName, array $fieldConfig, ArrayPosition|null $position = null): self { $this->checkFormFieldNameIsValid($fieldName); @@ -661,7 +640,8 @@ public function addFieldFromFormGenerator(string $fieldName, array $fieldConfig, $position = ArrayPosition::last(); } - // make sure "name" is set because not all form fields do need it and it would thus overwrite the array indexes + // make sure "name" is set because not all form fields do need it and it would + // thus overwrite the array indexes $fieldName = $fieldConfig['name'] ?: 'field_'.$fieldConfig['id']; // Make sure it has a "name" attribute because it is mandatory @@ -789,7 +769,8 @@ public function validate(): bool // Bind to Entity instance if (null !== $this->boundEntity) { - // If the field is a relation, store the value in the helper which will be processed by doctrine events later on + // If the field is a relation, store the value in the helper which will be + // processed by doctrine events later on if (null !== ($table = $this->getTableNameForEntity($this->boundEntity)) && ($GLOBALS['TL_DCA'][$table]['fields'][$fieldName]['relation']['type'] ?? null) === 'haste-ManyToMany') { /** @var DoctrineOrmHelper $doctrineHelper */ $doctrineHelper = System::getContainer()->get(DoctrineOrmHelper::class); @@ -840,7 +821,6 @@ public function addToObject(object $objObject): self $objObject->hasUploads = $this->hasUploads(); $objObject->novalidate = $this->generateNoValidateAttribute(); - /** @var Widget $widget */ $widgets = []; // Split hidden and visigle widgets @@ -884,14 +864,14 @@ public function getHelperObject(): \stdClass /** * Generate a form and return it as HTML string. */ - public function generate(string $templateName = null): string + public function generate(string|null $templateName = null): string { if (null === $templateName) { $templateName = 'form'; try { TemplateLoader::getPath($templateName, 'html5'); - } catch (\Exception $e) { + } catch (\Exception) { $templateName = 'form_wrapper'; } } @@ -940,12 +920,13 @@ public function fetch(string $fieldName): mixed /** * Return the submitted data as an associative array. */ - public function fetchAll(callable $callback = null): array + public function fetchAll(callable|null $callback = null): array { $data = []; foreach ($this->widgets as $fieldName => $widget) { - // Do not check $widget->submitInput() here because the callback could handle it differently + // Do not check $widget->submitInput() here because the callback could + // handle it differently if (\is_callable($callback)) { $value = $callback($fieldName, $widget); } else { @@ -974,10 +955,55 @@ protected function checkFormFieldNameIsValid(string $fieldName): void } } + /** + * Create the data container mock. + */ + private function createDataContainerMock(mixed $value, string $field, string $name): DataContainer + { + return new class($this->getBoundModel(), $value, $field, $name) extends DataContainer { + public function __construct($model, $value, $field, $name) + { + $this->id = $model ? $model->id : 0; + $this->table = $model ? $model::getTable() : ''; + $this->value = $value; + $this->field = $field; + $this->inputName = $name; + $this->activeRecord = $model; // BC + + parent::__construct(); + } + + public function getCurrentRecord(int|string|null $id = null, string|null $table = null): array|null + { + if (!$id) { + return null; + } + + $record = $this->Database + ->prepare("SELECT * FROM $table WHERE id=?") + ->limit(1) + ->execute($id) + ; + + return $record->numRows ? $record->row() : null; + } + + public function getPalette(): void + { + // noop + } + + protected function save($varValue): void + { + // noop + } + }; + } + /** * Get the table name for entity. */ - private function getTableNameForEntity(object $entity): ?string + private function getTableNameForEntity(object $entity): string|null { return $this->getMetaDataForEntity($entity)?->getTableName(); } @@ -997,14 +1023,14 @@ private function hasEntitySingleValuedRelation(object $entity, string $field): b /** * Get the meta data for entity. */ - private function getMetaDataForEntity(object $entity): ?ClassMetadata + private function getMetaDataForEntity(object $entity): ClassMetadata|null { static $cache = []; - $className = get_class($entity); + $className = $entity::class; - if (!array_key_exists($className, $cache)) { - $cache[$className] = $this->getEntityManager()?->getClassMetadata(get_class($entity)); + if (!\array_key_exists($className, $cache)) { + $cache[$className] = $this->getEntityManager()?->getClassMetadata($entity::class); } return $cache[$className]; @@ -1013,7 +1039,7 @@ private function getMetaDataForEntity(object $entity): ?ClassMetadata /** * Get the entity manager. */ - private function getEntityManager(): ?EntityManager + private function getEntityManager(): EntityManager|null { $service = 'doctrine.orm.entity_manager'; @@ -1021,9 +1047,6 @@ private function getEntityManager(): ?EntityManager return null; } - /** @var EntityManager $entityManager */ - $entityManager = System::getContainer()->get($service); - - return $entityManager; + return System::getContainer()->get($service); } } diff --git a/src/Form/Validator/MandatoryOn.php b/src/Form/Validator/MandatoryOn.php index eda17b6f..9c2bac03 100644 --- a/src/Form/Validator/MandatoryOn.php +++ b/src/Form/Validator/MandatoryOn.php @@ -24,7 +24,7 @@ public function validate(mixed $value, Widget $widget, Form $form): mixed $targetWidget = $form->getWidget($fieldName); $targetWidgetValue = $targetWidget->value; - if ('' === trim($value) && $this->matches[$targetWidget->name] && \in_array($targetWidgetValue, $this->matches[$targetWidget->name], true)) { + if ('' === trim((string) $value) && $this->matches[$targetWidget->name] && \in_array($targetWidgetValue, $this->matches[$targetWidget->name], true)) { throw new \RuntimeException($GLOBALS['TL_LANG']['MSC']['mandatory']); } } diff --git a/src/Formatter.php b/src/Formatter.php index cbeb29c3..18d522ed 100644 --- a/src/Formatter.php +++ b/src/Formatter.php @@ -90,7 +90,7 @@ public function dcaLabelFromArray(array $fieldConfig): string /** * Format DCA field value according to Contao Core standard. */ - public function dcaValue(string $table, string $field, mixed $value, DataContainer $dc = null): mixed + public function dcaValue(string $table, string $field, mixed $value, DataContainer|null $dc = null): mixed { $this->framework->initialize(); @@ -116,7 +116,7 @@ public function dcaValue(string $table, string $field, mixed $value, DataContain /** * Format field value according to Contao Core standard. */ - public function dcaValueFromArray(array $fieldConfig, mixed $value, DataContainer $dc = null): mixed + public function dcaValueFromArray(array $fieldConfig, mixed $value, DataContainer|null $dc = null): mixed { $value = StringUtil::deserialize($value); @@ -129,7 +129,7 @@ public function dcaValueFromArray(array $fieldConfig, mixed $value, DataContaine $fieldConfig['options'] = $fieldConfig['options_callback']($dc); } elseif (isset($fieldConfig['foreignKey']) && $value) { // foreignKey - $chunks = explode('.', $fieldConfig['foreignKey'], 2); + $chunks = explode('.', (string) $fieldConfig['foreignKey'], 2); $fieldConfig['options'] = []; @@ -140,8 +140,8 @@ public function dcaValueFromArray(array $fieldConfig, mixed $value, DataContaine } } - if (isset($fieldConfig['eval']['csv']) && str_contains($value, $fieldConfig['eval']['csv'])) { - $value = explode($fieldConfig['eval']['csv'], $value); + if (isset($fieldConfig['eval']['csv']) && str_contains((string) $value, (string) $fieldConfig['eval']['csv'])) { + $value = explode($fieldConfig['eval']['csv'], (string) $value); } if (\is_array($value)) { @@ -153,15 +153,15 @@ public function dcaValueFromArray(array $fieldConfig, mixed $value, DataContaine } if ('date' === ($fieldConfig['eval']['rgxp'] ?? null)) { - return ((string) $value !== '') ? $this->date((int) $value) : ''; + return '' !== (string) $value ? $this->date((int) $value) : ''; } if ('time' === ($fieldConfig['eval']['rgxp'] ?? null)) { - return ((string) $value !== '') ? $this->time((int) $value) : ''; + return '' !== (string) $value ? $this->time((int) $value) : ''; } - if ('datim' === ($fieldConfig['eval']['rgxp'] ?? null) || \in_array(($fieldConfig['flag'] ?? null), [5, 6, 7, 8, 9, 10], true) || 'tstamp' === ($fieldConfig['name'] ?? null)) { - return ((string) $value !== '') ? $this->datim((int) $value) : ''; + if ('datim' === ($fieldConfig['eval']['rgxp'] ?? null) || \in_array($fieldConfig['flag'] ?? null, [5, 6, 7, 8, 9, 10], true) || 'tstamp' === ($fieldConfig['name'] ?? null)) { + return '' !== (string) $value ? $this->datim((int) $value) : ''; } if (($fieldConfig['eval']['isBoolean'] ?? false) || ('checkbox' === ($fieldConfig['inputType'] ?? null) && !($fieldConfig['eval']['multiple'] ?? false))) { @@ -176,7 +176,7 @@ public function dcaValueFromArray(array $fieldConfig, mixed $value, DataContaine return \is_array($fieldConfig['reference'][$value]) ? $fieldConfig['reference'][$value][0] : $fieldConfig['reference'][$value]; } - if ((($fieldConfig['eval']['isAssociative'] ?? null) || ArrayUtil::isAssoc($fieldConfig['options'] ?? null)) && isset($fieldConfig['options'][$value])) { + if (isset($fieldConfig['options'][$value]) && (($fieldConfig['eval']['isAssociative'] ?? null) || ArrayUtil::isAssoc($fieldConfig['options'] ?? null))) { return \is_array($fieldConfig['options'][$value]) ? $fieldConfig['options'][$value][0] : $fieldConfig['options'][$value]; } diff --git a/src/Model/DcaRelationsModel.php b/src/Model/DcaRelationsModel.php index 02a4f822..94b394d7 100644 --- a/src/Model/DcaRelationsModel.php +++ b/src/Model/DcaRelationsModel.php @@ -14,9 +14,6 @@ abstract class DcaRelationsModel extends Model { - /** - * {@inheritdoc} - */ public function __set($key, $value): void { if (($this->arrRelations[$key]['type'] ?? null) === 'haste-ManyToMany' && !\is_array($value)) { @@ -26,14 +23,11 @@ public function __set($key, $value): void parent::__set($key, $value); } - /** - * {@inheritdoc} - */ public function getRelated($key, array $options = []) { try { $relation = static::getRelation(static::getTable(), $key); - } catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException) { $relation = null; } @@ -52,7 +46,8 @@ public function getRelated($key, array $options = []) $collection = []; - // Fetch from registry first (only possible if no options and the relation field is the PK) + // Fetch from registry first (only possible if no options and the relation field + // is the PK) if (0 === \count($options) && $relation['field'] === $strClass::getPk()) { foreach ($ids as $k => $id) { $model = Registry::getInstance()->fetch($relation['related_table'], $id); @@ -81,9 +76,6 @@ public function getRelated($key, array $options = []) return parent::getRelated($key, $options); } - /** - * {@inheritdoc} - */ public function save() { $values = []; @@ -118,7 +110,8 @@ public static function getReferenceValues(string $table, string $field, mixed $v /** @var Connection $connection */ $connection = System::getContainer()->get('database_connection'); - // Preserve the values order by using the force saved values in the table in the ORDER BY statement + // Preserve the values order by using the force saved values in the table in the + // ORDER BY statement if (1 === \count($values) && $relation['forceSave'] && \array_key_exists(strtolower($field), $connection->createSchemaManager()->listTableColumns($relation['related_table']))) { $recordValues = $connection->fetchOne('SELECT '.$field.' FROM '.$relation['related_table'].' WHERE '.$relation['field'].'=? LIMIT 1', [$values[0]]); $recordValues = StringUtil::deserialize($recordValues); @@ -143,7 +136,8 @@ public static function getRelatedValues(string $table, string $field, mixed $val /** @var Connection $connection */ $connection = System::getContainer()->get('database_connection'); - // Preserve the values order by using the force saved values in the table in the ORDER BY statement + // Preserve the values order by using the force saved values in the table in the + // ORDER BY statement if (1 === \count($values) && $relation['forceSave'] && \array_key_exists(strtolower($field), $connection->createSchemaManager()->listTableColumns($relation['reference_table']))) { $recordValues = $connection->fetchOne('SELECT '.$field.' FROM '.$relation['reference_table'].' WHERE '.$relation['reference'].'=? LIMIT 1', [$values[0]]); $recordValues = StringUtil::deserialize($recordValues); diff --git a/src/StringParser.php b/src/StringParser.php index 6d1da445..bca4175a 100644 --- a/src/StringParser.php +++ b/src/StringParser.php @@ -14,9 +14,13 @@ class StringParser * Text filter options. */ public const NO_TAGS = 1; + public const NO_BREAKS = 2; + public const NO_EMAILS = 4; + public const NO_INSERTTAGS = 8; + public const NO_ENTITIES = 16; /** @@ -38,7 +42,7 @@ public function recursiveReplaceTokensAndTags(string $text, array $tokens, int $ $buffer = System::getContainer()->get('contao.insert_tag.parser')->replaceInline($buffer); // check if the insert tags have returned a simple token - if (str_contains($buffer, '##') && $buffer !== $text) { + if (str_contains((string) $buffer, '##') && $buffer !== $text) { $buffer = $this->recursiveReplaceTokensAndTags($buffer, $tokens, $textFlags); } @@ -93,7 +97,7 @@ public function convertToText(mixed $value, int $options): mixed // Remove HTML tags but keep line breaks for
and

if ($options & static::NO_TAGS) { - $value = strip_tags(preg_replace('{(?!^)<(br|p|/p).*?/?>\n?(?!$)}is', "\n", $value)); + $value = strip_tags((string) preg_replace('{(?!^)<(br|p|/p).*?/?>\n?(?!$)}is', "\n", $value)); } if ($options & static::NO_INSERTTAGS) { @@ -118,7 +122,7 @@ public function convertToText(mixed $value, int $options): mixed /** * Flatten input data, Simple Tokens can't handle arrays. */ - public function flatten(mixed $value, string $key, array & $data, string $pattern = ', '): void + public function flatten(mixed $value, string $key, array &$data, string $pattern = ', '): void { if (\is_object($value)) { return; diff --git a/src/UndoManager.php b/src/UndoManager.php index e6889821..37d4589c 100644 --- a/src/UndoManager.php +++ b/src/UndoManager.php @@ -16,8 +16,10 @@ class UndoManager { - public function __construct(private readonly Connection $connection, private readonly EventDispatcherInterface $eventDispatcher,) - { + public function __construct( + private readonly Connection $connection, + private readonly EventDispatcherInterface $eventDispatcher, + ) { } /** @@ -49,11 +51,11 @@ public function add(int $undoId, string $key, mixed $data): bool { $undoData = $this->connection->fetchOne('SELECT haste_data FROM tl_undo WHERE id=?', [$undoId]); - if ($undoData === false) { + if (false === $undoData) { return false; } - $undoData = $undoData ? json_decode($undoData, true) : []; + $undoData = $undoData ? json_decode((string) $undoData, true) : []; $undoData[$key] = $data; $affectedRows = $this->connection->update('tl_undo', ['haste_data' => json_encode($undoData)], ['id' => $undoId]); @@ -64,7 +66,7 @@ public function add(int $undoId, string $key, mixed $data): bool /** * Undo the record. */ - public function undo(int $undoId, DataContainer $dc = null): bool + public function undo(int $undoId, DataContainer|null $dc = null): bool { $record = $this->connection->fetchAssociative('SELECT * FROM tl_undo WHERE id=?', [$undoId]); $data = StringUtil::deserialize($record['data']); @@ -75,7 +77,7 @@ public function undo(int $undoId, DataContainer $dc = null): bool $error = false; $fieldsMapper = []; - $hasteData = json_decode($record['haste_data'], true); + $hasteData = json_decode((string) $record['haste_data'], true); $schemaManager = $this->connection->createSchemaManager(); // Restore the data @@ -139,7 +141,7 @@ public function hasData(int $undoId): bool return false; } - $undoData = json_decode($undoData, true); + $undoData = json_decode((string) $undoData, true); return \is_array($undoData) && \count($undoData) > 0; } diff --git a/src/UrlParser.php b/src/UrlParser.php index b7dc4dba..a27b855d 100644 --- a/src/UrlParser.php +++ b/src/UrlParser.php @@ -12,7 +12,7 @@ class UrlParser /** * Add a query string to the given URI string or page ID. */ - public function addQueryString(string $query, string $url = null): string + public function addQueryString(string $query, string|null $url = null): string { $url = $this->prepareUrl($url); $query = trim(StringUtil::ampersand($query, false), '&'); @@ -39,7 +39,7 @@ public function addQueryString(string $query, string $url = null): string /** * Remove query parameters from the current URL. */ - public function removeQueryString(array $params, string $url = null): string + public function removeQueryString(array $params, string|null $url = null): string { $url = $this->prepareUrl($url); @@ -66,7 +66,7 @@ public function removeQueryString(array $params, string $url = null): string /** * Remove query parameters from the current URL using a callback method. */ - public function removeQueryStringCallback(callable $callback, string $url = null): string + public function removeQueryStringCallback(callable $callback, string|null $url = null): string { $url = $this->prepareUrl($url); @@ -74,7 +74,8 @@ public function removeQueryStringCallback(callable $callback, string $url = null parse_str($queryString, $queries); - // Cannot use array_filter because flags ARRAY_FILTER_USE_BOTH is only supported in PHP 5.6 + // Cannot use array_filter because flags ARRAY_FILTER_USE_BOTH is only supported + // in PHP 5.6 foreach ($queries as $k => $v) { if (true !== $callback($v, $k)) { unset($queries[$k]); @@ -93,7 +94,7 @@ public function removeQueryStringCallback(callable $callback, string $url = null /** * Prepare URL from ID and keep query string from current string. */ - protected function prepareUrl(string $url = null): string + protected function prepareUrl(string|null $url = null): string { if (null === $url) { $url = Environment::get('requestUri'); diff --git a/src/Util/ArrayPosition.php b/src/Util/ArrayPosition.php index 0bcd7f59..f72eeb45 100644 --- a/src/Util/ArrayPosition.php +++ b/src/Util/ArrayPosition.php @@ -7,14 +7,18 @@ class ArrayPosition { public const FIRST = 0; + public const LAST = 1; + public const BEFORE = 2; + public const AFTER = 3; protected int $position; + protected string $fieldName; - public function __construct(int $position, string $fieldName = null) + public function __construct(int $position, string|null $fieldName = null) { switch ($position) { case static::FIRST: @@ -37,12 +41,12 @@ public function __construct(int $position, string $fieldName = null) } } - public function position() + public function position(): int { return $this->position; } - public function fieldName() + public function fieldName(): string { return $this->fieldName; } @@ -77,21 +81,21 @@ public function addToArray(array $existing, array $new): array public static function first(): static { - return new static(static::FIRST); + return new self(static::FIRST); } public static function last(): static { - return new static(static::LAST); + return new self(static::LAST); } public static function before($fieldName): static { - return new static(static::BEFORE, $fieldName); + return new self(static::BEFORE, $fieldName); } public static function after($fieldName): static { - return new static(static::AFTER, $fieldName); + return new self(static::AFTER, $fieldName); } } diff --git a/src/Util/Pagination.php b/src/Util/Pagination.php index a57bcaf5..c216833e 100644 --- a/src/Util/Pagination.php +++ b/src/Util/Pagination.php @@ -10,16 +10,25 @@ class Pagination { public const STATE_CLEAN = 0; + public const STATE_DIRTY = 1; protected int $currentState = self::STATE_DIRTY; + protected bool $outOfRange = false; + protected int $total; + protected int $perPage; + protected string $urlParameter; + protected int $maxPaginationLinks; + protected int $limit; + protected int $offset; + protected \Contao\Pagination $pagination; public function __construct(int $total, int $perPage, string $urlParameter) @@ -149,7 +158,7 @@ protected function compile(): void $this->getTotal(), $this->getPerPage(), $this->getMaxPaginationLinks(), - $this->getUrlParameter() + $this->getUrlParameter(), ); $this->currentState = self::STATE_CLEAN; diff --git a/tests/CodefogHasteBundleTest.php b/tests/CodefogHasteBundleTest.php index 97723cd7..77fff3d1 100644 --- a/tests/CodefogHasteBundleTest.php +++ b/tests/CodefogHasteBundleTest.php @@ -1,5 +1,7 @@ pageTitle; } - public function setPageTitle(?string $pageTitle): self + public function setPageTitle(string|null $pageTitle): self { $this->pageTitle = $pageTitle; return $this; } - public function getJumpTo(): ?int + public function getJumpTo(): int|null { return $this->jumpTo; } - public function setJumpTo(?int $jumpTo): self + public function setJumpTo(int|null $jumpTo): self { $this->jumpTo = $jumpTo; diff --git a/tests/Fixtures/FormTextField.php b/tests/Fixtures/FormTextField.php index b4f1faac..b5419153 100644 --- a/tests/Fixtures/FormTextField.php +++ b/tests/Fixtures/FormTextField.php @@ -1,11 +1,16 @@ value = \Contao\Input::post($this->name); + $this->value = Input::post($this->name); } } diff --git a/tests/Fixtures/Input.php b/tests/Fixtures/Input.php index dc6e289f..1ddecf14 100644 --- a/tests/Fixtures/Input.php +++ b/tests/Fixtures/Input.php @@ -1,5 +1,7 @@ assertInstanceOf(Form::class, $this->createForm()); } - public function testSetFormActionFromUri() + public function testSetFormActionFromUri(): void { $form = $this->createForm(); $form->setAction('foobar'); - $this->assertEquals('foobar', $form->getAction()); + $this->assertSame('foobar', $form->getAction()); } - public function testFormId() + public function testFormId(): void { - $this->assertEquals('my-form-id', $this->createForm()->getFormId()); + $this->assertSame('my-form-id', $this->createForm()->getFormId()); } - public function testIsSubmitted() + public function testIsSubmitted(): void { $this->assertTrue($this->createForm()->isSubmitted()); $this->assertFalse($this->createForm(false)->isSubmitted()); } - public function testBoundEntity() + public function testBoundEntity(): void { $form = $this->createForm(); - $form ->addFormField('pageTitle', [ 'inputType' => 'text', @@ -58,12 +59,12 @@ public function testBoundEntity() $boundEntity = $form->getBoundEntity(); $this->assertTrue(spl_object_hash($entity) === spl_object_hash($boundEntity)); - $this->assertEquals('My page title test', $boundEntity->getPageTitle()); - $this->assertEquals(42, $boundEntity->getJumpTo()); + $this->assertSame('My page title test', $boundEntity->getPageTitle()); + $this->assertSame(42, $boundEntity->getJumpTo()); } } - public function testBoundEntityDefaultValues() + public function testBoundEntityDefaultValues(): void { $form = $this->createForm(false); @@ -83,14 +84,13 @@ public function testBoundEntityDefaultValues() $form->createWidgets(); - $this->assertEquals('My page', $form->getWidget('pageTitle')->value); - $this->assertEquals(11, $form->getWidget('jumpTo')->value); + $this->assertSame('My page', $form->getWidget('pageTitle')->value); + $this->assertSame(11, $form->getWidget('jumpTo')->value); } - public function testBoundModel() + public function testBoundModel(): void { $form = $this->createForm(); - $form ->addFormField('pageTitle', [ 'inputType' => 'text', @@ -110,12 +110,12 @@ public function testBoundModel() $boundModel = $form->getBoundModel(); $this->assertTrue(spl_object_hash($pageModel) === spl_object_hash($boundModel)); - $this->assertEquals('My page title test', $boundModel->pageTitle); - $this->assertEquals(42, $boundModel->jumpTo); + $this->assertSame('My page title test', $boundModel->pageTitle); + $this->assertSame(42, $boundModel->jumpTo); } } - public function testBoundModelDefaultValues() + public function testBoundModelDefaultValues(): void { $form = $this->createForm(false); @@ -138,9 +138,9 @@ public function testBoundModelDefaultValues() $form->createWidgets(); - $this->assertEquals(13, $form->getWidget('id')->value); - $this->assertEquals('My page', $form->getWidget('pageTitle')->value); - $this->assertEquals(11, $form->getWidget('jumpTo')->value); + $this->assertSame(13, $form->getWidget('id')->value); + $this->assertSame('My page', $form->getWidget('pageTitle')->value); + $this->assertSame(11, $form->getWidget('jumpTo')->value); } private function createForm(bool $isSubmitted = true): Form @@ -148,6 +148,6 @@ private function createForm(bool $isSubmitted = true): Form $GLOBALS['TL_MODELS']['tl_page'] = PageModel::class; $GLOBALS['TL_FFL']['text'] = FormTextField::class; - return new Form('my-form-id', 'POST', fn () => $isSubmitted); + return new Form('my-form-id', 'POST', static fn () => $isSubmitted); } } diff --git a/tests/StringParserTest.php b/tests/StringParserTest.php index c002cbe1..3341a75c 100644 --- a/tests/StringParserTest.php +++ b/tests/StringParserTest.php @@ -1,5 +1,7 @@ flatten($value, $key, $data); - $this->assertEquals($expected, $data); + $this->assertSame($expected, $data); } public function flattenDataProvider() @@ -75,8 +77,7 @@ public function flattenDataProvider() ], ], - // Arrays are handled recursively - // Array keys are retained + // Arrays are handled recursively Array keys are retained [ ['bar' => ['baz']], 'foo', diff --git a/tests/UrlParserTest.php b/tests/UrlParserTest.php index 0a651025..7d733c08 100644 --- a/tests/UrlParserTest.php +++ b/tests/UrlParserTest.php @@ -1,5 +1,7 @@ removeQueryStringCallback( - static function ($value, $key) use ($paramsToRemove) { - return !in_array($key, $paramsToRemove, true); - }, - $request + static fn ($value, $key) => !\in_array($key, $paramsToRemove, true), + $request, ); $this->assertSame($expectedResult, $actualResult); } - public function addQueryStringProvider() { // current request -> query to add -> expected result @@ -122,7 +121,6 @@ public function addQueryStringProvider() ]; } - public function removeQueryStringProvider() { // current request -> query to remove -> expected result diff --git a/tests/Util/ArrayPositionTest.php b/tests/Util/ArrayPositionTest.php index 34a6e3a1..c165be64 100644 --- a/tests/Util/ArrayPositionTest.php +++ b/tests/Util/ArrayPositionTest.php @@ -1,5 +1,7 @@ assertEquals(ArrayPosition::FIRST, $handler->position()); + $this->assertSame(ArrayPosition::FIRST, $handler->position()); $result = $handler->addToArray( - array('test1'=>'test', 'test2'=>'test', 'test3'=>'test'), - array('first'=>'value') + ['test1' => 'test', 'test2' => 'test', 'test3' => 'test'], + ['first' => 'value'], ); - $this->assertEquals('value', $result['first']); + $this->assertSame('value', $result['first']); $keys = array_keys($result); - $this->assertEquals('first', $keys[0]); - $this->assertEquals('test1', $keys[1]); - $this->assertEquals('test2', $keys[2]); - $this->assertEquals('test3', $keys[3]); + $this->assertSame('first', $keys[0]); + $this->assertSame('test1', $keys[1]); + $this->assertSame('test2', $keys[2]); + $this->assertSame('test3', $keys[3]); } - public function testLast() + public function testLast(): void { $handler = ArrayPosition::last(); - $this->assertEquals(ArrayPosition::LAST, $handler->position()); + $this->assertSame(ArrayPosition::LAST, $handler->position()); $result = $handler->addToArray( - array('test1'=>'test', 'test2'=>'test', 'test3'=>'test'), - array('last'=>'value') + ['test1' => 'test', 'test2' => 'test', 'test3' => 'test'], + ['last' => 'value'], ); - $this->assertEquals('value', $result['last']); + $this->assertSame('value', $result['last']); $keys = array_keys($result); - $this->assertEquals('test1', $keys[0]); - $this->assertEquals('test2', $keys[1]); - $this->assertEquals('test3', $keys[2]); - $this->assertEquals('last', $keys[3]); + $this->assertSame('test1', $keys[0]); + $this->assertSame('test2', $keys[1]); + $this->assertSame('test3', $keys[2]); + $this->assertSame('last', $keys[3]); } - public function testBefore() + public function testBefore(): void { $handler = ArrayPosition::before('test2'); - $this->assertEquals(ArrayPosition::BEFORE, $handler->position()); - $this->assertEquals('test2', $handler->fieldName()); + $this->assertSame(ArrayPosition::BEFORE, $handler->position()); + $this->assertSame('test2', $handler->fieldName()); $result = $handler->addToArray( - array('test1'=>'test', 'test2'=>'test', 'test3'=>'test'), - array('before2'=>'value') + ['test1' => 'test', 'test2' => 'test', 'test3' => 'test'], + ['before2' => 'value'], ); - $this->assertEquals('value', $result['before2']); + $this->assertSame('value', $result['before2']); $keys = array_keys($result); - $this->assertEquals('test1', $keys[0]); - $this->assertEquals('before2', $keys[1]); - $this->assertEquals('test2', $keys[2]); - $this->assertEquals('test3', $keys[3]); + $this->assertSame('test1', $keys[0]); + $this->assertSame('before2', $keys[1]); + $this->assertSame('test2', $keys[2]); + $this->assertSame('test3', $keys[3]); } - public function testAfter() + public function testAfter(): void { $handler = ArrayPosition::after('test2'); - $this->assertEquals(ArrayPosition::AFTER, $handler->position()); - $this->assertEquals('test2', $handler->fieldName()); + $this->assertSame(ArrayPosition::AFTER, $handler->position()); + $this->assertSame('test2', $handler->fieldName()); $result = $handler->addToArray( - array('test1'=>'test', 'test2'=>'test', 'test3'=>'test'), - array('after2'=>'value') + ['test1' => 'test', 'test2' => 'test', 'test3' => 'test'], + ['after2' => 'value'], ); - $this->assertEquals('value', $result['after2']); + $this->assertSame('value', $result['after2']); $keys = array_keys($result); - $this->assertEquals('test1', $keys[0]); - $this->assertEquals('test2', $keys[1]); - $this->assertEquals('after2', $keys[2]); - $this->assertEquals('test3', $keys[3]); + $this->assertSame('test1', $keys[0]); + $this->assertSame('test2', $keys[1]); + $this->assertSame('after2', $keys[2]); + $this->assertSame('test3', $keys[3]); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 85f99763..3534d16f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -12,9 +12,7 @@ error_reporting(E_ALL); -$include = function ($file) { - return file_exists($file) ? include $file : false; -}; +$include = fn ($file) => file_exists($file) ? include $file : false; if ( false === ($loader = $include(__DIR__.'/../vendor/autoload.php')) @@ -34,20 +32,20 @@ return; } - if (false !== strpos($class, '\\') && 0 !== strncmp($class, 'Contao\\', 7) && 0 !== strncmp($class, 'Codefog\HasteBundle\\', 19)) { + if (str_contains((string) $class, '\\') && !str_starts_with((string) $class, 'Contao\\') && 0 !== strncmp((string) $class, 'Codefog\HasteBundle\\', 19)) { return; } $isContaoClass = false; $isBundleClass = false; - if (0 === strncmp($class, 'Contao\\', 7)) { - $class = substr($class, 7); + if (str_starts_with((string) $class, 'Contao\\')) { + $class = substr((string) $class, 7); $isContaoClass = true; } - if (0 === strncmp($class, 'Codefog\HasteBundle\\', 19)) { - $class = substr($class, 19); + if (0 === strncmp((string) $class, 'Codefog\HasteBundle\\', 19)) { + $class = substr((string) $class, 19); $isBundleClass = true; } diff --git a/tools/ecs/composer.json b/tools/ecs/composer.json deleted file mode 100644 index b28ad40f..00000000 --- a/tools/ecs/composer.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "require": { - "contao/easy-coding-standard": "^3.0" - }, - "config": { - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } - } -} diff --git a/tools/ecs/composer.lock b/tools/ecs/composer.lock deleted file mode 100644 index 8401dc67..00000000 --- a/tools/ecs/composer.lock +++ /dev/null @@ -1,356 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "1a77f453fb2cee32bb655dca54548909", - "packages": [ - { - "name": "contao/easy-coding-standard", - "version": "3.6.0", - "source": { - "type": "git", - "url": "https://github.com/contao/easy-coding-standard.git", - "reference": "d680103a1c62a1987c60678dfed12d2b7b5f425a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/contao/easy-coding-standard/zipball/d680103a1c62a1987c60678dfed12d2b7b5f425a", - "reference": "d680103a1c62a1987c60678dfed12d2b7b5f425a", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^7.0", - "symplify/easy-coding-standard": "^9.4.68" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Contao\\EasyCodingStandard\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Leo Feyer", - "homepage": "https://github.com/leofeyer" - } - ], - "description": "EasyCodingStandard configurations for Contao", - "support": { - "issues": "https://github.com/contao/easy-coding-standard/issues", - "source": "https://github.com/contao/easy-coding-standard/tree/3.6.0" - }, - "time": "2021-11-17T10:22:00+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "367a8d9d5f7da2a0136422d27ce8840583926955" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/367a8d9d5f7da2a0136422d27ce8840583926955", - "reference": "367a8d9d5f7da2a0136422d27ce8840583926955", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.7.0" - }, - "time": "2022-08-09T12:23:23+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.3", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-05-25T10:58:12+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "symplify/easy-coding-standard", - "version": "9.4.70", - "source": { - "type": "git", - "url": "https://github.com/symplify/easy-coding-standard.git", - "reference": "9276b0c7a1a5671fc4a067656ab40d0aea42aaca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/9276b0c7a1a5671fc4a067656ab40d0aea42aaca", - "reference": "9276b0c7a1a5671fc4a067656ab40d0aea42aaca", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "conflict": { - "friendsofphp/php-cs-fixer": "<3.0", - "squizlabs/php_codesniffer": "<3.6" - }, - "bin": [ - "bin/ecs" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "9.5-dev" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Prefixed scoped version of ECS package", - "support": { - "source": "https://github.com/symplify/easy-coding-standard/tree/9.4.70" - }, - "funding": [ - { - "url": "https://www.paypal.me/rectorphp", - "type": "custom" - }, - { - "url": "https://github.com/tomasvotruba", - "type": "github" - } - ], - "time": "2021-10-02T16:09:04+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" -}