1 | <?php |
||
11 | class JsonDefinitionHash implements DefinitionElementInterface |
||
12 | { |
||
13 | /** |
||
14 | * @var string Name of this hash |
||
15 | */ |
||
16 | private $name; |
||
17 | /** |
||
18 | * @var JsonDefinition |
||
19 | */ |
||
20 | private $parent; |
||
21 | /** |
||
22 | * @var DefinitionElementInterface[] Array of fields.. |
||
23 | */ |
||
24 | private $fields = []; |
||
25 | /** |
||
26 | * @var Schema\Field Field definition |
||
27 | */ |
||
28 | private $definition; |
||
29 | |||
30 | /** |
||
31 | * Constructor |
||
32 | * |
||
33 | * @param string $name Name of this hash |
||
34 | * @param JsonDefinition $parent Parent definiton |
||
35 | * @param DefinitionElementInterface[] $fields Fields of the hash |
||
36 | * @param Schema\Field $definition Field definition |
||
|
|||
37 | */ |
||
38 | 42 | public function __construct($name, JsonDefinition $parent, array $fields, Schema\Field $definition = null) |
|
39 | { |
||
40 | 42 | $this->name = $name; |
|
41 | 42 | $this->parent = $parent; |
|
42 | 42 | $this->fields = $fields; |
|
43 | 42 | $this->definition = $definition; |
|
44 | 42 | } |
|
45 | |||
46 | /** |
||
47 | * Returns the hash name |
||
48 | * |
||
49 | * @return string Name |
||
50 | */ |
||
51 | 22 | public function getName() |
|
55 | |||
56 | /** |
||
57 | * Returns the definition as array.. |
||
58 | * |
||
59 | * @return array the definition |
||
60 | */ |
||
61 | 6 | public function getDefAsArray() |
|
62 | { |
||
63 | 6 | return array_replace( |
|
64 | [ |
||
65 | 6 | 'name' => $this->getName(), |
|
66 | 6 | 'type' => $this->getType(), |
|
67 | 6 | 'exposedName' => $this->getName(), |
|
68 | 6 | 'doctrineType' => $this->getTypeDoctrine(), |
|
69 | 6 | 'serializerType' => $this->getTypeSerializer(), |
|
70 | 6 | 'relType' => self::REL_TYPE_EMBED, |
|
71 | 3 | 'isClassType' => true, |
|
72 | 3 | 'constraints' => [], |
|
73 | 3 | 'required' => true, |
|
74 | 3 | 'searchable' => false, |
|
75 | 3 | ], |
|
76 | 6 | $this->definition === null ? [] : [ |
|
77 | 2 | 'exposedName' => $this->definition->getExposeAs() ?: $this->getName(), |
|
78 | |||
79 | 2 | 'title' => $this->definition->getTitle(), |
|
80 | 2 | 'description' => $this->definition->getDescription(), |
|
81 | 2 | 'readOnly' => $this->definition->getReadOnly(), |
|
82 | 2 | 'required' => $this->definition->getRequired(), |
|
83 | 4 | 'searchable' => $this->definition->getSearchable(), |
|
84 | ] |
||
85 | 3 | ); |
|
86 | } |
||
87 | |||
88 | /** |
||
89 | * {@inheritDoc} |
||
90 | * |
||
91 | * @return string type |
||
92 | */ |
||
93 | 8 | public function getType() |
|
97 | |||
98 | /** |
||
99 | * {@inheritDoc} |
||
100 | * |
||
101 | * @return string type |
||
102 | */ |
||
103 | 8 | public function getTypeDoctrine() |
|
107 | |||
108 | /** |
||
109 | * Returns the field type in a serializer-understandable way.. |
||
110 | * |
||
111 | * @return string Type |
||
112 | */ |
||
113 | 8 | public function getTypeSerializer() |
|
117 | |||
118 | /** |
||
119 | * Returns the field definition of this hash from "local perspective", |
||
120 | * meaning that we only include fields inside this hash BUT with all |
||
121 | * the stuff from the json file. this is needed to generate a Document/Model |
||
122 | * from this hash (generate a json file again) |
||
123 | * |
||
124 | * @return JsonDefinition the definition of this hash in a standalone array ready to be json_encoded() |
||
125 | */ |
||
126 | 10 | public function getJsonDefinition() |
|
127 | { |
||
128 | 10 | $definition = (new Schema\Definition()) |
|
129 | 10 | ->setId($this->getClassName()) |
|
130 | 10 | ->setDescription($this->definition === null ? null : $this->definition->getDescription()) |
|
131 | 10 | ->setTitle($this->definition === null ? null : $this->definition->getTitle()) |
|
132 | 10 | ->setIsSubDocument(true) |
|
133 | 10 | ->setTarget(new Schema\Target()); |
|
134 | |||
135 | 10 | foreach ($this->fields as $field) { |
|
136 | 10 | foreach ($this->processFieldDefinitionsRecursive($field) as $definitions) { |
|
137 | 10 | $definition->getTarget()->addField($definitions); |
|
138 | 5 | } |
|
139 | 5 | } |
|
140 | 10 | foreach ($this->parent->getRelations() as $relation) { |
|
141 | 4 | $relation = $this->processParentRelation($relation); |
|
142 | 4 | if ($relation !== null) { |
|
143 | 4 | $definition->getTarget()->addRelation($relation); |
|
144 | 2 | } |
|
145 | 5 | } |
|
146 | |||
147 | 10 | return new JsonDefinition($definition); |
|
148 | } |
||
149 | |||
150 | /** |
||
151 | * Method getFieldDefinitionsRecursive |
||
152 | * |
||
153 | * @param DefinitionElementInterface $field |
||
154 | * @return Schema\Field[] |
||
155 | */ |
||
156 | 10 | private function processFieldDefinitionsRecursive(DefinitionElementInterface $field) |
|
157 | { |
||
158 | 10 | if ($field instanceof JsonDefinitionField) { |
|
159 | 10 | return [$this->cloneFieldDefinition($field->getDef())]; |
|
160 | 4 | } elseif ($field instanceof JsonDefinitionArray) { |
|
161 | 8 | return $this->processFieldDefinitionsRecursive($field->getElement()); |
|
162 | 2 | } elseif ($field instanceof JsonDefinitionHash) { |
|
163 | 4 | return array_reduce( |
|
164 | 4 | $field->fields, |
|
165 | 4 | function (array $subfields, DefinitionElementInterface $subfield) { |
|
166 | 4 | return array_merge($subfields, $this->processFieldDefinitionsRecursive($subfield)); |
|
167 | 4 | }, |
|
168 | 4 | $field->definition === null ? [] : [$this->cloneFieldDefinition($field->definition)] |
|
169 | 2 | ); |
|
170 | } |
||
171 | |||
172 | throw new \InvalidArgumentException(sprintf('Unknown field type "%s"', get_class($field))); |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Clone field definition |
||
177 | * |
||
178 | * @param Schema\Field $field Field |
||
179 | * @return Schema\Field |
||
180 | */ |
||
181 | 10 | private function cloneFieldDefinition(Schema\Field $field) |
|
187 | |||
188 | /** |
||
189 | * Process parent relation |
||
190 | * |
||
191 | * @param Schema\Relation $relation Parent relation |
||
192 | * @return Schema\Relation|null |
||
193 | */ |
||
194 | 4 | private function processParentRelation(Schema\Relation $relation) |
|
205 | |||
206 | /** |
||
207 | * Returns the class name of this hash, possibly |
||
208 | * taking the parent element into the name. this |
||
209 | * string here results in the name of the generated Document. |
||
210 | * |
||
211 | * @param boolean $fq if true, we'll return the class name full qualified |
||
212 | * |
||
213 | * @return string |
||
214 | */ |
||
215 | 20 | private function getClassName($fq = false) |
|
224 | } |
||
225 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.