PHP code example of netgroup / datatransformationlayer

1. Go to this page and download the library: Download netgroup/datatransformationlayer library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

netgroup / datatransformationlayer example snippets




namespace App\Conversion\Projection;

use App\Conversion\Definition\ProjectionPlanBuilder;
use App\Conversion\Converter\DateTimeFormatConverter;
use App\Conversion\Converter\MemberFullnameConverter;

final class MemberListProjection implements ProjectionInterface
{
    public function name(): string
    {
        return 'member_list';
    }

    public function build(ProjectionPlanBuilder $builder): void
    {
        $builder->field(OrderListField::CreatedAt)
                //->convert(TrimConverter::class) // mehrere Konvertierungsschritte möglich!
                ->convert(DateTimeFormatConverter::class, ['format' => 'd.m.Y H:i']);
    }
}



namespace App\Conversion\Converter;

use App\Conversion\Definition\ConversionContext;
use DateTimeImmutable;
use DateTimeZone;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class DateTimeFormatConverter implements FieldConverterInterface
{
    public function convert(mixed $value, array $row, ConversionContext $context, array $params = []): mixed
    {
        $params = $this->resolve($params);

        if ($value === null || $value === '') {
            return null;
        }

        $timezone = new DateTimeZone((string) $context->option('timezone', 'UTC'));

        if (is_int($value) || (is_string($value) && ctype_digit($value))) {
            $dt = (new DateTimeImmutable('@' . (string) $value))->setTimezone($timezone);
            return $dt->format($params['format']);
        }

        $dt = new DateTimeImmutable((string) $value, $timezone);
        return $dt->format($params['format']);
    }

    private function resolve(array $params): array
    {
        $r = new OptionsResolver();
        $r->setDefaults(['format' => 'c']);
        $r->setAllowedTypes('format', 'string');

        return $r->resolve($params);
    }
}



namespace App\Conversion\Converter;

use App\Conversion\Definition\ConversionContext;

final class MemberFullnameConverter implements FieldConverterInterface
{
    public function convert(mixed $value, array $row, ConversionContext $context, array $params = []): mixed
    {
        $firstname = trim((string) ($row['firstname'] ?? ''));
        $lastname  = trim((string) ($row['lastname'] ?? ''));

        $full = trim($firstname . ' ' . $lastname);

        // Policy: wenn kein Name vorhanden, dann null (konfigurierbar über euer Projekt)
        return $full !== '' ? $full : null;
    }
}



namespace App\Controller;

use NetGroup\DataTransformationLayer\Classes\Services\Helper\TransforamtionHelper;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

final class MemberController extends AbstractController
{

    public function __construct(private readonly Connection $connection, private readonly TransforamtionHelper $helper)
    {
    }

    public function list(): Response
    {
        $rows = $this->connection->createQueryBuilder()
            ->select('m.id', 'm.tstamp', 'm.firstname', 'm.lastname', 'm.email')
            ->from('tl_member', 'm')
            ->where('m.disable != 1')
            ->setMaxResults(5000)
            ->executeQuery()
            ->fetchAllAssociative()
        ;

        $rows = $this->helper->transform('member_list', $rows, ['timezone' => 'Europe/Berlin']);

        return $this->render('member/list.html.twig', [
            'rows' => $rows,
        ]);
    }
}



namespace App\Conversion\Converter;

use App\Conversion\Definition\ConversionContext;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Connection;

final class PageTitleLookupConverter implements FieldConverterInterface, PrefetchingConverterInterface
{
    /** @var array<int, string> */
    private array $titleById = [];

    public function __construct(private readonly Connection $connection) {}

