Passed
Push — feature/issue-250 ( 5a78c9 )
by Mikaël
07:02
created

StructArray::addArrayMethodOffsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
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 16
    public function addStructMethodsSetAndGet(): self
28
    {
29 16
        parent::addStructMethodsSetAndGet();
30
        $this
31 16
            ->addArrayMethodCurrent()
32 16
            ->addArrayMethodItem()
33 16
            ->addArrayMethodFirst()
34 16
            ->addArrayMethodLast()
35 16
            ->addArrayMethodOffsetGet()
36 16
            ->addArrayMethodAdd()
37 16
            ->addArrayMethodGetAttributeName()
38
        ;
39
40 16
        return $this;
41
    }
42
43 22
    public function setModel(AbstractModel $model): self
44
    {
45 22
        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 18
        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 16
    protected function addStructMethodAddTo(StructAttributeModel $attribute): Struct
56
    {
57 16
        return $this;
58
    }
59
60 16
    protected function addArrayMethodCurrent(): self
61
    {
62 16
        return $this->addArrayMethodGenericMethod(self::METHOD_CURRENT, $this->getArrayMethodBody(self::METHOD_CURRENT), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
63
    }
64
65 16
    protected function addArrayMethodItem(): self
66
    {
67 16
        return $this->addArrayMethodGenericMethod(self::METHOD_ITEM, $this->getArrayMethodBody(self::METHOD_ITEM, '$index'), [
68 16
            'index',
69 16
        ], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
70
    }
71
72 16
    protected function addArrayMethodFirst(): self
73
    {
74 16
        return $this->addArrayMethodGenericMethod(self::METHOD_FIRST, $this->getArrayMethodBody(self::METHOD_FIRST), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
75
    }
76
77 16
    protected function addArrayMethodLast(): self
78
    {
79 16
        return $this->addArrayMethodGenericMethod(self::METHOD_LAST, $this->getArrayMethodBody(self::METHOD_LAST), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
80
    }
81
82 16
    protected function addArrayMethodOffsetGet(): self
83
    {
84 16
        return $this->addArrayMethodGenericMethod(self::METHOD_OFFSET_GET, $this->getArrayMethodBody(self::METHOD_OFFSET_GET, '$offset'), [
85 16
            'offset',
86 16
        ], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
87
    }
88
89 16
    protected function addArrayMethodGetAttributeName(): self
90
    {
91 16
        return $this->addArrayMethodGenericMethod(
92 16
            self::METHOD_GET_ATTRIBUTE_NAME,
93
            sprintf(
94 16
                'return \'%s\';',
95
                $this
96 16
                    ->getModel()
97 16
                    ->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 16
                    ->offsetGet(0)
99 16
                    ->getName()
100
            ),
101 16
            [],
102 16
            self::TYPE_STRING
103
        );
104
    }
105
106 16
    protected function addArrayMethodAdd(): self
107
    {
108 16
        if ($this->getModelFromStructAttribute() instanceof StructModel) {
109 14
            $method = new PhpMethod(self::METHOD_ADD, [
110 14
                new PhpFunctionParameter(
111 14
                    'item',
112 14
                    PhpFunctionParameter::NO_VALUE,
113 14
                    null,
114 14
                    $this->getStructAttribute()
115
                ),
116 14
            ], self::TYPE_SELF);
117
118 14
            if ($this->getGenerator()->getOptionValidation()) {
119 14
                $rules = new Rules($this, $method, $this->getStructAttribute(), $this->methods);
0 ignored issues
show
Bug introduced by
It seems like $this->getStructAttribute() can also be of type null; however, parameter $attribute of WsdlToPhp\PackageGenerat...on\Rules::__construct() does only seem to accept WsdlToPhp\PackageGenerator\Model\StructAttribute, maybe add an additional type check? ( Ignorable by Annotation )

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

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