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;
}

Таким образом, вы можете заполнить свою коллекцию форм, используя созданный массив.

Я думаю, что еще одним решением было бы использовать преобразователь данных. Надеюсь это поможет

Другие вопросы по тегам