<commit_before><?php

/*
 * This file is part of the Integrated package.
 *
 * (c) e-Active B.V. <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Integrated\Bundle\SlugBundle\EventListener;

use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessor;

use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;

use Doctrine\ODM\MongoDB\Event\PreUpdateEventArgs as ODMPreUpdateEventArgs;
use Doctrine\ODM\MongoDB\UnitOfWork as ODMUnitOfWork;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\DocumentRepository;

use Doctrine\ORM\Event\PreUpdateEventArgs as ORMPreUpdateEventArgs;
use Doctrine\ORM\UnitOfWork as ORMUnitOfWork;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

use Metadata\MetadataFactoryInterface;

use Integrated\Bundle\SlugBundle\Mapping\Metadata\PropertyMetadata;
use Integrated\Bundle\SlugBundle\Slugger\SluggerInterface;

/**
 * Doctrine ORM and ODM subscriber for slug generation
 *
 * @author <NAME> <<EMAIL>>
 */
class SluggableSubscriber implements EventSubscriber
{
    /**
     * @var MetadataFactoryInterface
     */
    private $metadataFactory;

    /**
     * @var SluggerInterface
     */
    private $slugger;

    /**
     * @var PropertyAccessor
     */
    private $propertyAccessor;

    /**
     * @param MetadataFactoryInterface $metadataFactory
     * @param SluggerInterface         $slugger
     */
    public function __construct(MetadataFactoryInterface $metadataFactory, SluggerInterface $slugger)
    {
        $this->metadataFactory = $metadataFactory;
        $this->slugger = $slugger;
        $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
    }

    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return [
            'prePersist',
            //'postPersist', // @todo
            'preUpdate',
            //'onFlush', // @todo implement to support update after a persist
        ];
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        // used for slug as id
        $this->handleEvent($args);
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function postPersist(LifecycleEventArgs $args)
    {
        // used for id in slug
        $this->handleEvent($args);
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args)
    {
        $this->handleEvent($args);
    }

    /**
     * @param LifecycleEventArgs $args
     */
    protected function handleEvent(LifecycleEventArgs $args)
    {
        $object = $args->getObject();
        $om = $args->getObjectManager();

        $classMetadata = $this->metadataFactory->getMetadataForClass(get_class($object));

        foreach ($classMetadata->propertyMetadata as $propertyMetadata) {

            if ($propertyMetadata instanceof PropertyMetadata && count($propertyMetadata->slugFields)) {

                if ($args instanceof ODMPreUpdateEventArgs || $args instanceof ORMPreUpdateEventArgs) {

                    if ($args->hasChangedField($propertyMetadata->name)) {
                        // generate custom slug
                        $slug = $this->slugger->slugify($args->getNewValue($propertyMetadata->name));

                    } else {
                        return; // no changes
                    }

                } else {
                    // generate custom slug
                    $slug = $this->slugger->slugify($propertyMetadata->getValue($object));
                }

                if (!trim($slug)) {
                    // generate slug from the sluggable fields<commit_msg>Added check to prevent duplicate slug generation<commit_after><?php

/*
 * This file is part of the Integrated package.
 *
 * (c) e-Active B.V. <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Integrated\Bundle\SlugBundle\EventListener;

use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessor;

use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;

use Doctrine\ODM\MongoDB\UnitOfWork as ODMUnitOfWork;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\DocumentRepository;

use Doctrine\ORM\UnitOfWork as ORMUnitOfWork;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

use Metadata\MetadataFactoryInterface;

use Integrated\Bundle\SlugBundle\Mapping\Metadata\PropertyMetadata;
use Integrated\Bundle\SlugBundle\Slugger\SluggerInterface;

/**
 * Doctrine ORM and ODM subscriber for slug generation
 *
 * @author <NAME> <<EMAIL>>
 */
class SluggableSubscriber implements EventSubscriber
{
    /**
     * @var MetadataFactoryInterface
     */
    private $metadataFactory;

    /**
     * @var SluggerInterface
     */
    private $slugger;

    /**
     * @var PropertyAccessor
     */
    private $propertyAccessor;

    /**
     * @param MetadataFactoryInterface $metadataFactory
     * @param SluggerInterface         $slugger
     */
    public function __construct(MetadataFactoryInterface $metadataFactory, SluggerInterface $slugger)
    {
        $this->metadataFactory = $metadataFactory;
        $this->slugger = $slugger;
        $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
    }

    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return [
            'prePersist',
            'postPersist',
            'preUpdate',
            //'onFlush', // @todo implement to support update after a persist
        ];
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        // used for slug as id
        $this->handleEvent($args, 'prePersist');
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function postPersist(LifecycleEventArgs $args)
    {
        // used for id in slug
        $this->handleEvent($args, 'postPersist');
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args)
    {
        $this->handleEvent($args, 'preUpdate');
    }

    /**
     * @param LifecycleEventArgs $args
     * @param string             $event
     */
    protected function handleEvent(LifecycleEventArgs $args, $event)
    {
        $object = $args->getObject();
        $om = $args->getObjectManager();
        $class = get_class($object);

        $classMetadata = $this->metadataFactory->getMetadataForClass($class);
        $classMetadataInfo = $om->getClassMetadata($class);

        $identifierFields = $classMetadataInfo->getIdentifierFieldNames();

        foreach ($classMetadata->propertyMetadata as $propertyMetadata) {

            if ($propertyMetadata instanceof PropertyMetadata && count($propertyMetadata->slugFields)) {

                $hasIdentifierFields = count(array_intersect($identifierFields, $propertyMetadata->slugFields)) > 0;

                if ($event == 'prePersist' && $hasIdentifierFields || $event == 'postPersist' && !$hasIdentifierFields) {
                    continue; // generate slug in another event
                }

                if ($event == 'preUpdate') {

                    if ($args->hasChangedField($propertyMetadata->name)) {
                        // generate custom slug
                        $slug = $this->slugger->slugify($args->getNewValue($propertyMetadata->name));

                    } else {
                        continue; // no changes
                    }

                } else {
                    // generate custom slug
                    $slug = $this->slugger->slugify($propertyMetadata->getValue($object));
                }

                if (!trim($slug)) {
                    // generate slug from the sluggable fields
{'fraction_non_alphanumeric': 0.10705274540430133, 'fraction_numerical': 0.00012014898474107894, 'mean_word_length': 2.510754955714888, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 59, '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': '4212117', 'n_tokens_mistral': 2255, 'n_tokens_neox': 2182, 'n_words': 476}