Symfony 3 - Форма - CollectionType в сущности без доктрины
Я борюсь с формами symfony3 и классом CollectionType:
У меня есть страница с несколькими сложными формами. Я не пользуюсь какой-либо базой данных (проверенные формы отправляются в зарубежный REST-сервис)
Теперь предположим, что у меня есть объект сущности для моего запроса под названием "ProductService":
class ProductService
{
/** @var string */
private $msg;
/** @var array*/
private $products
}
И класс ProductServiceType для отображения формы:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('products', CollectionType::class, [
'entry_type' => ProductType::class,
])
->add('msg' [...]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ProductService::class,
]);
}
С этой настройкой все работает как шарм, все продукты будут добавлены в массив продуктов моей сущности. Проблема в том, что я хочу, чтобы $products был объектом SplObjectStorage:
class ProductService
{
/** @var string */
private $msg;
/** @var SplObjectStorage */
private $products
}
Если я установлю его на это и добавлю пустой объект, Symfony больше не сможет отображать форму. Выдает следующее сообщение об ошибке: Предупреждение: SplObjectStorage::offsetExists() ожидает, что параметр 1 будет объектом, задана строка
Итак, кто-нибудь может сказать мне, как обрабатывать collectionType в сущности, когда НЕ используется доктрина и orm? Единственная возможность использовать массивы, или есть какая-либо документация для этого случая, я не нашел? (Мне все еще интересно, как Symfony вызывает offsetExists, должна быть реализована некоторая реализация для обработки SplObjectStorage, или я ошибаюсь?)
1 ответ
Я считаю, что ваша ошибка вызвана тем, что коллекция форм не была реализована для обработки SplObjectStorage, как вы ожидаете. Вы можете создать проблему для этого в хранилище Symfony.
Ошибка возникает, когда Symfony пытается заполнить коллекцию форм, читая ваши продукты из ProductService следующим образом:
$products = $productService->getProducts();
$products->offsetExists(0); //here is the error.
потому что он ожидает, что любое хранилище, которое реализует ArrayAccess, будет прочитано таким образом, но для SplObjectStorage это не так.
Элементы формы имеют установочную ссылку property_path, которую вы можете использовать, чтобы обойти вашу проблему.
Мое решение состоит в том, чтобы использовать этот параметр и вернуть возвращаемый массив для заполнения вашей коллекции:
$builder
->add('products', CollectionType::class, [
'entry_type' => ProductType::class,
'property_path' => 'productsArray'
])
class ProductService
{
...
public function getProductsArray() {
$prArray= [];
foreach ($this->products as $value) {
$prArray[] = $value;
}
return $prArray;
}
Таким образом, вы можете заполнить свою коллекцию форм, используя созданный массив.
Я думаю, что еще одним решением было бы использовать преобразователь данных. Надеюсь это поможет