Passed
Pull Request — master (#52)
by Vincent
23:37
created

FileListener::prePersist()   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->mapManyToOne([
70 9
                'fieldName' => $fileConfiguration->uploadsFieldName,
71 9
                'targetEntity' => $fileConfiguration->uploadsEntityClass,
72
                'joinColumns' => [
73
                    [
74 9
                        'name' => $namingStrategy->joinKeyColumnName($uploadsClassMetadata->getName()),
75 9
                        'referencedColumnName' => $namingStrategy->referenceColumnName(),
76 9
                        'onDelete' => 'SET NULL',
77
                        'nullable' => true,
78
                    ],
79
                ],
80 9
                'inversedBy' => $uploadsConfiguration->fieldName,
81
            ]);
82
        }
83
84 9
        if (!$uploadsClassMetadata->hasAssociation($uploadsConfiguration->fieldName)) {
85 9
            $uploadsClassMetadata->mapOneToMany([
86 9
                'fieldName' => $uploadsConfiguration->fieldName,
87 9
                'targetEntity' => $fileClassMetadata->getName(),
88 9
                'mappedBy' => $fileConfiguration->uploadsEntityClass,
89
            ]);
90
        }
91
92 9
        $fileClassMetadata->addEntityListener('prePersist', __CLASS__, 'prePersist');
93 9
        $fileClassMetadata->addEntityListener('preUpdate', __CLASS__, 'preUpdate');
94 9
        $fileClassMetadata->addEntityListener('preRemove', __CLASS__, 'preRemove');
95 9
    }
96
97
    public function prePersist(object $object): void
98
    {
99
        $this->fileHelper->persistUploadedFile($object);
100
    }
101
102
    public function preUpdate(object $object, LifecycleEventArgs $args): void
103
    {
104
        $manager = $args->getEntityManager();
105
        $uow = $manager->getUnitOfWork();
106
        $this->fileHelper->persistUploadedFile($object, $uow->getEntityChangeSet($object));
107
    }
108
109
    public function preRemove(object $object): void
110
    {
111
        $this->fileHelper->removeFile($object);
112
    }
113
}
114