Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@
"mezzio/mezzio-cors": "^1.13.0",
"mezzio/mezzio-fastroute": "^3.12.0",
"mezzio/mezzio-hal": "^2.10.1",
"mezzio/mezzio-helpers": "^5.18",
"mezzio/mezzio-problem-details": "^1.15.0",
"mezzio/mezzio-twigrenderer": "^2.17.0",
"ramsey/uuid-doctrine": "^2.1.0",
"roave/psr-container-doctrine": "^5.2.2",
"symfony/filesystem": "^7.2.0",
Expand Down
11 changes: 5 additions & 6 deletions config/autoload/mezzio.global.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
use Laminas\ConfigAggregator\ConfigAggregator;

return [
// Toggle the configuration cache. Set this to boolean false, or remove the
// directive, to disable configuration caching. Toggling development mode
// will also disable it by default; clear the configuration cache using
// `composer clear-config-cache`.
// Toggle the configuration cache.
// Set this to boolean false or remove the directive to disable configuration caching.
// Toggling development mode will also disable it by default.
// Clear the configuration cache using `composer clear-config-cache`.
ConfigAggregator::ENABLE_CACHE => true,

// Enable debugging; typically used to provide debugging information within templates.
'debug' => false,
'mezzio' => [
// Provide templates for the error handling middleware to use when
// generating responses.
// Provide templates for the error handling middleware to use when generating responses.
'error_handler' => [
'template_404' => 'error::404',
'template_error' => 'error::error',
Expand Down
20 changes: 5 additions & 15 deletions config/autoload/templates.global.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,11 @@

declare(strict_types=1);

use Api\App\Template\RendererInterface;

return [
'debug' => false,
'templates' => [
'extension' => 'html.twig',
],
'twig' => [
'assets_url' => '/',
'assets_version' => null,
'autoescape' => 'html',
'auto_reload' => true,
'cache_dir' => 'data/cache/twig',
'extensions' => [],
'globals' => [],
'optimizations' => -1,
'runtime_loaders' => [],
'timezone' => 'UTC',
RendererInterface::class => [
'globals' => [],
'extension' => 'phtml',
],
];
1 change: 0 additions & 1 deletion config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
Mezzio\Hal\ConfigProvider::class,
Mezzio\ProblemDetails\ConfigProvider::class,
Mezzio\Router\FastRouteRouter\ConfigProvider::class,
Mezzio\Twig\ConfigProvider::class,
Mezzio\Helper\ConfigProvider::class,
Mezzio\ConfigProvider::class,
Mezzio\Router\ConfigProvider::class,
Expand Down
19 changes: 8 additions & 11 deletions src/App/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
use Api\App\Middleware\ResourceProviderMiddleware;
use Api\App\Service\ErrorReportService;
use Api\App\Service\ErrorReportServiceInterface;
use Api\App\Template\Parser;
use Api\App\Template\ParserInterface;
use Api\App\Template\Renderer;
use Api\App\Template\RendererInterface;
use Dot\DependencyInjection\Factory\AttributedServiceFactory;
use Laminas\Hydrator\ArraySerializableHydrator;
use Mezzio\Application;
Expand All @@ -25,13 +29,6 @@
use Mezzio\Hal\Metadata\RouteBasedCollectionMetadata;
use Mezzio\Hal\Metadata\RouteBasedResourceMetadata;
use Mezzio\ProblemDetails\ProblemDetailsMiddleware;
use Mezzio\Template\TemplateRendererInterface;
use Mezzio\Twig\TwigEnvironmentFactory;
use Mezzio\Twig\TwigExtension;
use Mezzio\Twig\TwigExtensionFactory;
use Mezzio\Twig\TwigRenderer;
use Mezzio\Twig\TwigRendererFactory;
use Twig\Environment;

class ConfigProvider
{
Expand Down Expand Up @@ -62,14 +59,14 @@ private function getDependencies(): array
PostErrorReportResourceHandler::class => AttributedServiceFactory::class,
ErrorReportService::class => AttributedServiceFactory::class,
TokenGenerateCommand::class => AttributedServiceFactory::class,
Environment::class => TwigEnvironmentFactory::class,
TwigExtension::class => TwigExtensionFactory::class,
TwigRenderer::class => TwigRendererFactory::class,
Parser::class => AttributedServiceFactory::class,
Renderer::class => AttributedServiceFactory::class,
],
'aliases' => [
AuthenticationInterface::class => OAuth2Adapter::class,
ErrorReportServiceInterface::class => ErrorReportService::class,
TemplateRendererInterface::class => TwigRenderer::class,
RendererInterface::class => Renderer::class,
ParserInterface::class => Parser::class,
],
];
}
Expand Down
74 changes: 74 additions & 0 deletions src/App/src/Template/Parser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace Api\App\Template;

use Dot\DependencyInjection\Attribute\Inject;
use Mezzio\Helper\UrlHelperInterface;

use function array_key_exists;
use function sprintf;

class Parser implements ParserInterface
{
protected array $globals = [];

#[Inject(
UrlHelperInterface::class,
'config',
)]
public function __construct(
protected UrlHelperInterface $urlHelper,
array $config = [],
) {
$this->globals = $this->prepareGlobals($config);
}

public function __invoke(string $path, array $params = []): void
{
foreach ($params as $key => $value) {
${$key} = $value;
}
foreach ($this->globals as $key => $value) {
${$key} = $value;
}

include $path;
}

public function absoluteUrl(string $path, ?string $baseUrl = null): string
{
if ($baseUrl === null) {
$baseUrl = $this->globals['application']['url'] ?? '';
}

return sprintf('%s%s', $baseUrl, $path);
}

public function url(
?string $routeName = null,
array $routeParams = [],
array $queryParams = [],
?string $fragmentIdentifier = null,
array $options = []
): string {
return $this->urlHelper->generate($routeName, $routeParams, $queryParams, $fragmentIdentifier, $options);
}

public function getGlobals(): array
{
return $this->globals;
}

public function prepareGlobals(array $config = []): array
{
$globals = $config[RendererInterface::class]['globals'] ?? [];

if (array_key_exists('application', $config)) {
$globals['application'] = $config['application'] ?? [];
}

return $globals;
}
}
18 changes: 18 additions & 0 deletions src/App/src/Template/ParserInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Api\App\Template;

