* * 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; use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\PropertyAccess\PropertyPath; /** * Adds property path support to a choice list factory. * * Pass the decorated factory to the constructor: * * ```php * $decorator = new PropertyAccessDecorator($factory); * ``` * * You can now pass property paths for generating choice values, labels, view * indices, HTML attributes and for determining the preferred choices and the * choice groups: * * ```php * // extract values from the $value property * $list = $createListFromChoices($objects, 'value'); * ``` * * @author Bernhard Schussek */ class PropertyAccessDecorator implements ChoiceListFactoryInterface { private $decoratedFactory; private $propertyAccessor; public function __construct(ChoiceListFactoryInterface $decoratedFactory, PropertyAccessorInterface $propertyAccessor = null) { $this->decoratedFactory = $decoratedFactory; $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); } /** * Returns the decorated factory. * * @return ChoiceListFactoryInterface The decorated factory */ public function getDecoratedFactory() { return $this->decoratedFactory; } /** * {@inheritdoc} * * @param iterable $choices The choices * @param null|callable|string|PropertyPath $value The callable or path for * generating the choice values * * @return ChoiceListInterface The choice list */ public function createListFromChoices($choices, $value = null) { if (is_string($value) && !is_callable($value)) { $value = new PropertyPath($value); } elseif (is_string($value) && is_callable($value)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($value instanceof PropertyPath) { $accessor = $this->propertyAccessor; $value = function ($choice) use ($accessor, $value) { // The callable may be invoked with a non-object/array value // when such values are passed to // ChoiceListInterface::getValuesForChoices(). Handle this case // so that the call to getValue() doesn't break. if (is_object($choice) || is_array($choice)) { return $accessor->getValue($choice, $value); } }; } return $this->decoratedFactory->createListFromChoices($choices, $value); } /** * {@inheritdoc} * * @param ChoiceLoaderInterface $loader The choice loader * @param null|callable|string|PropertyPath $value The callable or path for * generating the choice values * * @return ChoiceListInterface The choice list */ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = null) { if (is_string($value) && !is_callable($value)) { $value = new PropertyPath($value); } elseif (is_string($value) && is_callable($value)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($value instanceof PropertyPath) { $accessor = $this->propertyAccessor; $value = function ($choice) use ($accessor, $value) { // The callable may be invoked with a non-object/array value // when such values are passed to // ChoiceListInterface::getValuesForChoices(). Handle this case // so that the call to getValue() doesn't break. if (is_object($choice) || is_array($choice)) { return $accessor->getValue($choice, $value); } }; } return $this->decoratedFactory->createListFromLoader($loader, $value); } /** * {@inheritdoc} * * @param ChoiceListInterface $list The choice list * @param null|array|callable|string|PropertyPath $preferredChoices The preferred choices * @param null|callable|string|PropertyPath $label The callable or path generating the choice labels * @param null|callable|string|PropertyPath $index The callable or path generating the view indices * @param null|callable|string|PropertyPath $groupBy The callable or path generating the group names * @param null|array|callable|string|PropertyPath $attr The callable or path generating the HTML attributes * * @return ChoiceListView The choice list view */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null) { $accessor = $this->propertyAccessor; if (is_string($label) && !is_callable($label)) { $label = new PropertyPath($label); } elseif (is_string($label) && is_callable($label)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($label instanceof PropertyPath) { $label = function ($choice) use ($accessor, $label) { return $accessor->getValue($choice, $label); }; } if (is_string($preferredChoices) && !is_callable($preferredChoices)) { $preferredChoices = new PropertyPath($preferredChoices); } elseif (is_string($preferredChoices) && is_callable($preferredChoices)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($preferredChoices instanceof PropertyPath) { $preferredChoices = function ($choice) use ($accessor, $preferredChoices) { try { return $accessor->getValue($choice, $preferredChoices); } catch (UnexpectedTypeException $e) { // Assume not preferred if not readable return false; } }; } if (is_string($index) && !is_callable($index)) { $index = new PropertyPath($index); } elseif (is_string($index) && is_callable($index)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($index instanceof PropertyPath) { $index = function ($choice) use ($accessor, $index) { return $accessor->getValue($choice, $index); }; } if (is_string($groupBy) && !is_callable($groupBy)) { $groupBy = new PropertyPath($groupBy); } elseif (is_string($groupBy) && is_callable($groupBy)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($groupBy instanceof PropertyPath) { $groupBy = function ($choice) use ($accessor, $groupBy) { try { return $accessor->getValue($choice, $groupBy); } catch (UnexpectedTypeException $e) { // Don't group if path is not readable } }; } if (is_string($attr) && !is_callable($attr)) { $attr = new PropertyPath($attr); } elseif (is_string($attr) && is_callable($attr)) { @trigger_error('Passing callable strings is deprecated since Symfony 3.1 and PropertyAccessDecorator will treat them as property paths in 4.0. You should use a "\Closure" instead.', E_USER_DEPRECATED); } if ($attr instanceof PropertyPath) { $attr = function ($choice) use ($accessor, $attr) { return $accessor->getValue($choice, $attr); }; } return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr); } } __halt_compiler();----SIGNATURE:----YbB1xQUvnJ1xRwmBsQTtTib0H6PkrqYa34gxjkqsY6M5wmBKZP1Gc/cPXq+xvf2vhVGLJnc1tHxzHrjnzcwHtsts2TtDgMV4tdtxukFfQdMwjTOVhev3btH6UYBDNU2zyWEEY6UC0675Hh6YEkPZ1HFeJH4Ku9+pjHbO3JuPA4IUBRiD/o5rVc/PoJdi4Nf/rvhXPpHKVoogME+XsS5ZoAX08GvzsAm9yG/6POdx2e98qX/7CxdTC6VjfLd7WTtR2HBStA4UmrJJvFsKnottI6nuhzMiIDroS94ljhURdxG+8i0/EHTSmDCKAfxm5XItb89eRWeiZfj8UFTX8csWVUBGLL390Jf8jgp0rtLhgSSaEHzP5dbpWcUgd6bevloFYJW7x92EAqWlkKejY5cvxyrPgv+cgySRwW7u/ZLQbUe07lEaS30qRHp4sne777FbJMHuCLHPu1qR5sxumC4u3LOreiTJ7CiPHuqX9L5UEkL3Bkxppz+cVyyZpKKGrBilDQcRxe/Kix/gYHKb9WUXWY57Eo0tEQ8VhZ+yMD2Xx89j3wSaAh6fuGeDlQMdOJver4Z6U7U8EbMSfvRf0AEOQOwhRg26t0EGJHVlNiRgqx47s1xrEBoSHnTZq1ec5VdLnaSzRnscYca4ZGhxXXq6xIgTPpf0rwelrb2uFY81KFc=----ATTACHMENT:----NTcxNDQ1OTUxMTQwMjU2IDIwMjQ3NDYwMjExOTYyMTEgMjMwMjE5ODU2NTgyMDgyOA==