242 lines
6.5 KiB
PHP
242 lines
6.5 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the PHPFlasher package.
|
|
* (c) Younes KHOUBZA <younes.khoubza@gmail.com>
|
|
*/
|
|
|
|
namespace Flasher\Prime\Response\Resource;
|
|
|
|
use Flasher\Prime\Config\Config;
|
|
use Flasher\Prime\Config\ConfigInterface;
|
|
use Flasher\Prime\Notification\Envelope;
|
|
use Flasher\Prime\Response\Response;
|
|
use Flasher\Prime\Stamp\HandlerStamp;
|
|
use Flasher\Prime\Stamp\ViewStamp;
|
|
use Flasher\Prime\Template\TemplateEngineInterface;
|
|
|
|
final class ResourceManager implements ResourceManagerInterface
|
|
{
|
|
/**
|
|
* @var ConfigInterface
|
|
*/
|
|
private $config;
|
|
|
|
/**
|
|
* @var TemplateEngineInterface|null
|
|
*/
|
|
private $templateEngine;
|
|
|
|
/**
|
|
* @var array<string, string[]>
|
|
*/
|
|
private $scripts = array();
|
|
|
|
/**
|
|
* @var array<string, string[]>
|
|
*/
|
|
private $styles = array();
|
|
|
|
/**
|
|
* @var array<string, array<string, mixed>>
|
|
*/
|
|
private $options = array();
|
|
|
|
public function __construct(ConfigInterface $config = null, TemplateEngineInterface $templateEngine = null)
|
|
{
|
|
$this->config = $config ?: new Config();
|
|
$this->templateEngine = $templateEngine;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function buildResponse(Response $response)
|
|
{
|
|
$rootScript = $this->selectAssets($this->config->get('root_script'));
|
|
$rootScript = is_string($rootScript) ? $rootScript : null;
|
|
|
|
$response->setRootScript($rootScript);
|
|
|
|
$handlers = array();
|
|
foreach ($response->getEnvelopes() as $envelope) {
|
|
$handler = $this->resolveHandler($envelope);
|
|
if (null === $handler || \in_array($handler, $handlers, true)) {
|
|
continue;
|
|
}
|
|
$handlers[] = $handler;
|
|
|
|
$this->populateResponse($response, $handler);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function addScripts($handler, array $scripts)
|
|
{
|
|
$this->scripts[$handler] = $scripts;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function addStyles($handler, array $styles)
|
|
{
|
|
$this->styles[$handler] = $styles;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function addOptions($handler, array $options)
|
|
{
|
|
$this->options[$handler] = $options;
|
|
}
|
|
|
|
/**
|
|
* @return ConfigInterface
|
|
*/
|
|
public function getConfig()
|
|
{
|
|
return $this->config;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $assets
|
|
*
|
|
* @return string[]|string
|
|
*/
|
|
private function selectAssets($assets)
|
|
{
|
|
$use = $this->config->get('use_cdn', true) ? 'cdn' : 'local';
|
|
|
|
return is_array($assets) && array_key_exists($use, $assets) ? $assets[$use] : $assets;
|
|
}
|
|
|
|
/**
|
|
* @return string|null
|
|
*/
|
|
private function resolveHandler(Envelope $envelope)
|
|
{
|
|
$handlerStamp = $envelope->get('Flasher\Prime\Stamp\HandlerStamp');
|
|
if (!$handlerStamp instanceof HandlerStamp) {
|
|
return null;
|
|
}
|
|
|
|
$handler = $handlerStamp->getHandler();
|
|
if ('flasher' !== $handler && 0 !== strpos($handler, 'theme.')) {
|
|
return $handler;
|
|
}
|
|
|
|
$theme = $this->getTheme($handler);
|
|
if (null === $theme) {
|
|
return $handler;
|
|
}
|
|
|
|
if (!isset($this->scripts[$handler])) {
|
|
$scripts = $this->config->get('themes.'.$theme.'.scripts', array());
|
|
$this->addScripts('theme.'.$theme, (array) $scripts);
|
|
}
|
|
|
|
if (!isset($this->styles[$handler])) {
|
|
$styles = $this->config->get('themes.'.$theme.'.styles', array());
|
|
$this->addStyles('theme.'.$theme, (array) $styles);
|
|
}
|
|
|
|
if (!isset($this->options[$handler])) {
|
|
$options = $this->config->get('themes.'.$theme.'.options', array());
|
|
$this->addOptions('theme.'.$theme, $options);
|
|
}
|
|
|
|
if ('flasher' === $theme) {
|
|
$scripts = $this->config->get('scripts', array());
|
|
|
|
if (isset($this->scripts['theme.flasher'])) {
|
|
$scripts = array_merge($this->scripts['theme.flasher'], $scripts);
|
|
}
|
|
|
|
if (isset($this->scripts['flasher'])) {
|
|
$scripts = array_merge($this->scripts['flasher'], $scripts);
|
|
}
|
|
|
|
$this->addScripts('theme.flasher', (array) $scripts);
|
|
|
|
$styles = $this->config->get('styles', array());
|
|
if (isset($this->styles['theme.flasher'])) {
|
|
$styles = array_merge($this->styles['theme.flasher'], $styles);
|
|
}
|
|
if (isset($this->scripts['flasher'])) {
|
|
$styles = array_merge($this->styles['flasher'], $styles);
|
|
}
|
|
$this->addStyles('theme.flasher', (array) $styles);
|
|
|
|
$options = $this->config->get('options', array());
|
|
if (isset($this->options['theme.flasher'])) {
|
|
$options = array_merge($this->options['theme.flasher'], $options);
|
|
}
|
|
if (isset($this->options['flasher'])) {
|
|
$options = array_merge($this->options['flasher'], $options);
|
|
}
|
|
$this->addOptions('theme.flasher', $options);
|
|
}
|
|
|
|
/** @var string|null $view */
|
|
$view = $this->config->get('themes.'.$theme.'.view');
|
|
if (null === $view || null === $this->templateEngine) {
|
|
return 'theme.'.$theme;
|
|
}
|
|
|
|
$compiled = $this->templateEngine->render($view, array('envelope' => $envelope));
|
|
$envelope->withStamp(new ViewStamp($compiled));
|
|
|
|
return 'theme.'.$theme;
|
|
}
|
|
|
|
/**
|
|
* @param string $handler
|
|
*
|
|
* @return string|null
|
|
*/
|
|
private function getTheme($handler)
|
|
{
|
|
if ('flasher' === $handler) {
|
|
return 'flasher';
|
|
}
|
|
|
|
if (0 === strpos($handler, 'theme.')) {
|
|
return substr($handler, \strlen('theme.'));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param string $handler
|
|
*
|
|
* @return void
|
|
*/
|
|
private function populateResponse(Response $response, $handler)
|
|
{
|
|
if (isset($this->scripts[$handler])) {
|
|
$scripts = $this->selectAssets($this->scripts[$handler]);
|
|
$scripts = is_array($scripts) ? $scripts : array();
|
|
|
|
$response->addScripts($scripts);
|
|
}
|
|
|
|
if (isset($this->styles[$handler])) {
|
|
$styles = $this->selectAssets($this->styles[$handler]);
|
|
$styles = is_array($styles) ? $styles : array();
|
|
|
|
$response->addStyles($styles);
|
|
}
|
|
|
|
if (isset($this->options[$handler])) {
|
|
$response->addOptions($handler, $this->options[$handler]);
|
|
}
|
|
}
|
|
}
|