Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)
This commit is contained in:
82
src/Form/Extension/ApiFormExtension.php
Normal file
82
src/Form/Extension/ApiFormExtension.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user