Files
core/app/Handlers/Registrators/TemplateRegistrator.php
T

285 lines
8.1 KiB
PHP

<?php
namespace App\Handlers\Registrators;
use App\Enumerations\TemplatePaths;
use App\Enumerations\Templates;
use App\Models\Template;
use App\Models\TemplatePath;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Symfony\Component\Process\Exception\InvalidArgumentException;
class TemplateRegistrator
{
/**
* @var string absolute path to base directory of registered template paths
*/
protected $baseDirectory;
/**
* @var string namespace of registered templates
*/
protected $namespace;
/**
* @var string absolute path to currently registered directory
* This variable is set in register() method as $baseDirectory/$path
*/
protected $registeredPath;
/**
* @var int ID of module
*/
protected $moduleId;
/**
* Set base path
*
* @param mixed $baseDirectory
*/
public function setBaseDirectory($baseDirectory)
{
$baseDirectory = str_replace('/', DIRECTORY_SEPARATOR, $baseDirectory);
$baseDirectory = base_path($baseDirectory);
$baseDirectory = rtrim($baseDirectory, DIRECTORY_SEPARATOR);
if (!is_dir($baseDirectory)) {
throw new InvalidArgumentException('Invalid path ' . $baseDirectory);
}
$this->baseDirectory = $baseDirectory;
}
/**
* Set module ID for registered path
*
* @param int $moduleId
*/
public function setModuleId($moduleId)
{
$this->moduleId = $moduleId;
}
/**
* Set namespace for registered template path
*
* @param string $namespace
*/
public function setNamespace($namespace)
{
$this->namespace = $namespace . '::';
}
/**
* Resets namespace
*/
public function unsetNamespace()
{
$this->namespace = null;
$this->setModuleId(null);
}
/**
* Registers new template path.
* This method registeres given path itself with all subdirectories
*
* @param string $path path relatively to root of the project
* @param string $name human readable identification of given template path
*
* @throws \Exception
*/
public function register($path, $name)
{
// check if base directory was set
if (!$this->baseDirectory || !is_dir($this->baseDirectory)) {
throw new \Exception('Set $baseDirectory before registering template path.');
}
$this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path;
// register path
$this->registerPath($this->registeredPath, $name);
$this->unsetNamespace();
}
/**
* Get relative path to project root
*
* @param $directory
*
* @return string
*/
protected function relativePath($directory)
{
return trim(str_replace(base_path(), '', $directory), '/');
}
/**
* Crawl subdirectories and register them
*
* @param string $directory path relative to $baseDirectory variable
* @param string $name name of parent directory
*/
protected function scanForSubdirectories($directory, $name)
{
$directories = File::directories($directory);
foreach ($directories as $dir) {
$base = basename($dir);
$name = preg_replace('/\.(.+)/', '.' . $base, $name);
$this->registerPath($dir, $name, $directory);
}
}
/**
* Registers template path and templates into system
*
* @param string $path relative path to $baseDirectory variable
* @param string $name human readable name of this path (used in overview)
* @param null|string $parent path to parent directory
*/
protected function registerPath($path, $name, $parent = null)
{
// skip custom directories (contains updated templates only)
$dirName = basename($path);
$ignoredDirectories = [
Template::EDITED_TEMPLATES_DIRECTORY,
Template::ASSETS_DIRECTORY,
Template::MODULES_DIRECTORY
];
if (in_array($dirName, $ignoredDirectories)) {
return;
}
// save template path into database
$templatePathId = $this->saveTemplatePath($path, $name, $parent);
// save all templates into database
$this->registerTemplates($path, $templatePathId);
// try to find some subdirectories and other templates
$this->scanForSubdirectories($path, $name);
}
/**
* Registers all templates
* This method takes all templates in given directory and registers them into database. Templates registered in
* this way may be used for further manipulation.
*
* @param $path
* @param $templatePathId
*
* @throws \App\Enumerations\Exceptions\EnumerationExistsException
*/
protected function registerTemplates($path, $templatePathId)
{
$templates = File::files($path);
foreach ($templates as $template) {
// skip all non-template files - we assume that every file with suffix ".blade.php" is Blade template
if (!Str::endsWith($template, Template::TEMPLATE_SUFFIX)) {
continue;
}
// get all templates and template name (path/to/template.blade.php -> path.to.template)
$templateName = $this->getTemplateName($template);
$registeredTemplates = Templates::getWithTranslations();
if (!in_array($templateName, $registeredTemplates)) {
$params = [
'template_name' => $templateName,
'name' => $templateName,
'path' => $templatePathId,
'module_id' => $this->moduleId,
'description' => '',
'editable' => 1
];
echo 'ukladam do db '.$templateName."\n";
// save template into database
$newTemplate = Template::create($params);
// push template into enumeration - so it will not be registered again
Templates::push($newTemplate->id, $templateName);
}
}
}
/**
* Save template into database and return its ID
*
* @param $path
* @param $name
* @param null $parent
*
* @return mixed|null
* @throws \App\Enumerations\Exceptions\EnumerationExistsException
*/
protected function saveTemplatePath($path, $name, $parent = null)
{
$registeredPaths = TemplatePaths::getWithTranslations();
$relativePath = $this->relativePath($path);
if (!in_array($relativePath, $registeredPaths)) {
$parentId = $this->getId($this->relativePath($parent));
$params = [
'path' => $relativePath,
'name' => $name,
'namespace' => $this->namespace,
'parent_id' => $parentId
];
// save into database
$path = TemplatePath::create($params);
// add to enumeration
TemplatePaths::push($path->id, $relativePath);
return $path->id;
}
return $this->getId($relativePath);
}
/**
* Get ID of registered template
*
* @param $path
*
* @return null|int null when parent not found, ID of parent otherwise
*/
private function getId($path)
{
// get registered paths
$paths = TemplatePaths::getWithTranslations();
$paths = array_flip($paths);
if (is_null($path) || !isset($paths[$path])) {
return null;
}
return $paths[$path];
}
/**
* Get template name
* Converts path to template to corresponding name
*
* @param $template
*
* @return string
*/
private function getTemplateName($template)
{
$templateName = str_replace($this->registeredPath . DIRECTORY_SEPARATOR, '', $template);
$templateName = str_replace(DIRECTORY_SEPARATOR, '.', $templateName);
$templateName = str_replace(Template::TEMPLATE_SUFFIX, '', $templateName);
return $this->namespace . $templateName;
}
}