Passed
Push — develop ( 32a57e...589086 )
by Mikaël
03:14 queued 36s
created

PhpClass::setInterfaces()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PhpGenerator\Element;
6
7
use InvalidArgumentException;
8
9
class PhpClass extends AbstractElement
10
{
11
    const PHP_DECLARATION = 'class';
12
13
    const PHP_ABSTRACT_KEYWORD = 'abstract';
14
15
    const PHP_IMPLEMENTS_KEYWORD = 'implements';
16
17
    const PHP_EXTENDS_KEYWORD = 'extends';
18
19
    protected bool $abstract;
20
21
    /**
22
     * @var string|PhpClass
23
     */
24
    protected $extends;
25
26
    /**
27
     * @var string[]|PhpClass[]
28
     */
29
    protected array $interfaces;
30
31 116
    public function __construct(string $name, bool $abstract = false, $extends = null, array $interfaces = [])
32
    {
33 116
        parent::__construct($name);
34
        $this
35 116
            ->setAbstract($abstract)
36 116
            ->setExtends($extends)
37 116
            ->setInterfaces($interfaces);
38 116
    }
39
40 116
    public function setAbstract(bool $abstract): self
41
    {
42 116
        if (!is_bool($abstract)) {
0 ignored issues
show
introduced by
The condition is_bool($abstract) is always true.
Loading history...
43
            throw new InvalidArgumentException(sprintf('Abstract must be a boolean, "%s" given', gettype($abstract)));
44
        }
45 116
        $this->abstract = $abstract;
46 116
        return $this;
47
    }
48
49 48
    public function getAbstract(): bool
50
    {
51 48
        return $this->abstract;
52
    }
53
54 64
    protected function getPhpAbstract(): string
55
    {
56 64
        return $this->getAbstract() === false ? '' : static::PHP_ABSTRACT_KEYWORD . ' ';
57
    }
58
59
    /**
60
     * @throws InvalidArgumentException
61
     * @param string|PhpClass|null $extends
62
     * @return PhpClass
63
     */
64 116
    public function setExtends($extends): self
65
    {
66 116
        if (!self::extendsIsValid($extends)) {
67 2
            throw new InvalidArgumentException('Extends must be a string or a PhpClass instance');
68
        }
69 116
        $this->extends = $extends;
70 116
        return $this;
71
    }
72
73
    /**
74
     * @param string|PhpClass|null $extends
75
     * @return bool
76
     */
77 116
    public static function extendsIsValid($extends): bool
78
    {
79 116
        return $extends === null || self::stringIsValid($extends, true, true) || $extends instanceof PhpClass;
80
    }
81
82
    /**
83
     * @return string|PhpClass
84
     */
85 50
    public function getExtends()
86
    {
87 50
        return $this->extends;
88
    }
89
90 64
    protected function getPhpExtends(): string
91
    {
92 64
        $extends = $this->getExtends();
93 64
        return empty($extends) ? '' : sprintf(' %s %s', static::PHP_EXTENDS_KEYWORD, ($extends instanceof PhpClass ? $extends->getName() : $extends));
94
    }
95
96
    /**
97
     * @throws InvalidArgumentException
98
     * @param string[]|PhpClass[] $interfaces
99
     * @return PhpClass
100
     */
101 116
    public function setInterfaces(array $interfaces = []): self
102
    {
103 116
        if (!self::interfacesAreValid($interfaces)) {
104 2
            throw new InvalidArgumentException('Interfaces are not valid');
105
        }
106 116
        $this->interfaces = $interfaces;
107 116
        return $this;
108
    }
109
110
    /**
111
     * @param string[]|PhpClass[] $interfaces
112
     * @return bool
113
     */
114 116
    public static function interfacesAreValid(array $interfaces = []): bool
115
    {
116 116
        $valid = true;
117 116
        foreach ($interfaces as $interface) {
118 28
            $valid &= self::interfaceIsValid($interface);
119
        }
120 116
        return (bool) $valid;
121
    }
122
123
    /**
124
     * @param string|PhpClass $interface
125
     * @return bool
126
     */
127 28
    public static function interfaceIsValid($interface): bool
128
    {
129 28
        return self::stringIsValid($interface) || $interface instanceof PhpClass;
130
    }
131
132
    /**
133
     *
134
     * @return string[]|PhpClass[]
135
     */
136 66
    public function getInterfaces(): array
137
    {
138 66
        return $this->interfaces;
139
    }
140
141
    /**
142
     * @return string
143
     */
144 64
    protected function getPhpInterfaces(): string
145
    {
146 64
        $interfaces = [];
147 64
        foreach ($this->getInterfaces() as $interface) {
148 24
            $interfaces[] = $this->getPhpInterface($interface);
149
        }
150 64
        return empty($interfaces) ? '' : sprintf(' %s%s', static::PHP_IMPLEMENTS_KEYWORD, implode(',', $interfaces));
151
    }
152
153
    /**
154
     * @param string|PhpClass $interface
155
     * @return string
156
     */
157 24
    protected function getPhpInterface($interface): string
158
    {
159 24
        return sprintf(' %s', is_string($interface) ? $interface : $interface->getName());
160
    }
161
162 64
    public function getPhpDeclaration(): string
163
    {
164 64
        return trim(sprintf('%s%s %s%s%s', $this->getPhpAbstract(), static::PHP_DECLARATION, $this->getPhpName(), $this->getPhpExtends(), $this->getPhpInterfaces()));
165
    }
166
167
    /**
168
     * defines authorized children element types
169
     * @return string[]
170
     */
171 32
    public function getChildrenTypes(): array
172
    {
173
        return [
174 32
            'string',
175
            PhpAnnotationBlock::class,
176
            PhpMethod::class,
177
            PhpConstant::class,
178
            PhpProperty::class,
179
        ];
180
    }
181
182
    /**
183
     * Allows to indicate that children are contained by brackets,
184
     * in the case the method returns true, getBracketBeforeChildren
185
     * is called instead of getLineBeforeChildren and getBracketAfterChildren
186
     * is called instead of getLineAfterChildren, but be aware that these methods
187
     * call the two others
188
     * @return bool
189
     */
190 32
    public function useBracketsForChildren(): bool
191
    {
192 32
        return true;
193
    }
194
}
195