steevanb / doctrine-read-only-hydrator

Add SimpleObject and ReadOnly hydrators do Doctrine.
GNU General Public License v3.0
57 stars 14 forks source link

Incompatible with newer doctrine #22

Closed FluffyDiscord closed 2 years ago

FluffyDiscord commented 3 years ago

Argument 1 passed to steevanb\DoctrineReadOnlyHydrator\EventSubscriber\ReadOnlySubscriber::postLoad() must be an instance of Doctrine\Common\Persistence\Event\LifecycleEventArgs, instance of Doctrine\ORM\Event\LifecycleEventArgs given, called in \vendor\symfony\doctrine-bridge\ContainerAwareEventManager.php on line 64

composer.json snipplet

"require": {
    "php": "7.4",
    "ext-ctype": "*",
    "ext-curl": "*",
    "ext-decimal": "*",
    "ext-dom": "*",
    "ext-iconv": "*",
    "ext-imagick": "*",
    "ext-json": "*",
    "ext-libxml": "*",
    "ext-pdo": "*",
    "ext-xmlreader": "*",
    "ext-xmlwriter": "*",
    "ext-zlib": "*",
    "alex.oleshkevich/fast-xml-parser": "^1.0",
    "alsatian/form-bundle": "^1.0",
    "beberlei/doctrineextensions": "^1.3",
    "cocur/slugify": "^4.0",
    "doctrine/annotations": "^1.0",
    "duzun/hquery": "^3.0",
    "gedmo/doctrine-extensions": "^3.0",
    "guzzlehttp/guzzle": "^7.2",
    "helios-ag/fm-elfinder-bundle": "^10.1",
    "knplabs/doctrine-behaviors": "^2.0",
    "liip/imagine-bundle": "^2.3",
    "maennchen/zipstream-php": "^2.1",
    "nelmio/cors-bundle": "^2.1",
    "nyholm/psr7": "^1.4",
    "nzo/url-encryptor-bundle": "^6.0",
    "openlss/lib-array2xml": "^1.0",
    "phpdocumentor/reflection-docblock": "^5.2",
    "phpoffice/phpspreadsheet": "^1.18",
    "scienta/doctrine-json-functions": "^4.3",
    "sensio/framework-extra-bundle": "^5.2",
    "spatie/browsershot": "^3.44",
    "steevanb/doctrine-read-only-hydrator": "2.3",
    "symfony-bundles/json-request-bundle": "^4.0",
    "symfony/apache-pack": "^1.0",
    "symfony/asset": "5.2.*",
    "symfony/console": "5.2.*",
    "symfony/doctrine-messenger": "5.2.*",
    "symfony/dotenv": "5.2.*",
    "symfony/expression-language": "5.2.*",
    "symfony/flex": "1.12.2",
    "symfony/form": "5.2.*",
    "symfony/framework-bundle": "5.2.*",
    "symfony/http-client": "5.2.*",
    "symfony/intl": "5.2.*",
    "symfony/mailer": "5.2.*",
    "symfony/messenger": "5.2.*",
    "symfony/monolog-bundle": "^3.6",
    "symfony/orm-pack": "^2.1",
    "symfony/process": "5.2.*",
    "symfony/property-access": "5.2.*",
    "symfony/property-info": "5.2.*",
    "symfony/proxy-manager-bridge": "5.2.*",
    "symfony/security-bundle": "5.2.*",
    "symfony/serializer": "5.2.*",
    "symfony/translation": "5.2.*",
    "symfony/twig-bundle": "5.2.*",
    "symfony/validator": "5.2.*",
    "symfony/web-link": "5.2.*",
    "symfony/webpack-encore-bundle": "^1.6",
    "symfony/yaml": "5.2.*",
    "thepay/api-client": "^1.2",
    "zenstruck/schedule-bundle": "^1.0"
  },
  "require-dev": {
    "alexandresalome/doctrine-extra-bundle": "^0.3.4",
    "doctrine/doctrine-fixtures-bundle": "^3.2",
    "symfony/debug-pack": "*",
    "symfony/maker-bundle": "^1.13",
    "symfony/profiler-pack": "*",
    "symfony/test-pack": "*"
  },
  "config": {
    "platform": {
      "php": "7.4" 
    },
    "preferred-install": {
      "*": "dist"
    },
    "sort-packages": true
  },
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  },
  "autoload-dev": {
    "psr-4": {
      "App\\Tests\\": "tests/"
    }
  },
  "replace": {
    "paragonie/random_compat": "2.*",
    "symfony/polyfill-ctype": "*",
    "symfony/polyfill-iconv": "*",
    "symfony/polyfill-php71": "*",
    "symfony/polyfill-php70": "*",
    "symfony/polyfill-php56": "*"
  },
  "conflict": {
    "symfony/symfony": "*"
  },
  "extra": {
    "symfony": {
      "allow-contrib": "true",
      "require": "5.2.*"
    }
  }
