Проблема с окном поиска Symfony

У меня проблема с созданием окна поиска с помощью Symfony и Doctrine. Я использую Symfony версии 2.8.

Моя проблема:

EntityManager # persist () ожидает, что параметр 1 будет объектом сущности, заданным массивом. 500 Внутренняя ошибка сервера - ORMInvalidArgumentException

Итак, это мой Тип для моего типа окна поиска:

/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)  {

    $builder->add('searchBox',SearchType::class,array('label'=>'Vous cherchez : Un auteur ? Un éditeur ? Un ouvrage ?','attr'=>array('class'=>'form-control')));

}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class1' => 'SB\MainBundle\Entity\Ouvrages',
        'data_class2' => 'SB\MainBundle\Entity\Auteurs',
        'data_class3' => 'SB\MainBundle\Entity\Editeurs'
    ));
}

И это мой код контроллера после редактирования:

public function indexAction(Request $request) {
    $ouvragesVentes = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesVentes();
    $ouvragesEchanges = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesEchanges();
    $categories = $this->getDoctrine()->getRepository('SBMainBundle:Categories')->getAllCats();

    $form = $this->createForm(SearchBoxType::class);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $searchBoxValue = $form->getData();

        $bookName = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvrageName($searchBoxValue);
        $editorName = $this->getDoctrine()->getRepository('SBMainBundle:Editeurs')->getEditeurName($searchBoxValue);
        $autorName = $this->getDoctrine()->getRepository('SBMainBundle:Auteurs')->getAuteurName($searchBoxValue);

        //if author
        if ($searchBoxValue == $autorName){
            return $this->redirect($this->generateUrl('sb_main_auteur'));
        }
        //if editor
        if ($searchBoxValue == $editorName){
            return $this->redirect($this->generateUrl('sb_main_editeur'));
        }
        //if book name
        if ($searchBoxValue == $bookName){
            return $this->redirect($this->generateUrl('sb_main_ouvrage'));
        }
    }

    $datas = array('categories'=>$categories,'form'=>$form->createView(),'ouvragesEchanges'=>$ouvragesEchanges,'ouvragesVentes'=>$ouvragesVentes);
    return $this->render('SBMainBundle:Main:index.html.twig',$datas);
}

Изменить: Моя формаHandler

    protected $request;
protected $form;
protected $em;


//faire une injection de dépendance avec Request,Manager,Form(Objet)
public function __construct(Request $request,EntityManager $em, Form $form){
    $this->request = $request;
    $this->em = $em;
    $this->form = $form;
}

//vérifie si le formulaire est soumis et valide
public function process(){

    if ($this->request->getMethod() == "POST"){
        //récupération des données de la requête de la superglobale $_POST
        $this->form->handleRequest($this->request);
        //si ok, on appel onSuccess()
        if ($this->form->isValid()){
            $this->onSuccess($this->form->getData());
            return true;
        }
    }
    return false;

}

//si formulaire soumis et valide, on presiste l'objet (enregistre dans la DB)
public function onSuccess($object){
    //on persiste dans la DB via le manager Doctrine
    $this->em->persist($object);
    $this->em->flush();
}

Я смотрел здесь, но Думаю, это не решение моей проблемы. Тогда кто-нибудь может сказать мне, что не так? Нужен ли мне объект окна поиска даже с окном поиска?

Спасибо за вашу помощь !

Редактировать :

Трассировки стека

in src\SB\MainBundle\Repository\OuvragesRepository.php at line 130   -

