1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Storage package |
5
|
|
|
* |
6
|
|
|
* (c) Michal Wachowski <[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
|
|
|
namespace Moss\Storage\Model\Definition\Relation; |
13
|
|
|
|
14
|
|
|
use Moss\Storage\GetTypeTrait; |
15
|
|
|
use Moss\Storage\Model\Definition\DefinitionException; |
16
|
|
|
use Moss\Storage\Model\Definition\RelationInterface; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Relation definition describing relationship between entities in model |
20
|
|
|
* |
21
|
|
|
* @author Michal Wachowski <[email protected]> |
22
|
|
|
* @package Moss\Storage |
23
|
|
|
*/ |
24
|
|
|
abstract class AbstractRelation implements RelationInterface |
25
|
|
|
{ |
26
|
|
|
use GetTypeTrait; |
27
|
|
|
|
28
|
|
|
protected $entity; |
29
|
|
|
|
30
|
|
|
protected $mediator; |
31
|
|
|
|
32
|
|
|
protected $type; |
33
|
|
|
protected $container; |
34
|
|
|
|
35
|
|
|
protected $keys = []; |
36
|
|
|
protected $in = []; |
37
|
|
|
protected $out = []; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Returns container name or builds it from namespaced class name if passed name is empty string |
41
|
|
|
* |
42
|
|
|
* @param null|string $container |
43
|
|
|
* |
44
|
|
|
* @return string |
45
|
|
|
*/ |
46
|
|
|
protected function containerName($container = null) |
47
|
|
|
{ |
48
|
|
|
if ($container !== null) { |
49
|
|
|
return $container; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
$pos = strrpos($this->entity, '\\'); |
53
|
|
|
if ($pos === false) { |
54
|
|
|
return $this->entity; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
return substr($this->entity, strrpos($this->entity, '\\') + 1); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Assigns key pairs to passed container |
62
|
|
|
* |
63
|
|
|
* @param array $keys |
64
|
|
|
* @param array $container |
65
|
|
|
*/ |
66
|
|
|
protected function assignKeys(array $keys, array &$container) |
67
|
|
|
{ |
68
|
|
|
foreach ($keys as $local => $foreign) { |
69
|
|
|
$this->assertField($local); |
70
|
|
|
$this->assertField($foreign); |
71
|
|
|
|
72
|
|
|
$container[$local] = $foreign; |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Asserts keys (non empty array) |
78
|
|
|
* |
79
|
|
|
* @param $keys |
80
|
|
|
* |
81
|
|
|
* @throws DefinitionException |
82
|
|
|
*/ |
83
|
|
|
protected function assertKeys($keys) |
84
|
|
|
{ |
85
|
|
|
if (empty($keys)) { |
86
|
|
|
throw new DefinitionException(sprintf('No keys in "%s" relation definition', $this->entity)); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Asserts trough keys, must be same number in both arrays |
93
|
|
|
* |
94
|
|
|
* @param array $inKeys |
95
|
|
|
* @param array $outKeys |
96
|
|
|
* |
97
|
|
|
* @throws DefinitionException |
98
|
|
|
*/ |
99
|
|
|
protected function assertTroughKeys($inKeys, $outKeys) |
100
|
|
|
{ |
101
|
|
View Code Duplication |
if (empty($inKeys) || empty($outKeys)) { |
|
|
|
|
102
|
|
|
throw new DefinitionException(sprintf('Invalid keys for relation "%s", must be two arrays with key-value pairs', $this->entity, count($inKeys))); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
View Code Duplication |
if (count($inKeys) !== count($outKeys)) { |
|
|
|
|
106
|
|
|
throw new DefinitionException(sprintf('Both key arrays for relation "%s", must have the same number of elements', $this->entity)); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Asserts field name |
112
|
|
|
* |
113
|
|
|
* @param string $field |
114
|
|
|
* |
115
|
|
|
* @throws DefinitionException |
116
|
|
|
*/ |
117
|
|
|
protected function assertField($field) |
118
|
|
|
{ |
119
|
|
|
if (empty($field)) { |
120
|
|
|
throw new DefinitionException(sprintf('Invalid field name for relation "%s.%s" can not be empty', $this->entity, $field)); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
if (is_numeric($field)) { |
124
|
|
|
throw new DefinitionException(sprintf('Invalid field name for relation "%s.%s" can not be numeric', $this->entity, $field)); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
if (!is_string($field)) { |
128
|
|
|
throw new DefinitionException(sprintf('Invalid field name for relation "%s.%s" must be string, %s given', $this->entity, $field, $this->getType($field))); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Returns relation name in entity |
134
|
|
|
* |
135
|
|
|
* @return string |
136
|
|
|
*/ |
137
|
|
|
public function name() |
138
|
|
|
{ |
139
|
|
|
return $this->container(); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Returns relation mediating instance |
144
|
|
|
* |
145
|
|
|
* @return string |
146
|
|
|
*/ |
147
|
|
|
public function mediator() |
148
|
|
|
{ |
149
|
|
|
return $this->mediator; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Returns relation type |
154
|
|
|
* |
155
|
|
|
* @return string |
156
|
|
|
*/ |
157
|
|
|
public function type() |
158
|
|
|
{ |
159
|
|
|
return $this->type; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Returns relation entity class name |
164
|
|
|
* |
165
|
|
|
* @return string |
166
|
|
|
*/ |
167
|
|
|
public function entity() |
168
|
|
|
{ |
169
|
|
|
return $this->entity; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Returns table name |
174
|
|
|
* |
175
|
|
|
* @return string |
176
|
|
|
*/ |
177
|
|
|
public function container() |
178
|
|
|
{ |
179
|
|
|
return $this->container; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* Returns associative array containing local key - foreign key pairs |
184
|
|
|
* |
185
|
|
|
* @return array |
186
|
|
|
*/ |
187
|
|
|
public function keys() |
188
|
|
|
{ |
189
|
|
|
return $this->keys; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Returns array containing local keys |
194
|
|
|
* |
195
|
|
|
* @return array |
196
|
|
|
*/ |
197
|
|
|
public function localKeys() |
198
|
|
|
{ |
199
|
|
|
return $this->in; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Returns array containing foreign keys |
204
|
|
|
* |
205
|
|
|
* @return array |
206
|
|
|
*/ |
207
|
|
|
public function foreignKeys() |
208
|
|
|
{ |
209
|
|
|
return $this->out; |
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.