Синхронизировал частично с CMS2

This commit is contained in:
origami11 2017-02-09 17:14:11 +03:00
parent 6b412f5d6f
commit f2938b1353
30 changed files with 1447 additions and 1099 deletions

View file

@ -1,54 +1,212 @@
<?php
/**
* Обработка файлов для установки
*/
* <code>
* $setup = new Setup('test.xml');
* $setup->set('target', 'dst');
* $setup->executeActions('install');
* </code>
*/
class Setup
{
/**
* Содержимое PHP файла
*/
static function fileContent($file, array $tpl)
protected $actions = array();
public $context = array();
protected $file;
protected $action;
protected $node;
protected $stack = array();
public $zip;
public $target;
public function __construct($file)
{
ob_start();
include $file;
$result = ob_get_contents();
ob_clean();
return $result;
$this->file = $file;
$this->node = simplexml_load_file($file);
$this->target = '';
$this->zip = new ZipArchive();
$this->zip->open(strtr($file, array('.xml' => '.zip')));
array_push($this->stack, $this->node);
$this->registerAction('copy', array($this, 'copyFile'));
$this->registerAction('make-directory', array($this, 'makeDirectory'));
$this->registerAction('make-link', array($this, 'makeLink'));
$this->registerAction('include', array($this, 'includeFile'));
$this->registerAction('when', array($this, 'testWhen'));
}
/**
* Копирует файлы шаблонной директории
* Регистрация новых действия для установки
*/
static function copyTemplatePath($srcPath, $dstPath, array $tpl, $tplFile = 'tpl')
public function registerAction($name, $action)
{
$out = new Path($srcPath);
$path = new Path($dstPath);
$files = $path->getContentRec(null, array(".svn"));
$this->actions[$name] = $action;
}
foreach ($files as $file) {
if (Path::getExtension($file) == $tplFile) {
// Шаблон
$dst = $out->append($path->relPath (Path::skipExtension($file)));
Path::prepare($dst);
file_put_contents($dst, self::fileContent($file, $tpl));
} else {
// Обычный файл
$dst = $out->append($path->relPath ($file));
Path::prepare($dst);
copy($file, $dst);
}
/**
* Установка переменных для шаблона
*/
public function set($name, $value)
{
$this->context[$name] = $value;
}
function replaceFn($matches) {
if (isset($this->context[$matches[2]])) {
$v = $this->context[$matches[2]];
} else {
$v = $matches[2];
}
if ($matches[1] == '*') {
return addslashes($v);
}
return $v;
}
public function fileContent($file, array $tpl)
{
$result = $this->zip->getFromName($file);
$result = preg_replace_callback('/\{\{\s*(\*?)(\w+)\s*\}\}/', array($this, 'replaceFn'), $result);
return $result;
}
function callAction($name, array $attributes)
{
if(isset($this->actions[$name])) {
call_user_func_array($this->actions[$name], $attributes);
}
}
/**
* Заменяет переменные на их значения в строке
*/
function replaceVariable(array $match)
{
if (isset($this->context[$match[1]])) {
return $this->context[$match[1]];
}
return $match[0];
}
/**
* Для всех аттрибутов заменяет переменные на их значения
*/
function resolve($attributes)
{
$result = array();
foreach ($attributes as $key => $value) {
$result [$key] = preg_replace_callback("/\\\${(\w+)}/", array($this, 'replaceVariable'), $value);
}
return $result;
}
/**
* Выполняет список действий если для действия не указан аттрибут when то оно выполняется всегда
*
* @param $action специальное действие
*/
function executeActions($action = "install")
{
$this->action = $action;
if ($this->stack[count($this->stack) - 1] === false) {
return;
}
/*.SimpleXMLElement.*/$item = $this->stack[count($this->stack) - 1];
$root = $item->children();
foreach ($root as $node)
{
$attributes = $node->attributes();
array_push($this->stack, $node);
$this->callAction($node->getName(), array($this->resolve($attributes)));
array_pop($this->stack);
}
}
/**
* Копирования файла
* @param preserve Не переписывать файл если он существует
* @param template Файл является шаблоном подставить параметры до копирования
* @param src Исходный файл
* @param dst Новый файл
*/
public function copyFile(array $attributes)
{
$path = $this->targetPath($attributes['dst']);
if (!(file_exists($path) && isset($attributes['preserve']))) {
file_put_contents($path, $this->fileContent($attributes['src'], $this->context));
}
}
/**
* Создает символическую ссылку на папку/файл
* @param dst Имя папки
*/
public function makeLink(array $attributes)
{
if (function_exists('symlink')) {
symlink($attributes['target'], $attributes['link']);
}
}
/**
* Подключение файла установки
* @param file Имя подключаемого файла
*/
public function includeFile(array $attributes)
{
$file = basename($this->file) . "/" . $attributes['file'];
$setup = new Setup($file);
$setup->context = $this->context;
$setup->executeActions();
}
function targetPath($s) {
return $this->target . '/' . $s;
}
/**
* Создает новую папку
* @param dst Имя папки
*/
public function makeDirectory(array $attributes)
{
$path = $this->targetPath($attributes['dst']);
if (!file_exists($path)) {
mkdir($path);
}
}
function testWhen(array $attributes)
{
if (!isset($attributes['test']) || $attributes['test'] == $this->action) {
$this->executeActions($this->action);
}
}
/**
* Выполнение Списка SQL команд
*/
static function batchSQL(Connection $conn, $file)
function batchSQLZip(/*.Database.*/ $conn, $file)
{
$stmtList = SQLStatementExtractor::extractFile ($file);
$stmtList = Tools_SQLStatementExtractor::extract($this->zip->getFromName($file));
foreach ($stmtList as $stmt) {
$conn->executeQuery ($stmt);
}
}
static function batchSQL(/*.Database.*/ $conn, $file)
{
$stmtList = Utils_SQLStatementExtractor::extractFile($file);
foreach ($stmtList as $stmt) {
$conn->executeQuery ($stmt);
}
}
}