public function getOuvrageName($titre){
    $query = $this->getEntityManager()->createQuery(
        "SELECT o FROM SBMainBundle:Ouvrages o WHERE o.titreOuvrage = $titre ORDER BY o.id DESC "
    );
    return $query->getResult();


at ErrorHandler ->handleError ('8', 'Array to string conversion',     'C:\wamp\www\switchbook\src\SB\MainBundle\Repository\OuvragesRepository.php', '130', array('titre' => array('searchBox' => 'flammarion'))) 
in src\SB\MainBundle\Repository\OuvragesRepository.php at line 130   +
at OuvragesRepository ->getOuvrageName (array('searchBox' => 'flammarion')) 
in src\SB\MainBundle\Controller\MainController.php at line 35   +
at MainController ->indexAction (object(Request))
at call_user_func_array (array(object(MainController), 'indexAction'),   array(object(Request))) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 144   +
at HttpKernel ->handleRaw (object(Request), '1') 

в vendor \ symfony \ symfony \ src \ Symfony \ Component \ HttpKernel \ HttpKernel.php в строке 64 + в HttpKernel -> handle (object (Request), '1', true) в vendor \ symfony \ symfony \ src \ Symfony \ Component \ HttpKernel \ DependencyInjection \ ContainerAwareHttpKernel.php в строке 69 + в ContainerAwareHttpKernel -> handle (object (Request), '1', true) в vendor \ symfony \ symfony \ src \ Symfony \ Component \ HttpKernel \ Kernel.php в строке 185 + в Kernel -> handle (object (Request)) в web \ app_dev.php в строке 28 +

Новое редактирование:

Отсутствуют некоторые обязательные параметры ("titreOuvrage") для создания URL-адреса для маршрута "sb_main_ouvrage".

sb_main_ouvrage:
path:     /ouvrage/{titreOuvrage}
defaults: { _controller: SBMainBundle:Main:ouvrage}

Трассировки стека

в app \ cache \ dev \ classes.php в строке 911

$variables = array_flip($variables);
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
if ($diff = array_diff_key($variables, $mergedParams)) {throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name));}
$url ='';
$optional = true;

at UrlGenerator ->doGenerate (array('titreOuvrage'), array('_controller' => 'SB\MainBundle\Controller\MainController::ouvrageAction'), array(), array(array('variable', '/', '[^/]++', 'titreOuvrage'), array('text', '/ouvrage')), array(), 'sb_main_ouvrage', '1', array(), array()) 
in app\cache\dev\appDevDebugProjectContainerUrlGenerator.php at line 92   +
at appDevDebugProjectContainerUrlGenerator ->generate ('sb_main_ouvrage', array(), '1') 
in app\cache\dev\classes.php at line 1286   +
at Router ->generate ('sb_main_ouvrage', array(), '1') 
in vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Controller\Controller.php at line 52   +
at Controller ->generateUrl ('sb_main_ouvrage') 
in src\SB\MainBundle\Controller\MainController.php at line 49   +
at MainController ->indexAction (object(Request))
at call_user_func_array (array(object(MainController), 'indexAction'), array(object(Request))) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 144   +
at HttpKernel ->handleRaw (object(Request), '1') 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 64   +
at HttpKernel ->handle (object(Request), '1', true) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel.php at line 69   +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php at line 185   +
at Kernel ->handle (object(Request)) 
in web\app_dev.php at line 28

И мой контроллер для страницы сопоставления:

    public function ouvrageAction(Ouvrages $ouvrages){
    $ouvrage =  $ouvrages->getTitreOuvrage();
    $categories = $this->getDoctrine()->getRepository('SBMainBundle:Categories')->getAllCats();
    $ouvragesVentes = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesVentesByName($ouvrage);
    $ouvragesEchanges = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesEchangesByName($ouvrage);
    $datas = array('ouvragesVentes'=>$ouvragesVentes,'ouvragesEchanges'=>$ouvragesEchanges,'categories'=>$categories,'ouvrages'=>$ouvrages);
    return $this->render('SBMainBundle:Main:ouvrage.html.twig',$datas);
}

person Tirkal    schedule 28.03.2017    source источник
comment
Было бы неплохо иметь код вашего FormHandler, ошибка может быть оттуда. Ваша ошибка говорит о вызове persist (), но я не вижу ничего в вашем коде.   -  person DFayet    schedule 28.03.2017
comment
Я добавляю свой formHandler, но он мне нужен для многих форм для моего приложения. Нужно ли мне создавать новую для своего окна поиска?   -  person Tirkal    schedule 28.03.2017


Ответы (1)


В вашей форме нет объекта (или несколько), что означает, что ваша $ form-> getData () вернет массив. И, как говорится в ошибке, вы не можете передать массив методу persist ().

Если ваша цель - сохранить каждый поиск, отправленный в вашей базе данных, вам необходимо создать объект SearchBox (или как вы хотите его назвать) и соответственно установить data_class.

Если вы не хотите сохранять результаты поиска, вам не нужно вызывать обработчика. (потому что он ничего не делает, кроме вызова persist ()) И вам не нужна сущность, проверьте, как обрабатывать отправку без data_class

