From 463743d3bffd13223191dec9c70bde5c50f2ba15 Mon Sep 17 00:00:00 2001 From: Ralph Asendeteufrer Date: Thu, 11 Oct 2012 16:54:52 -0400 Subject: [PATCH 1/5] BUG 8626 Backup issues PROBLEM the backup is too bigger to be handle in some os configurations systema files SOLUTION A new class will help to compress into several files instead one. to use the new feature the admin would use and extra option as follow: processmaker workspace-backup -s {} to restore may use : processmaker workspace-restore -m In both case there are to new arguments -s and -m, these are for use the new feature only, if they are not added the old way is still available. --- workflow/engine/bin/tasks/cliWorkspaces.php | 36 ++- workflow/engine/classes/class.wsTools.php | 237 +++++++++++++++++++- 2 files changed, 260 insertions(+), 13 deletions(-) diff --git a/workflow/engine/bin/tasks/cliWorkspaces.php b/workflow/engine/bin/tasks/cliWorkspaces.php index a73f674e0..47e5f6c2b 100755 --- a/workflow/engine/bin/tasks/cliWorkspaces.php +++ b/workflow/engine/bin/tasks/cliWorkspaces.php @@ -52,6 +52,7 @@ EOT ); CLI::taskArg('workspace', false); CLI::taskArg('backup-file', true); +CLI::taskOpt("filesize", "Set the max size of the compresed splitted files, by default the max is 1000 Mb.", "s:","filesize="); CLI::taskRun(run_workspace_backup); CLI::taskName('workspace-restore'); @@ -70,11 +71,12 @@ CLI::taskArg('backup-file', false); CLI::taskArg('workspace', true); CLI::taskOpt("overwrite", "If a workspace already exists, overwrite it.", "o", "overwrite"); CLI::taskOpt("info", "Only shows information about a backup archive.", "i"); +CLI::taskOpt("multiple", "Restore from multiple compresed enumerated files.", "m"); CLI::taskOpt("workspace", "Select which workspace to restore if multiple workspaces are present in the archive.", "w:", "workspace="); CLI::taskRun(run_workspace_restore); -CLI::taskName('cacheview-repair'); +CLI::taskName('cacheview-rep air'); CLI::taskDescription(<<workspaceExists()) throw new Exception("Workspace '{$workspace->name}' not found"); //If this is a relative path, put the file in the backups directory - if (strpos($filename, "/") === false && strpos($filename, '\\') === false) + if (strpos($filename, "/") === false && strpos($filename, '\\') === false){ $filename = PATH_DATA . "backups/$filename"; + } CLI::logging("Backing up to $filename\n"); - $backup = workspaceTools::createBackup($filename); - foreach ($workspaces as $workspace) - $workspace->backup($backup); + $filesize = array_key_exists("filesize", $opts) ? $opts['filesize'] : -1; + if($filesize >= 0) + { + $multipleBackup = new MultipleFilesBackup ($filename,$filesize);//if filesize is 0 the default size will be took + //using new method + foreach ($workspaces as $workspace){ + $multipleBackup->addToBackup($workspace); + } + $multipleBackup->letsBackup(); + } + else + { + //ansient method to backup into one large file + $backup = workspaceTools::createBackup($filename); + foreach ($workspaces as $workspace) + $workspace->backup($backup); + } CLI::logging("\n"); workspaceTools::printSysInfo(); foreach ($workspaces as $workspace) { @@ -405,8 +422,15 @@ function run_workspace_restore($args, $opts) { CLI::logging("Restoring from $filename\n"); $workspace = array_key_exists("workspace", $opts) ? $opts['workspace'] : NULL; $overwrite = array_key_exists("overwrite", $opts); + $multiple = array_key_exists("multiple", $opts); $dstWorkspace = $args[1]; - workspaceTools::restore($filename, $workspace, $dstWorkspace, $overwrite); +//echo "filename: ".$filename." workspace:".$workspace." dts:".$dstWorkspace." over:".$overwrite." multiple:".$multiple."\n"; + if(!empty($multiple)){ + MultipleFilesBackup::letsRestore ($filename,$workspace,$dstWorkspace,$overwrite); + } + else{ + workspaceTools::restore($filename, $workspace, $dstWorkspace, $overwrite); + } } } diff --git a/workflow/engine/classes/class.wsTools.php b/workflow/engine/classes/class.wsTools.php index 7177e8f67..5ec820ff0 100755 --- a/workflow/engine/classes/class.wsTools.php +++ b/workflow/engine/classes/class.wsTools.php @@ -292,12 +292,15 @@ class workspaceTools { */ public function upgradeContent($workSpace=SYS_SYS) { $this->initPropel(true); - require_once 'classes/model/Translation.php'; - $translation = new Translation(); - $information = $translation->getTranslationEnvironments(); - $arrayLang = array(); - foreach ($information as $key => $value) { - $arrayLang[] = trim($value['LOCALE']); + require_once('classes/model/Language.php'); + G::LoadThirdParty('pear/json', 'class.json'); + $lang = array(); + foreach (System::listPoFiles() as $poFile) { + $poName = basename($poFile); + $names = explode(".", basename($poFile)); + $extension = array_pop($names); + $langid = array_pop($names); + $arrayLang[] = $langid; } require_once('classes/model/Content.php'); $regenerateContent = new Content(); @@ -868,7 +871,6 @@ class workspaceTools { //Remove leftovers. G::rm_dir($tempDirectory); } - //TODO: Move to class.dbMaintenance.php /** * create a user in the database @@ -1114,4 +1116,225 @@ class workspaceTools { } } + + +/** Class MultipleFilesBackup +* create a backup of this workspace +* +* Exports the database and copies the files to an tar archive o several if the max filesize is reached. +* +*/ +class MultipleFilesBackup{ + + private $dir_to_compress = ""; + private $filename = "backUpProcessMaker.tar"; + private $fileSize = "1000"; // 1 GB by default. + private $sizeDescriptor = "m"; //megabytes + private $tempDirectories=array(); + + /* Constructor + * @filename contains the path and filename of the comppress file(s). + * @size got the Max size of the compressed files, by default if the $size less to zero will mantains 1000 Mb as Max size. + */ + function MultipleFilesBackup($filename,$size) + { + if(!empty($filename)){ + $this->filename = $filename; + } + if(!empty($size) && (int)$size > 0){ + $this->fileSize = $size; + } + } + /* Gets workspace information enough to make its backup. + * @workspace contains the workspace to be add to the commpression process. + */ + public function addToBackup($workspace) + { + //verifing if workspace exists. + if (!$workspace->workspaceExists()) { + echo "Workspace {$workspace->name} not found\n"; + return false; + } + //create destination path + if (!file_exists(PATH_DATA . "upgrade/")){ + mkdir(PATH_DATA . "upgrade/"); + } + $tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, '')); + mkdir($tempDirectory); + $metadata = $workspace->getMetadata(); + CLI::logging("Temporing up database...\n"); + $metadata["databases"] = $workspace->exportDatabase($tempDirectory); + $metadata["directories"] = array("{$workspace->name}.files"); + $metadata["version"] = 1; + $metaFilename = "$tempDirectory/{$workspace->name}.meta"; + if (!file_put_contents($metaFilename, + str_replace(array(",", "{", "}"), array(",\n ", "{\n ", "\n}\n"), + G::json_encode($metadata)))) { + CLI::logging("Could not create backup metadata"); + } + CLI::logging("Adding database to backup...\n"); + $this->addToBackup($tempDirectory); + CLI::logging("Adding files to backup...\n"); + $this->addToBackup($workspace->path); + $this->tempDirectories[] = $tempDirectory; + } + + /* Add a directory containing Db files or info files to be commpressed + * @directory the name and path of the directory to be add to the commpression process. + */ + private function addToBackup($directory) + { + if(!empty($directory)){ + $this->dir_to_compress .= $directory . " "; + } + } + + /* Commpress the DB and files into a single or several files with numerical series extentions + */ + public function letsBackup() + { + // creating command + $CommpressCommand = "tar czv "; + $CommpressCommand .= $this->dir_to_compress; + $CommpressCommand .= "| split -b "; + $CommpressCommand .= $this->fileSize; + $CommpressCommand .= "m -d - "; + $CommpressCommand .= $this->filename . "."; + //executing command to create the files + echo exec($CommpressCommand); + //Remove leftovers dirs. + foreach($this->tempDirectories as $tempDirectory) + { + CLI::logging("Deleting: ".$tempDirectory."\n"); + G::rm_dir($tempDirectory); + } + } + /* 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. + * @ srcWorkspace contains the workspace to be restored. + * @ dstWorkspace contains the workspace to be overwriting. + * @ overwrite got the option true if the workspace will be overwrite. + */ + static public function letsRestore($filename, $srcWorkspace, $dstWorkspace = NULL, $overwrite = true) + { + // Needed info: + // TEMPDIR /shared/workflow_data/upgrade/ + // BACKUPS /shared/workflow_data/backups/ + + // Creating command cat myfiles_split.tgz_* | tar xz + $DecommpressCommand = "cat " . $filename . ".* "; + $DecommpressCommand .= " | tar xzv"; + + $tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, '')); + $parentDirectory = PATH_DATA . "upgrade"; + if (is_writable($parentDirectory)) { + mkdir($tempDirectory); + } else { + throw new Exception("Could not create directory:" . $parentDirectory); + } + //Extract all backup files, including database scripts and workspace files + CLI::logging("Restoring into ".$tempDirectory."\n"); + chdir($tempDirectory); + echo exec($DecommpressCommand); + CLI::logging("\nUncompressed into: ".$tempDirectory."\n"); + + //Search for metafiles in the new standard (the old standard would contain meta files. + $metaFiles = glob($tempDirectory . "/*.meta"); + if (empty($metaFiles)) { + $metaFiles = glob($tempDirectory . "/*.txt"); + if (!empty($metaFiles)){ + return workspaceTools::restoreLegacy($tempDirectory); + } + else{ + throw new Exception("No metadata found in backup"); + } + } + else { + CLI::logging("Found " . count($metaFiles) . " workspaces in backup:\n"); + foreach ($metaFiles as $metafile){ + CLI::logging("-> " . basename($metafile) . "\n"); + } + } + if (count($metaFiles) > 1 && (!isset($srcWorkspace))){ + throw new Exception("Multiple workspaces in backup but no workspace specified to restore"); + } + if (isset($srcWorkspace) && !in_array("$srcWorkspace.meta", array_map(basename, $metaFiles))){ + throw new Exception("Workspace $srcWorkspace not found in backup"); + } + foreach ($metaFiles as $metaFile) { + $metadata = G::json_decode(file_get_contents($metaFile)); + if ($metadata->version != 1){ + throw new Exception("Backup version {$metadata->version} not supported"); + } + $backupWorkspace = $metadata->WORKSPACE_NAME; + if (isset($dstWorkspace)) { + $workspaceName = $dstWorkspace; + $createWorkspace = true; + } + else { + $workspaceName = $metadata->WORKSPACE_NAME; + $createWorkspace = false; + } + if (isset($srcWorkspace) && strcmp($metadata->WORKSPACE_NAME, $srcWorkspace) != 0) { + CLI::logging(CLI::warning("> Workspace $backupWorkspace found, but not restoring.") . "\n"); + continue; + } + else { + CLI::logging("> Restoring " . CLI::info($backupWorkspace) . " to " . CLI::info($workspaceName) . "\n"); + } + $workspace = new workspaceTools($workspaceName); + if ($workspace->workspaceExists()){ + if ($overwrite){ + CLI::logging(CLI::warning("> Workspace $workspaceName already exist, overwriting!") . "\n"); + } + else{ + throw new Exception("Destination workspace already exist (use -o to overwrite)"); + } + } + if (file_exists($workspace->path)) { + G::rm_dir($workspace->path); + } + foreach ($metadata->directories as $dir) { + CLI::logging("+> Restoring directory '$dir'\n"); + if (!rename("$tempDirectory/$dir", $workspace->path)) { + throw new Exception("There was an error copying the backup files ($tempDirectory/$dir) to the workspace directory {$workspace->path}."); + } + } + + CLI::logging("> Changing file permissions\n"); + $shared_stat = stat(PATH_DATA); + if ($shared_stat !== false){ + workspaceTools::dirPerms($workspace->path, $shared_stat['uid'], $shared_stat['gid'], $shared_stat['mode']); + } + else{ + CLI::logging(CLI::error ("Could not get the shared folder permissions, not changing workspace permissions") . "\n"); + } + + list($dbHost, $dbUser, $dbPass) = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); + + CLI::logging("> Connecting to system database in '$dbHost'\n"); + $link = mysql_connect($dbHost, $dbUser, $dbPass); + @mysql_query("SET NAMES 'utf8';"); + if (!$link){ + throw new Exception('Could not connect to system database: ' . mysql_error()); + } + + $newDBNames = $workspace->resetDBInfo($dbHost, $createWorkspace); + + foreach ($metadata->databases as $db) { + $dbName = $newDBNames[$db->name]; + CLI::logging("+> Restoring database {$db->name} to $dbName\n"); + $workspace->executeSQLScript($dbName, "$tempDirectory/{$db->name}.sql"); + $workspace->createDBUser($dbName, $db->pass, "localhost", $dbName); + $workspace->createDBUser($dbName, $db->pass, "%", $dbName); + } + $workspace->upgradeCacheView(false); + mysql_close($link); + + } + CLI::logging("Removing temporary files\n"); + G::rm_dir($tempDirectory); + CLI::logging(CLI::info("Done restoring") . "\n"); + } +} ?> From 1c7b1d658da5b44de3bc48a75f0406b4968b506f Mon Sep 17 00:00:00 2001 From: Ralph Asendeteufrer Date: Fri, 12 Oct 2012 11:55:22 -0400 Subject: [PATCH 2/5] BUG 9881 PM 2.0.44 testing 3. Al enviar una combinacion invalidad de parametros a PMFNewCase() se vence la sesion del usuario. PROBLEM The session vars were replaced with invalid values. SOLUTION Restore the session vars with healty values. --- workflow/engine/classes/class.wsBase.php | 173 +++++++++++++---------- 1 file changed, 99 insertions(+), 74 deletions(-) diff --git a/workflow/engine/classes/class.wsBase.php b/workflow/engine/classes/class.wsBase.php index 224b23155..3a3783bfe 100755 --- a/workflow/engine/classes/class.wsBase.php +++ b/workflow/engine/classes/class.wsBase.php @@ -76,7 +76,7 @@ class wsBase { public $stored_system_variables; //boolean public $wsSessionId; //web service session id, if the wsbase function is used from a WS request - + private $originalValues = array (); // session temporary array store. public function __construct ($params = null) { @@ -1599,6 +1599,94 @@ class wsBase return $result; } } + + /** + * save the $_SESSION variables into $originalValues array, to unset them temporary. + * + */ + private function saveTemporarySessionVars() + { + //Unset any variable, because we are starting a new case + if (isset( $_SESSION['APPLICATION'] )) { + $this->originalValues['APPLICATION'] = $_SESSION['APPLICATION']; + unset( $_SESSION['APPLICATION'] ); + } + + if (isset( $_SESSION['PROCESS'] )) { + $this->originalValues['PROCESS'] = $_SESSION['PROCESS']; + unset( $_SESSION['PROCESS'] ); + } + + if (isset( $_SESSION['TASK'] )) { + $this->originalValues['TASK'] = $_SESSION['TASK']; + unset( $_SESSION['TASK'] ); + } + + if (isset( $_SESSION['INDEX'] )) { + $this->originalValues['INDEX'] = $_SESSION['INDEX']; + unset( $_SESSION['INDEX'] ); + } + + if (isset( $_SESSION['USER_LOGGED'] )) { + $this->originalValues['USER_LOGGED'] = $_SESSION['USER_LOGGED']; + unset( $_SESSION['USER_LOGGED'] ); + } + + if (isset( $_SESSION['USR_USERNAME'] )) { + $this->originalValues['USR_USERNAME'] = $_SESSION['USR_USERNAME']; + unset( $_SESSION['USR_USERNAME'] ); + } + + if (isset( $_SESSION['STEP_POSITION'] )) { + $this->originalValues['STEP_POSITION'] = $_SESSION['STEP_POSITION']; + unset( $_SESSION['STEP_POSITION'] ); + } + } + + /** + * restore the Session variables with values of $originalValues array, if this is set. + * + */ + private function restoreSessionVars() + { + //Restore original values + if (isset( $this->originalValues['APPLICATION'] )) { + $_SESSION['APPLICATION'] = $this->originalValues['APPLICATION']; + unset( $this->originalValues['APPLICATION']); + } + + if (isset( $this->originalValues['PROCESS'] )) { + $_SESSION['PROCESS'] = $this->originalValues['PROCESS']; + unset( $this->originalValues['PROCESS']); + } + + if (isset( $this->originalValues['TASK'] )) { + $_SESSION['TASK'] = $this->originalValues['TASK']; + unset( $this->originalValues['TASK']); + } + + if (isset( $this->originalValues['INDEX'] )) { + $_SESSION['INDEX'] = $this->originalValues['INDEX']; + unset( $this->originalValues['INDEX']); + } + + if (isset( $this->originalValues['USR_USERNAME'] )) { + $_SESSION['USR_USERNAME'] = $this->originalValues['USR_USERNAME']; + unset( $this->originalValues['USR_USERNAME']); + } + + if (isset( $this->originalValues['USER_LOGGED'] )) { + G::pr("restore:".$this->originalValues['USER_LOGGED']." se:".$_SESSION['USER_LOGGED']); + $_SESSION['USER_LOGGED'] = $this->originalValues['USER_LOGGED']; + unset( $this->originalValues['USER_LOGGED']); + G::pr("restore:".$this->originalValues['USER_LOGGED']." se:".$_SESSION['USER_LOGGED']); + } + + if (isset( $this->originalValues['STEP_POSITION'] )) { + $_SESSION['STEP_POSITION'] = $this->originalValues['STEP_POSITION']; + unset( $this->originalValues['STEP_POSITION']); + } + } /** * new Case begins a new case under the name of the logged-in user. @@ -1612,59 +1700,23 @@ class wsBase public function newCase ($processId, $userId, $taskId, $variables) { try { - $originalValues = array (); - - //Unset any variable, because we are starting a new case - if (isset( $_SESSION['APPLICATION'] )) { - $originalValues['APPLICATION'] = $_SESSION['APPLICATION']; - unset( $_SESSION['APPLICATION'] ); - } - - if (isset( $_SESSION['PROCESS'] )) { - $originalValues['PROCESS'] = $_SESSION['PROCESS']; - unset( $_SESSION['PROCESS'] ); - } - - if (isset( $_SESSION['TASK'] )) { - $originalValues['TASK'] = $_SESSION['TASK']; - unset( $_SESSION['TASK'] ); - } - - if (isset( $_SESSION['INDEX'] )) { - $originalValues['INDEX'] = $_SESSION['INDEX']; - unset( $_SESSION['INDEX'] ); - } - - if (isset( $_SESSION['USER_LOGGED'] )) { - $originalValues['USER_LOGGED'] = $_SESSION['USER_LOGGED']; - unset( $_SESSION['USER_LOGGED'] ); - } - - if (isset( $_SESSION['USR_USERNAME'] )) { - $originalValues['USR_USERNAME'] = $_SESSION['USR_USERNAME']; - unset( $_SESSION['USR_USERNAME'] ); - } - - if (isset( $_SESSION['STEP_POSITION'] )) { - $originalValues['STEP_POSITION'] = $_SESSION['STEP_POSITION']; - unset( $_SESSION['STEP_POSITION'] ); - } - + + $this->saveTemporarySessionVars(); + $Fields = array (); if (is_array( $variables ) && count( $variables ) > 0) { $Fields = $variables; } - $oProcesses = new Processes(); $pro = $oProcesses->processExists( $processId ); if (! $pro) { $result = new wsResponse( 11, G::loadTranslation( 'ID_INVALID_PROCESS' ) . " " . $processId ); - + G::pr("invalid process"); + $this->restoreSessionVars(); return $result; } - $oCase = new Cases(); $oTask = new Tasks(); $startingTasks = $oCase->getStartCases( $userId ); @@ -1692,17 +1744,16 @@ class wsBase if ($tasksInThisProcess > 1) { $result = new wsResponse( 13, G::loadTranslation( 'ID_MULTIPLE_STARTING_TASKS' ) ); - + $this->restoreSessionVars(); return $result; } } if ($founded == '') { $result = new wsResponse( 14, G::loadTranslation( 'ID_TASK_INVALID_USER_NOT_ASSIGNED_TASK' ) ); - + $this->restoreSessionVars(); return $result; } - $case = $oCase->startCase( $taskId, $userId ); $_SESSION['APPLICATION'] = $case['APPLICATION']; @@ -1715,37 +1766,11 @@ class wsBase $caseId = $case['APPLICATION']; $caseNr = $case['CASE_NUMBER']; - $oldFields = $oCase->loadCase( $caseId ); - $oldFields['APP_DATA'] = array_merge( $oldFields['APP_DATA'], $Fields ); - $up_case = $oCase->updateCase( $caseId, $oldFields ); - - //Restore original values - if (isset( $originalValues['APPLICATION'] )) { - $_SESSION['APPLICATION'] = $originalValues['APPLICATION']; - } - - if (isset( $originalValues['PROCESS'] )) { - $_SESSION['PROCESS'] = $originalValues['PROCESS']; - } - - if (isset( $originalValues['TASK'] )) { - $_SESSION['TASK'] = $originalValues['TASK']; - } - - if (isset( $originalValues['INDEX'] )) { - $_SESSION['INDEX'] = $originalValues['INDEX']; - } - - if (isset( $originalValues['USR_USERNAME'] )) { - $_SESSION['USR_USERNAME'] = $originalValues['USR_USERNAME']; - } - - if (isset( $originalValues['STEP_POSITION'] )) { - $_SESSION['STEP_POSITION'] = $originalValues['STEP_POSITION']; - } + + $this->restoreSessionVars(); $result = new wsResponse( 0, G::loadTranslation( 'ID_STARTED_SUCCESSFULLY' ) ); $result->caseId = $caseId; @@ -1754,7 +1779,7 @@ class wsBase return $result; } catch (Exception $e) { $result = new wsResponse( 100, $e->getMessage() ); - + $this->restoreSessionVars(); return $result; } } From b4e3c54302917166b51ab19f7813bc74a49d6c0f Mon Sep 17 00:00:00 2001 From: Ralph Asendeteufrer Date: Fri, 12 Oct 2012 12:52:50 -0400 Subject: [PATCH 3/5] RESTORING to set a fresh Pull request. --- workflow/engine/classes/class.wsBase.php | 209 +++++++++++------------ 1 file changed, 100 insertions(+), 109 deletions(-) diff --git a/workflow/engine/classes/class.wsBase.php b/workflow/engine/classes/class.wsBase.php index 3a3783bfe..d88c44935 100755 --- a/workflow/engine/classes/class.wsBase.php +++ b/workflow/engine/classes/class.wsBase.php @@ -76,7 +76,7 @@ class wsBase { public $stored_system_variables; //boolean public $wsSessionId; //web service session id, if the wsbase function is used from a WS request - private $originalValues = array (); // session temporary array store. + public function __construct ($params = null) { @@ -323,6 +323,7 @@ class wsBase $oCriteria->addSelectColumn( ApplicationPeer::APP_NUMBER ); $oCriteria->addSelectColumn( ApplicationPeer::APP_STATUS ); $oCriteria->addSelectColumn( AppDelegationPeer::DEL_INDEX ); + $oCriteria->addSelectColumn( ApplicationPeer::PRO_UID ); $oCriteria->addAsColumn( 'CASE_TITLE', 'C1.CON_VALUE' ); $oCriteria->addAlias( "C1", 'CONTENT' ); $caseTitleConds = array (); @@ -354,15 +355,21 @@ class wsBase 'delIndex' => $aRow['DEL_INDEX'] ); */ - $result[] = array ('guid' => $aRow['APP_UID'],'name' => $aRow['APP_NUMBER'],'status' => $aRow['APP_STATUS'],'delIndex' => $aRow['DEL_INDEX'] - ); + $result[] = array('guid' => $aRow['APP_UID'], + 'name' => $aRow['APP_NUMBER'], + 'status' => $aRow['APP_STATUS'], + 'delIndex' => $aRow['DEL_INDEX'], + 'processId' => $aRow['PRO_UID']); $oDataset->next(); } return $result; } catch (Exception $e) { - $result[] = array ('guid' => $e->getMessage(),'name' => $e->getMessage(),'status' => $e->getMessage(),'status' => $e->getMessage() - ); + $result[] = array ('guid' => $e->getMessage(), + 'name' => $e->getMessage(), + 'status' => $e->getMessage(), + 'status' => $e->getMessage(), + 'processId' => $e->getMessage()); return $result; } @@ -385,16 +392,21 @@ class wsBase $oDataset->next(); while ($aRow = $oDataset->getRow()) { - $result[] = array ('guid' => $aRow['APP_UID'],'name' => $aRow['APP_NUMBER'],'delIndex' => $aRow['DEL_INDEX'] - ); + $result[] = array ('guid' => $aRow['APP_UID'], + 'name' => $aRow['APP_NUMBER'], + 'delIndex' => $aRow['DEL_INDEX'], + 'processId' => $aRow['PRO_UID']); $oDataset->next(); } return $result; } catch (Exception $e) { - $result[] = array ('guid' => $e->getMessage(),'name' => $e->getMessage(),'status' => $e->getMessage(),'status' => $e->getMessage() - ); + $result[] = array ('guid' => $e->getMessage(), + 'name' => $e->getMessage(), + 'status' => $e->getMessage(), + 'status' => $e->getMessage(), + 'processId' => $e->getMessage()); return $result; } @@ -665,7 +677,9 @@ class wsBase $result = array (); $oCriteria = new Criteria( 'workflow' ); $del = DBAdapter::getStringDelimiter(); + $oCriteria->addSelectColumn( TaskPeer::PRO_UID ); $oCriteria->addSelectColumn( TaskPeer::TAS_UID ); + $oCriteria->addSelectColumn( TaskPeer::TAS_START ); $oCriteria->setDistinct(); $oCriteria->addAsColumn( 'TAS_TITLE', 'C1.CON_VALUE' ); $oCriteria->addAlias( "C1", 'CONTENT' ); @@ -687,8 +701,10 @@ class wsBase $oDataset->next(); while ($aRow = $oDataset->getRow()) { - $result[] = array ('guid' => $aRow['TAS_UID'],'name' => $aRow['TAS_TITLE'] - ); + $result[] = array ('guid' => $aRow['TAS_UID'], + 'name' => $aRow['TAS_TITLE'], + 'processId' => $aRow['PRO_UID'], + 'initialTask' => $aRow['TAS_START'] == 'TRUE' ? '1' : '0'); $oDataset->next(); } @@ -1599,94 +1615,6 @@ class wsBase return $result; } } - - /** - * save the $_SESSION variables into $originalValues array, to unset them temporary. - * - */ - private function saveTemporarySessionVars() - { - //Unset any variable, because we are starting a new case - if (isset( $_SESSION['APPLICATION'] )) { - $this->originalValues['APPLICATION'] = $_SESSION['APPLICATION']; - unset( $_SESSION['APPLICATION'] ); - } - - if (isset( $_SESSION['PROCESS'] )) { - $this->originalValues['PROCESS'] = $_SESSION['PROCESS']; - unset( $_SESSION['PROCESS'] ); - } - - if (isset( $_SESSION['TASK'] )) { - $this->originalValues['TASK'] = $_SESSION['TASK']; - unset( $_SESSION['TASK'] ); - } - - if (isset( $_SESSION['INDEX'] )) { - $this->originalValues['INDEX'] = $_SESSION['INDEX']; - unset( $_SESSION['INDEX'] ); - } - - if (isset( $_SESSION['USER_LOGGED'] )) { - $this->originalValues['USER_LOGGED'] = $_SESSION['USER_LOGGED']; - unset( $_SESSION['USER_LOGGED'] ); - } - - if (isset( $_SESSION['USR_USERNAME'] )) { - $this->originalValues['USR_USERNAME'] = $_SESSION['USR_USERNAME']; - unset( $_SESSION['USR_USERNAME'] ); - } - - if (isset( $_SESSION['STEP_POSITION'] )) { - $this->originalValues['STEP_POSITION'] = $_SESSION['STEP_POSITION']; - unset( $_SESSION['STEP_POSITION'] ); - } - } - - /** - * restore the Session variables with values of $originalValues array, if this is set. - * - */ - private function restoreSessionVars() - { - //Restore original values - if (isset( $this->originalValues['APPLICATION'] )) { - $_SESSION['APPLICATION'] = $this->originalValues['APPLICATION']; - unset( $this->originalValues['APPLICATION']); - } - - if (isset( $this->originalValues['PROCESS'] )) { - $_SESSION['PROCESS'] = $this->originalValues['PROCESS']; - unset( $this->originalValues['PROCESS']); - } - - if (isset( $this->originalValues['TASK'] )) { - $_SESSION['TASK'] = $this->originalValues['TASK']; - unset( $this->originalValues['TASK']); - } - - if (isset( $this->originalValues['INDEX'] )) { - $_SESSION['INDEX'] = $this->originalValues['INDEX']; - unset( $this->originalValues['INDEX']); - } - - if (isset( $this->originalValues['USR_USERNAME'] )) { - $_SESSION['USR_USERNAME'] = $this->originalValues['USR_USERNAME']; - unset( $this->originalValues['USR_USERNAME']); - } - - if (isset( $this->originalValues['USER_LOGGED'] )) { - G::pr("restore:".$this->originalValues['USER_LOGGED']." se:".$_SESSION['USER_LOGGED']); - $_SESSION['USER_LOGGED'] = $this->originalValues['USER_LOGGED']; - unset( $this->originalValues['USER_LOGGED']); - G::pr("restore:".$this->originalValues['USER_LOGGED']." se:".$_SESSION['USER_LOGGED']); - } - - if (isset( $this->originalValues['STEP_POSITION'] )) { - $_SESSION['STEP_POSITION'] = $this->originalValues['STEP_POSITION']; - unset( $this->originalValues['STEP_POSITION']); - } - } /** * new Case begins a new case under the name of the logged-in user. @@ -1700,23 +1628,59 @@ class wsBase public function newCase ($processId, $userId, $taskId, $variables) { try { - - $this->saveTemporarySessionVars(); - + $originalValues = array (); + + //Unset any variable, because we are starting a new case + if (isset( $_SESSION['APPLICATION'] )) { + $originalValues['APPLICATION'] = $_SESSION['APPLICATION']; + unset( $_SESSION['APPLICATION'] ); + } + + if (isset( $_SESSION['PROCESS'] )) { + $originalValues['PROCESS'] = $_SESSION['PROCESS']; + unset( $_SESSION['PROCESS'] ); + } + + if (isset( $_SESSION['TASK'] )) { + $originalValues['TASK'] = $_SESSION['TASK']; + unset( $_SESSION['TASK'] ); + } + + if (isset( $_SESSION['INDEX'] )) { + $originalValues['INDEX'] = $_SESSION['INDEX']; + unset( $_SESSION['INDEX'] ); + } + + if (isset( $_SESSION['USER_LOGGED'] )) { + $originalValues['USER_LOGGED'] = $_SESSION['USER_LOGGED']; + unset( $_SESSION['USER_LOGGED'] ); + } + + if (isset( $_SESSION['USR_USERNAME'] )) { + $originalValues['USR_USERNAME'] = $_SESSION['USR_USERNAME']; + unset( $_SESSION['USR_USERNAME'] ); + } + + if (isset( $_SESSION['STEP_POSITION'] )) { + $originalValues['STEP_POSITION'] = $_SESSION['STEP_POSITION']; + unset( $_SESSION['STEP_POSITION'] ); + } + $Fields = array (); if (is_array( $variables ) && count( $variables ) > 0) { $Fields = $variables; } + $oProcesses = new Processes(); $pro = $oProcesses->processExists( $processId ); if (! $pro) { $result = new wsResponse( 11, G::loadTranslation( 'ID_INVALID_PROCESS' ) . " " . $processId ); - G::pr("invalid process"); - $this->restoreSessionVars(); + return $result; } + $oCase = new Cases(); $oTask = new Tasks(); $startingTasks = $oCase->getStartCases( $userId ); @@ -1744,16 +1708,17 @@ class wsBase if ($tasksInThisProcess > 1) { $result = new wsResponse( 13, G::loadTranslation( 'ID_MULTIPLE_STARTING_TASKS' ) ); - $this->restoreSessionVars(); + return $result; } } if ($founded == '') { $result = new wsResponse( 14, G::loadTranslation( 'ID_TASK_INVALID_USER_NOT_ASSIGNED_TASK' ) ); - $this->restoreSessionVars(); + return $result; } + $case = $oCase->startCase( $taskId, $userId ); $_SESSION['APPLICATION'] = $case['APPLICATION']; @@ -1766,11 +1731,37 @@ class wsBase $caseId = $case['APPLICATION']; $caseNr = $case['CASE_NUMBER']; + $oldFields = $oCase->loadCase( $caseId ); + $oldFields['APP_DATA'] = array_merge( $oldFields['APP_DATA'], $Fields ); + $up_case = $oCase->updateCase( $caseId, $oldFields ); - - $this->restoreSessionVars(); + + //Restore original values + if (isset( $originalValues['APPLICATION'] )) { + $_SESSION['APPLICATION'] = $originalValues['APPLICATION']; + } + + if (isset( $originalValues['PROCESS'] )) { + $_SESSION['PROCESS'] = $originalValues['PROCESS']; + } + + if (isset( $originalValues['TASK'] )) { + $_SESSION['TASK'] = $originalValues['TASK']; + } + + if (isset( $originalValues['INDEX'] )) { + $_SESSION['INDEX'] = $originalValues['INDEX']; + } + + if (isset( $originalValues['USR_USERNAME'] )) { + $_SESSION['USR_USERNAME'] = $originalValues['USR_USERNAME']; + } + + if (isset( $originalValues['STEP_POSITION'] )) { + $_SESSION['STEP_POSITION'] = $originalValues['STEP_POSITION']; + } $result = new wsResponse( 0, G::loadTranslation( 'ID_STARTED_SUCCESSFULLY' ) ); $result->caseId = $caseId; @@ -1779,7 +1770,7 @@ class wsBase return $result; } catch (Exception $e) { $result = new wsResponse( 100, $e->getMessage() ); - $this->restoreSessionVars(); + return $result; } } From 3455186be6ee054c92ba8dba55479582e7accb9d Mon Sep 17 00:00:00 2001 From: Ralph Asendeteufrer Date: Fri, 12 Oct 2012 14:44:13 -0400 Subject: [PATCH 4/5] BUG 9881 PM 2.0.44 testing 3. Al enviar una combinacion invalidad de parametros a PMFNewCase() se vence la sesion del usuario. PROBLEM The session vars were replaced with invalid values. SOLUTION Restore the session vars with healty values. --- workflow/engine/classes/class.wsBase.php | 164 +++++++++++++---------- 1 file changed, 96 insertions(+), 68 deletions(-) diff --git a/workflow/engine/classes/class.wsBase.php b/workflow/engine/classes/class.wsBase.php index d88c44935..535e27a13 100755 --- a/workflow/engine/classes/class.wsBase.php +++ b/workflow/engine/classes/class.wsBase.php @@ -76,7 +76,7 @@ class wsBase { public $stored_system_variables; //boolean public $wsSessionId; //web service session id, if the wsbase function is used from a WS request - + private $originalValues = array (); // SESSION temporary array store. public function __construct ($params = null) { @@ -1616,6 +1616,92 @@ class wsBase } } + /** + * save the $_SESSION variables into $originalValues array, to unset them temporary. + * + */ + private function saveTemporarySessionVars() + { + //Unset any variable, because we are starting a new case + if (isset( $_SESSION['APPLICATION'] )) { + $this->originalValues['APPLICATION'] = $_SESSION['APPLICATION']; + unset( $_SESSION['APPLICATION'] ); + } + + if (isset( $_SESSION['PROCESS'] )) { + $this->originalValues['PROCESS'] = $_SESSION['PROCESS']; + unset( $_SESSION['PROCESS'] ); + } + + if (isset( $_SESSION['TASK'] )) { + $this->originalValues['TASK'] = $_SESSION['TASK']; + unset( $_SESSION['TASK'] ); + } + + if (isset( $_SESSION['INDEX'] )) { + $this->originalValues['INDEX'] = $_SESSION['INDEX']; + unset( $_SESSION['INDEX'] ); + } + + if (isset( $_SESSION['USER_LOGGED'] )) { + $this->originalValues['USER_LOGGED'] = $_SESSION['USER_LOGGED']; + unset( $_SESSION['USER_LOGGED'] ); + } + + if (isset( $_SESSION['USR_USERNAME'] )) { + $this->originalValues['USR_USERNAME'] = $_SESSION['USR_USERNAME']; + unset( $_SESSION['USR_USERNAME'] ); + } + + if (isset( $_SESSION['STEP_POSITION'] )) { + $this->originalValues['STEP_POSITION'] = $_SESSION['STEP_POSITION']; + unset( $_SESSION['STEP_POSITION'] ); + } + } + + /** + * restore the Session variables with values of $originalValues array, if this is set. + * + */ + private function restoreSessionVars() + { + //Restore original values + if (isset( $this->originalValues['APPLICATION'] )) { + $_SESSION['APPLICATION'] = $this->originalValues['APPLICATION']; + unset( $this->originalValues['APPLICATION']); + } + + if (isset( $this->originalValues['PROCESS'] )) { + $_SESSION['PROCESS'] = $this->originalValues['PROCESS']; + unset( $this->originalValues['PROCESS']); + } + + if (isset( $this->originalValues['TASK'] )) { + $_SESSION['TASK'] = $this->originalValues['TASK']; + unset( $this->originalValues['TASK']); + } + + if (isset( $this->originalValues['INDEX'] )) { + $_SESSION['INDEX'] = $this->originalValues['INDEX']; + unset( $this->originalValues['INDEX']); + } + + if (isset( $this->originalValues['USR_USERNAME'] )) { + $_SESSION['USR_USERNAME'] = $this->originalValues['USR_USERNAME']; + unset( $this->originalValues['USR_USERNAME']); + } + + if (isset( $this->originalValues['USER_LOGGED'] )) { + $_SESSION['USER_LOGGED'] = $this->originalValues['USER_LOGGED']; + unset( $this->originalValues['USER_LOGGED']); + } + + if (isset( $this->originalValues['STEP_POSITION'] )) { + $_SESSION['STEP_POSITION'] = $this->originalValues['STEP_POSITION']; + unset( $this->originalValues['STEP_POSITION']); + } + } + /** * new Case begins a new case under the name of the logged-in user. * @@ -1628,44 +1714,9 @@ class wsBase public function newCase ($processId, $userId, $taskId, $variables) { try { - $originalValues = array (); - - //Unset any variable, because we are starting a new case - if (isset( $_SESSION['APPLICATION'] )) { - $originalValues['APPLICATION'] = $_SESSION['APPLICATION']; - unset( $_SESSION['APPLICATION'] ); - } - - if (isset( $_SESSION['PROCESS'] )) { - $originalValues['PROCESS'] = $_SESSION['PROCESS']; - unset( $_SESSION['PROCESS'] ); - } - - if (isset( $_SESSION['TASK'] )) { - $originalValues['TASK'] = $_SESSION['TASK']; - unset( $_SESSION['TASK'] ); - } - - if (isset( $_SESSION['INDEX'] )) { - $originalValues['INDEX'] = $_SESSION['INDEX']; - unset( $_SESSION['INDEX'] ); - } - - if (isset( $_SESSION['USER_LOGGED'] )) { - $originalValues['USER_LOGGED'] = $_SESSION['USER_LOGGED']; - unset( $_SESSION['USER_LOGGED'] ); - } - - if (isset( $_SESSION['USR_USERNAME'] )) { - $originalValues['USR_USERNAME'] = $_SESSION['USR_USERNAME']; - unset( $_SESSION['USR_USERNAME'] ); - } - - if (isset( $_SESSION['STEP_POSITION'] )) { - $originalValues['STEP_POSITION'] = $_SESSION['STEP_POSITION']; - unset( $_SESSION['STEP_POSITION'] ); - } - + + $this->saveTemporarySessionVars(); + $Fields = array (); if (is_array( $variables ) && count( $variables ) > 0) { @@ -1677,7 +1728,7 @@ class wsBase if (! $pro) { $result = new wsResponse( 11, G::loadTranslation( 'ID_INVALID_PROCESS' ) . " " . $processId ); - + $this->restoreSessionVars(); return $result; } @@ -1708,14 +1759,14 @@ class wsBase if ($tasksInThisProcess > 1) { $result = new wsResponse( 13, G::loadTranslation( 'ID_MULTIPLE_STARTING_TASKS' ) ); - + $this->restoreSessionVars(); return $result; } } if ($founded == '') { $result = new wsResponse( 14, G::loadTranslation( 'ID_TASK_INVALID_USER_NOT_ASSIGNED_TASK' ) ); - + $this->restoreSessionVars(); return $result; } @@ -1738,31 +1789,8 @@ class wsBase $up_case = $oCase->updateCase( $caseId, $oldFields ); - //Restore original values - if (isset( $originalValues['APPLICATION'] )) { - $_SESSION['APPLICATION'] = $originalValues['APPLICATION']; - } - - if (isset( $originalValues['PROCESS'] )) { - $_SESSION['PROCESS'] = $originalValues['PROCESS']; - } - - if (isset( $originalValues['TASK'] )) { - $_SESSION['TASK'] = $originalValues['TASK']; - } - - if (isset( $originalValues['INDEX'] )) { - $_SESSION['INDEX'] = $originalValues['INDEX']; - } - - if (isset( $originalValues['USR_USERNAME'] )) { - $_SESSION['USR_USERNAME'] = $originalValues['USR_USERNAME']; - } - - if (isset( $originalValues['STEP_POSITION'] )) { - $_SESSION['STEP_POSITION'] = $originalValues['STEP_POSITION']; - } - + $this->restoreSessionVars(); + $result = new wsResponse( 0, G::loadTranslation( 'ID_STARTED_SUCCESSFULLY' ) ); $result->caseId = $caseId; $result->caseNumber = $caseNr; @@ -1770,7 +1798,7 @@ class wsBase return $result; } catch (Exception $e) { $result = new wsResponse( 100, $e->getMessage() ); - + $this->restoreSessionVars(); return $result; } } From 04de7b363f9dc00821f02a08b06691ebb314fb0e Mon Sep 17 00:00:00 2001 From: Ralph Asendeteufrer Date: Fri, 12 Oct 2012 14:57:51 -0400 Subject: [PATCH 5/5] BUG 9881 PM 2.0.44 testing 3. Al enviar una combinacion invalidad de parametros a PMFNewCase() se vence la sesion del usuario. PROBLEM The session vars were replaced with invalid values. SOLUTION Restore the session vars with healty values. --- workflow/engine/bin/tasks/cliWorkspaces.php | 36 +-- workflow/engine/classes/class.wsBase.php | 2 +- workflow/engine/classes/class.wsTools.php | 239 +------------------- 3 files changed, 15 insertions(+), 262 deletions(-) diff --git a/workflow/engine/bin/tasks/cliWorkspaces.php b/workflow/engine/bin/tasks/cliWorkspaces.php index 47e5f6c2b..a73f674e0 100755 --- a/workflow/engine/bin/tasks/cliWorkspaces.php +++ b/workflow/engine/bin/tasks/cliWorkspaces.php @@ -52,7 +52,6 @@ EOT ); CLI::taskArg('workspace', false); CLI::taskArg('backup-file', true); -CLI::taskOpt("filesize", "Set the max size of the compresed splitted files, by default the max is 1000 Mb.", "s:","filesize="); CLI::taskRun(run_workspace_backup); CLI::taskName('workspace-restore'); @@ -71,12 +70,11 @@ CLI::taskArg('backup-file', false); CLI::taskArg('workspace', true); CLI::taskOpt("overwrite", "If a workspace already exists, overwrite it.", "o", "overwrite"); CLI::taskOpt("info", "Only shows information about a backup archive.", "i"); -CLI::taskOpt("multiple", "Restore from multiple compresed enumerated files.", "m"); CLI::taskOpt("workspace", "Select which workspace to restore if multiple workspaces are present in the archive.", "w:", "workspace="); CLI::taskRun(run_workspace_restore); -CLI::taskName('cacheview-rep air'); +CLI::taskName('cacheview-repair'); CLI::taskDescription(<<workspaceExists()) throw new Exception("Workspace '{$workspace->name}' not found"); //If this is a relative path, put the file in the backups directory - if (strpos($filename, "/") === false && strpos($filename, '\\') === false){ + if (strpos($filename, "/") === false && strpos($filename, '\\') === false) $filename = PATH_DATA . "backups/$filename"; - } CLI::logging("Backing up to $filename\n"); + $backup = workspaceTools::createBackup($filename); - $filesize = array_key_exists("filesize", $opts) ? $opts['filesize'] : -1; - if($filesize >= 0) - { - $multipleBackup = new MultipleFilesBackup ($filename,$filesize);//if filesize is 0 the default size will be took - //using new method - foreach ($workspaces as $workspace){ - $multipleBackup->addToBackup($workspace); - } - $multipleBackup->letsBackup(); - } - else - { - //ansient method to backup into one large file - $backup = workspaceTools::createBackup($filename); + foreach ($workspaces as $workspace) + $workspace->backup($backup); - foreach ($workspaces as $workspace) - $workspace->backup($backup); - } CLI::logging("\n"); workspaceTools::printSysInfo(); foreach ($workspaces as $workspace) { @@ -422,15 +405,8 @@ function run_workspace_restore($args, $opts) { CLI::logging("Restoring from $filename\n"); $workspace = array_key_exists("workspace", $opts) ? $opts['workspace'] : NULL; $overwrite = array_key_exists("overwrite", $opts); - $multiple = array_key_exists("multiple", $opts); $dstWorkspace = $args[1]; -//echo "filename: ".$filename." workspace:".$workspace." dts:".$dstWorkspace." over:".$overwrite." multiple:".$multiple."\n"; - if(!empty($multiple)){ - MultipleFilesBackup::letsRestore ($filename,$workspace,$dstWorkspace,$overwrite); - } - else{ - workspaceTools::restore($filename, $workspace, $dstWorkspace, $overwrite); - } + workspaceTools::restore($filename, $workspace, $dstWorkspace, $overwrite); } } diff --git a/workflow/engine/classes/class.wsBase.php b/workflow/engine/classes/class.wsBase.php index 535e27a13..009550d86 100755 --- a/workflow/engine/classes/class.wsBase.php +++ b/workflow/engine/classes/class.wsBase.php @@ -76,7 +76,7 @@ class wsBase { public $stored_system_variables; //boolean public $wsSessionId; //web service session id, if the wsbase function is used from a WS request - private $originalValues = array (); // SESSION temporary array store. + private $originalValues = array (); // SESSION temporary array store. public function __construct ($params = null) { diff --git a/workflow/engine/classes/class.wsTools.php b/workflow/engine/classes/class.wsTools.php index 5ec820ff0..fb41599ee 100755 --- a/workflow/engine/classes/class.wsTools.php +++ b/workflow/engine/classes/class.wsTools.php @@ -54,7 +54,7 @@ class workspaceTools { * * @param bool $first true if this is the first workspace to be upgrade */ - public function upgrade($first=false, $buildCacheView=false, $workSpace=SYS_SYS) + public function upgrade($first=false, $buildCacheView=false, $workSpace=SYS_SYS) { $start = microtime(true); CLI::logging("> Updating database...\n"); @@ -292,15 +292,12 @@ class workspaceTools { */ public function upgradeContent($workSpace=SYS_SYS) { $this->initPropel(true); - require_once('classes/model/Language.php'); - G::LoadThirdParty('pear/json', 'class.json'); - $lang = array(); - foreach (System::listPoFiles() as $poFile) { - $poName = basename($poFile); - $names = explode(".", basename($poFile)); - $extension = array_pop($names); - $langid = array_pop($names); - $arrayLang[] = $langid; + require_once 'classes/model/Translation.php'; + $translation = new Translation(); + $information = $translation->getTranslationEnvironments(); + $arrayLang = array(); + foreach ($information as $key => $value) { + $arrayLang[] = trim($value['LOCALE']); } require_once('classes/model/Content.php'); $regenerateContent = new Content(); @@ -871,6 +868,7 @@ class workspaceTools { //Remove leftovers. G::rm_dir($tempDirectory); } + //TODO: Move to class.dbMaintenance.php /** * create a user in the database @@ -1116,225 +1114,4 @@ class workspaceTools { } } - - -/** Class MultipleFilesBackup -* create a backup of this workspace -* -* Exports the database and copies the files to an tar archive o several if the max filesize is reached. -* -*/ -class MultipleFilesBackup{ - - private $dir_to_compress = ""; - private $filename = "backUpProcessMaker.tar"; - private $fileSize = "1000"; // 1 GB by default. - private $sizeDescriptor = "m"; //megabytes - private $tempDirectories=array(); - - /* Constructor - * @filename contains the path and filename of the comppress file(s). - * @size got the Max size of the compressed files, by default if the $size less to zero will mantains 1000 Mb as Max size. - */ - function MultipleFilesBackup($filename,$size) - { - if(!empty($filename)){ - $this->filename = $filename; - } - if(!empty($size) && (int)$size > 0){ - $this->fileSize = $size; - } - } - /* Gets workspace information enough to make its backup. - * @workspace contains the workspace to be add to the commpression process. - */ - public function addToBackup($workspace) - { - //verifing if workspace exists. - if (!$workspace->workspaceExists()) { - echo "Workspace {$workspace->name} not found\n"; - return false; - } - //create destination path - if (!file_exists(PATH_DATA . "upgrade/")){ - mkdir(PATH_DATA . "upgrade/"); - } - $tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, '')); - mkdir($tempDirectory); - $metadata = $workspace->getMetadata(); - CLI::logging("Temporing up database...\n"); - $metadata["databases"] = $workspace->exportDatabase($tempDirectory); - $metadata["directories"] = array("{$workspace->name}.files"); - $metadata["version"] = 1; - $metaFilename = "$tempDirectory/{$workspace->name}.meta"; - if (!file_put_contents($metaFilename, - str_replace(array(",", "{", "}"), array(",\n ", "{\n ", "\n}\n"), - G::json_encode($metadata)))) { - CLI::logging("Could not create backup metadata"); - } - CLI::logging("Adding database to backup...\n"); - $this->addToBackup($tempDirectory); - CLI::logging("Adding files to backup...\n"); - $this->addToBackup($workspace->path); - $this->tempDirectories[] = $tempDirectory; - } - - /* Add a directory containing Db files or info files to be commpressed - * @directory the name and path of the directory to be add to the commpression process. - */ - private function addToBackup($directory) - { - if(!empty($directory)){ - $this->dir_to_compress .= $directory . " "; - } - } - - /* Commpress the DB and files into a single or several files with numerical series extentions - */ - public function letsBackup() - { - // creating command - $CommpressCommand = "tar czv "; - $CommpressCommand .= $this->dir_to_compress; - $CommpressCommand .= "| split -b "; - $CommpressCommand .= $this->fileSize; - $CommpressCommand .= "m -d - "; - $CommpressCommand .= $this->filename . "."; - //executing command to create the files - echo exec($CommpressCommand); - //Remove leftovers dirs. - foreach($this->tempDirectories as $tempDirectory) - { - CLI::logging("Deleting: ".$tempDirectory."\n"); - G::rm_dir($tempDirectory); - } - } - /* 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. - * @ srcWorkspace contains the workspace to be restored. - * @ dstWorkspace contains the workspace to be overwriting. - * @ overwrite got the option true if the workspace will be overwrite. - */ - static public function letsRestore($filename, $srcWorkspace, $dstWorkspace = NULL, $overwrite = true) - { - // Needed info: - // TEMPDIR /shared/workflow_data/upgrade/ - // BACKUPS /shared/workflow_data/backups/ - - // Creating command cat myfiles_split.tgz_* | tar xz - $DecommpressCommand = "cat " . $filename . ".* "; - $DecommpressCommand .= " | tar xzv"; - - $tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, '')); - $parentDirectory = PATH_DATA . "upgrade"; - if (is_writable($parentDirectory)) { - mkdir($tempDirectory); - } else { - throw new Exception("Could not create directory:" . $parentDirectory); - } - //Extract all backup files, including database scripts and workspace files - CLI::logging("Restoring into ".$tempDirectory."\n"); - chdir($tempDirectory); - echo exec($DecommpressCommand); - CLI::logging("\nUncompressed into: ".$tempDirectory."\n"); - - //Search for metafiles in the new standard (the old standard would contain meta files. - $metaFiles = glob($tempDirectory . "/*.meta"); - if (empty($metaFiles)) { - $metaFiles = glob($tempDirectory . "/*.txt"); - if (!empty($metaFiles)){ - return workspaceTools::restoreLegacy($tempDirectory); - } - else{ - throw new Exception("No metadata found in backup"); - } - } - else { - CLI::logging("Found " . count($metaFiles) . " workspaces in backup:\n"); - foreach ($metaFiles as $metafile){ - CLI::logging("-> " . basename($metafile) . "\n"); - } - } - if (count($metaFiles) > 1 && (!isset($srcWorkspace))){ - throw new Exception("Multiple workspaces in backup but no workspace specified to restore"); - } - if (isset($srcWorkspace) && !in_array("$srcWorkspace.meta", array_map(basename, $metaFiles))){ - throw new Exception("Workspace $srcWorkspace not found in backup"); - } - foreach ($metaFiles as $metaFile) { - $metadata = G::json_decode(file_get_contents($metaFile)); - if ($metadata->version != 1){ - throw new Exception("Backup version {$metadata->version} not supported"); - } - $backupWorkspace = $metadata->WORKSPACE_NAME; - if (isset($dstWorkspace)) { - $workspaceName = $dstWorkspace; - $createWorkspace = true; - } - else { - $workspaceName = $metadata->WORKSPACE_NAME; - $createWorkspace = false; - } - if (isset($srcWorkspace) && strcmp($metadata->WORKSPACE_NAME, $srcWorkspace) != 0) { - CLI::logging(CLI::warning("> Workspace $backupWorkspace found, but not restoring.") . "\n"); - continue; - } - else { - CLI::logging("> Restoring " . CLI::info($backupWorkspace) . " to " . CLI::info($workspaceName) . "\n"); - } - $workspace = new workspaceTools($workspaceName); - if ($workspace->workspaceExists()){ - if ($overwrite){ - CLI::logging(CLI::warning("> Workspace $workspaceName already exist, overwriting!") . "\n"); - } - else{ - throw new Exception("Destination workspace already exist (use -o to overwrite)"); - } - } - if (file_exists($workspace->path)) { - G::rm_dir($workspace->path); - } - foreach ($metadata->directories as $dir) { - CLI::logging("+> Restoring directory '$dir'\n"); - if (!rename("$tempDirectory/$dir", $workspace->path)) { - throw new Exception("There was an error copying the backup files ($tempDirectory/$dir) to the workspace directory {$workspace->path}."); - } - } - - CLI::logging("> Changing file permissions\n"); - $shared_stat = stat(PATH_DATA); - if ($shared_stat !== false){ - workspaceTools::dirPerms($workspace->path, $shared_stat['uid'], $shared_stat['gid'], $shared_stat['mode']); - } - else{ - CLI::logging(CLI::error ("Could not get the shared folder permissions, not changing workspace permissions") . "\n"); - } - - list($dbHost, $dbUser, $dbPass) = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); - - CLI::logging("> Connecting to system database in '$dbHost'\n"); - $link = mysql_connect($dbHost, $dbUser, $dbPass); - @mysql_query("SET NAMES 'utf8';"); - if (!$link){ - throw new Exception('Could not connect to system database: ' . mysql_error()); - } - - $newDBNames = $workspace->resetDBInfo($dbHost, $createWorkspace); - - foreach ($metadata->databases as $db) { - $dbName = $newDBNames[$db->name]; - CLI::logging("+> Restoring database {$db->name} to $dbName\n"); - $workspace->executeSQLScript($dbName, "$tempDirectory/{$db->name}.sql"); - $workspace->createDBUser($dbName, $db->pass, "localhost", $dbName); - $workspace->createDBUser($dbName, $db->pass, "%", $dbName); - } - $workspace->upgradeCacheView(false); - mysql_close($link); - - } - CLI::logging("Removing temporary files\n"); - G::rm_dir($tempDirectory); - CLI::logging(CLI::info("Done restoring") . "\n"); - } -} ?>