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.
Completed
Push — master ( 0fb5fa...110116 )
by SignpostMarv
02:05
created

AbstractDaftObject::CheckPublicScope()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 9
cts 9
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 2
crap 3
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 ReflectionClass;
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
    * Index of checked types.
34
    *
35
    * @see self::CheckTypeDefinesOwnIdProperties()
36
    *
37
    * @var bool[]
38
    */
39
    private static $checkedTypes = [];
40
41
    /**
42
    * Does some sanity checking.
43
    *
44
    * @see DefinesOwnIdPropertiesInterface
45
    * @see self::CheckTypeDefinesOwnIdProperties()
46
    *
47
    * @throws AlreadyIncorrectlyImplementedTypeException if static::class was previously determined to be incorrectly implemented
48
    */
49 44
    public function __construct()
50
    {
51
        if (
52 44
            ($this instanceof DefinesOwnIdPropertiesInterface) &&
53 32
            false === self::CheckTypeDefinesOwnIdProperties($this)
54
        ) {
55 1
            throw new AlreadyIncorrectlyImplementedTypeException(
56 1
                get_class($this) // phpunit coverage does not pick up static::class here
57
            );
58
        }
59 41
    }
60
61
    /**
62
    * {@inheritdoc}
63
    */
64 28 View Code Duplication
    public function __get(string $property)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
65
    {
66 28
        static $scopes = [];
67 28
        $expectedMethod = 'Get' . ucfirst($property);
68 28
        if (true !== method_exists($this, $expectedMethod)) {
69 1
            throw new UndefinedPropertyException(static::class, $property);
70 27
        } elseif (false === $this->CheckPublicScope($property, true)) {
71 1
            throw new NotPublicGetterPropertyException(
72 1
                static::class,
73 1
                $property
74
            );
75
        }
76
77 26
        return $this->$expectedMethod();
78
    }
79
80
    /**
81
    * {@inheritdoc}
82
    */
83 15 View Code Duplication
    public function __set(string $property, $v)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
84
    {
85 15
        static $scopes = [];
86 15
        $expectedMethod = 'Set' . ucfirst($property);
87
        if (
88 15
            true !== method_exists($this, $expectedMethod)
89
        ) {
90 1
            throw new PropertyNotWriteableException(static::class, $property);
91 14
        } elseif (false === $this->CheckPublicScope($property, false)) {
92 1
            throw new NotPublicSetterPropertyException(
93 1
                static::class,
94 1
                $property
95
            );
96
        }
97
98 13
        return $this->$expectedMethod($v);
99
    }
100
101
    /**
102
    * {@inheritdoc}
103
    *
104
    * @see static::NudgePropertyValue()
105
    */
106 8
    public function __unset(string $property) : void
107
    {
108 8
        $this->NudgePropertyValue($property, null);
109 6
    }
110
111
    /**
112
    * List of properties that can be defined on an implementation.
113
    *
114
    * @return string[]
115
    */
116 6
    final public static function DaftObjectProperties() : array
117
    {
118 6
        return static::PROPERTIES;
119
    }
120
121
    /**
122
    * {@inheritdoc}
123
    */
124 9
    final public static function DaftObjectNullableProperties() : array
125
    {
126 9
        return static::NULLABLE_PROPERTIES;
127
    }
128
129
    /**
130
    * Nudge the state of a given property, marking it as dirty.
131
    *
132
    * @param string $property property being nudged
133
    * @param mixed $value value to nudge property with
134
    *
135
    * @throws UndefinedPropertyException if $property is not in static::DaftObjectProperties()
136
    * @throws PropertyNotNullableException if $property is not in static::DaftObjectNullableProperties()
137
    * @throws PropertyNotRewriteableException if class is write-once read-many and $property was already changed
138
    */
139
    abstract protected function NudgePropertyValue(
140
        string $property,
141
        $value
142
    ) : void;
143
144
    /**
145
    * Checks if a type correctly defines it's own id.
146
    *
147
    * @param DaftObject $object
148
    *
149
    * @throws ClassDoesNotImplementClassException if $object is not an implementation of DefinesOwnIdPropertiesInterface
150
    * @throws ClassMethodReturnHasZeroArrayCountException if $object::DaftObjectIdProperties() does not contain at least one property
151
    * @throws ClassMethodReturnIsNotArrayOfStringsException if $object::DaftObjectIdProperties() is not string[]
152
    * @throws UndefinedPropertyException if an id property is not in $object::DaftObjectIdProperties()
153
    */
154 33
    final protected static function CheckTypeDefinesOwnIdProperties(
155
        DaftObject $object
156
    ) : bool {
157 33
        static $checkedTypes = [];
158
159 33
        if (false === isset($checkedTypes[get_class($object)])) {
160 8
            $checkedTypes[get_class($object)] = false;
161
162 8
            if (false === ($object instanceof DefinesOwnIdPropertiesInterface)) {
163 1
                throw new ClassDoesNotImplementClassException(
164 1
                    get_class($object),
165 1
                    DefinesOwnIdPropertiesInterface::class
166
                );
167
            }
168
169
            /**
170
            * @var DefinesOwnIdPropertiesInterface $object
171
            */
172 7
            $object = $object;
173
174 7
            $properties = $object::DaftObjectIdProperties();
175
176 7
            if (count($properties) < 1) {
177 1
                throw new ClassMethodReturnHasZeroArrayCountException(
178 1
                    get_class($object),
179 1
                    'DaftObjectIdProperties'
180
                );
181
            }
182
183 6
            foreach ($properties as $property) {
184 6
                if (false === is_string($property)) {
185 1
                    throw new ClassMethodReturnIsNotArrayOfStringsException(
186 1
                        get_class($object),
187 1
                        'DaftObjectIdProperties'
188
                    );
189
                } elseif (
190 5
                    false === in_array(
191 5
                        $property,
192 5
                        $object::DaftObjectProperties(),
193 5
                        true
194
                    )
195
                ) {
196
                    throw new UndefinedPropertyException(
197
                        get_class($object),
198
                        $property
199
                    );
200
                }
201
            }
202
203 5
            $checkedTypes[get_class($object)] = true;
204
        }
205
206 30
        return $checkedTypes[get_class($object)];
207
    }
208
209 35
    private function CheckPublicScope(string $property, bool $getter) : bool
210
    {
211 35
        static $scopes = [];
212 35
        $expectedMethod = ($getter ? 'Get' : 'Set') . ucwords($property);
213 35
        if (false === isset($scopes[$expectedMethod])) {
214 9
            $scopes[$expectedMethod] = (
215
                (
216 9
                    new ReflectionClass(static::class)
217 9
                )->getMethod($expectedMethod)
218 9
            )->isPublic();
219
        }
220
221 35
        return $scopes[$expectedMethod];
222
    }
223
}
224