Обратные вызовы жизненного цикла не работают

В настоящее время я пробую Symfony 4, но у меня возникают проблемы с событиями, вызванными действием базы данных (prePersist, preUpdate ...)

В Symfony 3 я использовал EntityListener для достижения этой цели, но я нашел их действительно запутанными в документации Symfony 4. Но я также обнаружил LifecycleCallbacks, которые использовал вот так:

/**
* @ORM\Entity(repositoryClass = "App\Repository\PostRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Post
{
     //Attributes and other functions not included for the sake of clarity, but if I use them, consider that they exist
     /**
     * @ORM\PrePersist
     */ 
    public function setPostSlug()
    {
         $title = $this->getPostTitle();
         $title = strtolower($title);

         $keywords = preg_split("/[\s,']+/", $title);
         $slug = implode('-', $keywords);

         dump($slug);

         $this->$slug = $slug;

         return $this;
     }
}

Мой пост создается с помощью формы Symfony, и перед сохранением я хочу разбить заголовок, который я дал своему сообщению, в стандартизированной строке, которую я буду использовать в своих URL-адресах для доступа к указанному сообщению. К сожалению, событие никогда не запускается при сохранении, несмотря на то, что слаг генерируется правильно. Я попытался выполнить операцию как для событий prePersist, так и для postPersist, но ничего не помогло. Я поискал проблему и увидел, что LifecycleCallbacks нужно было учесть очистку кеша, но это не помогло.

Вот действие, отвечающее за создание поста, если это может помочь:

/**
 * @Route("/admin/create/post", name = "admin-create-post")
 * @param Request $request
 */
public function createPost(Request $request)
{
    $post = new Post();

    $form = $this->createForm(PostType::class, $post);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()){
        $em = $this->getDoctrine()->getManager();
        $post = $form->getData();
        $em->persist($post);
        $em->flush();
        $this->redirectToRoute('main');
    }

    return $this->render('admin/new_post.html.twig', array(
        'form' => $form->createView()
    ));
}

Знаете ли вы источник проблемы или какие другие инструменты я мог бы использовать для получения желаемого результата?

Заранее спасибо.

Он должен работать точно так же, есть ли у вас определения сущностей в аннотациях или в yaml / xml?

kuba_ceg 17.03.2018 20:37

@kuba_ceg Я управляю всем с помощью аннотаций, как вы можете видеть в верхней части поста класса

Meleadeles 17.03.2018 20:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
2
641
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я управляю сложным жизненным циклом с помощью EventListener для этого .. сделайте:

# services.yml

AppBundle\EventListener\YourListener:
    tags:
        - { name: doctrine.event_listener, event: prePersist }

// YourListener.php
namespace AppBundle\EventListener;

class YourListener {
     /**
      * @param LifecycleEventArgs $args
      */
      public function prePersist(LifecycleEventArgs $args): void
      {
          $post = $args->getEntity();

          if ($post instanceof Post) {
             // Do your job
          }
      }
}

Но я использую Symfony EventListenerSubscriber вот так:

    /**
 * This needs to be set through passed argument in case of accident duplicate
 *
 * @ORM\PrePersist()
 */
public function setTrackingNumber()
{
    $this->trackingNumber = NumberCreator::randomStringWithNDigits(self::TRACKING_DIGIT_COUNT);
}

поэтому я думаю, вам нужно сделать это в своем установщике слагов вот так

 /**
 * @ORM\PrePersist
 */ 
public function setSlug()
{
     $title = $this->getPostTitle();
     $title = strtolower($title);

     $keywords = preg_split("/[\s,']+/", $title);
     $slug = implode('-', $keywords);

     dump($slug);

     $this->$slug = $slug;

     return $this;
 }

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

Хорошо, я попробую, но как насчет EventListenerSubscriber, который используется в документации Symfony? Это бесполезно?

Meleadeles 18.03.2018 12:10

@Meleadeles нет, конечно, нет, я редактирую ответ, посмотрите на это.

Farshadi 18.03.2018 12:17

@Meleadeles, но держите внимание к этой проблеме, я думаю, что после того, как вы настаиваете в первый раз, это работа ... и когда вы хотите обновить свой пост новым заголовком ... слаг, как предыдущий заголовок, я не уверен, но я думаю.

Farshadi 18.03.2018 12:27

Хорошо, похоже, проблема в названии метода, я изменил его на createSlug и снова ввел обычный сеттер, и он работал нормально. Спасибо.

Meleadeles 18.03.2018 12:56

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