diff --git a/composer.json b/composer.json index ffe87edb1..37282788e 100644 --- a/composer.json +++ b/composer.json @@ -76,7 +76,7 @@ "phpunit/phpunit": ">= 7.5", "psalm/plugin-phpunit": "^0.18.4", "psalm/plugin-symfony": "^4.0.2", - "rector/rector": "^0.17.7", + "rector/rector": "^1.1.0", "symfony/debug-bundle": "^5.1", "symfony/dotenv": "^4.4", "symfony/maker-bundle": "^1.20", diff --git a/phpstan-baseline-2024-05.neon b/phpstan-baseline-2024-05.neon new file mode 100644 index 000000000..728ec4edc --- /dev/null +++ b/phpstan-baseline-2024-05.neon @@ -0,0 +1,6 @@ +parameters: + ignoreErrors: + - + message: "#^Parameter \\#1 \\$records of method League\\\\Csv\\\\Writer\\:\\:insertAll\\(\\) expects iterable\\\\>, iterable\\\\> given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/UserExportController.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 62dbe0468..4e6745469 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -31,4 +31,5 @@ includes: - phpstan-baseline-level-3.neon - phpstan-baseline-level-4.neon - phpstan-baseline-level-5.neon + - phpstan-baseline-2024-05.neon diff --git a/rector.php b/rector.php index 0dd8e355c..8aa62bdd0 100644 --- a/rector.php +++ b/rector.php @@ -45,9 +45,6 @@ return static function (RectorConfig $rectorConfig): void { // skip some path... $rectorConfig->skip([ - // we need to discuss this: are we going to have FALSE in tests instead of an error ? - \Rector\Php71\Rector\FuncCall\CountOnNullRector::class, - // we must adapt service definition \Rector\Symfony\Symfony28\Rector\MethodCall\GetToConstructorInjectionRector::class, \Rector\Symfony\Symfony34\Rector\Closure\ContainerGetNameToTypeInTestsRector::class, diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php index ff89c04d2..eb2d3b011 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php @@ -49,20 +49,17 @@ interface CustomFieldInterface /** * Return if the value can be considered as empty. - * - * @param mixed $value the value passed throug the deserialize function */ - public function isEmptyValue($value, CustomField $customField); + public function isEmptyValue(mixed $value, CustomField $customField); /** * Return a repsentation of the value of the CustomField. * - * @param mixed $value the raw value, **not deserialized** (= as stored in the db) * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField * * @return string an html representation of the value */ - public function render($value, CustomField $customField, $documentType = 'html'); + public function render(mixed $value, CustomField $customField, $documentType = 'html'); /** * Transform the value into a format that can be stored in DB. diff --git a/src/Bundle/ChillCustomFieldsBundle/Tests/CustomFields/CustomFieldsChoiceTest.php b/src/Bundle/ChillCustomFieldsBundle/Tests/CustomFields/CustomFieldsChoiceTest.php index 48d4847d6..b9fe45820 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Tests/CustomFields/CustomFieldsChoiceTest.php +++ b/src/Bundle/ChillCustomFieldsBundle/Tests/CustomFields/CustomFieldsChoiceTest.php @@ -399,8 +399,6 @@ final class CustomFieldsChoiceTest extends KernelTestCase /** * @dataProvider emptyDataProvider - * - * @param mixed $data deserialized data */ public function testIsEmptyValueEmpty(mixed $data) { diff --git a/src/Bundle/ChillDocStoreBundle/Security/Guard/JWTOnDavUrlAuthenticator.php b/src/Bundle/ChillDocStoreBundle/Security/Guard/JWTOnDavUrlAuthenticator.php index 7695fb635..fe8ba2b73 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Guard/JWTOnDavUrlAuthenticator.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Guard/JWTOnDavUrlAuthenticator.php @@ -29,7 +29,7 @@ class JWTOnDavUrlAuthenticator extends JWTTokenAuthenticator TokenExtractorInterface $tokenExtractor, private readonly DavOnUrlTokenExtractor $davOnUrlTokenExtractor, TokenStorageInterface $preAuthenticationTokenStorage, - TranslatorInterface $translator = null, + ?TranslatorInterface $translator = null, ) { parent::__construct($jwtManager, $dispatcher, $tokenExtractor, $preAuthenticationTokenStorage, $translator); } diff --git a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php index e394e0a11..3b6c32148 100644 --- a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php +++ b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php @@ -149,7 +149,7 @@ final readonly class WopiEditTwigExtensionRuntime implements RuntimeExtensionInt * @throws \Twig\Error\RuntimeError * @throws \Twig\Error\SyntaxError */ - public function renderButtonGroup(Environment $environment, StoredObject $document, string $title = null, bool $canEdit = true, array $options = []): string + public function renderButtonGroup(Environment $environment, StoredObject $document, ?string $title = null, bool $canEdit = true, array $options = []): string { $accessToken = $this->davTokenProvider->createToken( $document, @@ -174,7 +174,7 @@ final readonly class WopiEditTwigExtensionRuntime implements RuntimeExtensionInt ]); } - public function renderEditButton(Environment $environment, StoredObject $document, array $options = null): string + public function renderEditButton(Environment $environment, StoredObject $document, ?array $options = null): string { return $environment->render(self::TEMPLATE, [ 'document' => $document, diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Security/Authorization/StoredObjectVoterTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Security/Authorization/StoredObjectVoterTest.php index 477427078..92c928681 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/Security/Authorization/StoredObjectVoterTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/Security/Authorization/StoredObjectVoterTest.php @@ -32,7 +32,7 @@ class StoredObjectVoterTest extends TestCase /** * @dataProvider provideDataVote */ - public function testVote(TokenInterface $token, null|object $subject, string $attribute, mixed $expected): void + public function testVote(TokenInterface $token, ?object $subject, string $attribute, mixed $expected): void { $voter = new StoredObjectVoter(); @@ -98,7 +98,7 @@ class StoredObjectVoterTest extends TestCase ]; } - private function buildToken(StoredObjectRoleEnum $storedObjectRoleEnum = null, StoredObject $storedObject = null): TokenInterface + private function buildToken(?StoredObjectRoleEnum $storedObjectRoleEnum = null, ?StoredObject $storedObject = null): TokenInterface { $token = $this->prophesize(TokenInterface::class); diff --git a/src/Bundle/ChillEventBundle/Controller/EventTypeController.php b/src/Bundle/ChillEventBundle/Controller/EventTypeController.php index 3d9570abb..aa6539bee 100644 --- a/src/Bundle/ChillEventBundle/Controller/EventTypeController.php +++ b/src/Bundle/ChillEventBundle/Controller/EventTypeController.php @@ -206,8 +206,6 @@ class EventTypeController extends AbstractController /** * Creates a form to delete a EventType entity by id. * - * @param mixed $id The entity id - * * @return \Symfony\Component\Form\Form The form */ private function createDeleteForm(mixed $id) diff --git a/src/Bundle/ChillEventBundle/Controller/RoleController.php b/src/Bundle/ChillEventBundle/Controller/RoleController.php index 8c0b63bc8..8177a8ba8 100644 --- a/src/Bundle/ChillEventBundle/Controller/RoleController.php +++ b/src/Bundle/ChillEventBundle/Controller/RoleController.php @@ -206,8 +206,6 @@ class RoleController extends AbstractController /** * Creates a form to delete a Role entity by id. * - * @param mixed $id The entity id - * * @return \Symfony\Component\Form\Form The form */ private function createDeleteForm(mixed $id) diff --git a/src/Bundle/ChillEventBundle/Controller/StatusController.php b/src/Bundle/ChillEventBundle/Controller/StatusController.php index c1b1018cd..c664ee439 100644 --- a/src/Bundle/ChillEventBundle/Controller/StatusController.php +++ b/src/Bundle/ChillEventBundle/Controller/StatusController.php @@ -206,8 +206,6 @@ class StatusController extends AbstractController /** * Creates a form to delete a Status entity by id. * - * @param mixed $id The entity id - * * @return \Symfony\Component\Form\Form The form */ private function createDeleteForm(mixed $id) diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php index 213efba24..909b1cbda 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php @@ -700,7 +700,6 @@ class CRUDController extends AbstractController * and view. * * @param string $action - * @param mixed $entity the entity for the current request, or an array of entities * * @return string the path to the template * diff --git a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php index 42d0d6a78..10fba6ddd 100644 --- a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php +++ b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php @@ -317,8 +317,8 @@ final class PermissionsGroupController extends AbstractController } return strcmp( - $translatableStringHelper->localize($a->getScope()->getName()), - $translatableStringHelper->localize($b->getScope()->getName()) + (string) $translatableStringHelper->localize($a->getScope()->getName()), + (string) $translatableStringHelper->localize($b->getScope()->getName()) ); } ); @@ -451,8 +451,6 @@ final class PermissionsGroupController extends AbstractController /** * Creates a form to delete a link to roleScope. - * - * @param mixed $permissionsGroup The entity id */ private function createDeleteRoleScopeForm( PermissionsGroup $permissionsGroup, diff --git a/src/Bundle/ChillMainBundle/Controller/UserExportController.php b/src/Bundle/ChillMainBundle/Controller/UserExportController.php index 41c2d1a85..e25e6074f 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserExportController.php @@ -73,6 +73,7 @@ final readonly class UserExportController ) ); $csv->addFormatter(fn (array $row) => null !== ($row['absenceStart'] ?? null) ? array_merge($row, ['absenceStart' => $row['absenceStart']->format('Y-m-d')]) : $row); + /* @phpstan-ignore-next-line as phpstan seem to ignore that we transform datetime into string */ $csv->insertAll($users); return new StreamedResponse( diff --git a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadPostalCodes.php b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadPostalCodes.php index c8010f604..29ee21ca6 100644 --- a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadPostalCodes.php +++ b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadPostalCodes.php @@ -344,11 +344,11 @@ class LoadPostalCodes extends AbstractFixture implements OrderedFixtureInterface ->findOneBy(['countryCode' => $countryCode]); foreach ($lines as $line) { - $code = str_getcsv($line); + $code = str_getcsv((string) $line); $c = new PostalCode(); $c->setCountry($country) ->setCode($code[0]) - ->setName(\ucwords(\strtolower($code[1]))); + ->setName(\ucwords(\strtolower((string) $code[1]))); if (null !== ($code[3] ?? null)) { $c->setRefPostalCodeId($code[3]); diff --git a/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php b/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php index 28c168893..e849dec07 100644 --- a/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php +++ b/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php @@ -73,7 +73,6 @@ interface AggregatorInterface extends ModifierInterface * * @param string $key The column key, as added in the query * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR') - * @param mixed $data The data from the export's form (as defined in `buildForm` * * @return \Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` */ diff --git a/src/Bundle/ChillMainBundle/Export/ExportElementValidatedInterface.php b/src/Bundle/ChillMainBundle/Export/ExportElementValidatedInterface.php index ea9094687..d4f58a570 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportElementValidatedInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportElementValidatedInterface.php @@ -30,8 +30,6 @@ interface ExportElementValidatedInterface /** * validate the form's data and, if required, build a contraint * violation on the data. - * - * @param mixed $data the data, as returned by the user */ public function validateForm(mixed $data, ExecutionContextInterface $context); } diff --git a/src/Bundle/ChillMainBundle/Export/ExportInterface.php b/src/Bundle/ChillMainBundle/Export/ExportInterface.php index 39e265153..a9d3efd13 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportInterface.php @@ -96,7 +96,6 @@ interface ExportInterface extends ExportElementInterface * * @param string $key The column key, as added in the query * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR') - * @param mixed $data The data from the export's form (as defined in `buildForm`) * * @return (callable(string|int|float|'_header'|null $value): string|int|\DateTimeInterface) where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` */ diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index 159b90b6b..9cb2a54ba 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -552,7 +552,6 @@ class ExportManager * * This function check the acl. * - * @param mixed $data the data under the initial 'filters' data * @param \Chill\MainBundle\Entity\Center[] $centers the picked centers * * @throw UnauthorizedHttpException if the user is not authorized @@ -615,9 +614,6 @@ class ExportManager return $usedTypes; } - /** - * @param mixed $data the data from the filter key of the ExportType - */ private function retrieveUsedFilters(mixed $data): iterable { if (null === $data) { @@ -634,8 +630,6 @@ class ExportManager /** * Retrieve the filter used in this export. * - * @param mixed $data the data from the `filters` key of the ExportType - * * @return array an array with types */ private function retrieveUsedFiltersType(mixed $data): iterable diff --git a/src/Bundle/ChillMainBundle/Search/SearchProvider.php b/src/Bundle/ChillMainBundle/Search/SearchProvider.php index e239b872d..73c48f4cf 100644 --- a/src/Bundle/ChillMainBundle/Search/SearchProvider.php +++ b/src/Bundle/ChillMainBundle/Search/SearchProvider.php @@ -257,10 +257,10 @@ class SearchProvider $this->mustBeExtracted[] = $matches[0][$key]; // strip parenthesis if ( - '"' === mb_substr((string) $match, 0, 1) - && '"' === mb_substr((string) $match, mb_strlen((string) $match) - 1) + '"' === mb_substr($match, 0, 1) + && '"' === mb_substr($match, mb_strlen($match) - 1) ) { - $match = trim(mb_substr((string) $match, 1, mb_strlen((string) $match) - 2)); + $match = trim(mb_substr($match, 1, mb_strlen($match) - 2)); } $terms[$matches[1][$key]] = $match; } diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php index 48c9b836f..9292016d6 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php @@ -199,8 +199,6 @@ class AuthorizationHelper implements AuthorizationHelperInterface * if the entity implements Chill\MainBundle\Entity\HasScopeInterface, * the scope is taken into account. * - * @param mixed $entity the entity may also implement HasScopeInterface - * * @return bool true if the user has access */ public function userHasAccess(User $user, mixed $entity, string $attribute) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index a7e178097..a38b7055c 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -788,7 +788,7 @@ class AccompanyingPeriod implements if (self::STEP_DRAFT === $this->getStep()) { return [[self::STEP_DRAFT]]; } - if (str_starts_with($this->getStep(), 'CONFIRM')) { + if (str_starts_with((string) $this->getStep(), 'CONFIRM')) { return [[self::STEP_DRAFT, self::STEP_CONFIRMED]]; } if (self::STEP_CLOSED === $this->getStep()) { diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index 6f22aacc8..c26392eda 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -1787,10 +1787,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI return $this; } - /** - * @param Collection $spokenLanguages - */ - public function setSpokenLanguages($spokenLanguages): self + public function setSpokenLanguages(mixed $spokenLanguages): self { $this->spokenLanguages = $spokenLanguages; diff --git a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php index f59f843ac..13a0e0139 100644 --- a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php @@ -112,8 +112,8 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor $andWhereSearchClause = []; $andWhereSearchClauseArgs = []; - if ('' !== trim($default)) { - foreach (\explode(' ', $default) as $str) { + if ('' !== trim((string) $default)) { + foreach (\explode(' ', (string) $default) as $str) { if ('' === trim($str)) { continue; } diff --git a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php index 721fbcb67..d1ce185d9 100644 --- a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php +++ b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php @@ -686,20 +686,9 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface, \Strin return $this; } - /** - * @return $this - */ - public function setCenters(Collection $centers) + public function setCenters(Collection $centers): self { - foreach ($centers as $center) { - $this->addCenter($center); - } - - foreach ($this->centers as $center) { - if (false === $centers->contains($center)) { - $this->removeCenter($center); - } - } + $this->centers = $centers; return $this; } diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index a087c20d9..633f980c8 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -17,7 +17,7 @@ use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\ListInterface; use PhpParser\Node; -use Rector\Core\Rector\AbstractRector; +use Rector\Rector\AbstractRector; use Rector\Symfony\NodeAnalyzer\ClassAnalyzer; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;