Я действительно запутался в своем фильтре форм.
Мой тестовый проект содержит 2 модели.
class Category extends AbstractEntity
{
use Nameable; // just property name and getter and setter
/**
* @var boolean
* @ORM\Column(name="issue", type="boolean")
*/
private $issue;
/**
* @var Collection|ArrayCollection|Entry[]
*
* @ORM\OneToMany(targetEntity="CashJournal\Model\Entry", mappedBy="category", fetch="EAGER", orphanRemoval=true, cascade={"persist", "remove"})
*/
private $entries;
}
запись
class Entry extends AbstractEntity
{
use Nameable;
/**
* @var null|float
*
* @ORM\Column(name="amount", type="decimal")
*/
private $amount;
/**
* @var null|Category
*
* @ORM\ManyToOne(targetEntity="CashJournal\Model\Category", inversedBy="entries", fetch="EAGER")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false)
*/
protected $category;
/**
* @var null|DateTime
*
* @ORM\Column(name="date_of_entry", type="datetime")
*/
private $dateOfEntry;
}
И если кто-тотребуется AbstractEntity
abstract class AbstractEntity implements EntityInterface
{
/**
* @var int
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
}
Каждая категория может иметь много записей.Я использую Doctrine
для этого отношения.И это прекрасно работает.
У меня есть форма на основе этого набора полей:
$this->add([
'name' => 'id',
'type' => Hidden::class
]);
$this->add([
'name' => 'name',
'type' => Text::class,
'options' => [
'label' => 'Name'
]
]);
$this->add([
'name' => 'amount',
'type' => Number::class,
'options' => [
'label' => 'Summe'
]
]);
$this->add([
'name' => 'date_of_entry',
'type' => Date::class,
'options' => [
'label' => 'Datum'
]
]);
$this->add([
'name' => 'category',
'type' => ObjectSelect::class,
'options' => [
'target_class' => Category::class,
]
]);
Так что моя форма отображает раскрывающийся список с моими категориями.Да, хорошо.
Чтобы загрузить категорию для моей сущности входа, я использую фильтр.
$this->add([
'name' => 'category',
'required' => true,
'filters' => [
[
'name' => Callback::class,
'options' => [
'callback' => [$this, 'loadCategory']
]
]
]
]);
И обратный вызов:
public function loadCategory(string $categoryId)
{
return $this->mapper->find($categoryId);
}
Маппер загружает категорию отлично,отличный.Но форма недействительна, потому что:
Объект класса CashJournal \ Model \ Category не может быть преобразован в int
Хорошо, поэтому я удаляю фильтр, нотеперь он не смог установить атрибуты Entry Entity, потому что установщик нуждается в Category
.Ошибка формы гласит:
Ввод неверный шаг
В Symfony я могу создать ParamConverter
, который преобразует category_id
в действительный Category
Entity.
Вопрос Как я могу использовать фильтр в качестве моего ParamConver?
Обновление Также, когда я приведу category_id к int, я получу ошибку из формы.
Обновление 2 Я изменил свой FieldSet на:
class EntryFieldSet extends Fieldset implements ObjectManagerAwareInterface
{
use ObjectManagerTrait;
/**
* {@inheritDoc}
*/
public function init()
{
$this->add([
'name' => 'id',
'type' => Hidden::class
]);
$this->add([
'name' => 'name',
'type' => Text::class,
'options' => [
'label' => 'Name'
]
]);
$this->add([
'name' => 'amount',
'type' => Number::class,
'options' => [
'label' => 'Summe'
]
]);
$this->add([
'name' => 'date_of_entry',
'type' => Date::class,
'options' => [
'label' => 'Datum'
]
]);
$this->add([
'name' => 'category',
'required' => false,
'type' => ObjectSelect::class,
'options' => [
'target_class' => Category::class,
'object_manager' => $this->getObjectManager(),
'property' => 'id',
'display_empty_item' => true,
'empty_item_label' => '---',
'label_generator' => function ($targetEntity) {
return $targetEntity->getName();
},
]
]);
parent::init();
}
}
Но это будет завершено с сообщением об ошибке:
Entry :: setDateOfEntry () должен быть экземпляром DateTime, строка должна иметь значение