AccessorTrait::_initProps()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
c 0
b 0
f 0
nc 1
1
<?php
2
3
namespace Saxulum\Accessor;
4
5
use Saxulum\Accessor\Accessors\Get;
6
use Saxulum\Accessor\Accessors\Set;
7
8
trait AccessorTrait
9
{
10
    /**
11
     * @var bool
12
     */
13
    private $__initProps = false;
14
15
    /**
16
     * @var Prop[]
17
     */
18
    private $__props = array();
19
20
    /**
21
     * @var string
22
     */
23
    private $__namespace;
24
25
    /**
26
     * can't be final, cause doctrine proxy
27
     *
28
     * @param  string     $name
29
     * @param  array      $arguments
30
     * @return mixed
31
     * @throws \Exception
32
     */
33
    public function __call($name, array $arguments = array())
34
    {
35
        return $this->__handleCall($name, $arguments);
36
    }
37
38
    /**
39
     * needed by symfony/property-access
40
     * can't be final, cause doctrine proxy
41
     *
42
     * @param  string $name
43
     * @return mixed
44
     */
45
    public function __get($name)
46
    {
47
        return $this->__handleGet($name);
48
    }
49
50
    /**
51
     * needed by symfony/property-access
52
     * can't be final, cause doctrine proxy
53
     *
54
     * @param  string $name
55
     * @param  mixed  $value
56
     * @return mixed
57
     */
58
    public function __set($name, $value)
59
    {
60
        return $this->__handleSet($name, $value);
61
    }
62
63
    /**
64
     * @param  string     $name
65
     * @param  array      $arguments
66
     * @return mixed
67
     * @throws \Exception
68
     */
69
    private function __handleCall($name, array $arguments)
70
    {
71
        if (false === $this->__initProps) {
72
            $this->__initProps = true;
73
            $this->_initProps();
74
        }
75
76
        // needed by twig, cause it tries to call a method with the property name
77
        if (property_exists($this, $name)) {
78
            $method = Get::PREFIX . ucfirst($name);
79
80
            return $this->$method();
81
        }
82
83
        foreach (AccessorRegistry::getAccessors() as $prefix => $accessor) {
84
            if (strpos($name, $prefix) === 0) {
85
                $property = lcfirst(substr($name, strlen($prefix)));
86
                if (isset($this->__props[$property])) {
87
                    $prop = $this->__props[$property];
88
                    if ($prop->hasMethod($prefix)) {
89
                        return $accessor->callback(
90
                            new CallbackBag($prop, $this, $this->$property, $arguments)
91
                        );
92
                    }
93
                }
94
            }
95
        }
96
97
        throw new \Exception('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
98
    }
99
100
    /**
101
     * @param  string $name
102
     * @return mixed
103
     */
104
    private function __handleGet($name)
105
    {
106
        $method = Get::PREFIX . ucfirst($name);
107
108
        return $this->$method();
109
    }
110
111
    /**
112
     * @param  string $name
113
     * @param  mixed  $value
114
     * @return mixed
115
     */
116
    private function __handleSet($name, $value)
117
    {
118
        $method = Set::PREFIX . ucfirst($name);
119
120
        return $this->$method($value);
121
    }
122
123
    /**
124
     * @param  Prop       $property
125
     * @return static
126
     * @throws \Exception
127
     */
128
    final protected function _prop(Prop $property)
129
    {
130
        $name = $property->getName();
131
132
        if (!property_exists($this, $name)) {
133
            throw new \InvalidArgumentException("Property does not exists");
134
        }
135
136
        if (isset($this->__props[$name])) {
137
            throw new \Exception("Override Property is not allowed, to enhance stability!");
138
        }
139
140
        $this->__props[$name] = $property;
141
142
        return $this;
143
    }
144
145
    /**
146
     * @return string
147
     */
148
    final public function _generatePhpDoc()
149
    {
150
        if (false === $this->__initProps) {
151
            $this->__initProps = true;
152
            $this->_initProps();
153
        }
154
155
        $phpDoc = '';
156
        foreach ($this->__props as $prop) {
157
            $phpDoc .= $prop->generatePhpDoc($this->__getNamespace());
158
        }
159
160
        return $phpDoc;
161
    }
162
163
    /**
164
     * @return string
165
     */
166
    private function __getNamespace()
167
    {
168
        if (null === $this->__namespace) {
169
            $namespace = __CLASS__;
170
            $pos = strrpos($namespace, '\\');
171
            $this->__namespace = (false === $pos || 0 === $pos) ? '' : substr($namespace, 0, $pos);
172
        }
173
174
        return $this->__namespace;
175
    }
176
177
    abstract protected function _initProps();
178
}
179