<?php
declare(strict_types=1);
namespace Butschster\ContextGenerator\Lib\Variable;
use Butschster\ContextGenerator\Application\Logger\LoggerPrefix;
use Butschster\ContextGenerator\Lib\Variable\Provider\VariableProviderInterface;
use Psr\Log\LoggerInterface;
use Spiral\Core\Attribute\Proxy;
/**
* Processor that replaces variable references in text
*/
final readonly class VariableReplacementProcessor implements VariableReplacementProcessorInterface
{
public function __construct(
#[Proxy]
private VariableProviderInterface $provider,
#[LoggerPrefix(prefix: 'variable-replacement')]
private ?LoggerInterface $logger = null,
) {}
/**
* Process text by replacing variable references
*
* @param string $text Text containing variable references
* @return string Text with variables replaced
*/
public function process(string $text): string
{
// Replace ${VAR_NAME} syntax
$result = \preg_replace_callback(
'/\${([a-zA-Z0-9_]+)}/',
fn(array $matches) => $this->replaceVariable($matches[1], '${%s}'),
$text,
);
// Replace {{VAR_NAME}} syntax
return (string) \preg_replace_callback(
'/{{([a-zA-Z0-9_]+)}}/',
fn(array $matches) => $this->replaceVariable($matches[1], '{{%s}}'),
(string) $result,
);
}
/**
* Replace a single variable reference
*
* @param string $name Variable name
* @return string Variable value or original reference if not found
*/
private function replaceVariable(string $name, string $format): string
{
if (!$this->provider->has($name)) {
// Keep the original reference if not found and not failing
return \sprintf($format, $name);
}
// Get the variable value
$value = $this->provider->get($name);
$this->logger?->debug('Replacing variable', [
'name' => $name,
'value' => $value,
]);
// If value is null (should not happen due to has() check), return empty string
return $value ?? '';
}
}