1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Spiral Framework. Cycle ProxyFactory |
5
|
|
|
* |
6
|
|
|
* @license MIT |
7
|
|
|
* @author Valentin V (Vvval) |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
declare(strict_types=1); |
11
|
|
|
|
12
|
|
|
namespace Cycle\ORM\Promise\Declaration; |
13
|
|
|
|
14
|
|
|
use PhpParser\Node\Stmt\ClassMethod; |
15
|
|
|
use ReflectionProperty; |
16
|
|
|
use SplObjectStorage; |
17
|
|
|
|
18
|
|
|
use function Cycle\ORM\Promise\phpVersionBetween; |
19
|
|
|
|
20
|
|
|
final class Structure |
21
|
|
|
{ |
22
|
|
|
/** @var string[] */ |
23
|
|
|
public $constants = []; |
24
|
|
|
|
25
|
|
|
/** @var ClassMethod[] */ |
26
|
|
|
public $methods = []; |
27
|
|
|
|
28
|
|
|
/** @var bool */ |
29
|
|
|
public $hasClone; |
30
|
|
|
|
31
|
|
|
/** @var SplObjectStorage */ |
32
|
|
|
private $properties; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Structure constructor. |
36
|
|
|
*/ |
37
|
|
|
protected function __construct() |
38
|
|
|
{ |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @param array $constants |
43
|
|
|
* @param SplObjectStorage $properties |
44
|
|
|
* @param bool $hasClone |
45
|
|
|
* @param ClassMethod ...$methods |
46
|
|
|
* @return Structure |
47
|
|
|
*/ |
48
|
|
|
public static function create( |
49
|
|
|
array $constants, |
50
|
|
|
SplObjectStorage $properties, |
51
|
|
|
bool $hasClone, |
52
|
|
|
ClassMethod ...$methods |
53
|
|
|
): Structure { |
54
|
|
|
$self = new self(); |
55
|
|
|
$self->constants = $constants; |
56
|
|
|
$self->properties = $properties; |
57
|
|
|
$self->methods = $methods; |
58
|
|
|
$self->hasClone = $hasClone; |
59
|
|
|
|
60
|
|
|
return $self; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* A list of properties to be unset due to they are initialized (have a default value). |
65
|
|
|
* @return string[] |
66
|
|
|
*/ |
67
|
|
View Code Duplication |
public function toBeUnsetProperties(): array |
|
|
|
|
68
|
|
|
{ |
69
|
|
|
$names = []; |
70
|
|
|
/** @var ReflectionProperty $property */ |
71
|
|
|
foreach ($this->properties as $property) { |
72
|
|
|
if ($this->doesDefaultMatter($property) && $property->isPublic()) { |
73
|
|
|
$names[] = $property->getName(); |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
return $names; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* A list of public properties. Any access to them be proxied. |
82
|
|
|
* @return string[] |
83
|
|
|
*/ |
84
|
|
View Code Duplication |
public function publicProperties(): array |
|
|
|
|
85
|
|
|
{ |
86
|
|
|
$names = []; |
87
|
|
|
/** @var ReflectionProperty $property */ |
88
|
|
|
foreach ($this->properties as $property) { |
89
|
|
|
if ($property->isPublic()) { |
90
|
|
|
$names[] = $property->getName(); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
return $names; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* @return string[] |
99
|
|
|
*/ |
100
|
|
|
public function properties(): array |
101
|
|
|
{ |
102
|
|
|
$names = []; |
103
|
|
|
/** @var ReflectionProperty $property */ |
104
|
|
|
foreach ($this->properties as $property) { |
105
|
|
|
$names[] = $property->getName(); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
return $names; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @return array |
113
|
|
|
*/ |
114
|
|
|
public function methodNames(): array |
115
|
|
|
{ |
116
|
|
|
$names = []; |
117
|
|
|
foreach ($this->methods as $method) { |
118
|
|
|
$names[] = $method->name->name; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $names; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Since php7.4.1 the behaviour changed as it was before php7.4.0. All properties should be unset. |
126
|
|
|
* @see https://github.com/php/php-src/pull/4974 |
127
|
|
|
* @param ReflectionProperty $property |
128
|
|
|
* @return bool |
129
|
|
|
*/ |
130
|
|
|
private function doesDefaultMatter(ReflectionProperty $property): bool |
131
|
|
|
{ |
132
|
|
|
return !phpVersionBetween('7.4.0', '7.4.1') || $this->properties[$property] === true; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.