mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 01:08:26 +00:00 
			
		
		
		
	adapt rector rules for chained builder->add
This commit is contained in:
		| @@ -183,43 +183,11 @@ PHP */ | ||||
|             if ($stmt instanceof Node\Stmt\Expression | ||||
|                 // it must be a method call | ||||
|                 && $stmt->expr instanceof Node\Expr\MethodCall | ||||
|                 // the method call must be "add" | ||||
|                 && $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_ | ||||
|                 && false !== ($results = $this->handleMethodCallBuilderAdd($stmt->expr, $builderName)) | ||||
|             ) { | ||||
|  | ||||
|                 // we parse on the 3rd argument, to find if there is an 'empty_data' key | ||||
|                 $emptyDataIndex = null; | ||||
|                 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; | ||||
|                 ['stmt' => $newMethodCAll, 'emptyDataToReplace' => $newEmptyDataToReplace] = $results; | ||||
|                 $newStmts[] = new Node\Stmt\Expression($newMethodCAll); | ||||
|                 $emptyDataToReplace = [...$emptyDataToReplace, ...$newEmptyDataToReplace]; | ||||
|             } else { | ||||
|                 $newStmts[] = $stmt; | ||||
|             } | ||||
| @@ -229,4 +197,77 @@ PHP */ | ||||
|  | ||||
|         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. | ||||
|     } | ||||
| } | ||||
| ?> | ||||
		Reference in New Issue
	
	Block a user