Issues (332)

src/Bridge/Doctrine/Common/DataPersister.php (1 issue)

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\ContextAwareDataPersisterInterface;
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 ContextAwareDataPersisterInterface
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, array $context = []): bool
42
    {
43
        return null !== $this->getManager($data);
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function persist($data, array $context = [])
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, array $context = [])
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
    private function getManager($data): ?DoctrineObjectManager
82
    {
83
        return \is_object($data) ? $this->managerRegistry->getManagerForClass($this->getObjectClass($data)) : null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return is_object($data) ...ectClass($data)) : null could return the type Doctrine\Persistence\ObjectManager which includes types incompatible with the type-hinted return Doctrine\Common\Persistence\ObjectManager|null. Consider adding an additional type-check to rule them out.
Loading history...
84
    }
85
86
    /**
87
     * Checks if doctrine does not manage data automatically.
88
     */
89
    private function isDeferredExplicit(DoctrineObjectManager $manager, $data): bool
90
    {
91
        $classMetadata = $manager->getClassMetadata($this->getObjectClass($data));
92
        if ($classMetadata instanceof ClassMetadataInfo && method_exists($classMetadata, 'isChangeTrackingDeferredExplicit')) {
93
            return $classMetadata->isChangeTrackingDeferredExplicit();
94
        }
95
96
        return false;
97
    }
98
}
99