steevanb commented 3 years ago

The doctrine mentality "it's not a BC break" will kill me one day :p

steevanb commented 3 years ago

Could you please try composer require steevanb/doctrine-read-only-hydrator:dev-event-args#12af28d6d46d2bc33412d56d172a014c2e7bd54c and tell me if it's ok for you?

FluffyDiscord commented 3 years ago

even worse - didnt change anything except the composer require above

Attempted to load class "ReadOnlyHydratorBundle" from namespace "steevanb\DoctrineReadOnlyHydrator\Bridge\ReadOnlyHydratorBundle".
Did you forget a "use" statement for another namespace?
FluffyDiscord commented 3 years ago

this works correctly

steevanb\DoctrineReadOnlyHydrator\EventSubscriber\ReadOnlySubscriber

<?php

namespace steevanb\DoctrineReadOnlyHydrator\EventSubscriber;

use Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs;
use steevanb\DoctrineReadOnlyHydrator\Hydrator\SimpleObjectHydrator;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Events;
use steevanb\DoctrineReadOnlyHydrator\Entity\ReadOnlyEntityInterface;
use steevanb\DoctrineReadOnlyHydrator\Exception\ReadOnlyEntityCantBeFlushedException;
use steevanb\DoctrineReadOnlyHydrator\Exception\ReadOnlyEntityCantBePersistedException;

class ReadOnlySubscriber implements EventSubscriber
{
    /** @return array */
    public function getSubscribedEvents()
    {
        return [
            Events::prePersist,
            Events::preFlush,
            Events::onClassMetadataNotFound,
            Events::postLoad
        ];
    }

    public function prePersist($args)
    {
        if ($this->isReadOnlyEntity($args->getObject())) {
            throw new ReadOnlyEntityCantBePersistedException($args->getObject());
        }
    }

    public function preFlush($args)
    {
        $unitOfWork = $args->getEntityManager()->getUnitOfWork();
        $entities = array_merge(
            $unitOfWork->getScheduledEntityInsertions(),
            $unitOfWork->getScheduledEntityUpdates(),
            $unitOfWork->getScheduledEntityDeletions()
        );
        foreach ($entities as $entity) {
            if ($this->isReadOnlyEntity($entity)) {
                throw new ReadOnlyEntityCantBeFlushedException($entity);
            }
        }
    }

    public function onClassMetadataNotFound($eventArgs)
    {
        try {
            // added check here, or else I have notices about classes not existing 
            if(empty($eventArgs->getClassName())) {
                return;
            }
            if (class_implements(
                $eventArgs->getClassName(),
                'steevanb\\DoctrineReadOnlyHydrator\\Entity\\ReadOnlyEntityInterface'
            )) {
                $eventArgs->setFoundMetadata(
                    $eventArgs->getObjectManager()->getClassMetadata(get_parent_class($eventArgs->getClassName()))
                );
            }
        } catch (\Exception $exception) {}
    }

    public function postLoad($eventArgs)
    {
        if ($eventArgs->getObject() instanceof ReadOnlyEntityInterface) {
            // add ReadOnlyProxy to classMetada list
            // without it, you can't use Doctrine automatic id finder
            // like $queryBuilder->setParameter('foo', $foo)
            // instead of  $queryBuilder->setParameter('foo', $foo->getId())
            $eventArgs->getObjectManager()->getClassMetadata(get_class($eventArgs->getObject()));
        }
    }

    /**
     * @param object $entity
     * @return bool
     */
    protected function isReadOnlyEntity($entity)
    {
        return
            $entity instanceof ReadOnlyEntityInterface
            || isset($entity->{SimpleObjectHydrator::READ_ONLY_PROPERTY});
    }
}

EDIT: small correction

FluffyDiscord commented 2 years ago

made myself a fork that suits my needs, closing down this issue