Merged in feature/PMC-563 (pull request #6868)
PMC-563 Approved-by: Paula Quispe <paula.quispe@processmaker.com> Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
@@ -80,7 +80,6 @@ return array(
|
|||||||
'ToolBar' => ToolBar::class,
|
'ToolBar' => ToolBar::class,
|
||||||
'Tree' => PmTree::class,
|
'Tree' => PmTree::class,
|
||||||
'triggerLibrary' => TriggerLibrary::class,
|
'triggerLibrary' => TriggerLibrary::class,
|
||||||
'Upgrade' => Upgrade::class,
|
|
||||||
'workspaceTools' => WorkspaceTools::class,
|
'workspaceTools' => WorkspaceTools::class,
|
||||||
'wsBase' => WsBase::class,
|
'wsBase' => WsBase::class,
|
||||||
'wsResponse' => WsResponse::class,
|
'wsResponse' => WsResponse::class,
|
||||||
|
|||||||
@@ -519,13 +519,15 @@ class database extends database_base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute a sql query
|
* Execute a sql query
|
||||||
*
|
*
|
||||||
* @param string $query
|
* @param string $query
|
||||||
|
* @param bool $throwError
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function executeQuery($query)
|
public function executeQuery($query, $throwError = false)
|
||||||
{
|
{
|
||||||
$this->logQuery($query);
|
$this->logQuery($query);
|
||||||
|
|
||||||
@@ -545,7 +547,11 @@ class database extends database_base
|
|||||||
return $result;
|
return $result;
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
$this->logQuery($exception->getMessage());
|
$this->logQuery($exception->getMessage());
|
||||||
return [];
|
if ($throwError) {
|
||||||
|
throw $exception;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,4 +1018,87 @@ class database extends database_base
|
|||||||
}
|
}
|
||||||
return $flag;
|
return $flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate drop trigger SQL
|
||||||
|
*
|
||||||
|
* @param string $triggerName
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDropTrigger($triggerName)
|
||||||
|
{
|
||||||
|
return "DROP TRIGGER IF EXISTS `{$triggerName}`;";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate alter table with or without adding the indexes
|
||||||
|
*
|
||||||
|
* @param string $tableName
|
||||||
|
* @param array $columns
|
||||||
|
* @param array $indexes
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateAddColumnsSql($tableName, $columns, $indexes = [])
|
||||||
|
{
|
||||||
|
$indexesAlreadyAdded = [];
|
||||||
|
$sql = 'ALTER TABLE ' . $this->sQuoteCharacter . $tableName . $this->sQuoteCharacter . ' ';
|
||||||
|
foreach ($columns as $columnName => $parameters) {
|
||||||
|
if (isset($parameters['Type']) && isset($parameters['Null'])) {
|
||||||
|
$sql .= 'ADD COLUMN ' . $this->sQuoteCharacter . $columnName . $this->sQuoteCharacter . ' ' . $parameters['Type'];
|
||||||
|
if ($parameters['Null'] == 'YES') {
|
||||||
|
$sql .= ' NULL';
|
||||||
|
} else {
|
||||||
|
$sql .= ' NOT NULL';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($parameters['AutoIncrement']) && $parameters['AutoIncrement']) {
|
||||||
|
$sql .= ' AUTO_INCREMENT';
|
||||||
|
}
|
||||||
|
if (isset($parameters['PrimaryKey']) && $parameters['PrimaryKey']) {
|
||||||
|
$sql .= ' PRIMARY KEY';
|
||||||
|
$indexesAlreadyAdded[] = $columnName;
|
||||||
|
}
|
||||||
|
if (isset($parameters['Unique']) && $parameters['Unique']) {
|
||||||
|
$sql .= ' UNIQUE';
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to check the property AI
|
||||||
|
if (isset($parameters['AI'])) {
|
||||||
|
if ($parameters['AI'] == 1) {
|
||||||
|
$sql .= ' AUTO_INCREMENT';
|
||||||
|
} else {
|
||||||
|
if ($parameters['Default'] != '') {
|
||||||
|
$sql .= " DEFAULT '" . $parameters['Default'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isset($parameters['Default'])) {
|
||||||
|
$sql .= " DEFAULT '" . $parameters['Default'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql .= ', ';
|
||||||
|
}
|
||||||
|
foreach ($indexes as $indexName => $indexColumns) {
|
||||||
|
$indexType = 'INDEX';
|
||||||
|
if ($indexName === 'primaryKey' || $indexName === 'PRIMARY') {
|
||||||
|
$indexType = 'PRIMARY';
|
||||||
|
$indexName = 'KEY';
|
||||||
|
// If is primary key is not needed add a new index, the column already was added like primary key
|
||||||
|
if (count($indexColumns) == 1 && $indexesAlreadyAdded == $indexColumns) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql .= 'ADD ' . $indexType . ' ' . $indexName . ' (';
|
||||||
|
foreach ($indexColumns as $column) {
|
||||||
|
$sql .= $this->sQuoteCharacter . $column . $this->sQuoteCharacter . ', ';
|
||||||
|
}
|
||||||
|
$sql = substr($sql, 0, -2);
|
||||||
|
$sql .= '), ';
|
||||||
|
}
|
||||||
|
$sql = rtrim($sql, ', ');
|
||||||
|
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,16 @@ use ProcessMaker\Core\System;
|
|||||||
|
|
||||||
CLI::taskName('upgrade');
|
CLI::taskName('upgrade');
|
||||||
CLI::taskDescription("Upgrade workspaces.\n\n This command should be run after upgrading ProcessMaker to a new version so that all workspaces are also upgraded to the\n new version.");
|
CLI::taskDescription("Upgrade workspaces.\n\n This command should be run after upgrading ProcessMaker to a new version so that all workspaces are also upgraded to the\n new version.");
|
||||||
|
CLI::taskOpt('child', "Used by the main upgrade thread", 'child', 'child');
|
||||||
CLI::taskOpt('buildACV', 'If this option is enabled, the Cache View is built.', 'ACV', 'buildACV');
|
CLI::taskOpt('buildACV', 'If this option is enabled, the Cache View is built.', 'ACV', 'buildACV');
|
||||||
CLI::taskOpt('noxml', 'If this option is enabled, the XML files translation is not built.', 'NoXml', 'no-xml');
|
CLI::taskOpt('noxml', 'If this option is enabled, the XML files translation is not built.', 'NoXml', 'no-xml');
|
||||||
|
CLI::taskOpt('nomafe', 'If this option is enabled, the MAFE files translation is not built.', 'nomafe', 'no-mafe');
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
CLI::taskOpt('keep_dyn_content', "Include the DYN_CONTENT_HISTORY value. Ex: --keep_dyn_content", 'i', 'keep_dyn_content');
|
CLI::taskOpt('keep_dyn_content', "Include the DYN_CONTENT_HISTORY value. Ex: --keep_dyn_content", 'i', 'keep_dyn_content');
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
CLI::taskRun("run_upgrade");
|
CLI::taskRun("run_upgrade");
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
|
|
||||||
CLI::taskName('unify-database');
|
CLI::taskName('unify-database');
|
||||||
CLI::taskDescription(
|
CLI::taskDescription(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
@@ -34,179 +36,164 @@ CLI::taskArg('workspace');
|
|||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
CLI::taskRun("run_unify_database");
|
CLI::taskRun("run_unify_database");
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
|
CLI::taskName('upgrade-query');
|
||||||
|
CLI::taskRun('runUpgradeQuery');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A version of rm_dir which does not exits on error.
|
* Execute the upgrade
|
||||||
*
|
*
|
||||||
* @param string $filename directory or file to remove
|
* @param array $parameters
|
||||||
* @param bool $filesOnly either to remove the containing directory as well or not
|
* @param array $args
|
||||||
*/
|
*/
|
||||||
function rm_dir($filename, $filesOnly = false)
|
function run_upgrade($parameters, $args)
|
||||||
{
|
{
|
||||||
if (is_file($filename)) {
|
// Get values from command and arguments
|
||||||
@unlink($filename) or CLI::logging(CLI::error("Could not remove file $filename")."\n");
|
$workspaces = get_workspaces_from_args($parameters);
|
||||||
} else {
|
$mainThread = $printHF = !array_key_exists('child', $args);
|
||||||
foreach (glob("$filename/*") as $f) {
|
$updateXmlForms = !array_key_exists('noxml', $args);
|
||||||
rm_dir($f);
|
$updateMafe = !array_key_exists('nomafe', $args);
|
||||||
}
|
$keepDynContent = false;
|
||||||
if (!$filesOnly) {
|
/*----------------------------------********---------------------------------*/
|
||||||
@rmdir($filename) or CLI::logging(CLI::error("Could not remove directory $filename")."\n");
|
$keepDynContent = array_key_exists('keep_dyn_content', $args); //In community version this section will be removed
|
||||||
}
|
/*----------------------------------********---------------------------------*/
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function run_upgrade($command, $args)
|
// Initializing variables
|
||||||
{
|
$globalStartTime = microtime(true);
|
||||||
CLI::logging("UPGRADE", PROCESSMAKER_PATH . "upgrade.log");
|
$numberOfWorkspaces = count($workspaces);
|
||||||
CLI::logging("Checking files integrity...\n");
|
$countWorkspace = 1;
|
||||||
//setting flag to true to check into sysGeneric.php
|
|
||||||
$workspaces = get_workspaces_from_args($command);
|
if ($printHF) {
|
||||||
$oneWorkspace = 'true';
|
// Set upgrade flag
|
||||||
if (count($workspaces) == 1) {
|
if (count($workspaces) === 1) {
|
||||||
foreach ($workspaces as $index => $workspace) {
|
// For the specific workspace send in the command
|
||||||
$oneWorkspace = $workspace->name;
|
G::isPMUnderUpdating(1, $workspaces[0]->name);
|
||||||
|
} else {
|
||||||
|
// For all workspaces
|
||||||
|
G::isPMUnderUpdating(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print information when start the upgrade process
|
||||||
|
CLI::logging('UPGRADE LOG INITIALIZED', PROCESSMAKER_PATH . 'upgrade.log');
|
||||||
|
CLI::logging("UPGRADE STARTED\n");
|
||||||
}
|
}
|
||||||
$flag = G::isPMUnderUpdating(1, $oneWorkspace);
|
|
||||||
//start to upgrade
|
foreach ($workspaces as $workspace) {
|
||||||
$checksum = System::verifyChecksum();
|
if ($mainThread) {
|
||||||
if ($checksum === false) {
|
CLI::logging("FOLDERS AND FILES OF THE SYSTEM\n");
|
||||||
CLI::logging(CLI::error("checksum.txt not found, integrity check is not possible") . "\n");
|
// Upgrade actions for global files
|
||||||
if (!CLI::question("Integrity check failed, do you want to continue the upgrade?")) {
|
CLI::logging("* Start cleaning compiled folder...\n");
|
||||||
CLI::logging("Upgrade failed\n");
|
$start = microtime(true);
|
||||||
$flag = G::isPMUnderUpdating(0);
|
if (defined('PATH_C')) {
|
||||||
die();
|
G::rm_dir(PATH_C);
|
||||||
}
|
G::mk_dir(PATH_C, 0777);
|
||||||
} else {
|
|
||||||
if (!empty($checksum['missing'])) {
|
|
||||||
CLI::logging(CLI::error("The following files were not found in the installation:")."\n");
|
|
||||||
foreach ($checksum['missing'] as $missing) {
|
|
||||||
CLI::logging(" $missing\n");
|
|
||||||
}
|
}
|
||||||
}
|
CLI::logging("* End cleaning compiled folder...(Completed on " . (microtime(true) - $start) . " seconds)\n");
|
||||||
if (!empty($checksum['diff'])) {
|
|
||||||
CLI::logging(CLI::error("The following files have modifications:")."\n");
|
CLI::logging("* Start to remove deprecated files...\n");
|
||||||
foreach ($checksum['diff'] as $diff) {
|
$start = microtime(true);
|
||||||
CLI::logging(" $diff\n");
|
$workspace->removeDeprecatedFiles();
|
||||||
|
CLI::logging("* End to remove deprecated files...(Completed on " . (microtime(true) - $start) . " seconds)\n");
|
||||||
|
|
||||||
|
CLI::logging("* Start checking Enterprise folder/files...\n");
|
||||||
|
$start = microtime(true);
|
||||||
|
$workspace->verifyFilesOldEnterprise();
|
||||||
|
CLI::logging("* End checking Enterprise folder/files...(Completed on " . (microtime(true) - $start) . " seconds)\n");
|
||||||
|
|
||||||
|
CLI::logging("* Start checking framework paths...\n");
|
||||||
|
$start = microtime(true);
|
||||||
|
$workspace->checkFrameworkPaths();
|
||||||
|
CLI::logging("* End checking framework paths...(Completed on " . (microtime(true) - $start) . " seconds)\n");
|
||||||
|
|
||||||
|
CLI::logging("* Start fixing serialized instance in serverConf.singleton file...\n");
|
||||||
|
$start = microtime(true);
|
||||||
|
$serverConf = ServerConf::getSingleton();
|
||||||
|
$serverConf->updateClassNameInFile();
|
||||||
|
CLI::logging("* End fixing serialized instance in serverConf.singleton file...(Completed on " .
|
||||||
|
(microtime(true) - $start) . " seconds)\n");
|
||||||
|
|
||||||
|
CLI::logging("* Start the safe upgrade for javascript files cached by the browser (Maborak, ExtJs)...\n");
|
||||||
|
$start = microtime(true);
|
||||||
|
G::browserCacheFilesSetUid();
|
||||||
|
CLI::logging("* End the safe upgrade for javascript files cached by the browser (Maborak, ExtJs)...(Completed on " .
|
||||||
|
(microtime(true) - $start) . " seconds)\n");
|
||||||
|
|
||||||
|
CLI::logging("* Start to backup patch files...\n");
|
||||||
|
$arrayPatch = glob(PATH_TRUNK . 'patch-*');
|
||||||
|
if ($arrayPatch) {
|
||||||
|
foreach ($arrayPatch as $value) {
|
||||||
|
if (file_exists($value)) {
|
||||||
|
// Copy patch content
|
||||||
|
$names = pathinfo($value);
|
||||||
|
$nameFile = $names['basename'];
|
||||||
|
|
||||||
|
$contentFile = file_get_contents($value);
|
||||||
|
$contentFile = preg_replace("[\n|\r|\n\r]", '', $contentFile);
|
||||||
|
CLI::logging($contentFile . ' installed (' . $nameFile . ')', PATH_DATA . 'log/upgrades.log');
|
||||||
|
|
||||||
|
// Move patch file
|
||||||
|
$newFile = PATH_DATA . $nameFile;
|
||||||
|
G::rm_dir($newFile);
|
||||||
|
copy($value, $newFile);
|
||||||
|
G::rm_dir($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
CLI::logging("* End to backup patch files...(Completed on " . (microtime(true) - $start) . " seconds)\n");
|
||||||
if (!(empty($checksum['missing']) || empty($checksum['diff']))) {
|
|
||||||
if (!CLI::question("Integrity check failed, do you want to continue the upgrade?")) {
|
|
||||||
CLI::logging("Upgrade failed\n");
|
|
||||||
$flag = G::isPMUnderUpdating(0);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CLI::logging("Clearing cache...\n");
|
|
||||||
if (defined('PATH_C')) {
|
|
||||||
G::rm_dir(PATH_C);
|
|
||||||
G::mk_dir(PATH_C, 0777);
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = count($workspaces);
|
CLI::logging("* Start to backup log files...\n");
|
||||||
$first = true;
|
$start = microtime(true);
|
||||||
$errors = false;
|
$workspace->backupLogFiles();
|
||||||
$countWorkspace = 0;
|
CLI::logging("* End to backup log files... (Completed on " . (microtime(true) - $start) . " seconds)\n");
|
||||||
$buildCacheView = array_key_exists('buildACV', $args);
|
|
||||||
$flagUpdateXml = !array_key_exists('noxml', $args);
|
|
||||||
$optionMigrateHistoryData = [
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
'keepDynContent' => array_key_exists('keep_dyn_content', $args)
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($workspaces as $index => $workspace) {
|
// The previous actions should be executed only the first time
|
||||||
if (empty(config("system.workspace"))) {
|
$mainThread = false;
|
||||||
define("SYS_SYS", $workspace->name);
|
|
||||||
config(["system.workspace" => $workspace->name]);
|
|
||||||
}
|
}
|
||||||
|
if ($numberOfWorkspaces === 1) {
|
||||||
|
// Displaying information of the current workspace to upgrade
|
||||||
|
CLI::logging("UPGRADING DATABASE AND FILES OF WORKSPACE '{$workspace->name}' ($countWorkspace/$numberOfWorkspaces)\n");
|
||||||
|
|
||||||
if (!defined("PATH_DATA_SITE")) {
|
// Build parameters
|
||||||
define("PATH_DATA_SITE", PATH_DATA . "sites" . PATH_SEP . config("system.workspace") . PATH_SEP);
|
$arrayOptTranslation = [
|
||||||
}
|
'updateXml' => $updateXmlForms,
|
||||||
|
'updateMafe' => $updateMafe
|
||||||
|
];
|
||||||
|
$optionMigrateHistoryData = [
|
||||||
|
'keepDynContent' => $keepDynContent
|
||||||
|
];
|
||||||
|
|
||||||
if (!defined('DB_ADAPTER')) {
|
// Upgrade database and files from a specific workspace
|
||||||
define('DB_ADAPTER', 'mysql');
|
$workspace->upgrade($workspace->name, SYS_LANG, $arrayOptTranslation, $optionMigrateHistoryData);
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$countWorkspace++;
|
|
||||||
CLI::logging("Upgrading workspaces ($countWorkspace/$count): " . CLI::info($workspace->name) . "\n");
|
|
||||||
$workspace->upgrade($buildCacheView, $workspace->name, false, 'en', ['updateXml' => $flagUpdateXml, 'updateMafe' => $first], $optionMigrateHistoryData);
|
|
||||||
$workspace->close();
|
$workspace->close();
|
||||||
$first = false;
|
} else {
|
||||||
$flagUpdateXml = false;
|
// Build arguments
|
||||||
} catch (Exception $e) {
|
$args = '--child';
|
||||||
CLI::logging("Errors upgrading workspace " . CLI::info($workspace->name) . ": " . CLI::error($e->getMessage()) . "\n");
|
$args .= $updateXmlForms ? '' : ' --no-xml';
|
||||||
$errors = true;
|
$args .= $updateMafe ? '' : ' --no-mafe';
|
||||||
|
$args .= $keepDynContent ? ' --keep_dyn_content' : '';
|
||||||
|
|
||||||
|
// Build and execute command in another thread
|
||||||
|
$command = PHP_BINARY . ' processmaker upgrade ' . $args . ' ' . $workspace->name;
|
||||||
|
passthru($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// After the first execution is required set this values to false
|
||||||
|
$updateXmlForms = false;
|
||||||
|
$updateMafe = false;
|
||||||
|
|
||||||
|
// Increment workspaces counter
|
||||||
|
$countWorkspace++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Verify the information of the singleton ServConf by changing the name of the class if is required.
|
if ($printHF) {
|
||||||
CLI::logging("\nCheck/Fix serialized instance in serverConf.singleton file\n\n");
|
// Print information when finish the upgrade process
|
||||||
$serverConf = ServerConf::getSingleton();
|
CLI::logging('UPGRADE FINISHED (Completed on ' . (microtime(true) - $globalStartTime) .
|
||||||
$serverConf->updateClassNameInFile();
|
' seconds), ProcessMaker ' . System::getVersion() . ' installed)' . "\n\n");
|
||||||
|
|
||||||
// SAVE Upgrades/Patches
|
// Delete upgrade flag
|
||||||
$arrayPatch = glob(PATH_TRUNK . 'patch-*');
|
G::isPMUnderUpdating(0);
|
||||||
|
|
||||||
if ($arrayPatch) {
|
|
||||||
foreach ($arrayPatch as $value) {
|
|
||||||
if (file_exists($value)) {
|
|
||||||
// copy content the patch
|
|
||||||
$names = pathinfo($value);
|
|
||||||
$nameFile = $names['basename'];
|
|
||||||
|
|
||||||
$contentFile = file_get_contents($value);
|
|
||||||
$contentFile = preg_replace("[\n|\r|\n\r]", '', $contentFile);
|
|
||||||
CLI::logging($contentFile . ' installed (' . $nameFile . ')', PATH_DATA . 'log/upgrades.log');
|
|
||||||
|
|
||||||
// move file of patch
|
|
||||||
$newFile = PATH_DATA . $nameFile;
|
|
||||||
G::rm_dir($newFile);
|
|
||||||
copy($value, $newFile);
|
|
||||||
G::rm_dir($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CLI::logging('ProcessMaker ' . System::getVersion(). ' installed', PATH_DATA . 'log/upgrades.log');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Safe upgrade for JavaScript files
|
|
||||||
CLI::logging("\nSafe upgrade for files cached by the browser\n\n");
|
|
||||||
|
|
||||||
G::browserCacheFilesSetUid();
|
|
||||||
|
|
||||||
//Status
|
|
||||||
if ($errors) {
|
|
||||||
CLI::logging("Upgrade finished but there were errors upgrading workspaces.\n");
|
|
||||||
CLI::logging(CLI::error("Please check the log above to correct any issues.") . "\n");
|
|
||||||
} else {
|
|
||||||
CLI::logging("Upgrade successful\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//setting flag to false
|
|
||||||
$flag = G::isPMUnderUpdating(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function listFiles($dir)
|
|
||||||
{
|
|
||||||
$files = array();
|
|
||||||
$lista = glob($dir.'/*');
|
|
||||||
foreach ($lista as $valor) {
|
|
||||||
if (is_dir($valor)) {
|
|
||||||
$inner_files = listFiles($valor);
|
|
||||||
if (is_array($inner_files)) {
|
|
||||||
$files = array_merge($files, $inner_files);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_file($valor)) {
|
|
||||||
array_push($files, $valor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $files;
|
|
||||||
}
|
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
function run_unify_database($args)
|
function run_unify_database($args)
|
||||||
{
|
{
|
||||||
@@ -314,3 +301,25 @@ function run_unify_database($args)
|
|||||||
$flag = G::isPMUnderUpdating(0);
|
$flag = G::isPMUnderUpdating(0);
|
||||||
}
|
}
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query, used internally for upgrade process
|
||||||
|
*
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
function runUpgradeQuery($options)
|
||||||
|
{
|
||||||
|
// Initializing variables
|
||||||
|
$workspaceName = $options[0];
|
||||||
|
$query = base64_decode($options[1]);
|
||||||
|
$isRbac = (bool)$options[2];
|
||||||
|
|
||||||
|
// Creating a new instance of the extended class
|
||||||
|
$workspace = new WorkspaceTools($workspaceName);
|
||||||
|
|
||||||
|
// Execute the query
|
||||||
|
$workspace->upgradeQuery($query, $isRbac);
|
||||||
|
|
||||||
|
// Terminate without error
|
||||||
|
exit('success');
|
||||||
|
}
|
||||||
|
|||||||
@@ -106,26 +106,6 @@ EOT
|
|||||||
CLI::taskArg('workspace', true, true);
|
CLI::taskArg('workspace', true, true);
|
||||||
CLI::taskRun("run_plugins_database_upgrade");
|
CLI::taskRun("run_plugins_database_upgrade");
|
||||||
|
|
||||||
CLI::taskName('workspace-upgrade');
|
|
||||||
CLI::taskDescription(<<<EOT
|
|
||||||
Upgrade the specified workspace(s).
|
|
||||||
|
|
||||||
If no workspace is specified, the command will be run in all workspaces. More
|
|
||||||
than one workspace can be specified.
|
|
||||||
|
|
||||||
This command is a shortcut to execute all the upgrade commands for workspaces.
|
|
||||||
Upgrading a workspace will make it correspond to the current version of
|
|
||||||
ProcessMaker.
|
|
||||||
|
|
||||||
Use this command to upgrade workspaces individually, otherwise use the
|
|
||||||
'processmaker upgrade' command to upgrade the entire system.
|
|
||||||
EOT
|
|
||||||
);
|
|
||||||
CLI::taskArg('workspace-name', true, true);
|
|
||||||
CLI::taskOpt('buildACV', 'If this option is enabled, the Cache View is built.', 'ACV', 'buildACV');
|
|
||||||
CLI::taskOpt('noxml', 'If this option is enabled, the XML files translation is not built.', 'NoXml', 'no-xml');
|
|
||||||
CLI::taskRun("run_workspace_upgrade");
|
|
||||||
|
|
||||||
CLI::taskName('translation-repair');
|
CLI::taskName('translation-repair');
|
||||||
CLI::taskDescription(<<<EOT
|
CLI::taskDescription(<<<EOT
|
||||||
Upgrade or repair translations for the specified workspace(s).
|
Upgrade or repair translations for the specified workspace(s).
|
||||||
@@ -412,69 +392,6 @@ function run_info($args, $opts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we need to execute the workspace-upgrade
|
|
||||||
* If we apply the command for all workspaces, we will need to execute one by one by redefining the constants
|
|
||||||
*
|
|
||||||
* @param string $args, workspace name that we need to apply the database-upgrade
|
|
||||||
* @param string $opts, additional arguments
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function run_workspace_upgrade($args, $opts)
|
|
||||||
{
|
|
||||||
//Read the additional parameters for this command
|
|
||||||
$parameters = '';
|
|
||||||
$parameters .= array_key_exists('buildACV', $opts) ? '--buildACV ' : '';
|
|
||||||
$parameters .= array_key_exists('noxml', $opts) ? '--no-xml ' : '';
|
|
||||||
$parameters .= array_key_exists("lang", $opts) ? 'lang=' . $opts['lang'] : 'lang=' . SYS_LANG;
|
|
||||||
|
|
||||||
//Check if the command is executed by a specific workspace
|
|
||||||
if (count($args) === 1) {
|
|
||||||
workspace_upgrade($args, $opts);
|
|
||||||
} else {
|
|
||||||
$workspaces = get_workspaces_from_args($args);
|
|
||||||
foreach ($workspaces as $workspace) {
|
|
||||||
passthru(PHP_BINARY . ' processmaker upgrade ' . $parameters . ' ' . $workspace->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is executed only by one workspace, for the command workspace-upgrade
|
|
||||||
*
|
|
||||||
* @param array $args, workspace name for to apply the upgrade
|
|
||||||
* @param array $opts, specify additional arguments for language, flag for buildACV, flag for noxml
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function workspace_upgrade($args, $opts) {
|
|
||||||
$first = true;
|
|
||||||
$workspaces = get_workspaces_from_args($args);
|
|
||||||
$lang = array_key_exists("lang", $opts) ? $opts['lang'] : 'en';
|
|
||||||
$buildCacheView = array_key_exists('buildACV', $opts);
|
|
||||||
$flagUpdateXml = !array_key_exists('noxml', $opts);
|
|
||||||
|
|
||||||
$wsName = $workspaces[key($workspaces)]->name;
|
|
||||||
Bootstrap::setConstantsRelatedWs($wsName);
|
|
||||||
//Loop, read all the attributes related to the one workspace
|
|
||||||
foreach ($workspaces as $workspace) {
|
|
||||||
try {
|
|
||||||
$workspace->upgrade(
|
|
||||||
$buildCacheView,
|
|
||||||
$workspace->name,
|
|
||||||
false,
|
|
||||||
$lang,
|
|
||||||
['updateXml' => $flagUpdateXml, 'updateMafe' => $first]
|
|
||||||
);
|
|
||||||
$first = false;
|
|
||||||
$flagUpdateXml = false;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
G::outRes("Errors upgrading workspace " . CLI::info($workspace->name) . ": " . CLI::error($e->getMessage()) . "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We will upgrade the CONTENT table
|
* We will upgrade the CONTENT table
|
||||||
* If we apply the command for all workspaces, we will need to execute one by one by redefining the constants
|
* If we apply the command for all workspaces, we will need to execute one by one by redefining the constants
|
||||||
@@ -1121,7 +1038,7 @@ function migrate_new_cases_lists($command, $args, $opts)
|
|||||||
foreach ($workspaces as $workspace) {
|
foreach ($workspaces as $workspace) {
|
||||||
print_r("Upgrading database in " . pakeColor::colorize($workspace->name, "INFO") . "\n");
|
print_r("Upgrading database in " . pakeColor::colorize($workspace->name, "INFO") . "\n");
|
||||||
try {
|
try {
|
||||||
$workspace->migrateList($workspace->name, true, $lang);
|
$workspace->migrateList(true, $lang);
|
||||||
echo "> List tables are done\n";
|
echo "> List tables are done\n";
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
G::outRes("> Error: " . CLI::error($e->getMessage()) . "\n");
|
G::outRes("> Error: " . CLI::error($e->getMessage()) . "\n");
|
||||||
@@ -1146,17 +1063,15 @@ function migrate_counters($command, $args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function migrate_list_unassigned($command, $args, $opts)
|
function migrate_list_unassigned($command, $args)
|
||||||
{
|
{
|
||||||
$filter = new InputFilter();
|
$filter = new InputFilter();
|
||||||
$opts = $filter->xssFilterHard($opts);
|
|
||||||
$args = $filter->xssFilterHard($args);
|
$args = $filter->xssFilterHard($args);
|
||||||
$lang = array_key_exists("lang", $opts) ? $opts['lang'] : 'en';
|
|
||||||
$workspaces = get_workspaces_from_args($args);
|
$workspaces = get_workspaces_from_args($args);
|
||||||
foreach ($workspaces as $workspace) {
|
foreach ($workspaces as $workspace) {
|
||||||
print_r("Upgrading Unassigned List in" . pakeColor::colorize($workspace->name, "INFO") . "\n");
|
print_r("Upgrading Unassigned List in" . pakeColor::colorize($workspace->name, "INFO") . "\n");
|
||||||
try {
|
try {
|
||||||
$workspace->regenerateListUnassigned();
|
$workspace->runRegenerateListUnassigned();
|
||||||
echo "> Unassigned List is done\n";
|
echo "> Unassigned List is done\n";
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
G::outRes("> Error: " . CLI::error($e->getMessage()) . "\n");
|
G::outRes("> Error: " . CLI::error($e->getMessage()) . "\n");
|
||||||
@@ -1210,7 +1125,7 @@ function migrate_content($args, $opts)
|
|||||||
foreach ($workspaces as $workspace) {
|
foreach ($workspaces as $workspace) {
|
||||||
print_r('Regenerating content in: ' . pakeColor::colorize($workspace->name, 'INFO') . "\n");
|
print_r('Regenerating content in: ' . pakeColor::colorize($workspace->name, 'INFO') . "\n");
|
||||||
CLI::logging("-> Regenerating content \n");
|
CLI::logging("-> Regenerating content \n");
|
||||||
$workspace->migrateContentRun($workspace->name, $lang);
|
$workspace->migrateContentRun($lang);
|
||||||
}
|
}
|
||||||
$stop = microtime(true);
|
$stop = microtime(true);
|
||||||
CLI::logging("<*> Optimizing content data Process took " . ($stop - $start) . " seconds.\n");
|
CLI::logging("<*> Optimizing content data Process took " . ($stop - $start) . " seconds.\n");
|
||||||
@@ -1462,4 +1377,4 @@ function check_queries_incompatibilities($wsName)
|
|||||||
} else {
|
} else {
|
||||||
echo ">> No MySQL 5.7 incompatibilities in variables found for this workspace." . PHP_EOL;
|
echo ">> No MySQL 5.7 incompatibilities in variables found for this workspace." . PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,11 +94,21 @@ class MultipleFilesBackup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore from file(s) commpressed by letsBackup function, into a temporary directory
|
/**
|
||||||
* @ filename got the name and path of the compressed file(s), if there are many files with file extention as a numerical series, the extention should be discriminated.
|
* Restore from file(s) compressed by letsBackup function, into a temporary directory
|
||||||
* @ srcWorkspace contains the workspace to be restored.
|
*
|
||||||
* @ dstWorkspace contains the workspace to be overwriting.
|
* @param string $filename Got the name and path of the compressed file(s), if there are many files with file extention as a numerical series, the extention should be discriminated.
|
||||||
* @ overwrite got the option true if the workspace will be overwrite.
|
* @param string $srcWorkspace Contains the workspace to be restored.
|
||||||
|
* @param bool $dstWorkspace Contains the workspace to be overwriting.
|
||||||
|
* @param bool $overwrite Got the option true if the workspace will be overwrite.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
* @see workflow/engine/bin/tasks/cliWorkspaces.php::run_workspace_restore()
|
||||||
|
*
|
||||||
|
* @link https://wiki.processmaker.com/3.0/Backing_up_and_Restoring_ProcessMaker#RestoringWorkspaces
|
||||||
|
*
|
||||||
|
* @deprecated Method outdated, only run the upgrade of APP_CACHE_VIEW table
|
||||||
*/
|
*/
|
||||||
public static function letsRestore($filename, $srcWorkspace, $dstWorkspace = null, $overwrite = true)
|
public static function letsRestore($filename, $srcWorkspace, $dstWorkspace = null, $overwrite = true)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,128 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
use ProcessMaker\Core\System;
|
|
||||||
|
|
||||||
class Upgrade
|
|
||||||
{
|
|
||||||
private $addon = null;
|
|
||||||
|
|
||||||
public function __construct($addon)
|
|
||||||
{
|
|
||||||
$this->addon = $addon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function install()
|
|
||||||
{
|
|
||||||
|
|
||||||
$filter = new InputFilter();
|
|
||||||
$start = microtime(1);
|
|
||||||
$filename = $this->addon->getDownloadFilename();
|
|
||||||
$time = microtime(1);
|
|
||||||
|
|
||||||
$archive = new Archive_Tar ($filename);
|
|
||||||
$time = microtime(1);
|
|
||||||
$extractDir = dirname($this->addon->getDownloadFilename()) . "/extract";
|
|
||||||
$extractDir = $filter->xssFilterHard($extractDir);
|
|
||||||
$backupDir = dirname($this->addon->getDownloadFilename()) . "/backup";
|
|
||||||
$backupDir = $filter->xssFilterHard($backupDir);
|
|
||||||
if (file_exists($extractDir)) {
|
|
||||||
G::rm_dir($extractDir);
|
|
||||||
}
|
|
||||||
if (file_exists($backupDir)) {
|
|
||||||
G::rm_dir($backupDir);
|
|
||||||
}
|
|
||||||
if (!is_dir($backupDir)) {
|
|
||||||
mkdir($backupDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
$time = microtime(1);
|
|
||||||
echo "Extracting files...\n";
|
|
||||||
$archive->extractModify($extractDir, 'processmaker');
|
|
||||||
$checksumFile = file_get_contents("$extractDir/checksum.txt");
|
|
||||||
$time = microtime(1);
|
|
||||||
$checksums = array();
|
|
||||||
foreach (explode("\n", $checksumFile) as $line) {
|
|
||||||
$checksums[trim(substr($line, 33))] = substr($line, 0, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
$checksum = array();
|
|
||||||
$changedFiles = array();
|
|
||||||
$time = microtime(1);
|
|
||||||
$files = $this->ls_dir($extractDir);
|
|
||||||
|
|
||||||
echo "Updating ProcessMaker files...\n";
|
|
||||||
$time = microtime(1);
|
|
||||||
$checksumTime = 0;
|
|
||||||
foreach ($checksums as $filename => $checksum) {
|
|
||||||
if (is_dir("$extractDir/$filename")) {
|
|
||||||
$filename = $filter->xssFilterHard($filename);
|
|
||||||
print $filename;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$installedFile = PATH_TRUNK . "/$filename";
|
|
||||||
if (!file_exists($installedFile)) {
|
|
||||||
$installedMD5 = "";
|
|
||||||
} else {
|
|
||||||
$time = microtime(1);
|
|
||||||
$installedMD5 = G::encryptFileOld($installedFile);
|
|
||||||
$checksumTime += microtime(1) - $time;
|
|
||||||
}
|
|
||||||
$archiveMD5 = $checksum;
|
|
||||||
if (strcasecmp($archiveMD5, $installedMD5) != 0) {
|
|
||||||
$changedFiles[] = $filename;
|
|
||||||
if (!is_dir(dirname($backupDir.'/'.$filename))) {
|
|
||||||
mkdir(dirname($backupDir.'/'.$filename), 0777, true);
|
|
||||||
}
|
|
||||||
if (file_exists($installedFile) && is_file($installedFile)) {
|
|
||||||
copy($installedFile, $backupDir.'/'.$filename);
|
|
||||||
}
|
|
||||||
if (!is_dir(dirname($installedFile))) {
|
|
||||||
mkdir(dirname($installedFile), 0777, true);
|
|
||||||
}
|
|
||||||
if (!copy("$extractDir/$filename", $installedFile)) {
|
|
||||||
throw new Exception("Could not overwrite '$filename'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Updated %d files\n", count($changedFiles));
|
|
||||||
printf("Clearing cache...\n");
|
|
||||||
if (defined('PATH_C')) {
|
|
||||||
G::rm_dir(PATH_C);
|
|
||||||
mkdir(PATH_C, 0777, true);
|
|
||||||
}
|
|
||||||
$workspaces = System::listWorkspaces();
|
|
||||||
$count = count($workspaces);
|
|
||||||
$first = true;
|
|
||||||
$num = 0;
|
|
||||||
foreach ($workspaces as $index => $workspace) {
|
|
||||||
try {
|
|
||||||
$num += 1;
|
|
||||||
printf("Upgrading workspaces ($num/$count): {$workspace->name}\n");
|
|
||||||
$workspace->upgrade(false, config("system.workspace"), false, 'en', ['updateXml' => $first, 'updateMafe' => $first]);
|
|
||||||
$workspace->close();
|
|
||||||
$first = false;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
printf("Errors upgrading workspace {$workspace->name}: {$e->getMessage()}\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function ls_dir($dir, $basename = null)
|
|
||||||
{
|
|
||||||
$files = array();
|
|
||||||
if ($basename == null) {
|
|
||||||
$basename = $dir;
|
|
||||||
}
|
|
||||||
foreach (glob("$dir/*") as $filename) {
|
|
||||||
if (is_dir($filename)) {
|
|
||||||
$files = array_merge($files, $this->ls_dir($filename, $basename));
|
|
||||||
} else {
|
|
||||||
$files[] = substr($filename, strlen($basename) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $files;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -385,13 +385,7 @@ class AddonsManager extends BaseAddonsManager
|
|||||||
|
|
||||||
$this->setState();
|
$this->setState();
|
||||||
} else {
|
} else {
|
||||||
if ($this->getAddonType() == "core") {
|
throw new Exception("Addon type {$this->getAddonType()} not supported.");
|
||||||
$upgrade = new Upgrade($this);
|
|
||||||
|
|
||||||
$upgrade->install();
|
|
||||||
} else {
|
|
||||||
throw new Exception("Addon type {$this->getAddonType()} not supported.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,10 @@ class AppCacheView extends BaseAppCacheView
|
|||||||
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
||||||
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
||||||
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
||||||
$c->add(TaskPeer::TAS_GROUP_VARIABLE, '');
|
$c->add(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, '')->addOr(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, null, Criteria::ISNULL))
|
||||||
|
);
|
||||||
$c->add(TaskUserPeer::USR_UID, $userUid);
|
$c->add(TaskUserPeer::USR_UID, $userUid);
|
||||||
|
|
||||||
$rs = TaskPeer::doSelectRS($c);
|
$rs = TaskPeer::doSelectRS($c);
|
||||||
@@ -314,7 +317,10 @@ class AppCacheView extends BaseAppCacheView
|
|||||||
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
||||||
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
||||||
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
||||||
$c->add(TaskPeer::TAS_GROUP_VARIABLE, '');
|
$c->add(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, '')->addOr(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, null, Criteria::ISNULL))
|
||||||
|
);
|
||||||
$c->add(TaskUserPeer::USR_UID, $aGroups, Criteria::IN);
|
$c->add(TaskUserPeer::USR_UID, $aGroups, Criteria::IN);
|
||||||
|
|
||||||
$rs = TaskPeer::doSelectRS($c);
|
$rs = TaskPeer::doSelectRS($c);
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ class AppDelay extends BaseAppDelay
|
|||||||
if (empty($usrUid)) {
|
if (empty($usrUid)) {
|
||||||
global $RBAC;
|
global $RBAC;
|
||||||
$usrUid = $RBAC->aUserInfo['USER_INFO']['USR_UID'];
|
$usrUid = $RBAC->aUserInfo['USER_INFO']['USR_UID'];
|
||||||
|
}
|
||||||
|
if (empty($usrId)) {
|
||||||
$u = new Users();
|
$u = new Users();
|
||||||
$usrId = $u->load($usrUid)['USR_ID'];
|
$usrId = $u->load($usrUid)['USR_ID'];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -398,7 +398,10 @@ class ListUnassigned extends BaseListUnassigned implements ListInterface
|
|||||||
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
||||||
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
||||||
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
||||||
$c->add(TaskPeer::TAS_GROUP_VARIABLE, '');
|
$c->add(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, '')->addOr(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, null, Criteria::ISNULL))
|
||||||
|
);
|
||||||
$c->add(TaskUserPeer::USR_UID, $userUid);
|
$c->add(TaskUserPeer::USR_UID, $userUid);
|
||||||
//TU_TYPE = 2 is a AdHoc task
|
//TU_TYPE = 2 is a AdHoc task
|
||||||
if (!$adHocUsers) {
|
if (!$adHocUsers) {
|
||||||
@@ -430,7 +433,10 @@ class ListUnassigned extends BaseListUnassigned implements ListInterface
|
|||||||
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
$c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN);
|
||||||
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
$c->add(ProcessPeer::PRO_STATUS, 'ACTIVE');
|
||||||
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
$c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE');
|
||||||
$c->add(TaskPeer::TAS_GROUP_VARIABLE, '');
|
$c->add(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, '')->addOr(
|
||||||
|
$c->getNewCriterion(TaskPeer::TAS_GROUP_VARIABLE, null, Criteria::ISNULL))
|
||||||
|
);
|
||||||
$c->add(TaskUserPeer::USR_UID, $groupsList, Criteria::IN);
|
$c->add(TaskUserPeer::USR_UID, $groupsList, Criteria::IN);
|
||||||
//TU_TYPE = 2 is a AdHoc task
|
//TU_TYPE = 2 is a AdHoc task
|
||||||
if (!$adHocUsers) {
|
if (!$adHocUsers) {
|
||||||
|
|||||||
98
workflow/engine/src/ProcessMaker/Core/ProcessesManager.php
Normal file
98
workflow/engine/src/ProcessMaker/Core/ProcessesManager.php
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ProcessMaker\Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage the processes that runs in the shell
|
||||||
|
*/
|
||||||
|
class ProcessesManager
|
||||||
|
{
|
||||||
|
// Class properties
|
||||||
|
private $processes;
|
||||||
|
private $sleepTime = 1;
|
||||||
|
private $terminated = [];
|
||||||
|
private $errors = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @param array $processes
|
||||||
|
*/
|
||||||
|
public function __construct(array $processes)
|
||||||
|
{
|
||||||
|
$this->processes = $processes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of terminated processes
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTerminated()
|
||||||
|
{
|
||||||
|
return $this->terminated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of processes with errors
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sleep time after each statuses revision
|
||||||
|
*
|
||||||
|
* @param int $sleepTime
|
||||||
|
*/
|
||||||
|
public function setSleepTime($sleepTime)
|
||||||
|
{
|
||||||
|
$this->sleepTime = $sleepTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the processes
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
// Start all processes
|
||||||
|
foreach ($this->processes as $process) {
|
||||||
|
$process->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manage the processes
|
||||||
|
$this->manage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage all started processes
|
||||||
|
*/
|
||||||
|
private function manage()
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
// Check all remaining processes
|
||||||
|
foreach ($this->processes as $index => $process) {
|
||||||
|
// If the process has finished, save the info and destroy it
|
||||||
|
if ($process->getStatus() === RunProcess::TERMINATED || $process->getStatus() === RunProcess::ERROR) {
|
||||||
|
$processInfo = ['command' => $process->getCommand(), 'rawAnswer' => $process->getRawAnswer()];
|
||||||
|
if ($process->getStatus() === RunProcess::TERMINATED) {
|
||||||
|
// Processes completed successfully
|
||||||
|
$this->terminated[] = $processInfo;
|
||||||
|
} else {
|
||||||
|
// Processes completed with errors
|
||||||
|
$this->errors[] = $processInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the process
|
||||||
|
unset($this->processes[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Waiting...
|
||||||
|
sleep($this->sleepTime);
|
||||||
|
} while (!empty($this->processes));
|
||||||
|
}
|
||||||
|
}
|
||||||
146
workflow/engine/src/ProcessMaker/Core/RunProcess.php
Normal file
146
workflow/engine/src/ProcessMaker/Core/RunProcess.php
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ProcessMaker\Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class run a command in shell and stores the pointer to him
|
||||||
|
*/
|
||||||
|
class RunProcess
|
||||||
|
{
|
||||||
|
// Class constants
|
||||||
|
const TERMINATED = 'terminated';
|
||||||
|
const RUNNING = 'running';
|
||||||
|
const NOT_RUNNING = 'not_running';
|
||||||
|
const ERROR = 'error';
|
||||||
|
|
||||||
|
// This constant can be overrides in the child class according to the command response, always should be have a value
|
||||||
|
const EXPECTED_ANSWER = '1';
|
||||||
|
|
||||||
|
// Class properties
|
||||||
|
private $resource;
|
||||||
|
private $command;
|
||||||
|
private $rawAnswer;
|
||||||
|
private $status;
|
||||||
|
private $exitCode;
|
||||||
|
private $pipes;
|
||||||
|
private $descriptors = [
|
||||||
|
['pipe', 'r'],
|
||||||
|
['pipe', 'w'],
|
||||||
|
['pipe', 'w']
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @param string $command
|
||||||
|
*/
|
||||||
|
public function __construct($command)
|
||||||
|
{
|
||||||
|
$this->command = $command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class destructor, the resource created should be closed
|
||||||
|
*/
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
if (is_resource($this->resource)) {
|
||||||
|
proc_close($this->resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the command
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCommand()
|
||||||
|
{
|
||||||
|
return $this->command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the raw response
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getRawAnswer()
|
||||||
|
{
|
||||||
|
return $this->rawAnswer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getStatus()
|
||||||
|
{
|
||||||
|
// If already exist a status return this value
|
||||||
|
if ($this->status !== null) {
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If doesn't exists a resource the process is not running
|
||||||
|
if (!is_resource($this->resource)) {
|
||||||
|
return self::NOT_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the process is running return this value
|
||||||
|
if ($this->isRunning()) {
|
||||||
|
return self::RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the process is not running, parse the response to determine the status
|
||||||
|
$this->rawAnswer = stream_get_contents($this->pipes[1]);
|
||||||
|
$this->status = $this->parseAnswer();
|
||||||
|
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the exit code
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getExitCode()
|
||||||
|
{
|
||||||
|
return $this->exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the command
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$this->resource = proc_open($this->command, $this->descriptors, $this->pipes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process is running?
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isRunning()
|
||||||
|
{
|
||||||
|
// Get the process status
|
||||||
|
$status = proc_get_status($this->resource);
|
||||||
|
|
||||||
|
// If process is not running get the exit code
|
||||||
|
if ($status['running'] === false) {
|
||||||
|
$this->exitCode = $status['exitcode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $status['running'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the raw response and compare with the expected answer in order to determine the status
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function parseAnswer()
|
||||||
|
{
|
||||||
|
return $this->rawAnswer === self::EXPECTED_ANSWER ? self::TERMINATED : self::ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -243,39 +243,6 @@ class System
|
|||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Review the checksum.txt
|
|
||||||
*
|
|
||||||
* @return array $result
|
|
||||||
*/
|
|
||||||
public static function verifyChecksum()
|
|
||||||
{
|
|
||||||
if (!file_exists(PATH_TRUNK . "checksum.txt")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$lines = explode("\n", file_get_contents(PATH_TRUNK . "checksum.txt"));
|
|
||||||
$result = array("diff" => array(), "missing" => array()
|
|
||||||
);
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
if (empty($line)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
list ($checksum, $empty, $filename) = explode(" ", $line);
|
|
||||||
//Skip xmlform because these files always change.
|
|
||||||
if (strpos($filename, "/xmlform/") !== false) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (file_exists(realpath($filename))) {
|
|
||||||
if (strcmp($checksum, G::encryptFileOld(realpath($filename))) != 0) {
|
|
||||||
$result['diff'][] = $filename;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result['missing'][] = $filename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function checks files to do updated to pm
|
* This function checks files to do updated to pm
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ProcessMaker\Upgrade;
|
||||||
|
|
||||||
|
use ProcessMaker\Core\RunProcess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended class to manage the processes that executes a queries in the upgrade process
|
||||||
|
*/
|
||||||
|
class RunProcessUpgradeQuery extends RunProcess
|
||||||
|
{
|
||||||
|
// Class constants
|
||||||
|
const SUCCESS = 'success';
|
||||||
|
const CMD = PHP_BINARY . ' processmaker upgrade-query %s %s %s';
|
||||||
|
const RBAC = '1';
|
||||||
|
const NO_RBAC = '0';
|
||||||
|
|
||||||
|
// Class properties
|
||||||
|
private $workspace;
|
||||||
|
private $sql;
|
||||||
|
private $isRbac;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @param string $workspace
|
||||||
|
* @param string $sql
|
||||||
|
* @param bool $isRbac
|
||||||
|
*/
|
||||||
|
public function __construct($workspace, $sql, $isRbac = false)
|
||||||
|
{
|
||||||
|
// Set properties values
|
||||||
|
$this->workspace = $workspace;
|
||||||
|
$this->sql = $sql;
|
||||||
|
$this->isRbac = $isRbac;
|
||||||
|
|
||||||
|
// Build the command and send to the parent class
|
||||||
|
parent::__construct($this->buildCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the parent method in order to compare the raw response with the SUCCESS value
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function parseAnswer()
|
||||||
|
{
|
||||||
|
return $this->getRawAnswer() === self::SUCCESS ? parent::TERMINATED : parent::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the command to execute a query for the upgrade process
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function buildCommand()
|
||||||
|
{
|
||||||
|
return sprintf(self::CMD, $this->workspace, base64_encode($this->sql),
|
||||||
|
($this->isRbac ? self::RBAC : self::NO_RBAC));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user