sasae/src/SasaeContext.php

94 lines
2.6 KiB
PHP

<?php
// SasaeContext.php
// Created: 2024-08-04
// Updated: 2024-08-04
namespace Sasae;
use InvalidArgumentException;
use Stringable;
use Twig\TemplateWrapper as TwigTemplateWrapper;
/**
* Provides a wrapper of Twig\TemplateWrapper.
*/
class SasaeContext implements Stringable {
/**
* @internal
* @param array<string, mixed> $vars
*/
public function __construct(
private TwigTemplateWrapper $wrapper,
private array $vars = []
) {}
/**
* Returns the underlying wrapper instance.
*
* @return TwigTemplateWrapper
*/
public function getWrapper(): TwigTemplateWrapper {
return $this->wrapper;
}
/**
* Sets a local variable.
*
* $path is evaluated to allow accessing deeper layer arrays without overwriting it entirely.
*
* @param string $path Array path to the variable.
* @param mixed $value Desired value.
*/
public function setVar(string $path, mixed $value): void {
$path = explode('.', $path);
$target = &$this->vars;
$targetName = array_pop($path);
if(!empty($path)) {
$path = array_reverse($path);
while(($name = array_pop($path)) !== null) {
if(!is_array($target))
throw new InvalidArgumentException('The $path you\'re attempting to write to conflicts with a non-array type.');
if(!array_key_exists($name, $target))
$target[$name] = [];
$target = &$target[$name];
}
}
if(!is_array($target))
throw new InvalidArgumentException('The $path you\'re attempting to write to conflicts with a non-array type.');
$target[$targetName] = $value;
}
/**
* Merges a set of variables into the local variable set.
*
* @param array<string, mixed> $vars Variables to apply to the set.
*/
public function setVars(array $vars): void {
$this->vars = array_merge($this->vars, $vars);
}
/**
* Renders the template to a string, taking additional variables that are not commit to local set.
*
* @param array<string, mixed>|null $vars Additional local variables, nullable to avoid additional function calls.
* @return string Rendered template.
*/
public function render(?array $vars = null): string {
return $this->wrapper->render(
$vars === null ? $this->vars : array_merge($this->vars, $vars)
);
}
/**
* Renders the template to a string.
*
* @return string Rendered template.
*/
public function __toString(): string {
return $this->render();
}
}