Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates;
|
||||
|
||||
use Xentral\Core\DependencyInjection\ContainerInterface;
|
||||
use Xentral\Modules\SystemTemplates\Validator\MetaDataValidation;
|
||||
use Xentral\Modules\SystemTemplates\Validator\Ruleset;
|
||||
use Xentral\Modules\SystemTemplates\Validator\SystemTemplateValidator;
|
||||
|
||||
final class Bootstrap
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function registerServices()
|
||||
{
|
||||
return [
|
||||
'SystemTemplatesService' => 'onInitSystemTemplatesService',
|
||||
'SystemTemplatesGateway' => 'onInitSystemTemplatesGateway',
|
||||
'MetaDataValidation' => 'onInitMetaDataValidation',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
*
|
||||
* @return SystemTemplatesService
|
||||
*/
|
||||
public static function onInitSystemTemplatesService(ContainerInterface $container)
|
||||
{
|
||||
/** @var string $templateFilePath */
|
||||
$templateFilePath = __DIR__ . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR;
|
||||
|
||||
return new SystemTemplatesService(
|
||||
$container->get('SystemTemplatesGateway'),
|
||||
$container->get('DatabaseBackup'),
|
||||
$container->get('FileBackup'),
|
||||
$container->get('BackupService'),
|
||||
$container->get('Database'),
|
||||
$container->get('MetaDataValidation'),
|
||||
$container->get('BackupLog'),
|
||||
$templateFilePath
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
*
|
||||
* @return SystemTemplatesGateway
|
||||
*/
|
||||
public static function onInitSystemTemplatesGateway(ContainerInterface $container)
|
||||
{
|
||||
return new SystemTemplatesGateway($container->get('Database'), $container->get('BackupGateway'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SystemTemplateValidator
|
||||
*/
|
||||
public static function onInitMetaDataValidation()
|
||||
{
|
||||
/** @var string $templateFilePath */
|
||||
$templateFilePath = __DIR__ . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR;
|
||||
|
||||
return new SystemTemplateValidator(new MetaDataValidation(new Ruleset(),$templateFilePath));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Exception;
|
||||
|
||||
use InvalidArgumentException as SplInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class InvalidArgumentException
|
||||
*
|
||||
* @package Xentral\Modules\SystemTemplates\Exception
|
||||
*/
|
||||
class InvalidArgumentException extends SplInvalidArgumentException implements SystemTemplatesExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Exception;
|
||||
|
||||
use RuntimeException as SplRuntimeException;
|
||||
|
||||
/**
|
||||
* Class RuntimeException
|
||||
*
|
||||
* @package Xentral\Modules\SystemTemplates\Exception
|
||||
*/
|
||||
class RuntimeException extends SplRuntimeException implements SystemTemplatesExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Exception;
|
||||
|
||||
use Xentral\Core\Exception\ModuleExceptionInterface;
|
||||
|
||||
/**
|
||||
* Interface SystemTemplatesExceptionInterface
|
||||
*
|
||||
* @package Xentral\Modules\SystemTemplates\Exception
|
||||
*/
|
||||
interface SystemTemplatesExceptionInterface extends ModuleExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\Backup\BackupGateway;
|
||||
|
||||
final class SystemTemplatesGateway
|
||||
{
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/** @var BackupGateway $gateway */
|
||||
private $gateway;
|
||||
|
||||
/**
|
||||
* SystemTemplatesGateway constructor.
|
||||
*
|
||||
* @param Database $db
|
||||
* @param BackupGateway $gateway
|
||||
*/
|
||||
public function __construct(Database $db, BackupGateway $gateway)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->gateway = $gateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateById(int $id): array
|
||||
{
|
||||
return $this->db->fetchRow(
|
||||
'SELECT
|
||||
s.id,
|
||||
s.title,
|
||||
s.category,
|
||||
s.description,
|
||||
s.filename,
|
||||
s.created_at,
|
||||
s.footer_icons
|
||||
FROM `systemtemplates` AS `s` WHERE s.hidden = 0 AND s.id = :id',
|
||||
['id' => $id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTables(): array
|
||||
{
|
||||
return $this->gateway->getTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTablesChecksum(): array
|
||||
{
|
||||
return $this->gateway->getTablesChecksum();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAdminUserIds(): array
|
||||
{
|
||||
return $this->gateway->getAdminUserIds();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates;
|
||||
|
||||
use Config;
|
||||
use Xentral\Components\Backup\DatabaseBackup;
|
||||
use Xentral\Components\Backup\FileBackup;
|
||||
use Xentral\Components\Backup\Logger\BackupLog;
|
||||
use Xentral\Components\Database\Exception\DatabaseExceptionInterface;
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\Backup\BackupGateway;
|
||||
use Xentral\Modules\Backup\BackupService;
|
||||
use Xentral\Modules\SystemTemplates\Exception\InvalidArgumentException;
|
||||
use Xentral\Modules\SystemTemplates\Exception\RuntimeException;
|
||||
use Xentral\Modules\SystemTemplates\Validator\Exception\SystemTemplateValidatorException;
|
||||
use Xentral\Modules\SystemTemplates\Validator\SystemTemplateValidator;
|
||||
use Xentral\Modules\Backup\Exception\RuntimeException As BackupModuleRuntimeException;
|
||||
use ZipArchive;
|
||||
use \Exception;
|
||||
|
||||
final class SystemTemplatesService
|
||||
{
|
||||
/** @var BackupGateway $gateway */
|
||||
private $gateway;
|
||||
|
||||
/** @var string file */
|
||||
const META_FILE = 'meta.json';
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/** @var FileBackup $oFileBackup */
|
||||
private $oFileBackup;
|
||||
|
||||
/** @var DatabaseBackup $oDbBackup */
|
||||
private $oDbBackup;
|
||||
|
||||
/** @var BackupLog $logger */
|
||||
private $logger;
|
||||
|
||||
/** @var string $templateFilePath */
|
||||
private $templateFilePath;
|
||||
|
||||
/** @var SystemTemplateValidator $validator */
|
||||
private $validator;
|
||||
|
||||
/** @var BackupService $backupService */
|
||||
private $backupService;
|
||||
|
||||
/**
|
||||
* SystemTemplatesService constructor.
|
||||
*
|
||||
* @param SystemTemplatesGateway $gateway
|
||||
* @param DatabaseBackup $oDbBackup
|
||||
* @param FileBackup $oFileBackup
|
||||
* @param BackupService $backupService
|
||||
* @param Database $database
|
||||
* @param SystemTemplateValidator $validator
|
||||
* @param BackupLog $logger
|
||||
* @param string $templateFilePath
|
||||
*/
|
||||
public function __construct(
|
||||
SystemTemplatesGateway $gateway,
|
||||
DatabaseBackup $oDbBackup,
|
||||
FileBackup $oFileBackup,
|
||||
BackupService $backupService,
|
||||
Database $database,
|
||||
SystemTemplateValidator $validator,
|
||||
BackupLog $logger,
|
||||
string $templateFilePath
|
||||
) {
|
||||
$this->gateway = $gateway;
|
||||
$this->db = $database;
|
||||
$this->oFileBackup = $oFileBackup;
|
||||
$this->oDbBackup = $oDbBackup;
|
||||
$this->logger = $logger;
|
||||
$this->templateFilePath = $templateFilePath;
|
||||
$this->validator = $validator;
|
||||
$this->backupService = $backupService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $templates
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function importTemplates(array $templates = []): bool
|
||||
{
|
||||
|
||||
if (empty($templates)) {
|
||||
throw new InvalidArgumentException('Templates data are missing!');
|
||||
}
|
||||
|
||||
$this->db->beginTransaction();
|
||||
$this->db->perform('DELETE FROM `systemtemplates`');
|
||||
|
||||
try {
|
||||
foreach ($templates as $template) {
|
||||
$this->addTemplate($template);
|
||||
}
|
||||
} catch (DatabaseExceptionInterface $exception) {
|
||||
$this->db->rollBack();
|
||||
|
||||
return false;
|
||||
} catch (InvalidArgumentException $exception) {
|
||||
$this->db->rollBack();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $template
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function addTemplate(array $template = []): void
|
||||
{
|
||||
if (empty($template)) {
|
||||
throw new InvalidArgumentException('Template cannot be empty');
|
||||
}
|
||||
if (!is_array($template)) {
|
||||
throw new InvalidArgumentException('Template should be an Array');
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$this->validator->fromMeta($template)->isValid()) {
|
||||
throw new InvalidArgumentException(json_encode($this->validator->getErrors()));
|
||||
}
|
||||
} catch (SystemTemplateValidatorException $exception) {
|
||||
throw new InvalidArgumentException($exception->getMessage());
|
||||
}
|
||||
|
||||
$sql = 'INSERT INTO systemtemplates (filename, category, title, description)
|
||||
VALUES (:filename, :category, :title, :description)';
|
||||
$this->db->perform($sql, $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTemplatesDir(): string
|
||||
{
|
||||
return $this->templateFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $key
|
||||
*
|
||||
* @throws InvalidArgumentException | RuntimeException
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getMetaContent(?string $key = null)
|
||||
{
|
||||
if (!file_exists($sMetaFile = $this->getTemplatesDir() . static::META_FILE)) {
|
||||
throw new InvalidArgumentException(sprintf('Cannot find meta file'));
|
||||
}
|
||||
|
||||
if (empty($sJsonContent = file_get_contents($sMetaFile))) {
|
||||
throw new RuntimeException('Meta content cannot be read');
|
||||
}
|
||||
|
||||
if (($xData = json_decode($sJsonContent, true)) !== null && (json_last_error() === JSON_ERROR_NONE)) {
|
||||
|
||||
if ($key !== null && array_key_exists($key, $xData)) {
|
||||
return $xData[$key];
|
||||
}
|
||||
|
||||
return $xData;
|
||||
}
|
||||
throw new RuntimeException('Reading Meta data failed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|false|string
|
||||
*/
|
||||
public function getMetaFileCheckSum()
|
||||
{
|
||||
if (file_exists($sMetaFile = $this->getTemplatesDir() . static::META_FILE)) {
|
||||
return md5_file($sMetaFile);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFullFilePath(string $fileName): string
|
||||
{
|
||||
if (!empty($fileName)) {
|
||||
return $this->getTemplatesDir() . $fileName;
|
||||
}
|
||||
throw new RuntimeException('Filename is missing');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Config $config
|
||||
* @param string $filename
|
||||
* @param array $options
|
||||
*/
|
||||
public function install(Config $config, string $filename, array $options = []): void
|
||||
{
|
||||
|
||||
if ($sTmpDir = $this->oFileBackup->begin($this->getTemplatesDir())) {
|
||||
$ssid = array_key_exists('ssid', $options) ? $options['ssid'] : null;
|
||||
|
||||
$this->logger->write('--BEGIN--');
|
||||
if (null !== $ssid) {
|
||||
$this->logger->write($ssid, null, BackupService::SESSION_FILE, false, false);
|
||||
}
|
||||
$sBackupTmpFullPath = $sTmpDir . 'backup_temp.sql';
|
||||
$this->logger->write('DUMP backup table');
|
||||
$this->oDbBackup->createDump($this->backupService->convertLegacyDbConf($config), $sBackupTmpFullPath,
|
||||
'backup');
|
||||
$sMySQLFile = $this->backupService->getMySQLFileName($filename) . '.gz';
|
||||
|
||||
$FullBckPath = $this->getFullFilePath($filename);
|
||||
$oZip = new ZipArchive;
|
||||
$xRes = $oZip->open($FullBckPath);
|
||||
$this->logger->write('Fetch Database DUMP from template archive');
|
||||
if ($xRes !== true) {
|
||||
throw new RuntimeException(sprintf('Database Dump not found in %s', $FullBckPath));
|
||||
}
|
||||
$oZip->extractTo($sTmpDir, [$sMySQLFile]);
|
||||
$oZip->close();
|
||||
$licenseData = $this->db->fetchRow(
|
||||
'SELECT `lizenz`, `schluessel` FROM `firmendaten` ORDER BY `id` DESC LIMIT 1'
|
||||
);
|
||||
$asTables = $this->gateway->getTables();
|
||||
$this->logger->write('DROP ALL TABLES');
|
||||
foreach ($asTables as $sTable) {
|
||||
$this->db->perform('DROP TABLE IF EXISTS ' . $sTable);
|
||||
}
|
||||
$sMySQLFullPath = $sTmpDir . $sMySQLFile;
|
||||
$this->logger->write('RESTORE Template Databases');
|
||||
$this->oDbBackup->restoreDump($this->backupService->convertLegacyDbConf($config), $sMySQLFullPath);
|
||||
// remove Backup Dump
|
||||
$this->logger->write('REMOVE DUMP FILE');
|
||||
@unlink($sMySQLFullPath);
|
||||
|
||||
// RESTORE Backup table
|
||||
$this->logger->write('RESTORE Backup table');
|
||||
$this->oDbBackup->restoreDump($this->backupService->convertLegacyDbConf($config),
|
||||
$sBackupTmpFullPath . '.gz');
|
||||
@unlink($sBackupTmpFullPath . '.gz');
|
||||
if (!empty($licenseData)) {
|
||||
$lastId = $this->db->fetchCol('SELECT MAX(`id`) FROM `firmendaten`');
|
||||
$this->db->perform(
|
||||
'UPDATE `firmendaten` SET `lizenz` = :license, `schluessel` = :authkey WHERE `id` = :id',
|
||||
['license' => $licenseData['lizenz'], 'authkey' => $licenseData['schluessel'], 'id' => $lastId]
|
||||
);
|
||||
}
|
||||
$this->logger->write('RESTORE Local Template files ');
|
||||
|
||||
$restoreOptions = ['template_file_dir' => $this->getTemplatesDir()];
|
||||
if (array_key_exists('exclude_dir', $options) && is_array($options['exclude_dir'])) {
|
||||
$restoreOptions['exclude_dir'] = $options['exclude_dir'];
|
||||
}
|
||||
foreach(['dms', 'pdfarchiv', 'pdfmirror', 'emailbackup', 'uebertragung'] as $subDirectory) {
|
||||
@exec('rm -Rf '.$config->WFuserdata.$subDirectory.'/'.$config->WFdbname);
|
||||
}
|
||||
|
||||
$this->oFileBackup->restoreFileSystem($filename, $config->WFuserdata, $restoreOptions);
|
||||
if (array_key_exists('user_id', $options)) {
|
||||
$iUserId = $options['user_id'];
|
||||
$ssid = array_key_exists('ssid', $options) ? $options['ssid'] : null;
|
||||
$ip = array_key_exists('ip', $options) ? $options['ip'] : null;
|
||||
$this->logger->write('RECONNECT current User');
|
||||
$this->backupService->reconnectUser($iUserId, $ssid, $ip);
|
||||
}
|
||||
@unlink($config->WFuserdata.'/cronjobkey.txt');
|
||||
$this->logger->write('--END--');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $templateFileName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function checkSumOnAfterInstall(string $templateFileName): ?array
|
||||
{
|
||||
$hDbCheckSums = $this->gateway->getTablesChecksum();
|
||||
$metaFileName = $this->oDbBackup->getMetaFileName($templateFileName);
|
||||
$metaPath = $this->getTemplatesDir() . $metaFileName;
|
||||
if (($xData = $this->oDbBackup->getMetaInfo($metaPath)) && !empty($hFileCheckSums = $xData['tables'])) {
|
||||
$hDiff = array_diff_assoc($this->oDbBackup->excludeCheckSumTables($hDbCheckSums),
|
||||
$this->oDbBackup->excludeCheckSumTables($hFileCheckSums));
|
||||
|
||||
return !empty($hDiff) ? array_keys($hDiff) : [];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param string|null $userPath
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getDumpMetaData(string $filename, ?string $userPath = null)
|
||||
{
|
||||
$userPath = null === $userPath ? $this->getTemplatesDir() : $userPath;
|
||||
$filePath = $this->oFileBackup->getLocalPath($filename, $userPath, false);
|
||||
|
||||
return $this->oDbBackup->getDumpMetaData($filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xConfig
|
||||
* @param string $identifier
|
||||
* @param string $sParam
|
||||
* @param string $cronFile
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function addToProcessStarter(
|
||||
string $xConfig,
|
||||
string $identifier = 'Vorlage/System-Backup',
|
||||
string $sParam = 'system_template_configuration_cron',
|
||||
string $cronFile = 'system_template'
|
||||
): bool
|
||||
{
|
||||
try {
|
||||
return $this->backupService->addToProcessStarter($xConfig, $identifier, $sParam, $cronFile);
|
||||
} catch (BackupModuleRuntimeException $exception) {
|
||||
throw new RuntimeException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeLoggerFiles(): void
|
||||
{
|
||||
$this->backupService->removeLoggerFiles();
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Validator\Exception;
|
||||
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class SystemTemplateValidatorException extends RuntimeException implements SystemTemplateValidatorExceptionInterface
|
||||
{
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Validator\Exception;
|
||||
|
||||
interface SystemTemplateValidatorExceptionInterface
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Validator;
|
||||
|
||||
use Xentral\Modules\SystemTemplates\Validator\Exception\SystemTemplateValidatorException;
|
||||
|
||||
|
||||
final class MetaDataValidation implements SystemTemplateValidatorInterface
|
||||
{
|
||||
/** @var array $data */
|
||||
private $data = [];
|
||||
|
||||
/** @var array $errors */
|
||||
private $errors = [];
|
||||
|
||||
/** @var string $templePath */
|
||||
private $templePath;
|
||||
|
||||
/** @var array $mandatoryFields */
|
||||
private $mandatoryFields = [];
|
||||
|
||||
/** @var bool $autoRulesCheck */
|
||||
private $autoRulesCheck;
|
||||
|
||||
/** @var Ruleset $ruleSet */
|
||||
private $ruleSet;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function validateDefault()
|
||||
{
|
||||
return [
|
||||
'title' => [
|
||||
'rule' => static function ($data) {
|
||||
return !empty($data['title']) && is_string($data['title']);
|
||||
},
|
||||
'required' => true,
|
||||
'message' => sprintf('%s should be a non empty String', 'Title'),
|
||||
],
|
||||
'description' => [
|
||||
'rule' => static function ($data) {
|
||||
return !empty($data['description']) && is_string($data['description']);
|
||||
},
|
||||
'required' => true,
|
||||
'message' => sprintf('%s should be a non empty String', 'Description'),
|
||||
],
|
||||
'category' => [
|
||||
'rule' => static function ($data) {
|
||||
return !empty($data['category']) && is_string($data['category']);
|
||||
},
|
||||
'required' => true,
|
||||
'message' => sprintf('%s should be a non empty String', 'Category'),
|
||||
],
|
||||
'filename' => [
|
||||
'rule' => ['isFileName'],
|
||||
'required' => true,
|
||||
'message' => 'File name cannot be blank or non string',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* MetaDataValidation constructor.
|
||||
*
|
||||
* @param Ruleset $ruleset
|
||||
* @param $templatePath
|
||||
* @param bool $autoRulesCheck
|
||||
*/
|
||||
public function __construct(Ruleset $ruleset, $templatePath, $autoRulesCheck = true)
|
||||
{
|
||||
$this->templePath = $templatePath;
|
||||
$this->ruleSet = $ruleset;
|
||||
$this->autoRulesCheck = $autoRulesCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $error
|
||||
*/
|
||||
public function addError($error)
|
||||
{
|
||||
$this->errors[] = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMandatoryFieldName($fieldName)
|
||||
{
|
||||
if (!empty($fieldName)) {
|
||||
$this->mandatoryFields = array_merge($this->mandatoryFields, [$fieldName]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $validateConfig
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($validateConfig = null)
|
||||
{
|
||||
try {
|
||||
$this->checkMandatory();
|
||||
} catch (SystemTemplateValidatorException $exception) {
|
||||
$this->addError($exception->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->autoRulesCheck === false) {
|
||||
$this->applyRules($validateConfig);
|
||||
}
|
||||
|
||||
return empty($this->errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $configMethod
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function applyRules($configMethod = null)
|
||||
{
|
||||
$this->ruleSet->setRules($this, $configMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function checkMandatory()
|
||||
{
|
||||
$missing = array_diff($this->mandatoryFields, array_keys($this->data));
|
||||
if (!empty($missing)) {
|
||||
throw new SystemTemplateValidatorException(
|
||||
sprintf('Missing mandatory parameter "%s', json_encode(array_unique($missing)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data = [])
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFileName($name = null)
|
||||
{
|
||||
$fileName = null === $name && !empty($this->data['filename']) ? $this->data['filename'] : $name;
|
||||
|
||||
if (empty($fileName) || !is_string($fileName)) {
|
||||
$this->addError('File name cannot be blank or non string');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!file_exists($this->templePath . $fileName)) {
|
||||
$this->addError(sprintf('File "%s" cannot be found', $fileName));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Validator;
|
||||
|
||||
use Closure;
|
||||
use Xentral\Modules\SystemTemplates\Validator\Exception\SystemTemplateValidatorException;
|
||||
|
||||
|
||||
final class Ruleset
|
||||
{
|
||||
/** @var SystemTemplateValidatorInterface $validator */
|
||||
private $validator;
|
||||
|
||||
/** @var string $configMethod */
|
||||
private $configMethod;
|
||||
|
||||
/** @var string */
|
||||
const DEFAULT_RULES_CONFIGURATOR = 'validateDefault';
|
||||
|
||||
/**
|
||||
* @param string|null $configMethod
|
||||
*/
|
||||
public function __construct($configMethod = null)
|
||||
{
|
||||
if (null === $configMethod) {
|
||||
$configMethod = static::DEFAULT_RULES_CONFIGURATOR;
|
||||
}
|
||||
$this->configMethod = $configMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SystemTemplateValidatorInterface $validator
|
||||
* @param string $configMethod
|
||||
*/
|
||||
public function setRules(SystemTemplateValidatorInterface $validator, $configMethod = null)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
$configMethod = $configMethod === null ? $this->configMethod : $configMethod;
|
||||
if (!method_exists($this->validator, $configMethod)) {
|
||||
throw new SystemTemplateValidatorException(
|
||||
sprintf('Validate Config method %s is missing', $configMethod)
|
||||
);
|
||||
}
|
||||
$ruleConfigs = $this->validator->{$configMethod}();
|
||||
if (!empty($ruleConfigs)) {
|
||||
foreach ($ruleConfigs as $fieldName => $config) {
|
||||
if (!is_string($fieldName) || empty($fieldName)) {
|
||||
throw new SystemTemplateValidatorException(
|
||||
sprintf('Field name is missing in Configuration at index %s', $fieldName)
|
||||
);
|
||||
}
|
||||
|
||||
if (!array_key_exists('rule', $config) || empty($config['rule'])) {
|
||||
throw new SystemTemplateValidatorException(
|
||||
sprintf('Rule is missing in Configuration at index "%s', $fieldName)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRule($fieldName, $config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
* @param array $config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addRule($fieldName, $config)
|
||||
{
|
||||
$callbackResponse = false;
|
||||
|
||||
$rule = $config['rule'];
|
||||
$message = !empty($config['message']) ? $config['message'] : sprintf('%s is Invalid', $fieldName);
|
||||
|
||||
if (is_array($rule) && !method_exists($this->validator, $rule[0])) {
|
||||
throw new SystemTemplateValidatorException(sprintf('Custom check method %s is missing !', $rule[0]));
|
||||
}
|
||||
|
||||
if (array_key_exists('required', $config) && in_array($config['required'], [true, 1], true)) {
|
||||
$this->validator->setMandatoryFieldName($fieldName);
|
||||
}
|
||||
|
||||
if (is_array($rule)) {
|
||||
$arg = empty($rule[1]) ? [] : [$rule[1]];
|
||||
$callbackResponse = call_user_func_array([$this->validator, $rule[0]], $arg);
|
||||
|
||||
} elseif ($rule instanceof Closure) {
|
||||
$callbackResponse = $rule($this->validator->getData());
|
||||
}
|
||||
|
||||
if ($callbackResponse !== true) {
|
||||
$this->validator->addError($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Validator;
|
||||
|
||||
|
||||
use Xentral\Modules\SystemTemplates\Validator\Exception\SystemTemplateValidatorException;
|
||||
|
||||
final class SystemTemplateValidator
|
||||
{
|
||||
|
||||
/** @var SystemTemplateValidatorInterface $validator */
|
||||
private $validator;
|
||||
|
||||
|
||||
/**
|
||||
* SystemTemplateValidator constructor.
|
||||
*
|
||||
* @param SystemTemplateValidatorInterface $validator
|
||||
*/
|
||||
public function __construct(SystemTemplateValidatorInterface $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return SystemTemplateValidator
|
||||
*/
|
||||
public function fromMeta($data = [])
|
||||
{
|
||||
$this->validator->setData($data);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $validateConfig
|
||||
*
|
||||
* @throws SystemTemplateValidatorException
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($validateConfig = null)
|
||||
{
|
||||
$this->validator->applyRules($validateConfig);
|
||||
|
||||
return $this->validator->isValid($validateConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->validator->getErrors();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Xentral\Modules\SystemTemplates\Validator;
|
||||
|
||||
interface SystemTemplateValidatorInterface
|
||||
{
|
||||
/** @param string|null $methodName */
|
||||
public function isValid($methodName = null);
|
||||
|
||||
public function getErrors();
|
||||
|
||||
public function setData($data);
|
||||
|
||||
public function validateDefault();
|
||||
|
||||
public function setMandatoryFieldName($fieldName);
|
||||
|
||||
public function addError($error);
|
||||
|
||||
public function getData();
|
||||
|
||||
public function applyRules($ruleMethod = null);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"module" : "System Templates",
|
||||
"templates": [
|
||||
{
|
||||
"filename" : "werkzustand.zip",
|
||||
"title" : "Werkzustand",
|
||||
"category": "Allgemein",
|
||||
"description" : "Die Datenbank wird auf Grundzustand gestellt."
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
.template-status-message{
|
||||
position: absolute;
|
||||
width: auto;
|
||||
height: auto;
|
||||
text-align: center;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -70%);
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
var SystemTemplatesModule = function ($) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @type {{readStatus: readStatus, init: init, setTemplateCache: setTemplateCache, runLoadTemplate:
|
||||
* runLoadTemplate, getCacheTemplateValue: (function(string): *), isInitialized: boolean, storage:
|
||||
* {$systemTemplatesDialog: null}, initDialog: initDialog, initLoadTemplate: initLoadTemplate,
|
||||
* showTemplateInfo: showTemplateInfo, setInterval: (function(): number), reloadUrl: reloadUrl, registerEvents:
|
||||
* registerEvents}}
|
||||
*/
|
||||
var me = {
|
||||
|
||||
isInitialized: false,
|
||||
|
||||
storage: {
|
||||
$dialog: null,
|
||||
$confirmResetWithWrittenUsernameDialog: null
|
||||
},
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
init: function () {
|
||||
if (me.isInitialized === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
me.storage.$dialog = $('#system-templates-dialog');
|
||||
me.storage.$confirmResetWithWrittenUsernameDialog = $('#system-templates-confirm-reset-with-written-username');
|
||||
|
||||
if (me.storage.$dialog.length === 0) {
|
||||
throw 'Could not initialize DataTableLabelsUi. Required elements are missing.';
|
||||
}
|
||||
|
||||
me.initDialog();
|
||||
me.registerEvents();
|
||||
|
||||
me.isInitialized = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
initDialog: function () {
|
||||
me.storage.$dialog.dialog({
|
||||
modal: true,
|
||||
bgiframe: true,
|
||||
closeOnEscape: false,
|
||||
minWidth: 650,
|
||||
maxHeight: 700,
|
||||
autoOpen: false,
|
||||
buttons: {
|
||||
ABBRECHEN: {
|
||||
id: 'cancel-recovery-btn',
|
||||
text: 'ABBRECHEN',
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
},
|
||||
SPEICHERN: {
|
||||
text: 'DATEN LÖSCHEN',
|
||||
id: 'run-recovery-btn',
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
me.storage.$confirmResetWithWrittenUsernameDialog.dialog('open');
|
||||
}
|
||||
}
|
||||
},
|
||||
open: function (event, ui) {
|
||||
},
|
||||
close: function (event, ui) {
|
||||
}
|
||||
});
|
||||
|
||||
me.storage.$confirmResetWithWrittenUsernameDialog.dialog({
|
||||
modal: true,
|
||||
bgiframe: true,
|
||||
closeOnEscape: false,
|
||||
minWidth: 650,
|
||||
maxHeight: 700,
|
||||
autoOpen: false,
|
||||
buttons: {
|
||||
ABBRECHEN: {
|
||||
id: 'cancel-reset-confirmation',
|
||||
text: 'ABBRECHEN',
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
},
|
||||
SPEICHERN: {
|
||||
text: 'DATEN LÖSCHEN',
|
||||
id: 'run-reset',
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
var iTid = parseInt(me.getCacheTemplateValue('tid'));
|
||||
me.confirmWrittenUserForReset(iTid);
|
||||
}
|
||||
}
|
||||
},
|
||||
open: function (event, ui) {
|
||||
},
|
||||
close: function (event, ui) {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
registerEvents: function () {
|
||||
|
||||
// LOAD TEMPLATE
|
||||
$('.load-template-badge').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var fieldId = $(this).data('id');
|
||||
if (me.hasProcessStarterEnabled() === true) {
|
||||
me.initLoadTemplate(fieldId);
|
||||
} else {
|
||||
me.showProcessStarterMissingError();
|
||||
}
|
||||
});
|
||||
|
||||
// LOAD TEMPLATE INFO
|
||||
$('.load-template-info').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var fieldId = $(this).data('id');
|
||||
me.showTemplateInfo(fieldId);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} id
|
||||
*/
|
||||
showTemplateInfo: function (id) {
|
||||
//console.log('DUMMY' + id);
|
||||
//@TODO implement Show Info
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasProcessStarterEnabled: function () {
|
||||
var $templateModalStorage = $('#system-templates-dialog');
|
||||
return parseInt($templateModalStorage.data('ps')) === 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
showProcessStarterMissingError: function () {
|
||||
var message = 'Es sieht so aus, als ob der Prozessstarter Cronjob nicht regelmäßig ' +
|
||||
'ausgeführt wird! Bitte aktivieren Sie diesen ' +
|
||||
'(<a href="http://helpdesk.wawision.de/doku.php?id=entwickler:grundinstallation#einrichten_des_heartbeat-cronjobs_optional" target="_blank">Link zu Helpdesk</a>)!';
|
||||
me.storage.$dialog.dialog('open');
|
||||
$('#run-recovery-btn').hide();
|
||||
$('#bck-message').addClass('error').html(message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiates SystemTemplates loading
|
||||
*
|
||||
* @param {number} id
|
||||
* @return {void}
|
||||
*/
|
||||
initLoadTemplate: function (id) {
|
||||
var tmpId = parseInt(id);
|
||||
if (isNaN(tmpId) || (tmpId <= 0 && tmpId !== -1)) {
|
||||
return;
|
||||
}
|
||||
me.setTemplateCache('tid', id);
|
||||
if ($('#run-recovery-btn').prop('disabled')) {
|
||||
$('#run-recovery-btn').prop('disabled', false);
|
||||
}
|
||||
if ($('#run-recovery-btn').css('display') === 'none') {
|
||||
$('#run-recovery-btn').show();
|
||||
}
|
||||
// Check Meta
|
||||
$.ajax({
|
||||
url: 'index.php?module=systemtemplates&action=load&cmd=check-meta',
|
||||
data: {id: tmpId},
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
App.loading.open();
|
||||
},
|
||||
success: function (data) {
|
||||
me.storage.$dialog.dialog('open');
|
||||
if (data.status === false) {
|
||||
$('#systemTemplatesModalTimer').addClass('hide').loadingOverlay('remove');
|
||||
if (data.missing_file) {
|
||||
$('#run-recovery-btn').prop('disabled', true);
|
||||
$('#run-recovery-btn').hide();
|
||||
setTimeout(function () {
|
||||
me.storage.$dialog.dialog('close');
|
||||
}, 5000);
|
||||
$('#bck-message').addClass('error').html(data.message_missing_file);
|
||||
return;
|
||||
}
|
||||
$('#bck-message').addClass('error').html(data.message);
|
||||
|
||||
} else {
|
||||
$('#bck-message').addClass('warning').html(data.message);
|
||||
}
|
||||
},
|
||||
error: function ($xhr, textStatus, errorThrown) {
|
||||
alert('Template konnte nicht geladen werden');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('RunLoad DUMMY' + id);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} data
|
||||
* @param {number} value
|
||||
* @param {string} value
|
||||
*/
|
||||
setTemplateCache: function (data, value) {
|
||||
$('#system-templates-dialog').attr('data-' + data, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Runs System Templates loading
|
||||
*
|
||||
* @param {number} id
|
||||
*/
|
||||
runLoadTemplate: function (id) {
|
||||
$('#run-recovery-btn').prop('disabled', true);
|
||||
|
||||
var refreshId = me.setInterval();
|
||||
me.setTemplateCache('refreshId', refreshId);
|
||||
// run recovery
|
||||
$('#systemTemplatesModalTimer').removeClass('hide').loadingOverlay('show').dialog({
|
||||
modal: true, minWidth: 1200, resizable: false, closeOnEscape: false,
|
||||
dialogClass: 'no-titlebar',
|
||||
open: function (event, ui) {
|
||||
$('.ui-dialog-titlebar').hide();
|
||||
$('#systemTemplatesModalTimer').css({'overflow': 'hidden'});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
*Reloads current page with parameter message
|
||||
* @param {string} msg
|
||||
*/
|
||||
reloadUrl: function (msg) {
|
||||
window.location.href = 'index.php?module=systemtemplates&action=list&msg=' + msg;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
readStatus: function () {
|
||||
var fileName = me.getCacheTemplateValue('filename');
|
||||
var sData = {};
|
||||
if (fileName != null) {
|
||||
sData = {'file_name': fileName};
|
||||
}
|
||||
$.ajax({
|
||||
url: 'index.php?module=systemtemplates&action=readstatus',
|
||||
data: sData,
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data.finished === true) {
|
||||
var refreshId = me.getCacheTemplateValue('refreshId');
|
||||
clearInterval(refreshId);
|
||||
me.reloadUrl(data.message);
|
||||
return;
|
||||
}
|
||||
if ($('.template-status-message').length > 0) {
|
||||
if ($('.template-status-message').hasClass('hide')) {
|
||||
$('.template-status-message').removeClass('hide');
|
||||
}
|
||||
if (data.finished === false && $('#live-status').length > 0) {
|
||||
$('#live-status').html($.trim(data.message) + ' ...');
|
||||
}
|
||||
} else {
|
||||
$('#systemTemplatesModalTimer div.loading-back').after(
|
||||
'<div class="template-status-message hide"><p id="live-status"></p></div>');
|
||||
}
|
||||
//console.log(data);
|
||||
},
|
||||
error: function ($xhr, textStatus, errorThrown) {
|
||||
var interValId = me.getCacheTemplateValue('refresh');
|
||||
var genericErrorMsg = me.getCacheTemplateValue('generic_error');
|
||||
if (interValId) {
|
||||
clearInterval(interValId);
|
||||
}
|
||||
me.reloadUrl(genericErrorMsg);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {number} refreshId
|
||||
*/
|
||||
setInterval: function () {
|
||||
return setInterval(function () {
|
||||
me.readStatus();
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
* @return {string}|{null}
|
||||
*/
|
||||
getCacheTemplateValue: function (data) {
|
||||
return typeof $('#system-templates-dialog').data(data) !== 'undefined' ? $('#system-templates-dialog').data(
|
||||
data) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} id
|
||||
*/
|
||||
confirmWrittenUserForReset: function(id){
|
||||
$.ajax({
|
||||
url: 'index.php?module=systemtemplates&action=load&cmd=confirm-username',
|
||||
data: {
|
||||
id: id,
|
||||
username: $('#username-confirmation').val()
|
||||
},
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
beforeSend: function() {
|
||||
App.loading.open();
|
||||
},
|
||||
success: function(data) {
|
||||
if(data.status){
|
||||
App.loading.close();
|
||||
me.resetToFactorySettings(id);
|
||||
}else{
|
||||
alert(data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} id
|
||||
*/
|
||||
resetToFactorySettings: function(id){
|
||||
$.ajax({
|
||||
url: 'index.php?module=systemtemplates&action=load&cmd=reset-to-factory-settings',
|
||||
data: {id: id},
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data.status) {
|
||||
alert(data.message);
|
||||
me.runLoadTemplate(id);
|
||||
clearInterval(refreshId);
|
||||
me.reloadUrl(data.message);
|
||||
}else{
|
||||
alert(data.message);
|
||||
}
|
||||
me.setTemplateCache('generic_error', data.generic_error);
|
||||
},
|
||||
error: function ($xhr, textStatus, errorThrown) {
|
||||
alert('Template konnte nicht geladen werden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return {
|
||||
init: me.init
|
||||
};
|
||||
|
||||
}(jQuery);
|
||||
|
||||
$(function () {
|
||||
if ($('#system-templates-dialog').length > 0) {
|
||||
SystemTemplatesModule.init();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user