Passed
Pull Request — master (#52)
by Daniel
06:37
created

FileListener::preRemove()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentBundle\EventListener\Doctrine;
15
16
use Doctrine\ORM\EntityManagerInterface;
17
use Doctrine\ORM\Event\LifecycleEventArgs;
18
use Doctrine\ORM\Mapping\ClassMetadataInfo;
19
use Doctrine\Persistence\Event\LoadClassMetadataEventArgs;
20
use Silverback\ApiComponentBundle\Exception\OutOfBoundsException;
21
use Silverback\ApiComponentBundle\Helper\FileHelper;
22
use Silverback\ApiComponentBundle\Helper\UploadsHelper;
23
24
/**
25
 * Configures mapping between Uploads and MediaObject resources.
26
 *
27
 * @author Daniel West <[email protected]>
28
 */
29
class FileListener
30
{
31
    private FileHelper $fileHelper;
32
    private UploadsHelper $uploadsHelper;
33
34 9
    public function __construct(FileHelper $fileHelper, UploadsHelper $uploadsHelper)
35
    {
36 9
        $this->fileHelper = $fileHelper;
37 9
        $this->uploadsHelper = $uploadsHelper;
38 9
    }
39
40 9
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
41
    {
42
        /** @var ClassMetadataInfo $fileClassMetadata */
43 9
        $fileClassMetadata = $eventArgs->getClassMetadata();
44 9
        if (!$this->fileHelper->isConfigured($fileClassMetadata->getName())) {
45 9
            return;
46
        }
47
48 9
        $fileConfiguration = $this->fileHelper->getConfiguration($fileClassMetadata->getName());
49 9
        if (!$this->uploadsHelper->isConfigured($fileConfiguration->uploadsEntityClass)) {
50
            throw new OutOfBoundsException('The value of uploadsEntityClass on your MediaObject is not configured as an Uploads resource');
51
        }
52
53 9
        $uploadsConfiguration = $this->uploadsHelper->getConfiguration($fileConfiguration->uploadsEntityClass);
54
55 9
        $em = $eventArgs->getObjectManager();
56 9
        if (!$em instanceof EntityManagerInterface) {
57
            return;
58
        }
59
        /** @var ClassMetadataInfo $uploadsClassMetadata */
60 9
        $uploadsClassMetadata = $em->getClassMetadata($fileConfiguration->uploadsEntityClass);
61 9
        $namingStrategy = $em->getConfiguration()->getNamingStrategy();
62
63 9
        if (!$fileClassMetadata->hasAssociation($fileConfiguration->uploadsEntityClass)) {
64 9
            $fileClassMetadata->mapField([
65 9
                'fieldName' => $fileConfiguration->filePathFieldName,
66
                'nullable' => false,
67
            ]);
68
69 9
            $fileClassMetadata->mapField([
70 9
                'fieldName' => $fileConfiguration->uploadedAtFieldName,
71 9
                'type' => 'datetime',
72
                'nullable' => false,
73
            ]);
74
75 9
            $fileClassMetadata->mapManyToOne([
76 9
                'fieldName' => $fileConfiguration->uploadsFieldName,
77 9
                'targetEntity' => $fileConfiguration->uploadsEntityClass,
78
                'joinColumns' => [
79
                    [
80 9
                        'name' => $namingStrategy->joinKeyColumnName($uploadsClassMetadata->getName()),
81 9
                        'referencedColumnName' => $namingStrategy->referenceColumnName(),
82 9
                        'onDelete' => 'SET NULL',
83
                        'nullable' => true,
84
                    ],
85
                ],
86 9
                'inversedBy' => $uploadsConfiguration->fieldName,
87
            ]);
88
        }
89
90 9
        if (!$uploadsClassMetadata->hasAssociation($uploadsConfiguration->fieldName)) {
91 9
            $uploadsClassMetadata->mapOneToMany([
92 9
                'fieldName' => $uploadsConfiguration->fieldName,
93 9
                'targetEntity' => $fileClassMetadata->getName(),
94 9
                'mappedBy' => $fileConfiguration->uploadsEntityClass,
95
            ]);
96
        }
97
98 9
        $fileClassMetadata->addEntityListener('prePersist', __CLASS__, 'prePersist');
99 9
        $fileClassMetadata->addEntityListener('preUpdate', __CLASS__, 'preUpdate');
100 9
        $fileClassMetadata->addEntityListener('preRemove', __CLASS__, 'preRemove');
101 9
    }
102
103
    public function prePersist(object $object): void
104
    {
105
        $this->fileHelper->persistUploadedFile($object);
106
    }
107
108
    public function preUpdate(object $object, LifecycleEventArgs $args): void
109
    {
110
        $manager = $args->getEntityManager();
111
        $uow = $manager->getUnitOfWork();
112
        $this->fileHelper->persistUploadedFile($object, $uow->getEntityChangeSet($object));
113
    }
114
115
    public function preRemove(object $object): void
116
    {
117
        $this->fileHelper->removeFile($object);
118
    }
119
}
120