Properties   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 0
cbo 3
dl 0
loc 99
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __get() 0 13 3
A __set() 0 19 4
A propertyAccessException() 0 6 1
A __isset() 0 6 1
A __unset() 0 15 3
1
<?php
2
/**
3
 * This file is part of Properties package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Serafim\Properties;
11
12
use Railt\Io\Exception\ExternalFileException;
13
use Railt\Io\File;
14
use Serafim\Properties\Exception\AccessDeniedException;
15
use Serafim\Properties\Exception\NotReadableException;
16
use Serafim\Properties\Exception\NotWritableException;
17
18
/**
19
 * Trait Properties
20
 */
21
trait Properties
22
{
23
    /**
24
     * @param mixed $name
25
     * @return mixed
26
     * @throws \Psr\SimpleCache\InvalidArgumentException
27
     * @throws \Railt\Io\Exception\ExternalFileException
28
     * @throws \Railt\Io\Exception\NotReadableException
29
     */
30
    public function __get($name)
31
    {
32
        \assert(\is_scalar($name));
33
34
        $attribute = Bootstrap::getInstance()->getAttribute(static::class, (string)$name);
35
36
        if ($attribute && $attribute->isReadable()) {
37
            return $attribute->getValueFrom($this);
38
        }
39
40
        $error = \sprintf('Property %s::$%s not readable', __CLASS__, $name);
41
        throw $this->propertyAccessException(NotReadableException::class, $error);
42
    }
43
44
    /**
45
     * @param mixed $name
46
     * @param mixed $value
47
     * @return mixed
48
     * @throws AccessDeniedException
49
     * @throws \Psr\SimpleCache\InvalidArgumentException
50
     * @throws \Railt\Io\Exception\NotReadableException
51
     */
52
    public function __set($name, $value)
53
    {
54
        \assert(\is_scalar($name));
55
56
        $attribute = Bootstrap::getInstance()->getAttribute(static::class, (string)$name);
57
58
        if ($attribute && $attribute->isWritable()) {
59
            if (! $attribute->match($value)) {
60
                $error = 'New value of %s::$%s is not compatible with type hint definition';
61
                $error = \sprintf($error, __CLASS__, $name);
62
                throw $this->propertyAccessException(NotWritableException::class, $error);
63
            }
64
65
            return $attribute->setValueTo($this, $value);
66
        }
67
68
        $error = \sprintf('Property %s::$%s not writable', __CLASS__, $name);
69
        throw $this->propertyAccessException(NotWritableException::class, $error);
70
    }
71
72
    /**
73
     * @param string|ExternalFileException $exception
74
     * @param string $message
75
     * @return AccessDeniedException
76
     * @throws \Railt\Io\Exception\NotReadableException
77
     */
78
    private function propertyAccessException(string $exception, string $message): AccessDeniedException
79
    {
80
        [$file, $line] = Bootstrap::getInstance()->getInvocationPosition();
0 ignored issues
show
Bug introduced by
The variable $file does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $line does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
81
82
        return (new $exception($message))->throwsIn(File::fromPathname($file), $line, 0);
83
    }
84
85
    /**
86
     * @param mixed $name
87
     * @return bool
88
     * @throws \Psr\SimpleCache\InvalidArgumentException
89
     */
90
    public function __isset($name)
91
    {
92
        \assert(\is_scalar($name));
93
94
        return Bootstrap::getInstance()->hasAttribute(static::class, $name);
95
    }
96
97
    /**
98
     * @param mixed $name
99
     * @return bool
100
     * @throws AccessDeniedException
101
     * @throws \Psr\SimpleCache\InvalidArgumentException
102
     * @throws \Railt\Io\Exception\NotReadableException
103
     */
104
    public function __unset($name)
105
    {
106
        \assert(\is_scalar($name));
107
108
        $attribute = Bootstrap::getInstance()->getAttribute(static::class, (string)$name);
109
110
        if ($attribute && $attribute->isWritable()) {
111
            unset($this->$name);
112
113
            return true;
114
        }
115
116
        $error = \sprintf('Can not remove not writable property %s::$%s', __CLASS__, $name);
117
        throw $this->propertyAccessException(NotWritableException::class, $error);
118
    }
119
}
120