Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ClassMethods.php
001 <?php
002 /**
003 * Zend Framework (http://framework.zend.com/)
004 *
005 * @link http://github.com/zendframework/zf2 for the canonical source repository
006 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
007 * @license http://framework.zend.com/license/new-bsd New BSD License
008 */
009
010 namespace Zend\Stdlib\Hydrator;
011
012 use Traversable;
013 use Zend\Stdlib\Exception;
014 use Zend\Stdlib\ArrayUtils;
015 use Zend\Stdlib\Hydrator\Filter\FilterComposite;
016 use Zend\Stdlib\Hydrator\Filter\FilterProviderInterface;
017 use Zend\Stdlib\Hydrator\Filter\GetFilter;
018 use Zend\Stdlib\Hydrator\Filter\HasFilter;
019 use Zend\Stdlib\Hydrator\Filter\IsFilter;
020 use Zend\Stdlib\Hydrator\Filter\MethodMatchFilter;
021 use Zend\Stdlib\Hydrator\Filter\OptionalParametersFilter;
022 use Zend\Stdlib\Hydrator\NamingStrategy\NamingStrategyInterface;
023 use Zend\Stdlib\Hydrator\NamingStrategy\UnderscoreNamingStrategy;
024
025 class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
026 {
027 /**
028 * Holds the names of the methods used for hydration, indexed by class::property name,
029 * false if the hydration method is not callable/usable for hydration purposes
030 *
031 * @var string[]|bool[]
032 */
033 private $hydrationMethodsCache = array();
034
035 /**
036 * A map of extraction methods to property name to be used during extraction, indexed
037 * by class name and method name
038 *
039 * @var string[][]
040 */
041 private $extractionMethodsCache = array();
042
043 /**
044 * Flag defining whether array keys are underscore-separated (true) or camel case (false)
045 *
046 * @var bool
047 */
048 protected $underscoreSeparatedKeys = true;
049
050 /**
051 * @var \Zend\Stdlib\Hydrator\Filter\FilterInterface
052 */
053 private $callableMethodFilter;
054
055 /**
056 * Define if extract values will use camel case or name with underscore
057 * @param bool|array $underscoreSeparatedKeys
058 */
059 public function __construct($underscoreSeparatedKeys = true)
060 {
061 parent::__construct();
062 $this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys);
063
064 $this->callableMethodFilter = new OptionalParametersFilter();
065
066 $this->filterComposite->addFilter('is', new IsFilter());
067 $this->filterComposite->addFilter('has', new HasFilter());
068 $this->filterComposite->addFilter('get', new GetFilter());
069 $this->filterComposite->addFilter('parameter', new OptionalParametersFilter(), FilterComposite::CONDITION_AND);
070 }
071
072 /**
073 * @param array|Traversable $options
074 * @return ClassMethods
075 * @throws Exception\InvalidArgumentException
076 */
077 public function setOptions($options)
078 {
079 if ($options instanceof Traversable) {
080 $options = ArrayUtils::iteratorToArray($options);
081 } elseif (!is_array($options)) {
082 throw new Exception\InvalidArgumentException(
083 'The options parameter must be an array or a Traversable'
084 );
085 }
086 if (isset($options['underscoreSeparatedKeys'])) {
087 $this->setUnderscoreSeparatedKeys($options['underscoreSeparatedKeys']);
088 }
089
090 return $this;
091 }
092
093 /**
094 * @param bool $underscoreSeparatedKeys
095 * @return ClassMethods
096 */
097 public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys)
098 {
099 $this->underscoreSeparatedKeys = (bool) $underscoreSeparatedKeys;
100
101 if ($this->underscoreSeparatedKeys) {
102 $this->setNamingStrategy(new UnderscoreNamingStrategy);
103 } elseif ($this->getNamingStrategy() instanceof UnderscoreNamingStrategy) {
104 $this->removeNamingStrategy();
105 }
106
107 return $this;
108 }
109
110 /**
111 * @return bool
112 */
113 public function getUnderscoreSeparatedKeys()
114 {
115 return $this->underscoreSeparatedKeys;
116 }
117
118 /**
119 * Extract values from an object with class methods
120 *
121 * Extracts the getter/setter of the given $object.
122 *
123 * @param object $object
124 * @return array
125 * @throws Exception\BadMethodCallException for a non-object $object
126 */
127 public function extract($object)
128 {
129 if (!is_object($object)) {
130 throw new Exception\BadMethodCallException(sprintf(
131 '%s expects the provided $object to be a PHP object)',
132 __METHOD__
133 ));
134 }
135
136 $objectClass = get_class($object);
137
138 // reset the hydrator's hydrator's cache for this object, as the filter may be per-instance
139 if ($object instanceof FilterProviderInterface) {
140 $this->extractionMethodsCache[$objectClass] = null;
141 }
142
143 // pass 1 - finding out which properties can be extracted, with which methods (populate hydration cache)
144 if (! isset($this->extractionMethodsCache[$objectClass])) {
145 $this->extractionMethodsCache[$objectClass] = array();
146 $filter = $this->filterComposite;
147 $methods = get_class_methods($object);
148
149 if ($object instanceof FilterProviderInterface) {
150 $filter = new FilterComposite(
151 array($object->getFilter()),
152 array(new MethodMatchFilter('getFilter'))
153 );
154 }
155
156 foreach ($methods as $method) {
157 $methodFqn = $objectClass . '::' . $method;
158
159 if (! ($filter->filter($methodFqn) && $this->callableMethodFilter->filter($methodFqn))) {
160 continue;
161 }
162
163 $attribute = $method;
164
165 if (strpos($method, 'get') === 0) {
166 $attribute = substr($method, 3);
167 if (!property_exists($object, $attribute)) {
168 $attribute = lcfirst($attribute);
169 }
170 }
171
172 $this->extractionMethodsCache[$objectClass][$method] = $attribute;
173 }
174 }
175
176 $values = array();
177
178 // pass 2 - actually extract data
179 foreach ($this->extractionMethodsCache[$objectClass] as $methodName => $attributeName) {
180 $realAttributeName = $this->extractName($attributeName, $object);
181 $values[$realAttributeName] = $this->extractValue($realAttributeName, $object->$methodName(), $object);
182 }
183
184 return $values;
185 }
186
187 /**
188 * Hydrate an object by populating getter/setter methods
189 *
190 * Hydrates an object by getter/setter methods of the object.
191 *
192 * @param array $data
193 * @param object $object
194 * @return object
195 * @throws Exception\BadMethodCallException for a non-object $object
196 */
197 public function hydrate(array $data, $object)
198 {
199 if (!is_object($object)) {
200 throw new Exception\BadMethodCallException(sprintf(
201 '%s expects the provided $object to be a PHP object)',
202 __METHOD__
203 ));
204 }
205
206 $objectClass = get_class($object);
207
208 foreach ($data as $property => $value) {
209 $propertyFqn = $objectClass . '::$' . $property;
210
211 if (! isset($this->hydrationMethodsCache[$propertyFqn])) {
212 $setterName = 'set' . ucfirst($this->hydrateName($property, $data));
213
214 $this->hydrationMethodsCache[$propertyFqn] = is_callable(array($object, $setterName))
215 ? $setterName
216 : false;
217 }
218
219 if ($this->hydrationMethodsCache[$propertyFqn]) {
220 $object->{$this->hydrationMethodsCache[$propertyFqn]}($this->hydrateValue($property, $value, $data));
221 }
222 }
223
224 return $object;
225 }
226
227 /**
228 * {@inheritDoc}
229 */
230 public function addFilter($name, $filter, $condition = FilterComposite::CONDITION_OR)
231 {
232 $this->resetCaches();
233
234 return parent::addFilter($name, $filter, $condition);
235 }
236
237 /**
238 * {@inheritDoc}
239 */
240 public function removeFilter($name)
241 {
242 $this->resetCaches();
243
244 return parent::removeFilter($name);
245 }
246
247 /**
248 * {@inheritDoc}
249 */
250 public function setNamingStrategy(NamingStrategyInterface $strategy)
251 {
252 $this->resetCaches();
253
254 return parent::setNamingStrategy($strategy);
255 }
256
257 /**
258 * {@inheritDoc}
259 */
260 public function removeNamingStrategy()
261 {
262 $this->resetCaches();
263
264 return parent::removeNamingStrategy();
265 }
266
267 /**
268 * Reset all local hydration/extraction caches
269 */
270 private function resetCaches()
271 {
272 $this->hydrationMethodsCache = $this->extractionMethodsCache = array();
273 }
274 }
275