Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)

This commit is contained in:
Kevin Papst
2022-12-31 21:19:55 +01:00
committed by GitHub
parent 95e06746bd
commit 90a0fd8a22
2164 changed files with 83700 additions and 86426 deletions

View File

@@ -0,0 +1,82 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Form\Extension;
use App\Form\API\ActivityApiEditForm;
use App\Form\API\ActivityRateApiForm;
use App\Form\API\CustomerApiEditForm;
use App\Form\API\CustomerRateApiForm;
use App\Form\API\ProjectApiEditForm;
use App\Form\API\ProjectRateApiForm;
use App\Form\API\TagApiEditForm;
use App\Form\API\TeamApiEditForm;
use App\Form\API\TimesheetApiEditForm;
use App\Form\API\UserApiCreateForm;
use App\Form\API\UserApiEditForm;
use App\Form\Type\BillableType;
use App\Form\Type\YesNoType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class ApiFormExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
return [
ActivityApiEditForm::class,
ActivityRateApiForm::class,
CustomerApiEditForm::class,
CustomerRateApiForm::class,
ProjectApiEditForm::class,
ProjectRateApiForm::class,
TagApiEditForm::class,
TeamApiEditForm::class,
TimesheetApiEditForm::class,
UserApiCreateForm::class,
UserApiEditForm::class,
];
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if ($builder->has('metaFields')) {
$builder->remove('metaFields');
}
$replaces = [];
foreach ($builder as $child) {
if (\in_array($child->getType()->getInnerType()->getParent(), [CheckboxType::class, BillableType::class, YesNoType::class])) {
$replaces[] = [
'name' => $child->getName(),
'label' => $child->getFormConfig()->getOption('label'),
'required' => $child->getFormConfig()->getRequired(),
];
}
}
foreach ($replaces as $field) {
$builder->remove($field['name']);
$builder->add($field['name'], CheckboxType::class, [
'label' => $field['label'],
'required' => $field['required'],
]);
}
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'csrf_protection' => false,
]);
}
}

View File

@@ -18,7 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Adds a linked help text with the link to the given documentation
*/
class DocumentationLinkExtension extends AbstractTypeExtension
final class DocumentationLinkExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
@@ -30,7 +30,7 @@ class DocumentationLinkExtension extends AbstractTypeExtension
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['docu_chapter'] = $options['docu_chapter'] ?? null;
}
@@ -38,7 +38,7 @@ class DocumentationLinkExtension extends AbstractTypeExtension
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefined(['docu_chapter']);
$resolver->setAllowedTypes('docu_chapter', 'string');

View File

