Completed
Push — master ( 12bc5f...b06c34 )
by Dominik
01:52
created

Resolver::__call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Model;
6
7
use Interop\Container\ContainerInterface;
8
9
final class Resolver implements ResolverInterface
10
{
11
    /**
12
     * @var ContainerInterface|RepositoryInterface[]
13
     */
14
    private $container;
15
16
    /**
17
     * @var string[]|array
18
     */
19
    private $repositoryKeys;
20
21
    /**
22
     * @param ContainerInterface $container
23
     * @param array              $repositoryKeys
24
     */
25
    public function __construct(ContainerInterface $container, array $repositoryKeys)
26
    {
27
        $this->container = $container;
28
        $this->repositoryKeys = $repositoryKeys;
29
    }
30
31
    /**
32
     * @param string $name
33
     * @param array  $arguments
34
     *
35
     * @return mixed
36
     */
37
    public function __call($name, $arguments)
38
    {
39
        $modelClass = array_shift($arguments);
40
41
        if (substr($name, 0, 4) === 'lazy') {
42
            $name = substr($name, 4);
43
44
            return function () use ($modelClass, $name, $arguments) {
45
                return $this->getRepositoryByClass($modelClass)->$name(...$arguments);
46
            };
47
        }
48
49
        return $this->getRepositoryByClass($modelClass)->$name(...$arguments);
50
    }
51
52
    /**
53
     * @param string $modelClass
54
     * @param string $id
55
     *
56
     * @return ModelInterface|null
57
     */
58
    public function find(string $modelClass, string $id)
59
    {
60
        return $this->getRepositoryByClass($modelClass)->find($id);
61
    }
62
63
    /**
64
     * @param string     $modelClass
65
     * @param array      $criteria
66
     * @param array|null $orderBy
67
     *
68
     * @return ModelInterface|null
69
     */
70
    public function findOneBy(string $modelClass, array $criteria, array $orderBy = null)
71
    {
72
        return $this->getRepositoryByClass($modelClass)->findOneBy($criteria, $orderBy);
73
    }
74
75
    /**
76
     * @param string     $modelClass
77
     * @param array      $criteria
78
     * @param array|null $orderBy
79
     * @param int|null   $limit
80
     * @param int|null   $offset
81
     *
82
     * @return array
83
     */
84
    public function findBy(
85
        string $modelClass,
86
        array $criteria,
87
        array $orderBy = null,
88
        int $limit = null,
89
        int $offset = null
90
    ): array {
91
        return $this->getRepositoryByClass($modelClass)->findBy($criteria, $orderBy, $limit, $offset);
92
    }
93
94
    /**
95
     * @param string $modelClass
96
     * @param string $id
97
     *
98
     * @return \Closure
99
     */
100
    public function lazyFind(string $modelClass, string $id): \Closure
101
    {
102
        return function () use ($modelClass, $id) {
103
            return $this->find($modelClass, $id);
104
        };
105
    }
106
107
    /**
108
     * @param string     $modelClass
109
     * @param array      $criteria
110
     * @param array|null $orderBy
111
     *
112
     * @return \Closure
113
     */
114
    public function lazyFindOneBy(string $modelClass, array $criteria, array $orderBy = null): \Closure
115
    {
116
        return function () use ($modelClass, $criteria, $orderBy) {
117
            return $this->findOneBy($modelClass, $criteria, $orderBy);
118
        };
119
    }
120
121
    /**
122
     * @param string     $modelClass
123
     * @param array      $criteria
124
     * @param array|null $orderBy
125
     * @param int|null   $limit
126
     * @param int|null   $offset
127
     *
128
     * @return \Closure
129
     */
130
    public function lazyFindBy(
131
        string $modelClass,
132
        array $criteria,
133
        array $orderBy = null,
134
        int $limit = null,
135
        int $offset = null
136
    ): \Closure {
137
        return function () use ($modelClass, $criteria, $orderBy, $limit, $offset) {
138
            return $this->findBy($modelClass, $criteria, $orderBy, $limit, $offset);
139
        };
140
    }
141
142
    /**
143
     * @param ModelInterface $model
144
     */
145
    public function persist(ModelInterface $model)
146
    {
147
        $this->getRepositoryByClass(get_class($model))->persist($model);
148
    }
149
150
    /**
151
     * @param ModelInterface $model
152
     */
153
    public function remove(ModelInterface $model)
154
    {
155
        $this->getRepositoryByClass(get_class($model))->remove($model);
156
    }
157
158
    /**
159
     * @param string $modelClass
160
     *
161
     * @return RepositoryInterface
162
     */
163
    private function getRepositoryByClass(string $modelClass): RepositoryInterface
164
    {
165
        foreach ($this->repositoryKeys as $repositoryKey) {
166
            /** @var RepositoryInterface $repository */
167
            $repository = $this->container->get($repositoryKey);
168
            if ($repository->isResponsible($modelClass)) {
169
                return $repository;
170
            }
171
        }
172
173
        throw MissingRepositoryException::create($modelClass);
174
    }
175
}
176