Issues (51)

src/File/StructArray.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\File;
6
7
use WsdlToPhp\PackageGenerator\File\Element\PhpFunctionParameter;
8
use WsdlToPhp\PackageGenerator\File\Validation\Rules;
9
use WsdlToPhp\PackageGenerator\Model\AbstractModel;
10
use WsdlToPhp\PackageGenerator\Model\Struct as StructModel;
11
use WsdlToPhp\PackageGenerator\Model\StructAttribute as StructAttributeModel;
12
use WsdlToPhp\PhpGenerator\Element\AssignedValueElementInterface;
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 20
    public function addStructMethodsSetAndGet(): self
28
    {
29 20
        parent::addStructMethodsSetAndGet();
30 20
        $this
31 20
            ->addArrayMethodCurrent()
32 20
            ->addArrayMethodItem()
33 20
            ->addArrayMethodFirst()
34 20
            ->addArrayMethodLast()
35 20
            ->addArrayMethodOffsetGet()
36 20
            ->addArrayMethodAdd()
37 20
            ->addArrayMethodGetAttributeName()
38 20
        ;
39
40 20
        return $this;
41
    }
42
43 20
    public function setModel(AbstractModel $model): self
44
    {
45 20
        if ($model instanceof StructModel && !$model->isArray()) {
46
            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 26
49
        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 26
    }
51 4
52
    protected function addClassElement(): AbstractModelFile
53
    {
54 22
        return AbstractModelFile::addClassElement();
55
    }
56
57
    /**
58
     * Disable this feature within StructArray class.
59
     */
60 20
    protected function addStructMethodAddTo(StructAttributeModel $attribute): Struct
61
    {
62 20
        return $this;
63
    }
64
65 20
    protected function addArrayMethodCurrent(): self
66
    {
67 20
        return $this->addArrayMethodGenericMethod(self::METHOD_CURRENT, $this->getArrayMethodBody(self::METHOD_CURRENT), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
68
    }
69
70 20
    protected function addArrayMethodItem(): self
71
    {
72 20
        return $this->addArrayMethodGenericMethod(self::METHOD_ITEM, $this->getArrayMethodBody(self::METHOD_ITEM, '$index'), [
73 20
            'index',
74 20
        ], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
75
    }
76
77 20
    protected function addArrayMethodFirst(): self
78
    {
79 20
        return $this->addArrayMethodGenericMethod(self::METHOD_FIRST, $this->getArrayMethodBody(self::METHOD_FIRST), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
80
    }
81
82 20
    protected function addArrayMethodLast(): self
83
    {
84 20
        return $this->addArrayMethodGenericMethod(self::METHOD_LAST, $this->getArrayMethodBody(self::METHOD_LAST), [], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
85
    }
86
87 20
    protected function addArrayMethodOffsetGet(): self
88
    {
89 20
        return $this->addArrayMethodGenericMethod(self::METHOD_OFFSET_GET, $this->getArrayMethodBody(self::METHOD_OFFSET_GET, '$offset'), [
90 20
            'offset',
91 20
        ], '?'.$this->getStructAttributeTypeAsPhpType($this->getStructAttribute(), false));
92
    }
93
94 20
    protected function addArrayMethodGetAttributeName(): self
95
    {
96
        /** @var StructModel $model */
97 20
        $model = $this->getModel();
98
99 20
        return $this->addArrayMethodGenericMethod(
100 20
            self::METHOD_GET_ATTRIBUTE_NAME,
101 20
            sprintf(
102 20
                'return \'%s\';',
103 20
                $model
104 20
                    ->getAttributes()
105 20
                    ->offsetGet(0)
106 20
                    ->getName()
107 20
            ),
108 20
            [],
109 20
            self::TYPE_STRING
110 20
        );
111
    }
112
113 20
    protected function addArrayMethodAdd(): self
114
    {
115 20
        if ($this->getModelFromStructAttribute() instanceof StructModel) {
116 18
            $method = new PhpMethod(self::METHOD_ADD, [
117 18
                new PhpFunctionParameter(
118 18
                    'item',
119 18
                    AssignedValueElementInterface::NO_VALUE,
120 18
                    null,
121 18
                    $this->getStructAttribute()
122 18
                ),
123 18
            ], self::TYPE_SELF);
124
125 18
            if ($this->getGenerator()->getOptionValidation()) {
126 18
                $rules = new Rules($this, $method, $this->getStructAttribute(), $this->methods);
0 ignored issues
show
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

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