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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ClassMethods.php

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 8.56 KiB


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