Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Pool::getPropertyAccessor() method #6634

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions UPGRADE-3.x.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
UPGRADE 3.x
===========

UPGRADE FROM 3.xx to 3.xx
=========================

### Sonata\AdminBundle\Admin\Pool

- Passing a `Symfony\Component\PropertyAccess\PropertyAccessorInterface` instance as 4 argument instantiating
`Sonata\AdminBundle\Admin\Pool` is deprecated.
- `Sonata\AdminBundle\Admin\Pool::getPropertyAccessor()` method has been deprecated. You SHOULD inject `Symfony\Component\PropertyAccess\PropertyAccessorInterface`
where is needed.

### Sonata\AdminBundle\Action\SetObjectFieldValueAction

Not passing a `Symfony\Component\PropertyAccess\PropertyAccessorInterface` instance as argument 5 instantiating
`Sonata\AdminBundle\Action\SetObjectFieldValueAction` is deprecated.

### Sonata\AdminBundle\Admin\AdminHelper

Not passing a `Symfony\Component\PropertyAccess\PropertyAccessorInterface` instance as argument 1 instantiating
`Sonata\AdminBundle\Admin\AdminHelper` is deprecated.

### Sonata\AdminBundle\Twig\Extension\SonataAdminExtension

Argument 5 of `Sonata\AdminBundle\Admin\SonataAdminExtension` constructor SHOULD be a
`Symfony\Component\PropertyAccess\PropertyAccessorInterface` instance and argument 6 SHOULD be a
`Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface` instance or "null".

UPGRADE FROM 3.80 to 3.81
=========================

Expand Down
36 changes: 31 additions & 5 deletions src/Action/SetObjectFieldValueAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Twig\Environment;
Expand Down Expand Up @@ -50,11 +51,23 @@ final class SetObjectFieldValueAction
private $resolver;

/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;

