Completed
Push — master ( 1bc299...b12741 )
by Kirill
03:33
created

Properties::setPropertyValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
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\File;
13
use Serafim\Properties\Attribute\AttributeInterface;
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 $this->$name;
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 $this->$name = $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 $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
     */
89
    public function __isset($name): bool
90
    {
91
        \assert(\is_scalar($name));
92
93
        return \property_exists($this, $name);
94
    }
95
96
    /**
97
     * @param mixed $name
98
     * @throws NotWritableException
99
     * @throws \Psr\SimpleCache\InvalidArgumentException
100
     */
101
    public function __unset($name)
102
    {
103
        \assert(\is_scalar($name));
104
105
        $this->__set($name, null);
106
    }
107
}
108