<commit_before><?php
/**
 * Created by PhpStorm.
 * User: sjoder
 * Date: 23.03.2017
 * Time: 12:22
 */

namespace PM\Bundle\ToolBundle\EventListener;

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use PM\Bundle\ToolBundle\Framework\Annotations\Encrypted;
use PM\Bundle\ToolBundle\Framework\Interfaces\EncryptedEntityInterface;
use PM\Bundle\ToolBundle\Framework\Utilities\CryptUtility;

/**
 * Class EncryptionSubscriber
 *
 * @package PM\Bundle\ToolBundle\EventListener
 */
class EncryptionSubscriber implements EventSubscriber
{
    const METHOD_ENCRYPT = 'encrypt';
    const METHOD_DECRYPT = 'decrypt';

    /**
     * @var string
     */
    private $secret;

    /**
     * @var AnnotationReader
     */
    private $reader;

    /**
     * EncryptionSubscriber constructor.
     *
     * @param AnnotationReader $reader
     * @param string           $secret
     */
    public function __construct(AnnotationReader $reader, $secret)
    {
        $this->reader = $reader;
        $this->secret = $secret;
    }

    /**
     * @return AnnotationReader
     */
    public function getReader()
    {
        return $this->reader;
    }

    /**
     * @return string
     */
    public function getSecret()
    {
        return $this->secret;
    }

    /**
     * Get Subscribed Events
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        $secret = $this->getSecret();

        if (true === empty($secret)) {
            return [];
        }

        return [
            'postLoad',
            'preFlush',
            'preUpdate'
        ];
    }

    /**
     * PostLoad: Decrypt
     *
     * @param LifecycleEventArgs $args
     */
    public function postLoad($args)
    {
        $this->process($args->getEntity(), self::METHOD_DECRYPT);
    }

    /**
     * PreFlush: Encrypt
     *
     * @param PreFlushEventArgs $args
     */
    public function preFlush(PreFlushEventArgs $args)
    {
        foreach ($args->getEntityManager()->getUnitOfWork()->getScheduledEntityInsertions() as $entity) {
            $this->process($entity, self::METHOD_ENCRYPT);
        }
    }

    /**
     * Pre Update: Encrypt
     *
     * @param PreUpdateEventArgs $args
     */
    public function preUpdate(PreUpdateEventArgs $args)
    {
        foreach ($args->getEntityManager()->getUnitOfWork()->getScheduledEntityUpdates() as $entity) {
            $this->process($entity, self::METHOD_ENCRYPT);
        }

    }

    /**
     * Process
     *
     * @param mixed  $entity
     * @param string $method
     *
     * @return bool
     */
    private function process($entity, $method)
    {
        if (false === ($entity instanceof EncryptedEntityInterface)) {
            return false;
        }

        if (null !== $entity->isEncrypted() && ((self::METHOD_ENCRYPT === $method && true === $entity->isEncrypted()) || (self::METHOD_DECRYPT === $method) && false === $entity->isEncrypted())) {
            return false;
        }

        $entityClass = get_class($entity);
        $encryptionKey = substr(hash('sha256', $this->getSecret()), 1, 32);

        $reflectionClass = new \ReflectionClass($entityClass);
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
            /** @var Encrypted $propertyAnnotation */
            $propertyAnnotation = $this->getReader()->getPropertyAnnotation($reflectionProperty, Encrypted::class);
            if (null === $propertyAnnotation) {
                continue;
            }

            $reflectionProperty->setAccessible(true);

            $fieldValue = $reflectionProperty->getValue($entity);

            if (null === $fieldValue || true === empty($fieldValue)) {
                continue;
            }

            $reflectionProperty->setValue($entity, CryptUtility::$method($fieldValue, $encryptionKey));
        }<commit_msg>another fix<commit_after><?php
/**
 * Created by PhpStorm.
 * User: sjoder
 * Date: 23.03.2017
 * Time: 12:22
 */

namespace PM\Bundle\ToolBundle\EventListener;

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use PM\Bundle\ToolBundle\Framework\Annotations\Encrypted;
use PM\Bundle\ToolBundle\Framework\Interfaces\EncryptedEntityInterface;
use PM\Bundle\ToolBundle\Framework\Utilities\CryptUtility;

/**
 * Class EncryptionSubscriber
 *
 * @package PM\Bundle\ToolBundle\EventListener
 */
class EncryptionSubscriber implements EventSubscriber
{
    const METHOD_ENCRYPT = 'encrypt';
    const METHOD_DECRYPT = 'decrypt';

