diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml index 2525008..e1ada9c 100644 --- a/.github/workflows/linting.yaml +++ b/.github/workflows/linting.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: ['8.1', '8.2', '8.3', '8.4', '8.5'] + php: ['8.4', '8.5'] name: Linting - PHP ${{ matrix.php }} steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index b7693b2..7bd6a8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## Version 3.0.0 + +Compatibility: requires minimum Kimai 3.0.0 + +- Compatibility with Symfony 7.4 + ## Version 2.22.1 Compatibility: requires minimum Kimai 2.36.0 diff --git a/Command/KimaiImporterCommand.php b/Command/KimaiImporterCommand.php index fae1ee3..f39d5ec 100755 --- a/Command/KimaiImporterCommand.php +++ b/Command/KimaiImporterCommand.php @@ -117,7 +117,7 @@ final class KimaiImporterCommand extends Command * @var array */ private array $activities = []; - private bool $debug = false; + private bool $debug = false; // @phpstan-ignore property.tooWideBool /** * Global activities (either because they were global OR because --global was used). * @@ -596,13 +596,13 @@ private function validateKimai1Data(array $options, array $users, array $custome */ private function checkDatabaseVersion(Connection $connection, SymfonyStyle $io): bool { - $optionColumn = $connection->quoteIdentifier('option'); + $optionColumn = $connection->quoteSingleIdentifier('option'); $qb = $connection->createQueryBuilder(); try { $connection->createQueryBuilder() ->select('1') - ->from($connection->quoteIdentifier($this->dbPrefix . 'configuration')) + ->from($connection->quoteSingleIdentifier($this->dbPrefix . 'configuration')) ->executeQuery(); } catch (Exception $e) { $io->error( @@ -614,7 +614,7 @@ private function checkDatabaseVersion(Connection $connection, SymfonyStyle $io): $version = $connection->createQueryBuilder() ->select('value') - ->from($connection->quoteIdentifier($this->dbPrefix . 'configuration')) + ->from($connection->quoteSingleIdentifier($this->dbPrefix . 'configuration')) ->where($qb->expr()->eq($optionColumn, ':option')) ->setParameter('option', 'version') ->executeQuery() @@ -638,7 +638,7 @@ private function checkDatabaseVersion(Connection $connection, SymfonyStyle $io): $revision = $connection->createQueryBuilder() ->select('value') - ->from($connection->quoteIdentifier($this->dbPrefix . 'configuration')) + ->from($connection->quoteSingleIdentifier($this->dbPrefix . 'configuration')) ->where($qb->expr()->eq($optionColumn, ':option')) ->setParameter('option', 'revision') ->executeQuery() @@ -728,7 +728,7 @@ private function fetchAllFromImport(string $table, array $where = []): array { $query = $this->connection->createQueryBuilder() ->select('*') - ->from($this->connection->quoteIdentifier($this->dbPrefix . $table)); + ->from($this->connection->quoteSingleIdentifier($this->dbPrefix . $table)); foreach ($where as $column => $value) { $query->andWhere($query->expr()->eq($column, $value)); @@ -741,7 +741,7 @@ private function countFromImport(string $table, array $where = []): int { $query = $this->connection->createQueryBuilder() ->select('COUNT(*)') - ->from($this->connection->quoteIdentifier($this->dbPrefix . $table)); + ->from($this->connection->quoteSingleIdentifier($this->dbPrefix . $table)); foreach ($where as $column => $value) { $query->andWhere($query->expr()->eq($column, $value)); @@ -754,7 +754,7 @@ private function fetchIteratorFromImport(string $table): \Traversable { $query = $this->connection->createQueryBuilder() ->select('*') - ->from($this->connection->quoteIdentifier($this->dbPrefix . $table)); + ->from($this->connection->quoteSingleIdentifier($this->dbPrefix . $table)); return $query->executeQuery()->iterateAssociative(); } @@ -2164,7 +2164,7 @@ private function fixEncoding(): void foreach ($columns as $column) { foreach ($searchReplace as $search => $replace) { $query = $this->connection->createQueryBuilder() - ->update($this->dbPrefix . $table, $this->dbPrefix . $table) + ->update($this->dbPrefix . $table) ->set($column, \sprintf('REPLACE(%s, "%s", "%s")', $column, $search, $replace)) ->where($column . ' LIKE "%' . $search . '%"') ; diff --git a/Form/ImportForm.php b/Form/ImportForm.php index 0237117..d74a1cc 100644 --- a/Form/ImportForm.php +++ b/Form/ImportForm.php @@ -26,6 +26,11 @@ class ImportForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { + $maxSize = $options['max_file_size']; + if (!\is_string($maxSize)) { + $maxSize = ImporterService::MAX_FILESIZE; + } + $builder ->add('delimiter', ChoiceType::class, [ 'label' => 'importer.delimiter', @@ -46,16 +51,14 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'help' => 'importer.file_chooser_help', 'help_translation_parameters' => [ '{{rows}}' => $options['max_row_size'], - '{{size}}' => $options['max_file_size'], + '{{size}}' => $maxSize, ], 'attr' => [ 'accept' => 'text/csv,application/json', ], 'constraints' => [ new NotNull(), - new File([ - 'maxSize' => $options['max_file_size'], - ]) + new File(maxSize: $maxSize) ], ]) ; diff --git a/ImportBundle.php b/ImportBundle.php index 08414d8..b0c9ddf 100644 --- a/ImportBundle.php +++ b/ImportBundle.php @@ -22,9 +22,7 @@ class ImportBundle extends Bundle implements PluginInterface // some validator rules that we skip during import, because they are not relevant here // do not use the class name directly, because that would raise the required kimai version - public const SKIP_VALIDATOR_CODES = [ - 'kimai-timesheet-87', 'kimai-timesheet-88', 'kimai-timesheet-89', // timesheet deactivated before 2.0.16 - 'kimai-timesheet-deactivated-activity', 'kimai-timesheet-deactivated-project', 'kimai-timesheet-deactivated-customer', // timesheet deactivated after 2.0.16 + public const array SKIP_VALIDATOR_CODES = [ TimesheetDeactivated::DISABLED_ACTIVITY_ERROR, TimesheetDeactivated::DISABLED_PROJECT_ERROR, TimesheetDeactivated::DISABLED_CUSTOMER_ERROR, // timesheet deactivated current codes TimesheetLockdown::PERIOD_LOCKED, // lockdown is obviously not necessary to check here TimesheetLongRunning::LONG_RUNNING, TimesheetLongRunning::MAXIMUM, TimesheetZeroDuration::ZERO_DURATION_ERROR, // if this was allowed in the past, it should be imported diff --git a/Importer/ImporterService.php b/Importer/ImporterService.php index 1c0b67c..f54fe70 100644 --- a/Importer/ImporterService.php +++ b/Importer/ImporterService.php @@ -17,7 +17,7 @@ use KimaiPlugin\ImportBundle\Model\ImportRow; use League\Csv\Reader; use Psr\Log\LoggerInterface; -use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; +use Symfony\Component\DependencyInjection\Attribute\AutowireIterator; final class ImporterService { @@ -28,7 +28,7 @@ final class ImporterService * @param iterable $importer */ public function __construct( - #[TaggedIterator(ImporterInterface::class)] + #[AutowireIterator(ImporterInterface::class)] private readonly iterable $importer, private readonly EntityManagerInterface $entityManager, private readonly LoggerInterface $logger diff --git a/composer.json b/composer.json index be4daca..6a6d857 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Import data from CSV files via Web UI", "homepage": "https://www.kimai.org/store/keleo-importer-bundle.html", "type": "kimai-plugin", - "version": "2.22.1", + "version": "3.0.0", "keywords": [ "kimai", "kimai-plugin" @@ -17,7 +17,7 @@ ], "extra": { "kimai": { - "require": 23600, + "require": 30000, "name": "Importer" } }, @@ -32,7 +32,7 @@ "symfony/runtime": false }, "platform": { - "php": "8.1.3" + "php": "8.4.4" }, "preferred-install": { "*": "dist" @@ -50,15 +50,16 @@ "@phpstan" ] }, + "minimum-stability": "beta", "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", - "kimai/kimai": "dev-main", + "kimai/kimai": "dev-dev", "phpstan/phpstan": "^2.0", "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-doctrine": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", "phpstan/phpstan-symfony": "^2.0", - "symfony/console": "^6.0", - "symfony/event-dispatcher": "^6.0" + "symfony/console": "^7.0", + "symfony/event-dispatcher": "^7.0" } }