    public function prefetch(array $rows, ConversionContext $context, array $params = []): void
    {
        $ids = [];

        foreach ($rows as $row) {
            $id = $row['pid'] ?? null;
            if (is_numeric($id)) {
                $ids[(int) $id] = true;
            }
        }

        $ids = array_keys($ids);

        if ($ids === []) {
            $this->titleById = [];
            return;
        }

        $result = $this->connection->createQueryBuilder()
            ->select('p.id', 'p.title')
            ->from('tl_page', 'p')
            ->where('p.id IN (:ids)')
            ->setParameter('ids', $ids, ArrayParameterType::INTEGER)
            ->executeQuery()
            ->fetchAllAssociative()
        ;

        $map = [];

        foreach ($result as $row) {
            $map[(int) $row['id']] = (string) $row['title'];
        }

        $this->titleById = $map;
    }

    public function convert(mixed $value, array $row, ConversionContext $context, array $params = []): mixed
    {
        if (!is_numeric($value)) {
            return null;
        }

        $id = (int) $value;

        // Policy: unbekannte IDs -> null (siehe Abschnitt "Fehler- & Null-Policy")
        return $this->titleById[$id] ?? null;
    }
}

$builder->addField('zielfeld_name')
        ->compute(ConverterClass::class, $params, 'optionales_quellfeld');

public function build(ProjectionPlanBuilder $builder): void
{
    // Neues Feld 'formatted_price' aus dem bestehenden Feld 'price'
    $builder->addField('formatted_price')
            ->compute(CurrencyFormatConverter::class, ['currency' => 'EUR'], 'price');
}

public function build(ProjectionPlanBuilder $builder): void
{
    // Neues Feld 'full_name' aus firstname + lastname (kein einzelnes Quellfeld)
    $builder->addField('full_name')
            ->compute(FullNameConverter::class);
}

$builder->addField('display_label')
        ->compute(LookupConverter::class, ['table' => 'tl_page'], 'pid')
        ->compute(TruncateConverter::class, ['maxLength' => 50]);

$builder->removeField('feldname');

$builder->removeField('quantity')
        ->removeField('unit_price');

public function build(ProjectionPlanBuilder $builder): void
{
    // Technische IDs entfernen
    $builder->removeField('pid');
    $builder->removeField('sorting');
}



namespace App\Conversion\Projection;

use NetGroup\DataTransformationLayer\Classes\Definition\ProjectionPlanBuilder;
use NetGroup\DataTransformationLayer\Classes\Projection\ProjectionInterface;
use App\Conversion\Converter\DateTimeFormatConverter;
use App\Conversion\Converter\MultiplyFieldsConverter;

final class OrderExportProjection implements ProjectionInterface
{
    public function name(): string
    {
        return 'order_export';
    }

    public function build(ProjectionPlanBuilder $builder): void
    {
        // 1) Neues berechnetes Feld hinzufügen
        $builder->addField('total_price')
                ->compute(MultiplyFieldsConverter::class, [
                    'fields' => ['quantity', 'unit_price'],
                ]);

        // 2) Bestehendes Feld transformieren
        $builder->field('created_at')
                ->convert(DateTimeFormatConverter::class, ['format' => 'd.m.Y']);

        // 3) Originalfelder nach Berechnung entfernen
        $builder->removeField('quantity');
        $builder->removeField('unit_price');
    }
}



namespace App\Conversion\Projection;

use NetGroup\DataTransformationLayer\Classes\Services\Helper\ArrayColumnSorter;

final class MyClass
{

    public function __construct(private readonly ArrayColumnSorter $sorter)
    {
    }

    public function doSomething(): array
    {
        $rows = [
            ['description' => 'Nur ein Test', 'title' => 'Test 001', 'id' => 12],
            ['description' => 'Nur noch ein Test', 'title' => 'Test 002', 'id' => 34]
        ];

        $order = ['id', 'title', 'description'];

        return $this->sorter->sort($rows, $order;
    }
}

[
    ['id' => 12, 'title' => 'Test 001', 'description' => 'Nur ein Test'],
    ['id' => 34, 'title' => 'Test 002', 'description' => 'Nur noch ein Test']
]