AbstractProperty::getPath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace MisterIcy\ExcelWriter\Properties;
5
6
use MisterIcy\ExcelWriter\Exceptions\PropertyException;
7
use MisterIcy\ExcelWriter\Properties\Traits\CallableTrait;
8
use MisterIcy\ExcelWriter\Properties\Traits\FormatTrait;
9
use MisterIcy\ExcelWriter\Properties\Traits\FormulaTrait;
10
use MisterIcy\ExcelWriter\Properties\Traits\HeaderTrait;
11
use MisterIcy\ExcelWriter\Properties\Traits\NullableTrait;
12
use Symfony\Component\PropertyAccess\PropertyAccess;
13
use Symfony\Component\PropertyAccess\PropertyAccessor;
14
use Error;
15
16
/**
17
 * Class AbstractProperty
18
 * @package MisterIcy\ExcelWriter\Properties
19
 */
20
abstract class AbstractProperty implements PropertyInterface
21
{
22
    use FormulaTrait, FormatTrait, HeaderTrait, CallableTrait, NullableTrait;
23
24
    /**
25
     * A static property accessor to read data from arrays/objects
26
     *
27
     * @var PropertyAccessor
28
     */
29
    protected static $accessor;
30
31
    /**
32
     * Property Path
33
     *
34
     * @var string
35
     */
36
    protected $path;
37
38
    /**
39
     * @return string|null
40
     */
41
    public function getPath()
42
    {
43
        return $this->path;
44
    }
45
46
    /**
47
     * @param string $path
48
     * @return self
49
     */
50
    public function setPath(string $path): self
51
    {
52
        $this->path = $path;
53
        return $this;
54
    }
55
56
    /**
57
     * Checks if we passed a callable in the property, thus
58
     * making it callable - a custom function must be executed
59
     * before rendering the final value
60
     *
61
     * @return bool
62
     */
63
    public function isCallable() : bool
64
    {
65
        return (!is_null($this->callable));
66
    }
67
68
    /**
69
     * Renders a property's value
70
     *
71
     * @param object $object
72
     * @return mixed
73
     * @throws PropertyException
74
     */
75
    public function renderProperty(object $object)
76
    {
77
78
        if ($this->isCallable()) {
79
            return $this->handleCallable($this->getValue($object));
80
        }
81
82
        if ($this->isFormula) {
83
            return strval($this->getFormula());
84
        }
85
86
        return $this->getValue($object);
87
    }
88
89
    /**
90
     * Gets the Property Accessor, in a singleton way
91
     *
92
     * @return PropertyAccessor
93
     */
94
    final protected static function getAccessor()
95
    {
96
        if (null === static::$accessor) {
97
            static::$accessor = PropertyAccess::createPropertyAccessor();
98
        }
99
        return static::$accessor;
100
    }
101
102
    /**
103
     * Checks if a property is valid and readable
104
     *
105
     * @param object $object
106
     * @return bool
107
     * @throws Error
108
     */
109
    public function checkProperty(object $object): bool
110
    {
111
112
113
        if (static::getAccessor()->isReadable($object, $this->getPath())) {
114
            return true;
115
        }
116
        if (!$this->isStrict()) {
117
            return false;
118
        }
119
        $objectIdentifier = method_exists($object, '__toString') ?
120
            call_user_func_array([$object, '__toString'], []) : get_class($object);
121
        throw new Error(
122
            sprintf("I couldn't read property %s of %s", $this->getPath(), $objectIdentifier)
123
        );
124
    }
125
126
    /**
127
     * Gets the value of a specific object's property
128
     *
129
     * @param object $object
130
     * @return mixed
131
     * @throws PropertyException
132
     */
133
    protected function getValue(object $object)
134
    {
135
        $check = $this->checkProperty($object);
136
        if ($check) {
137
            return static::getAccessor()->getValue($object, $this->getPath());
138
        }
139
        return null;
140
    }
141
}
142