Сущности, переданные в поле выбора, должны управляться — по-разному в app.php и в app_dev.php.

Добро пожаловать!

Я добавил поле в форму

    ->add('languageLevel', ChoiceType::class, [
        'choices' => [
            Meme::LEVEL_BEGINNER => Meme::LEVEL_BEGINNER,
            Meme::LEVEL_INTERMEDIATE => Meme::LEVEL_INTERMEDIATE,
            Meme::LEVEL_ADVANCED => Meme::LEVEL_ADVANCED,
            Meme::LEVEL_EXPERT => Meme::LEVEL_EXPERT
        ]
    ])

Эта форма сохраняет объект «Мем» с тем же свойством.

/**
 * @var string
 * @ORM\Column(name="language_level", type="string", length=20)
 */
private $languageLevel;

prod.log дает мне это:

[2017-12-17 23:41:18] request.INFO: Matched route "meme_add". {"route":"meme_add","route_parameters":{"_controller":"AppBundle\\Controller\\MemeController::addAction","_route":"meme_add"},"request_uri":"http://keenweasel.com/meme/add","method":"GET"} []
[2017-12-17 23:41:18] security.DEBUG: Read existing security token from the session. {"key":"_security_main"} []
[2017-12-17 23:41:18] security.DEBUG: User was reloaded from a user provider. {"username":"acid","provider":"FOS\\UserBundle\\Security\\UserProvider"} []
[2017-12-17 23:41:18] php.WARNING: Warning: spl_object_hash() expects parameter 1 to be object, integer given {"exception":"[object] (ErrorException(code: 0): Warning: spl_object_hash() expects parameter 1 to be object, integer given at /var/www/keen/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1239)"} []
[2017-12-17 23:41:18] php.WARNING: Warning: spl_object_hash() expects parameter 1 to be object, integer given {"exception":"[object] (ErrorException(code: 0): Warning: spl_object_hash() expects parameter 1 to be object, integer given at /var/www/keen/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1592)"} []
[2017-12-17 23:41:18] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Form\Exception\RuntimeException: "Entities passed to the choice field must be managed. Maybe persist them in the entity manager?" at /var/www/keen/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php line 98 {"exception":"[object] (Symfony\\Component\\Form\\Exception\\RuntimeException(code: 0): Entities passed to the choice field must be managed. Maybe persist them in the entity manager? at /var/www/keen/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php:98)"} []
[2017-12-17 23:41:18] security.DEBUG: Stored the security token in the session. {"key":"_security_main"} []

в dev.log на моей машине разработчика ничего подобного нет, и все работает нормально. На prod я получаю ошибку 500. Любая помощь, пожалуйста? Я попытался удалить поставщика и установить его еще раз на обоих серверах dev и prod. Многократная очистка кеша с --env=prod.


РЕДАКТИРОВАТЬ

Хорошо, возникла та же проблема на сервере разработки (просто переключился с app_dev.php на app.php в конфигурации apache и добавил app/autoload.php)

/**
 * @Route("/meme/add", name="meme_add")
 * @param Request $request
 * @return \Symfony\Component\HttpFoundation\Response
 * @internal param Request $request
 */
public function addAction(Request $request)
{
    $user = $this->getUser();
    if (!$user || !$user->hasRole('ROLE_MEME_ADD_AWAITING')) {
        $this->addFlash('notice', 'You need to login');
        return $this->redirectToRoute('fos_user_security_login');
    }

    if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
        throw $this->createAccessDeniedException();
    }

    $meme = new Meme();
    $form = $this->createForm(MemeAddType::class, $meme);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid() ) {
        if ($user->hasRole('ROLE_MEME_ADD_AWAITING')) {
            $meme->setPublishingStatus('awaiting-publishing');
        } else if ($this->getUser()->hasRole('ROLE_MEME_ADD_MAIN')) {
            $meme->setPublishingStatus('published');
        }
        $em = $this->getDoctrine()->getManager();
        $em->persist($meme);
        $em->flush();
    }

    return $this->render(
        '@App/memes/add.html.twig',
        [
            'memeAddForm' => $form->createView()
        ]
    );
}

Форма:

<?php

namespace AppBundle\Form;

use AppBundle\Entity\Language;
use AppBundle\Entity\Meme;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichImageType;

