Completed
Push — feature/issue-165 ( 83f642...d66719 )
by Mikaël
23:02 queued 18s
created

Struct::isArray()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 7
nc 13
nop 0
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 7
rs 8.8333
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 1548
    public function __construct(Generator $generator, $name, $isStruct = true, $isRestriction = false)
70
    {
71 1548
        parent::__construct($generator, $name);
72 774
        $this
73 1548
            ->setStruct($isStruct)
74 1548
            ->setRestriction($isRestriction)
75 1548
            ->setAttributes(new StructAttributeContainer($generator))
76 1548
            ->setValues(new StructValueContainer($generator))
77 1548
            ->setTypes([]);
78 1548
    }
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 450
    public function getContextualPart()
86
    {
87 450
        $part = $this->getGenerator()->getOptionStructsFolder();
88 450
        if ($this->isRestriction()) {
89 168
            $part = $this->getGenerator()->getOptionEnumsFolder();
90 423
        } elseif ($this->isArray()) {
91 78
            $part = $this->getGenerator()->getOptionArraysFolder();
92 39
        }
93 450
        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 258
    public function getDocSubPackages()
103
    {
104 258
        $package = self::DOC_SUB_PACKAGE_STRUCTS;
105 258
        if ($this->isRestriction()) {
106 84
            $package = self::DOC_SUB_PACKAGE_ENUMERATIONS;
107 234
        } elseif ($this->isArray()) {
108 48
            $package = self::DOC_SUB_PACKAGE_ARRAYS;
109 24
        }
110
        return [
111 258
            $package,
112 129
        ];
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 504
    public function isArray()
121
    {
122
        return
123
        (
124
            (
125
                (
126 504
                    ($this->isStruct() && $this->countOwnAttributes() === 1) ||
127 480
                    (!$this->isStruct() && $this->countOwnAttributes() <= 1)
128 252
                ) &&
129 330
                stripos($this->getName(), 'array') !== false
130 165
            ) ||
131 489
            (!$this->isStruct() && $this->getMetaValueFirstSet(['arraytype', 'arrayType'], false) !== false)
132 252
        );
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 522
    public function getAttributes($includeInheritanceAttributes = false, $requiredFirst = false)
144
    {
145 522
        if ($includeInheritanceAttributes === false && $requiredFirst === false) {
146 522
            $attributes = $this->attributes;
147 261
        } else {
148 204
            $attributes = $this->getAllAttributes($includeInheritanceAttributes, $requiredFirst);
149
        }
150 522
        return $attributes;
151
    }
152
    /**
153
     * @param bool $includeInheritanceAttributes
154
     * @param bool $requiredFirst
155
     * @return StructAttributeContainer
156
     */
157 204
    protected function getAllAttributes($includeInheritanceAttributes, $requiredFirst)
158
    {
159 204
        $allAttributes = new StructAttributeContainer($this->getGenerator());
160 204
        if ($includeInheritanceAttributes === true) {
161 6
            $this->addInheritanceAttributes($allAttributes);
162 3
        }
163 204
        foreach ($this->attributes as $attribute) {
164 204
            $allAttributes->add($attribute);
165 102
        }
166 204
        if ($requiredFirst === true) {
167 204
            $attributes = $this->putRequiredFirst($allAttributes);
168 102
        } else {
169
            $attributes = $allAttributes;
170
        }
171 204
        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 204
    protected function putRequiredFirst(StructAttributeContainer $allAttributes)
192
    {
193 204
        $attributes = new StructAttributeContainer($this->getGenerator());
194 204
        $requiredAttributes = new StructAttributeContainer($this->getGenerator());
195 204
        $notRequiredAttributes = new StructAttributeContainer($this->getGenerator());
196 204
        foreach ($allAttributes as $attribute) {
197 204
            if ($attribute->isRequired()) {
198 54
                $requiredAttributes->add($attribute);
199 27
            } else {
200 192
                $notRequiredAttributes->add($attribute);
201
            }
202 102
        }
203 204
        foreach ($requiredAttributes as $attribute) {
204 54
            $attributes->add($attribute);
205 102
        }
206 204
        foreach ($notRequiredAttributes as $attribute) {
207 186
            $attributes->add($attribute);
208 102
        }
209 204
        unset($requiredAttributes, $notRequiredAttributes);
210 204
        return $attributes;
211
    }
212
    /**
213
     * Returns the number of own attributes
214
     * @uses Struct::getAttributes()
215
     * @return int
216
     */
217 504
    public function countOwnAttributes()
218
    {
219 504
        return $this->getAttributes(false, false)->count();
220
    }
221
    /**
222
     * Sets the attributes of the struct
223
     * @param StructAttributeContainer $structAttributeContainer
224
     * @return Struct
225
     */
226 1548
    public function setAttributes(StructAttributeContainer $structAttributeContainer)
227
    {
228 1548
        $this->attributes = $structAttributeContainer;
229 1548
        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 330
    public function getAttribute($attributeName)
256
    {
257 330
        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 498
    public function isRestriction()
274
    {
275 498
        return $this->isRestriction;
276
    }
277
    /**
278
     * Sets the isRestriction value
279
     * @param bool $isRestriction
280
     * @return Struct
281
     */
282 1548
    public function setRestriction($isRestriction = true)
283
    {
284 1548
        $this->isRestriction = $isRestriction;
285 1548
        return $this;
286
    }
287
    /**
288
     * Returns the isStruct value
289
     * @return bool
290
     */
291 552
    public function isStruct()
292
    {
293 552
        return $this->isStruct;
294
    }
295
    /**
296
     * Sets the isStruct value
297
     * @param bool $isStruct
298
     * @return Struct
299
     */
300 1548
    public function setStruct($isStruct = true)
301
    {
302 1548
        $this->isStruct = $isStruct;
303 1548
        return $this;
304
    }
305
    /**
306
     * Returns the list value
307
     * @return string
308
     */
309 24
    public function getList()
310
    {
311 24
        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 216
    public function isList()
319
    {
320 216
        return !empty($this->list);
321
    }
322
    /**
323
     * Sets the list value
324
     * @param string $list
325
     * @return Struct
326
     */
327 516
    public function setList($list = '')
328
    {
329 516
        $this->list = $list;
330 516
        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 1548
    protected function setValues(StructValueContainer $structValueContainer)
346
    {
347 1548
        $this->values = $structValueContainer;
348 1548
        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 246
    public function getExtends($short = false)
384
    {
385 246
        $extends = '';
386 246
        if ($this->isArray()) {
387 48
            $extends = $this->getGenerator()->getOptionStructArrayClass();
388 231
        } elseif (!$this->isRestriction()) {
389 174
            $extends = $this->getGenerator()->getOptionStructClass();
390 87
        }
391 246
        return $short ? Utils::removeNamespace($extends) : $extends;
392
    }
393
    /**
394
     * @return Struct|null
395
     */
396 360
    public function getInheritanceStruct()
397
    {
398 360
        return $this->getName() === $this->getInheritance() ? null : $this->getGenerator()->getStructByName(str_replace('[]', '', $this->getInheritance()));
399
    }
400
    /**
401
     * @return string
402
     */
403 228
    public function getTopInheritance()
404
    {
405 228
        $inheritance = $this->getInheritance();
406 228
        if (!empty($inheritance)) {
407 162
            $struct = $this->getInheritanceStruct();
408 162
            while ($struct instanceof Struct) {
409 72
                $structInheritance = $struct->getInheritance();
410 72
                if (!empty($structInheritance)) {
411 36
                    $inheritance = $structInheritance;
412 18
                }
413 72
                $struct = $struct->getInheritanceStruct();
414 36
            }
415 81
        }
416 228
        return $inheritance;
417
    }
418
    /**
419
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::getMeta()
420
     * @return string[]
421
     */
422 348
    public function getMeta()
423
    {
424 348
        $inheritanceStruct = $this->getInheritanceStruct();
425 348
        return array_merge_recursive(parent::getMeta(), ($inheritanceStruct && !$inheritanceStruct->isStruct()) ? $inheritanceStruct->getMeta() : []);
426
    }
427
    /**
428
     * @param $filename
429
     * @return StructReservedMethod|StructArrayReservedMethod
430
     */
431 228
    public function getReservedMethodsInstance($filename = null)
432
    {
433 228
        $instance = StructReservedMethod::instance($filename);
434 228
        if ($this->isArray()) {
435 54
            $instance = StructArrayReservedMethod::instance($filename);
436 27
        }
437 228
        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 210
    public function isUnion()
450
    {
451 210
        return count($this->types) > 0;
452
    }
453
    /**
454
     * @param string[] $types
455
     * @return Struct
456
     */
457 1548
    public function setTypes($types)
458
    {
459 1548
        $this->types = $types;
460 1548
        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 492
    public function setAttributesFromSerializedJson(array $attributes)
481
    {
482 492
        foreach ($attributes as $attribute) {
483 486
            $this->attributes->add(self::instanceFromSerializedJson($this->generator, $attribute)->setOwner($this));
484 246
        }
485 492
    }
486
    /**
487
     * @param array $values
488
     */
489 492
    public function setValuesFromSerializedJson(array $values)
490
    {
491 492
        foreach ($values as $value) {
492 456
            $this->values->add(self::instanceFromSerializedJson($this->generator, $value)->setOwner($this));
493 246
        }
494 492
    }
495
}
496