interface ParserInterface
{
public function absoluteUrl(string $path, ?string $baseUrl = null): string;

public function url(
?string $routeName = null,
array $routeParams = [],
array $queryParams = [],
?string $fragmentIdentifier = null,
array $options = []
): string;
}
71 changes: 71 additions & 0 deletions src/App/src/Template/Renderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace Api\App\Template;

use Api\App\Exception\RuntimeException;
use Core\App\Message;
use Dot\DependencyInjection\Attribute\Inject;

use function array_key_exists;
use function explode;
use function is_readable;
use function is_string;
use function ob_get_clean;
use function ob_start;
use function realpath;
use function sprintf;

class Renderer implements RendererInterface
{
protected array $templates = [];
protected string $extension;

#[Inject(
ParserInterface::class,
'config',
)]
public function __construct(
protected ParserInterface $parser,
array $config = [],
) {
$this->templates = $config['templates'] ?? [];
$this->extension = $config[RendererInterface::class]['extension'] ?? 'phtml';
}

public function render(string $template, array $params = []): false|string
{
ob_start();
($this->parser)($this->getPath($template), $params);
return ob_get_clean();
}

public function getExtension(): string
{
return $this->extension;
}

/**
* @throws RuntimeException
*/
public function getPath(string $template): string
{
[$namespace, $templateName] = explode('::', $template, 2);
if (! array_key_exists($namespace, $this->templates)) {
throw RuntimeException::create(Message::templateNotFound($template));
}

$path = realpath(sprintf('%s/%s.%s', $this->templates[$namespace], $templateName, $this->extension));
if (! is_string($path) || ! is_readable($path)) {
throw RuntimeException::create(Message::templateNotFound($template));
}

return $path;
}

public function getTemplates(): array
{
return $this->templates;
}
}
10 changes: 10 additions & 0 deletions src/App/src/Template/RendererInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Api\App\Template;

interface RendererInterface
{
public function render(string $template, array $params = []): false|string;
}
6 changes: 6 additions & 0 deletions src/Core/src/App/src/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Message
public const ROLE_NOT_FOUND = 'Role not found.';
public const SERVICE_NOT_FOUND = 'Service %s not found in the container.';
public const SETTING_NOT_FOUND = 'Setting "%s" not found.';
public const TEMPLATE_NOT_FOUND = 'Template "%s" not found.';
public const UNSUPPORTED_MEDIA_TYPE = 'Unsupported Media Type.';
public const USER_ACTIVATED = 'User account has been activated.';
public const USER_ALREADY_ACTIVATED = 'User account is already active.';
Expand Down Expand Up @@ -137,6 +138,11 @@ public static function settingNotFound(string $identifier): string
return sprintf(self::SETTING_NOT_FOUND, $identifier);
}

public static function templateNotFound(string $template): string
{
return sprintf(self::TEMPLATE_NOT_FOUND, $template);
}

public static function unsupportedMediaType(array $types = []): string
{
if (count($types) === 0) {
Expand Down
Loading
Loading