1 | <?php |
||
14 | abstract class AbstractSqlRepository implements RepositoryInterface |
||
15 | { |
||
16 | use CollectionBuilderTrait; |
||
17 | use QueryStringParserTrait; |
||
18 | |||
19 | /** |
||
20 | * @var \Aura\Sql\ExtendedPdoInterface |
||
21 | */ |
||
22 | protected $dbal; |
||
23 | |||
24 | /** |
||
25 | * |
||
26 | * @var mixed |
||
27 | */ |
||
28 | protected $relationships = []; |
||
29 | |||
30 | /** |
||
31 | * Construct. |
||
32 | * |
||
33 | * @param \Aura\Sql\ExtendedPdoInterface $dbal |
||
34 | */ |
||
35 | 2 | public function __construct(ExtendedPdoInterface $dbal) |
|
39 | |||
40 | /** |
||
41 | * {@inheritdoc} |
||
42 | */ |
||
43 | 1 | public function countFromRequest(ServerRequestInterface $request, $joins = '', $conditionals = '', $end = '') |
|
44 | { |
||
45 | 1 | $rules = $this->parseQueryString($request->getUri()->getQuery()); |
|
46 | |||
47 | 1 | list($query, $params) = $this->buildQueryFromRules( |
|
48 | 1 | $rules, |
|
49 | 1 | 'SELECT COUNT(*) as total FROM ', |
|
50 | 1 | $joins, |
|
51 | 1 | $conditionals, |
|
52 | $end |
||
53 | 1 | ); |
|
54 | |||
55 | 1 | return (int) $this->dbal->fetchOne($query, $params)['total']; |
|
56 | } |
||
57 | |||
58 | /** |
||
59 | * {@inheritdoc} |
||
60 | */ |
||
61 | 1 | public function getFromRequest( |
|
62 | ServerRequestInterface $request, |
||
63 | $start = 'SELECT * FROM ', |
||
64 | $joins = '', |
||
65 | $conditionals = '', |
||
66 | $end = '' |
||
67 | ) { |
||
68 | 1 | $rules = $this->parseQueryString($request->getUri()->getQuery()); |
|
69 | |||
70 | 1 | list($query, $params) = $this->buildQueryFromRules($rules, $start, $joins, $conditionals, $end); |
|
71 | |||
72 | 1 | if (array_key_exists('sort', $rules)) { |
|
73 | 1 | $query .= sprintf(' ORDER BY %s ', $rules['sort']); |
|
74 | 1 | $query .= (array_key_exists('sort_direction', $rules)) ? $rules['sort_direction'] : 'ASC'; |
|
75 | 1 | } |
|
76 | |||
77 | 1 | if (array_key_exists('limit', $rules)) { |
|
78 | 1 | $query .= ' LIMIT '; |
|
79 | 1 | $query .= (array_key_exists('offset', $rules)) ? sprintf('%d,', $rules['offset']) : ''; |
|
80 | 1 | $query .= $rules['limit']; |
|
81 | 1 | } |
|
82 | |||
83 | 1 | return $this->buildCollection($this->dbal->fetchAll($query, $params)) |
|
84 | 1 | ->setTotal($this->countFromRequest($request, $joins, $conditionals, $end)); |
|
85 | } |
||
86 | |||
87 | /** |
||
88 | * Build a base query without sorting and limits from filter rules. |
||
89 | * |
||
90 | * @param array $rules |
||
91 | * @param string $start |
||
92 | * @param string $joins |
||
93 | * @param string $conditionals |
||
94 | * @param string $end |
||
95 | * |
||
96 | * @return array |
||
97 | */ |
||
98 | 1 | protected function buildQueryFromRules(array $rules, $start, $joins, $conditionals, $end) |
|
99 | { |
||
100 | 1 | $start = $start . $this->getTable(); |
|
101 | 1 | $query = sprintf('%s %s %s', $start, $joins, $conditionals); |
|
102 | |||
103 | 1 | $params = []; |
|
104 | |||
105 | 1 | if (array_key_exists('filter', $rules)) { |
|
106 | 1 | foreach ($rules['filter'] as $key => $where) { |
|
107 | 1 | $keyword = ($key === 0 || $conditionals !== '') ? ' WHERE' : ' AND'; |
|
108 | 1 | $delimiter = strtoupper($where['delimiter']); |
|
109 | 1 | $binding = (in_array($delimiter, ['IN', 'NOT IN'])) ? sprintf('(:%s)', $where['binding']) : ':' . $where['binding']; |
|
110 | 1 | $query .= sprintf('%s %s %s %s', $keyword, $where['field'], $delimiter, $binding); |
|
111 | |||
112 | 1 | $params[$where['binding']] = $where['value']; |
|
113 | 1 | } |
|
114 | 1 | } |
|
115 | |||
116 | 1 | $query .= " {$end}"; |
|
117 | |||
118 | 1 | return [$query, $params]; |
|
119 | } |
||
120 | |||
121 | /** |
||
122 | * {@inheritdoc} |
||
123 | */ |
||
124 | 1 | public function countByField($field, $value) |
|
140 | |||
141 | /** |
||
142 | * {@inheritdoc} |
||
143 | */ |
||
144 | 1 | public function getByField($field, $value) |
|
161 | |||
162 | /** |
||
163 | * {@inheritdoc} |
||
164 | */ |
||
165 | public function getRelationshipsFor(Collection $collection, array $relationships = []) |
||
180 | |||
181 | /** |
||
182 | * Attach relationships to a specific entity. |
||
183 | * |
||
184 | * @param string $entityType |
||
185 | * @param string $relationship |
||
186 | * @param array $userData |
||
187 | * |
||
188 | * @return void |
||
189 | */ |
||
190 | protected function getEntityRelationships($entityType, $relationship, array $userData) |
||
227 | |||
228 | /** |
||
229 | * Get possible relationships and the properties attached to them. |
||
230 | * |
||
231 | * @param string $relationship |
||
232 | * |
||
233 | * @throws \InvalidArgumentException when requested relationship is not defined |
||
234 | * @throws \RuntimeException when map structure is defined incorrectly |
||
235 | * |
||
236 | * @return array |
||
237 | */ |
||
238 | public function getRelationshipMap($relationship) |
||
273 | |||
274 | /** |
||
275 | * Returns table that repository is reading from. |
||
276 | * |
||
277 | * @return string |
||
278 | */ |
||
279 | abstract protected function getTable(); |
||
280 | } |
||
281 |