File: /virtual/nagasaki/public_html/ec/vendor/symfony/form/ChoiceList/Factory/PropertyAccessDecorator.php
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <bschussek@gmail.com>
*/
class PropertyAccessDecorator implements ChoiceListFactoryInterface
{
/**
* @var ChoiceListFactoryInterface
*/
private $decoratedFactory;
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;
/**
* Decorates the given factory.
*
* @param ChoiceListFactoryInterface $decoratedFactory The decorated factory
* @param null|PropertyAccessorInterface $propertyAccessor The used property accessor
*/
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 array|\Traversable $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);
}
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 array|\Traversable $choices The choices
* @param null|callable|string|PropertyPath $value The callable or path for
* generating the choice values
*
* @return ChoiceListInterface The choice list
*
* @deprecated Added for backwards compatibility in Symfony 2.7, to be
* removed in Symfony 3.0.
*/
public function createListFromFlippedChoices($choices, $value = null, $triggerDeprecationNotice = true)
{
// Property paths are not supported here, because array keys can never
// be objects
return $this->decoratedFactory->createListFromFlippedChoices($choices, $value, $triggerDeprecationNotice);
}
/**
* {@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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
}