Completed
Push — develop ( 2afd17...8aece3 )
by Mikaël
24:19
created

Struct::getTopInheritance()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 15
ccs 13
cts 13
cp 1
rs 9.2
c 1
b 0
f 1
cc 4
eloc 10
nc 2
nop 0
crap 4
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
10
/**
11
 * Class Struct stands for an available struct described in the WSDL
12
 */
13
class Struct extends AbstractModel
14
{
15
    /**
16
     * @var string
17
     */
18
    const DOC_SUB_PACKAGE_STRUCTS = 'Structs';
19
    /**
20
     * @var string
21
     */
22
    const DOC_SUB_PACKAGE_ENUMERATIONS = 'Enumerations';
23
    /**
24
     * @var string
25
     */
26
    const DOC_SUB_PACKAGE_ARRAYS = 'Arrays';
27
    /**
28
     * Attributes of the struct
29
     * @var StructAttributeContainer
30
     */
31
    private $attributes;
32
    /**
33
     * Is the struct a restriction with defined values  ?
34
     * @var bool
35
     */
36
    private $isRestriction = false;
37
    /**
38
     * If the struct is a restriction with values, then store values
39
     * @var StructValueContainer
40
     */
41
    private $values;
42
    /**
43
     * Define if the urrent struct is a concrete struct or just a virtual struct to store meta informations
44
     * @var bool
45
     */
46
    private $isStruct = false;
47
    /**
48
     * Main constructor
49
     * @see AbstractModel::__construct()
50
     * @uses Struct::setIsStruct()
51
     * @param Generator $generator
52
     * @param string $name the original name
53
     * @param bool $isStruct defines if it's a real sruct or not
54
     * @param bool $isRestriction defines if it's an enumeration or not
55
     */
56 476
    public function __construct(Generator $generator, $name, $isStruct = true, $isRestriction = false)
57
    {
58 476
        parent::__construct($generator, $name);
59 357
        $this
60 476
            ->setIsStruct($isStruct)
61 476
            ->setIsRestriction($isRestriction)
62 476
            ->setAttributes(new StructAttributeContainer($generator))
63 476
            ->setValues(new StructValueContainer($generator));
64 476
    }
65
    /**
66
     * Returns the contextual part of the class name for the package
67
     * @see AbstractModel::getContextualPart()
68
     * @uses Struct::getIsRestriction()
69
     * @return string
70
     */
71 216
    public function getContextualPart()
72
    {
73 216
        $part = $this->getGenerator()->getOptionStructsFolder();
74 216
        if ($this->getIsRestriction()) {
75 80
            $part = $this->getGenerator()->getOptionEnumsFolder();
76 207
        } elseif ($this->isArray()) {
77 44
            $part = $this->getGenerator()->getOptionArraysFolder();
78 33
        }
79 216
        return $part;
80
    }
81
    /**
82
     * Returns the sub package name which the model belongs to
83
     * Must be overridden by sub classes
84
     * @see AbstractModel::getDocSubPackages()
85
     * @uses Struct::getIsRestriction()
86
     * @return array
87
     */
88 120
    public function getDocSubPackages()
89
    {
90 120
        $package = self::DOC_SUB_PACKAGE_STRUCTS;
91 120
        if ($this->getIsRestriction()) {
92 52
            $package = self::DOC_SUB_PACKAGE_ENUMERATIONS;
93 112
        } elseif ($this->isArray()) {
94 28
            $package = self::DOC_SUB_PACKAGE_ARRAYS;
95 21
        }
96
        return array(
97 120
            $package,
98 90
        );
99
    }
100
    /**
101
     * Returns true if the current struct is a collection of values (like an array)
102
     * @uses AbstractModel::getName()
103
     * @uses Struct::countOwnAttributes()
104
     * @return bool
105
     */
106 232
    public function isArray()
107
    {
108 232
        return ($this->countOwnAttributes() === 1 && stripos($this->getName(), 'array') !== false);
109
    }
110
    /**
111
     * Returns the attributes of the struct and potentially from the parent class
112
     * @uses AbstractModel::getInheritance()
113
     * @uses Struct::getIsStruct()
114
     * @uses Struct::getAttributes()
115
     * @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.
116
     * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _contrust method with the required attribute at first
117
     * @return StructAttributeContainer
118
     */
119 244
    public function getAttributes($includeInheritanceAttributes = false, $requiredFirst = false)
120
    {
121 244
        if ($includeInheritanceAttributes === false && $requiredFirst === false) {
122 244
            $attributes = $this->attributes;
123 183
        } else {
124 84
            $attributes = $this->getAllAttributes($includeInheritanceAttributes, $requiredFirst);
125
        }
126 244
        return $attributes;
127
    }
128
    /**
129
     * @param bool $includeInheritanceAttributes
130
     * @param bool $requiredFirst
131
     * @return StructAttributeContainer
132
     */
133 84
    protected function getAllAttributes($includeInheritanceAttributes, $requiredFirst)
134
    {
135 84
        $allAttributes = new StructAttributeContainer($this->getGenerator());
136 84
        if ($includeInheritanceAttributes === true) {
137 4
            $this->addInheritanceAttributes($allAttributes);
138 3
        }
139 84
        foreach ($this->attributes as $attribute) {
140 84
            $allAttributes->add($attribute);
141 63
        }
142 84
        if ($requiredFirst === true) {
143 84
            $attributes = $this->putRequiredFirst($allAttributes);
144 63
        } else {
145
            $attributes = $allAttributes;
146
        }
147 84
        return $attributes;
148
    }
149
    /**
150
     * @param StructAttributeContainer $attributes
151
     */
152 4
    protected function addInheritanceAttributes(StructAttributeContainer $attributes)
153
    {
154 4
        if ($this->getInheritance() != '' && ($model = $this->getInheritanceStruct()) instanceof Struct) {
155
            while ($model->getIsStruct()) {
156
                foreach ($model->getAttributes() as $attribute) {
157
                    $attributes->add($attribute);
158
                }
159
                $model = $this->getGenerator()->getStruct($model->getInheritance());
160
            }
161
        }
162 4
    }
163
    /**
164
     * @param StructAttributeContainer $allAttributes
165
     * @return StructAttributeContainer
166
     */
167 84
    protected function putRequiredFirst(StructAttributeContainer $allAttributes)
168
    {
169 84
        $attributes = new StructAttributeContainer($this->getGenerator());
170 84
        $requiredAttributes = new StructAttributeContainer($this->getGenerator());
171 84
        $notRequiredAttributes = new StructAttributeContainer($this->getGenerator());
172 84
        foreach ($allAttributes as $attribute) {
173 84
            if ($attribute->isRequired()) {
174 28
                $requiredAttributes->add($attribute);
175 21
            } else {
176 78
                $notRequiredAttributes->add($attribute);
177
            }
178 63
        }
179 84
        foreach ($requiredAttributes as $attribute) {
180 28
            $attributes->add($attribute);
181 63
        }
182 84
        foreach ($notRequiredAttributes as $attribute) {
183 76
            $attributes->add($attribute);
184 63
        }
185 84
        unset($requiredAttributes, $notRequiredAttributes);
186 84
        return $attributes;
187
    }
188
    /**
189
     * Returns the number of own attributes
190
     * @uses Struct::getAttributes()
191
     * @return int
192
     */
193 232
    public function countOwnAttributes()
194
    {
195 232
        return $this->getAttributes(false, false)->count();
196
    }
197
    /**
198
     * Sets the attributes of the struct
199
     * @param StructAttributeContainer $structAttributeContainer
200
     * @return Struct
201
     */
202 476
    public function setAttributes(StructAttributeContainer $structAttributeContainer)
203
    {
204 476
        $this->attributes = $structAttributeContainer;
205 476
        return $this;
206
    }
207
    /**
208
     * Adds attribute based on its original name
209
     * @throws \InvalidArgumentException
210
     * @param string $attributeName the attribute name
211
     * @param string $attributeType the attribute type
212
     * @return Struct
213
     */
214 424
    public function addAttribute($attributeName, $attributeType)
215
    {
216 424
        if (empty($attributeName) || empty($attributeType)) {
217 8
            throw new \InvalidArgumentException(sprintf('Attribute name "%s" and/or attribute type "%s" is invalid for Struct "%s"', $attributeName, $attributeType, $this->getName()), __LINE__);
218
        }
219 416
        if ($this->attributes->getStructAttributeByName($attributeName) === null) {
220 412
            $structAttribute = new StructAttribute($this->getGenerator(), $attributeName, $attributeType, $this);
221 412
            $this->attributes->add($structAttribute);
222 309
        }
223 416
        return $this;
224
    }
225
    /**
226
     * Returns the attribute by its name, otherwise null
227
     * @uses Struct::getAttributes()
228
     * @param string $attributeName the original attribute name
229
     * @return StructAttribute|null
230
     */
231 284
    public function getAttribute($attributeName)
232
    {
233 284
        return $this->attributes->getStructAttributeByName($attributeName);
234
    }
235
    /**
236
     * Returns the isRestriction value
237
     * @return bool
238
     */
239 248
    public function getIsRestriction()
240
    {
241 248
        return $this->isRestriction;
242
    }
243
    /**
244
     * Sets the isRestriction value
245
     * @param bool $isRestriction
246
     * @return Struct
247
     */
248 476
    public function setIsRestriction($isRestriction = true)
249
    {
250 476
        $this->isRestriction = $isRestriction;
251 476
        return $this;
252
    }
253
    /**
254
     * Returns the isStruct value
255
     * @return bool
256
     */
257 176
    public function getIsStruct()
258
    {
259 176
        return $this->isStruct;
260
    }
261
    /**
262
     * Sets the isStruct value
263
     * @param bool $isStruct
264
     * @return Struct
265
     */
266 476
    public function setIsStruct($isStruct = true)
267
    {
268 476
        $this->isStruct = $isStruct;
269 476
        return $this;
270
    }
271
    /**
272
     * Returns the values for an enumeration
273
     * @return StructValueContainer
274
     */
275 268
    public function getValues()
276
    {
277 268
        return $this->values;
278
    }
279
    /**
280
     * Sets the values for an enumeration
281
     * @param StructValueContainer $structValueContainer
282
     * @return Struct
283
     */
284 476
    private function setValues(StructValueContainer $structValueContainer)
285
    {
286 476
        $this->values = $structValueContainer;
287 476
        return $this;
288
    }
289
    /**
290
     * Adds value to values array
291
     * @uses Struct::getValue()
292
     * @uses Struct::getValues()
293
     * @param mixed $value the original value
294
     * @return Struct
295
     */
296 272
    public function addValue($value)
297
    {
298 272
        if ($this->getValue($value) === null) {
299 268
            $this->values->add(new StructValue($this->getGenerator(), $value, $this->getValues()->count(), $this));
300 268
            $this->setIsRestriction(true);
301 268
            $this->setIsStruct(true);
302 201
        }
303 272
        return $this;
304
    }
305
    /**
306
     * Gets the value object for the given value
307
     * @uses Struct::getValues()
308
     * @uses AbstractModel::getName()
309
     * @param string $value Value name
310
     * @return StructValue|null
311
     */
312 272
    public function getValue($value)
313
    {
314 272
        return $this->values->getStructValueByName($value);
315
    }
316
    /**
317
     * Allows to define from which class the curent model extends
318
     * @param bool $short
319
     * @return string
320
     */
321 112
    public function getExtends($short = false)
322
    {
323 112
        $extends = '';
324 112
        if ($this->isArray()) {
325 28
            $extends = $this->getGenerator()->getOptionStructArrayClass();
326 107
        } elseif (!$this->getIsRestriction()) {
327 64
            $extends = $this->getGenerator()->getOptionStructClass();
328 48
        }
329 112
        return $short ? Utils::removeNamespace($extends) : $extends;
330
    }
331
    /**
332
     * @return Struct|null
333
     */
334 140
    public function getInheritanceStruct()
335
    {
336 140
        return $this->getGenerator()->getStruct($this->getInheritance());
337
    }
338
    /**
339
     * @return Struct|null
340
     */
341 76
    public function getTopInheritance()
342
    {
343 76
        $inheritance = $this->getInheritance();
344 76
        if (!empty($inheritance)) {
345 28
            $struct = $this->getInheritanceStruct();
346 28
            while ($struct instanceof Struct) {
347 20
                $structInheritance = $struct->getInheritance();
348 20
                if (!empty($structInheritance)) {
349 16
                    $inheritance = $structInheritance;
350 12
                }
351 20
                $struct = $struct->getInheritanceStruct();
352 15
            }
353 21
        }
354 76
        return $inheritance;
355
    }
356
    /**
357
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::getMeta()
358
     * @return string[]
359
     */
360 140
    public function getMeta()
361
    {
362 140
        $inheritanceStruct = $this->getInheritanceStruct();
363 140
        return array_merge_recursive(parent::getMeta(), ($inheritanceStruct && !$inheritanceStruct->getIsStruct()) ? $inheritanceStruct->getMeta() : array());
364
    }
365
}
366