Passed
Pull Request — develop (#234)
by Mikaël
03:31
created

StructArray::addStructMethodAddTo()   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
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\File;
6
7
use InvalidArgumentException;
8
use WsdlToPhp\PackageGenerator\File\Element\PhpFunctionParameter;
9
use WsdlToPhp\PackageGenerator\File\Validation\Rules;
10
use WsdlToPhp\PackageGenerator\Model\AbstractModel;
11
use WsdlToPhp\PackageGenerator\Model\Struct as StructModel;
12
use WsdlToPhp\PackageGenerator\Model\StructAttribute as StructAttributeModel;
13
use WsdlToPhp\PhpGenerator\Element\PhpAnnotation;
14
use WsdlToPhp\PhpGenerator\Element\PhpAnnotationBlock;
15
use WsdlToPhp\PhpGenerator\Element\PhpMethod;
16
17
final class StructArray extends Struct
18
{
19
    public const METHOD_GET_ATTRIBUTE_NAME = 'getAttributeName';
20
    public const METHOD_CURRENT = 'current';
21
    public const METHOD_ITEM = 'item';
22
    public const METHOD_FIRST = 'first';
23
    public const METHOD_LAST = 'last';
24
    public const METHOD_OFFSET_GET = 'offsetGet';
25
    public const METHOD_ADD = 'add';
26
27 17
    public function addStructMethodsSetAndGet(): self
28
    {
29 17
        parent::addStructMethodsSetAndGet();
30
        $this
31 17
            ->addArrayMethodCurrent()
32 17
            ->addArrayMethodItem()
33 17
            ->addArrayMethodFirst()
34 17
            ->addArrayMethodLast()
35 17
            ->addArrayMethodOffsetGet()
36 17
            ->addArrayMethodAdd()
37 17
            ->addArrayMethodGetAttributeName()
38
        ;
39
40 17
        return $this;
41
    }
42
43 23
    public function setModel(AbstractModel $model): self
44
    {
45 23
        if ($model instanceof StructModel && !$model->isArray()) {
46 4
            throw new InvalidArgumentException('The model is not a valid array struct (name must contain Array and the model must contain only one property', __LINE__);
47
        }
48
49 19
        return parent::setModel($model);
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::setModel($model) returns the type WsdlToPhp\PackageGenerator\File\Struct which includes types incompatible with the type-hinted return WsdlToPhp\PackageGenerator\File\StructArray.
Loading history...
50
    }
51
52
    /**
53
     * Disable this feature within StructArray class.
54
     */
55 17
    protected function addStructMethodAddTo(StructAttributeModel $attribute): Struct
56
    {
57 17
        return $this;
58
    }
59
60 17
    protected function addArrayMethodCurrent(): self
61
    {
62 17
        return $this->addArrayMethodGenericMethod(self::METHOD_CURRENT, $this->getArrayMethodBody(self::METHOD_CURRENT), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
63
    }
64
65 17
    protected function addArrayMethodItem(): self
66
    {
67 17
        return $this->addArrayMethodGenericMethod(self::METHOD_ITEM, $this->getArrayMethodBody(self::METHOD_ITEM, '$index'), [
68 17
            'index',
69 17
        ], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
70
    }
71
72 17
    protected function addArrayMethodFirst(): self
73
    {
74 17
        return $this->addArrayMethodGenericMethod(self::METHOD_FIRST, $this->getArrayMethodBody(self::METHOD_FIRST), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
75
    }
76
77 17
    protected function addArrayMethodLast(): self
78
    {
79 17
        return $this->addArrayMethodGenericMethod(self::METHOD_LAST, $this->getArrayMethodBody(self::METHOD_LAST), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
80
    }
81
82 17
    protected function addArrayMethodOffsetGet(): self
83
    {
84 17
        return $this->addArrayMethodGenericMethod(self::METHOD_OFFSET_GET, $this->getArrayMethodBody(self::METHOD_OFFSET_GET, '$offset'), [
85 17
            'offset',
86 17
        ], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
87
    }
88
89 17
    protected function addArrayMethodGetAttributeName(): self
90
    {
91 17
        return $this->addArrayMethodGenericMethod(
92 17
            self::METHOD_GET_ATTRIBUTE_NAME,
93 9
            sprintf(
94 17
                'return \'%s\';',
95
                $this
96 17
                    ->getModel()
97 17
                    ->getAttributes()
0 ignored issues
show
Bug introduced by
The method getAttributes() does not exist on WsdlToPhp\PackageGenerator\Model\AbstractModel. It seems like you code against a sub-type of WsdlToPhp\PackageGenerator\Model\AbstractModel such as WsdlToPhp\PackageGenerator\Model\Struct. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
                    ->/** @scrutinizer ignore-call */ getAttributes()
Loading history...
98 17
                    ->offsetGet(0)
99 17
                    ->getName()
100
            ),
101 17
            [],
102 17
            self::TYPE_STRING
103
        );
104
    }
105
106 17
    protected function addArrayMethodAdd(): self
107
    {
108 17
        if ($this->getModelFromStructAttribute() instanceof StructModel) {
109 15
            $method = new PhpMethod(self::METHOD_ADD, [
110 15
                new PhpFunctionParameter(
111 15
                    'item',
112 15
                    PhpFunctionParameter::NO_VALUE,
113 15
                    $this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false),
114 15
                    $this->getStructAttribute()
115
                ),
116 15
            ], self::TYPE_SELF);
117
118 15
            if ($this->getGenerator()->getOptionValidation()) {
119 14
                $rules = new Rules($this, $method, $this->getStructAttribute(), $this->methods);
120 14
                $rules->getEnumerationRule()->applyRule('item', null);
121
            }
122
123 15
            $method->addChild('return parent::add($item);');
124 15
            $this->methods->add($method);
125
        }
126
127 17
        return $this;
128
    }
129
130 17
    protected function addArrayMethodGenericMethod(string $name, string $body, array $methodParameters = [], ?string $returnType = null): self
131
    {
132 17
        $method = new PhpMethod($name, $methodParameters, $returnType);
133 17
        $method->addChild($body);
134 17
        $this->methods->add($method);
135
136 17
        return $this;
137
    }
138
139 17
    protected function getArrayMethodGetAttributeNameAnnotationBlock(): PhpAnnotationBlock
140
    {
141 17
        return new PhpAnnotationBlock([
142 17
            'Returns the attribute name',
143 17
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::%s()', $this->getModel()->getExtends(true), self::METHOD_GET_ATTRIBUTE_NAME)),
144 17
            new PhpAnnotation(self::ANNOTATION_RETURN, sprintf('string %s', $this->getModel()->getAttributes()->offsetGet(0)->getName())),
145
        ]);
146
    }
147
148 17
    protected function getArrayMethodCurrentAnnotationBlock(): PhpAnnotationBlock
149
    {
150 17
        return $this->getArrayMethodGenericAnnotationBlock(self::METHOD_CURRENT, 'Returns the current element');
151
    }
152
153 17
    protected function getArrayMethodFirstAnnotationBlock(): PhpAnnotationBlock
154
    {
155 17
        return $this->getArrayMethodGenericAnnotationBlock(self::METHOD_FIRST, 'Returns the first element');
156
    }
157
158 17
    protected function getArrayMethodLastAnnotationBlock(): PhpAnnotationBlock
159
    {
160 17
        return $this->getArrayMethodGenericAnnotationBlock(self::METHOD_LAST, 'Returns the last element');
161
    }
162
163 17
    protected function getArrayMethodItemAnnotationBlock(): PhpAnnotationBlock
164
    {
165 17
        return $this->getArrayMethodGenericAnnotationBlock(self::METHOD_ITEM, 'Returns the indexed element', 'int $index');
166
    }
167
168 17
    protected function getArrayMethodOffsetGetAnnotationBlock(): PhpAnnotationBlock
169
    {
170 17
        return $this->getArrayMethodGenericAnnotationBlock(self::METHOD_OFFSET_GET, 'Returns the element at the offset', 'int $offset');
171
    }
172
173 15
    protected function getArrayMethodAddAnnotationBlock(): PhpAnnotationBlock
174
    {
175 15
        return new PhpAnnotationBlock([
176 15
            'Add element to array',
177 15
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::add()', $this->getModel()->getExtends(true))),
178 15
            new PhpAnnotation(self::ANNOTATION_THROWS, InvalidArgumentException::class),
179 15
            new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $item', $this->getStructAttributeType(null, true, false))),
180 15
            new PhpAnnotation(self::ANNOTATION_RETURN, sprintf('%s', $this->getModel()->getPackagedName(true))),
181
        ]);
182
    }
183
184 17
    protected function getArrayMethodGenericAnnotationBlock(string $name, string $description, $param = null): PhpAnnotationBlock
185
    {
186 17
        $annotationBlock = new PhpAnnotationBlock([
187 17
            $description,
188 17
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::%s()', $this->getModel()->getExtends(true), $name)),
189
        ]);
190
191 17
        if (!empty($param)) {
192 17
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, $param));
193
        }
194 17
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getStructAttributeTypeGetAnnotation($this->getStructAttribute(), false, true)));
195
196 17
        return $annotationBlock;
197
    }
198
199 17
    protected function getStructMethodAnnotationBlock(PhpMethod $method): ?PhpAnnotationBlock
200
    {
201 17
        switch ($method->getName()) {
202 17
            case self::METHOD_GET_ATTRIBUTE_NAME:
203 17
                $annotationBlock = $this->getArrayMethodGetAttributeNameAnnotationBlock();
204
205 17
                break;
206
207 17
            case self::METHOD_CURRENT:
208 17
                $annotationBlock = $this->getArrayMethodCurrentAnnotationBlock();
209
210 17
                break;
211
212 17
            case self::METHOD_FIRST:
213 17
                $annotationBlock = $this->getArrayMethodFirstAnnotationBlock();
214
215 17
                break;
216
217 17
            case self::METHOD_ITEM:
218 17
                $annotationBlock = $this->getArrayMethodItemAnnotationBlock();
219
220 17
                break;
221
222 17
            case self::METHOD_LAST:
223 17
                $annotationBlock = $this->getArrayMethodLastAnnotationBlock();
224
225 17
                break;
226
227 17
            case self::METHOD_OFFSET_GET:
228 17
                $annotationBlock = $this->getArrayMethodOffsetGetAnnotationBlock();
229
230 17
                break;
231
232 17
            case self::METHOD_ADD:
233 15
                $annotationBlock = $this->getArrayMethodAddAnnotationBlock();
234
235 15
                break;
236
237
            default:
238 17
                $annotationBlock = parent::getStructMethodAnnotationBlock($method);
239
240 17
                break;
241
        }
242
243 17
        return $annotationBlock;
244
    }
245
246 17
    protected function getArrayMethodBody(string $method, $var = ''): string
247
    {
248 17
        return sprintf('return parent::%s(%s);', $method, $var);
249
    }
250
}
251