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 ]; // 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; } }