Stores the current user into createdBy and updatedBy properties

@param LifecycleEventArgs $eventArgs
502954
public function prePersist(LifecycleEventArgs $eventArgs)
    {
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();
        $entity = $eventArgs->getEntity();

        $classMetadata = $em->getClassMetadata(get_class($entity));
        if ($this->isBlameable($classMetadata)) {
            if (!$entity->getCreatedBy()) {
                $user = $this->getUser();
                if ($this->isValidUser($user)) {
                    $entity->setCreatedBy($user);

                    $uow->propertyChanged($entity, 'createdBy', null, $user);
                    $uow->scheduleExtraUpdate($entity, [
                        'createdBy' => [null,  $user],
                    ]);
                }
            }
            if (!$entity->getUpdatedBy()) {
                $user = $this->getUser();
                if ($this->isValidUser($user)) {
                    $entity->setUpdatedBy($user);
                    $uow->propertyChanged($entity, 'updatedBy', null, $user);

                    $uow->scheduleExtraUpdate($entity, [
                        'updatedBy' => [null, $user],
                    ]);
                }
            }
        }
    }
1061951
public function preUpdate(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getObject();

        if (!$this->hasTrait($entity, 'Blast\BaseEntitiesBundle\Entity\Traits\Timestampable')) {
            return;
        }

        $this->logger->debug(
            '[TimestampableListener] Entering TimestampableListener for « preUpdate » event'
        );

        $now = new DateTime('NOW');
        $entity->setUpdatedAt($now);
    }
307197
public function preRemove(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getEntity();

        //if we remove a BP we need to replace by a VBP ref
        if ($entity instanceof BusinessPage) {
            //remove BP ref
            $event = new ViewReferenceEvent($entity);
            $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
            $em = $eventArgs->getEntityManager();
            $businessTemplate = $entity->getTemplate();
            $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
                $businessTemplate,
                $entity->getBusinessEntity(),
                $em
            );
            //create VBP ref
            //TODO :: dont rebuild if businessEntity or businessTemplate doesn't exist
            $event = new ViewReferenceEvent($page);
            $this->dispatcher->dispatch(ViewReferenceEvents::UPDATE_VIEW_REFERENCE, $event);
        }

        //if it's a businessEntity, we need to remove all BP and VBP ref
        if ($businessEntity = $this->businessEntityHelper->findByEntityInstance($entity)) {
            $em = $eventArgs->getEntityManager();
            $businessTemplates = $em->getRepository('VictoireBusinessPageBundle:BusinessTemplate')->findPagePatternByBusinessEntity($businessEntity);
            foreach ($businessTemplates as $businessTemplate) {

                // Generate a viewReference for each BT translation
                foreach ($businessTemplate->getTranslations() as $translation) {
                    $businessTemplate->setCurrentLocale($translation->getLocale());
                    if ($page = $em->getRepository('Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage')->findPageByBusinessEntityAndPattern($businessTemplate, $entity, $businessEntity)) {
                        $event = new ViewReferenceEvent($page);
                        $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
                    } else {
                        $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
                            $businessTemplate,
                            $entity,
                            $em
                        );
                        $event = new ViewReferenceEvent($page);
                        $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
                    }
                }
            }
        }
        //if we remove a businessTemplate remove all VBT ref (BP cascade remove)
        if ($entity instanceof BusinessTemplate) {
            $em = $eventArgs->getEntityManager();
            $entities = $this->businessPageHelper->getEntitiesAllowed($entity, $em);

            // Generate a viewReference for each BT translation
            foreach ($entity->getTranslations() as $translation) {
                $entity->setCurrentLocale($translation->getLocale());
                foreach ($entities as $be) {
                    $page = $this->businessPageBuilder->generateEntityPageFromTemplate(
                        $entity,
                        $be,
                        $em
                    );
                    $event = new ViewReferenceEvent($page);
                    $this->dispatcher->dispatch(ViewReferenceEvents::REMOVE_VIEW_REFERENCE, $event);
                }
            }
        }
    }
