marc-leopold/server/plugins/rainlab/builder/classes/FilesystemGenerator.php

138 lines
4.4 KiB
PHP

<?php namespace RainLab\Builder\Classes;
use Lang;
use File;
use October\Rain\Parse\Bracket as TextParser;
use ApplicationException;
use SystemException;
/**
* Generates filesystem objects basing on a structure provided with an array
* and using file templates and variables. Variables in template files use
* the Twig syntax, but processed with October\Rain\Syntax\Bracket.
*
* Example - generate a plugin directory containing the plugin.php file.
* The file is created from a template, which uses a couple of variables.
*
* $structure = [
* 'author',
* 'author/plugin',
* 'author/plugin/plugin.php' => 'plugin.php.tpl'
* ];
* $generator = new FilesystemGenerator('$', $structure, '$/Author/Plugin/templates/plugin');
*
* $variables = [
* 'namespace' => 'Author/Plugin'
* ];
* $generator->setVariables($variables);
* $generator->generate();
*
* @package rainlab\builder
* @author Alexey Bobkov, Samuel Georges
*/
class FilesystemGenerator
{
protected $destinationPath;
protected $structure;
protected $variables = [];
protected $templatesPath;
/**
* Initializes the object.
* @param string $destinationPath Destination path to create the filesystem objects in.
* The path can contain filesystem symbols.
* @param array $structure Specifies the structure as array.
* @param string $templatesPath Path to the directory that contains file templates.
* The parameter is required only in case any files should be created. The path can
* contain filesystem symbols.
*/
public function __construct($destinationPath, array $structure, $templatesPath = null)
{
$this->destinationPath = File::symbolizePath($destinationPath);
$this->structure = $structure;
if ($templatesPath) {
$this->templatesPath = File::symbolizePath($templatesPath);
}
}
public function setVariables($variables)
{
foreach ($variables as $key=>$value) {
$this->setVariable($key, $value);
}
}
public function setVariable($key, $value)
{
$this->variables[$key] = $value;
}
public function generate()
{
if (!File::isDirectory($this->destinationPath)) {
throw new SystemException(Lang::get('rainlab.builder::lang.common.destination_dir_not_exists', ['path'=>$this->destinationPath]));
}
foreach ($this->structure as $key=>$value) {
if (is_numeric($key)) {
$this->makeDirectory($value);
}
else {
$this->makeFile($key, $value);
}
}
}
public function getTemplateContents($templateName)
{
$templatePath = $this->templatesPath.DIRECTORY_SEPARATOR.$templateName;
if (!File::isFile($templatePath)) {
throw new SystemException(Lang::get('rainlab.builder::lang.common.template_not_found', ['name'=>$templateName]));
}
$fileContents = File::get($templatePath);
return TextParser::parse($fileContents, $this->variables);
}
protected function makeDirectory($dirPath)
{
$path = $this->destinationPath.DIRECTORY_SEPARATOR.$dirPath;
if (File::isDirectory($path)) {
throw new ApplicationException(Lang::get('rainlab.builder::lang.common.error_dir_exists', ['path'=>$path]));
}
if (!File::makeDirectory($path, 0777, true, true)) {
throw new SystemException(Lang::get('rainlab.builder::lang.common.error_make_dir', ['name'=>$path]));
}
}
protected function makeFile($filePath, $templateName)
{
$path = $this->destinationPath.DIRECTORY_SEPARATOR.$filePath;
if (File::isFile($path)) {
throw new ApplicationException(Lang::get('rainlab.builder::lang.common.error_file_exists', ['path'=>$path]));
}
$fileDirectory = dirname($path);
if (!File::isDirectory($fileDirectory)) {
if (!File::makeDirectory($fileDirectory, 0777, true, true)) {
throw new SystemException(Lang::get('rainlab.builder::lang.common.error_make_dir', ['name'=>$fileDirectory]));
}
}
$fileContents = $this->getTemplateContents($templateName);
if (@File::put($path, $fileContents) === false) {
throw new SystemException(Lang::get('rainlab.builder::lang.common.error_generating_file', ['path'=>$path]));
}
@File::chmod($path);
}
}