<commit_before><?php

namespace Victoire\Bundle\PageBundle\EventSubscriber;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\UnitOfWork;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Victoire\Bundle\BusinessEntityPageBundle\Entity\BusinessEntityPage;
use Victoire\Bundle\CoreBundle\Helper\ViewCacheHelper;
use Victoire\Bundle\CoreBundle\Helper\ViewUrlHelper;
use Victoire\Bundle\PageBundle\Entity\BasePage;
use Victoire\Bundle\CoreBundle\Entity\View;
use Victoire\Bundle\PageBundle\Helper\UserCallableHelper;

/**
 * This class listen Page Entity changes.
 */
class PageSubscriber implements EventSubscriber
{
    protected $router;
    protected $userClass;
    protected $userCallable;
    protected $viewCacheHelper;
    protected $viewUrlHelper;

    /**
     * Constructor
     * @param Router             $router          @router
     * @param UserCallableHelper $userCallable    @victoire_page.user_callable
     * @param string             $userClass       %victoire_core.user_class%
     * @param ViewCacheHelper    $viewCacheHelper @victoire_core.view_cache_helper
     * @param ViewUrlHelper      $viewUrlHelper   @victoire_core.view_url_helper
     */
    public function __construct($router, $userCallable, $userClass, $viewCacheHelper, $viewUrlHelper)
    {
        $this->router          = $router;
        $this->userClass       = $userClass;
        $this->userCallable    = $userCallable;
        $this->viewCacheHelper = $viewCacheHelper;
        $this->viewUrlHelper = $viewUrlHelper;
    }

    /**
     * bind to LoadClassMetadata method
     *
     * @return string[] The subscribed events
     */
    public function getSubscribedEvents()
    {
        return array(
            'loadClassMetadata',
            'onFlush',
            'postPersist',
        );
    }

    /**
     * Insert enabled widgets in base widget DiscriminatorMap
     *
     * @param LoadClassMetadataEventArgs $eventArgs
     */
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $metadata = $eventArgs->getClassMetadata();

        //set a relation between Page and User to define the page author
        $metaBuilder = new ClassMetadataBuilder($metadata);

        //Add author relation on view
        if ($this->userClass && $metadata->name === 'Victoire\Bundle\CoreBundle\Entity\View') {
            $metadata->mapManyToOne(array(
                'fieldName'    => 'author',
                'targetEntity' => $this->userClass,
                'cascade'      => array('persist'),
                'inversedBy'   => 'pages',
                'joinColumns' => array(
                    array(
                        'name' => 'author_id',
                        'referencedColumnName' => 'id',
                        'onDelete' => 'SET NULL',
                    ),
                ),
            ));
        }

        // if $pages property exists, add the inversed side on User
        if ($metadata->name === $this->userClass && property_exists($this->userClass, 'pages')) {
            $metaBuilder->addOneToMany('pages', 'Victoire\Bundle\PageBundle\Entity\View', 'author');
        }
    }

    /**
     * This method is called on flush
     * @param OnFlushEventArgs $eventArgs The flush event args.
     *
     * @return void
     */
    public function onFlush(OnFlushEventArgs $eventArgs)
    {
        /** @var EntityManager $entityManager */
        $entityManager = $eventArgs->getEntityManager();
        /** @var UnitOfWork $uow */
        $uow = $entityManager->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof BasePage) {
                $computeUrl = ((array_key_exists('slug', $uow->getEntityChangeSet($entity)) //the slug of the page has been modified
                            || array_key_exists('parent', $uow->getEntityChangeSet($entity)))
                            ); //the parent has been modified
                if ($computeUrl) {
                    $this->viewUrlHelper->buildUrl($entity, $uow, $entityManager) ;
                }
                $meta = $entityManager->getClassMetadata(get_class($entity));
                $uow->recomputeSingleEntityChangeSet($meta, $entity);
                $entity->setAuthor($this->userCallable->getCurrentUser());
            }
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof BasePage) {
                $computeUrl = ((array_key_exists('slug', $uow->getEntityChangeSet($entity)) //the slug of the page has been modified
                            || array_key_exists('parent', $uow->getEntityChangeSet($entity)))
                            ); //the parent has been modified
                if ($computeUrl) {
                    $this->viewUrlHelper->buildUrl($entity, $uow, $entityManager);
                    $meta = $entityManager->getClassMetadata(get_class($entity));
                    $uow->computeChangeSet($meta, $entity);
                    $this->updateCache($entity);
                }
            }
        }
    }

    /**
     * @param LifecycleEventArgs $eventArgs
     */
    public function postPersist(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getEntity();
        if ($entity instanceof View) {
            $this->updateCache($entity);
        }
    }

    /**
     * There is changes in the Page, we have to update the page references cache file
     * @param BasePage $page the page
     *
     * @return void
     */
    protected function updateCache(View $page)
    {
        if ($page instanceof BusinessEntityPage) {
            $this->viewCacheHelper->update($page, $page->getBusinessEntity());
        } else {
            $this->viewCacheHelper->update($page);
        }
    }
}
<commit_msg>prefer use webviewInterface than base page to rebuild url<commit_after><?php

