Completed
Push — dev ( 243dfc...851a92 )
by Arnaud
9s
created

DataProviderFactory::get()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 8
nc 3
nop 2
1
<?php
2
3
namespace LAG\AdminBundle\DataProvider\Factory;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Exception;
7
use LAG\AdminBundle\DataProvider\DataProvider;
8
use LAG\AdminBundle\DataProvider\DataProviderInterface;
9
use LAG\AdminBundle\Repository\RepositoryInterface;
10
11
class DataProviderFactory
12
{
13
    /**
14
     * The loaded data providers
15
     *
16
     * @var DataProviderInterface[]
17
     */
18
    protected $dataProviders = [];
19
20
    /**
21
     * @var EntityManagerInterface
22
     */
23
    protected $entityManager;
24
25
    /**
26
     * DataProviderFactory constructor.
27
     *
28
     * @param EntityManagerInterface $entityManager A Doctrine ORM entity manager
29
     */
30
    public function __construct(EntityManagerInterface $entityManager)
31
    {
32
        $this->entityManager = $entityManager;
33
    }
34
35
    /**
36
     * Add a data provider to the collection.
37
     *
38
     * @param string $id The data provider service id
39
     * @param DataProviderInterface $dataProvider The data provider
40
     *
41
     * @throws Exception
42
     */
43
    public function add($id, DataProviderInterface $dataProvider)
44
    {
45
        if ($this->has($id)) {
46
            throw new Exception('Trying to add the data provider '.$id.' twice');
47
        }
48
        // add the data provider to collection, indexed by ids
49
        $this->dataProviders[$id] = $dataProvider;
50
    }
51
52
    /**
53
     * Return an configured data provider or try to create one for the given entity class.
54
     *
55
     * @param string|null id The id of an existing data provider service
56
     * @param string|null $entityClass The class of the related entity. It will be used to find a repository in Doctrine
57
     * registry
58
     *
59
     * @return DataProviderInterface
60
     *
61
     * @throws Exception
62
     */
63
    public function get($id = null, $entityClass = null)
64
    {
65
        if (null === $id && null === $entityClass) {
66
            throw new Exception('You should either provide an data provider or a entity class to get a data provider');
67
        }
68
69
        if (null !== $id && $this->has($id)) {
70
            // a name is provided and the data provider exist, so we return the found data provider
71
            $dataProvider = $this->dataProviders[$id];
72
        } else {
73
            // no name was provided, so we try to create a generic data provider with th given entity class
74
            $dataProvider = $this->create($entityClass);
75
        }
76
77
        return $dataProvider;
78
    }
79
80
    /**
81
     * Return true if a data provider with the given id exists.
82
     *
83
     * @param string $id The data provider id
84
     *
85
     * @return bool
86
     */
87
    public function has($id)
88
    {
89
        return array_key_exists($id, $this->dataProviders);
90
    }
91
92
    /**
93
     * Create a generic data provider.
94
     *
95
     * @param string $entityClass The class of the related entity
96
     * @return DataProviderInterface The created data provider
97
     *
98
     * @throws Exception An exception is thrown if the found repository with given entity class does not implements
99
     * RepositoryInterface.
100
     */
101
    public function create($entityClass)
102
    {
103
        // get the repository corresponding to the given entity class
104
        $repository = $this
105
            ->entityManager
106
            ->getRepository($entityClass);
107
108
        // the repository should implements the RepositoryInterface, to ensure it has the methods create and save
109
        if (!($repository instanceof RepositoryInterface)) {
110
            $repositoryClass = get_class($repository);
111
112
            throw new Exception(
113
                sprintf(
114
                    'Repository %s should implements %s',
115
                    $repositoryClass,
116
                    RepositoryInterface::class
117
                )
118
            );
119
        }
120
        // create a new generic data provider from the found repository
121
        $dataProvider = new DataProvider($repository);
122
123
        return $dataProvider;
124
    }
125
}
126