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;
}
}