/**
* NEXT_MAJOR: Make all arguments mandatory.
*
* @param ValidatorInterface $validator
* @param DataTransformerResolver|null $resolver
*/
public function __construct(Environment $twig, Pool $pool, $validator, $resolver = null)
{
public function __construct(
Environment $twig,
Pool $pool,
$validator,
$resolver = null,
?PropertyAccessorInterface $propertyAccessor = null
) {
// NEXT_MAJOR: Move ValidatorInterface check to method signature
if (!($validator instanceof ValidatorInterface)) {
throw new \InvalidArgumentException(sprintf(
Expand All @@ -75,10 +88,23 @@ public function __construct(Environment $twig, Pool $pool, $validator, $resolver
$resolver = new DataTransformerResolver();
}

// NEXT_MAJOR: Remove this check.
if (null === $propertyAccessor) {
@trigger_error(sprintf(
'Omitting the argument 5 for "%s()" or passing "null" is deprecated since sonata-project/admin-bundle'
.' 3.x and will throw a \TypeError error in version 4.0. You must pass an instance of %s instead.',
__METHOD__,
PropertyAccessorInterface::class
), E_USER_DEPRECATED);

$propertyAccessor = $pool->getPropertyAccessor();
}

$this->pool = $pool;
$this->twig = $twig;
$this->validator = $validator;
$this->resolver = $resolver;
$this->propertyAccessor = $propertyAccessor;
}

/**
Expand Down Expand Up @@ -137,15 +163,15 @@ public function __invoke(Request $request): JsonResponse

// If property path has more than 1 element, take the last object in order to validate it
if ($propertyPath->getLength() > 1) {
$object = $this->pool->getPropertyAccessor()->getValue($object, $propertyPath->getParent());
$object = $this->propertyAccessor->getValue($object, $propertyPath->getParent());

$elements = $propertyPath->getElements();
$field = end($elements);
$propertyPath = new PropertyPath($field);
}

if ('' === $value) {
$this->pool->getPropertyAccessor()->setValue($object, $propertyPath, null);
$this->propertyAccessor->setValue($object, $propertyPath, null);
} else {
$dataTransformer = $this->resolver->resolve($fieldDescription, $admin->getModelManager());

Expand All @@ -161,7 +187,7 @@ public function __invoke(Request $request): JsonResponse
), Response::HTTP_NOT_FOUND);
}

$this->pool->getPropertyAccessor()->setValue($object, $propertyPath, $value);
$this->propertyAccessor->setValue($object, $propertyPath, $value);
}

$violations = $this->validator->validate($object);
Expand Down
3 changes: 2 additions & 1 deletion src/Admin/AbstractAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
use Symfony\Component\HttpFoundation\InputBag;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface as RoutingUrlGeneratorInterface;
use Symfony\Component\Security\Acl\Model\DomainObjectInterface;
Expand Down Expand Up @@ -3722,7 +3723,7 @@ final protected function appendParentObject(object $object): void
$parentObject = $parentAdmin->getObject($this->request->get($parentAdmin->getIdParameter()));

if (null !== $parentObject) {
$propertyAccessor = $this->getConfigurationPool()->getPropertyAccessor();
$propertyAccessor = PropertyAccess::createPropertyAccessor();
$propertyPath = new PropertyPath($this->getParentAssociationMapping());

$value = $propertyAccessor->getValue($object, $propertyPath);
Expand Down
70 changes: 60 additions & 10 deletions src/Admin/AdminHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

/**
* @final since sonata-project/admin-bundle 3.52
Expand All @@ -39,13 +40,57 @@ class AdminHelper
private const FORM_FIELD_DELETE = '_delete';

/**
* @var Pool
* NEXT_MAJOR: Remove this property.
*
* @var Pool|null
*/
protected $pool;

public function __construct(Pool $pool)
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;

/**
* NEXT_MAJOR: Change signature for (PropertyAccessorInterface $propertyAccessor).
*/
public function __construct($poolOrPropertyAccessor)
{
$this->pool = $pool;
// NEXT_MAJOR: Remove this block.
if (!$poolOrPropertyAccessor instanceof Pool && !$poolOrPropertyAccessor instanceof PropertyAccessorInterface) {
throw new \TypeError(sprintf(
'Argument 1 passed to "%s()" must be either an instance of %s or %s, %s given.',
__METHOD__,
Pool::class,
PropertyAccessorInterface::class,
\is_object($poolOrPropertyAccessor) ? 'instance of "'.\get_class($poolOrPropertyAccessor).'"' : '"'.\gettype($poolOrPropertyAccessor).'"'
));
}

// NEXT_MAJOR: Remove this block.
if ($poolOrPropertyAccessor instanceof Pool) {
@trigger_error(sprintf(
'Passing an instance of "%s" as argument 1 for "%s()" is deprecated since'
.' sonata-project/admin-bundle 3.x and will throw a \TypeError error in version 4.0.'
.' You MUST pass an instance of %s instead.',
Pool::class,
__METHOD__,
PropertyAccessorInterface::class
), E_USER_DEPRECATED);

$this->pool = $poolOrPropertyAccessor;
$this->propertyAccessor = $poolOrPropertyAccessor->getPropertyAccessor();

return;
}

// NEXT_MAJOR: Remove this block.
if ((\func_get_args()[1] ?? null) instanceof Pool) {
$this->pool = \func_get_args()[1];
}

// NEXT_MAJOR: Change $poolOrPropertyAccessor to $propertyAccessor.
$this->propertyAccessor = $poolOrPropertyAccessor;
}

/**
Expand Down Expand Up @@ -93,6 +138,15 @@ public function getChildFormView(FormView $formView, $elementId)
*/
public function getAdmin($code)
{
if (null === $this->pool) {
throw new \LogicException(sprintf(
'You MUST pass a "%s" instance as argument 2 when constructing "%s" to be able to call "%s()".',
Pool::class,
self::class,
__METHOD__
));
}

return $this->pool->getInstance($code);
}

Expand Down Expand Up @@ -144,11 +198,9 @@ public function appendFormFieldElement(AdminInterface $admin, $subject, $element
//Child form not found (probably nested one)
//if childFormBuilder was not found resulted in fatal error getName() method call on non object
if (!$childFormBuilder) {
$propertyAccessor = $this->pool->getPropertyAccessor();

$path = $this->getElementAccessPath($elementId, $subject);

$collection = $propertyAccessor->getValue($subject, $path);
$collection = $this->propertyAccessor->getValue($subject, $path);

if ($collection instanceof DoctrinePersistentCollection || $collection instanceof PersistentCollection) {
//since doctrine 2.4
Expand All @@ -160,7 +212,7 @@ public function appendFormFieldElement(AdminInterface $admin, $subject, $element
}

$collection->add(new $modelClassName());
$propertyAccessor->setValue($subject, $path, $collection);
$this->propertyAccessor->setValue($subject, $path, $collection);

$fieldDescription = null;
} else {
Expand Down Expand Up @@ -281,8 +333,6 @@ public function camelize($property)
*/
public function getElementAccessPath($elementId, $model)
{
$propertyAccessor = $this->pool->getPropertyAccessor();

$idWithoutIdentifier = preg_replace('/^[^_]*_/', '', $elementId);
$initialPath = preg_replace('#(_(\d+)_)#', '[$2]_', $idWithoutIdentifier);

Expand All @@ -294,7 +344,7 @@ public function getElementAccessPath($elementId, $model)
$currentPath .= empty($currentPath) ? $part : '_'.$part;
$separator = empty($totalPath) ? '' : '.';

if ($propertyAccessor->isReadable($model, $totalPath.$separator.$currentPath)) {
if ($this->propertyAccessor->isReadable($model, $totalPath.$separator.$currentPath)) {
$totalPath .= $separator.$currentPath;
$currentPath = '';
}
Expand Down
25 changes: 25 additions & 0 deletions src/Admin/Pool.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ class Pool
protected $options = [];

/**
* NEXT_MAJOR: Remove this property.
*
* @var PropertyAccessorInterface
*
* @deprecated since sonata-project/admin-bundle 3.x, will be dropped in 4.0.
*/
protected $propertyAccessor;

Expand All @@ -87,6 +91,8 @@ class Pool
private $templateRegistry;

/**
* NEXT_MAJOR: Remove $propertyAccessor argument.
*
* @param string $title
* @param string $logoTitle
* @param array $options
Expand All @@ -102,6 +108,17 @@ public function __construct(
$this->title = $title;
$this->titleLogo = $logoTitle;
$this->options = $options;

// NEXT_MAJOR: Remove this block.
if (null !== $propertyAccessor) {
@trigger_error(sprintf(
'Passing an "%s" instance as argument 4 to "%s()" is deprecated since sonata-project/admin-bundle 3.x.',
PropertyAccessorInterface::class,
__METHOD__
), E_USER_DEPRECATED);
}

// NEXT_MAJOR: Remove next line.
$this->propertyAccessor = $propertyAccessor;
}

Expand Down Expand Up @@ -545,8 +562,16 @@ public function getOption($name, $default = null)
return $default;
}

/**
* @deprecated since sonata-project/admin-bundle 3.x, will be dropped in 4.0. Use Symfony "PropertyAccess" instead.
*/
public function getPropertyAccessor()
{
@trigger_error(sprintf(
'The "%s" method is deprecated since version 3.x and will be removed in 4.0.',
__METHOD__
), E_USER_DEPRECATED);

if (null === $this->propertyAccessor) {
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
}
Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
new ReferenceConfigurator('sonata.admin.pool'),
new ReferenceConfigurator('validator'),
new ReferenceConfigurator('sonata.admin.form.data_transformer_resolver'),
new ReferenceConfigurator('property_accessor'),
])

->set('sonata.admin.action.retrieve_autocomplete_items', RetrieveAutocompleteItemsAction::class)
Expand Down
3 changes: 2 additions & 1 deletion src/Resources/config/core.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
'',
'',
[],
new ReferenceConfigurator('property_accessor'),
])
->call('setTemplateRegistry', [
new ReferenceConfigurator('sonata.admin.global_template_registry'),
Expand All @@ -76,6 +75,8 @@
->set('sonata.admin.helper', AdminHelper::class)
->public()
->args([
new ReferenceConfigurator('property_accessor'),
// NEXT_MAJOR: Remove next line.
new ReferenceConfigurator('sonata.admin.pool'),
])

Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/twig.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
(new ReferenceConfigurator('logger'))->nullOnInvalid(),
new ReferenceConfigurator('translator'),
new ReferenceConfigurator('service_container'),
new ReferenceConfigurator('property_accessor'),
new ReferenceConfigurator('security.authorization_checker'),
])
->call('setXEditableTypeMapping', [
Expand Down
Loading