Passed
Pull Request — master (#2235)
by Antoine
04:09
created

DataPersister::persist()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 14
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 1
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[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 ApiPlatform\Core\Bridge\Doctrine\Common;
15
16
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
17
use ApiPlatform\Core\Util\ClassInfoTrait;
18
use Doctrine\Common\Persistence\ManagerRegistry;
19
use Doctrine\Common\Persistence\ObjectManager as DoctrineObjectManager;
20
use Doctrine\ORM\Mapping\ClassMetadataInfo;
21
22
/**
23
 * Data persister for Doctrine.
24
 *
25
 * @author Baptiste Meyer <[email protected]>
26
 */
27
final class DataPersister implements DataPersisterInterface
28
{
29
    use ClassInfoTrait;
30
31
    private $managerRegistry;
32
33
    public function __construct(ManagerRegistry $managerRegistry)
34
    {
35
        $this->managerRegistry = $managerRegistry;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function supports($data): bool
42
    {
43
        return null !== $this->getManager($data);
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function persist($data)
50
    {
51
        if (!$manager = $this->getManager($data)) {
52
            return $data;
53
        }
54
55
        if (!$manager->contains($data) || $this->isDeferredExplicit($manager, $data)) {
56
            $manager->persist($data);
57
        }
58
59
        $manager->flush();
60
        $manager->refresh($data);
61
62
        return $data;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function remove($data)
69
    {
70
        if (!$manager = $this->getManager($data)) {
71
            return;
72
        }
73
74
        $manager->remove($data);
75
        $manager->flush();
76
    }
77
78
    /**
79
     * Gets the Doctrine object manager associated with given data.
80
     *
81
     *
82
     * @return DoctrineObjectManager|null
83
     */
84
    private function getManager($data)
85
    {
86
        return \is_object($data) ? $this->managerRegistry->getManagerForClass($this->getObjectClass($data)) : null;
87
    }
88
89
    /**
90
     * Checks if doctrine does not manage data automatically.
91
     *
92
     * @return bool
93
     */
94
    private function isDeferredExplicit(DoctrineObjectManager $manager, $data)
95
    {
96
        $classMetadata = $manager->getClassMetadata($this->getObjectClass($data));
97
        if ($classMetadata instanceof ClassMetadataInfo && \method_exists($classMetadata, 'isChangeTrackingDeferredExplicit')) {
98
            return $classMetadata->isChangeTrackingDeferredExplicit();
99
        }
100
101
        return false;
102
    }
103
}
104