745222
public function preSoftDelete(LifecycleEventArgs $args)
    {
        $em = $args->getEntityManager();
        $entity = $args->getEntity();

        $entityReflection = new \ReflectionObject($entity);

        $namespaces = $em->getConfiguration()
            ->getMetadataDriverImpl()
            ->getAllClassNames();

        $reader = new AnnotationReader();
        foreach ($namespaces as $namespace) {
            $reflectionClass = new \ReflectionClass($namespace);
            if ($reflectionClass->isAbstract()) {
                continue;
            }

            $meta = $em->getClassMetadata($namespace);
            foreach ($reflectionClass->getProperties() as $property) {
                /** @var onSoftDelete $onDelete */
                if ($onDelete = $reader->getPropertyAnnotation($property, onSoftDelete::class)) {
                    $objects = null;
                    $manyToMany = null;
                    $manyToOne = null;
                    $oneToOne = null;

                    $associationMapping = null;
                    if (array_key_exists($property->getName(), $meta->getAssociationMappings())) {
                        $associationMapping = (object)$meta->getAssociationMapping($property->getName());
                    }

                    if (
                        ($manyToMany = $associationMapping && $associationMapping->type == ClassMetadataInfo::MANY_TO_MANY ? $associationMapping : null) ||
                        ($manyToOne = $associationMapping && $associationMapping->type == ClassMetadataInfo::MANY_TO_ONE ? $associationMapping : null) ||
                        ($oneToOne = $associationMapping && $associationMapping->type == ClassMetadataInfo::ONE_TO_ONE ? $associationMapping : null)
                    ) {
                        /** @var OneToOne|OneToMany|ManyToMany $relationship */
                        $relationship = $manyToOne ?: $manyToMany ?: $oneToOne;

                        $ns = null;
                        $nsOriginal = $relationship->targetEntity;
                        $nsFromRelativeToAbsolute = $entityReflection->getNamespaceName().'\\'.$relationship->targetEntity;
                        $nsFromRoot = '\\'.$relationship->targetEntity;
                        if (class_exists($nsOriginal)){
                            $ns = $nsOriginal;
                        } elseif (class_exists($nsFromRoot)){
                            $ns = $nsFromRoot;
                        } elseif (class_exists($nsFromRelativeToAbsolute)){
                            $ns = $nsFromRelativeToAbsolute;
                        }

                        if (!$this->isOnDeleteTypeSupported($onDelete, $relationship)) {
                            throw new \Exception(sprintf('%s is not supported for %s relationships', $onDelete->type, get_class($relationship)));
                        }

                        if (($manyToOne || $oneToOne) && $ns && $entity instanceof $ns) {
                            $objects = $em->getRepository($namespace)->findBy(array(
                                $property->name => $entity,
                            ));
                        } elseif ($manyToMany) {
                            // For ManyToMany relations, we only delete the relationship between
                            // two entities. This can be done on both side of the relation.
                            $allowMappedSide = get_class($entity) === $namespace;
                            $allowInversedSide = ($ns && $entity instanceof $ns);
                            if ($allowInversedSide) {
                                $mtmRelations = $em->getRepository($namespace)->createQueryBuilder('entity')
                                    ->innerJoin(sprintf('entity.%s', $property->name), 'mtm')
                                    ->addSelect('mtm')
                                    ->andWhere(sprintf(':entity MEMBER OF entity.%s', $property->name))
                                    ->setParameter('entity', $entity)
                                    ->getQuery()
                                    ->getResult();

                                foreach ($mtmRelations as $mtmRelation) {
                                    try {
                                        $propertyAccessor = PropertyAccess::createPropertyAccessor();
                                        $collection = $propertyAccessor->getValue($mtmRelation, $property->name);
                                        $collection->removeElement($entity);
                                    } catch (\Exception $e) {
                                        throw new \Exception(sprintf('No accessor found for %s in %s', $property->name, get_class($mtmRelation)));
                                    }
                                }
                            } elseif ($allowMappedSide) {
                                try {
                                    $propertyAccessor = PropertyAccess::createPropertyAccessor();
                                    $collection = $propertyAccessor->getValue($entity, $property->name);
                                    $collection->clear();
                                    continue;
                                } catch (\Exception $e) {
                                    throw new \Exception(sprintf('No accessor found for %s in %s', $property->name, get_class($entity)));
                                }
                            }
                        }
                    }

                    if ($objects) {
                        $factory = $em->getMetadataFactory();
                        $cacheDriver = $factory->getCacheDriver();
                        $cacheId = ExtensionMetadataFactory::getCacheId($namespace, 'Gedmo\SoftDeleteable');
                        $softDelete = false;
                        if (($config = $cacheDriver->fetch($cacheId)) !== false) {
                            $softDelete = isset($config['softDeleteable']) && $config['softDeleteable'];
                        }
                        foreach ($objects as $object) {
                            $this->processOnDeleteOperation($object, $onDelete, $property, $meta, $softDelete, $args, $config);
                        }
                    }
                }
            }
        }
    }
