WIP: Implement even more stuff

This commit is contained in:
Björn Fromme committed 2023-10-04 17:54:35 +02:00
1 parent cc1ab396af
commit 96d6170907
31 files changed
+874 -68

No files matched your search

+2
View File
@@ -16,8 +16,10 @@ class ApiClient
{
public const TYPE_NOTIFICATION = 'HINWEIS';
public const TYPE_CUSTOMER_DATA = 'KUNDENKONTO';
public const TYPE_PRODUCTS = 'PRODUKTE';
public const TYPE_BASE_DATA_COUNTRIES = 'STAMMLAENDER';
public const TYPE_BASE_DATA_PICKUPS = 'STAMMZUSTIEGE';
public const TYPE_BASE_DATA_HOTELS = 'STAMMHOTELS';
private array $config;
@@ -8,7 +8,7 @@ use App\BusProNet\Model\Country;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class Countries
class CountryDataProvider
{
public function __construct(private readonly ApiClient $apiClient, private readonly CacheInterface $cache)
{}
@@ -0,0 +1,39 @@
<?php
namespace App\BusProNet\DataProvider;
use App\BusProNet\ApiClient;
use App\BusProNet\ApiClientException;
use App\BusProNet\Model\Hotel;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class HotelDataProvider
{
public function __construct(private readonly ApiClient $apiClient, private readonly CacheInterface $cache)
{}
public function getAll(): array
{
try {
$hotels = $this->cache->get('bpn_hotels', function (ItemInterface $item) {
$item->expiresAfter(3600);
return $this
->apiClient
->getBaseData(ApiClient::TYPE_BASE_DATA_HOTELS)
->getItems()
;
});
} catch (ApiClientException $e) {
$hotels = [];
}
return $hotels;
}
public function get(int $busProId): ?Hotel
{
return $this->getAll()[$busProId] ?? null;
}
}
@@ -8,7 +8,7 @@ use App\BusProNet\Model\Pickup;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class Pickups
class PickupDataProvider
{
public function __construct(private readonly ApiClient $apiClient, private readonly CacheInterface $cache)
{}
@@ -0,0 +1,39 @@
<?php
namespace App\BusProNet\DataProvider;
use App\BusProNet\ApiClient;
use App\BusProNet\ApiClientException;
use App\BusProNet\Model\Product;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class ProductDataProvider
{
public function __construct(private readonly ApiClient $apiClient, private readonly CacheInterface $cache)
{}
public function getAll(): array
{
try {
$products = $this->cache->get('bpn_products', function (ItemInterface $item) {
$item->expiresAfter(3600);
return $this
->apiClient
->getBaseData(ApiClient::TYPE_PRODUCTS)
->getItems()
;
});
} catch (ApiClientException $e) {
$products = [];
}
return $products;
}
public function get(int $busProId): ?Product
{
return $this->getAll()[$busProId] ?? null;
}
}
+2 -8
View File
@@ -4,17 +4,11 @@ namespace App\BusProNet\Model;
class BaseDataResponse
{
private array $items = [];
public function __construct(private readonly array $items)
{}
public function getItems(): array
{
return $this->items;
}
public function setItems(array $items): static
{
$this->items = $items;
return $this;
}
}
+112
View File
@@ -0,0 +1,112 @@
<?php
namespace App\BusProNet\Model;
class Hotel
{
private ?int $id = null;
private ?int $busProId = null;
private ?string $code = null;
private ?string $name = null;
private ?string $city = null;
private ?string $street = null;
private ?string $phone = null;
private ?string $type = null;
public function getId(): ?int
{
return $this->id;
}
public function setId(?int $id): static
{
$this->id = $id;
return $this;
}
public function getBusProId(): ?int
{
return $this->busProId;
}
public function setBusProId(?int $busProId): static
{
$this->busProId = $busProId;
return $this;
}
public function getCode(): ?string
{
return $this->code;
}
public function setCode(?string $code): static
{
$this->code = $code;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(?string $name): static
{
$this->name = $name;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(?string $city): static
{
$this->city = $city;
return $this;
}
public function getStreet(): ?string
{
return $this->street;
}
public function setStreet(?string $street): static
{
$this->street = $street;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(?string $phone): static
{
$this->phone = $phone;
return $this;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(?string $type): static
{
$this->type = $type;
return $this;
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace App\BusProNet\Model;
class Product
{
private ?int $id = null;
private ?string $code = null;
private ?string $name = null;
public function getId(): ?int
{
return $this->id;
}
public function setId(?int $id): static
{
$this->id = $id;
return $this;
}
public function getCode(): ?string
{
return $this->code;
}
public function setCode(?string $code): static
{
$this->code = $code;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(?string $name): static
{
$this->name = $name;
return $this;
}
}
+54 -8
View File
@@ -4,13 +4,15 @@ namespace App\BusProNet;
use App\BusProNet\Model\Address;
use App\BusProNet\Model\BaseDataResponse;
use App\BusProNet\Model\NotificationResponse;
use App\BusProNet\Model\Communication;
use App\BusProNet\Model\Country;
use App\BusProNet\Model\CrmAttribute;
use App\BusProNet\Model\CrmAttributeGroup;
use App\BusProNet\Model\CrmAttributesResponse;
use App\BusProNet\Model\Hotel;
use App\BusProNet\Model\NotificationResponse;
use App\BusProNet\Model\Pickup;
use App\BusProNet\Model\Product;
use App\BusProNet\Model\ProfileResponse;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -55,6 +57,10 @@ class ResponseParser
return $this->createCountriesResponse($xml);
case ApiClient::TYPE_BASE_DATA_PICKUPS:
return $this->createPickupsResponse($xml);
case ApiClient::TYPE_BASE_DATA_HOTELS:
return $this->createHotelsResponse($xml);
case ApiClient::TYPE_PRODUCTS:
return $this->createProductsResponse($xml);
}
throw new ResponseParserException('Unable to parse XML response');
@@ -187,10 +193,7 @@ class ResponseParser
$countries[$token] = $country;
}
$response = new BaseDataResponse();
$response->setItems($countries);
return $response;
return new BaseDataResponse($countries);
}
public function createPickupsResponse(\SimpleXMLElement $xml): BaseDataResponse
@@ -211,10 +214,53 @@ class ResponseParser
$pickups[$busProId] = $pickup;
}
$response = new BaseDataResponse();
$response->setItems($pickups);
return new BaseDataResponse($pickups);
}
return $response;
public function createHotelsResponse(\SimpleXMLElement $xml): BaseDataResponse
{
$hotels = [];
foreach ($xml->xpath('hotel') as $item) {
$id = (int) $item->attributes()['id'];
$busProId = (int) $item->attributes()['idbuspro'];
$hotel = new Hotel();
$hotel
->setId($id)
->setBusProId($busProId)
->setCode((string) $item->attributes()['code'])
->setName($item->xpath('name') ? (string) $item->xpath('name')[0] : null)
->setCity($item->xpath('ort') ? (string) $item->xpath('ort')[0] : null)
->setStreet($item->xpath('strasse') ? (string) $item->xpath('strasse')[0] : null)
->setPhone($item->xpath('telefon') ? (string) $item->xpath('telefon')[0] : null)
->setType($item->xpath('art') ? (string) $item->xpath('art')[0] : null)
;
$hotels[$busProId] = $hotel;
}
return new BaseDataResponse($hotels);
}
public function createProductsResponse(\SimpleXMLElement $xml): BaseDataResponse
{
$products = [];
foreach ($xml->xpath('produkte/produkt') as $item) {
$code = (string) $item->attributes()['code'];
if (true === empty($code)) {
continue;
}
$id = (int) $item->attributes()['id'];
$product = new Product();
$product
->setId($id)
->setName((string) $item->attributes()['bezeichnung'])
->setCode($code)
;
$products[$id] = $product;
}
return new BaseDataResponse($products);
}
private function resolveOptions(array $options): array
@@ -0,0 +1,29 @@
<?php
namespace App\Controller\Admin\Assignment;
use App\Entity\Assignment;
use App\Form\AssignmentType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class CreateController extends AbstractController
{
#[Route('/admin/assignment/create', name: 'app_admin_assignment_create')]
public function index(Request $request): Response
{
$assignment = new Assignment();
$form = $this->createForm(AssignmentType::class, $assignment);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirectToRoute('app_admin_assignment_index');
}
return $this->render('admin/assignment/create.html.twig', [
'form' => $form,
]);
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Controller\Admin\Autocomplete;
use App\BusProNet\DataProvider\HotelDataProvider;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class HotelController extends AbstractController
{
public function __construct(private readonly HotelDataProvider $hotelDataProvider)
{}
#[Route('/admin/autocomplete/hotel', name: 'app_admin_autocomplete_hotel')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Request $request): JsonResponse
{
try {
$query = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$queryString = $query['search'];
} catch (\JsonException $e) {
throw $this->createNotFoundException();
}
$hotels = $this->hotelDataProvider->getAll();
$data = [];
foreach ($hotels as $hotel) {
$name = $hotel->getName();
if (1 === preg_match('/'.preg_quote($queryString, '/').'/i', $name)) {
$data[] = [
'value' => $hotel->getId(),
'text' => sprintf('%s (%s)', $name, $hotel->getCode()),
];
}
}
return $this->json($data);
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Controller\Admin\Autocomplete;
use App\BusProNet\DataProvider\ProductDataProvider;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class ProductController extends AbstractController
{
public function __construct(private readonly ProductDataProvider $productDataProvider)
{}
#[Route('/admin/autocomplete/product', name: 'app_admin_autocomplete_product')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Request $request): JsonResponse
{
try {
$query = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$queryString = $query['search'];
} catch (\JsonException $e) {
throw $this->createNotFoundException();
}
$products = $this->productDataProvider->getAll();
$data = [];
foreach ($products as $product) {
$name = $product->getName();
if (1 === preg_match('/'.preg_quote($queryString, '/').'/i', $name)) {
$data[] = [
'value' => $product->getId(),
'text' => sprintf('%s (%s)', $name, $product->getCode()),
];
}
}
return $this->json($data);
}
}
+53 -8
View File
@@ -25,10 +25,13 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
#[ORM\Column(type: 'string', length: 36, unique: true)]
private string $uuid;
#[ORM\Column(length: 64)]
private ?string $busProCode = null;
#[ORM\Column(nullable: true)]
private ?int $destinationBusProId = null;
#[ORM\Column]
#[ORM\ManyToOne]
private ?JobProfile $jobProfile = null;
#[ORM\Column(nullable: true)]
private ?int $available = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
@@ -37,6 +40,12 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
private ?\DateTimeImmutable $dateTo = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
private ?\DateTimeImmutable $pickupDate = null;
#[ORM\Column(nullable: true)]
private ?int $pickup = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $benefits = null;
@@ -77,14 +86,26 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
return $this->uuid;
}
public function getBusProCode(): ?string
public function getDestinationBusProId(): ?int
{
return $this->busProCode;
return $this->destinationBusProId;
}
public function setBusProCode(string $busProCode): static
public function setDestinationBusProId(?int $destinationBusProId): static
{
$this->busProCode = $busProCode;
$this->destinationBusProId = $destinationBusProId;
return $this;
}
public function getJobProfile(): ?JobProfile
{
return $this->jobProfile;
}
public function setJobProfile(?JobProfile $jobProfile): static
{
$this->jobProfile = $jobProfile;
return $this;
}
@@ -94,7 +115,7 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
return $this->available;
}
public function setAvailable(int $available): static
public function setAvailable(?int $available): static
{
$this->available = $available;
@@ -125,6 +146,30 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
return $this;
}
public function getPickupDate(): ?\DateTimeImmutable
{
return $this->pickupDate;
}
public function setPickupDate(?\DateTimeImmutable $pickupDate): static
{
$this->pickupDate = $pickupDate;
return $this;
}
public function getPickup(): ?int
{
return $this->pickup;
}
public function setPickup(?int $pickup): static
{
$this->pickup = $pickup;
return $this;
}
public function getBenefits(): ?string
{
return $this->benefits;
+70
View File
@@ -0,0 +1,70 @@
<?php
namespace App\Form;
use App\Entity\Assignment;
use App\Entity\Fee;
use App\Entity\JobProfile;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AssignmentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('available', IntegerType::class, [
'label' => 'Anzahl',
'required' => false,
])
->add('destinationBusProId', AutocompleteChoiceType::class, [
'label' => 'Destination',
'endpoint_route' => 'app_admin_autocomplete_hotel',
])
->add('jobProfile', EntityType::class, [
'label' => 'Jobprofil',
'class' => JobProfile::class,
'choice_label' => 'name',
'placeholder' => 'Bitte auswählen',
])
->add('dateFrom', DatepickerType::class, [
'label' => 'Einsatztermin von',
'mode' => 'range',
])
->add('dateTo', DatepickerType::class, [
'label' => 'Einsatztermin bis',
])
->add('pickupDate', DatepickerType::class, [
'label' => 'Busabfahrt',
'required' => false,
])
->add('pickup', BpnPickupType::class, [
'label' => 'Buszustieg',
'required' => false,
'placeholder' => 'Keine Busbegleitung',
])
->add('benefits', TextareaType::class, [
'label' => 'Benefits',
'required' => false,
])
->add('fees', EntityType::class, [
'label' => 'Honorar(e)',
'class' => Fee::class,
'choice_label' => 'name',
'multiple' => true,
'expanded' => true,
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Assignment::class,
]);
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class AutocompleteChoiceType extends AbstractType
{
public function __construct(private readonly UrlGeneratorInterface $urlGenerator)
{
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'endpoint_route' => null,
'choices' => [],
'compound' => false,
'placeholder' => null,
'endpoint_parameters' => [],
'controller_action' => null,
]);
$resolver->setAllowedTypes('choices', 'array');
}
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if ($options['endpoint_route']) {
$view->vars['endpoint_url'] = $this->urlGenerator->generate($options['endpoint_route'], $options['endpoint_parameters']);
} else {
$view->vars['choices'] = $options['choices'];
}
$view->vars['placeholder'] = $options['placeholder'];
$view->vars['initial_label'] = $form->getData();
$view->vars['initial_value'] = $form->getData();
$view->vars['action'] = $options['controller_action'];
}
public function getBlockPrefix(): string
{
return 'autocomplete';
}
}
+81
View File
@@ -0,0 +1,81 @@
<?php
namespace App\Form;
use App\Form\DataTransformer\EntityToIdTransformer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class AutocompleteEntityType extends AbstractType
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly UrlGeneratorInterface $urlGenerator
) {
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$dataTransformer = new EntityToIdTransformer($this->entityManager, $options['class']);
$builder->addModelTransformer($dataTransformer);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired(['class']);
$resolver->setDefaults([
'endpoint_route' => null,
'choices' => [],
'compound' => false,
'label_property' => 'label',
'label_function' => null,
'placeholder' => null,
'endpoint_parameters' => [],
'controller_action' => null,
]);
$resolver->setAllowedTypes('choices', 'array');
$resolver->setAllowedTypes('label_function', ['null', 'callable']);
}
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if ($options['endpoint_route']) {
$view->vars['endpoint_url'] = $this->urlGenerator->generate($options['endpoint_route'], $options['endpoint_parameters']);
} else {
$view->vars['choices'] = $options['choices'];
}
$view->vars['label_property'] = $options['label_property'];
$view->vars['placeholder'] = $options['placeholder'];
$view->vars['initial_label'] = '';
$view->vars['initial_value'] = null;
$view->vars['action'] = $options['controller_action'];
$entity = $form->getData();
if (null !== $entity) {
if (null !== $options['label_function']) {
$labelFunction = $options['label_function'];
$view->vars['initial_label'] = $labelFunction($entity);
} else {
$getter = 'get'.ucfirst($options['label_property']);
if (method_exists($entity, $getter)) {
$view->vars['initial_label'] = $entity->$getter();
}
}
$view->vars['initial_value'] = $entity->getId();
}
}
public function getBlockPrefix(): string
{
return 'autocomplete';
}
}
+2 -2
View File
@@ -2,7 +2,7 @@
namespace App\Form;
use App\BusProNet\DataProvider\Countries;
use App\BusProNet\DataProvider\CountryDataProvider;
use App\Form\ChoiceLoader\BpnCountryChoiceLoader;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\ChoiceList;
@@ -12,7 +12,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class BpnCountryType extends AbstractType
{
public function __construct(private readonly Countries $countries)
public function __construct(private readonly CountryDataProvider $countries)
{}
public function getParent(): string
+2 -2
View File
@@ -2,7 +2,7 @@
namespace App\Form;
use App\BusProNet\DataProvider\Pickups;
use App\BusProNet\DataProvider\PickupDataProvider;
use App\Form\ChoiceLoader\BpnPickupsChoiceLoader;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -10,7 +10,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class BpnPickupType extends AbstractType
{
public function __construct(private readonly Pickups $pickups)
public function __construct(private readonly PickupDataProvider $pickups)
{}
public function getParent(): string
@@ -2,7 +2,7 @@
namespace App\Form\ChoiceLoader;
use App\BusProNet\DataProvider\Countries;
use App\BusProNet\DataProvider\CountryDataProvider;
use App\BusProNet\Model\Country;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
@@ -10,7 +10,7 @@ use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
class BpnCountryChoiceLoader implements ChoiceLoaderInterface
{
public function __construct(private readonly Countries $countries, private readonly string $property)
public function __construct(private readonly CountryDataProvider $countries, private readonly string $property)
{}
public function loadChoiceList(callable $value = null): ChoiceListInterface
@@ -2,7 +2,7 @@
namespace App\Form\ChoiceLoader;
use App\BusProNet\DataProvider\Pickups;
use App\BusProNet\DataProvider\PickupDataProvider;
use App\BusProNet\Model\Pickup;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
@@ -10,7 +10,7 @@ use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
class BpnPickupsChoiceLoader implements ChoiceLoaderInterface
{
public function __construct(private readonly Pickups $pickups)
public function __construct(private readonly PickupDataProvider $pickups)
{}
public function loadChoiceList(callable $value = null): ChoiceListInterface
@@ -0,0 +1,41 @@
<?php
namespace App\Form\ChoiceLoader;
use App\BusProNet\DataProvider\ProductDataProvider;
use App\BusProNet\Model\Product;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
class BpnProductsChoiceLoader implements ChoiceLoaderInterface
{
public function __construct(private readonly ProductDataProvider $products)
{}
public function loadChoiceList(callable $value = null): ChoiceListInterface
{
$choices = [];
/** @var Product[] $products */
$products = $this->products->getAll();
foreach ($products as $product) {
$choices[$product->getName()] = $product->getId();
}
ksort($choices);
return new ArrayChoiceList($choices);
}
public function loadChoicesForValues(array $values, callable $value = null): array
{
return $values;
}
public function loadValuesForChoices(array $choices, callable $value = null): array
{
return $choices;
}
}
+4
View File
@@ -19,10 +19,13 @@ class DatepickerType extends AbstractType
'min_date' => null,
'max_date' => null,
'disable_weekends' => false,
'mode' => 'single', // 'single', 'multiple' or 'range'
]);
$resolver->setAllowedTypes('min_date', ['null', \DateTimeImmutable::class]);
$resolver->setAllowedTypes('max_date', ['null', \DateTimeImmutable::class]);
$resolver->setAllowedTypes('disable_weekends', 'bool');
$resolver->setAllowedTypes('mode', 'string');
$resolver->setAllowedValues('mode', ['single', 'multiple', 'range']);
}
public function buildView(FormView $view, FormInterface $form, array $options): void
@@ -30,6 +33,7 @@ class DatepickerType extends AbstractType
$view->vars['min_date'] = $options['min_date'];
$view->vars['max_date'] = $options['max_date'];
$view->vars['disable_weekends'] = $options['disable_weekends'];
$view->vars['mode'] = $options['mode'];
}
public function getParent(): string
+3 -1
View File
@@ -143,7 +143,9 @@ class AdminMenuBuilder extends AbstractMenuBuilder
$menu->addChild('zurück zur Übersicht', [
'route' => 'app_admin_teamer_index',
'icon' => 'back',
'extras' => [
'icon' => 'back',
],
]);
return $menu;
+7 -7
View File
@@ -2,8 +2,8 @@
namespace App\Twig;
use App\BusProNet\DataProvider\Countries;
use App\BusProNet\DataProvider\Pickups;
use App\BusProNet\DataProvider\CountryDataProvider;
use App\BusProNet\DataProvider\PickupDataProvider;
use App\BusProNet\Model\Country;
use App\Entity\Teamer;
use Carbon\Carbon;
@@ -15,11 +15,11 @@ use Twig\Extra\Intl\IntlExtension;
class AppRuntime implements RuntimeExtensionInterface
{
public function __construct(
private readonly RequestStack $requestStack,
private readonly IntlExtension $intlExtension,
private readonly Countries $countries,
private readonly Pickups $pickups,
private readonly string $environment
private readonly RequestStack $requestStack,
private readonly IntlExtension $intlExtension,
private readonly CountryDataProvider $countries,
private readonly PickupDataProvider $pickups,
private readonly string $environment
) {
}