Formularbuilder erweitern - RevisionTen/cms GitHub Wiki

Hier am Bespiel einer Planeten-Auswahl beschrieben wie man den Formularbuilder um neue Feldtypen ("Items") erweitert.

Feldtypen dürfen genau wie normale Symfony FormTypes auch Services sein und implementieren auch das normale FormTypeInterface.

forms:
    item_types:
        
        [...]

        PlanetItem:
            class: App\Form\Items\PlanetItem
            icon: 'fa-globe'

src/Form/Planet.php

<?php

declare(strict_types=1);

namespace App\Form;

class Planet
{
    public int $id;
    public string $label;
    public int $durchmesser;

    public function __construct(int $id, string $label, int $durchmesser)
    {
        $this->id = $id;
        $this->label = $label;
        $this->durchmesser = $durchmesser;
    }

    public function __toString()
    {
        return $this->label;
    }
}

src/Form/Items/PlanetItem.php

<?php

declare(strict_types=1);

namespace App\Form\Items;

use App\Form\Planet;
use RevisionTen\Forms\Form\Items\Item;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;

class PlanetItem extends Item
{
    /**
     * Diese Methode erstellt das Formular für die Optionen dieses Feld-Typen.
     *
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        parent::buildForm($builder, $options);

        $builder->add('inklusivePluto', CheckboxType::class, [
            'label' => 'Pluto ist auch ein Planet',
        ]);
    }


    /**
     * Diese Methode erstellt Frontend-Formular welches der Besucher sieht.
     *
     * {@inheritdoc}
     */
    public function buildItem(FormBuilderInterface $builder, array $itemOptions): void
    {
        $options = [
            'label' => !empty($itemOptions['hideLabel']) ? false : $itemOptions['label'],
            'required' => $itemOptions['required'],
            'compound' => false,
            'choice_label' => static function(Planet $planet) {
                return $planet->label;
            },
            'choice_value' => 'id',
            'choices' => [
                new Planet(1, 'Erde', 12756),
                new Planet(2, 'Mars', 6792),
                new Planet(3, 'Jupiter', 142984),
            ],
        ];

        if ($itemOptions['inklusivePluto']) {
            $options['choices'][] = new Planet(4, 'Pluto', 2374);
        }

        $builder->add($itemOptions['name'], ChoiceType::class, $options);
    }

    /**
     * Diese Methode beschreibt welche Twig-Variablen im Email-Template verfügbar sind.
     *
     * {@inheritdoc}
     */
    public static function getVariables(array $item): array
    {
        return [
            $item['name'].'.label',
            $item['name'].'.id',
            $item['name'].'.durchmesser',
        ];
    }
}