<commit_before><?php
namespace Ibrows\LoggableBundle\Listener;

use Doctrine\Common\EventArgs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\NoResultException;
use Gedmo\Loggable\Mapping\Event\LoggableAdapter;
use Gedmo\Tool\Wrapper\AbstractWrapper;
use Ibrows\LoggableBundle\Entity\ChangeSet;
use Ibrows\LoggableBundle\Entity\Log;
use Ibrows\LoggableBundle\Entity\LogMany2Many;
use Ibrows\LoggableBundle\Entity\LogParent;
use Ibrows\LoggableBundle\Model\ScheduledChangeable;

/**
 * Class LoggableListener
 * @package Ibrows\LoggableBundle\Listener
 */
class LoggableListener extends \Gedmo\Loggable\LoggableListener
{
    /**
     * @var array
     */
    protected $pendingParents = array();
    /**
     * @var bool
     */
    protected $enabled = true;
    /**
     * @var bool
     */
    protected $useOnySingleIds = true;
    /**
     * @var bool
     */
    protected $defaultAllVersioned = true;
    /**
     * @var string
     */
    protected $abstractLogEntryClass = 'Ibrows\LoggableBundle\Entity\AbstractLog';
    /**
     * @var string
     */
    protected $defaultLogEntryClass = 'Ibrows\LoggableBundle\Entity\Log';
    /**
     * @var string
     */
    protected $logParentEntryClass = 'Ibrows\LoggableBundle\Entity\LogParent';
    /**
     * @var string
     */
    protected $logCollectionEntryClass = 'Ibrows\LoggableBundle\Entity\LogMany2Many';


    /**
     * @param EventArgs $args
     */
    public function postPersist(EventArgs $args)
    {
        parent::postPersist($args);


        $ea = $this->getEventAdapter($args);
        $object = $ea->getObject();
        $om = $ea->getObjectManager();
        $oid = spl_object_hash($object);
        $uow = $om->getUnitOfWork();


        if ($this->pendingParents && array_key_exists($oid, $this->pendingParents)) {
            $wrapped = AbstractWrapper::wrap($object, $om);
            $id = $wrapped->getIdentifier($this->useOnySingleIds);
            foreach ($this->pendingParents[$oid] as $pending) {
                $logEntry = $pending['log'];
                $field = $pending['field'];
                $logEntryMeta = $om->getClassMetadata(get_class($logEntry));
                $logEntryMeta->getReflectionProperty($field)->setValue($logEntry, $id);
                $uow->scheduleExtraUpdate(
                    $logEntry,
                    array(
                        $field => array(null, $id)
                    )
                );
                $ea->setOriginalObjectProperty($uow, spl_object_hash($logEntry), $field, $id);
            }
            unset($this->pendingLogEntryInserts[$oid]);

        }

    }


    /**
     * @param EventArgs $eventArgs
     */
    public function onFlush(EventArgs $eventArgs)
    {
        if (!$this->enabled) {
            return;
        }

        $ea = $this->getEventAdapter($eventArgs);
        $om = $ea->getObjectManager();
        $uow = $om->getUnitOfWork();

        foreach ($ea->getScheduledObjectInsertions($uow) as $object) {
            $this->createLogEntry(self::ACTION_CREATE, $object, $ea);
        }
        foreach ($ea->getScheduledObjectUpdates($uow) as $object) {
            $this->createLogEntry(self::ACTION_UPDATE, $object, $ea);
        }
        foreach ($ea->getScheduledObjectDeletions($uow) as $object) {
            $this->createLogEntry(self::ACTION_REMOVE, $object, $ea);
        }


        foreach ($uow->getScheduledCollectionUpdates() as $collection) {
            $this->createMany2ManyLogEntry(self::ACTION_UPDATE, $collection, $ea);
        }
        foreach ($uow->getScheduledCollectionDeletions() as $collection) {
            $this->createMany2ManyLogEntry(self::ACTION_REMOVE, $collection, $ea);
        }

    }

