Completed
Pull Request — master (#90)
by Arnaud
03:24
created

DataProviderFactory::create()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2.0023

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
ccs 11
cts 12
cp 0.9167
rs 8.9713
cc 2
eloc 13
nc 2
nop 1
crap 2.0023
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 7
    public function __construct(EntityManagerInterface $entityManager)
31
    {
32 7
        $this->entityManager = $entityManager;
33 7
    }
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 4
    public function add($id, DataProviderInterface $dataProvider)
44
    {
45 4
        if ($this->has($id)) {
46 1
            throw new Exception('Trying to add the data provider '.$id.' twice');
47
        }
48
        // add the data provider to collection, indexed by ids
49 4
        $this->dataProviders[$id] = $dataProvider;
50 4
    }
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 2
    public function get($id = null, $entityClass = null)
64
    {
65 2
        if (null === $id && null === $entityClass) {
66 1
            throw new Exception('You should either provide an data provider or a entity class to get a data provider');
67
        }
68
69 2
        if (null !== $id && $this->has($id)) {
70
            // a name is provided and the data provider exist, so we return the found data provider
71 2
            $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 1
            $dataProvider = $this->create($entityClass);
75
        }
76
77 2
        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 4
    public function has($id)
88
    {
89 4
        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
     *
97
     * @return DataProviderInterface The created data provider
98
     *
99
     * @throws Exception An exception is thrown if the found repository with given entity class does not implements
100
     * RepositoryInterface.
101
     */
102 3
    public function create($entityClass)
103
    {
104
        // get the repository corresponding to the given entity class
105
        $repository = $this
106 3
            ->entityManager
107 3
            ->getRepository($entityClass);
108
109
        // the repository should implements the RepositoryInterface, to ensure it has the methods create and save
110 3
        if (!($repository instanceof RepositoryInterface)) {
111 2
            $repositoryClass = get_class($repository);
112
113 2
            throw new Exception(
114 2
                sprintf(
115 2
                    'Repository %s should implements %s',
116
                    $repositoryClass,
117 2
                    RepositoryInterface::class
118
                )
119
            );
120
        }
121
        // create a new generic data provider from the found repository
122 1
        $dataProvider = new DataProvider($repository);
123
124 1
        return $dataProvider;
125
    }
126
}
127