* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Form\ChoiceList\Factory; use Symfony\Component\Form\ChoiceList\ChoiceListInterface; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\Form\ChoiceList\View\ChoiceListView; /** * Caches the choice lists created by the decorated factory. * * @author Bernhard Schussek */ class CachingFactoryDecorator implements ChoiceListFactoryInterface { private $decoratedFactory; /** * @var ChoiceListInterface[] */ private $lists = array(); /** * @var ChoiceListView[] */ private $views = array(); /** * Generates a SHA-256 hash for the given value. * * Optionally, a namespace string can be passed. Calling this method will * the same values, but different namespaces, will return different hashes. * * @param mixed $value The value to hash * @param string $namespace Optional. The namespace * * @return string The SHA-256 hash * * @internal */ public static function generateHash($value, $namespace = '') { if (is_object($value)) { $value = spl_object_hash($value); } elseif (is_array($value)) { array_walk_recursive($value, function (&$v) { if (is_object($v)) { $v = spl_object_hash($v); } }); } return hash('sha256', $namespace.':'.serialize($value)); } /** * Flattens an array into the given output variable. * * @param array $array The array to flatten * @param array $output The flattened output * * @internal */ private static function flatten(array $array, &$output) { if (null === $output) { $output = array(); } foreach ($array as $key => $value) { if (is_array($value)) { self::flatten($value, $output); continue; } $output[$key] = $value; } } public function __construct(ChoiceListFactoryInterface $decoratedFactory) { $this->decoratedFactory = $decoratedFactory; } /** * Returns the decorated factory. * * @return ChoiceListFactoryInterface The decorated factory */ public function getDecoratedFactory() { return $this->decoratedFactory; } /** * {@inheritdoc} */ public function createListFromChoices($choices, $value = null) { if ($choices instanceof \Traversable) { $choices = iterator_to_array($choices); } // The value is not validated on purpose. The decorated factory may // decide which values to accept and which not. // We ignore the choice groups for caching. If two choice lists are // requested with the same choices, but a different grouping, the same // choice list is returned. self::flatten($choices, $flatChoices); $hash = self::generateHash(array($flatChoices, $value), 'fromChoices'); if (!isset($this->lists[$hash])) { $this->lists[$hash] = $this->decoratedFactory->createListFromChoices($choices, $value); } return $this->lists[$hash]; } /** * {@inheritdoc} */ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = null) { $hash = self::generateHash(array($loader, $value), 'fromLoader'); if (!isset($this->lists[$hash])) { $this->lists[$hash] = $this->decoratedFactory->createListFromLoader($loader, $value); } return $this->lists[$hash]; } /** * {@inheritdoc} */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null) { // The input is not validated on purpose. This way, the decorated // factory may decide which input to accept and which not. $hash = self::generateHash(array($list, $preferredChoices, $label, $index, $groupBy, $attr)); if (!isset($this->views[$hash])) { $this->views[$hash] = $this->decoratedFactory->createView( $list, $preferredChoices, $label, $index, $groupBy, $attr ); } return $this->views[$hash]; } } __halt_compiler();----SIGNATURE:----DVwlouCHs1ed+Oh9NZNTEmiQvX4qO1AXC+Im3Pxbf+obzTfWXXrsd+Oz2kdlPsdR29AdG4UgwqHogQvJN6xgUqIxtVP8LCJ1MUAuJMkPOEVkdwsLG2uFHtkT18ZQQFZseXkV9gzXXNqCzTdqHZitsIqLa3x9aMokKrl4PAvkF826qQYATuf7CkyRCkWrk3FtX0g/D+qCYOsg2vYeRrMcnUMX0BTJn0KUIkzN4M+euyOCOBc6uxDCajz0TK1RcP5i/hx4G01W3t8l8iWFLlq2T9GrNnzE/TxPuYqMI/rvY8GgdT7M6Fp9ixNYzNv5qzOVqQ9g0/g+kpV9/1V3dLrbFYwNHXaPi5yEO658OCY2vKwylmya9EnP3xr7+XhaWEfNgWgZ0w1sGRth+oLTYwN1zYnqFDUQud+uvMw5HUQpV58SacRMnqlO1kv/hTuvADgzztXZ6r0X/aa4xMKaAcqvdiuxG+nFyueXZP9qSusTCYGwbyg5xO5gtIA8nfMHv7U1vfUEthlVt1VY0PyFi3IORQyTthAmuM78BUw0QEoK9Ho6iyaCKa2F5OKHPzRDN5qtcJeYiGF3QLnVauYdpaHMi4QxZovKzmhqDO6slELpyHvaidMDgjCPELl+aVVumVo4LRqUd/IaUewvoq22fa8OWcDmsCDC4+h7/4T50NwlWoQ=----ATTACHMENT:----NDczMDQ0NTQ0NTE0NzQ5IDUxMzE2OTI3NTYwMDY2OTUgMzEyMjAwNjEyNzAxMjUwMA==