774882
public function postUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();
        if ($entity instanceof PackageVersionEntity) {
            $em = $args->getObjectManager();
            /* @var \Doctrine\ORM\EntityManager $em */
            $unitOfWork = $em->getUnitOfWork();
            $changeSet = $unitOfWork->getEntityChangeSet($entity);
            if (in_array('version', $changeSet)) {
                $this->refreshPackageLatestVersion($em, $entity->getPackage());
            }
        }
    }
339256
public function postPersist(LifecycleEventArgs $args)
    {
        $object = $args->getDocument();

        if (($names = $this->referenceRepository->getReferenceNames($object)) !== false) {
            foreach ($names as $name) {
                $identity = $args->getDocumentManager()
                    ->getUnitOfWork()
                    ->getDocumentIdentifier($object);

                $this->referenceRepository->setReferenceIdentity($name, $identity);
            }
        }
    }
852307
public function preUpdate(PreUpdateEventArgs $eventArgs): void
    {
        $object = $eventArgs->getObject();
        $this->gatherResourceAndItemTags($object, true);

        $changeSet = $eventArgs->getEntityChangeSet();
        $associationMappings = $eventArgs->getEntityManager()->getClassMetadata(ClassUtils::getClass($eventArgs->getObject()))->getAssociationMappings();

        foreach ($changeSet as $key => $value) {
            if (!isset($associationMappings[$key])) {
                continue;
            }

            $this->addTagsFor($value[0]);
            $this->addTagsFor($value[1]);
        }
    }
156669
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        /** @var ClassMetadata $metadata */
        $metadata = $eventArgs->getClassMetadata();

        $reflectionClass = $metadata->getReflectionClass();

        if (!$reflectionClass || !$this->hasTrait($reflectionClass, 'Librinfo\UserBundle\Entity\Traits\Traceable'))
            return; // return if current entity doesn't use Traceable trait

        // Check if parents already have the Traceable trait
        foreach ($metadata->parentClasses as $parent)
            if ($this->classAnalyzer->hasTrait($parent, 'Librinfo\UserBundle\Entity\Traits\Traceable'))
                return;

        $this->logger->debug("[TraceableListener] Entering TraceableListener for « loadClassMetadata » event");
        $this->logger->debug("[TraceableListener] Using « " . $this->userClass . " » as User class");

        // setting default mapping configuration for Traceable

        // createdBy
        $metadata->mapManyToOne([
            'targetEntity' => $this->userClass,
            'fieldName'    => 'createdBy',
            'joinColumn'   => [
                'name'                 => 'createdBy_id',
                'referencedColumnName' => 'id',
                'onDelete'             => 'SET NULL',
                'nullable'             => true
            ]
        ]);

        // updatedBy
        $metadata->mapManyToOne([
            'targetEntity' => $this->userClass,
            'fieldName'    => 'updatedBy',
            'joinColumn'   => [
                'name'                 => 'updatedBy_id',
                'referencedColumnName' => 'id',
                'onDelete'             => 'SET NULL',
                'nullable'             => true
            ]
        ]);

        $this->logger->debug("[TraceableListener] Added Traceable mapping metadata to Entity", ['class' => $metadata->getName()]);
    }
