phplibrary/src/Setup.php

233 lines
6.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* <code>
* $setup = new Setup('test.xml');
* $setup->set('target', 'dst');
* $setup->executeActions('install');
* </code>
*/
namespace ctiso;
use ctiso\Tools\SQLStatementExtractor;
use ctiso\Path;
class FakeZipArchive {
public $base;
function open($path) {
$this->base = $path;
}
function getFromName($file) {
return file_get_contents(Path::join($this->base, $file));
}
}
class Setup
{
protected $actions = array();
public $context = array();
protected $file;
protected $action;
protected $node;
protected $stack = array();
public $zip;
public $target;
public $source;
public function __construct($file)
{
$this->file = $file;
$this->node = simplexml_load_file($file);
$this->target = '';
$this->source = '';
$this->zip = new FakeZipArchive();
$this->zip->open(dirname($this->file) . '/' . $this->node->attributes()['dir']);
array_push($this->stack, $this->node);
$this->registerAction('copy', [$this, 'copyFile']);
$this->registerAction('make-directory', [$this, 'makeDirectory']);
$this->registerAction('make-link', [$this, 'makeLink']);
$this->registerAction('include', [$this, 'includeFile']);
$this->registerAction('when', [$this, 'testWhen']);
}
/**
* Регистрация новых действия для установки
*/
public function registerAction($name, $action)
{
$this->actions[$name] = $action;
}
/**
* Установка переменных для шаблона
*/
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*\}\}/', [$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 = [];
foreach ($attributes as $key => $value) {
$result [$key] = preg_replace_callback("/\\\${(\w+)}/", [$this, 'replaceVariable'], $value);
}
return $result;
}
/**
* Выполняет список действий если для действия не указан аттрибут when то оно выполняется всегда
*
* @param string $action специальное действие
*/
function executeActions($action = "install")
{
$this->action = $action;
if ($this->stack[count($this->stack) - 1] === false) {
return;
}
$item/*: \SimpleXMLElement*/ = $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(), [$this->resolve($attributes)]);
array_pop($this->stack);
}
}
/**
* Копирования файла
* preserve - Не переписывать файл если он существует
* template Файл является шаблоном подставить параметры до копирования
* src Исходный файл
* dst Новый файл
*
* @param array{preserve?: string, template: string, src: string, dst: string} $attributes
*/
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 array{target: string, link: string} $attributes
*/
public function makeLink(array $attributes)
{
if (function_exists('symlink')) {
symlink($attributes['target'], $attributes['link']);
}
}
/**
* Подключение файла установки
* @param array{file: string} $attributes Имя подключаемого файла
*/
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;
}
/**
* Создает новую папку
* dst Имя папки
*
* @param array{dst:string} $attributes
*/
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 команд
*/
function batchSQLZip($conn/*: Database*/, $file)
{
$stmtList = SQLStatementExtractor::extract($this->zip->getFromName($file));
foreach ($stmtList as $stmt) {
$conn->executeQuery ($stmt);
}
}
static function batchSQL($conn/*: Database*/, $file)
{
$stmtList = SQLStatementExtractor::extractFile($file);
foreach ($stmtList as $stmt) {
$conn->executeQuery ($stmt);
}
}
}