Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions config/grid.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ 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\DataObject\Service\PhpCodeTransformerServiceInterface:
class: Pimcore\Bundle\StudioBackendBundle\DataObject\Service\PhpCodeTransformerService

#
# Repository
#
Expand Down Expand Up @@ -417,3 +423,7 @@ 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' ]

42 changes: 42 additions & 0 deletions doc/03_Grid.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,5 +521,47 @@ 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.
---

**Available Configurations:**

- `phpClass`: The fully qualified class name of the transformer to execute. Must implement PhpCodeTransformerInterface.

---

**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\\ExamplePhpCodeTransformer",
}
}
]
}
}

...
```
3 changes: 2 additions & 1 deletion doc/05_Additional_Custom_Attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
- `pre_response.notification_recipient`
- `pre_response.php_code_transformer`
78 changes: 78 additions & 0 deletions src/DataObject/Controller/Grid/GetPhpCodeTransformerController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);

/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* 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)
*/

namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Controller\Grid;

use OpenApi\Attributes\Get;
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\PhpCodeTransformer;
use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\PhpCodeTransformerServiceInterface;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Property\GenericCollection;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\CollectionJson;
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;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\Serializer\SerializerInterface;

/**
* @internal
*/
final class GetPhpCodeTransformerController extends AbstractApiController
{
use PaginatedResponseTrait;

public function __construct(
SerializerInterface $serializer,
private readonly PhpCodeTransformerServiceInterface $phpCodeTransformerService,
) {
parent::__construct($serializer);
}

#[Route(
'/data-objects/grid/transformers/services/phpcode',
name: 'pimcore_studio_api_get_phpcode_transformers',
methods: ['GET']
)]
#[IsGranted(UserPermissions::USER_MANAGEMENT->value)]
#[Get(
path: self::PREFIX . '/data-objects/grid/transformers/services/phpcode',
operationId: 'data_object_get_phpcode_transformers',
description: 'data_object_get_phpcode_transformers_description',
summary: 'data_object_get_phpcode_transformers_summary',
tags: [Tags::DataObjectsGrid->value]
)]
#[SuccessResponse(
description: 'data_object_get_phpcode_transformers_success_response',
content: new CollectionJson(new GenericCollection(PhpCodeTransformer::class))
)]
#[DefaultResponses([
HttpResponseCodes::UNAUTHORIZED,
HttpResponseCodes::NOT_FOUND,
])]
public function getPhpCodeTransformers(): JsonResponse
{
$collection = $this->phpCodeTransformerService->getPhpCodeTransformers();

return $this->getPaginatedCollection(
$this->serializer,
$collection->getItems(),
$collection->getTotalItems()
);
}
}
32 changes: 32 additions & 0 deletions src/DataObject/Event/PreResponse/PhpCodeTransformerEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);

/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* 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)
*/

namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse;

use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\PhpCodeTransformer;
use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent;

final class PhpCodeTransformerEvent extends AbstractPreResponseEvent
{
public const EVENT_NAME = 'pre_response.php_code_transformer';

public function __construct(private readonly PhpCodeTransformer $transformer)
{
parent::__construct($this->transformer);
}

public function getTransformer(): PhpCodeTransformer
{
return $this->transformer;
}
}
67 changes: 67 additions & 0 deletions src/DataObject/Schema/PhpCodeTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);

/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* 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)
*/

namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Schema;

use OpenApi\Attributes\Property;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioBackendBundle\Util\Schema\AdditionalAttributesInterface;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\AdditionalAttributesTrait;

#[Schema(
title: 'Simple PHP Code Transformer',
description: 'A PHP code transformer service with basic information',
required: ['key', 'label', 'description', 'class'],
type: 'object',
)]

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,

#[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')]
private readonly string $class
) {
}

public function getKey(): string
{
return $this->key;
}

public function getLabel(): string
{
return $this->label;
}

public function getClass(): string
{
return $this->class;
}
}
67 changes: 67 additions & 0 deletions src/DataObject/Service/PhpCodeTransformerService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);

/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* 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)
*/

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 Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use function count;
use function get_class;

/**
* @internal
*/
final readonly class PhpCodeTransformerService implements PhpCodeTransformerServiceInterface
{
public function __construct(
private PhpCodeTransformerLoaderInterface $loader,
private EventDispatcherInterface $eventDispatcher
) {
}

public function getPhpCodeTransformers(): Collection
{
return $this->getTransformerCollection($this->loader->getTransformers());
}

/**
* Converts an array of transformers into a Collection of PhpCodeTransformer DTOs
*
* @param iterable<object> $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);
}
}
24 changes: 24 additions & 0 deletions src/DataObject/Service/PhpCodeTransformerServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);

/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* 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)
*/

namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Service;

use Pimcore\Bundle\StudioBackendBundle\Response\Collection;

/**
* @internal
*/
interface PhpCodeTransformerServiceInterface
{
public function getPhpCodeTransformers(): Collection;
}
Loading