GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 59ea50...e48355 )
by SignpostMarv
02:01
created

AbstractDaftObject   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Test Coverage

Coverage 95.65%

Importance

Changes 0
Metric Value
wmc 23
dl 0
loc 204
ccs 66
cts 69
cp 0.9565
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A DaftObjectProperties() 0 3 1
B CheckTypeDefinesOwnIdProperties() 0 40 6
A __set() 0 3 1
A __unset() 0 3 1
A __get() 0 3 1
A __construct() 0 6 2
A DaftObjectNullableProperties() 0 3 1
C DoGetSet() 0 42 8
A CheckPublicScope() 0 10 2
1
<?php
2
/**
3
* Base daft objects.
4
*
5
* @author SignpostMarv
6
*/
7
declare(strict_types=1);
8
9
namespace SignpostMarv\DaftObject;
10
11
use ReflectionMethod;
12
13
/**
14
* Base daft object.
15
*/
16
abstract class AbstractDaftObject implements DaftObject
17
{
18
    /**
19
    * List of properties that can be defined on an implementation.
20
    *
21
    * @var string[]
22
    */
23
    const PROPERTIES = [];
24
25
    /**
26
    * List of nullable properties that can be defined on an implementation.
27
    *
28
    * @var string[]
29
    */
30
    const NULLABLE_PROPERTIES = [];
31
32
    /**
33
    * Does some sanity checking.
34
    *
35
    * @see DefinesOwnIdPropertiesInterface
36
    * @see self::CheckTypeDefinesOwnIdProperties()
37
    */
38 46
    public function __construct()
39
    {
40
        if (
41 46
            ($this instanceof DefinesOwnIdPropertiesInterface)
42
        ) {
43 33
            self::CheckTypeDefinesOwnIdProperties($this);
44
        }
45 44
    }
46
47
    /**
48
    * {@inheritdoc}
49
    */
50 29
    public function __get(string $property)
51
    {
52 29
        return $this->DoGetSet($property, true);
53
    }
54
55
    /**
56
    * {@inheritdoc}
57
    */
58 17
    public function __set(string $property, $v)
59
    {
60 17
        return $this->DoGetSet($property, false, $v);
61
    }
62
63
    /**
64
    * {@inheritdoc}
65
    *
66
    * @see static::NudgePropertyValue()
67
    */
68 8
    public function __unset(string $property) : void
69
    {
70 8
        $this->NudgePropertyValue($property, null);
71 6
    }
72
73
    /**
74
    * List of properties that can be defined on an implementation.
75
    *
76
    * @return string[]
77
    */
78 43
    final public static function DaftObjectProperties() : array
79
    {
80 43
        return static::PROPERTIES;
81
    }
82
83
    /**
84
    * {@inheritdoc}
85
    */
86 9
    final public static function DaftObjectNullableProperties() : array
87
    {
88 9
        return static::NULLABLE_PROPERTIES;
89
    }
90
91
    /**
92
    * Nudge the state of a given property, marking it as dirty.
93
    *
94
    * @param string $property property being nudged
95
    * @param mixed $value value to nudge property with
96
    *
97
    * @throws UndefinedPropertyException if $property is not in static::DaftObjectProperties()
98
    * @throws PropertyNotNullableException if $property is not in static::DaftObjectNullableProperties()
99
    * @throws PropertyNotRewriteableException if class is write-once read-many and $property was already changed
100
    */
101
    abstract protected function NudgePropertyValue(
102
        string $property,
103
        $value
104
    ) : void;
105
106
    /**
107
    * Checks if a type correctly defines it's own id.
108
    *
109
    * @param DaftObject $object
110
    *
111
    * @throws ClassDoesNotImplementClassException if $object is not an implementation of DefinesOwnIdPropertiesInterface
112
    * @throws ClassMethodReturnHasZeroArrayCountException if $object::DaftObjectIdProperties() does not contain at least one property
113
    * @throws ClassMethodReturnIsNotArrayOfStringsException if $object::DaftObjectIdProperties() is not string[]
114
    * @throws UndefinedPropertyException if an id property is not in $object::DaftObjectIdProperties()
115
    */
116 34
    final protected static function CheckTypeDefinesOwnIdProperties(
117
        DaftObject $object
118
    ) : void {
119 34
        if (false === ($object instanceof DefinesOwnIdPropertiesInterface)) {
120 1
            throw new ClassDoesNotImplementClassException(
121 1
                get_class($object),
122 1
                DefinesOwnIdPropertiesInterface::class
123
            );
124
        }
125
126
        /**
127
        * @var DefinesOwnIdPropertiesInterface $object
128
        */
129 33
        $object = $object;
130
131 33
        $properties = $object::DaftObjectIdProperties();
132
133 33
        if (count($properties) < 1) {
134 1
            throw new ClassMethodReturnHasZeroArrayCountException(
135 1
                get_class($object),
136 1
                'DaftObjectIdProperties'
137
            );
138
        }
139
140 32
        foreach ($properties as $property) {
141 32
            if (false === is_string($property)) {
142 1
                throw new ClassMethodReturnIsNotArrayOfStringsException(
143 1
                    get_class($object),
144 1
                    'DaftObjectIdProperties'
145
                );
146
            } elseif (
147 31
                false === in_array(
148 31
                    $property,
149 31
                    $object::DaftObjectProperties(),
150 31
                    true
151
                )
152
            ) {
153
                throw new UndefinedPropertyException(
154
                    get_class($object),
155
                    $property
156
                );
157
            }
158
        }
159 31
    }
160
161
    /**
162
    * @param mixed $v
163
    *
164
    * @return mixed
165
    */
166 40
    private function DoGetSet(
167
        string $property,
168
        bool $getNotSet,
169
        $v = null
170
    ) {
171 40
        $expectedMethod = ($getNotSet ? 'Get' : 'Set') . ucfirst($property);
172
173
        if (
174
            false === (
175 40
                'id' === $property &&
176 9
                is_a(
177 9
                    static::class,
178 9
                    DefinesOwnIdPropertiesInterface::class,
179 40
                    true
180
                )
181
            ) &&
182 40
            false === in_array($property, static::DaftObjectProperties(), true)
183
        ) {
184 3
            throw new UndefinedPropertyException(static::class, $property);
185
        }
186
187 37
        $notExists = PropertyNotWriteableException::class;
188 37
        $notPublic = NotPublicSetterPropertyException::class;
189
190 37
        if ($getNotSet) {
191 28
            $notExists = PropertyNotReadableException::class;
192 28
            $notPublic = NotPublicGetterPropertyException::class;
193
        }
194
195 37
        if (false === method_exists($this, $expectedMethod)) {
196 2
            throw new $notExists(
197 2
                static::class,
198 2
                $property
199
            );
200 35
        } elseif (false === $this->CheckPublicScope($expectedMethod)) {
201 2
            throw new $notPublic(
202 2
                static::class,
203 2
                $property
204
            );
205
        }
206
207 33
        return $this->$expectedMethod($v);
208
    }
209
210 35
    private function CheckPublicScope(string $expectedMethod) : bool
211
    {
212 35
        static $scopes = [];
213 35
        if (false === isset($scopes[$expectedMethod])) {
214 8
            $scopes[$expectedMethod] = (
215 8
                new ReflectionMethod(static::class, $expectedMethod)
216 8
            )->isPublic();
217
        }
218
219 35
        return $scopes[$expectedMethod];
220
    }
221
}
222