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