class MemeAddType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('textOne', TextareaType::class, [
                'label' => 'A phrase or a word',
                'attr' => ['style' => 'width:320px; height: 110px']
            ])
            ->add('textOneLang', EntityType::class , [
                'class' => Language::class,
                'choice_label' => 'language',
                'expanded' => false,
                'multiple' => false,
                'label' => 'Language of the phrase of the word',
                'data' => 2

            ])
            ->add('textTwo', TextareaType::class, [
                'label' => 'Translation, might be with an example',
                'attr' => ['style' => 'width:320px; height: 110px']
            ])
            ->add('textTwoLang', EntityType::class , [
                'class' => Language::class,
                'choice_label' => 'language',
                'expanded' => false,
                'multiple' => false,
                'label' => 'Language of the translation of the phrase of the word',
                'data' => 2
            ])
            ->add('languageLevel', ChoiceType::class, [
                'choices' => [
                    Meme::LEVEL_BEGINNER => Meme::LEVEL_BEGINNER,
                    Meme::LEVEL_INTERMEDIATE => Meme::LEVEL_INTERMEDIATE,
                    Meme::LEVEL_ADVANCED => Meme::LEVEL_ADVANCED,
                    Meme::LEVEL_EXPERT => Meme::LEVEL_EXPERT
                ]
            ])
            ->add('imageFile', VichImageType::class)
            ->add(
                'save',
                SubmitType::class,
                [
                    'attr' => ['class' => 'save']
                ]
            )
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Meme::class
        ]);
    }

    public function getBlockPrefix()
    {
        return 'app_bundle_meme_add';
    }

    public function getName() {
        return 'app_bundle_meme_add';
    }
}

person pablosd    schedule 17.12.2017    source источник
comment
На что ссылаются Meme::LEVEL_BEGINNER, Meme::LEVEL_INTERMEDIATE, Meme::LEVEL_ADVANCED, Meme::LEVEL_EXPERT ?   -  person Sylvain Martin Saint Léon    schedule 18.12.2017
comment
Это всего лишь струны.   -  person pablosd    schedule 18.12.2017
comment
languageLevel сопоставлен, что содержит объект, переданный в форму?   -  person Sylvain Martin Saint Léon    schedule 19.12.2017
comment
Я обновил вопрос с формой и контроллером. Кроме того, повторил ту же проблему на сервере разработки. Странно, что на app_dev.php почему-то не было проблем ни на dev, ни на prod серверах.   -  person pablosd    schedule 19.12.2017
comment
Если у вас такая же проблема на dev, можете ли вы опубликовать более подробный отладочный файл? Ошибка, которую вы публикуете, не связана ни с одним из ваших файлов, что кажется нормальным...   -  person Sylvain Martin Saint Léon    schedule 19.12.2017


Ответы (2)


Попробуйте это в своем formType

<?php

namespace AppBundle\Form;

use AppBundle\Entity\Language;
use AppBundle\Entity\Meme;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichImageType;

class MemeAddType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('textOne', TextareaType::class, [
                'label' => 'A phrase or a word',
                'attr' => ['style' => 'width:320px; height: 110px']
            ])
            ->add('textOneLang', EntityType::class , [
                'class' => Language::class,
                'choice_label' => 'language',
                'expanded' => false,
                'multiple' => false,
                'label' => 'Language of the phrase of the word',
                'data' => 2

            ])
            ->add('textTwo', TextareaType::class, [
                'label' => 'Translation, might be with an example',
                'attr' => ['style' => 'width:320px; height: 110px']
            ])
            ->add('textTwoLang', EntityType::class , [
                'class' => Language::class,
                'choice_label' => 'language',
                'expanded' => false,
                'multiple' => false,
                'label' => 'Language of the translation of the phrase of the word',
                'data' => 2
            ])
            ->add('languageLevel', ChoiceType::class, [
                'choices' => [
                    Meme::LEVEL_BEGINNER => Meme::LEVEL_BEGINNER,
                    Meme::LEVEL_INTERMEDIATE => Meme::LEVEL_INTERMEDIATE,
                    Meme::LEVEL_ADVANCED => Meme::LEVEL_ADVANCED,
                    Meme::LEVEL_EXPERT => Meme::LEVEL_EXPERT
                ]
            ])
            ->add('imageFile', VichImageType::class)
            ->add(
                'save',
                SubmitType::class,
                [
                    'attr' => ['class' => 'save']
                ]
            )
        ;
        $builder->get('languageLevel')->resetViewTransformers();
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Meme::class
        ]);
    }

    public function getBlockPrefix()
    {
        return 'app_bundle_meme_add';
    }
}
person Sunil Jose    schedule 19.12.2017
comment
Совершенство! $builder-›get('languageLevel')-›resetViewTransformers(); это магия. Не могли бы вы объяснить, почему это необходимо в данном случае, это было бы большой воспитательной ценностью! :) - person pablosd; 19.12.2017
comment
Пожалуйста, проверьте эту ссылку symfony.com/doc/current/form/data_transformers.html . Я надеюсь, что это поможет вам получить знания о трансформерах. - person Sunil Jose; 21.12.2017

На самом деле, то, что происходило, было то, что я

 'data' => 2

в элементе формы textOneLang, поэтому он не работал, когда он был передан функции spl_object_hash(), которая принимает только объекты, а не целые числа. Преобразователь данных для этого не использовался. Но этот параметр «данные» изначально не должен был быть там, не знаю, как он там оказался. Вероятно, при попытке его отладки. Урок усвоен, выясните все параметры, а также просто выгрузите то, что у вас есть в качестве параметра в spl_object_hash().

Разница между app_dev.php и app.php не имеет к этому никакого отношения. Вероятно, он каким-то образом был закэширован в app_dev.php и работал в какой-то более старой версии.

person pablosd    schedule 01.01.2018