mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-08 00:39:50 +00:00
adapt rector rules for chained builder->add
This commit is contained in:
parent
3fb97c3945
commit
c52ba06ea0
@ -183,43 +183,11 @@ PHP */
|
|||||||
if ($stmt instanceof Node\Stmt\Expression
|
if ($stmt instanceof Node\Stmt\Expression
|
||||||
// it must be a method call
|
// it must be a method call
|
||||||
&& $stmt->expr instanceof Node\Expr\MethodCall
|
&& $stmt->expr instanceof Node\Expr\MethodCall
|
||||||
// the method call must be "add"
|
&& false !== ($results = $this->handleMethodCallBuilderAdd($stmt->expr, $builderName))
|
||||||
&& $stmt->expr->name instanceof Node\Identifier
|
|
||||||
&& $stmt->expr->name->name === 'add'
|
|
||||||
// and the method call must apply on the builder (compare with builderName)
|
|
||||||
&& $stmt->expr->var instanceof Node\Expr\Variable
|
|
||||||
&& $stmt->expr->var->name === $builderName
|
|
||||||
// it must have a first argument, a string
|
|
||||||
// TODO what happens if a value, or a const ?
|
|
||||||
&& ($stmt->expr->args[0] ?? null) instanceof Node\Arg
|
|
||||||
&& $stmt->expr->args[0]->value instanceof Node\Scalar\String_
|
|
||||||
// and a third argument, an array
|
|
||||||
&& ($stmt->expr->args[2] ?? null) instanceof Node\Arg
|
|
||||||
&& $stmt->expr->args[2]->value instanceof Node\Expr\Array_
|
|
||||||
) {
|
) {
|
||||||
|
['stmt' => $newMethodCAll, 'emptyDataToReplace' => $newEmptyDataToReplace] = $results;
|
||||||
// we parse on the 3rd argument, to find if there is an 'empty_data' key
|
$newStmts[] = new Node\Stmt\Expression($newMethodCAll);
|
||||||
$emptyDataIndex = null;
|
$emptyDataToReplace = [...$emptyDataToReplace, ...$newEmptyDataToReplace];
|
||||||
foreach ($stmt->expr->args[2]->value->items as $arrayItemIndex => $item) {
|
|
||||||
/* @phpstan-ignore-next-line */
|
|
||||||
if ($item->key->value === 'data') {
|
|
||||||
$k = $stmt->expr->args[0]->value->value;
|
|
||||||
$emptyDataToReplace[$k] = $item->value;
|
|
||||||
$emptyDataIndex = $arrayItemIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null !== $emptyDataIndex) {
|
|
||||||
$stmt->expr->args[2]->value->items = array_values(
|
|
||||||
array_filter(
|
|
||||||
$stmt->expr->args[2]->value->items,
|
|
||||||
/* @phpstan-ignore-next-line */
|
|
||||||
fn (Node\Expr\ArrayItem $item) => $item->key->value !== 'data'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$newStmts[] = $stmt;
|
|
||||||
} else {
|
} else {
|
||||||
$newStmts[] = $stmt;
|
$newStmts[] = $stmt;
|
||||||
}
|
}
|
||||||
@ -229,4 +197,77 @@ PHP */
|
|||||||
|
|
||||||
return ['build_form_method' => $buildFormMethod, "empty_to_replace" => $emptyDataToReplace];
|
return ['build_form_method' => $buildFormMethod, "empty_to_replace" => $emptyDataToReplace];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handleMethodCallBuilderAdd(Node\Expr\MethodCall $methodCall, string $builderName): array|false
|
||||||
|
{
|
||||||
|
$emptyDataToReplace = [];
|
||||||
|
// check for chained method call
|
||||||
|
if (
|
||||||
|
// this means that the MethodCall apply on another method call: a chained
|
||||||
|
$methodCall->var instanceof Node\Expr\MethodCall
|
||||||
|
) {
|
||||||
|
// as this is chained, we make a recursion on this method
|
||||||
|
|
||||||
|
$resultFormDeepMethodCall = $this->handleMethodCallBuilderAdd($methodCall->var, $builderName);
|
||||||
|
|
||||||
|
if (false === $resultFormDeepMethodCall) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
['stmt' => $chainedMethodCall, 'emptyDataToReplace' => $newEmptyDataToReplace] = $resultFormDeepMethodCall;
|
||||||
|
$emptyDataToReplace = $newEmptyDataToReplace;
|
||||||
|
$methodCall->var = $chainedMethodCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$methodCall->var instanceof Node\Expr\Variable
|
||||||
|
) {
|
||||||
|
if ($methodCall->var->name !== $builderName) {
|
||||||
|
// ho, this does not apply on a builder, so we cancel all the method calls
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($methodCall->name instanceof Node\Identifier && $methodCall->name->name !== 'add') {
|
||||||
|
return ['stmt' => $methodCall, 'emptyDataToReplace' => $emptyDataToReplace];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
// the method call must be "add"
|
||||||
|
$methodCall->name instanceof Node\Identifier
|
||||||
|
&& $methodCall->name->name === 'add'
|
||||||
|
// it must have a first argument, a string
|
||||||
|
// TODO what happens if a value, or a const ?
|
||||||
|
&& ($methodCall->args[0] ?? null) instanceof Node\Arg
|
||||||
|
&& $methodCall->args[0]->value instanceof Node\Scalar\String_
|
||||||
|
// and a third argument, an array
|
||||||
|
&& ($methodCall->args[2] ?? null) instanceof Node\Arg
|
||||||
|
&& $methodCall->args[2]->value instanceof Node\Expr\Array_
|
||||||
|
) {
|
||||||
|
// we parse on the 3rd argument, to find if there is an 'empty_data' key
|
||||||
|
$emptyDataIndex = null;
|
||||||
|
foreach ($methodCall->args[2]->value->items as $arrayItemIndex => $item) {
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
if ($item->key->value === 'data' or $item->key->value === 'empty_data') {
|
||||||
|
$k = $methodCall->args[0]->value->value;
|
||||||
|
$emptyDataToReplace[$k] = $item->value;
|
||||||
|
$emptyDataIndex = $arrayItemIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $emptyDataIndex) {
|
||||||
|
$methodCall->args[2]->value->items = array_values(
|
||||||
|
array_filter(
|
||||||
|
$methodCall->args[2]->value->items,
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
fn (Node\Expr\ArrayItem $item) => $item->key->value !== 'data'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['stmt' => $methodCall, 'emptyDataToReplace' => $emptyDataToReplace];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RuntimeException("Not supported situation");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Utils\Rector\Tests\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector\Fixture;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||||
|
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
class MyClass implements FilterInterface
|
||||||
|
{
|
||||||
|
public function describeAction($data, $format = 'string')
|
||||||
|
{
|
||||||
|
// TODO: Implement describeAction() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('foo', PickRollingDateType::class, [
|
||||||
|
'label' => 'Test thing',
|
||||||
|
'data' => new RollingDate(RollingDate::T_TODAY)
|
||||||
|
])
|
||||||
|
->anotherCall('test')
|
||||||
|
->add('baz', TextType::class, [
|
||||||
|
'label' => 'OrNiCar',
|
||||||
|
'data' => 'Castor'
|
||||||
|
])
|
||||||
|
->baz('foo');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
// TODO: Implement getTitle() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRole(): ?string
|
||||||
|
{
|
||||||
|
// TODO: Implement addRole() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
|
{
|
||||||
|
// TODO: Implement alterQuery() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyOn()
|
||||||
|
{
|
||||||
|
// TODO: Implement applyOn() method.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Utils\Rector\Tests\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector\Fixture;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||||
|
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
class MyClass implements FilterInterface
|
||||||
|
{
|
||||||
|
public function describeAction($data, $format = 'string')
|
||||||
|
{
|
||||||
|
// TODO: Implement describeAction() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('foo', PickRollingDateType::class, [
|
||||||
|
'label' => 'Test thing'
|
||||||
|
])
|
||||||
|
->anotherCall('test')
|
||||||
|
->add('baz', TextType::class, [
|
||||||
|
'label' => 'OrNiCar'
|
||||||
|
])
|
||||||
|
->baz('foo');
|
||||||
|
}
|
||||||
|
public function getFormDefaultData(): array
|
||||||
|
{
|
||||||
|
return ['foo' => new RollingDate(RollingDate::T_TODAY), 'baz' => 'Castor'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
// TODO: Implement getTitle() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRole(): ?string
|
||||||
|
{
|
||||||
|
// TODO: Implement addRole() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
|
{
|
||||||
|
// TODO: Implement alterQuery() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyOn()
|
||||||
|
{
|
||||||
|
// TODO: Implement applyOn() method.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
Loading…
x
Reference in New Issue
Block a user