Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/linting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
18 changes: 9 additions & 9 deletions Command/KimaiImporterCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ final class KimaiImporterCommand extends Command
* @var array<Activity[]>
*/
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).
*
Expand Down Expand Up @@ -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(
Expand All @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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();
}
Expand Down Expand Up @@ -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 . '%"')
;
Expand Down
11 changes: 7 additions & 4 deletions Form/ImportForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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)
],
])
;
Expand Down
4 changes: 1 addition & 3 deletions ImportBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Importer/ImporterService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -28,7 +28,7 @@ final class ImporterService
* @param iterable<ImporterInterface> $importer
*/
public function __construct(
#[TaggedIterator(ImporterInterface::class)]
#[AutowireIterator(ImporterInterface::class)]
private readonly iterable $importer,
private readonly EntityManagerInterface $entityManager,
private readonly LoggerInterface $logger
Expand Down
13 changes: 7 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -17,7 +17,7 @@
],
"extra": {
"kimai": {
"require": 23600,
"require": 30000,
"name": "Importer"
}
},
Expand All @@ -32,7 +32,7 @@
"symfony/runtime": false
},
"platform": {
"php": "8.1.3"
"php": "8.4.4"
},
"preferred-install": {
"*": "dist"
Expand All @@ -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"
}
}