preview_site-1.1.2/src/Generate/TomeStaticExtension.php
src/Generate/TomeStaticExtension.php
<?php
namespace Drupal\preview_site\Generate;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Session\AccountSwitcherInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\StreamWrapper\StreamWrapperManager;
use Drupal\Core\Url;
use Drupal\tome_static\StaticCache;
use Drupal\tome_static\StaticCacheInterface;
use Drupal\tome_static\StaticGenerator;
use Drupal\tome_static\StaticGeneratorInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
/**
* Defines an extension to tome's static generator.
*/
class TomeStaticExtension extends StaticGenerator {
/**
* Static directory.
*
* @var string
*/
protected $staticDirectory;
/**
* Copied paths.
*
* @var string[]
*/
protected $copiedPaths = [];
/**
* Tracks if generation is in progress.
*
* Whilst Tome sets an attribute on the Request, because the entity we're
* dealing with is loaded before the request stack is updated, we don't have
* access to that when deciding which entity to load. So we keep track of
* state internally.
*
* @var bool
*
* @see \Drupal\preview_site\Generate\GeneratePluginInterface::entityPreload
* @see \Drupal\preview_site\Generate\GeneratePluginInterface::generateBuildForAssetPath
*/
protected $isGenerating = FALSE;
/**
* {@inheritdoc}
*/
public function __construct(HttpKernelInterface $http_kernel, RequestStack $request_stack, EventDispatcherInterface $event_dispatcher, StaticCacheInterface $cache, AccountSwitcherInterface $account_switcher, FileSystemInterface $file_system) {
parent::__construct($http_kernel, $request_stack, $event_dispatcher, $cache, $account_switcher, $file_system);
$this->staticDirectory = Settings::get('tome_static_directory', '../html');
}
/**
* Sets static directory.
*
* @param string $staticDirectory
* Static directory.
*
* @return $this
*/
public function setStaticDirectory(string $staticDirectory): StaticGeneratorInterface {
$this->staticDirectory = $staticDirectory;
return $this;
}
/**
* {@inheritdoc}
*/
public function getStaticDirectory() {
return $this->staticDirectory;
}
/**
* {@inheritdoc}
*/
public function getDestination($path): string {
$destination = parent::getDestination($path);
try {
$json_api_root = Url::fromRoute('jsonapi.resource_list')->toString();
}
catch (RouteNotFoundException $e) {
$json_api_root = FALSE;
}
if ($json_api_root && str_starts_with($destination, $this->getStaticDirectory() . $json_api_root)) {
$destination = $this->getStaticDirectory() . $json_api_root . '/' . Crypt::hashBase64($path) . '.json';
}
return $destination;
}
/**
* {@inheritdoc}
*/
public function sanitizePath($path) {
return parent::sanitizePath($path);
}
/**
* {@inheritdoc}
*/
protected function copyPath($path, $destination): bool {
if (StreamWrapperManager::getScheme($path)) {
return parent::copyPath($path, $destination);
}
$path = urldecode($path);
$base_path = base_path();
if ($base_path !== '/') {
$base_path = ltrim($base_path, '/');
$pattern = '|^' . preg_quote($base_path, '|') . '|';
$path = preg_replace($pattern, '', $path);
}
if (file_exists($path) && is_file($path)
) {
$this->copiedPaths[] = $path;
return TRUE;
}
return FALSE;
}
/**
* Gets value of CopiedPaths.
*
* @return string[]
* Value of CopiedPaths.
*/
public function getCopiedPaths(): array {
return $this->copiedPaths;
}
/**
* Resets copied paths.
*/
public function resetCopiedPaths() : void {
$this->copiedPaths = [];
}
/**
* Sets value of IsGenerating.
*
* @param bool $isGenerating
* Value for IsGenerating.
*/
public function setIsGenerating(bool $isGenerating): TomeStaticExtension {
$this->isGenerating = $isGenerating;
return $this;
}
/**
* Gets value of isGenerating.
*
* @return bool
* Value of isGenerating.
*/
public function isGenerating(): bool {
return $this->isGenerating;
}
/**
* Get the cache.
*
* @return \Drupal\tome_static\StaticCache
* The cache.
*/
public function getCache(): StaticCache {
return $this->cache;
}
/**
* {@inheritdoc}
*
* We override to use the source instead of the destination when parsing
* references to css/js files.
*/
public function exportPaths(array $paths) {
$paths = array_diff($paths, $this->getExcludedPaths());
$paths = array_values(array_unique($paths));
$invoke_paths = [];
foreach ($paths as $path) {
$path = $this->makeExternalUrlLocal($path);
if (UrlHelper::isExternal($path)) {
continue;
}
$destination = $this->getDestination($path);
$sanitized_path = $this->sanitizePath($path);
if ($this->copyPath($sanitized_path, $destination)) {
if (pathinfo($destination, PATHINFO_EXTENSION) === 'css') {
$css_assets = $this->getCssAssets(file_get_contents($sanitized_path), $sanitized_path);
$invoke_paths = array_merge($invoke_paths, $this->exportPaths($css_assets));
}
if (pathinfo($destination, PATHINFO_EXTENSION) === 'js') {
$js_modules = $this->getJavascriptModules(file_get_contents($sanitized_path), $sanitized_path);
$invoke_paths = array_merge($invoke_paths, $this->exportPaths($js_modules));
}
}
else {
$invoke_paths[] = $path;
}
}
return $this->filterInvokePaths($invoke_paths, $this->currentRequest);
}
}