    /**
     * @param string $action
     * @param object $object
     * @param LoggableAdapter $ea
     */
    protected function createLogEntry($action, $object, LoggableAdapter $ea)
    {
        $om = $ea->getObjectManager();
        $wrapped = AbstractWrapper::wrap($object, $om);
        $meta = $wrapped->getMetadata();
        $config = $this->getConfiguration($om, $meta->name);

        if (!$config && !$this->defaultAllVersioned) {
            return;
        }
        $logEntry = $this->newLogEntry($ea, $meta->name, $action);



        if ($action === self::ACTION_CREATE && $ea->isPostInsertGenerator($meta)) {
            $this->pendingLogEntryInserts[spl_object_hash($object)] = $logEntry;
        } else {
            $logEntry->setObjectId($wrapped->getIdentifier());
        }

        $uow = $om->getUnitOfWork();
        $newValues = array();
        $oldValues = array();

        if ($action !== self::ACTION_REMOVE && (isset($config['versioned']) || $this->defaultAllVersioned)) {
            $changeSet = $ea->getObjectChangeSet($uow, $object);
            foreach ($changeSet as $field => $changes) {
                if (isset($config['versioned']) && !in_array($field, $config['versioned'])) {
                    continue;
                }
                if ($changes[1] == $changes[0]) {
                    continue;
                }

                $value = $changes[1];
                $oldValue = $changes[0];

                if (array_key_exists($field, $meta->associationMappings)) {
                    $fieldmetadata = $meta->associationMappings[$field];
                    if ($fieldmetadata['type'] == \Doctrine\ORM\Mapping\ClassMetadata::MANY_TO_ONE) {
                        //many2one
                        if ($value != null) {
                            $parentLogEntry = $this->addLogParent($ea, $logEntry, $value, self::ACTION_CREATE, $object, $field);
                        } else {<commit_msg>make sure no nesting level fatal error can occur<commit_after><?php
namespace Ibrows\LoggableBundle\Listener;

use Doctrine\Common\EventArgs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\NoResultException;
use Gedmo\Loggable\Mapping\Event\LoggableAdapter;
use Gedmo\Tool\Wrapper\AbstractWrapper;
use Ibrows\LoggableBundle\Entity\ChangeSet;
use Ibrows\LoggableBundle\Entity\Log;
use Ibrows\LoggableBundle\Entity\LogMany2Many;
use Ibrows\LoggableBundle\Entity\LogParent;
use Ibrows\LoggableBundle\Model\ScheduledChangeable;

/**
 * Class LoggableListener
 * @package Ibrows\LoggableBundle\Listener
 */
class LoggableListener extends \Gedmo\Loggable\LoggableListener
{
    /**
     * @var array
     */
    protected $pendingParents = array();
    /**
     * @var bool
     */
    protected $enabled = true;
    /**
     * @var bool
     */
    protected $useOnySingleIds = true;
    /**
     * @var bool
     */
    protected $defaultAllVersioned = true;
    /**
     * @var string
     */
    protected $abstractLogEntryClass = 'Ibrows\LoggableBundle\Entity\AbstractLog';
    /**
     * @var string
     */
    protected $defaultLogEntryClass = 'Ibrows\LoggableBundle\Entity\Log';
    /**
     * @var string
     */
    protected $logParentEntryClass = 'Ibrows\LoggableBundle\Entity\LogParent';
    /**
     * @var string
     */
    protected $logCollectionEntryClass = 'Ibrows\LoggableBundle\Entity\LogMany2Many';


    /**
     * @param EventArgs $args
     */
    public function postPersist(EventArgs $args)
    {
        parent::postPersist($args);


        $ea = $this->getEventAdapter($args);
        $object = $ea->getObject();
        $om = $ea->getObjectManager();
        $oid = spl_object_hash($object);
        $uow = $om->getUnitOfWork();


        if ($this->pendingParents && array_key_exists($oid, $this->pendingParents)) {
            $wrapped = AbstractWrapper::wrap($object, $om);
            $id = $wrapped->getIdentifier($this->useOnySingleIds);
            foreach ($this->pendingParents[$oid] as $pending) {
                $logEntry = $pending['log'];
                $field = $pending['field'];
                $logEntryMeta = $om->getClassMetadata(get_class($logEntry));
                $logEntryMeta->getReflectionProperty($field)->setValue($logEntry, $id);
                $uow->scheduleExtraUpdate(
                    $logEntry,
                    array(
                        $field => array(null, $id)
                    )
                );
                $ea->setOriginalObjectProperty($uow, spl_object_hash($logEntry), $field, $id);
            }
            unset($this->pendingLogEntryInserts[$oid]);

        }

    }


    /**
     * @param EventArgs $eventArgs
     */
    public function onFlush(EventArgs $eventArgs)
    {
        if (!$this->enabled) {
            return;
        }

        $ea = $this->getEventAdapter($eventArgs);
        $om = $ea->getObjectManager();
        $uow = $om->getUnitOfWork();

        foreach ($ea->getScheduledObjectInsertions($uow) as $object) {
            $this->createLogEntry(self::ACTION_CREATE, $object, $ea);
        }
        foreach ($ea->getScheduledObjectUpdates($uow) as $object) {
            $this->createLogEntry(self::ACTION_UPDATE, $object, $ea);
        }
        foreach ($ea->getScheduledObjectDeletions($uow) as $object) {
            $this->createLogEntry(self::ACTION_REMOVE, $object, $ea);
        }


        foreach ($uow->getScheduledCollectionUpdates() as $collection) {
            $this->createMany2ManyLogEntry(self::ACTION_UPDATE, $collection, $ea);
        }
        foreach ($uow->getScheduledCollectionDeletions() as $collection) {
            $this->createMany2ManyLogEntry(self::ACTION_REMOVE, $collection, $ea);
        }

    }

    /**
     * @param string $action
     * @param object $object
     * @param LoggableAdapter $ea
     */
    protected function createLogEntry($action, $object, LoggableAdapter $ea)
    {
        $om = $ea->getObjectManager();
        $wrapped = AbstractWrapper::wrap($object, $om);
        $meta = $wrapped->getMetadata();
        $config = $this->getConfiguration($om, $meta->name);

        if (!$config && !$this->defaultAllVersioned) {
            return;
        }
        $logEntry = $this->newLogEntry($ea, $meta->name, $action);



        if ($action === self::ACTION_CREATE && $ea->isPostInsertGenerator($meta)) {
            $this->pendingLogEntryInserts[spl_object_hash($object)] = $logEntry;
        } else {
            $logEntry->setObjectId($wrapped->getIdentifier());
        }

        $uow = $om->getUnitOfWork();
        $newValues = array();
        $oldValues = array();

        if ($action !== self::ACTION_REMOVE && (isset($config['versioned']) || $this->defaultAllVersioned)) {
            $changeSet = $ea->getObjectChangeSet($uow, $object);
            foreach ($changeSet as $field => $changes) {
                if (isset($config['versioned']) && !in_array($field, $config['versioned'])) {
                    continue;
                }
                if(is_object($changes[1]) && is_object($changes[0])){
                    // use === if both an object
                    if ($changes[1] === $changes[0]) {
                        continue;
                    }
                }else{
                    if ($changes[1] == $changes[0]) {
                        continue;
                    }
                }


                $value = $changes[1];
                $oldValue = $changes[0];

                if (array_key_exists($field, $meta->associationMappings)) {
                    $fieldmetadata = $meta->associationMappings[$field];
                    if ($fieldmetadata['type'] == \Doctrine\ORM\Mapping\ClassMetadata::MANY_TO_ONE) {
                        //many2one
                        if ($value != null) {
                            $parentLogEntry = $this->addLogParent($ea, $logEntry, $value, self::ACTION_CREATE, $object, $field);
                        } else {
{'fraction_non_alphanumeric': 0.1433965502445722, 'fraction_numerical': 0.001887925856002746, 'mean_word_length': 2.174611822391719, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 99, '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': '4865609', 'n_tokens_mistral': 3439, 'n_tokens_neox': 3329, 'n_words': 550}