Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * Zend Framework (http://framework.zend.com/)
|
Chris@0
|
4 *
|
Chris@0
|
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
|
Chris@0
|
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
Chris@0
|
7 * @license http://framework.zend.com/license/new-bsd New BSD License
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@0
|
10 namespace Zend\Stdlib;
|
Chris@0
|
11
|
Chris@0
|
12 use Traversable;
|
Chris@0
|
13
|
Chris@0
|
14 abstract class AbstractOptions implements ParameterObjectInterface
|
Chris@0
|
15 {
|
Chris@0
|
16 /**
|
Chris@0
|
17 * We use the __ prefix to avoid collisions with properties in
|
Chris@0
|
18 * user-implementations.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @var bool
|
Chris@0
|
21 */
|
Chris@0
|
22 protected $__strictMode__ = true;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * Constructor
|
Chris@0
|
26 *
|
Chris@0
|
27 * @param array|Traversable|null $options
|
Chris@0
|
28 */
|
Chris@0
|
29 public function __construct($options = null)
|
Chris@0
|
30 {
|
Chris@0
|
31 if (null !== $options) {
|
Chris@0
|
32 $this->setFromArray($options);
|
Chris@0
|
33 }
|
Chris@0
|
34 }
|
Chris@0
|
35
|
Chris@0
|
36 /**
|
Chris@0
|
37 * Set one or more configuration properties
|
Chris@0
|
38 *
|
Chris@0
|
39 * @param array|Traversable|AbstractOptions $options
|
Chris@0
|
40 * @throws Exception\InvalidArgumentException
|
Chris@0
|
41 * @return AbstractOptions Provides fluent interface
|
Chris@0
|
42 */
|
Chris@0
|
43 public function setFromArray($options)
|
Chris@0
|
44 {
|
Chris@0
|
45 if ($options instanceof self) {
|
Chris@0
|
46 $options = $options->toArray();
|
Chris@0
|
47 }
|
Chris@0
|
48
|
Chris@0
|
49 if (!is_array($options) && !$options instanceof Traversable) {
|
Chris@0
|
50 throw new Exception\InvalidArgumentException(
|
Chris@0
|
51 sprintf(
|
Chris@0
|
52 'Parameter provided to %s must be an %s, %s or %s',
|
Chris@0
|
53 __METHOD__,
|
Chris@0
|
54 'array',
|
Chris@0
|
55 'Traversable',
|
Chris@0
|
56 'Zend\Stdlib\AbstractOptions'
|
Chris@0
|
57 )
|
Chris@0
|
58 );
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 foreach ($options as $key => $value) {
|
Chris@0
|
62 $this->__set($key, $value);
|
Chris@0
|
63 }
|
Chris@0
|
64
|
Chris@0
|
65 return $this;
|
Chris@0
|
66 }
|
Chris@0
|
67
|
Chris@0
|
68 /**
|
Chris@0
|
69 * Cast to array
|
Chris@0
|
70 *
|
Chris@0
|
71 * @return array
|
Chris@0
|
72 */
|
Chris@0
|
73 public function toArray()
|
Chris@0
|
74 {
|
Chris@0
|
75 $array = [];
|
Chris@0
|
76 $transform = function ($letters) {
|
Chris@0
|
77 $letter = array_shift($letters);
|
Chris@0
|
78 return '_' . strtolower($letter);
|
Chris@0
|
79 };
|
Chris@0
|
80 foreach ($this as $key => $value) {
|
Chris@0
|
81 if ($key === '__strictMode__') {
|
Chris@0
|
82 continue;
|
Chris@0
|
83 }
|
Chris@0
|
84 $normalizedKey = preg_replace_callback('/([A-Z])/', $transform, $key);
|
Chris@0
|
85 $array[$normalizedKey] = $value;
|
Chris@0
|
86 }
|
Chris@0
|
87 return $array;
|
Chris@0
|
88 }
|
Chris@0
|
89
|
Chris@0
|
90 /**
|
Chris@0
|
91 * Set a configuration property
|
Chris@0
|
92 *
|
Chris@0
|
93 * @see ParameterObject::__set()
|
Chris@0
|
94 * @param string $key
|
Chris@0
|
95 * @param mixed $value
|
Chris@0
|
96 * @throws Exception\BadMethodCallException
|
Chris@0
|
97 * @return void
|
Chris@0
|
98 */
|
Chris@0
|
99 public function __set($key, $value)
|
Chris@0
|
100 {
|
Chris@0
|
101 $setter = 'set' . str_replace('_', '', $key);
|
Chris@0
|
102
|
Chris@0
|
103 if (is_callable([$this, $setter])) {
|
Chris@0
|
104 $this->{$setter}($value);
|
Chris@0
|
105
|
Chris@0
|
106 return;
|
Chris@0
|
107 }
|
Chris@0
|
108
|
Chris@0
|
109 if ($this->__strictMode__) {
|
Chris@0
|
110 throw new Exception\BadMethodCallException(sprintf(
|
Chris@0
|
111 'The option "%s" does not have a callable "%s" ("%s") setter method which must be defined',
|
Chris@0
|
112 $key,
|
Chris@0
|
113 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))),
|
Chris@0
|
114 $setter
|
Chris@0
|
115 ));
|
Chris@0
|
116 }
|
Chris@0
|
117 }
|
Chris@0
|
118
|
Chris@0
|
119 /**
|
Chris@0
|
120 * Get a configuration property
|
Chris@0
|
121 *
|
Chris@0
|
122 * @see ParameterObject::__get()
|
Chris@0
|
123 * @param string $key
|
Chris@0
|
124 * @throws Exception\BadMethodCallException
|
Chris@0
|
125 * @return mixed
|
Chris@0
|
126 */
|
Chris@0
|
127 public function __get($key)
|
Chris@0
|
128 {
|
Chris@0
|
129 $getter = 'get' . str_replace('_', '', $key);
|
Chris@0
|
130
|
Chris@0
|
131 if (is_callable([$this, $getter])) {
|
Chris@0
|
132 return $this->{$getter}();
|
Chris@0
|
133 }
|
Chris@0
|
134
|
Chris@0
|
135 throw new Exception\BadMethodCallException(sprintf(
|
Chris@0
|
136 'The option "%s" does not have a callable "%s" getter method which must be defined',
|
Chris@0
|
137 $key,
|
Chris@0
|
138 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))
|
Chris@0
|
139 ));
|
Chris@0
|
140 }
|
Chris@0
|
141
|
Chris@0
|
142 /**
|
Chris@0
|
143 * Test if a configuration property is null
|
Chris@0
|
144 * @see ParameterObject::__isset()
|
Chris@0
|
145 * @param string $key
|
Chris@0
|
146 * @return bool
|
Chris@0
|
147 */
|
Chris@0
|
148 public function __isset($key)
|
Chris@0
|
149 {
|
Chris@0
|
150 $getter = 'get' . str_replace('_', '', $key);
|
Chris@0
|
151
|
Chris@0
|
152 return method_exists($this, $getter) && null !== $this->__get($key);
|
Chris@0
|
153 }
|
Chris@0
|
154
|
Chris@0
|
155 /**
|
Chris@0
|
156 * Set a configuration property to NULL
|
Chris@0
|
157 *
|
Chris@0
|
158 * @see ParameterObject::__unset()
|
Chris@0
|
159 * @param string $key
|
Chris@0
|
160 * @throws Exception\InvalidArgumentException
|
Chris@0
|
161 * @return void
|
Chris@0
|
162 */
|
Chris@0
|
163 public function __unset($key)
|
Chris@0
|
164 {
|
Chris@0
|
165 try {
|
Chris@0
|
166 $this->__set($key, null);
|
Chris@0
|
167 } catch (Exception\BadMethodCallException $e) {
|
Chris@0
|
168 throw new Exception\InvalidArgumentException(
|
Chris@0
|
169 'The class property $' . $key . ' cannot be unset as'
|
Chris@0
|
170 . ' NULL is an invalid value for it',
|
Chris@0
|
171 0,
|
Chris@0
|
172 $e
|
Chris@0
|
173 );
|
Chris@0
|
174 }
|
Chris@0
|
175 }
|
Chris@0
|
176 }
|