RouteHelper.php in Theme Compiler 2.0.x
Same filename and directory in other branches
Namespace
Drupal\theme_compiler\RoutingFile
src/Routing/RouteHelper.phpView source
<?php
namespace Drupal\theme_compiler\Routing;
use Drupal\Core\Discovery\YamlDiscovery;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\compiler\CompilerContextInterface;
use Drupal\compiler\CompilerInputFile;
use Drupal\compiler\RefineableCompilerContext;
use Symfony\Component\Routing\Route;
/**
* Builds the route(s) that facilitate compilation of theme-provided assets.
*
* Copyright (C) 2021 Library Solutions, LLC (et al.).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* @internal
*/
class RouteHelper {
const COMPILER_CONTROLLER = 'theme_compiler.controller:serve';
/**
* A YAML discovery instance to find 'theme_compiler' configuration.
*
* @var \Drupal\Core\Plugin\Discovery\YamlDiscovery
*/
protected $discovery;
/**
* Constructs a RouteHelper object.
*
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
* The theme handler service.
*/
public function __construct(ThemeHandlerInterface $theme_handler) {
// Create a new YAML discovery plugin for 'theme_compiler' configuration.
$this->discovery = new YamlDiscovery('theme_compiler', $theme_handler
->getThemeDirectories());
}
/**
* Construct a compiler context from a theme, compiler, path, & config.
*
* The resulting compiler context will be serialized and stored as a default
* route parameter value. Theme-relative file paths will be resolved before
* being stored.
*
* @param string $theme
* The machine name of the theme containing the context.
* @param string $compiler
* The machine name of the desired compiler plugin to use.
* @param string $path
* A theme-relative path used to build the target route that will be used to
* serve the result of the configured compilation.
* @param array $config
* Configuration values for the target route. The following keys are used
* directly by this module:
*
* - 'files': an array exclusively containing file path strings (required)
* - 'options': an array of options to pass to the compiler
* - 'data': miscellaneous user-defined data to pass to the compiler
*
* Keys that do not appear in this list will be ignored.
*
* @return \Drupal\compiler\RefineableCompilerContext
* A compiler context used to define a compilation.
*/
protected function getThemeCompilerContext(string $theme, string $compiler, string $path, array $config) : RefineableCompilerContext {
if (empty($files = $config['files'] ?? []) || !is_array($files) || $files !== array_filter($files, 'is_string')) {
throw new \InvalidArgumentException('"files" is required to be a non-empty array that exclusively contains strings of file paths');
}
if (!is_array($options = $config['options'] ?? [])) {
throw new \InvalidArgumentException('"options" can either be undefined or an array');
}
// Store the theme name and the theme-relative target path as options.
$options['theme_compiler']['path'] = $path;
$options['theme_compiler']['theme'] = $theme;
// Compute the target URI for this context and hash it for an ID.
$options['theme_compiler']['uri'] = '/' . drupal_get_path('theme', $theme) . '/' . $path;
$options['theme_compiler']['id'] = hash('sha384', $options['theme_compiler']['uri']);
// Iterate over each defined theme-relative file path for processing.
foreach ($files as $index => $file) {
if (empty($result = realpath(\DRUPAL_ROOT . '/' . drupal_get_path('theme', $theme) . '/' . $file))) {
throw new \InvalidArgumentException('Unable to resolve theme-relative file path at index ' . var_export($index, TRUE) . ': ' . var_export($file, TRUE));
}
$inputs[] = new CompilerInputFile($result);
}
$context = new RefineableCompilerContext($compiler, $options, $inputs ?? [], $config['data'] ?? NULL);
return $context;
}
/**
* Generate a list of routes for a specific compiler's targets.
*
* @param string $theme
* The machine name of the theme for which routes should be generated.
* @param string $compiler
* The machine name of the compiler for which routes should be generated.
* @param array $targets
* An array of compiler target options keyed by a theme-relative
* target path.
*
* @return \Generator
* A collection of routes for the provided compiler's targets.
*/
protected function getThemeCompilerRoutes(string $theme, string $compiler, array $targets) : \Generator {
// Iterate over each target for this compiler for processing.
foreach ($targets as $path => $config) {
// Create a compiler context using this target's configuration; then
// create a route using the compiler context.
$context = $this
->getThemeCompilerContext($theme, $compiler, $path, $config);
$route = $this
->getThemeCompilerTargetRoute($context);
// Generate a keyed element for this route.
(yield "theme_compiler.{$context->getOption('theme_compiler')['id']}" => $route);
}
}
/**
* Generate a route to a specific theme-provided, compiled asset.
*
* @param \Drupal\compiler\CompilerContextInterface $context
* The source context which defines or configures the compilation.
*
* @return \Symfony\Component\Routing\Route
* A route to a theme-provided, compiled assets.
*/
protected function getThemeCompilerTargetRoute(CompilerContextInterface $context) : Route {
$route = new Route($context
->getOption('theme_compiler')['uri'], [
'_controller' => self::COMPILER_CONTROLLER,
'theme_compiler_context' => $context,
], [
'_access' => 'TRUE',
], [
'_maintenance_access' => 'TRUE',
]);
return $route;
}
/**
* Generate a list of routes for a specific theme's compiler configuration.
*
* @param string $theme
* The machine name of the theme for which routes should be generated.
* @param array $compilers
* An associative array of compiler target configurations keyed by the
* desired compiler's plugin identifier.
*
* @return \Generator
* A collection of routes for the provided theme's compiler configuration.
*/
protected function getThemeRoutes(string $theme, array $compilers) : \Generator {
foreach ($compilers as $compiler => $targets) {
foreach ($this
->getThemeCompilerRoutes($theme, $compiler, $targets) as $name => $route) {
(yield $name => $route);
}
}
}
/**
* Generate a list of routes for all applicable compiler configurations.
*
* @return \Generator
* A collection of routes produced by this module.
*
* @internal
*/
public function routes() : \Generator {
foreach ($this->discovery
->findAll() as $theme => $compilers) {
foreach ($this
->getThemeRoutes($theme, $compilers) as $name => $route) {
(yield $name => $route);
}
}
}
}
Classes
Name![]() |
Description |
---|---|
RouteHelper | Builds the route(s) that facilitate compilation of theme-provided assets. |