/* Decoded by unphp.net */ * * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ declare(strict_types=1); namespace Zephir\Documentation; use Zephir\Documentation; use Zephir\Exception; use function array_unshift; use function closedir; use function copy; use function count; use function explode; use function file_exists; use function file_get_contents; use function file_put_contents; use function is_array; use function is_dir; use function json_decode; use function json_encode; use function ltrim; use function mkdir; use function opendir; use function pathinfo; use function readdir; use function str_repeat; use function str_replace; use function strpos; use function touch; class Theme { /** * @var Documentation */ protected $documentation; /** * @var Theme */ protected $extendedTheme; protected $options; protected $outputDir; protected $projectConfig; protected $themeConfig; protected $themeDir; protected $themeInfos = []; public function __construct($themeDir, $outputDir, $themeConfig, $config, Documentation $documentation) { $this->outputDir = $outputDir; $this->themeConfig = $themeConfig; $this->themeDir = $themeDir; $this->options = $themeConfig['options']; $this->projectConfig = $config; $this->documentation = $documentation; $themeInfosPath = $this->getThemePath('theme.json'); if ($themeInfosPath) { $themeInfos = json_decode(file_get_contents($themeInfosPath), true); if (!$themeInfos) { throw new Exception("Cant parse file $themeInfosPath"); } else { $this->themeInfos = $themeInfos; if (isset($themeInfos['extends'])) { $extThemePath = $documentation->findThemePathByName($themeInfos['extends']); if (!$extThemePath) { throw new Exception('Unable to find extended theme ' . $themeInfos['extends']); } $this->extendedTheme = new self($extThemePath, $outputDir, $themeConfig, $config, $documentation); } } } } public function buildJsonClassDefinition($classList, NamespaceAccessor $nsA) { $output = [ 'allClasses' => [], 'allNamespaces' => [], 'classes' => [], 'namespaces' => [], ]; foreach ($classList as $class) { $cDef = $class->getClassDefinition(); $cName = $cDef->getCompleteName(); $output['allClasses'][$cName] = [ 'type' => $cDef->getType(), 'name' => $cName, 'shortname' => $cDef->getName(), ]; if (!strpos($cName, '\') > 0) { $output['classes'][] = $cName; } } $namespaces = $nsA->getByNamespace(); foreach ($namespaces as $ns) { $subclasses = []; $subnamespaces = []; foreach ($ns->getClasses() as $scs) { $subclasses[] = $scs->getClassDefinition()->getCompleteName(); } foreach ($ns->getNamespaces() as $sns) { $subnamespaces[] = $sns->getFullNamespace(); } $output['allNamespaces'][$ns->getFullNamespace()] = [ 'name' => $ns->getFullNamespace(), 'shortName' => $ns->getShortName(), 'parentName' => $ns->getParentName(), 'classes' => $subclasses, 'namespaces' => $subnamespaces, ]; if (!strpos($ns->getFullNamespace(), '\') > 0) { $output['namespaces'][] = $ns->getFullNamespace(); } } return json_encode($output); } /** * copy the static directory of the theme into the output directory. */ public function buildStaticDirectory(): void { $outputStt = $this->getOutputPath('asset'); if (!file_exists($outputStt)) { mkdir($outputStt, 0777, true); } $this->extendedTheme?->buildStaticDirectory(); $themeStt = $this->getThemePath('static'); if ($themeStt) { $files = []; $this->__copyDir($themeStt, $outputStt . '/static', $files); foreach ($files as $f) { foreach ($this->options as $optName => $opt) { $fcontent = file_get_contents($f); $fcontent = str_replace('%_' . $optName . '_%', $opt, $fcontent); file_put_contents($f, $fcontent); } } } } public function createFile($path, $content): void { $outputFile = $this->getOutputPath($path); touch($outputFile); file_put_contents($outputFile, $content); } /** * Parse and draw the specified file. * * @param FileInterface $file * * @throws Exception */ public function drawFile(FileInterface $file): void { $outputFile = ltrim($file->getOutputFile(), '/'); $output = pathinfo($this->outputDir . '/' . $outputFile); $outputDirname = $output['dirname']; $outputBasename = $output['basename']; $outputFilename = $outputDirname . '/' . $outputBasename; // todo : check if writable if (!file_exists($outputDirname)) { mkdir($outputDirname, 0777, true); } $subDirNumber = count(explode('/', $outputFile)) - 1; if ($subDirNumber > 0) { $pathToRoot = str_repeat('../', $subDirNumber); } else { $pathToRoot = './'; } $template = new Template($this, $file->getData(), $file->getTemplateName()); $template->setPathToRoot($pathToRoot); $template->setThemeOptions($this->options); $template->setProjectConfig($this->projectConfig); touch($outputFilename); $template->write($outputFilename); } public function getOutputPath($path) { $path = pathinfo($this->outputDir . '/' . $path); $pathDirname = $path['dirname']; $pathBasename = $path['basename']; $pathFilename = $pathDirname . '/' . $pathBasename; return $pathFilename; } /** * Get assets from the theme info (theme.json file placed inside the theme directory). * * @param string $name * * @return mixed|null */ public function getThemeInfo($name) { if (isset($this->themeInfos[$name])) { return $this->themeInfos[$name]; } return null; } /** * Similar with getThemeInfo but includes the value for all extended themes, and returns the results as an array. * * @param string $name * * @return array */ public function getThemeInfoExtendAware($name) { if ($this->extendedTheme) { $data = $this->extendedTheme->getThemeInfoExtendAware($name); } else { $data = []; } $info = $this->getThemeInfo($name); array_unshift($data, $info); return $data; } /** * find the path to a file in the theme. * * @param $path * * @return string */ public function getThemePath($path) { $path = pathinfo($this->themeDir . '/' . $path); $pathDirname = $path['dirname']; $pathBasename = $path['basename']; $pathFilename = $pathDirname . '/' . $pathBasename; if (!file_exists($pathFilename)) { return null; } return $pathFilename; } /** * find the path to a file in the theme or from the extended theme. * * @param $path * * @return string */ public function getThemePathExtendsAware($path) { $newPath = $this->getThemePath($path); if (!$newPath) { if ($this->extendedTheme) { return $this->extendedTheme->getThemePathExtendsAware($path); } } return $newPath; } /** * from : https://stackoverflow.com/questions/2050859/copy-entire-contents-of-a-directory-to-another-using-php. * * @param $src * @param $dst * @param $files */ private function __copyDir($src, $dst, &$files = null): void { $dir = opendir($src); @mkdir($dst); while (false !== ($file = readdir($dir))) { if (('.' != $file) && ('..' != $file)) { if (is_dir($src . '/' . $file)) { $this->__copyDir($src . '/' . $file, $dst . '/' . $file, $files); } else { copy($src . '/' . $file, $dst . '/' . $file); if (is_array($files)) { $files[] = $dst . '/' . $file; } } } } closedir($dir); } } ?>