Кстати. в вашем обработчике вы вызываете $ form-> isValid () без $ form-> isSubmitted () и этого кода

if ($formHandler->process()){
    return $this->redirect($this->generateUrl(''));
}

if ($form->isSubmitted() && $form->isValid()) {
// You will never come here, because $formHandler->process() will return true if your form is valid, and leave your indexAction
}

Надеюсь, это поможет вам.

Изменить

Данные, которые вы передаете в свой репозиторий,

$searchBoxValue = $form->getData();

Это вернет метку searchBoxValue в виде массива, потому что вы запрашиваете все данные формы.

Но вы хотите получить конкретные данные поля поиска, вам нужно сделать

$searchBoxValue = $form->get('searchBox')->getData();

Обратите внимание, что я бы рекомендовал использовать queryBuilder или, по крайней мере, защитить ваш запрос от SQL-инъекций.

e.g

public function getOuvrageName($titre){
    $query = $this->getEntityManager()->createQuery(
        "SELECT o FROM SBMainBundle:Ouvrages o WHERE o.titreOuvrage = :titre ORDER BY o.id DESC "
    )
    ->setParameter('titre', $titre);
    return $query->getResult();
}
person DFayet    schedule 28.03.2017
comment
Я пробую ваше решение, и у меня возникла новая проблема: Возникла исключительная ситуация при выполнении 'SELECT o0_.is_delete AS is_delete0, [...] FROM ouvrages o0_ WHERE o0_.titre_ouvrage =?' с params [lombres]: SQLSTATE [HY093]: недопустимый номер параметра: параметр не был определен. Я ищу в Google, но все решает мою проблему. - person Tirkal; 29.03.2017
comment
Вы можете показать нам код ваших методов выбора, я думаю, у вас есть stacktrace, который может сказать вам, в каком методе есть ошибка (или, по крайней мере, какой из них недействителен), и добавить код этого метода в ваш вопрос. - person DFayet; 29.03.2017
comment
Я могу показать вам свои запросы на поиск в моей базе данных, может быть, это поможет вам разобраться в моей проблеме. - person Tirkal; 29.03.2017
comment
Для меня проблема в методе getOuvrageName вашего репозитория. Нам нужен код, чтобы помочь вам. - person DFayet; 29.03.2017
comment
Мой код: `public function getOuvrageName ($ searchBoxValue) {$ query = $ this-› createQueryBuilder ('o') - ›where ('o.titreOuvrage =: searchBoxValue') -› setParameter ('searchBoxValue', $ searchBoxValue); return $ query- ›getQuery () -› getResult (); } ` - person Tirkal; 29.03.2017
comment
Ну, этот код вроде в порядке, на 100% мой плохой. У вас есть какая-нибудь трассировка стека или какое-либо представление о том, в каком методе ошибка? Если да, добавьте эту информацию в свой вопрос - person DFayet; 29.03.2017
comment
Я бы изменил свой запрос: публичная функция getOuvrageName ($ titre) {$ query = $ this- ›getEntityManager () -› createQuery (ВЫБРАТЬ o FROM SBMainBundle: Ouvrages o WHERE o.titreOuvrage = $ titre ORDER BY o.id DESC / / Requete en DQL proche du SQL, 1re partie); return $ query- ›getResult (); } Тогда у меня такая проблема: Примечание: преобразование массива в строку - person Tirkal; 30.03.2017
comment
Добавьте, пожалуйста, метод, который вылетает в вашем вопросе, будет проще решить. - person DFayet; 30.03.2017
comment
Я отредактировал свой stacktrace. Надеюсь, это вам поможет! - person Tirkal; 30.03.2017
comment
Это работает ! Но теперь у меня возникла новая проблема с моим маршрутом. Я модифицирую свой пост, чтобы вы посмотрели. - person Tirkal; 30.03.2017
comment
Это совершенно новая проблема, вам нужно проверить вызовы маршрута sb_main_ouvrage, у всех ли у них установлен аргумент titreOuvrage? Это более распространенная проблема, вы сможете найти ветку об этом сообщении об ошибке на SO или в Google :-) - person DFayet; 30.03.2017
comment
Привет ! Всем спасибо, решаю свои вопросы. Я очень благодарен за вашу помощь !!! На самом деле в моей маршрутизации отсутствует аргумент titreOuvrage. - person Tirkal; 31.03.2017