1 | <?php |
||||
2 | /** |
||||
3 | * |
||||
4 | * This file is part of the Aura project for PHP. |
||||
5 | * |
||||
6 | * @package Aura.Marshal |
||||
7 | * |
||||
8 | * @license https://opensource.org/licenses/mit-license.php MIT |
||||
9 | * |
||||
10 | */ |
||||
11 | namespace Aura\Marshal\Relation; |
||||
12 | |||||
13 | use Aura\Marshal\Exception; |
||||
14 | use Aura\Marshal\Manager; |
||||
15 | |||||
16 | /** |
||||
17 | * |
||||
18 | * A builder to create relationship definition objects. |
||||
19 | * |
||||
20 | * @package Aura.Marshal |
||||
21 | * |
||||
22 | */ |
||||
23 | class Builder |
||||
24 | { |
||||
25 | /** |
||||
26 | * |
||||
27 | * A map of relationships to classes. |
||||
28 | * |
||||
29 | * @var array<string, class-string<RelationInterface>> |
||||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||||
30 | * |
||||
31 | */ |
||||
32 | protected $relationship_class = [ |
||||
33 | 'belongs_to' => 'Aura\Marshal\Relation\BelongsTo', |
||||
34 | 'has_one' => 'Aura\Marshal\Relation\HasOne', |
||||
35 | 'has_many' => 'Aura\Marshal\Relation\HasMany', |
||||
36 | 'has_many_through' => 'Aura\Marshal\Relation\HasManyThrough', |
||||
37 | ]; |
||||
38 | |||||
39 | /** |
||||
40 | * |
||||
41 | * Builds and returns a relation object. |
||||
42 | * |
||||
43 | * @param string $type The name of the native type in the manager. |
||||
44 | * |
||||
45 | * @param string $name The name of the native field for the related |
||||
46 | * entity or collection. |
||||
47 | * |
||||
48 | * @param array<string, mixed> $info An array of relationship definition information. |
||||
49 | * |
||||
50 | * @param Manager $manager A type manager. |
||||
51 | * |
||||
52 | * @return RelationInterface |
||||
53 | * |
||||
54 | */ |
||||
55 | public function newInstance($type, $name, array $info, Manager $manager) |
||||
56 | { |
||||
57 | $base = [ |
||||
58 | 'relationship' => null, |
||||
59 | 'native_field' => null, |
||||
60 | 'foreign_type' => $name, |
||||
61 | 'foreign_field' => null, |
||||
62 | 'through_type' => null, |
||||
63 | 'through_native_field' => null, |
||||
64 | 'through_foreign_field' => null, |
||||
65 | ]; |
||||
66 | |||||
67 | $info = array_merge($base, $info); |
||||
68 | $info['type'] = $type; |
||||
69 | $info['name'] = $name; |
||||
70 | |||||
71 | $this->prepRelationship($info, $manager); |
||||
72 | $this->prepNative($info, $manager); |
||||
73 | $this->prepForeign($info, $manager); |
||||
74 | $this->prepThrough($info, $manager); |
||||
75 | |||||
76 | $relationship = $info['relationship']; |
||||
77 | $class = $this->relationship_class[$relationship]; |
||||
78 | |||||
79 | return new $class( |
||||
80 | $info['native_field'], |
||||
81 | $info['foreign'], |
||||
82 | $info['foreign_type'], |
||||
83 | $info['foreign_field'], |
||||
84 | $info['through'], |
||||
85 | $info['through_type'], |
||||
86 | $info['through_native_field'], |
||||
87 | $info['through_foreign_field'] |
||||
88 | ); |
||||
89 | } |
||||
90 | |||||
91 | /** |
||||
92 | * |
||||
93 | * Prepares the type-of-relationship name. |
||||
94 | * |
||||
95 | * @param array<string, mixed> $info The relationship definition. |
||||
96 | * |
||||
97 | * @param Manager $manager The type manager. |
||||
98 | * |
||||
99 | * @return void |
||||
100 | * |
||||
101 | */ |
||||
102 | protected function prepRelationship(&$info, Manager $manager) |
||||
0 ignored issues
–
show
The parameter
$manager is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
103 | { |
||||
104 | if (! $info['relationship']) { |
||||
105 | throw new Exception("No 'relationship' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
106 | } |
||||
107 | } |
||||
108 | |||||
109 | /** |
||||
110 | * |
||||
111 | * Prepares the native field name. |
||||
112 | * |
||||
113 | * @param array<string, mixed> $info The relationship definition. |
||||
114 | * |
||||
115 | * @param Manager $manager The type manager. |
||||
116 | * |
||||
117 | * @return void |
||||
118 | * |
||||
119 | */ |
||||
120 | protected function prepNative(&$info, Manager $manager) |
||||
0 ignored issues
–
show
The parameter
$manager is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
121 | { |
||||
122 | if (! $info['native_field']) { |
||||
123 | throw new Exception("No 'native_field' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
124 | } |
||||
125 | } |
||||
126 | |||||
127 | /** |
||||
128 | * |
||||
129 | * Prepares the foreign type name, field name, and type object. |
||||
130 | * |
||||
131 | * @param array<string, mixed> $info The relationship definition. |
||||
132 | * |
||||
133 | * @param Manager $manager The type manager. |
||||
134 | * |
||||
135 | * @return void |
||||
136 | * |
||||
137 | */ |
||||
138 | protected function prepForeign(&$info, Manager $manager) |
||||
139 | { |
||||
140 | if (! $info['foreign_type']) { |
||||
141 | throw new Exception("No 'foreign_type' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
142 | } |
||||
143 | |||||
144 | if (! $info['foreign_field']) { |
||||
145 | throw new Exception("No 'foreign_field' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
146 | } |
||||
147 | |||||
148 | $info['foreign'] = $manager->__get($info['foreign_type']); |
||||
149 | } |
||||
150 | |||||
151 | /** |
||||
152 | * |
||||
153 | * Prepares the through type name, field names, and type object. |
||||
154 | * |
||||
155 | * @param array<string, mixed> $info The relationship definition. |
||||
156 | * |
||||
157 | * @param Manager $manager The type manager. |
||||
158 | * |
||||
159 | * @return void |
||||
160 | * |
||||
161 | */ |
||||
162 | protected function prepThrough(&$info, Manager $manager) |
||||
163 | { |
||||
164 | if ($info['relationship'] != 'has_many_through') { |
||||
165 | $info['through'] = null; |
||||
166 | return; |
||||
167 | } |
||||
168 | |||||
169 | if (! $info['through_type']) { |
||||
170 | throw new Exception("No 'through_type' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
171 | } |
||||
172 | |||||
173 | if (! $info['through_native_field']) { |
||||
174 | throw new Exception("No 'through_native_field' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
175 | } |
||||
176 | |||||
177 | if (! $info['through_foreign_field']) { |
||||
178 | throw new Exception("No 'through_foreign_field' specified for relation '{$info['name']}' on type '{$info['type']}'."); |
||||
179 | } |
||||
180 | |||||
181 | $info['through'] = $manager->__get($info['through_type']); |
||||
182 | } |
||||
183 | } |
||||
184 |