From 9e2a295182a0a3ea01e29b96312ff98d4c770e93 Mon Sep 17 00:00:00 2001 From: Kevin Papst Date: Tue, 17 May 2022 11:52:45 +0200 Subject: [PATCH] Release 1.19.8 (#3296) * unify extension check * fix updating one config section redirects to all sections * weekly times: configure number of weeks for recent activities * weekly times: configure minimum number of rows * added explicit formats for en_GB and pt --- composer.json | 1 + composer.lock | 51 ++++++++++--------- config/packages/kimai.yaml | 10 +++- config/services.yaml | 2 +- src/Constants.php | 4 +- src/Controller/DoctorController.php | 5 +- src/Controller/QuickEntryController.php | 10 +++- .../SystemConfigurationController.php | 43 ++++++++++++---- src/DependencyInjection/Configuration.php | 6 +++ .../SystemConfigurationControllerTest.php | 30 +++++------ .../DependencyInjection/ConfigurationTest.php | 4 +- translations/system-configuration.de.xlf | 8 +++ translations/system-configuration.en.xlf | 8 +++ 13 files changed, 122 insertions(+), 60 deletions(-) diff --git a/composer.json b/composer.json index e4e3706f..2d1193a6 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "ext-json": "*", "ext-mbstring": "*", "ext-pdo": "*", + "ext-xml": "*", "ext-xsl": "*", "ext-zip": "*", "beberlei/doctrineextensions": "^1.2", diff --git a/composer.lock b/composer.lock index 9f61dfb2..e43d9fa7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1b9dd5a62d735ab920ce887fd95e2913", + "content-hash": "e49b6d7813734f458c32176aa129f251", "packages": [ { "name": "beberlei/doctrineextensions", @@ -1404,16 +1404,16 @@ }, { "name": "doctrine/persistence", - "version": "2.5.2", + "version": "2.5.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "4276c6cbc0ca692c190f650a2678623bf04af2d2" + "reference": "d7edf274b6d35ad82328e223439cc2bb2f92bd9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/4276c6cbc0ca692c190f650a2678623bf04af2d2", - "reference": "4276c6cbc0ca692c190f650a2678623bf04af2d2", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/d7edf274b6d35ad82328e223439cc2bb2f92bd9e", + "reference": "d7edf274b6d35ad82328e223439cc2bb2f92bd9e", "shasum": "" }, "require": { @@ -1486,7 +1486,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/2.5.2" + "source": "https://github.com/doctrine/persistence/tree/2.5.3" }, "funding": [ { @@ -1502,7 +1502,7 @@ "type": "tidelift" } ], - "time": "2022-05-02T17:29:02+00:00" + "time": "2022-05-03T09:16:53+00:00" }, { "name": "doctrine/sql-formatter", @@ -1770,16 +1770,16 @@ }, { "name": "friendsofphp/proxy-manager-lts", - "version": "v1.0.11", + "version": "v1.0.12", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/proxy-manager-lts.git", - "reference": "d1eadf86d5b843c496614ef075a8f655a880f1d8" + "reference": "8419f0158715b30d4b99a5bd37c6a39671994ad7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/d1eadf86d5b843c496614ef075a8f655a880f1d8", - "reference": "d1eadf86d5b843c496614ef075a8f655a880f1d8", + "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/8419f0158715b30d4b99a5bd37c6a39671994ad7", + "reference": "8419f0158715b30d4b99a5bd37c6a39671994ad7", "shasum": "" }, "require": { @@ -1836,7 +1836,7 @@ ], "support": { "issues": "https://github.com/FriendsOfPHP/proxy-manager-lts/issues", - "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.11" + "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.12" }, "funding": [ { @@ -1848,7 +1848,7 @@ "type": "tidelift" } ], - "time": "2022-05-04T11:03:58+00:00" + "time": "2022-05-05T09:31:05+00:00" }, { "name": "friendsofsymfony/rest-bundle", @@ -4201,16 +4201,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6cafed9212aa56aaa3aaf3b67c0fd1e5de53f50c" + "reference": "981cc368a216c988e862a75e526b6076987d1b50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6cafed9212aa56aaa3aaf3b67c0fd1e5de53f50c", - "reference": "6cafed9212aa56aaa3aaf3b67c0fd1e5de53f50c", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", + "reference": "981cc368a216c988e862a75e526b6076987d1b50", "shasum": "" }, "require": { @@ -4239,9 +4239,9 @@ "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.5.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.5.1" }, - "time": "2022-05-04T07:46:54+00:00" + "time": "2022-05-05T11:32:40+00:00" }, { "name": "psr/cache", @@ -11852,16 +11852,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.6.5", + "version": "1.6.7", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "462f7651f3454f280d6a397be3290634ab937022" + "reference": "d41c39cb2e487663bce9bbd97c660e244b73abad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/462f7651f3454f280d6a397be3290634ab937022", - "reference": "462f7651f3454f280d6a397be3290634ab937022", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d41c39cb2e487663bce9bbd97c660e244b73abad", + "reference": "d41c39cb2e487663bce9bbd97c660e244b73abad", "shasum": "" }, "require": { @@ -11887,7 +11887,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.6.5" + "source": "https://github.com/phpstan/phpstan/tree/1.6.7" }, "funding": [ { @@ -11907,7 +11907,7 @@ "type": "tidelift" } ], - "time": "2022-05-04T10:49:26+00:00" + "time": "2022-05-04T22:55:41+00:00" }, { "name": "phpstan/phpstan-doctrine", @@ -14077,6 +14077,7 @@ "ext-json": "*", "ext-mbstring": "*", "ext-pdo": "*", + "ext-xml": "*", "ext-xsl": "*", "ext-zip": "*" }, diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml index 42703db2..d3ba4d08 100644 --- a/config/packages/kimai.yaml +++ b/config/packages/kimai.yaml @@ -37,7 +37,7 @@ kimai: # mode: default # The default time to pre-fill the "create timesheet" form (in some cases). - # This setting is only respected by some timetracking modes and not in all situations. + # This setting is only respected by some time-tracking modes and not in all situations. # # Accepted formats, see # - https://www.php.net/manual/en/datetime.formats.php @@ -244,6 +244,10 @@ kimai: date: 'Y-m-d' date_time: 'm-d H:i' duration: '%%h:%%m h' + en_GB: + date_type: 'dd/MM/yyyy' + date: 'd-m-Y' + date_time: 'd-m H:i' es: date_type: 'dd.MM.yyyy' date: 'd.m.Y' @@ -275,6 +279,10 @@ kimai: date: 'd.m.Y' date_time: 'd.m. H:i' duration: '%%hu%%m' + pt: + date_type: 'dd/MM/yyyy' + date: 'd/m/Y' + date_time: 'd-m H:i' pt_BR: date_type: 'dd-MM-yyyy' date: 'd-m-Y' diff --git a/config/services.yaml b/config/services.yaml index 41993017..8c006e82 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -2,7 +2,7 @@ # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: locale: en - app_locales: ar|cs|da|de|de_AT|de_CH|el|en|eo|es|eu|fa|fi|fo|fr|he|hr|hu|it|ja|ko|nb_NO|nl|pl|pt|pt_BR|ro|ru|sk|sv|tr|vi|zh_CN + app_locales: ar|cs|da|de|de_AT|de_CH|el|en|en_GB|eo|es|eu|fa|fi|fo|fr|he|hr|hu|it|ja|ko|nb_NO|nl|pl|pt|pt_BR|ro|ru|sk|sv|tr|vi|zh_CN services: # default configuration for services in *this* file diff --git a/src/Constants.php b/src/Constants.php index 8f5902f6..30992226 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -17,11 +17,11 @@ class Constants /** * The current release version */ - public const VERSION = '1.19.7'; + public const VERSION = '1.19.8'; /** * The current release: major * 10000 + minor * 100 + patch */ - public const VERSION_ID = 11907; + public const VERSION_ID = 11908; /** * The current release status, either "stable" or "dev" */ diff --git a/src/Controller/DoctorController.php b/src/Controller/DoctorController.php index bc84740a..a2f7f74a 100644 --- a/src/Controller/DoctorController.php +++ b/src/Controller/DoctorController.php @@ -29,13 +29,14 @@ class DoctorController extends AbstractController * Some are not a hard requiremenet, but some functions might not work as expected. */ public const REQUIRED_EXTENSIONS = [ + 'gd', 'intl', 'json', 'mbstring', 'pdo', + 'xml', + 'xsl', 'zip', - 'gd', - 'xml' ]; /** diff --git a/src/Controller/QuickEntryController.php b/src/Controller/QuickEntryController.php index 727f970f..20cd6f72 100644 --- a/src/Controller/QuickEntryController.php +++ b/src/Controller/QuickEntryController.php @@ -99,7 +99,13 @@ class QuickEntryController extends AbstractController // attach recent activities $amount = $this->configuration->getQuickEntriesRecentAmount(); - $timesheets = $this->repository->getRecentActivities($this->getUser(), null, $amount); + $startFrom = null; + $takeOverWeeks = $this->configuration->find('quick_entry.recent_activity_weeks'); + if ($takeOverWeeks !== null && \intval($takeOverWeeks) > 0) { + $startFrom = clone $startWeek; + $startFrom->modify(sprintf('-%s weeks', $takeOverWeeks)); + } + $timesheets = $this->repository->getRecentActivities($this->getUser(), $startFrom, $amount); foreach ($timesheets as $timesheet) { $id = $timesheet->getProject()->getId() . '_' . $timesheet->getActivity()->getId(); if (\array_key_exists($id, $rows)) { @@ -145,7 +151,7 @@ class QuickEntryController extends AbstractController } // add empty rows for simpler starting - $minRows = 3; + $minRows = \intval($this->configuration->find('quick_entry.minimum_rows')); if (\count($models) < $minRows) { $newRows = $minRows - \count($models); for ($a = 0; $a < $newRows; $a++) { diff --git a/src/Controller/SystemConfigurationController.php b/src/Controller/SystemConfigurationController.php index 0d26fd07..9251a9d8 100644 --- a/src/Controller/SystemConfigurationController.php +++ b/src/Controller/SystemConfigurationController.php @@ -42,6 +42,7 @@ use Symfony\Component\Form\Extension\Core\Type\CountryType; use Symfony\Component\Form\Extension\Core\Type\CurrencyType; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -114,7 +115,7 @@ final class SystemConfigurationController extends AbstractController $configurations[] = [ 'model' => $configModel, - 'form' => $this->createConfigurationsForm($configModel)->createView(), + 'form' => $this->createConfigurationsForm($configModel, true)->createView(), ]; } @@ -124,13 +125,14 @@ final class SystemConfigurationController extends AbstractController } /** - * @Route(path="/update/{section}", name="system_configuration_update", methods={"POST"}) + * @Route(path="/update/{section}/{single}", name="system_configuration_update", methods={"POST"}) * + * @internal do not link directly to this route * @param Request $request * @param string $section * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response */ - public function configUpdate(Request $request, string $section) + public function configUpdate(Request $request, string $section, bool $single) { $configModel = null; $configSettings = $this->getInitializedConfigurations(); @@ -145,7 +147,7 @@ final class SystemConfigurationController extends AbstractController throw $this->createNotFoundException('Could not find config model: ' . $section); } - $form = $this->createConfigurationsForm($configModel); + $form = $this->createConfigurationsForm($configModel, $single); $form->handleRequest($request); if ($form->isSubmitted()) { @@ -157,6 +159,10 @@ final class SystemConfigurationController extends AbstractController $this->flashUpdateException($ex); } + if ($single) { + return $this->redirectToRoute('system_configuration_section', ['section' => $section]); + } + return $this->redirectToRoute('system_configuration'); } else { $this->flashError('action.update.error', ['%reason%' => 'Validation problem']); @@ -167,8 +173,12 @@ final class SystemConfigurationController extends AbstractController $configurations = []; foreach ($configSettings as $configModel) { + if ($single && $section !== $configModel->getSection()) { + continue; + } + if ($section !== $configModel->getSection()) { - $form2 = $this->createConfigurationsForm($configModel); + $form2 = $this->createConfigurationsForm($configModel, $single); } else { $form2 = $form; } @@ -183,14 +193,10 @@ final class SystemConfigurationController extends AbstractController ]); } - /** - * @param SystemConfigurationModel $configuration - * @return \Symfony\Component\Form\FormInterface - */ - private function createConfigurationsForm(SystemConfigurationModel $configuration) + private function createConfigurationsForm(SystemConfigurationModel $configuration, bool $isSingleSection = false): FormInterface { $options = [ - 'action' => $this->generateUrl('system_configuration_update', ['section' => $configuration->getSection()]), + 'action' => $this->generateUrl('system_configuration_update', ['section' => $configuration->getSection(), 'single' => $isSingleSection ? '1' : '0']), 'method' => 'POST', ]; @@ -401,6 +407,21 @@ final class SystemConfigurationController extends AbstractController ->setConstraints([ new Range(['min' => 0, 'max' => 20]), ]), + (new Configuration()) + ->setName('quick_entry.recent_activity_weeks') + ->setType(IntegerType::class) + ->setTranslationDomain('system-configuration') + ->setRequired(false) + ->setConstraints([ + new Range(['min' => 0, 'max' => 20]), + ]), + (new Configuration()) + ->setName('quick_entry.minimum_rows') + ->setType(IntegerType::class) + ->setTranslationDomain('system-configuration') + ->setConstraints([ + new Range(['min' => 1, 'max' => 5]), + ]), ]), (new SystemConfigurationModel('lockdown_period')) ->setConfiguration([ diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index a6e632ba..d6f6e33c 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -88,6 +88,12 @@ class Configuration implements ConfigurationInterface ->integerNode('recent_activities') ->defaultValue(5) ->end() + ->integerNode('recent_activity_weeks') + ->defaultNull() + ->end() + ->integerNode('minimum_rows') + ->defaultValue(3) + ->end() ->end() ; diff --git a/tests/Controller/SystemConfigurationControllerTest.php b/tests/Controller/SystemConfigurationControllerTest.php index 418005af..7cdf7044 100644 --- a/tests/Controller/SystemConfigurationControllerTest.php +++ b/tests/Controller/SystemConfigurationControllerTest.php @@ -69,19 +69,19 @@ class SystemConfigurationControllerTest extends ControllerBaseTest public function getTestDataForms() { return [ - ['form[name=system_configuration_form_timesheet]', $this->createUrl('/admin/system-config/update/timesheet')], - ['form[name=system_configuration_form_quick_entry]', $this->createUrl('/admin/system-config/update/quick_entry')], - ['form[name=system_configuration_form_lockdown_period]', $this->createUrl('/admin/system-config/update/lockdown_period')], - ['form[name=system_configuration_form_invoice]', $this->createUrl('/admin/system-config/update/invoice')], - ['form[name=system_configuration_form_authentication]', $this->createUrl('/admin/system-config/update/authentication')], - ['form[name=system_configuration_form_rounding]', $this->createUrl('/admin/system-config/update/rounding')], - ['form[name=system_configuration_form_customer]', $this->createUrl('/admin/system-config/update/customer')], - ['form[name=system_configuration_form_project]', $this->createUrl('/admin/system-config/update/project')], - ['form[name=system_configuration_form_activity]', $this->createUrl('/admin/system-config/update/activity')], - ['form[name=system_configuration_form_user]', $this->createUrl('/admin/system-config/update/user')], - ['form[name=system_configuration_form_theme]', $this->createUrl('/admin/system-config/update/theme')], - ['form[name=system_configuration_form_calendar]', $this->createUrl('/admin/system-config/update/calendar')], - ['form[name=system_configuration_form_branding]', $this->createUrl('/admin/system-config/update/branding')], + ['form[name=system_configuration_form_timesheet]', $this->createUrl('/admin/system-config/update/timesheet/0')], + ['form[name=system_configuration_form_quick_entry]', $this->createUrl('/admin/system-config/update/quick_entry/0')], + ['form[name=system_configuration_form_lockdown_period]', $this->createUrl('/admin/system-config/update/lockdown_period/0')], + ['form[name=system_configuration_form_invoice]', $this->createUrl('/admin/system-config/update/invoice/0')], + ['form[name=system_configuration_form_authentication]', $this->createUrl('/admin/system-config/update/authentication/0')], + ['form[name=system_configuration_form_rounding]', $this->createUrl('/admin/system-config/update/rounding/0')], + ['form[name=system_configuration_form_customer]', $this->createUrl('/admin/system-config/update/customer/0')], + ['form[name=system_configuration_form_project]', $this->createUrl('/admin/system-config/update/project/0')], + ['form[name=system_configuration_form_activity]', $this->createUrl('/admin/system-config/update/activity/0')], + ['form[name=system_configuration_form_user]', $this->createUrl('/admin/system-config/update/user/0')], + ['form[name=system_configuration_form_theme]', $this->createUrl('/admin/system-config/update/theme/0')], + ['form[name=system_configuration_form_calendar]', $this->createUrl('/admin/system-config/update/calendar/0')], + ['form[name=system_configuration_form_branding]', $this->createUrl('/admin/system-config/update/branding/0')], ]; } @@ -220,7 +220,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest public function testUpdateUserConfig() { $client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN); - $this->assertAccessIsGranted($client, '/admin/system-config/'); + $this->assertAccessIsGranted($client, '/admin/system-config/edit/user'); $configService = static::$kernel->getContainer()->get(SystemConfiguration::class); $this->assertNull($configService->find('defaults.user.timezone')); @@ -238,7 +238,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest ] ]); - $this->assertIsRedirect($client, $this->createUrl('/admin/system-config/')); + $this->assertIsRedirect($client, $this->createUrl('/admin/system-config/edit/user')); $client->followRedirect(); $this->assertTrue($client->getResponse()->isSuccessful()); $this->assertHasFlashSaveSuccess($client); diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index eda2a615..e751f218 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -463,7 +463,9 @@ class ConfigurationTest extends TestCase 'financial_year' => null, ], 'quick_entry' => [ - 'recent_activities' => 5 + 'recent_activities' => 5, + 'recent_activity_weeks' => null, + 'minimum_rows' => 3, ], ]; diff --git a/translations/system-configuration.de.xlf b/translations/system-configuration.de.xlf index f6d514f5..a5dcec13 100644 --- a/translations/system-configuration.de.xlf +++ b/translations/system-configuration.de.xlf @@ -90,6 +90,14 @@ label.quick_entry.recent_activities Anzahl übernommener Einträge aus Vorwochen + + label.quick_entry.recent_activity_weeks + Verwende Einträge aus den letzten X Wochen (leer oder 0 für gesamte Zeit) + + + label.quick_entry.minimum_rows + Minimale Anzahl an Zeilen + label.theme.autocomplete_chars Minimale Anzahl Buchstaben für den Start der Autovervollständigung diff --git a/translations/system-configuration.en.xlf b/translations/system-configuration.en.xlf index 6da63d24..5052cbff 100644 --- a/translations/system-configuration.en.xlf +++ b/translations/system-configuration.en.xlf @@ -90,6 +90,14 @@ label.quick_entry.recent_activities Number of entries taken over from previous weeks + + label.quick_entry.recent_activity_weeks + Take over entries from the last X weeks (empty or 0 for all time) + + + label.quick_entry.minimum_rows + Minimum number of rows + label.theme.autocomplete_chars Minimum number of letters to start auto-completion