From 264df1f82fb4bd857f994dc1f927c6aa908c36e0 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Mon, 20 Oct 2025 10:17:20 +0000 Subject: [PATCH 01/19] PhpCode as a new Transformer --- config/grid.yaml | 12 ++ src/Grid/Column/Transformer/PhpCode.php | 113 ++++++++++++++++++ .../PhpCode/ExamplePhpCodeTransformer.php | 72 +++++++++++ .../PhpCode/PhpCodeTransformerInterface.php | 40 +++++++ .../PhpCodeTransformerResolverInterface.php | 36 ++++++ .../TaggedPhpCodeTransformerResolver.php | 58 +++++++++ 6 files changed, 331 insertions(+) create mode 100644 src/Grid/Column/Transformer/PhpCode.php create mode 100644 src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php create mode 100644 src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php create mode 100644 src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php create mode 100644 src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php diff --git a/config/grid.yaml b/config/grid.yaml index 4525b2643..f5506fe86 100644 --- a/config/grid.yaml +++ b/config/grid.yaml @@ -62,6 +62,9 @@ services: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Resolver\ResolverTypeGuesserInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Resolver\ResolverTypeGuesser + + Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerResolverInterface: + class: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\TaggedPhpCodeTransformerResolver # # Repository @@ -417,3 +420,12 @@ services: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\Translate: tags: [ 'pimcore.studio_backend.grid_transformer' ] + + Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode: + tags: [ 'pimcore.studio_backend.grid_transformer' ] + + # + # Example Transformer + # + Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\ExamplePhpCodeTransformer: + tags: [ 'pimcore.studio_backend.phpcode_transformer' ] diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php new file mode 100644 index 000000000..62021fcfa --- /dev/null +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -0,0 +1,113 @@ +getName(), + sprintf( + 'Invalid "phpClass" configuration (must be a string) for %s transformer. ', + $this->getKey() + ) + ); + } + + if (isset($arguments) && !is_array($arguments)) { + throw new TransformerException( + $this->getName(), + sprintf( + 'Invalid "arguments" configuration (must be an array if provided) for %s transformer.', + $this->getKey() + ) + ); + } + + $transformer = $this->resolver->resolve($phpClass); + + if (!$transformer) { + throw new TransformerException($this->getName(), "PHP Class '{$phpClass}' not found."); + } + + $results = []; + foreach ($value as $val) { + $transformed = $transformer->transform($val->getValue(), $arguments); + + $results[] = new AdvancedValue( + 'string', + $transformed[0] ?? null, + $val->getFieldName() + ); + } + + return $results; + + } + + public function getName(): string + { + return 'PHP Code'; + } + + public function getKey(): string + { + return 'phpCode'; + } + + public function getDescription(): string + { + return 'Executes tagged PHP services on grid values.'; + } + + public function getConfigOptions(): array + { + $options = []; + + foreach ($this->resolver->getTransformers() as $executable) { + $options[] = [ + 'value' => get_class($executable), + 'label' => $executable->getKey(), + ]; + } + + return [ + 'phpClass' => [ + 'type' => 'select', + 'label' => 'PHP Transformer Class', + 'options' => $options, + ], + 'arguments' => [ + 'type' => 'keyValue', + 'label' => 'Arguments', + 'default' => [], + ], + ]; + } +} diff --git a/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php b/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php new file mode 100644 index 000000000..6df2270ab --- /dev/null +++ b/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php @@ -0,0 +1,72 @@ + [ + 'type' => 'boolean', + 'label' => 'Enable Transformation', + 'default' => true, + ], + 'arguments' => [ + 'type' => 'keyValue', + 'label' => 'Arguments', + 'default' => [], + ], + ]; + } + +} \ No newline at end of file diff --git a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php new file mode 100644 index 000000000..8faa6c962 --- /dev/null +++ b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php @@ -0,0 +1,40 @@ + + */ + public function getTransformers(): iterable; + + /** + * @throws InvalidArgumentException If no matching transformer is found + */ + public function resolve(string $className): PhpCodeTransformerInterface; +} \ No newline at end of file diff --git a/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php b/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php new file mode 100644 index 000000000..5287cbd78 --- /dev/null +++ b/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php @@ -0,0 +1,58 @@ + $transformers + */ + public function __construct( + #[TaggedIterator(self::TRANSFORMER_TAG)] + private iterable $transformers, + ) {} + + /** + * @return iterable + */ + public function getTransformers(): iterable + { + return $this->transformers; + } + + /** + * @throws InvalidArgumentException + */ + public function resolve(string $className): PhpCodeTransformerInterface + { + foreach ($this->transformers as $transformer) { + if (get_class($transformer) === $className) { + return $transformer; + } + } + + throw new InvalidArgumentException( + sprintf('No PhpCode transformer found for class "%s"', $className) + ); + } +} \ No newline at end of file From 5b03ae26f5c8671ccf872a1e45104e3f65051efb Mon Sep 17 00:00:00 2001 From: stunnerparas <49896041+stunnerparas@users.noreply.github.com> Date: Mon, 20 Oct 2025 10:19:51 +0000 Subject: [PATCH 02/19] Apply php-cs-fixer changes --- src/Grid/Column/Transformer/PhpCode.php | 20 +++++++++++-------- .../PhpCode/ExamplePhpCodeTransformer.php | 9 ++++----- .../PhpCodeTransformerResolverInterface.php | 3 +-- .../TaggedPhpCodeTransformerResolver.php | 6 +++--- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index 62021fcfa..a81837829 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -11,19 +11,23 @@ * @license Pimcore Open Core License (POCL) */ - namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\TransformerException; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerResolverInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\TransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Util\AdvancedValue; +use function get_class; +use function is_array; +use function is_string; +use function sprintf; final class PhpCode implements TransformerInterface { public function __construct( - private readonly PhpCodeTransformerResolverInterface $resolver - ) {} + private readonly PhpCodeTransformerResolverInterface $resolver + ) { + } public function transform(array $value, array $config): array { @@ -50,12 +54,12 @@ public function transform(array $value, array $config): array ); } - $transformer = $this->resolver->resolve($phpClass); + $transformer = $this->resolver->resolve($phpClass); if (!$transformer) { throw new TransformerException($this->getName(), "PHP Class '{$phpClass}' not found."); } - + $results = []; foreach ($value as $val) { $transformed = $transformer->transform($val->getValue(), $arguments); @@ -65,9 +69,9 @@ public function transform(array $value, array $config): array $transformed[0] ?? null, $val->getFieldName() ); - } + } - return $results; + return $results; } @@ -93,7 +97,7 @@ public function getConfigOptions(): array foreach ($this->resolver->getTransformers() as $executable) { $options[] = [ 'value' => get_class($executable), - 'label' => $executable->getKey(), + 'label' => $executable->getKey(), ]; } diff --git a/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php b/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php index 6df2270ab..900eae8f1 100644 --- a/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php +++ b/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php @@ -13,9 +13,10 @@ */ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode; + use Pimcore\Bundle\StudioBackendBundle\Grid\Util\AdvancedValue; -use Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerInterface; +use function is_string; /** * @internal @@ -33,7 +34,7 @@ public function transform(mixed $value, array $arguments): array 'string', $transformed, 'null' - ) + ), ]; } @@ -52,7 +53,6 @@ public function getDescription(): string return 'Transforms string values to uppercase for demonstration purposes.'; } - public function getConfigOptions(): array { return [ @@ -68,5 +68,4 @@ public function getConfigOptions(): array ], ]; } - -} \ No newline at end of file +} diff --git a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php index 373905468..c2a5ea60b 100644 --- a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php +++ b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php @@ -15,7 +15,6 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; -use Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerInterface; /** * @internal @@ -33,4 +32,4 @@ public function getTransformers(): iterable; * @throws InvalidArgumentException If no matching transformer is found */ public function resolve(string $className): PhpCodeTransformerInterface; -} \ No newline at end of file +} diff --git a/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php b/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php index 5287cbd78..44cf032a8 100644 --- a/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php +++ b/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php @@ -14,7 +14,6 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; -use Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerInterface; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use function get_class; use function sprintf; @@ -30,7 +29,8 @@ public function __construct( #[TaggedIterator(self::TRANSFORMER_TAG)] private iterable $transformers, - ) {} + ) { + } /** * @return iterable @@ -55,4 +55,4 @@ public function resolve(string $className): PhpCodeTransformerInterface sprintf('No PhpCode transformer found for class "%s"', $className) ); } -} \ No newline at end of file +} From 08b51a6fc34667e2c938456b7f194e6a77053e42 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Mon, 20 Oct 2025 10:26:32 +0000 Subject: [PATCH 03/19] Updating the docs --- doc/03_Grid.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/doc/03_Grid.md b/doc/03_Grid.md index 948f71b68..680ce3641 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -522,4 +522,53 @@ The `Translate` transformer translates a given value using Symfony’s Translato } } ... -``` \ No newline at end of file +``` + +#### PhpCode Transformer + +The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. You can specify the class to use via its fully qualified name (phpClass) and pass custom arguments to control its behavior. This is ideal for advanced use cases where transformation logic depends on external services, dynamic configuration, or custom business rules. + +--- + +**Available Configurations:** + +- `phpClass`: The fully qualified class name of the transformer to execute. Must implement PhpCodeTransformerInterface. +- `arguments`: A key-value map of arguments passed to the transformer. These can be used to customize the transformation logic. + +--- + + +**Example Configuration:** + +```json +{ + "key": "phpCodeTransformedName", + "locale": "en", + "type": "dataobject.advanced", + "config": { + "title": "PHP Code Transformed Name", + "advancedColumns": [ + { + "key": "simpleField", + "config": { + "field": "name" + } + } + ], + "transformers": [ + { + "key": "phpCode", + "config": { + "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\PhpCode\\ExamplePhpCodeTransformer", + "arguments": { + "first": "argument1", + "second": "argument2" + } + } + } + ] + } +} + +... +``` From 06723c2cb053cf7eb69f51bf406c8298d0362664 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Mon, 20 Oct 2025 10:31:41 +0000 Subject: [PATCH 04/19] Fix ci issue --- src/Grid/Column/Transformer/PhpCode.php | 2 +- .../Transformer/PhpCode/PhpCodeTransformerInterface.php | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index a81837829..7038d3fbc 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -44,7 +44,7 @@ public function transform(array $value, array $config): array ); } - if (isset($arguments) && !is_array($arguments)) { + if (!is_array($arguments)) { throw new TransformerException( $this->getName(), sprintf( diff --git a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php index 8faa6c962..f0f8c1015 100644 --- a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php +++ b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php @@ -22,10 +22,8 @@ interface PhpCodeTransformerInterface { /** - * Transforms a value of the advanced column in the grid. - * - * @param AdvancedValue[] $value - * + * @param mixed $value + * @param array $arguments * @return AdvancedValue[] */ public function transform(mixed $value, array $arguments): array; From e2f68c37059fa3f15aebf8acaf9b149dad63979e Mon Sep 17 00:00:00 2001 From: stunnerparas <49896041+stunnerparas@users.noreply.github.com> Date: Mon, 20 Oct 2025 10:32:30 +0000 Subject: [PATCH 05/19] Apply php-cs-fixer changes --- .../Column/Transformer/PhpCode/PhpCodeTransformerInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php index f0f8c1015..2201c0fd5 100644 --- a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php +++ b/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php @@ -24,6 +24,7 @@ interface PhpCodeTransformerInterface /** * @param mixed $value * @param array $arguments + * * @return AdvancedValue[] */ public function transform(mixed $value, array $arguments): array; From 2b423c6fbc0c2e600ec2effc06b7d5a1b3a1c789 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Mon, 20 Oct 2025 10:41:56 +0000 Subject: [PATCH 06/19] Minor fixees --- src/Grid/Column/Transformer/PhpCode.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index 7038d3fbc..8ed45a10e 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -56,10 +56,6 @@ public function transform(array $value, array $config): array $transformer = $this->resolver->resolve($phpClass); - if (!$transformer) { - throw new TransformerException($this->getName(), "PHP Class '{$phpClass}' not found."); - } - $results = []; foreach ($value as $val) { $transformed = $transformer->transform($val->getValue(), $arguments); From ad7837a7ebdf65a862ca2a7d326071a59b04ddc0 Mon Sep 17 00:00:00 2001 From: Martin Eiber Date: Mon, 20 Oct 2025 13:17:15 +0200 Subject: [PATCH 07/19] [Grid] Inheritance of Classification Store Delivers an array of InheritanceData (#1462) --- src/Grid/Column/Resolver/DataObject/AdapterResolver.php | 2 +- .../Resolver/DataObject/ClassificationStoreResolver.php | 2 +- src/Grid/Schema/ColumnData.php | 4 ++-- src/Grid/Util/Trait/ColumnDataTrait.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Grid/Column/Resolver/DataObject/AdapterResolver.php b/src/Grid/Column/Resolver/DataObject/AdapterResolver.php index 8b39c3855..3a3d6c1b5 100644 --- a/src/Grid/Column/Resolver/DataObject/AdapterResolver.php +++ b/src/Grid/Column/Resolver/DataObject/AdapterResolver.php @@ -115,7 +115,7 @@ public function supportedElementTypes(): array ]; } - private function getInheritanceData(Concrete $element, Data $fieldDefinition, string $field): InheritanceData + private function getInheritanceData(Concrete $element, Data $fieldDefinition, string $field): array|InheritanceData { return $this->dataObjectServiceResolver->useInheritedValues( false, diff --git a/src/Grid/Column/Resolver/DataObject/ClassificationStoreResolver.php b/src/Grid/Column/Resolver/DataObject/ClassificationStoreResolver.php index a8928e052..6529151d4 100644 --- a/src/Grid/Column/Resolver/DataObject/ClassificationStoreResolver.php +++ b/src/Grid/Column/Resolver/DataObject/ClassificationStoreResolver.php @@ -82,7 +82,7 @@ public function resolveForCoreElement(Column $column, ElementInterface $element) locale: $column->getLocale(), value: $value, fieldType: $keyGroupRelation->getType(), - inheritance: $normalizedData->getInheritance(), + inheritance: $normalizedData->getInheritance()[$config->getGroupId()][$locale][$config->getKeyId()], ); $returnData->addAdditionalAttribute('groupId', $config->getGroupId()); diff --git a/src/Grid/Schema/ColumnData.php b/src/Grid/Schema/ColumnData.php index e73a1b2d4..6f9cc6f60 100644 --- a/src/Grid/Schema/ColumnData.php +++ b/src/Grid/Schema/ColumnData.php @@ -42,7 +42,7 @@ public function __construct( example: ['objectId' => 42, 'inInherited' => true], nullable: true )] - private readonly ?InheritanceData $inheritance = null + private readonly null|InheritanceData|array $inheritance = null ) { } @@ -66,7 +66,7 @@ public function getValue(): mixed return $this->value; } - public function getInheritance(): ?InheritanceData + public function getInheritance(): null|InheritanceData|array { return $this->inheritance; } diff --git a/src/Grid/Util/Trait/ColumnDataTrait.php b/src/Grid/Util/Trait/ColumnDataTrait.php index 691d42dca..b8a9f6969 100644 --- a/src/Grid/Util/Trait/ColumnDataTrait.php +++ b/src/Grid/Util/Trait/ColumnDataTrait.php @@ -23,7 +23,7 @@ private function getColumnData( Column $column, mixed $value, string $fieldType, - ?InheritanceData $inheritanceData = null + null|InheritanceData|array $inheritanceData = null ): ColumnData { return new ColumnData($column->getKey(), $column->getLocale(), $value, $fieldType, $inheritanceData); } From 76f31a4d25cb27a0abcdd05656bcf77b0cf529df Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Tue, 21 Oct 2025 13:08:43 +0000 Subject: [PATCH 08/19] Organize the naming convention and minor code adjustment --- config/grid.yaml | 10 +-- doc/03_Grid.md | 19 +++-- .../PhpCodeTransformerInterface.php | 7 +- src/Grid/Column/Transformer/PhpCode.php | 39 +++------- .../PhpCode/ExamplePhpCodeTransformer.php | 71 ------------------- ...aggedIteratorPhpCodeTransformerLoader.php} | 6 +- .../PhpCodeTransformerLoaderInterface.php} | 5 +- 7 files changed, 31 insertions(+), 126 deletions(-) rename src/Grid/Column/{Transformer/PhpCode => }/PhpCodeTransformerInterface.php (81%) delete mode 100644 src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php rename src/Grid/{Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php => Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php} (80%) rename src/Grid/{Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php => Service/PhpCodeTransformerLoaderInterface.php} (82%) diff --git a/config/grid.yaml b/config/grid.yaml index f5506fe86..c5215c2ca 100644 --- a/config/grid.yaml +++ b/config/grid.yaml @@ -60,11 +60,12 @@ services: Pimcore\Bundle\StudioBackendBundle\Grid\Service\ColumnConfigurationForRelationServiceInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\ColumnConfigurationForRelationService + Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface: + class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\Loader\TaggedIteratorPhpCodeTransformerLoader + Pimcore\Bundle\StudioBackendBundle\Grid\Column\Resolver\ResolverTypeGuesserInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Resolver\ResolverTypeGuesser - Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerResolverInterface: - class: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\TaggedPhpCodeTransformerResolver # # Repository @@ -424,8 +425,3 @@ services: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode: tags: [ 'pimcore.studio_backend.grid_transformer' ] - # - # Example Transformer - # - Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\ExamplePhpCodeTransformer: - tags: [ 'pimcore.studio_backend.phpcode_transformer' ] diff --git a/doc/03_Grid.md b/doc/03_Grid.md index 680ce3641..0c70e52c7 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -533,7 +533,6 @@ The `PhpCode` transformer delegates value transformation to a custom PHP class i **Available Configurations:** - `phpClass`: The fully qualified class name of the transformer to execute. Must implement PhpCodeTransformerInterface. -- `arguments`: A key-value map of arguments passed to the transformer. These can be used to customize the transformation logic. --- @@ -556,17 +555,15 @@ The `PhpCode` transformer delegates value transformation to a custom PHP class i } ], "transformers": [ - { - "key": "phpCode", - "config": { - "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\PhpCode\\ExamplePhpCodeTransformer", - "arguments": { - "first": "argument1", - "second": "argument2" + { + "key": "phpCode", + "config": { + "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\PhpCode\\ExamplePhpCodeTransformer", + "firstValue": "firstValue", + "secondValue": "secondValue" + } } - } - } - ] + ] } } diff --git a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php b/src/Grid/Column/PhpCodeTransformerInterface.php similarity index 81% rename from src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php rename to src/Grid/Column/PhpCodeTransformerInterface.php index 2201c0fd5..ad8355f56 100644 --- a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerInterface.php +++ b/src/Grid/Column/PhpCodeTransformerInterface.php @@ -12,13 +12,10 @@ * @license Pimcore Open Core License (POCL) */ -namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode; +namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column; use Pimcore\Bundle\StudioBackendBundle\Grid\Util\AdvancedValue; -/** - * @internal - */ interface PhpCodeTransformerInterface { /** @@ -27,7 +24,7 @@ interface PhpCodeTransformerInterface * * @return AdvancedValue[] */ - public function transform(mixed $value, array $arguments): array; + public function transform(array $value, array $config): array; public function getName(): string; diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index 8ed45a10e..0e6df1def 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -14,25 +14,25 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\TransformerException; -use Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode\PhpCodeTransformerResolverInterface; +use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\TransformerInterface; -use Pimcore\Bundle\StudioBackendBundle\Grid\Util\AdvancedValue; use function get_class; -use function is_array; use function is_string; use function sprintf; +/** + * @internal + */ final class PhpCode implements TransformerInterface { public function __construct( - private readonly PhpCodeTransformerResolverInterface $resolver + private readonly PhpCodeTransformerLoaderInterface $resolver ) { } public function transform(array $value, array $config): array { - $phpClass = $config['phpClass'] ?? null; - $arguments = $config['arguments'] ?? []; + $phpClass = $config['phpClass'] ?? null; if (!isset($phpClass) || !is_string($phpClass)) { throw new TransformerException( @@ -43,30 +43,13 @@ public function transform(array $value, array $config): array ) ); } - - if (!is_array($arguments)) { - throw new TransformerException( - $this->getName(), - sprintf( - 'Invalid "arguments" configuration (must be an array if provided) for %s transformer.', - $this->getKey() - ) - ); - } - + + //Check if class exists $transformer = $this->resolver->resolve($phpClass); - $results = []; - foreach ($value as $val) { - $transformed = $transformer->transform($val->getValue(), $arguments); - - $results[] = new AdvancedValue( - 'string', - $transformed[0] ?? null, - $val->getFieldName() - ); - } - + //Transform the entire value and return result + $results = $transformer->transform($value, $config); + return $results; } diff --git a/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php b/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php deleted file mode 100644 index 900eae8f1..000000000 --- a/src/Grid/Column/Transformer/PhpCode/ExamplePhpCodeTransformer.php +++ /dev/null @@ -1,71 +0,0 @@ - [ - 'type' => 'boolean', - 'label' => 'Enable Transformation', - 'default' => true, - ], - 'arguments' => [ - 'type' => 'keyValue', - 'label' => 'Arguments', - 'default' => [], - ], - ]; - } -} diff --git a/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php similarity index 80% rename from src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php rename to src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php index 44cf032a8..937ed2faa 100644 --- a/src/Grid/Column/Transformer/PhpCode/TaggedPhpCodeTransformerResolver.php +++ b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php @@ -11,8 +11,10 @@ * @license Pimcore Open Core License (POCL) */ -namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode; +namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service\Loader; +use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; +use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use function get_class; @@ -21,7 +23,7 @@ /** * @internal */ -final readonly class TaggedPhpCodeTransformerResolver implements PhpCodeTransformerResolverInterface +final readonly class TaggedIteratorPhpCodeTransformerLoader implements PhpCodeTransformerLoaderInterface { /** * @param iterable $transformers diff --git a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php similarity index 82% rename from src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php rename to src/Grid/Service/PhpCodeTransformerLoaderInterface.php index c2a5ea60b..61a82e6d3 100644 --- a/src/Grid/Column/Transformer/PhpCode/PhpCodeTransformerResolverInterface.php +++ b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php @@ -12,14 +12,15 @@ * @license Pimcore Open Core License (POCL) */ -namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer\PhpCode; +namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service; +use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; /** * @internal */ -interface PhpCodeTransformerResolverInterface +interface PhpCodeTransformerLoaderInterface { public const TRANSFORMER_TAG = 'pimcore.studio_backend.phpcode_transformer'; From b01189c6badb3fb60ae9a0220a17d125dc52eaa7 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Wed, 22 Oct 2025 07:31:46 +0000 Subject: [PATCH 09/19] Added Php code new end point and minor adjustments --- config/grid.yaml | 3 + doc/03_Grid.md | 5 +- .../Grid/GetPhpCodeTransformerController.php | 80 +++++++++++++++++++ .../PhpCodeTransformerCollectionException.php | 27 +++++++ .../Column/PhpCodeTransformerInterface.php | 4 +- .../Service/PhpCodeTransformerCollector.php | 56 +++++++++++++ .../PhpCodeTransformerCollectorInterface.php | 26 ++++++ translations/studio_api_docs.en.yaml | 5 ++ 8 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php create mode 100644 src/Exception/Api/PhpCodeTransformerCollectionException.php create mode 100644 src/Grid/Service/PhpCodeTransformerCollector.php create mode 100644 src/Grid/Service/PhpCodeTransformerCollectorInterface.php diff --git a/config/grid.yaml b/config/grid.yaml index c5215c2ca..a6efc7201 100644 --- a/config/grid.yaml +++ b/config/grid.yaml @@ -60,6 +60,9 @@ services: Pimcore\Bundle\StudioBackendBundle\Grid\Service\ColumnConfigurationForRelationServiceInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\ColumnConfigurationForRelationService + Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerCollectorInterface: + class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerCollector + Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\Loader\TaggedIteratorPhpCodeTransformerLoader diff --git a/doc/03_Grid.md b/doc/03_Grid.md index 0c70e52c7..3e68c4cdd 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -528,6 +528,9 @@ The `Translate` transformer translates a given value using Symfony’s Translato The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. You can specify the class to use via its fully qualified name (phpClass) and pass custom arguments to control its behavior. This is ideal for advanced use cases where transformation logic depends on external services, dynamic configuration, or custom business rules. +To get the list of available PHP Transformer classes, you can call the following endpoint: +`GET /pimcore-studio/api//data-objects/grid/transformers/services/phpcode` + --- **Available Configurations:** @@ -558,7 +561,7 @@ The `PhpCode` transformer delegates value transformation to a custom PHP class i { "key": "phpCode", "config": { - "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\PhpCode\\ExamplePhpCodeTransformer", + "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\ExamplePhpCodeTransformer", "firstValue": "firstValue", "secondValue": "secondValue" } diff --git a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php new file mode 100644 index 000000000..a43943f08 --- /dev/null +++ b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php @@ -0,0 +1,80 @@ +value] + )] + #[SuccessResponse( + description: 'data_object_get_phpcode_transformers_success_response', + content: new JsonContent( + properties: [ + new Property(property: 'transformers', type: 'array', items: new Items( + properties: [ + new Property(property: 'key', type: 'string'), + new Property(property: 'label', type: 'string'), + new Property(property: 'description', type: 'string'), + ] + )) + ] + ) + )] + #[DefaultResponses([ + HttpResponseCodes::UNAUTHORIZED, + HttpResponseCodes::NOT_FOUND, + ])] + public function getPhpCodeTransformers(): JsonResponse + { + return $this->jsonResponse([ + 'transformers' => $this->collector->collect(), + ]); + } + +} \ No newline at end of file diff --git a/src/Exception/Api/PhpCodeTransformerCollectionException.php b/src/Exception/Api/PhpCodeTransformerCollectionException.php new file mode 100644 index 000000000..534496d7d --- /dev/null +++ b/src/Exception/Api/PhpCodeTransformerCollectionException.php @@ -0,0 +1,27 @@ +value, $message); + } +} diff --git a/src/Grid/Column/PhpCodeTransformerInterface.php b/src/Grid/Column/PhpCodeTransformerInterface.php index ad8355f56..422669848 100644 --- a/src/Grid/Column/PhpCodeTransformerInterface.php +++ b/src/Grid/Column/PhpCodeTransformerInterface.php @@ -19,8 +19,8 @@ interface PhpCodeTransformerInterface { /** - * @param mixed $value - * @param array $arguments + * @param array $value + * @param array $config * * @return AdvancedValue[] */ diff --git a/src/Grid/Service/PhpCodeTransformerCollector.php b/src/Grid/Service/PhpCodeTransformerCollector.php new file mode 100644 index 000000000..413b1be14 --- /dev/null +++ b/src/Grid/Service/PhpCodeTransformerCollector.php @@ -0,0 +1,56 @@ +loader->getTransformers() as $transformer) { + if (!method_exists($transformer, 'getKey') || !method_exists($transformer, 'getName')) { + throw new PhpCodeTransformerCollectionException( + sprintf( + 'Invalid transformer: class "%s" must implement getKey() and getName() methods.', + get_class($transformer) + ) + ); + } + + $transformers[] = [ + 'key' => $transformer->getKey(), + 'label' => $transformer->getName(), + 'description' => $transformer->getDescription(), + 'class' => get_class($transformer), + ]; + } + + return $transformers; + } +} diff --git a/src/Grid/Service/PhpCodeTransformerCollectorInterface.php b/src/Grid/Service/PhpCodeTransformerCollectorInterface.php new file mode 100644 index 000000000..9d6a669af --- /dev/null +++ b/src/Grid/Service/PhpCodeTransformerCollectorInterface.php @@ -0,0 +1,26 @@ + Date: Wed, 22 Oct 2025 07:48:56 +0000 Subject: [PATCH 10/19] Apply php-cs-fixer changes --- .../Grid/GetPhpCodeTransformerController.php | 13 ++++++------- src/Grid/Column/Transformer/PhpCode.php | 6 +++--- .../TaggedIteratorPhpCodeTransformerLoader.php | 2 +- src/Grid/Service/PhpCodeTransformerCollector.php | 4 +++- .../Service/PhpCodeTransformerLoaderInterface.php | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php index a43943f08..6f580819c 100644 --- a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php +++ b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php @@ -8,20 +8,20 @@ * Full copyright and license information is available in * LICENSE.md which is distributed with this source code. * - * @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com) - * @license Pimcore Open Core License (POCL) + * @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com) + * @license Pimcore Open Core License (POCL) */ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Controller\Grid; use OpenApi\Attributes\Get; -use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\Items; +use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\Property; use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController; use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerCollectorInterface; -use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses; +use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags; use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes; use Symfony\Component\HttpFoundation\JsonResponse; @@ -62,7 +62,7 @@ public function __construct( new Property(property: 'label', type: 'string'), new Property(property: 'description', type: 'string'), ] - )) + )), ] ) )] @@ -76,5 +76,4 @@ public function getPhpCodeTransformers(): JsonResponse 'transformers' => $this->collector->collect(), ]); } - -} \ No newline at end of file +} diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index 0e6df1def..9be5887a8 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -14,8 +14,8 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\TransformerException; -use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\TransformerInterface; +use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use function get_class; use function is_string; use function sprintf; @@ -43,13 +43,13 @@ public function transform(array $value, array $config): array ) ); } - + //Check if class exists $transformer = $this->resolver->resolve($phpClass); //Transform the entire value and return result $results = $transformer->transform($value, $config); - + return $results; } diff --git a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php index 937ed2faa..4dafe00eb 100644 --- a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php +++ b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php @@ -13,9 +13,9 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service\Loader; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; -use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use function get_class; use function sprintf; diff --git a/src/Grid/Service/PhpCodeTransformerCollector.php b/src/Grid/Service/PhpCodeTransformerCollector.php index 413b1be14..4ba5e90ec 100644 --- a/src/Grid/Service/PhpCodeTransformerCollector.php +++ b/src/Grid/Service/PhpCodeTransformerCollector.php @@ -15,6 +15,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\PhpCodeTransformerCollectionException; +use function get_class; use function sprintf; /** @@ -24,7 +25,8 @@ final class PhpCodeTransformerCollector implements PhpCodeTransformerCollectorIn { public function __construct( private readonly PhpCodeTransformerLoaderInterface $loader, - ) {} + ) { + } /** * @throws PhpCodeTransformerCollectionException diff --git a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php index 61a82e6d3..a4ac1eba2 100644 --- a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php +++ b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php @@ -14,8 +14,8 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service; -use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; +use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; /** * @internal From 6377a3dcc9dbd37d3abb36bad0c0b7106fcd69ca Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Wed, 22 Oct 2025 08:12:10 +0000 Subject: [PATCH 11/19] Fix issue --- src/Grid/Service/PhpCodeTransformerCollectorInterface.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Grid/Service/PhpCodeTransformerCollectorInterface.php b/src/Grid/Service/PhpCodeTransformerCollectorInterface.php index 9d6a669af..05ab54a9d 100644 --- a/src/Grid/Service/PhpCodeTransformerCollectorInterface.php +++ b/src/Grid/Service/PhpCodeTransformerCollectorInterface.php @@ -14,6 +14,8 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\PhpCodeTransformerCollectionException; + /** * @internal */ From 0585a640dfaff339ea5656007ff6fefea04a6a2c Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Thu, 23 Oct 2025 13:02:51 +0000 Subject: [PATCH 12/19] Managing flow from taggedservice,compilerpass, loader, service and api --- config/grid.yaml | 7 +- doc/03_Grid.md | 11 +--- doc/05_Additional_Custom_Attributes.md | 3 +- .../Grid/GetPhpCodeTransformerController.php | 42 ++++++------ .../PreResponse/PhpCodeTransformerEvent.php | 34 ++++++++++ src/DataObject/Schema/PhpCodeTransformer.php | 59 +++++++++++++++++ .../Service/PhpCodeTransformerService.php | 66 +++++++++++++++++++ .../PhpCodeTransformerServiceInterface.php} | 12 ++-- .../CompilerPass/PhpCodeTransformerPass.php | 46 +++++++++++++ .../Column/PhpCodeTransformerInterface.php | 4 -- .../Transformer/ExamplePhpCodeTransformer.php | 51 ++++++++++++++ ...TaggedIteratorPhpCodeTransformerLoader.php | 13 ++-- .../Service/PhpCodeTransformerCollector.php | 58 ---------------- .../PhpCodeTransformerLoaderInterface.php | 2 +- src/PimcoreStudioBackendBundle.php | 2 + 15 files changed, 299 insertions(+), 111 deletions(-) create mode 100644 src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php create mode 100644 src/DataObject/Schema/PhpCodeTransformer.php create mode 100644 src/DataObject/Service/PhpCodeTransformerService.php rename src/{Grid/Service/PhpCodeTransformerCollectorInterface.php => DataObject/Service/PhpCodeTransformerServiceInterface.php} (56%) create mode 100644 src/DependencyInjection/CompilerPass/PhpCodeTransformerPass.php create mode 100644 src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php delete mode 100644 src/Grid/Service/PhpCodeTransformerCollector.php diff --git a/config/grid.yaml b/config/grid.yaml index a6efc7201..383f60622 100644 --- a/config/grid.yaml +++ b/config/grid.yaml @@ -60,15 +60,14 @@ services: Pimcore\Bundle\StudioBackendBundle\Grid\Service\ColumnConfigurationForRelationServiceInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\ColumnConfigurationForRelationService - Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerCollectorInterface: - class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerCollector - Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Service\Loader\TaggedIteratorPhpCodeTransformerLoader Pimcore\Bundle\StudioBackendBundle\Grid\Column\Resolver\ResolverTypeGuesserInterface: class: Pimcore\Bundle\StudioBackendBundle\Grid\Column\Resolver\ResolverTypeGuesser - + + Pimcore\Bundle\StudioBackendBundle\DataObject\Service\PhpCodeTransformerServiceInterface: + class: Pimcore\Bundle\StudioBackendBundle\DataObject\Service\PhpCodeTransformerService # # Repository diff --git a/doc/03_Grid.md b/doc/03_Grid.md index 3e68c4cdd..ec799ea39 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -526,11 +526,7 @@ The `Translate` transformer translates a given value using Symfony’s Translato #### PhpCode Transformer -The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. You can specify the class to use via its fully qualified name (phpClass) and pass custom arguments to control its behavior. This is ideal for advanced use cases where transformation logic depends on external services, dynamic configuration, or custom business rules. - -To get the list of available PHP Transformer classes, you can call the following endpoint: -`GET /pimcore-studio/api//data-objects/grid/transformers/services/phpcode` - +The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. You can specify the class to use via its fully qualified name (phpClass) and pass custom arguments to control its behavior. This is ideal for advanced use cases where transformation logic depends on external services, dynamic configuration, or custom business rules. --- **Available Configurations:** @@ -539,7 +535,6 @@ To get the list of available PHP Transformer classes, you can call the following --- - **Example Configuration:** ```json @@ -562,8 +557,6 @@ To get the list of available PHP Transformer classes, you can call the following "key": "phpCode", "config": { "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\ExamplePhpCodeTransformer", - "firstValue": "firstValue", - "secondValue": "secondValue" } } ] @@ -571,4 +564,4 @@ To get the list of available PHP Transformer classes, you can call the following } ... -``` +``` \ No newline at end of file diff --git a/doc/05_Additional_Custom_Attributes.md b/doc/05_Additional_Custom_Attributes.md index 15753af76..73bd83586 100644 --- a/doc/05_Additional_Custom_Attributes.md +++ b/doc/05_Additional_Custom_Attributes.md @@ -156,4 +156,5 @@ final class AssetEvent extends AbstractPreResponseEvent - `pre_response.version` - `pre_response.website_settings.item` - `pre_response.workflow_details` -- `pre_response.notification_recipient` \ No newline at end of file +- `pre_response.notification_recipient` +- `pre_response.php_code_transformer` \ No newline at end of file diff --git a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php index 6f580819c..41764e871 100644 --- a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php +++ b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php @@ -1,5 +1,4 @@ value)] #[Get( path: self::PREFIX . '/data-objects/grid/transformers/services/phpcode', operationId: 'data_object_get_phpcode_transformers', @@ -53,18 +57,8 @@ public function __construct( tags: [Tags::DataObjectsGrid->value] )] #[SuccessResponse( - description: 'data_object_get_phpcode_transformers_success_response', - content: new JsonContent( - properties: [ - new Property(property: 'transformers', type: 'array', items: new Items( - properties: [ - new Property(property: 'key', type: 'string'), - new Property(property: 'label', type: 'string'), - new Property(property: 'description', type: 'string'), - ] - )), - ] - ) + description: 'data_object_get_phpcode_transformers_success_response', + content: new CollectionJson(new GenericCollection(PhpCodeTransformer::class)) )] #[DefaultResponses([ HttpResponseCodes::UNAUTHORIZED, @@ -72,8 +66,12 @@ public function __construct( ])] public function getPhpCodeTransformers(): JsonResponse { - return $this->jsonResponse([ - 'transformers' => $this->collector->collect(), - ]); + $collection = $this->phpCodeTransformerService->getPhpCodeTransformers(); + + return $this->getPaginatedCollection( + $this->serializer, + $collection->getItems(), + $collection->getTotalItems() + ); } } diff --git a/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php b/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php new file mode 100644 index 000000000..e2355635f --- /dev/null +++ b/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php @@ -0,0 +1,34 @@ +transformer); + } + + public function getTransformer(): PhpCodeTransformer + { + return $this->transformer; + } +} diff --git a/src/DataObject/Schema/PhpCodeTransformer.php b/src/DataObject/Schema/PhpCodeTransformer.php new file mode 100644 index 000000000..12289b196 --- /dev/null +++ b/src/DataObject/Schema/PhpCodeTransformer.php @@ -0,0 +1,59 @@ +key; + } + + public function getLabel(): string + { + return $this->label; + } + + public function getClass(): string + { + return $this->class; + } + +} diff --git a/src/DataObject/Service/PhpCodeTransformerService.php b/src/DataObject/Service/PhpCodeTransformerService.php new file mode 100644 index 000000000..01b669f5e --- /dev/null +++ b/src/DataObject/Service/PhpCodeTransformerService.php @@ -0,0 +1,66 @@ +getTransformerCollection($this->loader->getTransformers()); + } + + /** + * Converts an array of transformers into a Collection of PhpCodeTransformer DTOs + * + * @param iterable $transformers Raw transformer objects + * + */ + private function getTransformerCollection(iterable $transformers): Collection + { + $items = []; + + foreach ($transformers as $transformer) { + $item = new PhpCodeTransformer( + key: $transformer->getKey(), + label: $transformer->getName(), + class: get_class($transformer) + ); + + $this->eventDispatcher->dispatch( + new PhpCodeTransformerEvent($item), + PhpCodeTransformerEvent::EVENT_NAME + ); + + $items[] = $item; + } + + return new Collection(count($items), $items); + } +} diff --git a/src/Grid/Service/PhpCodeTransformerCollectorInterface.php b/src/DataObject/Service/PhpCodeTransformerServiceInterface.php similarity index 56% rename from src/Grid/Service/PhpCodeTransformerCollectorInterface.php rename to src/DataObject/Service/PhpCodeTransformerServiceInterface.php index 05ab54a9d..4b3493fcb 100644 --- a/src/Grid/Service/PhpCodeTransformerCollectorInterface.php +++ b/src/DataObject/Service/PhpCodeTransformerServiceInterface.php @@ -1,5 +1,4 @@ findTaggedServiceIds(TaggedIteratorPhpCodeTransformerLoader::PHPCODE_TRANSFORMER_TAG), + + ] + ); + + foreach ($taggedServices as $environmentType) { + $this->checkInterface($environmentType, PhpCodeTransformerInterface::class); + } + } +} diff --git a/src/Grid/Column/PhpCodeTransformerInterface.php b/src/Grid/Column/PhpCodeTransformerInterface.php index 422669848..b664dad79 100644 --- a/src/Grid/Column/PhpCodeTransformerInterface.php +++ b/src/Grid/Column/PhpCodeTransformerInterface.php @@ -29,8 +29,4 @@ public function transform(array $value, array $config): array; public function getName(): string; public function getKey(): string; - - public function getDescription(): string; - - public function getConfigOptions(): array; } diff --git a/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php b/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php new file mode 100644 index 000000000..a0385b1b8 --- /dev/null +++ b/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php @@ -0,0 +1,51 @@ + $transformers */ public function __construct( - #[TaggedIterator(self::TRANSFORMER_TAG)] + #[TaggedIterator(self::PHPCODE_TRANSFORMER_TAG)] private iterable $transformers, ) { } /** - * @return iterable + * * @return array */ - public function getTransformers(): iterable + public function getTransformers(): array { - return $this->transformers; + $transformers = []; + foreach ($this->transformers as $transformer) { + $transformers[$transformer->getKey()] = $transformer; + } + + return $transformers; } /** diff --git a/src/Grid/Service/PhpCodeTransformerCollector.php b/src/Grid/Service/PhpCodeTransformerCollector.php deleted file mode 100644 index 4ba5e90ec..000000000 --- a/src/Grid/Service/PhpCodeTransformerCollector.php +++ /dev/null @@ -1,58 +0,0 @@ -loader->getTransformers() as $transformer) { - if (!method_exists($transformer, 'getKey') || !method_exists($transformer, 'getName')) { - throw new PhpCodeTransformerCollectionException( - sprintf( - 'Invalid transformer: class "%s" must implement getKey() and getName() methods.', - get_class($transformer) - ) - ); - } - - $transformers[] = [ - 'key' => $transformer->getKey(), - 'label' => $transformer->getName(), - 'description' => $transformer->getDescription(), - 'class' => get_class($transformer), - ]; - } - - return $transformers; - } -} diff --git a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php index a4ac1eba2..a4043ccd5 100644 --- a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php +++ b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php @@ -22,7 +22,7 @@ */ interface PhpCodeTransformerLoaderInterface { - public const TRANSFORMER_TAG = 'pimcore.studio_backend.phpcode_transformer'; + public const PHPCODE_TRANSFORMER_TAG = 'pimcore.studio_backend.phpcode_transformer'; /** * @return iterable diff --git a/src/PimcoreStudioBackendBundle.php b/src/PimcoreStudioBackendBundle.php index 55d68a257..5e4479f95 100644 --- a/src/PimcoreStudioBackendBundle.php +++ b/src/PimcoreStudioBackendBundle.php @@ -28,6 +28,7 @@ use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\PatchAdapterPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\SettingsProviderPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\TransformerPass; +use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\PhpCodeTransformerPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\UpdateAdapterPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\PimcoreStudioBackendExtension; use Pimcore\Extension\Bundle\AbstractPimcoreBundle; @@ -92,6 +93,7 @@ public function build(ContainerBuilder $container): void $container->addCompilerPass(new MercureTopicsProviderPass()); $container->addCompilerPass(new FieldDefinitionResolverPass()); $container->addCompilerPass(new TransformerPass()); + $container->addCompilerPass(new PhpCodeTransformerPass()); $container->addCompilerPass(new DocumentTypeAdapterPass()); } From f69708dcd5b16715a4cd1e3fc6ec89cc6bf262cf Mon Sep 17 00:00:00 2001 From: stunnerparas <49896041+stunnerparas@users.noreply.github.com> Date: Thu, 23 Oct 2025 13:12:49 +0000 Subject: [PATCH 13/19] Apply php-cs-fixer changes --- .../Controller/Grid/GetPhpCodeTransformerController.php | 7 ++++--- .../Event/PreResponse/PhpCodeTransformerEvent.php | 4 +--- src/DataObject/Schema/PhpCodeTransformer.php | 5 ++--- src/DataObject/Service/PhpCodeTransformerService.php | 5 +++-- .../Column/Transformer/ExamplePhpCodeTransformer.php | 9 ++++----- src/PimcoreStudioBackendBundle.php | 2 +- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php index 41764e871..247a5c5fd 100644 --- a/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php +++ b/src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php @@ -14,7 +14,6 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Controller\Grid; use OpenApi\Attributes\Get; -use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes; use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController; use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\PhpCodeTransformer; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\PhpCodeTransformerServiceInterface; @@ -23,6 +22,7 @@ use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags; +use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes; use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions; use Pimcore\Bundle\StudioBackendBundle\Util\Trait\PaginatedResponseTrait; use Symfony\Component\HttpFoundation\JsonResponse; @@ -36,6 +36,7 @@ final class GetPhpCodeTransformerController extends AbstractApiController { use PaginatedResponseTrait; + public function __construct( SerializerInterface $serializer, private readonly PhpCodeTransformerServiceInterface $phpCodeTransformerService, @@ -57,8 +58,8 @@ public function __construct( tags: [Tags::DataObjectsGrid->value] )] #[SuccessResponse( - description: 'data_object_get_phpcode_transformers_success_response', - content: new CollectionJson(new GenericCollection(PhpCodeTransformer::class)) + description: 'data_object_get_phpcode_transformers_success_response', + content: new CollectionJson(new GenericCollection(PhpCodeTransformer::class)) )] #[DefaultResponses([ HttpResponseCodes::UNAUTHORIZED, diff --git a/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php b/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php index e2355635f..1f8aa8816 100644 --- a/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php +++ b/src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php @@ -11,12 +11,10 @@ * @license Pimcore Open Core License (POCL) */ - namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse; -use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent; use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\PhpCodeTransformer; - +use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent; final class PhpCodeTransformerEvent extends AbstractPreResponseEvent { diff --git a/src/DataObject/Schema/PhpCodeTransformer.php b/src/DataObject/Schema/PhpCodeTransformer.php index 12289b196..d50557b45 100644 --- a/src/DataObject/Schema/PhpCodeTransformer.php +++ b/src/DataObject/Schema/PhpCodeTransformer.php @@ -13,7 +13,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Schema; -use OpenApi\Attributes\Property; +use OpenApi\Attributes\Property; use OpenApi\Attributes\Schema; use Pimcore\Bundle\StudioBackendBundle\Util\Schema\AdditionalAttributesInterface; use Pimcore\Bundle\StudioBackendBundle\Util\Trait\AdditionalAttributesTrait; @@ -28,7 +28,7 @@ final class PhpCodeTransformer implements AdditionalAttributesInterface { use AdditionalAttributesTrait; - + public function __construct( #[Property(description: 'Unique key of the transformer', type: 'string', example: 't_key')] private readonly string $key, @@ -55,5 +55,4 @@ public function getClass(): string { return $this->class; } - } diff --git a/src/DataObject/Service/PhpCodeTransformerService.php b/src/DataObject/Service/PhpCodeTransformerService.php index 01b669f5e..f7ffcdecb 100644 --- a/src/DataObject/Service/PhpCodeTransformerService.php +++ b/src/DataObject/Service/PhpCodeTransformerService.php @@ -13,11 +13,12 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Service; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse\PhpCodeTransformerEvent; use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\PhpCodeTransformer; use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\Response\Collection; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse\PhpCodeTransformerEvent; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use function count; use function get_class; /** @@ -35,7 +36,7 @@ public function getPhpCodeTransformers(): Collection { return $this->getTransformerCollection($this->loader->getTransformers()); } - + /** * Converts an array of transformers into a Collection of PhpCodeTransformer DTOs * diff --git a/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php b/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php index a0385b1b8..3aa74b1e2 100644 --- a/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php +++ b/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php @@ -14,8 +14,9 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Column\Transformer; -use Pimcore\Bundle\StudioBackendBundle\Grid\Util\AdvancedValue; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; +use Pimcore\Bundle\StudioBackendBundle\Grid\Util\AdvancedValue; +use function is_string; /** * @internal @@ -33,7 +34,7 @@ public function transform(mixed $value, array $arguments): array 'string', $transformed, 'null' - ) + ), ]; } @@ -46,6 +47,4 @@ public function getKey(): string { return 'examplePhpCode'; } - - -} \ No newline at end of file +} diff --git a/src/PimcoreStudioBackendBundle.php b/src/PimcoreStudioBackendBundle.php index 5e4479f95..6a9575d4e 100644 --- a/src/PimcoreStudioBackendBundle.php +++ b/src/PimcoreStudioBackendBundle.php @@ -26,9 +26,9 @@ use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\ListingFilterPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\MercureTopicsProviderPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\PatchAdapterPass; +use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\PhpCodeTransformerPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\SettingsProviderPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\TransformerPass; -use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\PhpCodeTransformerPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\CompilerPass\UpdateAdapterPass; use Pimcore\Bundle\StudioBackendBundle\DependencyInjection\PimcoreStudioBackendExtension; use Pimcore\Extension\Bundle\AbstractPimcoreBundle; From 868ef7b1ef2a42d100bc7f7e311af559ee36f7e0 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Thu, 23 Oct 2025 13:57:00 +0000 Subject: [PATCH 14/19] fix ci issue --- src/DataObject/Schema/PhpCodeTransformer.php | 15 ++++++++++++--- src/Grid/Column/Transformer/PhpCode.php | 5 +---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/DataObject/Schema/PhpCodeTransformer.php b/src/DataObject/Schema/PhpCodeTransformer.php index d50557b45..77a5056bd 100644 --- a/src/DataObject/Schema/PhpCodeTransformer.php +++ b/src/DataObject/Schema/PhpCodeTransformer.php @@ -30,13 +30,22 @@ final class PhpCodeTransformer implements AdditionalAttributesInterface use AdditionalAttributesTrait; public function __construct( - #[Property(description: 'Unique key of the transformer', type: 'string', example: 't_key')] + #[Property( + description: 'Unique key of the transformer', + type: 'string', + example: 't_key')] private readonly string $key, - #[Property(description: 'Label of the transformer', type: 'string', example: 'Transformer')] + #[Property( + description: 'Label of the transformer', + type: 'string', + example: 'Transformer')] private readonly string $label, - #[Property(description: 'Fully qualified class name of the transformer', type: 'string', example: 'App\\Transformer\\MyTransformer')] + #[Property( + description: 'Fully qualified class name of the transformer', + type: 'string', + example: 'App\\Transformer\\MyTransformer')] private readonly string $class ) { } diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index 9be5887a8..2874400a0 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -48,10 +48,7 @@ public function transform(array $value, array $config): array $transformer = $this->resolver->resolve($phpClass); //Transform the entire value and return result - $results = $transformer->transform($value, $config); - - return $results; - + return $transformer->transform($value, $config); } public function getName(): string From 28705e9aebe53dc43acbe1c3d7b6b697be01d9cd Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Thu, 23 Oct 2025 14:00:56 +0000 Subject: [PATCH 15/19] Remove example --- .../Transformer/ExamplePhpCodeTransformer.php | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php diff --git a/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php b/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php deleted file mode 100644 index 3aa74b1e2..000000000 --- a/src/Grid/Column/Transformer/ExamplePhpCodeTransformer.php +++ /dev/null @@ -1,50 +0,0 @@ - Date: Thu, 23 Oct 2025 14:02:17 +0000 Subject: [PATCH 16/19] Apply php-cs-fixer changes --- src/DataObject/Schema/PhpCodeTransformer.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/DataObject/Schema/PhpCodeTransformer.php b/src/DataObject/Schema/PhpCodeTransformer.php index 77a5056bd..0754106a4 100644 --- a/src/DataObject/Schema/PhpCodeTransformer.php +++ b/src/DataObject/Schema/PhpCodeTransformer.php @@ -31,20 +31,20 @@ final class PhpCodeTransformer implements AdditionalAttributesInterface public function __construct( #[Property( - description: 'Unique key of the transformer', - type: 'string', + description: 'Unique key of the transformer', + type: 'string', example: 't_key')] private readonly string $key, #[Property( - description: 'Label of the transformer', - type: 'string', + description: 'Label of the transformer', + type: 'string', example: 'Transformer')] private readonly string $label, #[Property( - description: 'Fully qualified class name of the transformer', - type: 'string', + description: 'Fully qualified class name of the transformer', + type: 'string', example: 'App\\Transformer\\MyTransformer')] private readonly string $class ) { From 669eed9abc323825d58f67052c87419c87b77e73 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Fri, 24 Oct 2025 10:21:27 +0000 Subject: [PATCH 17/19] Replace php class with key value and minor document adjustment --- doc/03_Grid.md | 8 +++++--- src/DataObject/Schema/PhpCodeTransformer.php | 13 +------------ .../Service/PhpCodeTransformerService.php | 2 -- src/Grid/Column/PhpCodeTransformerInterface.php | 2 +- src/Grid/Column/Transformer/PhpCode.php | 8 ++++---- .../TaggedIteratorPhpCodeTransformerLoader.php | 12 ++++-------- .../Service/PhpCodeTransformerLoaderInterface.php | 6 +++--- 7 files changed, 18 insertions(+), 33 deletions(-) diff --git a/doc/03_Grid.md b/doc/03_Grid.md index ec799ea39..cec744c6f 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -526,12 +526,14 @@ The `Translate` transformer translates a given value using Symfony’s Translato #### PhpCode Transformer -The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. You can specify the class to use via its fully qualified name (phpClass) and pass custom arguments to control its behavior. This is ideal for advanced use cases where transformation logic depends on external services, dynamic configuration, or custom business rules. +The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. +To register a transformer, the service must be tagged with the appropriate Symfony service tag (e.g. studio_backend.grid.php_code_transformer) so it can be discovered by the system. +Developers can write their own PHP services to handle complex transformations. This is helpful when the logic needs to use other services or custom settings. --- **Available Configurations:** -- `phpClass`: The fully qualified class name of the transformer to execute. Must implement PhpCodeTransformerInterface. +- `phpCodeKey`: The fully qualified key value of the PHPCode transformer to execute. Must implement PhpCodeTransformerInterface. --- @@ -556,7 +558,7 @@ The `PhpCode` transformer delegates value transformation to a custom PHP class i { "key": "phpCode", "config": { - "phpClass": "Pimcore\\Bundle\\StudioBackendBundle\\Grid\\Column\\Transformer\\ExamplePhpCodeTransformer", + "phpCodeKey": "phpCodeTransformerKeyValue", } } ] diff --git a/src/DataObject/Schema/PhpCodeTransformer.php b/src/DataObject/Schema/PhpCodeTransformer.php index 0754106a4..12b9c2c53 100644 --- a/src/DataObject/Schema/PhpCodeTransformer.php +++ b/src/DataObject/Schema/PhpCodeTransformer.php @@ -21,7 +21,7 @@ #[Schema( title: 'Simple PHP Code Transformer', description: 'A PHP code transformer service with basic information', - required: ['key', 'label', 'description', 'class'], + required: ['key', 'label'], type: 'object', )] @@ -41,12 +41,6 @@ public function __construct( type: 'string', example: 'Transformer')] private readonly string $label, - - #[Property( - description: 'Fully qualified class name of the transformer', - type: 'string', - example: 'App\\Transformer\\MyTransformer')] - private readonly string $class ) { } @@ -59,9 +53,4 @@ public function getLabel(): string { return $this->label; } - - public function getClass(): string - { - return $this->class; - } } diff --git a/src/DataObject/Service/PhpCodeTransformerService.php b/src/DataObject/Service/PhpCodeTransformerService.php index f7ffcdecb..828f4dc87 100644 --- a/src/DataObject/Service/PhpCodeTransformerService.php +++ b/src/DataObject/Service/PhpCodeTransformerService.php @@ -19,7 +19,6 @@ use Pimcore\Bundle\StudioBackendBundle\Response\Collection; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use function count; -use function get_class; /** * @internal @@ -51,7 +50,6 @@ private function getTransformerCollection(iterable $transformers): Collection $item = new PhpCodeTransformer( key: $transformer->getKey(), label: $transformer->getName(), - class: get_class($transformer) ); $this->eventDispatcher->dispatch( diff --git a/src/Grid/Column/PhpCodeTransformerInterface.php b/src/Grid/Column/PhpCodeTransformerInterface.php index b664dad79..cde9479d7 100644 --- a/src/Grid/Column/PhpCodeTransformerInterface.php +++ b/src/Grid/Column/PhpCodeTransformerInterface.php @@ -19,7 +19,7 @@ interface PhpCodeTransformerInterface { /** - * @param array $value + * @param AdvancedValue[] $value * @param array $config * * @return AdvancedValue[] diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index 2874400a0..bb5c3e53f 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -32,20 +32,20 @@ public function __construct( public function transform(array $value, array $config): array { - $phpClass = $config['phpClass'] ?? null; + $phpCodeKey = $config['phpCodeKey'] ?? null; - if (!isset($phpClass) || !is_string($phpClass)) { + if (!isset($phpCodeKey) || !is_string($phpCodeKey)) { throw new TransformerException( $this->getName(), sprintf( - 'Invalid "phpClass" configuration (must be a string) for %s transformer. ', + 'Invalid "phpCodeKey" configuration (must be a string) for %s transformer. ', $this->getKey() ) ); } //Check if class exists - $transformer = $this->resolver->resolve($phpClass); + $transformer = $this->resolver->resolve($phpCodeKey); //Transform the entire value and return result return $transformer->transform($value, $config); diff --git a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php index 7c4bb43c4..3abfabf0c 100644 --- a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php +++ b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php @@ -17,7 +17,6 @@ use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; -use function get_class; use function sprintf; /** @@ -25,9 +24,6 @@ */ final readonly class TaggedIteratorPhpCodeTransformerLoader implements PhpCodeTransformerLoaderInterface { - /** - * @param iterable $transformers - */ public function __construct( #[TaggedIterator(self::PHPCODE_TRANSFORMER_TAG)] private iterable $transformers, @@ -35,7 +31,7 @@ public function __construct( } /** - * * @return array + * @return array */ public function getTransformers(): array { @@ -50,16 +46,16 @@ public function getTransformers(): array /** * @throws InvalidArgumentException */ - public function resolve(string $className): PhpCodeTransformerInterface + public function resolve(string $key): PhpCodeTransformerInterface { foreach ($this->transformers as $transformer) { - if (get_class($transformer) === $className) { + if ($transformer->getKey() === $key) { return $transformer; } } throw new InvalidArgumentException( - sprintf('No PhpCode transformer found for class "%s"', $className) + sprintf('No PhpCode transformer found for key "%s"', $key) ); } } diff --git a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php index a4043ccd5..2fdcf74df 100644 --- a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php +++ b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php @@ -25,12 +25,12 @@ interface PhpCodeTransformerLoaderInterface public const PHPCODE_TRANSFORMER_TAG = 'pimcore.studio_backend.phpcode_transformer'; /** - * @return iterable + * @return array */ - public function getTransformers(): iterable; + public function getTransformers(): array; /** * @throws InvalidArgumentException If no matching transformer is found */ - public function resolve(string $className): PhpCodeTransformerInterface; + public function resolve(string $key): PhpCodeTransformerInterface; } From 859baf2aa4a0f028b54efbb631c67769cef99875 Mon Sep 17 00:00:00 2001 From: stunnerparas Date: Fri, 24 Oct 2025 11:20:33 +0000 Subject: [PATCH 18/19] Minor adjustment --- doc/03_Grid.md | 2 +- .../PhpCodeTransformerCollectionException.php | 27 ------------------- src/Grid/Column/Transformer/PhpCode.php | 4 +-- ...TaggedIteratorPhpCodeTransformerLoader.php | 8 +++--- .../PhpCodeTransformerLoaderInterface.php | 4 +-- 5 files changed, 8 insertions(+), 37 deletions(-) delete mode 100644 src/Exception/Api/PhpCodeTransformerCollectionException.php diff --git a/doc/03_Grid.md b/doc/03_Grid.md index cec744c6f..2cced4e30 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -527,7 +527,7 @@ The `Translate` transformer translates a given value using Symfony’s Translato #### PhpCode Transformer The `PhpCode` transformer delegates value transformation to a custom PHP class implementing the Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface. This allows developers to encapsulate complex transformation logic in reusable services. -To register a transformer, the service must be tagged with the appropriate Symfony service tag (e.g. studio_backend.grid.php_code_transformer) so it can be discovered by the system. +To register a transformer, the service must be tagged with the appropriate Symfony service tag (studio_backend.grid.php_code_transformer) so it can be discovered by the system. Developers can write their own PHP services to handle complex transformations. This is helpful when the logic needs to use other services or custom settings. --- diff --git a/src/Exception/Api/PhpCodeTransformerCollectionException.php b/src/Exception/Api/PhpCodeTransformerCollectionException.php deleted file mode 100644 index 534496d7d..000000000 --- a/src/Exception/Api/PhpCodeTransformerCollectionException.php +++ /dev/null @@ -1,27 +0,0 @@ -value, $message); - } -} diff --git a/src/Grid/Column/Transformer/PhpCode.php b/src/Grid/Column/Transformer/PhpCode.php index bb5c3e53f..b37e54f9e 100644 --- a/src/Grid/Column/Transformer/PhpCode.php +++ b/src/Grid/Column/Transformer/PhpCode.php @@ -78,9 +78,9 @@ public function getConfigOptions(): array } return [ - 'phpClass' => [ + 'phpCodeKey' => [ 'type' => 'select', - 'label' => 'PHP Transformer Class', + 'label' => 'PHP Transformer Key', 'options' => $options, ], 'arguments' => [ diff --git a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php index 3abfabf0c..838914d1b 100644 --- a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php +++ b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php @@ -13,7 +13,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service\Loader; -use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; @@ -44,7 +44,7 @@ public function getTransformers(): array } /** - * @throws InvalidArgumentException + * @throws NotFoundException */ public function resolve(string $key): PhpCodeTransformerInterface { @@ -54,8 +54,6 @@ public function resolve(string $key): PhpCodeTransformerInterface } } - throw new InvalidArgumentException( - sprintf('No PhpCode transformer found for key "%s"', $key) - ); + throw new NotFoundException('PhpCode transformer', $key, 'key'); } } diff --git a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php index 2fdcf74df..7674c50f6 100644 --- a/src/Grid/Service/PhpCodeTransformerLoaderInterface.php +++ b/src/Grid/Service/PhpCodeTransformerLoaderInterface.php @@ -14,7 +14,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\Grid\Service; -use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; /** @@ -30,7 +30,7 @@ interface PhpCodeTransformerLoaderInterface public function getTransformers(): array; /** - * @throws InvalidArgumentException If no matching transformer is found + * @throws NotFoundException */ public function resolve(string $key): PhpCodeTransformerInterface; } From 0d91378ef53ac0152bdcf5fa1557f318cf1b7b45 Mon Sep 17 00:00:00 2001 From: stunnerparas <49896041+stunnerparas@users.noreply.github.com> Date: Fri, 24 Oct 2025 11:26:07 +0000 Subject: [PATCH 19/19] Apply php-cs-fixer changes --- .../Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php index 838914d1b..b98d8652d 100644 --- a/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php +++ b/src/Grid/Service/Loader/TaggedIteratorPhpCodeTransformerLoader.php @@ -17,7 +17,6 @@ use Pimcore\Bundle\StudioBackendBundle\Grid\Column\PhpCodeTransformerInterface; use Pimcore\Bundle\StudioBackendBundle\Grid\Service\PhpCodeTransformerLoaderInterface; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; -use function sprintf; /** * @internal