Files
Fedor ac7467f0b4 Major CRM updates: AI Assistant, Court Status API, S3 integration improvements, and extensive file storage system
- Added comprehensive AI Assistant system (aiassist/ directory):
  * Vector search and embedding capabilities
  * Typebot proxy integration
  * Elastic search functionality
  * Message classification and chat history
  * MCP proxy for external integrations

- Implemented Court Status API (GetCourtStatus.php):
  * Real-time court document status checking
  * Integration with external court systems
  * Comprehensive error handling and logging

- Enhanced S3 integration:
  * Improved file backup system with metadata
  * Batch processing capabilities
  * Enhanced error logging and recovery
  * Copy operations with URL fixing

- Added Telegram contact creation API
- Improved error logging across all modules
- Enhanced callback system for AI responses
- Extensive backup file storage with timestamps
- Updated documentation and README files

- File storage improvements:
  * Thousands of backup files with proper metadata
  * Fix operations for broken file references
  * Project-specific backup and recovery systems
  * Comprehensive file integrity checking

Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
2025-10-16 11:17:21 +03:00

912 lines
33 KiB
PHP

<?php
/**
* Created by JetBrains PhpStorm.
* User: Stefan Warnat <support@stefanwarnat.de>
* Date: 04.05.14 12:24
* You must not use this file without permission.
*/
namespace Workflow;
class Repository
{
private $_data = false;
private $_repoId;
private $_messages = false;
private $_updated = false;
const INSTALL_ALL = 'INSTALL_ALL';
const INSTALL_NEW = 'INSTALL_NEW';
const INSTALL_ONLY_UPDATES = 'ONLY_UPDATE';
public function __construct($repoId) {
$this->_repoId = $repoId;
}
public function initData($data) {
$this->_data = $data;
if(is_string($this->_data['available_status'])) {
$this->_data['available_status'] = json_decode(html_entity_decode($this->_data['available_status']), true);
}
}
private function getData() {
if(false !== $this->_data) {
return $this->_data;
}
$adb = \PearDatabase::getInstance();
$sql = 'SELECT * FROM vtiger_wf_repository WHERE id = '.$this->_repoId.' ORDER BY id';
$result = $adb->query($sql, true);
$this->_data = $adb->fetchByAssoc($result);
$this->_data['available_status'] = @json_decode($this->_data['available_status'], true);
return $this->_data;
}
public function getUrl() {
//file_exists($this->licenseDir.'/.HTTPLicense')
return self::modifyUrl($this->get('url'));
}
public function pushPackageLicense($code) {
$mod = new \Workflow2();
$params = array(
'module' => 'Workflow2',
'mod_version' => $mod->getVersion(),
'releasepath' => $this->get('status'),
'licensehash' => $this->get('licensecode'),
'push-license' => $code,
);
$options = array();
if(strpos($this->get('url'), 'redoo-networks') !== false) {
$ca = dirname(__FILE__). DIRECTORY_SEPARATOR. 'cert';
$options = array(
// 'capath' => $ca,
);
}
$adb = \PearDatabase::getInstance();
$sql = 'UPDATE vtiger_wf_repository SET licenseCode = ? WHERE id = ?';
$adb->pquery($sql, array($code, $this->_repoId));
VtUtils::getContentFromUrl($this->getUrl(), $params, 'auto', $options);
$this->update();
$this->installAll(self::INSTALL_ALL);
}
/**
* check the Repository for Updates
*/
public function update($force = false) {
if($this->_updated === true && $force == false) {
return;
}
$data = $this->getData();
if(strtotime($data['last_update']) > time() - 120) {
$this->_updated = true;
return;
}
if(file_exists(vglobal('rootDirectory').'modules/Workflow2/.HTTPLicense') === false) {
$start = microtime(true);
VtUtils::getContentFromUrl('https://repo.redoo-networks.com/robots.txt');
if(microtime(true) - $start >= 0.2) {
touch(vglobal('rootDirectory').'modules/Workflow2/.HTTPLicense');
}
}
$adb = \PearDatabase::getInstance();
//$moduleModel = \Vtiger_Module_Model::getInstance("Workflow2");
$sql = 'DELETE FROM vtiger_wf_repository_types WHERE repos_id = ?';
$adb->pquery($sql, array($this->_repoId));
$content = $this->getContentFromRepository();
$available_status = array();
try {
$root = new \SimpleXMLElement($content);
} catch(\Exception $exp) {
throw new \Exception('['.$this->getUrl().'] no task repository '.$exp->getMessage());
}
$messages = array();
if(isset($root->messages)) {
foreach($root->messages->message as $msg) {
$messages[] = array((string)$msg->attributes()->type, (string)$msg);
}
}
if(isset($root->available_status)) {
foreach($root->available_status->status as $status) {
$available_status[] = array((string)$status->attributes()->label, (string)$status->attributes()->value);
}
} else {
$available_status[] = array('Stable', 'stable');
}
$types = array();
if(count($root->task) == 1) {
$tasks = array($root->task);
} else {
$tasks = $root->task;
}
foreach($tasks as $task)
{
switch($this->get('version')) {
case '2':
$lastVersion = 0;
foreach($task->versions->version as $version) {
if($lastVersion == (string)$version['version']) {
continue;
}
$tmp = array(
'repos_id' => $this->_repoId,
'name' => (string)$task->name,
'version' => (string)$version['version'],
'url' => (string)$version->url,
'checksum' => (string)$version->signature,
'mode' => (string)$task->mode == 'task'?'task':'core',
'status' => (string)$version['releasepath'],
'autoinstall' => (string)$version['autoinstall'],
'module_required' => (string)$task->module_required,
);
if(isset($version['min_version'])) {
$tmp['min_version'] = (string)$version['min_version'];
} else {
$tmp['min_version'] = '0';
}
$types[] = $tmp;
}
break;
default:
$tmp = array(
'repos_id' => $this->_repoId,
'name' => (string)$task->name,
'version' => (string)$task->version,
'url' => (string)$task->url,
'checksum' => (string)$task->signature,
'mode' => (string)$task->mode,
'status' => (string)$task->status,
'autoinstall' => (string)$task->autoInstall,
'module_required' => (string)$task->module_required,
);
if(isset($task->min_version)) {
$tmp['min_version'] = (string)$task->min_version;
} else {
$tmp['min_version'] = '0';
}
$types[] = $tmp;
break;
}
}
foreach($types as $type) {
$tmp = array();
foreach($type as $key => $value) {
$tmp[] = '`'.$key.'` = "'.$value.'"';
}
$sql = 'REPLACE INTO vtiger_wf_repository_types SET last_update = '.time().', '.implode(',', $tmp);
$adb->query($sql, true);
}
if(isset($root->autoupdate)) {
$autoUpdate = ''.$root->autoupdate == 'true';
} else {
$autoUpdate = '';
}
if(isset($root->supportUrl)) {
$supportUrl = ''.$root->supportUrl;
} else {
$supportUrl = '';
}
$sql = 'UPDATE vtiger_wf_repository SET last_update = '.time().', messages = ?, available_status = ?,support_url = ?, autoupdate = ? WHERE id = ?';
$adb->pquery($sql, array(serialize($messages), VtUtils::json_encode($available_status), $supportUrl, $autoUpdate == '1'?1:0, $this->_repoId), true);
$this->_messages = $messages;
$this->_updated = true;
}
/**
* Install all available Files
*
* @param bool $onlyNew Should only uninstalled types downloaded?
*/
public function installAll($mode = false) {
if($mode === false) {
$mode = self::INSTALL_ALL;
}
$adb = \PearDatabase::getInstance();
$this->update();
$sql = 'SELECT version FROM vtiger_tab WHERE name = "Workflow2"';
$result = $adb->query($sql);
$moduleVersion = $adb->query_result($result, 0, 'version');
switch($mode) {
case self::INSTALL_NEW:
$sql = 'SELECT * FROM vtiger_wf_repository_types WHERE repos_id = '.$this->_repoId.' AND min_version <= "'.$moduleVersion.'" AND autoinstall = 1';
break;
default:
$sql = 'SELECT * FROM vtiger_wf_repository_types WHERE repos_id = '.$this->_repoId.' AND min_version <= "'.$moduleVersion.'"';
break;
}
$result = $adb->query($sql, true);
$tmpfname = tempnam(sys_get_temp_dir(), 'WFD2');
while($data = $adb->fetchByAssoc($result)) {
$prevent = false;
if(!empty($data['module_required'])) {
$parts = explode(',', $data['module_required']);
foreach($parts as $part) {
if(!vtlib_isModuleActive($part)) {
$prevent = true;
break;
}
}
}
if($prevent === true) {
continue;
}
$sql = 'SELECT * FROM vtiger_wf_types WHERE type = "'.$data['name'].'" AND repo_id = "'.$this->_repoId.'"';
$count = $adb->query($sql, true);
if($data['mode'] == 'task') {
if($adb->num_rows($count) > 0) {
$checkVersion = $adb->fetchByAssoc($count);
if($checkVersion['version'] == $data['version']) {
//var_dump('skip ' . $data['name']);
continue;
}
}
if($mode === self::INSTALL_NEW) {
if($adb->num_rows($count) > 0) {
continue;
}
} elseif($mode === self::INSTALL_ONLY_UPDATES) {
if($adb->num_rows($count) == 0) {
continue;
}
} elseif($mode === self::INSTALL_ALL) {
if($adb->num_rows($count) == 0 && $data['autoinstall'] == '0') {
continue;
}
}
$sql = 'SELECT * FROM vtiger_wf_types WHERE type = "'.$data['name'].'" AND repo_id != "'.$this->_repoId.'"';
$count = $adb->query($sql, true);
if($adb->num_rows($count) > 0) {
continue;
}
} else {
$sql = 'SELECT * FROM vtiger_wf_repository_core WHERE type = "'.$data['name'].'"';
$count = $adb->query($sql, true);
if($adb->num_rows($count) > 0) {
$checkVersion = $adb->fetchByAssoc($count);
if($checkVersion['version'] == $data['version']) {
//var_dump('skip ' . $data['name']);
continue;
}
}
}
$fileDownloadUrl = $data['url'];
//var_dump('execute ' . $data['name'], $checkVersion['version'], $data['version']);
$content = VtUtils::getContentFromUrl(html_entity_decode($fileDownloadUrl));
if($content === 'OFFLINE') return;
file_put_contents($tmpfname, $content);
if (false == \Workflow\Repository::checkSignature($tmpfname, $data['repos_id'], $data['checksum'])) {
continue;
}
\Workflow\Repository::installFile($tmpfname, $data['version'], $data['repos_id'], true, true);
}
@unlink($tmpfname);
}
public function hasLicenseKey() {
$data = $this->getData();
if(empty($data['licensecode'])) {
return false;
}
return true;
}
public function getLastUpdateDate() {
$data = $this->getData();
return \DateTimeField::convertToUserFormat($data['last_update']);
}
public function get($key) {
$data = $this->getData();
return $data[$key];
}
public function getContentFromRepository() {
$mod = new \Workflow2();
global $vtiger_current_version, $vtiger_compatible_version;
if(isset($vtiger_compatible_version) && !empty($vtiger_compatible_version)) {
$vtiger_current_version = $vtiger_compatible_version;
}
$versionParts = explode('.', $vtiger_current_version);
switch($this->get('version')) {
case '2':
$params = array(
'module' => 'Workflow2',
'vtiger_major' => $versionParts[0],
'mod_version' => $mod->getVersion(),
'releasepath' => $this->get('status'),
'licensehash' => $this->get('licensecode'),
);
break;
default:
$params = array(
'license' => $this->get('licensecode'),
'status' => $this->get('status'),
'version' => $mod->getVersion(),
);
break;
}
$options = array();
if(strpos($this->get('url'), 'redoo-networks') !== false) {
$ca = dirname(__FILE__). DIRECTORY_SEPARATOR. 'cert';
$options = array(
//'capath' => $ca,
);
}
$return = VtUtils::getContentFromUrl($this->getUrl(), $params, 'auto', $options);
return $return;
}
public function checkRepoForUpdate() {
$data = $this->getData();
$content = $this->getContentFromRepository();
if($content == 'OFFLINE') return;
try {
$root = new \SimpleXMLElement($content);
} catch(\Exception $exp) {
throw new \Exception('['.$this->getUrl().'] no task repository. Cannot read XML structure.');
}
if(isset($root->publicKey)) {
global $root_directory;
@mkdir($root_directory.'/'.PATH_MODULE.'/publicKeys/');
$options = array();
if(strpos($root->publicKey, 'redoo-networks') !== false) {
$ca = dirname(__FILE__). DIRECTORY_SEPARATOR. 'cert';
$options = array(
//'capath' => $ca,
);
}
$publicKey = VtUtils::getContentFromUrl(self::modifyUrl(''.$root->publicKey), array(), 'auto', $options);
file_put_contents($root_directory.'/'.PATH_MODULE.'/publicKeys/repo_'.$this->_repoId.'.pem', $publicKey);
}
if(isset($root->newUrl)) {
$newUrl = ''.$root->newUrl;
} else {
$newUrl = $data['url'];
}
if(isset($root->supportUrl)) {
$supportUrl = ''.$root->supportUrl;
} else {
$supportUrl = '';
}
$adb = \PearDatabase::getInstance();
$sql = 'UPDATE vtiger_wf_repository SET title = ?, url = ?, support_url = ? WHERE id = ?';
$adb->pquery($sql, array(''.$root->title, $newUrl, $supportUrl, $this->_repoId), true);
}
public static function deleteRepository($id) {
$adb = \PearDatabase::getInstance();
$sql = 'UPDATE vtiger_wf_repository SET deleted = 1 WHERE id = ?';
$adb->pquery($sql, array($id));
}
public static function testLicense($url, $licenseCode = '', $name = '', $skipCheck = false, $nonce = '') {
$mod = new \Workflow2();
$params = array(
'module' => 'Workflow2',
'mod_version' => $mod->getVersion(),
'releasepath' => 'stable',
'licensehash' => sha1($licenseCode),
);
$options = array();
if(strpos($url, 'redoo-networks') !== false) {
$ca = dirname(__FILE__). DIRECTORY_SEPARATOR. 'cert';
$options = array(
//'capath' => $ca,
);
}
$content = VtUtils::getContentFromUrl(self::modifyUrl($url), $params, 'post', $options);
if($content == 'OFFLINE') return true;
$simpleXml = simplexml_load_string($content);
$title = (string)$simpleXml->title;
if($nonce !== sha1(vglobal('site_URL').$url.'0s-f,mäp'.$title)) {
die('nothing');
}
if($simpleXml->valid_license.'' == '1') {
return true;
}
return false;
}
public static function modifyUrl($url) {
$rootDirectory = vglobal('root_directory');
if(file_exists($rootDirectory.'/modules/Workflow2/.HTTPLicense') && strpos($url, 'redoo') !== false) {
$url = str_replace('https://', 'http://', $url);
}
return $url;
}
public static function register($url, $licenseCode = '', $name = '', $skipCheck = false, $nonce = '', $pushPackagelicense = '') {
$adb = \PearDatabase::getInstance();
// Only allow repo.redoo-networks.com
if(strpos($url, '.redoo-networks.') !== false && strpos($url, 'repo.redoo-networks.com') === false) return;
$sql = 'SELECT * FROM vtiger_wf_repository WHERE url = ? AND deleted = 0';
$result = $adb->pquery($sql, array($url));
if($adb->num_rows($result) > 0) {
return $adb->query_result($result, 0, 'id');
//throw new \Exception('repository already added');
}
$mod = new \Workflow2();
$params = array(
'module' => 'Workflow2',
'mod_version' => $mod->getVersion(),
'releasepath' => 'stable',
'licensehash' => sha1($licenseCode),
);
$options = array();
if(strpos($url, 'redoo-networks') !== false) {
$ca = dirname(__FILE__). DIRECTORY_SEPARATOR. 'cert';
$options = array(
//'capath' => $ca,
);
}
$url = self::modifyUrl($url);
$content = VtUtils::getContentFromUrl($url, $params, 'post', $options);
if(defined('DEV_OFFLINE')) return true;
if($skipCheck === false) {
try {
$root = new \SimpleXMLElement($content);
} catch(\Exception $exp) {
throw new \Exception('no task repository');
}
if(empty($root->title)) {
throw new \Exception('no task repository (title missing)');
}
$title = (string)$root->title;
if($nonce !== sha1(vglobal('site_URL').$url.'0s-f,mäp'.$title)) {
die('nothing');
}
} else {
try {
$root = new \SimpleXMLElement($content);
} catch(\Exception $exp) { }
if(!empty($name)) {
$title = $name;
} else {
$title = (string)$root->title;
}
}
if(empty($licenseCode)) {
$licenseCode = (string)$root->systemkey;
}
if(isset($root['repoversion']) && (string)$root['repoversion'] == '2') {
$sql = 'INSERT INTO vtiger_wf_repository SET deleted = 0, title = ?, url = ?, support_url = "", licenseCode = ?, last_update = "0000-00-00", messages = "", available_status = "", autoupdate = "0", status = "stable", version = '.intval($root['repoversion']);
$adb->pquery($sql, array($title, $url, $licenseCode));
} else {
$sql = 'INSERT INTO vtiger_wf_repository SET deleted = 0, title = ?, url = ?, support_url = "", licenseCode = ?, status = "stable", messages = "", available_status = "", autoupdate = "0", last_update = "0000-00-00", version = 1';
$adb->pquery($sql, array($title, $url, md5($licenseCode)));
}
$repoId = \Workflow\VtUtils::LastDBInsertID();
if(isset($root)) {
if(isset($root->publicKey)) {
global $root_directory;
@mkdir($root_directory.'/'.PATH_MODULE.'/publicKeys/');
$options = array();
if(strpos($root->publicKey, 'redoo-networks') !== false) {
$ca = dirname(__FILE__). DIRECTORY_SEPARATOR. 'cert';
$options = array(
//'capath' => $ca,
);
}
$publicKey = VtUtils::getContentFromUrl(self::modifyUrl(''.$root->publicKey), array(), 'auto', $options);
//echo $root_directory.'/'.PATH_MODULE.'/publicKeys/repo_'.$repoId.'.pem';
file_put_contents($root_directory.'/'.PATH_MODULE.'/publicKeys/repo_'.$repoId.'.pem', $publicKey);
}
}
$obj = new Repository($repoId);
if(!empty($pushPackagelicense)) {
$obj->pushPackageLicense($pushPackagelicense);
}
$obj->update();
return $repoId;
}
/**
*
* @param bool $onlyInternal 'true' do return only repos from stefanwarnat.de
* @return Repository[]
*/
public static function getAll($onlyInternal = false) {
$adb = \PearDatabase::getInstance();
if($onlyInternal === false) {
$sql = 'SELECT * FROM vtiger_wf_repository WHERE deleted = 0 ORDER BY id';
} else {
$sql = 'SELECT * FROM vtiger_wf_repository WHERE url LIKE "%.redoo-networks%" AND deleted = 0 ORDER BY id';
}
$result = $adb->query($sql, true);
$return = array();
while($row = $adb->fetchByAssoc($result)) {
$tmp = new Repository($row['id']);
$tmp->initData($row);
$return[] = $tmp;
}
return $return;
}
public static function checkSignature($filePath, $repo_id, $signature) {
return true;
global $root_directory;
if(function_exists('openssl_verify') && file_exists($root_directory.'/'.PATH_MODULE.'/publicKeys/repo_'.$repo_id.'.pem')) {
$fp = fopen($root_directory.'/'.PATH_MODULE.'/publicKeys/repo_'.$repo_id.'.pem', "r");
$cert = fread($fp, 8192);
fclose($fp);
$signature = base64_decode($signature);
$ok = openssl_verify(file_get_contents($filePath), $signature, $cert);
if(empty($ok)) {
return false;
}
}
return true;
}
public static function installFile($fileName, $version = 0, $repoId = 0, $enableUpgrade = true, $enableDowngrade = false) {
global $adb;
include_once('vtlib/Vtiger/Unzip.php');
$unzip = new \Vtiger_Unzip($fileName, true);
$filelist = $unzip->getList();
if(isset($filelist['task.php']) && isset($filelist['task.xml'])) {
$tmpfname = tempnam(sys_get_temp_dir(), 'WFD2');
if(!$unzip->checkFileExistsInRootFolder('task.xml')) {
throw new \Exception('no task available: no task.xml');
}
if(!$unzip->checkFileExistsInRootFolder('task.php')) {
throw new \Exception('no task available: no task.php');
}
$unzip->unzip('task.xml', $tmpfname);
try {
$root = new \SimpleXMLElement(file_get_contents($tmpfname));
} catch(\Exception $exp) {
throw new \Exception('no task available '.$exp->getMessage());
}
$attributes = $root->attributes();
$type = ''.$root->name;
$sql = 'SELECT id FROM vtiger_wf_types WHERE type = "'.$type.'" AND repo_id != "'.$repoId.'"';
$result = $adb->query($sql);
if($adb->num_rows($result) > 0) {
if(empty($_COOKIE['taskupdater'])) {
throw new \Exception('Another Repository use this BlockType. You cannot use two Tasks with the same name!');
} else {
$sql = 'DELETE FROM vtiger_wf_types WHERE type = "'.$type.'"';
$adb->query($sql);
}
}
if($enableUpgrade == false) {
$sql = 'SELECT id FROM vtiger_wf_types WHERE type = "'.$type.'" AND repo_id = "'.$repoId.'"';
$result = $adb->query($sql);
if($adb->num_rows($result) > 0) {
throw new \Exception('Taskfile already existing. Try again and activate Upgrade of existing Taskfile.');
}
}
if($enableUpgrade == true && $enableDowngrade == false) {
$sql = 'SELECT id, version FROM vtiger_wf_types WHERE type = "'.$type.'" AND repo_id = "'.$repoId.'"';
$result = $adb->query($sql);
if($adb->num_rows($result) > 0) {
$data = $adb->fetchByAssoc($result);
if($data['version'] > intval($attributes['version'])) {
throw new \Exception('More recent version ('.$data['version'].') of this Taskfile already existing. You want install Version '.intval($attributes['version']).'. Try again and activate Downgrade if you want to install.');
}
}
}
$newVersion = intval($attributes['version']);
$data = array(
'type' => ''.$type,
'version' => $newVersion,
'repo_id' => ''.$repoId,
'handlerclass' => ''.$root->classname,
'module' => 'Workflow2',
'text' => ''.$root->label,
'input' => ''.$attributes['input'] == 'true' ? 1 : 0,
'styleclass' => ''.$attributes['styleclass'],
'category' => ''.$root->group,
);
if(isset($root->support_url)) {
$data['helpurl'] = ''.$root->support_url;
}
$outputs = array();
if(isset($root->outputs) && isset($root->outputs->output)) {
foreach($root->outputs->output as $output) {
$attr = $output->attributes();
$outputs[] = array(
(string)$attr['value'],
(string)$output,
(string)$attr['text'],
);
}
}
$data['output'] = json_encode($outputs);
$persons = array();
if(isset($root->persons) && isset($root->persons->person)) {
foreach($root->persons->person as $person) {
$attr = $person->attributes();
$persons[] = array(
(string)$attr['key'],
(string)$person,
);
}
}
$data['persons'] = json_encode($persons);
$limits = array();
if(isset($root->limit_module) && isset($root->limit_module->module)) {
foreach($root->limit_module->module as $mod) {
$limits[] = (string)$mod;
}
}
if(count($limits) > 0) {
$data['singleModule'] = json_encode($limits);
} else {
$data['singleModule'] = '';
}
$data['file'] = '';
if($unzip->checkFileExistsInRootFolder('icon.png')) {
$unzip->unzip('icon.png', $tmpfname);
rename($tmpfname, dirname(__FILE__).'/../../icons/task_'.$type.'.png');
//echo dirname(__FILE__).'/../../icons/task_'.$type.'.png'."\n";
$data['background'] = 'task_'.$type;
}
$fields = array();
foreach($data as $key => $value) {
$fields[] = '`'.$key.'` = ?';
$params[] = $value;
}
$fields[] = 'sort = ?';
$params[] = 99;
$sql = 'SELECT id, version FROM vtiger_wf_types WHERE type = "'.$type.'" AND repo_id = "'.$repoId.'"';
$result = $adb->query($sql);
if($adb->num_rows($result) > 0) {
$row = $adb->fetchByAssoc($result);
$oldVersion = $row['version'];
$sql = 'UPDATE vtiger_wf_types SET '.implode(',', $fields).' WHERE id = '.$row['id'];
} else {
$oldVersion = 0;
$nextID = $adb->getUniqueID("vtiger_wf_types");
$fields[] = 'id = ?';
$params[] = $nextID;
$sql = 'INSERT INTO vtiger_wf_types SET '.implode(',', $fields).'';
}
//echo $sql;
$adb->pquery($sql, $params, true);
if(isset($root->files)) {
self::_extractFiles($root->files->file, $unzip);
}
$unzip->unzip('task.php', $tmpfname);
rename($tmpfname, dirname(__FILE__).'/../../tasks/'.$root->classname.'.php');
//echo dirname(__FILE__).'/../../tasks/'.$root->classname.'.php'."\n";
if($unzip->checkFileExistsInRootFolder('task.js')) {
$unzip->unzip('task.js', $tmpfname);
$filename = ucfirst(str_replace('wftask','', strtolower($root->classname)));
rename($tmpfname, dirname(__FILE__).'/../../tasks/WfTask'.$filename.'.js');
// echo dirname(__FILE__).'/../../tasks/'.$root->classname.'.js'."\n";
}
if($unzip->checkFileExistsInRootFolder('task.tpl')) {
$unzip->unzip('task.tpl', $tmpfname);
rename($tmpfname, dirname(__FILE__).'/../../../../layouts/v7/modules/Settings/Workflow2/taskforms/WfTask'.ucfirst(strtolower($type)).'.tpl');
// echo dirname(__FILE__).'/../../../../layouts/vlayout/modules/Settings/Workflow2/taskforms/WfTask'.ucfirst(strtolower($type)).'.tpl'."\n";
}
if($unzip->checkFileExistsInRootFolder('statistik.tpl')) {
$unzip->unzip('statistik.tpl', $tmpfname);
rename($tmpfname, dirname(__FILE__).'/../../../../layouts/v7/modules/Settings/Workflow2/taskforms/WfStat'.ucfirst(strtolower($type)).'.tpl');
// echo dirname(__FILE__).'/../../../../layouts/vlayout/modules/Settings/Workflow2/taskforms/WfStat'.ucfirst(strtolower($type)).'.tpl'."\n";
}
if($unzip->checkFileExistsInRootFolder('setup.php')) {
$tmpfname = tempnam(WFD_TMP, 'WFD2');
@unlink($tmpfname);
@unlink($tmpfname.'.php');
if(class_exists('\\MODDBCheck') == false) {
class_alias('\\Workflow\\DbCheck', '\\MODDBCheck');
}
$newVersion = '';
if(!defined('WFD_TASK_MANAGEMENT')) define('WFD_TASK_MANAGEMENT', true);
if(file_exists(sha1_file($tmpfname.'.php'))) {
throw new \Exception('SECURITY problem! The task update script was precreated!');
}
try {
$unzip->unzip('setup.php', $tmpfname.'.php');
$hash1 = sha1_file($tmpfname.'.php');
require($tmpfname . '.php');
$hash2 = sha1_file($tmpfname.'.php');
if($hash1 !== $hash2) {
throw new \Exception('SECURITY problem! The task update script was changed during execution!');
}
} catch (\Exception $exp) {
unlink($tmpfname.'.php');
throw new \Exception('Error during '.$type.' Task Setup Script: '.$exp->getMessage());
}
unlink($tmpfname.'.php');
}
@unlink($tmpfname);
$unzip->close();
}
if(isset($filelist['core.xml'])) {
$tmpfname = tempnam(sys_get_temp_dir(), 'WFD2');
$unzip->unzip('core.xml', $tmpfname);
try {
$root = new \SimpleXMLElement(file_get_contents($tmpfname));
} catch(\Exception $exp) {
throw new \Exception('no core structure available '.$exp->getMessage());
}
$type = $root->type . '';
self::_extractFiles($root->files->file, $unzip);
$sql = 'SELECT id FROM vtiger_wf_repository_core WHERE type = "'.$type.'"';
$result = $adb->query($sql);
$fields = array(
'type = ?',
'version = ?'
);
$params = array($type, $version);
if($adb->num_rows($result) > 0) {
$row = $adb->fetchByAssoc($result);
$sql = 'UPDATE vtiger_wf_repository_core SET '.implode(',', $fields).' WHERE id = '.$row['id'];
} else {
$sql = 'INSERT INTO vtiger_wf_repository_core SET '.implode(',', $fields).'';
}
//echo $sql;
$adb->pquery($sql, $params, true);
$unzip->close();
}
}
private static function _extractFiles($files, &$unzip) {
global $root_directory;
$allowedPaths = array ( "modules/Workflow2/", 'modules/Settings/Workflow2/', 'layouts/v7/modules/Workflow2/', 'layouts/v7/modules/Settings/Workflow2/', 'languages');
$include = array();
foreach($files as $file) {
$filePath = '' . $file;
foreach($allowedPaths as $allowedPath) {
if(strpos($filePath, $allowedPath) === 0) {
$include[] = $filePath;
break;
}
}
}
// Unzip selectively
$unzip->unzipAllEx( $root_directory,
Array(
// Include only file/folders that need to be extracted
'include' => $include,
// NOTE: If excludes is not given then by those not mentioned in include are ignored.
)
);
}
}
?>