Completed
Push — master ( ab3100...ab2db9 )
by Mikaël
57:47 queued 20:08
created

Struct::setRestriction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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