HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/ai.naniguide.com/app/Services/TagTranslationService.php
<?php

namespace App\Services;

use Twig\Environment;
use Twig\Loader\ArrayLoader;
use App\Library\Contracts\TagResolverInterface;
use League\Pipeline\PipelineBuilder;

class TagTranslationService
{
    private Environment $twig;

    public function __construct()
    {
        $this->twig = new Environment(new ArrayLoader(), [
            'autoescape' => false,
            'cache' => false,
            'strict_variables' => false,
        ]);
    }

    public function translate(string $text, ?TagResolverInterface ...$resolvers): string
    {
        $resolvedTags = [];
        foreach ($resolvers as $resolver) {
            if (is_null($resolver)) {
                continue;
            }

            $tags = $resolver->getResolvedTags();

            // Inline pipeline definition (no external builder function)
            $tagsProcessor = (new PipelineBuilder())
                ->add(fn (array $tags) => $this->flattenTags($tags)) // go first
                ->add(fn (array $tags) => $this->duplicateUppercaseKeys($tags)) // go after that
                ->build();

            // Process tags through the pipeline
            $tags = $tagsProcessor->process($tags);

            $resolvedTags = array_merge($resolvedTags, $tags);
        }

        $template = $this->twig->createTemplate($text);
        return $template->render($resolvedTags);
    }

    /**
     * Recursively flatten nested arrays while keeping the original structure.
     *
     * Example:
     * Input:
     * [
     *     'list' => [
     *         'name' => 'Hello',
     *         'id' => 1,
     *     ]
     * ]
     *
     * Output:
     * [
     *     'list' => [
     *         'name' => 'Hello',
     *         'id' => 1,
     *     ],
     *     'list_name' => 'Hello',
     *     'list_id' => 1
     * ]
     *
     * This allows both Twig syntaxes to work:
     *   {{ list.name }}  and  {{ list_name }}
     */
    private function flattenTags(array $input, string $prefix = ''): array
    {
        $result = [];

        foreach ($input as $key => $value) {
            $fullKey = $prefix ? "{$prefix}_{$key}" : $key;

            if (is_array($value)) {
                // Keep nested array
                $result[$key] = $value;

                // Merge recursively flattened values
                $nested = $this->flattenTags($value, $fullKey);
                foreach ($nested as $nestedKey => $nestedValue) {
                    $result[$nestedKey] = $nestedValue;
                }
            } else {
                $result[$fullKey] = $value;
            }
        }

        return $result;
    }

    /**
     * Duplicate all keys (recursively) with uppercase equivalents.
     *
     * Example:
     * Input:
     * [ 'name' => 'John', 'list_id' => 1 ]
     *
     * Output:
     * [ 'name' => 'John', 'NAME' => 'John', 'list_id' => 1, 'LIST_ID' => 1 ]
     */
    private function duplicateUppercaseKeys(array $input): array
    {
        $result = [];

        foreach ($input as $key => $value) {
            if (is_array($value)) {
                $value = $this->duplicateUppercaseKeys($value);
                $result[$key] = $value;
                $result[strtoupper($key)] = $value;
            } else {
                $result[$key] = $value;
                $result[strtoupper($key)] = $value;
            }
        }

        return $result;
    }
}