514846
public function onFlush(OnFlushEventArgs $eventArgs)
    {
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            $this->debug('Inserting entity '.get_class($entity).'. Fields: '.
                             json_encode($uow->getEntityChangeSet($entity)));
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            $add = '';
            if (method_exists($entity, '__toString')) {
                $add = ' '.$entity->__toString();
            } elseif (method_exists($entity, 'getId')) {
                $add = ' with id '.$entity->getId();
            }

            $this->debug('Updating entity '.get_class($entity).$add.'. Data: '.
                             json_encode($uow->getEntityChangeSet($entity)));
        }

        foreach ($uow->getScheduledEntityDeletions() as $entity) {
            $add = '';
            if (method_exists($entity, '__toString')) {
                $add = ' '.$entity->__toString();
            } elseif (method_exists($entity, 'getId')) {
                $add = ' with id '.$entity->getId();
            }

            $this->debug('Deleting entity '.get_class($entity).$add.'.');
        }
    }
821062
public function postPersist(LifecycleEventArgs $args)
    {
        if ($args->getObject() instanceof BlockInterface && !$args->getObject() instanceof DocumentBlock) {
            $this->getService($args)->postPersist($args->getObject());
        }
    }
826928
private function updateViewReference(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getEntity();

        //if entity is a translation, get its translatable entity
        if (in_array(Translation::class, class_uses($entity)) && null !== $entity->getTranslatable()) {
            $entity = $entity->getTranslatable();
        }

        //if it's a businessEntity we need to rebuild virtuals (BPs are rebuild in businessEntitySubscriber)
        if ($businessEntity = $this->businessEntityHelper->findByEntityInstance($entity)) {
            $this->flushedBusinessEntities->add($entity);
        }
        //if it a businessTemplate we have to rebuild virtuals or update BP
        if ($entity instanceof BusinessTemplate) {
            $this->flushedBusinessTemplates->add($entity);
        }
    }
1120054
public function postLoad(EventArgs $eventArgs)
    {
        if (method_exists($eventArgs, 'getEntity')) {
            $this->_triggerEvent(Events::postLoad, $eventArgs->getEntity(), $eventArgs);
        }
    }
600226
public function prePersist(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getObject();

        if (!$this->hasTrait($entity, 'Blast\BaseEntitiesBundle\Entity\Traits\Timestampable')) {
            return;
        }

        $this->logger->debug(
            '[TimestampableListener] Entering TimestampableListener for « prePersist » event'
        );

        $now = new DateTime('NOW');
        $entity->setCreatedAt($now);
        $entity->setUpdatedAt($now);
    }
1261075
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $classMetadata = $eventArgs->getClassMetadata();
        $reflClass = $classMetadata->reflClass;

        if (!$reflClass) {
            return;
        }

        if ($reflClass->implementsInterface('Prezent\Doctrine\Translatable\TranslatableInterface')) {
            $this->mapTranslatable($classMetadata);
        }

        if ($reflClass->implementsInterface('Prezent\Doctrine\Translatable\TranslationInterface')) {
            $this->mapTranslation($classMetadata);
        }
    }
95597
public function preFlush(EventArgs $eventArgs)
    {
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            $this->_triggerEvent(Events::preFlush, $entity, $eventArgs);
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            $this->_triggerEvent(Events::preFlush, $entity, $eventArgs);
        }

        foreach ($uow->getScheduledEntityDeletions() as $entity) {
            $this->_triggerEvent(Events::preFlush, $entity, $eventArgs);
        }
    }
1312424
public function postLoad(LifecycleEventArgs $args) {
        $entity = $args->getEntity();
        if (!$this->hasInDecodedRegistry($entity, $args->getEntityManager())) {
            if ($this->processFields($entity, false)) {
                $this->addToDecodedRegistry($entity, $args->getEntityManager());
            }
        }
    }
436785
public function preFlush(PreFlushEventArgs $eventArgs)
    {
        $entityManager = $eventArgs->getEntityManager();
        $unitOfWork = $entityManager->getUnitOfWork();

        foreach ($unitOfWork->getScheduledEntityInsertions() as $object) {
            $this->updateObjectTranslations($entityManager, $object);
        }

        foreach ($unitOfWork->getIdentityMap() as $entities) {
            foreach ($entities as $object) {
                $this->updateObjectTranslations($entityManager, $object);
            }
        }
    }