Issues (163)

Subscriber/DoctrineProxySubscriber.php (3 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace JMS\Serializer\EventDispatcher\Subscriber;
6
7
use Doctrine\Common\Persistence\Proxy as LegacyProxy;
0 ignored issues
show
The type Doctrine\Common\Persistence\Proxy was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Doctrine\ODM\MongoDB\PersistentCollection as MongoDBPersistentCollection;
0 ignored issues
show
The type Doctrine\ODM\MongoDB\PersistentCollection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Doctrine\ODM\PHPCR\PersistentCollection as PHPCRPersistentCollection;
10
use Doctrine\ORM\PersistentCollection;
11
use Doctrine\Persistence\Proxy;
12
use JMS\Serializer\EventDispatcher\EventDispatcherInterface;
13
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
14
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
15
use ProxyManager\Proxy\LazyLoadingInterface;
16
17
final class DoctrineProxySubscriber implements EventSubscriberInterface
18
{
19
    /**
20
     * @var bool
21
     */
22
    private $skipVirtualTypeInit;
23
24
    /**
25
     * @var bool
26
     */
27
    private $initializeExcluded;
28 338
29
    public function __construct(bool $skipVirtualTypeInit = true, bool $initializeExcluded = false)
30 338
    {
31 338
        $this->skipVirtualTypeInit = $skipVirtualTypeInit;
32 338
        $this->initializeExcluded = $initializeExcluded;
33
    }
34 14
35
    public function onPreSerialize(PreSerializeEvent $event): void
36 14
    {
37 14
        $object = $event->getObject();
38
        $type = $event->getType();
39
40
        // If the set type name is not an actual class, but a faked type for which a custom handler exists, we do not
41
        // modify it with this subscriber. Also, we forgo autoloading here as an instance of this type is already created,
42 14
        // so it must be loaded if its a real class.
43
        $virtualType = !class_exists($type['name'], false);
44 14
45 14
        if (
46 14
            $object instanceof PersistentCollection
47
            || $object instanceof MongoDBPersistentCollection
48 1
            || $object instanceof PHPCRPersistentCollection
49 1
        ) {
50
            if (!$virtualType) {
51
                $event->setType('ArrayCollection');
52 1
            }
53
54
            return;
55 14
        }
56 14
57
        if (
58 3
            ($this->skipVirtualTypeInit && $virtualType) ||
59
            (!$object instanceof Proxy && !$object instanceof LazyLoadingInterface)
60
        ) {
61
            return;
62 11
        }
63 11
64 11
        // do not initialize the proxy if is going to be excluded by-class by some exclusion strategy
65 11
        if (false === $this->initializeExcluded && !$virtualType) {
66 11
            $context = $event->getContext();
67 2
            $exclusionStrategy = $context->getExclusionStrategy();
68
            $metadata = $context->getMetadataFactory()->getMetadataForClass(get_parent_class($object));
69
            if (null !== $metadata && null !== $exclusionStrategy && $exclusionStrategy->shouldSkipClass($metadata, $context)) {
0 ignored issues
show
It seems like $metadata can also be of type Metadata\ClassHierarchyMetadata; however, parameter $metadata of JMS\Serializer\Exclusion...face::shouldSkipClass() does only seem to accept JMS\Serializer\Metadata\ClassMetadata, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
            if (null !== $metadata && null !== $exclusionStrategy && $exclusionStrategy->shouldSkipClass(/** @scrutinizer ignore-type */ $metadata, $context)) {
Loading history...
70
                return;
71 10
            }
72
        }
73 10
74 9
        if ($object instanceof LazyLoadingInterface) {
75
            $object->initializeProxy();
76 10
        } else {
77
            $object->__load();
78 8
        }
79
80 8
        if (!$virtualType) {
81
            $event->setType(get_parent_class($object), $type['params']);
82 8
        }
83 1
    }
84
85
    public function onPreSerializeTypedProxy(PreSerializeEvent $event, string $eventName, string $class, string $format, EventDispatcherInterface $dispatcher): void
86 7
    {
87 7
        $type = $event->getType();
88 7
        // is a virtual type? then there is no need to change the event name
89
        if (!class_exists($type['name'], false)) {
90
            return;
91 7
        }
92 7
93 7
        $object = $event->getObject();
94 7
        if ($object instanceof Proxy) {
95
            $parentClassName = get_parent_class($object);
96
97 7
            // check if this is already a re-dispatch
98 7
            if (strtolower($class) !== strtolower($parentClassName)) {
99
                $event->stopPropagation();
100
                $newEvent = new PreSerializeEvent($event->getContext(), $object, ['name' => $parentClassName, 'params' => $type['params']]);
101 7
                $dispatcher->dispatch($eventName, $parentClassName, $format, $newEvent);
102
103 338
                // update the type in case some listener changed it
104
                $newType = $newEvent->getType();
105
                $event->setType($newType['name'], $newType['params']);
106 338
            }
107
        }
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public static function getSubscribedEvents()
114
    {
115
        return [
116
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerializeTypedProxy', 'interface' => Proxy::class],
117
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerializeTypedProxy', 'interface' => LegacyProxy::class],
118
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize', 'interface' => PersistentCollection::class],
119
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize', 'interface' => MongoDBPersistentCollection::class],
120
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize', 'interface' => PHPCRPersistentCollection::class],
121
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize', 'interface' => Proxy::class],
122
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize', 'interface' => LegacyProxy::class],
123
            ['event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize', 'interface' => LazyLoadingInterface::class],
124
        ];
125
    }
126
}
127