    /**
     * @var string
     */
    private $secret;

    /**
     * @var AnnotationReader
     */
    private $reader;

    /**
     * EncryptionSubscriber constructor.
     *
     * @param AnnotationReader $reader
     * @param string           $secret
     */
    public function __construct(AnnotationReader $reader, $secret)
    {
        $this->reader = $reader;
        $this->secret = $secret;
    }

    /**
     * @return AnnotationReader
     */
    public function getReader()
    {
        return $this->reader;
    }

    /**
     * @return string
     */
    public function getSecret()
    {
        return $this->secret;
    }

    /**
     * Get Subscribed Events
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        $secret = $this->getSecret();

        if (true === empty($secret)) {
            return [];
        }

        return [
            'postLoad',
            'preFlush',
            'preUpdate'
        ];
    }

    /**
     * PostLoad: Decrypt
     *
     * @param LifecycleEventArgs $args
     */
    public function postLoad($args)
    {
        $this->process($args->getEntity(), self::METHOD_DECRYPT);
    }

    /**
     * PreFlush: Encrypt
     *
     * @param PreFlushEventArgs $args
     */
    public function preFlush(PreFlushEventArgs $args)
    {
        foreach ($args->getEntityManager()->getUnitOfWork()->getScheduledEntityInsertions() as $entity) {
            $this->process($entity, self::METHOD_ENCRYPT);
        }
    }

    /**
     * Pre Update: Encrypt
     *
     * @param PreUpdateEventArgs $args
     */
    public function preUpdate(PreUpdateEventArgs $args)
    {
        foreach ($args->getEntityManager()->getUnitOfWork()->getScheduledEntityUpdates() as $entity) {
            $this->process($entity, self::METHOD_ENCRYPT);
        }

    }

    /**
     * Process
     *
     * @param mixed  $entity
     * @param string $method
     *
     * @return bool
     */
    private function process($entity, $method)
    {
        if (false === ($entity instanceof EncryptedEntityInterface)) {
            return false;
        }

        if (null !== $entity->isEncrypted() && ((self::METHOD_ENCRYPT === $method && true === $entity->isEncrypted()) || (self::METHOD_DECRYPT === $method && false === $entity->isEncrypted()))) {
            return false;
        }

        $entityClass = get_class($entity);
        $encryptionKey = substr(hash('sha256', $this->getSecret()), 1, 32);

        $reflectionClass = new \ReflectionClass($entityClass);
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
            /** @var Encrypted $propertyAnnotation */
            $propertyAnnotation = $this->getReader()->getPropertyAnnotation($reflectionProperty, Encrypted::class);
            if (null === $propertyAnnotation) {
                continue;
            }

            $reflectionProperty->setAccessible(true);

            $fieldValue = $reflectionProperty->getValue($entity);

            if (null === $fieldValue || true === empty($fieldValue)) {
                continue;
            }

            $reflectionProperty->setValue($entity, CryptUtility::$method($fieldValue, $encryptionKey));
        }
{'fraction_non_alphanumeric': 0.1330514797314101, 'fraction_numerical': 0.004476498383486694, 'mean_word_length': 2.3235537190082645, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, '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': '1351635', 'n_tokens_mistral': 2323, 'n_tokens_neox': 2220, 'n_words': 419}