Skip to content

Commit

Permalink
[PropertyAccess] Extracted PropertyAccess component out of Form
Browse files Browse the repository at this point in the history
  • Loading branch information
webmozart committed Jan 10, 2013
1 parent b981a6f commit 1bae7b2
Show file tree
Hide file tree
Showing 73 changed files with 2,703 additions and 1,887 deletions.
128 changes: 128 additions & 0 deletions UPGRADE-2.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,141 @@
{{ error.message }}
```

* FormType, ModelType and PropertyPathMapper now have constructors. If you
extended these classes, you should call the parent constructor now.
Note that you are not recommended to extend FormType nor ModelType. You should
extend AbstractType instead and use the Form component's own inheritance
mechanism (`AbstractType::getParent()`).

Before:

```
use Symfony\Component\Form\Extensions\Core\DataMapper\PropertyPathMapper;
class CustomMapper extends PropertyPathMapper
{
public function __construct()
{
// ...
}
// ...
}
```

After:

```
use Symfony\Component\Form\Extensions\Core\DataMapper\PropertyPathMapper;
class CustomMapper extends PropertyPathMapper
{
public function __construct()
{
parent::__construct();
// ...
}
// ...
}
```

#### Deprecations

* The methods `getParent()`, `setParent()` and `hasParent()` in
`FormBuilderInterface` were deprecated and will be removed in Symfony 2.3.
You should not rely on these methods in your form type because the parent
of a form can change after building it.

* The class PropertyPath and related classes were deprecated and moved to a
dedicated component PropertyAccess. If you used any of these classes or
interfaces, you should adapt the namespaces now. During the move,
InvalidPropertyException was renamed to NoSuchPropertyException.

Before:

```
use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\Form\Util\PropertyPathBuilder;
use Symfony\Component\Form\Util\PropertyPathInterface;
use Symfony\Component\Form\Util\PropertyPathIterator;
use Symfony\Component\Form\Util\PropertyPathIteratorInterface;
use Symfony\Component\Form\Exception\InvalidPropertyException;
use Symfony\Component\Form\Exception\InvalidPropertyPathException;
use Symfony\Component\Form\Exception\PropertyAccessDeniedException;
```

After:

```
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyPathBuilder;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
use Symfony\Component\PropertyAccess\PropertyPathIterator;
use Symfony\Component\PropertyAccess\PropertyPathIteratorInterface;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
use Symfony\Component\PropertyAccess\Exception\InvalidPropertyPathException;
use Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException;
```

Also, `FormUtil::singularify()` was split away into a class StringUtil
in the new component.

Before:

```
use Symfony\Component\Form\Util\FormUtil;
$singular = FormUtil::singularify($plural);
```

After:

```
use Symfony\Component\PropertyAccess\StringUtil;
$singular = StringUtil::singularify($plural);
```

The methods `getValue()` and `setValue()` were moved to a new class
PropertyAccessor.

Before:

```
use Symfony\Component\Form\Util\PropertyPath;
$propertyPath = new PropertyPath('some.path');
$value = $propertyPath->getValue($object);
$propertyPath->setValue($object, 'new value');
```

After (alternative 1):

```
use Symfony\Component\PropertyAccess\PropertyAccess;
$accessor = PropertyAccess::getPropertyAccessor();
$value = $propertyAccessor->getValue($object, 'some.path');
$accessor->setValue($object, 'some.path', 'new value');
```

After (alternative 2):

```
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyPath;
$accessor = PropertyAccess::getPropertyAccessor();
$propertyPath = new PropertyPath('some.path');
$value = $propertyAccessor->getValue($object, $propertyPath);
$accessor->setValue($object, $propertyPath, 'new value');
```

### Routing

* RouteCollection does not behave like a tree structure anymore but as a flat
Expand Down
6 changes: 6 additions & 0 deletions src/Symfony/Bridge/Doctrine/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
CHANGELOG
=========

2.2.0
-----

* added an optional PropertyAccessorInterface parameter to DoctrineType,
EntityType and EntityChoiceList

2.1.0
-----

Expand Down
24 changes: 13 additions & 11 deletions src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\Form\Exception\StringCastException;
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

/**
* A choice list presenting a list of Doctrine entities as choices
Expand Down Expand Up @@ -86,17 +87,18 @@ class EntityChoiceList extends ObjectChoiceList
/**
* Creates a new entity choice list.
*
* @param ObjectManager $manager An EntityManager instance
* @param string $class The class name
* @param string $labelPath The property path used for the label
* @param EntityLoaderInterface $entityLoader An optional query builder
* @param array $entities An array of choices
* @param array $preferredEntities An array of preferred choices
* @param string $groupPath A property path pointing to the property used
* to group the choices. Only allowed if
* the choices are given as flat array.
* @param ObjectManager $manager An EntityManager instance
* @param string $class The class name
* @param string $labelPath The property path used for the label
* @param EntityLoaderInterface $entityLoader An optional query builder
* @param array $entities An array of choices
* @param array $preferredEntities An array of preferred choices
* @param string $groupPath A property path pointing to the property used
* to group the choices. Only allowed if
* the choices are given as flat array.
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
*/
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null)
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null, PropertyAccessorInterface $propertyAccessor = null)
{
$this->em = $manager;
$this->entityLoader = $entityLoader;
Expand All @@ -122,7 +124,7 @@ public function __construct(ObjectManager $manager, $class, $labelPath = null, E
$entities = array();
}

parent::__construct($entities, $labelPath, $preferredEntities, $groupPath);
parent::__construct($entities, $labelPath, $preferredEntities, $groupPath, null, $propertyAccessor);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\PropertyAccess\PropertyAccess;

class DoctrineOrmExtension extends AbstractExtension
{
Expand All @@ -26,7 +27,7 @@ public function __construct(ManagerRegistry $registry)
protected function loadTypes()
{
return array(
new Type\EntityType($this->registry),
new Type\EntityType($this->registry, PropertyAccess::getPropertyAccessor()),
);
}

Expand Down
16 changes: 13 additions & 3 deletions src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

abstract class DoctrineType extends AbstractType
{
Expand All @@ -35,9 +37,15 @@ abstract class DoctrineType extends AbstractType
*/
private $choiceListCache = array();

public function __construct(ManagerRegistry $registry)
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;

public function __construct(ManagerRegistry $registry, PropertyAccessorInterface $propertyAccessor = null)
{
$this->registry = $registry;
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
}

public function buildForm(FormBuilderInterface $builder, array $options)
Expand All @@ -54,6 +62,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$choiceListCache =& $this->choiceListCache;
$registry = $this->registry;
$propertyAccessor = $this->propertyAccessor;
$type = $this;

$loader = function (Options $options) use ($type) {
Expand All @@ -64,7 +73,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
return null;
};

$choiceList = function (Options $options) use (&$choiceListCache, &$time) {
$choiceList = function (Options $options) use (&$choiceListCache, $propertyAccessor) {
// Support for closures
$propertyHash = is_object($options['property'])
? spl_object_hash($options['property'])
Expand Down Expand Up @@ -118,7 +127,8 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
$options['loader'],
$options['choices'],
$options['preferred_choices'],
$options['group_by']
$options['group_by'],
$propertyAccessor
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ protected function tearDown()
parent::tearDown();

$this->em = null;
$this->emRegistry = null;
}

protected function getExtensions()
Expand Down
3 changes: 3 additions & 0 deletions src/Symfony/Bridge/Propel1/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ CHANGELOG
-----

* added a collection type for the I18n behavior
* added an optional PropertyAccessorInterface parameter to ModelType and
ModelChoiceList
* [BC BREAK] ModelType now has a constructor

2.1.0
-----
Expand Down
22 changes: 12 additions & 10 deletions src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\StringCastException;
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

/**
* Widely inspired by the EntityChoiceList.
Expand Down Expand Up @@ -69,16 +70,17 @@ class ModelChoiceList extends ObjectChoiceList
*
* @see Symfony\Bridge\Propel1\Form\Type\ModelType How to use the preferred choices.
*
* @param string $class The FQCN of the model class to be loaded.
* @param string $labelPath A property path pointing to the property used for the choice labels.
* @param array $choices An optional array to use, rather than fetching the models.
* @param ModelCriteria $queryObject The query to use retrieving model data from database.
* @param string $groupPath A property path pointing to the property used to group the choices.
* @param array|ModelCriteria $preferred The preferred items of this choice.
* Either an array if $choices is given,
* or a ModelCriteria to be merged with the $queryObject.
* @param string $class The FQCN of the model class to be loaded.
* @param string $labelPath A property path pointing to the property used for the choice labels.
* @param array $choices An optional array to use, rather than fetching the models.
* @param ModelCriteria $queryObject The query to use retrieving model data from database.
* @param string $groupPath A property path pointing to the property used to group the choices.
* @param array|ModelCriteria $preferred The preferred items of this choice.
* Either an array if $choices is given,
* or a ModelCriteria to be merged with the $queryObject.
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
*/
public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array())
public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array(), PropertyAccessorInterface $propertyAccessor = null)
{
$this->class = $class;

Expand All @@ -104,7 +106,7 @@ public function __construct($class, $labelPath = null, $choices = null, $queryOb
$this->identifierAsIndex = true;
}

parent::__construct($choices, $labelPath, $preferred, $groupPath);
parent::__construct($choices, $labelPath, $preferred, $groupPath, null, $propertyAccessor);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Bridge/Propel1/Form/PropelExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Bridge\Propel1\Form;

use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\PropertyAccess\PropertyAccess;

/**
* Represents the Propel form extension, which loads the Propel functionality.
Expand All @@ -23,7 +24,7 @@ class PropelExtension extends AbstractExtension
protected function loadTypes()
{
return array(
new Type\ModelType(),
new Type\ModelType(PropertyAccess::getPropertyAccessor()),
new Type\TranslationCollectionType(),
new Type\TranslationType()
);
Expand Down
19 changes: 17 additions & 2 deletions src/Symfony/Bridge/Propel1/Form/Type/ModelType.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

/**
* ModelType class.
Expand Down Expand Up @@ -48,6 +50,16 @@
*/
class ModelType extends AbstractType
{
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;

public function __construct(PropertyAccessorInterface $propertyAccessor = null)
{
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($options['multiple']) {
Expand All @@ -57,14 +69,17 @@ public function buildForm(FormBuilderInterface $builder, array $options)

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$choiceList = function (Options $options) {
$propertyAccessor = $this->propertyAccessor;

$choiceList = function (Options $options) use ($propertyAccessor) {
return new ModelChoiceList(
$options['class'],
$options['property'],
$options['choices'],
$options['query'],
$options['group_by'],
$options['preferred_choices']
$options['preferred_choices'],
$propertyAccessor
);
};

Expand Down
Loading

0 comments on commit 1bae7b2

Please sign in to comment.