namespace Victoire\Bundle\PageBundle\EventSubscriber;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\UnitOfWork;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Victoire\Bundle\BusinessEntityPageBundle\Entity\BusinessEntityPage;
use Victoire\Bundle\CoreBundle\Helper\ViewCacheHelper;
use Victoire\Bundle\CoreBundle\Helper\ViewUrlHelper;
use Victoire\Bundle\PageBundle\Entity\BasePage;
use Victoire\Bundle\CoreBundle\Entity\View;
use Victoire\Bundle\PageBundle\Helper\UserCallableHelper;
use Victoire\Bundle\CoreBundle\Entity\WebViewInterface;

/**
 * This class listen Page Entity changes.
 */
class PageSubscriber implements EventSubscriber
{
    protected $router;
    protected $userClass;
    protected $userCallable;
    protected $viewCacheHelper;
    protected $viewUrlHelper;

    /**
     * Constructor
     * @param Router             $router          @router
     * @param UserCallableHelper $userCallable    @victoire_page.user_callable
     * @param string             $userClass       %victoire_core.user_class%
     * @param ViewCacheHelper    $viewCacheHelper @victoire_core.view_cache_helper
     * @param ViewUrlHelper      $viewUrlHelper   @victoire_core.view_url_helper
     */
    public function __construct($router, $userCallable, $userClass, $viewCacheHelper, $viewUrlHelper)
    {
        $this->router          = $router;
        $this->userClass       = $userClass;
        $this->userCallable    = $userCallable;
        $this->viewCacheHelper = $viewCacheHelper;
        $this->viewUrlHelper = $viewUrlHelper;
    }

    /**
     * bind to LoadClassMetadata method
     *
     * @return string[] The subscribed events
     */
    public function getSubscribedEvents()
    {
        return array(
            'loadClassMetadata',
            'onFlush',
            'postPersist',
        );
    }

    /**
     * Insert enabled widgets in base widget DiscriminatorMap
     *
     * @param LoadClassMetadataEventArgs $eventArgs
     */
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $metadata = $eventArgs->getClassMetadata();

        //set a relation between Page and User to define the page author
        $metaBuilder = new ClassMetadataBuilder($metadata);

        //Add author relation on view
        if ($this->userClass && $metadata->name === 'Victoire\Bundle\CoreBundle\Entity\View') {
            $metadata->mapManyToOne(array(
                'fieldName'    => 'author',
                'targetEntity' => $this->userClass,
                'cascade'      => array('persist'),
                'inversedBy'   => 'pages',
                'joinColumns' => array(
                    array(
                        'name' => 'author_id',
                        'referencedColumnName' => 'id',
                        'onDelete' => 'SET NULL',
                    ),
                ),
            ));
        }

        // if $pages property exists, add the inversed side on User
        if ($metadata->name === $this->userClass && property_exists($this->userClass, 'pages')) {
            $metaBuilder->addOneToMany('pages', 'Victoire\Bundle\PageBundle\Entity\View', 'author');
        }
    }

    /**
     * This method is called on flush
     * @param OnFlushEventArgs $eventArgs The flush event args.
     *
     * @return void
     */
    public function onFlush(OnFlushEventArgs $eventArgs)
    {
        /** @var EntityManager $entityManager */
        $entityManager = $eventArgs->getEntityManager();
        /** @var UnitOfWork $uow */
        $uow = $entityManager->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof WebViewInterface) {
                $computeUrl = ((array_key_exists('slug', $uow->getEntityChangeSet($entity)) //the slug of the page has been modified
                            || array_key_exists('parent', $uow->getEntityChangeSet($entity)))
                            ); //the parent has been modified
                if ($computeUrl) {
                    $this->viewUrlHelper->buildUrl($entity, $uow, $entityManager) ;
                }
                $meta = $entityManager->getClassMetadata(get_class($entity));
                $uow->recomputeSingleEntityChangeSet($meta, $entity);
                $entity->setAuthor($this->userCallable->getCurrentUser());
            }
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof WebViewInterface) {
                $computeUrl = ((array_key_exists('slug', $uow->getEntityChangeSet($entity)) //the slug of the page has been modified
                            || array_key_exists('parent', $uow->getEntityChangeSet($entity)))
                            ); //the parent has been modified
                if ($computeUrl) {
                    $this->viewUrlHelper->buildUrl($entity, $uow, $entityManager);
                    $meta = $entityManager->getClassMetadata(get_class($entity));
                    $uow->computeChangeSet($meta, $entity);
                    $this->updateCache($entity);
                }
            }
        }
    }

    /**
     * @param LifecycleEventArgs $eventArgs
     */
    public function postPersist(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getEntity();
        if ($entity instanceof View) {
            $this->updateCache($entity);
        }
    }

    /**
     * There is changes in the Page, we have to update the page references cache file
     * @param BasePage $page the page
     *
     * @return void
     */
    protected function updateCache(View $page)
    {
        if ($page instanceof BusinessEntityPage) {
            $this->viewCacheHelper->update($page, $page->getBusinessEntity());
        } else {
            $this->viewCacheHelper->update($page);
        }
    }
}

{'fraction_non_alphanumeric': 0.11272339727824233, 'fraction_numerical': 0.0, 'mean_word_length': 2.217884463202321, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3949859', 'n_tokens_mistral': 3287, 'n_tokens_neox': 3203, 'n_words': 674}