PropertyTrait::__set()   A
last analyzed

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.025

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 17
ccs 9
cts 10
cp 0.9
rs 9.6111
cc 5
nc 6
nop 2
crap 5.025
1
<?php
2
3
//----------------------------------------------------------------------
4
//
5
//  Copyright (C) 2017-2020 Artem Rodygin
6
//
7
//  You should have received a copy of the MIT License along with
8
//  this file. If not, see <http://opensource.org/licenses/MIT>.
9
//
10
//----------------------------------------------------------------------
11
12
namespace Webinarium;
13
14
/**
15
 * Trait to emulate automatic properties.
16
 */
17
trait PropertyTrait
18
{
19
    /** @var array Cached annotations. */
20
    private static array $_annotations;
21
22
    /**
23
     * {@inheritdoc}
24
     */
25
    public function __isset($name)
26
    {
27
        if (!isset(self::$_annotations)) {
28
            $this->parseAnnotations();
29
        }
30
31
        return self::$_annotations[$name] ?? null;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 7
    public function __get($name)
38
    {
39 7
        if (!isset(self::$_annotations)) {
40
            $this->parseAnnotations();
41
        }
42
43 7
        $access = self::$_annotations[$name] ?? null;
44
45 7
        if ($access !== 'property' && $access !== 'property-read') {
46 2
            throw new \InvalidArgumentException('Unknown read property: ' . $name);
47
        }
48
49 5
        $getters = $this->getters();
50
51 5
        return isset($getters[$name])
52 3
            ? $getters[$name]()
53 5
            : $this->{$name} ?? null;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 8
    public function __set($name, $value)
60
    {
61 8
        if (!isset(self::$_annotations)) {
62
            $this->parseAnnotations();
63
        }
64
65 8
        $access = self::$_annotations[$name] ?? null;
66
67 8
        if ($access !== 'property' && $access !== 'property-write') {
68 3
            throw new \InvalidArgumentException('Unknown write property: ' . $name);
69
        }
70
71 5
        $setters = $this->setters();
72
73 5
        isset($setters[$name])
74 3
            ? $setters[$name]($value)
75 2
            : $this->{$name} = $value;
76 5
    }
77
78
    /**
79
     * Returns array of custom getters.
80
     *
81
     * @return array
82
     */
83 1
    protected function getters(): array
84
    {
85 1
        return [];
86
    }
87
88
    /**
89
     * Returns array of custom setters.
90
     *
91
     * @return array
92
     */
93 1
    protected function setters(): array
94
    {
95 1
        return [];
96
    }
97
98
    /**
99
     * Parses annotations of the class.
100
     */
101 1
    private function parseAnnotations()
102
    {
103 1
        self::$_annotations = [];
104
105 1
        $class  = new \ReflectionClass(self::class);
106 1
        $phpdoc = explode("\n", $class->getDocComment());
107
108 1
        foreach ($phpdoc as $line) {
109
            // pattern = "@property[-read|-write] type[|type] $identifier"
110 1
            if (preg_match('/@(property|property\-read|property\-write)\W+[A-Za-z][_A-Za-z\d]*(\|[A-Za-z][_A-Za-z\d]*)*\W+\$([A-Za-z][_A-Za-z\d]*)/', $line, $matches)) {
111 1
                self::$_annotations[$matches[3]] = $matches[1];
112
            }
113
        }
114 1
    }
115
}
116