Passed
Push — develop ( 589086...18ac87 )
by Mikaël
03:46
created

PhpClass   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 187
ccs 52
cts 52
cp 1
rs 10
c 0
b 0
f 0
wmc 29

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getPhpInterfaces() 0 8 3
A getPhpAbstract() 0 3 2
A interfaceIsValid() 0 3 2
A getPhpDeclaration() 0 3 1
A setInterfaces() 0 8 2
A getPhpInterface() 0 3 2
A getInterfaces() 0 3 1
A interfacesAreValid() 0 8 2
A getAbstract() 0 3 1
A getPhpExtends() 0 5 3
A setExtends() 0 8 2
A getChildrenTypes() 0 8 1
A useBracketsForChildren() 0 3 1
A setAbstract() 0 5 1
A extendsIsValid() 0 3 3
A getExtends() 0 3 1
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
        $this->abstract = $abstract;
43
44 116
        return $this;
45
    }
46
47 48
    public function getAbstract(): bool
48
    {
49 48
        return $this->abstract;
50
    }
51
52 64
    protected function getPhpAbstract(): string
53
    {
54 64
        return $this->getAbstract() === false ? '' : static::PHP_ABSTRACT_KEYWORD . ' ';
55
    }
56
57
    /**
58
     * @throws InvalidArgumentException
59
     * @param string|PhpClass|null $extends
60
     * @return PhpClass
61
     */
62 116
    public function setExtends($extends): self
63
    {
64 116
        if (!self::extendsIsValid($extends)) {
65 2
            throw new InvalidArgumentException('Extends must be a string or a PhpClass instance');
66
        }
67 116
        $this->extends = $extends;
68
69 116
        return $this;
70
    }
71
72
    /**
73
     * @param string|PhpClass|null $extends
74
     * @return bool
75
     */
76 116
    public static function extendsIsValid($extends): bool
77
    {
78 116
        return $extends === null || self::stringIsValid($extends, true, true) || $extends instanceof PhpClass;
79
    }
80
81
    /**
82
     * @return string|PhpClass
83
     */
84 50
    public function getExtends()
85
    {
86 50
        return $this->extends;
87
    }
88
89 64
    protected function getPhpExtends(): string
90
    {
91 64
        $extends = $this->getExtends();
92
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
108 116
        return $this;
109
    }
110
111
    /**
112
     * @param string[]|PhpClass[] $interfaces
113
     * @return bool
114
     */
115 116
    public static function interfacesAreValid(array $interfaces = []): bool
116
    {
117 116
        $valid = true;
118 116
        foreach ($interfaces as $interface) {
119 28
            $valid &= self::interfaceIsValid($interface);
120
        }
121
122 116
        return (bool) $valid;
123
    }
124
125
    /**
126
     * @param string|PhpClass $interface
127
     * @return bool
128
     */
129 28
    public static function interfaceIsValid($interface): bool
130
    {
131 28
        return self::stringIsValid($interface) || $interface instanceof PhpClass;
132
    }
133
134
    /**
135
     *
136
     * @return string[]|PhpClass[]
137
     */
138 66
    public function getInterfaces(): array
139
    {
140 66
        return $this->interfaces;
141
    }
142
143
    /**
144
     * @return string
145
     */
146 64
    protected function getPhpInterfaces(): string
147
    {
148 64
        $interfaces = [];
149 64
        foreach ($this->getInterfaces() as $interface) {
150 24
            $interfaces[] = $this->getPhpInterface($interface);
151
        }
152
153 64
        return empty($interfaces) ? '' : sprintf(' %s%s', static::PHP_IMPLEMENTS_KEYWORD, implode(',', $interfaces));
154
    }
155
156
    /**
157
     * @param string|PhpClass $interface
158
     * @return string
159
     */
160 24
    protected function getPhpInterface($interface): string
161
    {
162 24
        return sprintf(' %s', is_string($interface) ? $interface : $interface->getName());
163
    }
164
165 64
    public function getPhpDeclaration(): string
166
    {
167 64
        return trim(sprintf('%s%s %s%s%s', $this->getPhpAbstract(), static::PHP_DECLARATION, $this->getPhpName(), $this->getPhpExtends(), $this->getPhpInterfaces()));
168
    }
169
170
    /**
171
     * defines authorized children element types
172
     * @return string[]
173
     */
174 32
    public function getChildrenTypes(): array
175
    {
176
        return [
177 32
            'string',
178
            PhpAnnotationBlock::class,
179
            PhpMethod::class,
180
            PhpConstant::class,
181
            PhpProperty::class,
182
        ];
183
    }
184
185
    /**
186
     * Allows to indicate that children are contained by brackets,
187
     * in the case the method returns true, getBracketBeforeChildren
188
     * is called instead of getLineBeforeChildren and getBracketAfterChildren
189
     * is called instead of getLineAfterChildren, but be aware that these methods
190
     * call the two others
191
     * @return bool
192
     */
193 32
    public function useBracketsForChildren(): bool
194
    {
195 32
        return true;
196
    }
197
}
198