@@ -21,11 +21,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/
final class EnhancedChoiceTypeExtension extends AbstractTypeExtension
{
/**
* @deprecated since 1.7 will be removed with 2.0
*/
public const TYPE_SELECTPICKER = 'selectpicker';
public static function getExtendedTypes(): iterable
{
return [EntityType::class, ChoiceType::class];
@@ -36,7 +31,7 @@ final class EnhancedChoiceTypeExtension extends AbstractTypeExtension
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if (isset($options['selectpicker']) && false === $options['selectpicker']) {
return;
@@ -59,16 +54,13 @@ final class EnhancedChoiceTypeExtension extends AbstractTypeExtension
}
if (false === $options['search']) {
$extendedOptions['data-minimum-results-for-search'] = 'Infinity';
$extendedOptions['data-disable-search'] = 1;
}
$view->vars['attr'] = array_merge($view->vars['attr'], $extendedOptions);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefined(['selectpicker']);
$resolver->setAllowedTypes('selectpicker', 'boolean');

View File

@@ -18,7 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Allows to register custom icons at form fields
*/
class IconExtension extends AbstractTypeExtension
final class IconExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
@@ -30,7 +30,7 @@ class IconExtension extends AbstractTypeExtension
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['icon'] = $options['icon'] ?? null;
}
@@ -38,7 +38,7 @@ class IconExtension extends AbstractTypeExtension
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefined(['icon']);
$resolver->setAllowedTypes('icon', 'string');

View File

@@ -19,19 +19,10 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Support Remote-API calls for Entity select-boxes.
*/
class SelectWithApiDataExtension extends AbstractTypeExtension
final class SelectWithApiDataExtension extends AbstractTypeExtension
{
/**
* @var UrlGeneratorInterface
*/
private $router;
/**
* @param UrlGeneratorInterface $router
*/
public function __construct(UrlGeneratorInterface $router)
public function __construct(private UrlGeneratorInterface $router)
{
$this->router = $router;
}
public static function getExtendedTypes(): iterable
@@ -44,7 +35,7 @@ class SelectWithApiDataExtension extends AbstractTypeExtension
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if (!isset($options['api_data'])) {
return;
@@ -56,6 +47,12 @@ class SelectWithApiDataExtension extends AbstractTypeExtension
throw new \InvalidArgumentException('Option "api_data" must be an array for form "' . $form->getName() . '"');
}
if (isset($apiData['create'])) {
$view->vars['attr'] = array_merge($view->vars['attr'], [
'data-create' => $this->router->generate($apiData['create']),
]);
}
if (!isset($apiData['select'])) {
return;
}
@@ -93,12 +90,15 @@ class SelectWithApiDataExtension extends AbstractTypeExtension
'data-empty-url' => $this->router->generate($apiData['route'], $apiData['empty_route_params']),
]);
}
if (isset($apiData['reload'])) {
$view->vars['attr'] = array_merge($view->vars['attr'], [
'data-reload' => $this->router->generate($apiData['reload']),
]);
}
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefined(['api_data']);
$resolver->setAllowedTypes('api_data', 'array');

View File

@@ -12,30 +12,25 @@ namespace App\Form\Extension;
use App\Form\Helper\ToolbarHelper;
use App\Form\Toolbar\ExportToolbarForm;
use App\Form\Toolbar\InvoiceToolbarForm;
use App\Form\Toolbar\InvoiceToolbarSimpleForm;
use App\Form\Toolbar\TimesheetExportToolbarForm;
use App\Form\Toolbar\TimesheetToolbarForm;
use App\Form\Toolbar\UserToolbarForm;
use App\Reporting\MonthlyUserListForm;
use App\Reporting\WeeklyUserListForm;
use App\Reporting\YearlyUserListForm;
use App\Reporting\MonthlyUserList\MonthlyUserListForm;
use App\Reporting\WeeklyUserList\WeeklyUserListForm;
use App\Reporting\YearlyUserList\YearlyUserListForm;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
final class ToolbarFormExtension extends AbstractTypeExtension
{
private $toolbarHelper;
public function __construct(ToolbarHelper $toolbarHelper)
public function __construct(private ToolbarHelper $toolbarHelper)
{
$this->toolbarHelper = $toolbarHelper;
}
public static function getExtendedTypes(): iterable
{
return [
InvoiceToolbarForm::class,
InvoiceToolbarSimpleForm::class,
ExportToolbarForm::class,
TimesheetToolbarForm::class,
TimesheetExportToolbarForm::class,
@@ -46,7 +41,7 @@ final class ToolbarFormExtension extends AbstractTypeExtension
];
}
public function buildForm(FormBuilderInterface $builder, array $options)
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$this->toolbarHelper->cleanupForm($builder);
}

View File

@@ -17,14 +17,8 @@ use Symfony\Component\Security\Core\Security;
final class UserExtension extends AbstractTypeExtension
{
/**
* @var Security
*/
private $security;
public function __construct(Security $security)
public function __construct(private Security $security)
{
$this->security = $security;
}
public static function getExtendedTypes(): iterable
@@ -32,7 +26,7 @@ final class UserExtension extends AbstractTypeExtension
return [FormType::class];
}
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefined(['user']);
// null needs to be allowed, as there is no user for anonymous forms (like "forgot password" and "registration")