Completed
Push — feature/issue-158 ( 8b9ab6...25acf9 )
by Mikaël
23:05 queued 36s
created

Struct::getValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace WsdlToPhp\PackageGenerator\Model;
4
5
use WsdlToPhp\PackageGenerator\Generator\Utils;
6
use WsdlToPhp\PackageGenerator\Container\Model\StructValue as StructValueContainer;
7
use WsdlToPhp\PackageGenerator\Container\Model\StructAttribute as StructAttributeContainer;
8
use WsdlToPhp\PackageGenerator\Generator\Generator;
9
use WsdlToPhp\PackageGenerator\ConfigurationReader\StructReservedMethod;
10
use WsdlToPhp\PackageGenerator\ConfigurationReader\StructArrayReservedMethod;
11
12
/**
13
 * Class Struct stands for an available struct described in the WSDL
14
 */
15
class Struct extends AbstractModel
16
{
17
    /**
18
     * @var string
19
     */
20
    const DOC_SUB_PACKAGE_STRUCTS = 'Structs';
21
    /**
22
     * @var string
23
     */
24
    const DOC_SUB_PACKAGE_ENUMERATIONS = 'Enumerations';
25
    /**
26
     * @var string
27
     */
28
    const DOC_SUB_PACKAGE_ARRAYS = 'Arrays';
29
    /**
30
     * Attributes of the struct
31
     * @var StructAttributeContainer
32
     */
33
    protected $attributes;
34
    /**
35
     * Is the struct a restriction with defined values  ?
36
     * @var bool
37
     */
38
    protected $isRestriction = false;
39
    /**
40
     * If the struct is a restriction with values, then store values
41
     * @var StructValueContainer
42
     */
43
    protected $values;
44
    /**
45
     * If the struct is a union with types, then store types
46
     * @var string[]
47
     */
48
    protected $types;
49
    /**
50
     * Defines if the current struct is a concrete struct or just a virtual struct to store meta informations
51
     * @var bool
52
     */
53
    protected $isStruct = false;
54
    /**
55
     * Defines if the current struct is a list of a type or not.
56
     * If it is a list of a type, then the list property value is the type
57
     * @var string
58
     */
59
    protected $list = '';
60
    /**
61
     * Main constructor
62
     * @see AbstractModel::__construct()
63
     * @uses Struct::setStruct()
64
     * @param Generator $generator
65
     * @param string $name the original name
66
     * @param bool $isStruct defines if it's a real struct or not
67
     * @param bool $isRestriction defines if it's an enumeration or not
68
     */
69 1542
    public function __construct(Generator $generator, $name, $isStruct = true, $isRestriction = false)
70
    {
71 1542
        parent::__construct($generator, $name);
72 771
        $this
73 1542
            ->setStruct($isStruct)
74 1542
            ->setRestriction($isRestriction)
75 1542
            ->setAttributes(new StructAttributeContainer($generator))
76 1542
            ->setValues(new StructValueContainer($generator))
77 1542
            ->setTypes([]);
78 1542
    }
79
    /**
80
     * Returns the contextual part of the class name for the package
81
     * @see AbstractModel::getContextualPart()
82
     * @uses Struct::isRestriction()
83
     * @return string
84
     */
85 444
    public function getContextualPart()
86
    {
87 444
        $part = $this->getGenerator()->getOptionStructsFolder();
88 444
        if ($this->isRestriction()) {
89 156
            $part = $this->getGenerator()->getOptionEnumsFolder();
90 417
        } elseif ($this->isArray()) {
91 78
            $part = $this->getGenerator()->getOptionArraysFolder();
92 39
        }
93 444
        return $part;
94
    }
95
    /**
96
     * Returns the sub package name which the model belongs to
97
     * Must be overridden by sub classes
98
     * @see AbstractModel::getDocSubPackages()
99
     * @uses Struct::isRestriction()
100
     * @return array
101
     */
102 252
    public function getDocSubPackages()
103
    {
104 252
        $package = self::DOC_SUB_PACKAGE_STRUCTS;
105 252
        if ($this->isRestriction()) {
106 84
            $package = self::DOC_SUB_PACKAGE_ENUMERATIONS;
107 228
        } elseif ($this->isArray()) {
108 48
            $package = self::DOC_SUB_PACKAGE_ARRAYS;
109 24
        }
110
        return [
111 252
            $package,
112 126
        ];
113
    }
114
    /**
115
     * Returns true if the current struct is a collection of values (like an array or a list of values)
116
     * @uses AbstractModel::getName()
117
     * @uses Struct::countOwnAttributes()
118
     * @return bool
119
     */
120 498
    public function isArray()
121
    {
122
        return
123
        (
124
            (
125
                (
126 498
                    ($this->isStruct() && $this->countOwnAttributes() === 1) ||
127 474
                    (!$this->isStruct() && $this->countOwnAttributes() <= 1)
128 249
                ) &&
129 324
                stripos($this->getName(), 'array') !== false
130 162
            ) ||
131 483
            (!$this->isStruct() && $this->getMetaValueFirstSet(['arraytype', 'arrayType'], false) !== false)
132 249
        );
133
    }
134
    /**
135
     * Returns the attributes of the struct and potentially from the parent class
136
     * @uses AbstractModel::getInheritance()
137
     * @uses Struct::isStruct()
138
     * @uses Struct::getAttributes()
139
     * @param bool $includeInheritanceAttributes include the attributes of parent class, default parent attributes are not included. If true, then the array is an associative array containing and index "attribute" for the StructAttribute object and an index "model" for the Struct object.
140
     * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _construct method with the required attribute at first
141
     * @return StructAttributeContainer
142
     */
143 516
    public function getAttributes($includeInheritanceAttributes = false, $requiredFirst = false)
144
    {
145 516
        if ($includeInheritanceAttributes === false && $requiredFirst === false) {
146 516
            $attributes = $this->attributes;
147 258
        } else {
148 198
            $attributes = $this->getAllAttributes($includeInheritanceAttributes, $requiredFirst);
149
        }
150 516
        return $attributes;
151
    }
152
    /**
153
     * @param bool $includeInheritanceAttributes
154
     * @param bool $requiredFirst
155
     * @return StructAttributeContainer
156
     */
157 198
    protected function getAllAttributes($includeInheritanceAttributes, $requiredFirst)
158
    {
159 198
        $allAttributes = new StructAttributeContainer($this->getGenerator());
160 198
        if ($includeInheritanceAttributes === true) {
161 6
            $this->addInheritanceAttributes($allAttributes);
162 3
        }
163 198
        foreach ($this->attributes as $attribute) {
164 198
            $allAttributes->add($attribute);
165 99
        }
166 198
        if ($requiredFirst === true) {
167 198
            $attributes = $this->putRequiredFirst($allAttributes);
168 99
        } else {
169
            $attributes = $allAttributes;
170
        }
171 198
        return $attributes;
172
    }
173
    /**
174
     * @param StructAttributeContainer $attributes
175
     */
176 6
    protected function addInheritanceAttributes(StructAttributeContainer $attributes)
177
    {
178 6
        if ($this->getInheritance() != '' && ($model = $this->getInheritanceStruct()) instanceof Struct) {
179
            while ($model instanceof Struct && $model->isStruct()) {
180
                foreach ($model->getAttributes() as $attribute) {
181
                    $attributes->add($attribute);
182
                }
183
                $model = $model->getInheritanceStruct();
184
            }
185
        }
186 6
    }
187
    /**
188
     * @param StructAttributeContainer $allAttributes
189
     * @return StructAttributeContainer
190
     */
191 198
    protected function putRequiredFirst(StructAttributeContainer $allAttributes)
192
    {
193 198
        $attributes = new StructAttributeContainer($this->getGenerator());
194 198
        $requiredAttributes = new StructAttributeContainer($this->getGenerator());
195 198
        $notRequiredAttributes = new StructAttributeContainer($this->getGenerator());
196 198
        foreach ($allAttributes as $attribute) {
197 198
            if ($attribute->isRequired()) {
198 48
                $requiredAttributes->add($attribute);
199 24
            } else {
200 190
                $notRequiredAttributes->add($attribute);
201
            }
202 99
        }
203 198
        foreach ($requiredAttributes as $attribute) {
204 48
            $attributes->add($attribute);
205 99
        }
206 198
        foreach ($notRequiredAttributes as $attribute) {
207 186
            $attributes->add($attribute);
208 99
        }
209 198
        unset($requiredAttributes, $notRequiredAttributes);
210 198
        return $attributes;
211
    }
212
    /**
213
     * Returns the number of own attributes
214
     * @uses Struct::getAttributes()
215
     * @return int
216
     */
217 498
    public function countOwnAttributes()
218
    {
219 498
        return $this->getAttributes(false, false)->count();
220
    }
221
    /**
222
     * Sets the attributes of the struct
223
     * @param StructAttributeContainer $structAttributeContainer
224
     * @return Struct
225
     */
226 1542
    public function setAttributes(StructAttributeContainer $structAttributeContainer)
227
    {
228 1542
        $this->attributes = $structAttributeContainer;
229 1542
        return $this;
230
    }
231
    /**
232
     * Adds attribute based on its original name
233
     * @throws \InvalidArgumentException
234
     * @param string $attributeName the attribute name
235
     * @param string $attributeType the attribute type
236
     * @return Struct
237
     */
238 402
    public function addAttribute($attributeName, $attributeType)
239
    {
240 402
        if (empty($attributeName) || empty($attributeType)) {
241 12
            throw new \InvalidArgumentException(sprintf('Attribute name "%s" and/or attribute type "%s" is invalid for Struct "%s"', $attributeName, $attributeType, $this->getName()), __LINE__);
242
        }
243 390
        if ($this->attributes->getStructAttributeByName($attributeName) === null) {
244 390
            $structAttribute = new StructAttribute($this->getGenerator(), $attributeName, $attributeType, $this);
245 390
            $this->attributes->add($structAttribute);
246 195
        }
247 390
        return $this;
248
    }
249
    /**
250
     * Returns the attribute by its name, otherwise null
251
     * @uses Struct::getAttributes()
252
     * @param string $attributeName the original attribute name
253
     * @return StructAttribute|null
254
     */
255 324
    public function getAttribute($attributeName)
256
    {
257 324
        return $this->attributes->getStructAttributeByName($attributeName);
258
    }
259
    /**
260
     * Returns the attribute by its cleaned name, otherwise null
261
     * @uses Struct::getAttributes()
262
     * @param string $attributeCleanName the cleaned attribute name
263
     * @return StructAttribute|null
264
     */
265 90
    public function getAttributeByCleanName($attributeCleanName)
266
    {
267 90
        return $this->attributes->getStructAttributeByCleanName($attributeCleanName);
268
    }
269
    /**
270
     * Returns the isRestriction value
271
     * @return bool
272
     */
273 492
    public function isRestriction()
274
    {
275 492
        return $this->isRestriction;
276
    }
277
    /**
278
     * Sets the isRestriction value
279
     * @param bool $isRestriction
280
     * @return Struct
281
     */
282 1542
    public function setRestriction($isRestriction = true)
283
    {
284 1542
        $this->isRestriction = $isRestriction;
285 1542
        return $this;
286
    }
287
    /**
288
     * Returns the isStruct value
289
     * @return bool
290
     */
291 546
    public function isStruct()
292
    {
293 546
        return $this->isStruct;
294
    }
295
    /**
296
     * Sets the isStruct value
297
     * @param bool $isStruct
298
     * @return Struct
299
     */
300 1542
    public function setStruct($isStruct = true)
301
    {
302 1542
        $this->isStruct = $isStruct;
303 1542
        return $this;
304
    }
305
    /**
306
     * Returns the list value
307
     * @return string
308
     */
309 18
    public function getList()
310
    {
311 18
        return $this->list;
312
    }
313
    /**
314
     * Returns if the current struct is a list
315
     * List are a set of basic-type values
316
     * @return bool
317
     */
318 210
    public function isList()
319
    {
320 210
        return !empty($this->list);
321
    }
322
    /**
323
     * Sets the list value
324
     * @param string $list
325
     * @return Struct
326
     */
327 510
    public function setList($list = '')
328
    {
329 510
        $this->list = $list;
330 510
        return $this;
331
    }
332
    /**
333
     * Returns the values for an enumeration
334
     * @return StructValueContainer
335
     */
336 144
    public function getValues()
337
    {
338 144
        return $this->values;
339
    }
340
    /**
341
     * Sets the values for an enumeration
342
     * @param StructValueContainer $structValueContainer
343
     * @return Struct
344
     */
345 1542
    protected function setValues(StructValueContainer $structValueContainer)
346
    {
347 1542
        $this->values = $structValueContainer;
348 1542
        return $this;
349
    }
350
    /**
351
     * Adds value to values array
352
     * @uses Struct::getValue()
353
     * @uses Struct::getValues()
354
     * @param mixed $value the original value
355
     * @return Struct
356
     */
357 102
    public function addValue($value)
358
    {
359 102
        if ($this->getValue($value) === null) {
360 102
            $this->values->add(new StructValue($this->getGenerator(), $value, $this->getValues()->count(), $this));
361 51
            $this
362 102
                ->setRestriction(true)
363 102
                ->setStruct(true);
364 51
        }
365 102
        return $this;
366
    }
367
    /**
368
     * Gets the value object for the given value
369
     * @uses Struct::getValues()
370
     * @uses AbstractModel::getName()
371
     * @param string $value Value name
372
     * @return StructValue|null
373
     */
374 144
    public function getValue($value)
375
    {
376 144
        return $this->values->getStructValueByName($value);
377
    }
378
    /**
379
     * Allows to define from which class the current model extends
380
     * @param bool $short
381
     * @return string
382
     */
383 240
    public function getExtends($short = false)
384
    {
385 240
        $extends = '';
386 240
        if ($this->isArray()) {
387 48
            $extends = $this->getGenerator()->getOptionStructArrayClass();
388 225
        } elseif (!$this->isRestriction()) {
389 168
            $extends = $this->getGenerator()->getOptionStructClass();
390 84
        }
391 240
        return $short ? Utils::removeNamespace($extends) : $extends;
392
    }
393
    /**
394
     * @return Struct|null
395
     */
396 354
    public function getInheritanceStruct()
397
    {
398 354
        return $this->getName() === $this->getInheritance() ? null : $this->getGenerator()->getStructByName(str_replace('[]', '', $this->getInheritance()));
399
    }
400
    /**
401
     * @return string
402
     */
403 222
    public function getTopInheritance()
404
    {
405 222
        $inheritance = $this->getInheritance();
406 222
        if (!empty($inheritance)) {
407 156
            $struct = $this->getInheritanceStruct();
408 156
            while ($struct instanceof Struct) {
409 66
                $structInheritance = $struct->getInheritance();
410 66
                if (!empty($structInheritance)) {
411 30
                    $inheritance = $structInheritance;
412 15
                }
413 66
                $struct = $struct->getInheritanceStruct();
414 33
            }
415 78
        }
416 222
        return $inheritance;
417
    }
418
    /**
419
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::getMeta()
420
     * @return string[]
421
     */
422 342
    public function getMeta()
423
    {
424 342
        $inheritanceStruct = $this->getInheritanceStruct();
425 342
        return array_merge_recursive(parent::getMeta(), ($inheritanceStruct && !$inheritanceStruct->isStruct()) ? $inheritanceStruct->getMeta() : []);
426
    }
427
    /**
428
     * @param $filename
429
     * @return StructReservedMethod|StructArrayReservedMethod
430
     */
431 222
    public function getReservedMethodsInstance($filename = null)
432
    {
433 222
        $instance = StructReservedMethod::instance($filename);
434 222
        if ($this->isArray()) {
435 54
            $instance = StructArrayReservedMethod::instance($filename);
436 27
        }
437 222
        return $instance;
438
    }
439
    /**
440
     * @return string[]
441
     */
442 6
    public function getTypes()
443
    {
444 6
        return $this->types;
445
    }
446
    /**
447
     * @return boolean
448
     */
449 204
    public function isUnion()
450
    {
451 204
        return count($this->types) > 0;
452
    }
453
    /**
454
     * @param string[] $types
455
     * @return Struct
456
     */
457 1542
    public function setTypes($types)
458
    {
459 1542
        $this->types = $types;
460 1542
        return $this;
461
    }
462
    /**
463
     * {@inheritDoc}
464
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::toJsonSerialize()
465
     */
466 6
    protected function toJsonSerialize()
467
    {
468
        return [
469 6
            'attributes' => $this->attributes,
470 6
            'restriction' => $this->isRestriction,
471 6
            'struct' => $this->isStruct,
472 6
            'types' => $this->types,
473 6
            'values' => $this->values,
474 6
            'list' => $this->list,
475 3
        ];
476
    }
477
    /**
478
     * @param array $attributes
479
     */
480 486
    public function setAttributesFromSerializedJson(array $attributes)
481
    {
482 486
        foreach ($attributes as $attribute) {
483 480
            $this->attributes->add(self::instanceFromSerializedJson($this->generator, $attribute)->setOwner($this));
484 243
        }
485 486
    }
486
    /**
487
     * @param array $values
488
     */
489 486
    public function setValuesFromSerializedJson(array $values)
490
    {
491 486
        foreach ($values as $value) {
492 450
            $this->values->add(self::instanceFromSerializedJson($this->generator, $value)->setOwner($this));
493 243
        }
494 486
    }
495
}
496