digipolisgent / setting-bundle
Requires
- php: >=7.1
- doctrine/doctrine-fixtures-bundle: ^3.0
- doctrine/orm: ^2.5
- symfony/config: ^5.0
- symfony/dependency-injection: ^5.0
- symfony/doctrine-bridge: ^5.3
- symfony/event-dispatcher: ^5.0
- symfony/form: ^5.0
- symfony/http-kernel: ^5.0
- symfony/uid: ^5.3
- symfony/validator: ^5.0
- symfony/yaml: ^5.0
Requires (Dev)
- phpunit/phpunit: ^9.0
- squizlabs/php_codesniffer: ^3.2
This package is auto-updated.
Last update: 2024-08-28 10:13:58 UTC
README
简介
这个库允许你为预定义实体类型的实例添加额外值。这些额外值及其特性由其他使用数据提供者的束动态定义。基于这些提供者,你的表单将自动构建并执行必要的验证。保存后,这些值(字符串、整数、数组集合等)可以通过我们在这个束中提供的服务轻松访问,以便在整个项目中使用。
兼容性
此束与所有 Symfony ^5.0 版本兼容。
安装
您可以使用 composer 在现有的 symfony 项目中安装此束。
composer require digipolisgent/setting-bundle
有关如何安装 symfony 束的更多信息,请参阅关于束的 Symfony 文档
没有要注册的路由或其他强制配置选项。
在阅读此文档之前
如果您不熟悉 symfony,我们建议您阅读Symfony 5 文档。
实体类型
实体类型是我们想要为其分配额外值的实体。我们通过使用 SettingImplementationTrait 定义这些类型。这还要求实现 getSettingImplementationName
方法。我们使用此名称来访问实体类型。
<?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use DigipolisGent\SettingBundle\Entity\Traits\SettingImplementationTrait; /** * @ORM\Entity() */ class Foo { /** * @ORM\Id * @ORM\Column(type="guid") * @ORM\GeneratedValue(strategy="UUID") */ protected $id; /** * Get id * * @return integer */ public function getId() { return $this->id; } use SettingImplementationTrait; /** * @return string */ public static function getSettingImplementationName() { return 'foo'; } }
特质的操作包括:
- 确保使用
DynamicSettingImplementationRelationSubscriber
更新数据库 - 向数据库添加
SettingEntityType
实体 - 可以使用
DataValueService
向实体添加额外数据 - 如果使用此特质设置的数据是实体,则
FormService
会添加并处理额外的配置
字段类型
这些服务将定义额外配置的字段在表单中的行为以及我们在整个应用程序中使用数据时的数据表示。
服务需要扩展自 AbstractFieldType
。例如,我们使用预定义的字段类型之一作为示例。
<?php namespace DigipolisGent\SettingBundle\FieldType; use Symfony\Component\Form\Extension\Core\Type\TextType; /** * Class StringFieldType * @package DigipolisGent\SettingBundle\FieldType */ class StringFieldType extends AbstractFieldType { /** * @return string */ public static function getName(): string { return 'string'; } /** * @return string */ public function getFormType(): string { return TextType::class; } /** * @param $value * @return array */ public function getOptions($value): array { $options = []; $options['attr']['value'] = $value ? $value : ''; return $options; } /** * @param $value * @return mixed */ public function decodeValue($value) { return $value; } /** * @param $value * @return string */ public function encodeValue($value): string { return $value; } }
这里重要的是我们给服务起的名字。我们将在以后使用此名称为之前使用的实体类型的实例添加额外的配置。
一旦字段类型就位,我们定义服务并将其标记为 field_type
services: _defaults: autowire: true autoconfigure: true public: true DigipolisGent\SettingBundle\FieldType\StringFieldType: tags: - { name: field_type}
数据类型
数据类型是您为每个实体类型想要添加的额外设置的表示。您可以通过添加 DataTypeProvider
来定义这些数据类型。这些数据类型提供者必须使用 data_type_provider
标签注册为标记服务,并实现 DataTypeProviderInterface
。
<?php namespace AppBundle\Provider; use DigipolisGent\SettingBundle\Provider\DataTypeProviderInterface; class DataTypeProvider implements DataTypeProviderInterface { /** * @return array */ public function getDataTypes() { return [ [ 'key' => 'bar', 'label' => 'My foo label', 'required' => true, 'field_type' => 'foo', 'entity_types' => ['foo'], ], ]; } }
所有键都会被检查
- 键:这是您在以后需要时可以访问额外设置的键
- 标签:这是在表单中使用的标签
- 字段类型:这是之前定义的字段类型的名称
- 实体类型:这是一份所有您想要此设置可用的实体类型名称的列表
加载数据类型和实体类型
为了使更改生效,数据库需要更新。以下命令将填充数据库。
bin/console doctrine:fixtures:load --append
表单构建
您可以通过为表单构建器添加事件订阅者来添加这些额外设置。该订阅者将确保表单按照字段类型定义的方式构建和处理。如果设置到表单中的数据不是实体类型,则不会发生任何操作。这样您还可以在通用表单中使用订阅者。
<?php namespace AppBundle\Form\Type; use DigipolisGent\SettingBundle\EventListener\SettingFormListener; use DigipolisGent\SettingBundle\Service\FormService; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\AbstractType; class YourFormType extends AbstractType { public $formService; /** * @param FormService $formService */ public function setFormService(FormService $formService) { $this->formService = $formService; } /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { parent::buildForm($builder, $options); $builder->addEventSubscriber(new SettingFormListener($this->formService)); } }
数据值服务
要在其他脚本中访问这些值,我们可以使用 DataValueService
。
例如,如果您想从之前使用表单保存的 foo
类实例中获取键为 bar
的值,您可以这样做。
$value = $this->dataValueService->getValue($foo, 'bar');
如果在某些数据处理之后您想更新此值并在表单中使其可见,您还可以存储该值。
$this->dataValueService->storeValue($foo, 'bar', 'manipulated string');
高级字段类型使用
您还可以使用字段类型来存储和处理实体,因为您可以在其中注入其他服务。这是一个示例,其中我们创建了一个 bar
实体的复选框列表。
<?php namespace AppBundle\FieldType; use AppBundle\Entity\Bar; use AppBundle\Form\Type\BarFormType; use DigipolisGent\SettingBundle\Entity\SettingDataValue; use DigipolisGent\SettingBundle\FieldType\AbstractFieldType; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Form\Extension\Core\Type\CollectionType; class BarCheckboxFieldType extends AbstractFieldType { private $entityManager; public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } public function getFormType(): string { return CollectionType::class; } /** * @param $value * @return array */ public function getOptions($value): array { $options = []; $options['entry_type'] = BarFormType::class; $options['allow_add'] = true; $options['allow_delete'] = true; $options['by_reference'] = false; $options['prototype'] = true; $options['prototype_data'] = new Bar(); $ids = json_decode($value, true); $barRepository = $this->entityManager->getRepository(Bar::class); $data = []; if (!is_null($ids)) { foreach ($ids as $id) { $data[] = $barRepository->find($id); } } $options['data'] = $data; return $options; } /** * @return string */ public static function getName(): string { return 'bar_checkbox'; } /** * @param $value * @return string */ public function encodeValue($value): string { $barIds = []; foreach ($value as $bar) { $this->entityManager->persist($bar); $capistranoSymlinkIds[] = $bar->getId(); } return json_encode($barIds); } public function decodeValue($value) { $barRepository = $this->entityManager->getRepository(Bar::class); $ids = []; if ($value == '' || is_null($ids)) { return []; } $bars = []; $ids = json_decode($value, true); foreach ($ids as $id) { $bars[] = $barRepository->find($id); } return $bars; } }
在您的数据类型提供者中将 bar_checkbox
作为字段类型使用将
- 在生成表单时提供一个包含所有
bar
实体的复选框列表 DataValueService
中的getValue
函数会为您提供Bar
实体的列表DataValueService
中的storeValue
函数让您有机会保存Bar
实体的列表
优点
- 您可以为实体添加额外的属性,这些属性可以在激活或停用套餐时出现或消失。
- 字段类型提供了重复使用代码的多种可能性。
- 通过更改 dataprovider 数组,您可以在几秒钟内更改结构