Completed
Push — master ( bead68...29f6d6 )
by Artem
17:01
created

JmsPreSerializeListener   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
c 1
b 0
f 0
lcom 1
cbo 7
dl 0
loc 104
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
C onPreSerialize() 0 46 7
A getSchemeAndHost() 0 4 1
1
<?php
2
/*
3
 * This file is part of the FreshVichUploaderSerializationBundle
4
 *
5
 * (c) Artem Genvald <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Fresh\VichUploaderSerializationBundle\EventListener;
12
13
use Doctrine\Common\Annotations\CachedReader;
14
use Doctrine\Common\Util\ClassUtils;
15
use Fresh\VichUploaderSerializationBundle\Annotation\VichSerializableField;
16
use Fresh\VichUploaderSerializationBundle\Annotation\VichSerializableClass;
17
use Fresh\VichUploaderSerializationBundle\Exception\IncompatibleUploadableAndSerializableFieldAnnotationException;
18
use JMS\Serializer\EventDispatcher\ObjectEvent;
19
use Monolog\Logger;
20
use Symfony\Component\Routing\RequestContext;
21
use Vich\UploaderBundle\Mapping\Annotation\UploadableField;
22
use Vich\UploaderBundle\Storage\StorageInterface;
23
24
/**
25
 * Class JmsPreSerializeListener
26
 *
27
 * @author Artem Genvald <[email protected]>
28
 */
29
class JmsPreSerializeListener
30
{
31
    /**
32
     * @var StorageInterface $storage Vich storage
33
     */
34
    private $storage;
35
36
    /**
37
     * @var RequestContext $requestContext Request context
38
     */
39
    private $requestContext;
40
41
    /**
42
     * @var CachedReader $annotationReader Cached annotation reader
43
     */
44
    private $annotationReader;
45
46
    /**
47
     * @var Logger $logger Logger
48
     */
49
    private $logger;
50
51
    /**
52
     * Constructor
53
     *
54
     * @param StorageInterface $storage          Vich storage
55
     * @param RequestContext   $requestContext   Request context
56
     * @param CachedReader     $annotationReader Cached annotation reader
57
     * @param Logger           $logger           Logger
58
     */
59
    public function __construct(
60
        StorageInterface $storage,
61
        RequestContext $requestContext,
62
        CachedReader $annotationReader,
63
        Logger $logger
64
    ) {
65
        $this->storage          = $storage;
66
        $this->requestContext   = $requestContext;
67
        $this->annotationReader = $annotationReader;
68
        $this->logger           = $logger;
69
    }
70
71
    /**
72
     * On pre serialize
73
     *
74
     * @param ObjectEvent $event Event
75
     */
76
    public function onPreSerialize(ObjectEvent $event)
77
    {
78
        $object = $event->getObject();
79
80
        $classAnnotation = $this->annotationReader->getClassAnnotation(
81
            new \ReflectionClass(ClassUtils::getClass($object)),
82
            VichSerializableClass::class
83
        );
84
85
        if ($classAnnotation instanceof VichSerializableClass) {
86
            $reflectionClass = ClassUtils::newReflectionClass($object);
87
            $this->logger->debug(sprintf('Found @VichSerializableClass annotation for the class "%s"', $reflectionClass->getName()));
0 ignored issues
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
88
89
            foreach ($reflectionClass->getProperties() as $property) {
90
                $vichSerializableAnnotation = $this->annotationReader->getPropertyAnnotation($property, VichSerializableField::class);
91
92
                if ($vichSerializableAnnotation instanceof VichSerializableField) {
93
                    $vichUploadableFileAnnotation = $this->annotationReader->getPropertyAnnotation($property, UploadableField::class);
94
95
                    if ($vichUploadableFileAnnotation instanceof UploadableField) {
96
                        throw new IncompatibleUploadableAndSerializableFieldAnnotationException(sprintf(
97
                            'The field "%s" in the class "%s" cannot have @UploadableField and @VichSerializableField annotations at the same moment.',
98
                            $property->getName(),
99
                            $reflectionClass->getName()
0 ignored issues
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
100
                        ));
101
                    }
102
                    $this->logger->debug(sprintf(
103
                        'Found @VichSerializableField annotation for the field "%s" in the class "%s"',
104
                        $property->getName(),
105
                        $reflectionClass->getName()
0 ignored issues
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
106
                    ));
107
108
                    $uri = null;
109
                    $property->setAccessible(true);
110
111
                    if ($property->getValue($event->getObject())) {
112
                        $uri = $this->storage->resolveUri($object, $vichSerializableAnnotation->getField());
113
                        if ($vichSerializableAnnotation->isIncludeHost()) {
114
                            $uri = $this->getSchemeAndHost().$uri;
115
                        }
116
                    }
117
                    $property->setValue($object, $uri);
118
                }
119
            }
120
        }
121
    }
122
123
    /**
124
     * Get scheme and host
125
     *
126
     * @return string Scheme and host
127
     */
128
    private function getSchemeAndHost()
129
    {
130
        return $this->requestContext->getScheme().'://'.$this->requestContext->getHost();
131
    }
132
}
133