Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.80% covered (warning)
89.80%
44 / 49
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
TagRestriction
89.80% covered (warning)
89.80%
44 / 49
57.14% covered (warning)
57.14%
4 / 7
23.56
0.00% covered (danger)
0.00%
0 / 1
 parseRestriction
87.50% covered (warning)
87.50%
21 / 24
0.00% covered (danger)
0.00%
0 / 1
8.12
 parseWsdl
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 parsingTag
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 parseRestrictionAttributes
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 parseRestrictionChildren
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 parseRestrictionChild
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 parseRestrictionChildAttribute
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace WsdlToPhp\PackageGenerator\Parser\Wsdl;
6
7use WsdlToPhp\DomHandler\AbstractAttributeHandler;
8use WsdlToPhp\DomHandler\AttributeHandler;
9use WsdlToPhp\PackageGenerator\Model\AbstractModel;
10use WsdlToPhp\PackageGenerator\Model\Struct;
11use WsdlToPhp\PackageGenerator\Model\StructAttribute;
12use WsdlToPhp\PackageGenerator\Model\Wsdl;
13use WsdlToPhp\WsdlHandler\AbstractDocument;
14use WsdlToPhp\WsdlHandler\Tag\AbstractTag;
15use WsdlToPhp\WsdlHandler\Tag\AbstractTag as Tag;
16use WsdlToPhp\WsdlHandler\Tag\TagRestriction as Restriction;
17
18final class TagRestriction extends AbstractTagParser
19{
20    public function parseRestriction(Restriction $restriction): void
21    {
22        /** @var AbstractTag $parent */
23        $parent = $restriction->getSuitableParent();
24        if (!$parent) {
25            return;
26        }
27
28        /** @var AbstractTag $parentParent */
29        $parentParent = $parent->getSuitableParent();
30        if ($parentParent) {
31            $parentModel = $this->getModel($parentParent);
32            if (!$parentModel instanceof Struct) {
33                return;
34            }
35
36            $parentAttribute = $parentModel->getAttribute($parent->getAttributeName());
37            if (!$parentAttribute instanceof StructAttribute) {
38                return;
39            }
40
41            $this
42                ->parseRestrictionAttributes($parentAttribute, $restriction)
43                ->parseRestrictionChildren($parentAttribute, $restriction)
44            ;
45        } else {
46            // If restriction has a base attribute, it's not necessarily, and probably surely,
47            // not declared as inheriting from the base attribute value.
48            // This is why it's first searched without type in order to complete its information,
49            // otherwise we look for the model already inheriting from the base attribute value.
50            $model = $this->getModel($parent, $restriction->getAttributeBase()) ?? $this->getModel($parent);
51
52            // If restriction is contained by a union tag, don't create the virtual struct as "union"s
53            // are wrongly parsed by SoapClient::__getTypes and this creates a duplicated element then
54            if (!$model && !$restriction->hasUnionParent()) {
55                $this->getGenerator()->getStructs()->addVirtualStruct($parent->getAttributeName(), $restriction->getAttributeBase());
56                $model = $this->getModel($parent, $restriction->getAttributeBase());
57            }
58
59            if ($model instanceof Struct) {
60                $this
61                    ->parseRestrictionAttributes($model, $restriction)
62                    ->parseRestrictionChildren($model, $restriction)
63                ;
64            }
65        }
66    }
67
68    protected function parseWsdl(Wsdl $wsdl): void
69    {
70        /** @var Restriction $tag */
71        foreach ($this->getTags() as $tag) {
72            if ($tag->isEnumeration()) {
73                continue;
74            }
75
76            $this->parseRestriction($tag);
77        }
78    }
79
80    protected function parsingTag(): string
81    {
82        return AbstractDocument::TAG_RESTRICTION;
83    }
84
85    protected function parseRestrictionAttributes(AbstractModel $model, Restriction $restriction): self
86    {
87        if (!$restriction->hasAttributes()) {
88            return $this;
89        }
90
91        // ensure inheritance of model is well-defined, SoapClient parser is based on SoapClient::__getTypes which can be false in some case
92        $model->setInheritance($restriction->getAttributeBase());
93
94        /** @var AbstractAttributeHandler $attribute */
95        foreach ($restriction->getAttributes() as $attribute) {
96            $model->addMeta($attribute->getName(), $attribute->getValue(true));
97        }
98
99        return $this;
100    }
101
102    protected function parseRestrictionChildren(AbstractModel $model, Restriction $restriction): self
103    {
104        foreach ($restriction->getElementChildren() as $child) {
105            if (!$child instanceof Tag) {
106                continue;
107            }
108
109            $this->parseRestrictionChild($model, $child);
110        }
111
112        return $this;
113    }
114
115    protected function parseRestrictionChild(AbstractModel $model, Tag $child): self
116    {
117        if ($child->hasAttributeValue()) {
118            $model->addMeta($child->getName(), $child->getValueAttributeValue(true));
119        } else {
120            foreach ($child->getAttributes() as $attribute) {
121                $this->parseRestrictionChildAttribute($model, $attribute);
122            }
123        }
124
125        return $this;
126    }
127
128    protected function parseRestrictionChildAttribute(AbstractModel $model, AttributeHandler $attribute): self
129    {
130        if ('arraytype' === mb_strtolower($attribute->getName())) {
131            $model->setInheritance($attribute->getValue());
132        }
133
134        $model->addMeta($attribute->getName(), $attribute->getValue(true));
135
136        return $this;
137    }
138}