Completed
Pull Request — master (#3)
by
unknown
02:33
created

JmsPreSerializeListener::getHostUrl()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 6
Ratio 42.86 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 6
loc 14
rs 8.2222
cc 7
eloc 7
nc 4
nop 0
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
     * @var array $serializedObjects Serialized objects
53
     */
54
    private $serializedObjects = [];
55
56
    /**
57
     * Constructor
58
     *
59
     * @param StorageInterface $storage          Vich storage
60
     * @param RequestContext   $requestContext   Request context
61
     * @param CachedReader     $annotationReader Cached annotation reader
62
     * @param Logger           $logger           Logger
63
     */
64
    public function __construct(
65
        StorageInterface $storage,
66
        RequestContext $requestContext,
67
        CachedReader $annotationReader,
68
        Logger $logger
69
    ) {
70
        $this->storage          = $storage;
71
        $this->requestContext   = $requestContext;
72
        $this->annotationReader = $annotationReader;
73
        $this->logger           = $logger;
74
    }
75
76
    /**
77
     * On pre serialize
78
     *
79
     * @param ObjectEvent $event Event
80
     */
81
    public function onPreSerialize(ObjectEvent $event)
82
    {
83
        $object = $event->getObject();
84
85
        $objectUid = spl_object_hash($object);
86
        if (in_array($objectUid, $this->serializedObjects)) {
87
            return;
88
        }
89
90
        $classAnnotation = $this->annotationReader->getClassAnnotation(
91
            new \ReflectionClass(ClassUtils::getClass($object)),
92
            VichSerializableClass::class
93
        );
94
95
        if ($classAnnotation instanceof VichSerializableClass) {
96
            $reflectionClass = ClassUtils::newReflectionClass(get_class($object));
97
            $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...
98
99
            foreach ($reflectionClass->getProperties() as $property) {
100
                $vichSerializableAnnotation = $this->annotationReader->getPropertyAnnotation($property, VichSerializableField::class);
101
102
                if ($vichSerializableAnnotation instanceof VichSerializableField) {
103
                    $vichUploadableFileAnnotation = $this->annotationReader->getPropertyAnnotation($property, UploadableField::class);
104
105
                    if ($vichUploadableFileAnnotation instanceof UploadableField) {
106
                        throw new IncompatibleUploadableAndSerializableFieldAnnotationException(sprintf(
107
                            'The field "%s" in the class "%s" cannot have @UploadableField and @VichSerializableField annotations at the same moment.',
108
                            $property->getName(),
109
                            $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...
110
                        ));
111
                    }
112
                    $this->logger->debug(sprintf(
113
                        'Found @VichSerializableField annotation for the field "%s" in the class "%s"',
114
                        $property->getName(),
115
                        $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...
116
                    ));
117
118
                    $uri = null;
119
                    $property->setAccessible(true);
120
121
                    if ($property->getValue($event->getObject())) {
122
                        $uri = $this->storage->resolveUri($object, $vichSerializableAnnotation->getField());
123
                        if ($vichSerializableAnnotation->isIncludeHost()) {
124
                            $uri = $this->getHostUrl().$uri;
125
                        }
126
                    }
127
                    $property->setValue($object, $uri);
128
                }
129
            }
130
131
            $this->serializedObjects[$objectUid] = $objectUid;
132
        }
133
    }
134
135
    /**
136
     * Get host url (scheme, host, port)
137
     *
138
     * @return string Host url
139
     */
140
    private function getHostUrl()
141
    {
142
        $url = $this->requestContext->getScheme().'://'.$this->requestContext->getHost();
143
144 View Code Duplication
        if ($this->requestContext->getScheme() == 'http' && $this->requestContext->getHttpPort() && $this->requestContext->getHttpPort() != 80) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
145
            $url .= ':'.$this->requestContext->getHttpPort();
146
        }
147
148 View Code Duplication
        if ($this->requestContext->getScheme() == 'https' && $this->requestContext->getHttpsPort() && $this->requestContext->getHttpsPort() != 443) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
            $url .= ':'.$this->requestContext->getHttpsPort();
150
        }
151
152
        return $url;
153
    }
154
}
155