heimrichhannot/contao-form-type-bundle

为contao表单生成器添加类型。

0.2.0 2024-09-04 12:39 UTC

This package is auto-updated.

Last update: 2024-09-04 12:40:56 UTC


README

表单类型包是Contao CMS的扩展,提供了一种通用的方式来使用contao表单生成器创建特定方法的表单。它面向开发者,不包含内置的表单类型。

特性

  • 使用contao表单生成器创建特定方法的表单的通用方式
  • 为选择、复选框和单选框表单字段提供选项事件
  • 表单类型可以支持一个首次向导来设置基本表单字段

安装

通过composer安装包,然后更新数据库

composer require heimrichhannot/contao-form-type-bundle

使用方法

创建新的表单类型

创建一个新的类,该类扩展了AbstractFormType。将其注册为服务,并启用自动配置。

可以在$GLOBALS['TL_LANG']['tl_form']['FORMTYPE']中设置标签

# contao/languages/de/tl_form.php
$GLOBALS['TL_LANG']['tl_form']['FORMTYPE']['huh_mediathek'] = 'Mediathek';

首次向导

您可以通过实现getDefaultFields()方法向您的表单类型添加首次向导。它期望以数组格式返回字段定义作为返回值。这些字段将在执行向导时创建。

public function getDefaultFields(FormModel $formModel): array
{
    return [
        [
            'type' => 'text',
            'name' => 'title',
            'label' => $this->translator->trans('tl_example.title.0', [], 'contao_tl_example'),
            'mandatory' => '1',
        ],
        [
            'type' => 'textarea',
            'name' => 'text',
            'label' => $this->translator->trans('tl_example.text.0', [], 'contao_tl_example'),
        ],
    ];
}

表单事件

您可以为表单生命周期中的事件注册事件监听器。这些事件是对相应Contao表单钩子的映射,但只会为特定表单类型触发。

以下事件可用

选项事件

如果您想为选择、复选框或单选框表单字段提供选项,您可以注册事件监听器。事件名称为huh.form_type.<formtype>.<field>.options'

// src/EventListener/OptionsEventListener.php
use HeimrichHannot\FormTypeBundle\Event\FieldOptionsEvent;

class OptionsEventListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            'huh.form_type.huh_media_library.licence.options' => 'onLicenceOptions',
        ];
    }

    public function onLicenceOptions(FieldOptionsEvent $event): void
    {
        $event->addOption('free', 'Free');
        $event->addOption('adobe', 'Adobe');
        $event->addOption('istock', 'iStock');
    }
}

字段选项的统一分发器

使用FieldOptionsDispatcherTrait来分发FieldOptionsEvent huh.form_type.<formtype>.<field>.options和Contao fields.<field>.options回调。

示例

use HeimrichHannot\MediaLibraryBundle\Trait\FieldOptionsDispatcherTrait;

class MyContainerOrFormType
{
    use FieldOptionsDispatcherTrait;

    #[AsCallback(table: 'tl_ml_product', target: 'fields.licence.options')]
    #[AsEventListener('huh.form_type.huh_media_library.licence.options')]
    public function getLicenceOptions(): array
    {
        return $this->dispatchFieldOptions([
            'free' => 'Released for use under indication of copyright',
            'locked' => 'Subject to licence'
        ]);
    }
}

表单上下文

在您的表单类型上实现表单上下文评估器,允许您根据表单的使用上下文改变表单的行为。这可以用来将现有数据加载到表单字段中,例如创建一个编辑表单。

内置的表单编辑上下文

该包内置了一个基本的默认表单上下文评估器,提供编辑功能。只需在您的表单类型中重写DEFAULT_FORM_CONTEXT_TABLE即可允许编辑相应的数据库模型。

protected const DEFAULT_FORM_CONTEXT_TABLE = 'tl_my_table';
  • 在Contao中创建您的表单。
  • 根据您想要编辑的数据库字段命名您的表单字段,例如title用于tl_my_table.title
  • 将查询参数?edit=<id>追加到包含表单的页面URL,以编辑具有主键<id>的现有行。

如果没有设置DEFAULT_FORM_CONTEXT_TABLE,则默认将表单视为创建表单。

创建您自己的表单上下文

要实现自己的表单上下文评估器,在您的表单类型中重写evaluateFormContext()

protected function evaluateFormContext(): FormContext
{
    $request = $this->container->get('request_stack')->getCurrentRequest();
    $editParameter = 'edit';
    $databaseTable = 'tl_my_table';

    if ($modelPk = $request->query->get($editParameter))
    {
        /** @var class-string<Model> $modelClass */
        $modelClass = Model::getClassFromTable($databaseTable);
        $modelInstance = $modelClass::findByPk($modelPk);
        if ($modelInstance === null) {
            return FormContext::invalid($databaseTable, 'Could not find object.');
        }
        return FormContext::update($databaseTable, $modelInstance->row());
    }

    return FormContext::create($databaseTable);
}

示例显示了一个表单上下文评估器的实现,该评估器允许通过查询参数edit提供的键编辑数据库模型。

要检索当前的表单上下文,请调用您的表单类型上的getter。

$formContext = $this->getFormContext();

我们不推荐直接调用$this->evaluateFormContext(),因为这会跳过您这样做时的未来缓存实现。

表单上下文操作

最常用的表单上下文操作已经实现。

use HeimrichHannot\FormTypeBundle\FormType\FormContextAction;

FormContextAction::CREATE;
FormContextAction::READ;
FormContextAction::UPDATE;
FormContextAction::DELETE;
FormContextAction::CLONE;
FormContextAction::INVALID;

FormContextAction::INVALID可用于指示表单不应被处理。

要使用内置操作实例化一个FormContext对象,请使用静态工厂方法

use HeimrichHannot\FormTypeBundle\FormType\FormContext;

$createContext  = FormContext::create('tl_my_table');
$readContext    = FormContext::read('tl_my_table', $data);
$updateContext  = FormContext::update('tl_my_table', $data);
$deleteContext  = FormContext::delete('tl_my_table', $data);

$cloneContext   = FormContext::clone('tl_my_table', $data);

$invalidContext = FormContext::invalid('tl_my_table', 'This is error detail.', $additionalData ?? []);

或者,您也可以使用FormContext构造函数

use HeimrichHannot\FormTypeBundle\FormType\FormContext;
use HeimrichHannot\FormTypeBundle\FormType\FormContextAction;

$formContext = new FormContext(FormContextAction::UPDATE, 'tl_my_table', $data);

然而,在构建 FormContext 对象时,您也可以指定自己的操作,或者通过覆盖现有对象的操作来实现。

use HeimrichHannot\FormTypeBundle\FormType\FormContext;
use HeimrichHannot\FormTypeBundle\FormType\FormContextAction;

$formContext = new FormContext('my_custom_action', 'tl_my_table', $data);
// or
$formContext->setAction('this_can_be_any_string_or_action');
// or
$formContext->setAction(FormContextAction::DELETE);

这样,您就不受内置操作的约束。