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
This commit is contained in:
Kevin Papst
2022-05-17 11:52:45 +02:00
committed by GitHub
parent 27c60d9fc4
commit 9e2a295182
13 changed files with 122 additions and 60 deletions

View File

@@ -16,6 +16,7 @@
"ext-json": "*",
"ext-mbstring": "*",
"ext-pdo": "*",
"ext-xml": "*",
"ext-xsl": "*",
"ext-zip": "*",
"beberlei/doctrineextensions": "^1.2",

51
composer.lock generated
View File

@@ -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": "*"
},

View File

@@ -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'

View File

@@ -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

View File

@@ -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"
*/

View File

@@ -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'
];
/**

View File

@@ -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++) {

View File

@@ -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([

View File

@@ -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()
;

View File

@@ -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);

View File

@@ -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,
],
];

View File

@@ -90,6 +90,14 @@
<source>label.quick_entry.recent_activities</source>
<target>Anzahl übernommener Einträge aus Vorwochen</target>
</trans-unit>
<trans-unit id="QxQOG3e" resname="label.quick_entry.recent_activity_weeks">
<source>label.quick_entry.recent_activity_weeks</source>
<target>Verwende Einträge aus den letzten X Wochen (leer oder 0 für gesamte Zeit)</target>
</trans-unit>
<trans-unit id="7Efrrn5" resname="label.quick_entry.minimum_rows">
<source>label.quick_entry.minimum_rows</source>
<target>Minimale Anzahl an Zeilen</target>
</trans-unit>
<trans-unit id="iZLna_g" resname="label.theme.autocomplete_chars">
<source>label.theme.autocomplete_chars</source>
<target>Minimale Anzahl Buchstaben für den Start der Autovervollständigung</target>

View File

@@ -90,6 +90,14 @@
<source>label.quick_entry.recent_activities</source>
<target>Number of entries taken over from previous weeks</target>
</trans-unit>
<trans-unit id="QxQOG3e" resname="label.quick_entry.recent_activity_weeks">
<source>label.quick_entry.recent_activity_weeks</source>
<target>Take over entries from the last X weeks (empty or 0 for all time)</target>
</trans-unit>
<trans-unit id="7Efrrn5" resname="label.quick_entry.minimum_rows">
<source>label.quick_entry.minimum_rows</source>
<target>Minimum number of rows</target>
</trans-unit>
<trans-unit id="iZLna_g" resname="label.theme.autocomplete_chars">
<source>label.theme.autocomplete_chars</source>
<target>Minimum number of letters to start auto-completion</target>