diff --git a/gulliver/bin/tasks/pakeGulliver.php b/gulliver/bin/tasks/pakeGulliver.php index 0f3959a35..9fad7970e 100644 --- a/gulliver/bin/tasks/pakeGulliver.php +++ b/gulliver/bin/tasks/pakeGulliver.php @@ -1683,18 +1683,38 @@ function getSysInfo() { $ip = getenv('REMOTE_ADDR'); } - $redhat = ''; - if( file_exists('/etc/redhat-release') ) { - $fnewsize = filesize('/etc/redhat-release'); - $fp = fopen('/etc/redhat-release', 'r'); - $redhat = trim(fread($fp, $fnewsize)); - fclose($fp); + /* For distros with the lsb_release, this returns a one-line description of + * the distro name, such as "CentOS release 5.3 (Final)" or "Ubuntu 10.10" + */ + $distro = exec("lsb_release -d -s 2> /dev/null"); + + /* For distros without lsb_release, we look for *release (such as + * redhat-release, gentoo-release, SuSE-release, etc) or *version (such as + * debian_version, slackware-version, etc) + */ + if (empty($distro)) { + foreach (glob("/etc/*release") as $filename) { + $distro = trim(file_get_contents($filename)); + if (!empty($distro)) + break; + } + if (empty($distro)) { + foreach (glob("/etc/*version") as $filename) { + $distro = trim(file_get_contents($filename)); + if (!empty($distro)) + break; + } + } } - $redhat .= " (" . PHP_OS . ")"; + + /* CentOS returns a string with quotes, remove them! */ + $distro = trim($distro, "\""); + + $distro .= " (" . PHP_OS . ")"; $Fields = array(); - $Fields['SYSTEM'] = $redhat; + $Fields['SYSTEM'] = $distro; $Fields['PHP'] = phpversion(); $Fields['PM_VERSION'] = PM_VERSION; $Fields['SERVER_ADDR'] = lookup($ipe[2]); diff --git a/gulliver/thirdparty/propel/Propel.php b/gulliver/thirdparty/propel/Propel.php index 945872e86..501dca3fe 100644 --- a/gulliver/thirdparty/propel/Propel.php +++ b/gulliver/thirdparty/propel/Propel.php @@ -257,6 +257,12 @@ class Propel { self::initialize(); } + public static function initConfiguration($configuration) + { + self::$configuration = $configuration; + self::initialize(); + } + /** * Determine whether Propel has already been initialized. * diff --git a/processmaker b/processmaker index e008702d9..a08847449 100644 --- a/processmaker +++ b/processmaker @@ -7,6 +7,6 @@ define("WORKFLOW_PATH", $scriptDir . 'workflow/'); define("WORKFLOW_BIN_PATH", $scriptDir . 'workflow/engine/bin/'); - include ( WORKFLOW_BIN_PATH . '/commands.php'); + include ( WORKFLOW_BIN_PATH . '/cli.php'); ?> diff --git a/workflow/engine/bin/commands.php b/workflow/engine/bin/cli.php similarity index 82% rename from workflow/engine/bin/commands.php rename to workflow/engine/bin/cli.php index 451059bf7..7763f1d8d 100644 --- a/workflow/engine/bin/commands.php +++ b/workflow/engine/bin/cli.php @@ -23,6 +23,15 @@ * */ +register_shutdown_function('shutdownFunction'); +function shutDownFunction() { + $error = error_get_last(); + if ($error['type'] == 1) { + //print_r($error); + debug_print_backtrace(); + } +} + /* Windows supports both / and \ as path separators, so use the Unix separator * for maximum compatibility. */ @@ -43,9 +52,12 @@ require_once( PATH_THIRDPARTY . 'pake/pakeGetopt.class.php'); require_once( PATH_CORE . 'config/environments.php'); + /* Hide notice, otherwise we get a lot of messages */ + error_reporting(E_ALL ^ E_NOTICE); + // register tasks - $dir = PATH_HOME . 'engine/bin/commands'; - $tasks = pakeFinder::type('file')->name( 'cmd*.php' )->in($dir); + $dir = PATH_HOME . 'engine/bin/tasks'; + $tasks = pakeFinder::type('file')->name( 'cli*.php' )->in($dir); foreach ($tasks as $task) { include_once($task); diff --git a/workflow/engine/bin/commands/cliCommon.php b/workflow/engine/bin/commands/cliCommon.php new file mode 100644 index 000000000..e430b5088 --- /dev/null +++ b/workflow/engine/bin/commands/cliCommon.php @@ -0,0 +1,76 @@ + + * --long-param + * --long-param= + * --long-param + * + * + * @param array $noopt List of parameters without values + */ +function parse_args($args, $noopt = array()) { + $result = array(); + while (list($tmp, $p) = each($args)) { + if ($p{0} == '-') { + $pname = substr($p, 1); + $value = true; + if ($pname{0} == '-') { + // long-opt (--) + $pname = substr($pname, 1); + if (strpos($p, '=') !== false) { + // value specified inline (--=) + list($pname, $value) = explode('=', substr($p, 2), 2); + } + } + // check if next parameter is a descriptor or a value + $nextparm = current($args); + if (!in_array($pname, $noopt) && $value === true && $nextparm !== false && $nextparm{0} != '-') list($tmp, $value) = each($args); + $result[$pname] = $value; + } else { + // param doesn't belong to any option + $result[] = $p; + } + } + return $result; +} + +function info($message) { + return pakeColor::colorize($message, "INFO"); +} + +function error($message) { + return pakeColor::colorize($message, "ERROR"); +} + +function logging($message, $filename = NULL) { + static $log_file = NULL; + if (isset($filename)) { + $log_file = fopen($filename, "a"); + fwrite($log_file, " -- " . date("c") . " " . $message . " --\n"); + } else { + if (isset($log_file)) + fwrite($log_file, $message); + echo $message; + } +} + +function get_workspaces_from_args($args, $includeAll = true) { + $opts = parse_args($args); + $workspaces = array(); + foreach ($opts as $opt => $arg) { + if (is_int($opt)) { + $workspaces[] = new workspaceTools($arg); + } + } + if (empty($workspaces) && $includeAll) { + $workspaces = System::listWorkspaces(); + } + return $workspaces; +} + +?> diff --git a/workflow/engine/bin/commands/cliUpgrade.php b/workflow/engine/bin/commands/cliUpgrade.php new file mode 100644 index 000000000..533ad64d2 --- /dev/null +++ b/workflow/engine/bin/commands/cliUpgrade.php @@ -0,0 +1,48 @@ + $workspace) { + try { + logging("Upgrading workspaces ($index/$count): " . info($workspace->name) . "\n"); + $workspace->upgrade($first); + $workspace->close(); + $first = false; + } catch (Exception $e) { + logging("Errors upgrading workspace " . info($workspace->name) . ": " . error($e->getMessage()) . "\n"); + } + } + logging("Upgrade successful\n"); +} + +?> diff --git a/workflow/engine/bin/commands/cliWorkspaces.php b/workflow/engine/bin/commands/cliWorkspaces.php new file mode 100644 index 000000000..836744c64 --- /dev/null +++ b/workflow/engine/bin/commands/cliWorkspaces.php @@ -0,0 +1,199 @@ +printMetadata(false); + } +} + +function run_workspace_upgrade($command, $args) { + $workspaces = get_workspaces_from_args($args); + foreach ($workspaces as $workspace) { + try { + $workspace->upgrade(); + } catch (Exception $e) { + echo "Errors upgrading workspace " . info($workspace->name) . ": " . error($e->getMessage()) . "\n"; + } + } +} + +function run_translation_upgrade($command, $args) { + $workspaces = get_workspaces_from_args($args); + $updateXml = true; + foreach ($workspaces as $workspace) { + try { + echo "Upgrading translation for " . pakeColor::colorize($workspace->name, "INFO") . "\n"; + $workspace->upgradeTranslation($updateXml); + $updateXml = false; + } catch (Exception $e) { + echo "Errors upgrading translation of workspace " . info($workspace->name) . ": " . error($e->getMessage()) . "\n"; + } + } +} + +function run_cacheview_upgrade($command, $args) { + $workspaces = get_workspaces_from_args($args); + $updateXml = true; + foreach ($workspaces as $workspace) { + try { + echo "Upgrading cache view for " . pakeColor::colorize($workspace->name, "INFO") . "\n"; + $workspace->upgradeCacheView(); + } catch (Exception $e) { + echo "Errors upgrading translation of workspace " . info($workspace->name) . ": " . error($e->getMessage()) . "\n"; + } + } +} + +function run_database_export($command, $args) { + G::LoadSystem('dbMaintenance'); + if (count($args) < 2) + throw new Exception ("Please provide a workspace name and a directory for export"); + $workspace = new workspaceTools($args[0]); + $workspace->exportDatabase($args[1]); +} + +function run_database_import($command, $args) { + throw new Exception("Not implemented"); +} + +function run_database_upgrade($task, $args) { + database_upgrade("upgrade", $args); +} + +function run_database_check($task, $args) { + database_upgrade("check", $args); +} + +function database_upgrade($command, $args) { + $workspaces = get_workspaces_from_args($args); + $checkOnly = (strcmp($command, "check") == 0); + foreach ($workspaces as $workspace) { + if ($checkOnly) + print_r("Checking database in ".pakeColor::colorize($workspace->name, "INFO")." "); + else + print_r("Upgrading database in ".pakeColor::colorize($workspace->name, "INFO")." "); + try { + $changes = $workspace->repairSchema($checkOnly); + if ($changes != false) { + if ($checkOnly) { + echo "> ".pakeColor::colorize("Run upgrade", "INFO")."\n"; + echo " Tables (add = " . count($changes['tablesToAdd']); + echo ", alter = " . count($changes['tablesToAlter']) . ") "; + echo "- Indexes (add = " . count($changes['tablesWithNewIndex']).""; + echo ", alter = " . count($changes['tablesToAlterIndex']).")\n"; + } else { + echo "> Schema fixed\n"; + } + } else { + echo "> OK\n"; + } + } catch (Exception $e) { + echo "> Error: ".error($e->getMessage()) . "\n"; + } + } +} + +function delete_app_from_table($con, $tableName, $appUid, $col="APP_UID") { + $stmt = $con->createStatement(); + $sql = "DELETE FROM " . $tableName . " WHERE " . $col . "='" . $appUid . "'"; + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); +} + +function run_drafts_clean($task, $args) { + echo "Cleaning drafts\n"; + + if (count($args) < 1) + throw new Exception ("Please specify a workspace name"); + $workspace = $args[0]; + + if (!file_exists(PATH_DB . $workspace . '/db.php')) { + throw new Exception('Could not find workspace ' . $workspace); + } + + $allDrafts = false; + if (count($args) < 2) { + echo "Cases older them this much days will be deleted (ENTER for all): "; + $days = rtrim( fgets( STDIN ), "\n" ); + if ($days == "") { + $allDrafts = true; + } + } else { + $days = $args[1]; + if (strcmp($days, "all") == 0) { + $allDrafts = true; + } + } + + if (!$allDrafts && (!is_numeric($days) || intval($days) <= 0)) { + throw new Exception("Days value is not valid: " . $days); + } + + if ($allDrafts) + echo "Removing all drafts\n"; + else + echo "Removing drafts older than " . $days . " days\n"; + + /* Load the configuration from the workspace */ + require_once( PATH_DB . $workspace . '/db.php' ); + require_once( PATH_THIRDPARTY . 'propel/Propel.php'); + + PROPEL::Init ( PATH_METHODS.'dbConnections/rootDbConnections.php' ); + $con = Propel::getConnection("root"); + + $stmt = $con->createStatement(); + + if (!$allDrafts) + $dateSql = "AND DATE_SUB(CURDATE(),INTERVAL " . $days . " DAY) >= APP_CREATE_DATE"; + else + $dateSql = ""; + /* Search for all the draft cases */ + $sql = "SELECT APP_UID FROM APPLICATION WHERE APP_STATUS='DRAFT'" . $dateSql; + $appRows = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + + /* Tables to remove the cases from */ + $tables = array( + "APPLICATION", + "APP_DELEGATION", + "APP_CACHE_VIEW", + "APP_THREAD", + "APP_DOCUMENT", + "APP_EVENT", + "APP_HISTORY", + "APP_MESSAGE" + ); + + echo "Found " . $appRows->getRecordCount() . " cases to remove"; + foreach ($appRows as $row) { + echo "."; + $appUid = $row['APP_UID']; + foreach ($tables as $table) { + delete_app_from_table($con, $table, $appUid); + } + delete_app_from_table($con, "CONTENT", $appUid, "CON_ID"); + if (file_exists(PATH_DB . $workspace . '/files/'. $appUid)) { + echo "\nRemoving files from " . $appUid . "\n"; + G::rm_dir(PATH_DB . $workspace . '/files/'. $appUid); + } + } + echo "\n"; +} + +?> \ No newline at end of file diff --git a/workflow/engine/classes/class.system.php b/workflow/engine/classes/class.system.php index be5005d96..c284026dd 100755 --- a/workflow/engine/classes/class.system.php +++ b/workflow/engine/classes/class.system.php @@ -42,7 +42,178 @@ class System { var $sRevision; var $sPath; var $newSystemClass; - + + /** + * List currently installed plugins + * + * @param + * @return array with the names of the plugins + */ + public static function getPlugins() { + $plugins = array (); + + foreach (glob(PATH_PLUGINS . "*") as $filename) { + $info = pathinfo($filename); + if (array_key_exists("extension", $info) && (strcmp($info["extension"], "php") == 0)) { + $plugins[] = $info["basename"]; + } + } + + sort($plugins, SORT_STRING); + return $plugins; + } + + /** + * Lists existing workspaces, returning an array of workspaceTools object + * for each. + * This is a class method, it does not require an instance. + * + * @author Alexandre Rosenfeld + * @access public + * @return array of workspace tools objects + */ + public static function listWorkspaces() { + $oDirectory = dir(PATH_DB); + $aWorkspaces = array(); + foreach (glob(PATH_DB . "*") as $filename) { + if (is_dir($filename) && file_exists($filename . "/db.php")) + $aWorkspaces[] = new workspaceTools (basename($filename)); + } + return $aWorkspaces; + } + + /** + * Get system information + * + * @param + * @return array with system information + */ + public static function getSysInfo() { + if( file_exists(PATH_METHODS . 'login/version-pmos.php') ) { + require_once (PATH_METHODS . 'login/version-pmos.php'); + } else { + define('PM_VERSION', 'Development Version'); + } + + $ipe = explode(" ", $_SERVER['SSH_CONNECTION']); + + if( getenv('HTTP_CLIENT_IP') ) { + $ip = getenv('HTTP_CLIENT_IP'); + } elseif( getenv('HTTP_X_FORWARDED_FOR') ) { + $ip = getenv('HTTP_X_FORWARDED_FOR'); + } else { + $ip = getenv('REMOTE_ADDR'); + } + + /* For distros with the lsb_release, this returns a one-line description of + * the distro name, such as "CentOS release 5.3 (Final)" or "Ubuntu 10.10" + */ + $distro = exec("lsb_release -d -s 2> /dev/null"); + + /* For distros without lsb_release, we look for *release (such as + * redhat-release, gentoo-release, SuSE-release, etc) or *version (such as + * debian_version, slackware-version, etc) + */ + if (empty($distro)) { + foreach (glob("/etc/*release") as $filename) { + $distro = trim(file_get_contents($filename)); + if (!empty($distro)) + break; + } + if (empty($distro)) { + foreach (glob("/etc/*version") as $filename) { + $distro = trim(file_get_contents($filename)); + if (!empty($distro)) + break; + } + } + } + + /* CentOS returns a string with quotes, remove them and append + * the OS name (such as LINUX, WINNT, DARWIN, etc) + */ + $distro = trim($distro, "\"") . " (" . PHP_OS . ")"; + + $Fields = array(); + $Fields['SYSTEM'] = $distro; + $Fields['PHP'] = phpversion(); + $Fields['PM_VERSION'] = PM_VERSION; + $Fields['SERVER_ADDR'] = $ipe[2]; //lookup($ipe[2]); + $Fields['IP'] = $ipe[0]; //lookup($ipe[0]); + + $Fields['PLUGINS_LIST'] = System::getPlugins(); + + return $Fields; + } + + public static function listPoFiles() { + $folders = glob(PATH_CORE . '/content/translations/*'); + + $items = glob(PATH_CORE . '/content/*.po'); + foreach ($folders as $folder) { + if (is_dir($folder)) { + $add = glob($folder . "/*.po"); + $items = array_merge($items, $add); + } + } + + return $items; + } + + public static function getFilesChecksum($dir, $root = NULL) { + if (!isset($root)) + $root = $dir; + $dir = realpath($dir); + $root = realpath($root); + $items = glob($dir . "/*"); + $checksums = array(); + foreach ($items as $item) { + $relname = substr($item, strlen($root)); + //Skip xmlform files, since they always change. + if (strpos($relname, "/xmlform/") !== false) + continue; + //Skip shared and compiled directories. + if ((strpos($relname, "/shared") === 0) || (strpos($relname, "/compiled") === 0)) { + continue; + } + if (is_dir($item)) { + $checksums = array_merge($checksums, System::getFilesChecksum($item, $root)); + } else { + $checksums[".$relname"] = md5_file($item); + } + } + return $checksums; + } + + public static function verifyChecksum() { + if (!file_exists(PATH_TRUNK . "checksum.txt")) + return false; + $filesChecksum = System::getFilesChecksum(PATH_TRUNK); + $lines = explode("\n", file_get_contents(PATH_TRUNK . "checksum.txt")); + $originalChecksum = array(); + foreach ($lines as $line) { + if (empty($line)) + continue; + list($checksum, $empty, $filename) = explode(" ", $line); + $originalChecksum[$filename] = $checksum; + } + $result = array("diff" => array(), "missing" => array()); + foreach ($originalChecksum as $filename => $checksum) { + //Skip hidden files that start with a dot. + if (substr(basename($filename), 0, 1) === '.') + continue; + //Skip xmlform files, since they always change. + if (strpos($filename, "/xmlform/") !== false) + continue; + if (!array_key_exists($filename, $filesChecksum)) { + $result['missing'][] = $filename; + } else if (strcmp($checksum, $filesChecksum[$filename]) != 0) { + $result['diff'][] = $filename; + } + } + return $result; + } + /** * This function checks files to do updated to pm * @@ -518,4 +689,181 @@ class System { $sContent = str_replace(");", ';', $sContent); return $sContent; } + + /** + * Retrieves a schema array from a file. + * + * @param string $sSchemaFile schema filename + * @param string $dbAdapter database adapter name + * @return $sContent + */ + public static function getSchema() { + $sSchemaFile = PATH_TRUNK . "workflow/engine/config/schema.xml"; + $dbAdapter = "mysql"; + $aSchema = array(); + $oXml = new DomDocument(); + $oXml->load($sSchemaFile); + $aTables = $oXml->getElementsByTagName('table'); + foreach ($aTables as $oTable) { + $aPrimaryKeys = array(); + $sTableName = $oTable->getAttribute('name'); + $aSchema[$sTableName] = array(); + $aColumns = $oTable->getElementsByTagName('column'); + foreach ($aColumns as $oColumn) { + $sColumName = $oColumn->getAttribute('name'); + $aSchema[$sTableName][$sColumName] = array(); + $aVendors = $oColumn->getElementsByTagName('vendor'); + foreach ($aVendors as $oVendor) { + if ($oVendor->getAttribute('type') == $dbAdapter) { + break; + } + } + $aParameters = $oColumn->getElementsByTagName('parameter'); + foreach ($aParameters as $oParameter) { + $parameterName = ucwords($oParameter->getAttribute('name')); + if ( $parameterName == 'Key' && strtoupper($oParameter->getAttribute('value')) == 'PRI' ) { + $aPrimaryKeys[] = $oColumn->getAttribute('name'); + } + + if ( in_array ( $parameterName, array('Field','Type','Null','Default') ) ) { + $aSchema[$sTableName][$sColumName][$parameterName] = $oParameter->getAttribute('value'); + } + } + } + + if ( is_array($aPrimaryKeys) && count($aPrimaryKeys) > 0 ) { + $aSchema[$sTableName]['INDEXES']['PRIMARY'] = $aPrimaryKeys; + } + $aIndexes = $oTable->getElementsByTagName('index'); + foreach ($aIndexes as $oIndex) { + $aIndex = array(); + $aIndexesColumns = $oIndex->getElementsByTagName('index-column'); + foreach ($aIndexesColumns as $oIndexColumn) { + $aIndex[] = $oIndexColumn->getAttribute('name'); + } + $aSchema[$sTableName]['INDEXES'][ $oIndex->getAttribute('name') ] = $aIndex; + } + } + return $aSchema; + } + + /** + * Returns the difference between two schema arrays + * + * @param array $aOldSchema original schema array + * @param array $aNewSchema new schema array + * @return array with tablesToAdd, tablesToAlter, tablesWithNewIndex and tablesToAlterIndex + */ + public static function compareSchema($aOldSchema, $aNewSchema) { + //$aChanges = array('tablesToDelete' => array(), 'tablesToAdd' => array(), 'tablesToAlter' => array()); + //Tables to delete, but this is disabled + //foreach ($aOldSchema as $sTableName => $aColumns) { + // if ( !isset($aNewSchema[$sTableName])) { + // if (!in_array($sTableName, array('KT_APPLICATION', 'KT_DOCUMENT', 'KT_PROCESS'))) { + // $aChanges['tablesToDelete'][] = $sTableName; + // } + // } + //} + + $aChanges = array('tablesToAdd' => array(), 'tablesToAlter' => array(), 'tablesWithNewIndex' => array(), 'tablesToAlterIndex'=> array()); + + //new tables to create and alter + foreach ($aNewSchema as $sTableName => $aColumns) { + if (!isset($aOldSchema[$sTableName])) { + $aChanges['tablesToAdd'][$sTableName] = $aColumns; + } + else { + //drop old columns + foreach ($aOldSchema[$sTableName] as $sColumName => $aParameters) { + if (!isset($aNewSchema[$sTableName][$sColumName])) { + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['DROP'][$sColumName] = $sColumName; + } + } + + //create new columns + //foreach ($aNewSchema[$sTableName] as $sColumName => $aParameters) { + foreach ($aColumns as $sColumName => $aParameters) { + if ($sColumName != 'INDEXES') { + if (!isset($aOldSchema[$sTableName][$sColumName])) { //this column doesnt exist in oldschema + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['ADD'][$sColumName] = $aParameters; + } + else { //the column exists + $newField = $aNewSchema[$sTableName][$sColumName]; + $oldField = $aOldSchema[$sTableName][$sColumName]; + //both are null, no change is required + if ( !isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = false; + //one of them is null, change IS required + if ( !isset($newField['Default']) && isset($oldField['Default']) && $oldField['Default']!= '') $changeDefaultAttr = true; + if ( isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = true; + //both are defined and they are different. + if ( isset($newField['Default']) && isset($oldField['Default']) ) { + if ( $newField['Default'] != $oldField['Default'] ) + $changeDefaultAttr = true; + else + $changeDefaultAttr = false; + } + //special cases + // BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html + if ( in_array(strtolower($newField['Type']), array('text','mediumtext') ) ) + $changeDefaultAttr = false; + + //#1067 - Invalid default value for datetime field + if ( in_array($newField['Type'], array('datetime')) && isset($newField['Default']) && $newField['Default']== '' ) + $changeDefaultAttr = false; + + //#1067 - Invalid default value for int field + if ( substr($newField['Type'], 0, 3 ) && isset($newField['Default']) && $newField['Default']== '' ) + $changeDefaultAttr = false; + + //if any difference exists, then insert the difference in aChanges + if ( $newField['Field'] != $oldField['Field'] || + $newField['Type'] != $oldField['Type'] || + $newField['Null'] != $oldField['Null'] || + $changeDefaultAttr ) { + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Field'] = $newField['Field']; + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Type'] = $newField['Type']; + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Null'] = $newField['Null']; + if ( isset($newField['Default']) ) + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = $newField['Default']; + else + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = null; + + } + } + } //only columns, no the indexes column + }//foreach $aColumns + + //now check the indexes of table + if ( isset($aNewSchema[$sTableName]['INDEXES']) ) { + foreach ( $aNewSchema[$sTableName]['INDEXES'] as $indexName => $indexFields ) { + if (!isset( $aOldSchema[$sTableName]['INDEXES'][$indexName]) ) { + if (!isset($aChanges['tablesWithNewIndex'][$sTableName])) { + $aChanges['tablesWithNewIndex'][$sTableName] = array(); + } + $aChanges['tablesWithNewIndex'][$sTableName][$indexName] = $indexFields; + } + else { + if ( $aOldSchema[$sTableName]['INDEXES'][$indexName] != $indexFields ) { + if (!isset($aChanges['tablesToAlterIndex'][$sTableName])) { + $aChanges['tablesToAlterIndex'][$sTableName] = array(); + } + $aChanges['tablesToAlterIndex'][$sTableName][$indexName] = $indexFields; + } + } + } + } + } //for-else table exists + } //for new schema + return $aChanges; + } + }// end System class diff --git a/workflow/engine/classes/class.wsTools.php b/workflow/engine/classes/class.wsTools.php index d947a0843..a1106afee 100644 --- a/workflow/engine/classes/class.wsTools.php +++ b/workflow/engine/classes/class.wsTools.php @@ -5,77 +5,197 @@ * * @author Alexandre Rosenfeld */ + class workspaceTools { - var $workspaceName = NULL; - var $dbFile = NULL; + var $name = NULL; + var $path = NULL; + var $db = NULL; + var $dbPath = NULL; + var $dbInfo = NULL; var $dbInfoRegExp = "/( *define *\( *'(?P.*?)' *, *\n* *')(?P.*?)(' *\) *;.*)/"; + var $initPropel = false; + var $initPropelRoot = false; /** - * Create a workspace tools object + * Create a workspace tools object. Note that workspace might not exist when + * this object is created, however most methods requires that a workspace with + * this name does exists. * * @author Alexandre Rosenfeld * @access public * @param string $workspaceName name of the workspace * @return void */ - function __construct($workspaceName) - { - $this->workspaceName = $workspaceName; - $this->dbFile = PATH_DB . $this->workspaceName . '/db.php'; + function __construct($workspaceName) { + $this->name = $workspaceName; + $this->path = PATH_DB . $this->name; + $this->dbPath = $this->path . '/db.php'; + if ($this->workspaceExists()) + $this->getDBInfo (); } - function listWorkspaces() { - $oDirectory = dir(PATH_DB); - $aWorkspaces = array (); - while( ($sObject = $oDirectory->read()) ) { - if( is_dir(PATH_DB . $sObject) && substr($sObject, 0, 1) != '.' && file_exists(PATH_DB . $sObject . PATH_SEP . 'db.php') ) { - $aWorkspaces[] = new workspaceTools($sObject); - } + public function workspaceExists() { + return (file_exists($this->path) && file_exists($this->dbPath)); + } + + public function upgrade($first = false) { + logging("> Updating database...\n"); + $this->upgradeDatabase(); + logging("> Updating translations...\n"); + $this->upgradeTranslation($first); + logging("> Updating cache view...\n"); + $this->upgradeCacheView(); + } + + public function getDBInfo() { + if (!$this->workspaceExists()) + throw new Exception("Could not get db.php in workspace " . $this->name); + if (isset($this->dbInfo)) + return $this->dbInfo; + $sDbFile = file_get_contents($this->dbPath); + /* This regular expression will match any "define ('', '');" + * with any combination of whitespace between words. + * Each match will have these groups: + * ((define('()2', ')1 ()3 (');)4 )0 + */ + preg_match_all($this->dbInfoRegExp, $sDbFile, $matches, PREG_SET_ORDER); + $values = array(); + foreach ($matches as $match) { + $values[$match['key']] = $match['value']; } - return $aWorkspaces; + $this->dbAdapter = $values["DB_ADAPTER"]; + $this->dbName = $values["DB_NAME"]; + $this->dbHost = $values["DB_HOST"]; + $this->dbUser = $values["DB_USER"]; + $this->dbPass = $values["DB_PASS"]; + return $this->dbInfo = $values; } - function getDBInfo() { - if( file_exists($this->dbFile) ) { - $sDbFile = file_get_contents($this->dbFile); - /* This regular expression will match any "define ('', '');" - * with any combination of whitespace between words. - * Each match will have these groups: - * ((define('()2', ')1 ()3 (');)4 )0 - */ - preg_match_all($this->dbInfoRegExp, $sDbFile, $matches, PREG_SET_ORDER); - $config = array(); - foreach ($matches as $match) { - $config[$match['key']] = $match['value']; - } - return $config; - } else { - throw new Exception("Workspace db.php not found."); - } - } - - function getSchema() { + public function getDBCredentials($dbName) { + $prefixes = array( + "wf" => "", + "rp" => "REPORT_", + "rb" => "RBAC_" + ); + $prefix = $prefixes[$dbName]; $dbInfo = $this->getDBInfo(); - $DB_ADAPTER = $dbInfo["DB_ADAPTER"]; - $DB_HOST = $dbInfo["DB_HOST"]; - $DB_USER = $dbInfo["DB_USER"]; - $DB_PASS = $dbInfo["DB_PASS"]; - $DB_NAME = $dbInfo["DB_NAME"]; + return array( + 'adapter' => $dbInfo["DB_ADAPTER"], + 'name' => $dbInfo["DB_".$prefix."NAME"], + 'host' => $dbInfo["DB_".$prefix."HOST"], + 'user' => $dbInfo["DB_".$prefix."USER"], + 'pass' => $dbInfo["DB_".$prefix."PASS"], + 'dsn' => sprintf("%s://%s:%s@%s/%s?encoding=utf8", $dbInfo['DB_ADAPTER'] , + $dbInfo["DB_".$prefix."USER"], $dbInfo["DB_".$prefix."PASS"], + $dbInfo["DB_".$prefix."HOST"], $dbInfo["DB_".$prefix."NAME"]) + ); + } + + private function initPropel($root = false) { + if (($this->initPropel && !$root) || ($this->initPropelRoot && $root)) + return; + $wfDetails = $this->getDBCredentials("wf"); + $rbDetails = $this->getDBCredentials("rb"); + $rpDetails = $this->getDBCredentials("rp"); + + $config = array( + 'datasources' => array( + 'workflow' => array( + 'connection' => $wfDetails["dsn"], + 'adapter' => $wfDetails["adapter"] + ), + 'rbac' => array( + 'connection' => $rbDetails["dsn"], + 'adapter' => $rbDetails["adapter"] + ), + 'rp' => array( + 'connection' => $rpDetails["dsn"], + 'adapter' => $rpDetails["adapter"] + ) + ) + ); + + if ($root) { + $dbHash = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); + + $dbInfo = $this->getDBInfo(); + $host = $dbHash[0]; + $user = $dbHash[1]; + $pass = $dbHash[2]; + $dbName = $dbInfo["DB_NAME"]; + + $rootConfig = array( + 'datasources' => array( + 'root' => array( + 'connection' => "mysql://$user:$pass@$host/$dbName?encoding=utf8", + 'adapter' => "mysql" + ) + ) + ); + + $config["datasources"] = array_merge($config["datasources"], $rootConfig["datasources"]); + + $this->initPropelRoot = true; + } + + $this->initPropel = true; + + require_once ( "propel/Propel.php" ); + require_once ( "creole/Creole.php" ); + + Propel::initConfiguration($config); + } + + private function closePropel() { + Propel::close(); + $this->initPropel = false; + $this->initPropelRoot = false; + } + + public function upgradeTranslation($updateXml = true) { + $this->initPropel(true); + G::LoadClass('languages'); + G::LoadThirdParty('pear/json', 'class.json'); + $languages = new languages(); + foreach (System::listPoFiles() as $poFile) { + logging("Updating language ".basename($poFile)."\n"); + $languages->importLanguage($poFile, $updateXml); + } + } + + private function getDatabase() { + if (isset($this->db) && $this->db->isConnected()) + return $this->db; + G::LoadSystem( 'database_' . strtolower($this->dbAdapter)); + $this->db = new database($this->dbAdapter, $this->dbHost, $this->dbUser, + $this->dbPass, $this->dbName); + if ( !$this->db->isConnected() ) { + $this->db->logQuery ('No available connection to database!'); + throw new Exception("Could not connect to database"); + } + return $this->db; + } + + private function closeDatabase() { + if (!isset($this->db)) + return; + $this->db->close(); + $this->db = NULL; + } + + public function close() { + $this->closePropel(); + $this->closeDatabase(); + } + + public function getSchema() { + $oDataBase = $this->getDatabase(); + + $aOldSchema = array(); try { - G::LoadSystem( 'database_' . strtolower($DB_ADAPTER)); - - $aOldSchema = array(); - $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); - - if ( !$oDataBase->isConnected() ) { - $oDataBase->logQuery ('Not exists an available connection!'); - return NULL; - } - $oDataBase->iFetchType = MYSQL_NUM; $oDataset1 = $oDataBase->executeQuery($oDataBase->generateShowTablesSQL()); - } catch ( Exception $e ) { $oDataBase->logQuery ( $e->getmessage() ); return NULL; @@ -118,181 +238,79 @@ class workspaceTools { return $aOldSchema; } - function getSchemaFromFile($sSchemaFile, $dbAdapter) { - $aSchema = array(); - $oXml = new DomDocument(); - $oXml->load($sSchemaFile); - $aTables = $oXml->getElementsByTagName('table'); - foreach ($aTables as $oTable) { - $aPrimaryKeys = array(); - $sTableName = $oTable->getAttribute('name'); - $aSchema[$sTableName] = array(); - $aColumns = $oTable->getElementsByTagName('column'); - foreach ($aColumns as $oColumn) { - $sColumName = $oColumn->getAttribute('name'); - $aSchema[$sTableName][$sColumName] = array(); - $aVendors = $oColumn->getElementsByTagName('vendor'); - foreach ($aVendors as $oVendor) { - if ($oVendor->getAttribute('type') == $dbAdapter) { - break; - } - } - $aParameters = $oColumn->getElementsByTagName('parameter'); - foreach ($aParameters as $oParameter) { - $parameterName = ucwords($oParameter->getAttribute('name')); - if ( $parameterName == 'Key' && strtoupper($oParameter->getAttribute('value')) == 'PRI' ) { - $aPrimaryKeys[] = $oColumn->getAttribute('name'); - } + public function upgradeCacheView($checkOnly = false, $lang = "en") { + $this->initPropel(true); - if ( in_array ( $parameterName, array('Field','Type','Null','Default') ) ) { - $aSchema[$sTableName][$sColumName][$parameterName] = $oParameter->getAttribute('value'); - } - } - } + require_once('classes/model/AppCacheView.php'); - if ( is_array($aPrimaryKeys) && count($aPrimaryKeys) > 0 ) { - $aSchema[$sTableName]['INDEXES']['PRIMARY'] = $aPrimaryKeys; - } - $aIndexes = $oTable->getElementsByTagName('index'); - foreach ($aIndexes as $oIndex) { - $aIndex = array(); - $aIndexesColumns = $oIndex->getElementsByTagName('index-column'); - foreach ($aIndexesColumns as $oIndexColumn) { - $aIndex[] = $oIndexColumn->getAttribute('name'); - } - $aSchema[$sTableName]['INDEXES'][ $oIndex->getAttribute('name') ] = $aIndex; - } + //check the language, if no info in config about language, the default is 'en' + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'APP_CACHE_VIEW_ENGINE','','','',''); + $appCacheViewEngine = $oConf->aConfig; + + //setup the appcacheview object, and the path for the sql files + $appCache = new AppCacheView(); + $appCache->setPathToAppCacheFiles ( PATH_METHODS . 'setup' . PATH_SEP .'setupSchemas'. PATH_SEP ); + + $userGrants = $appCache->checkGrantsForUser( false ); + + $currentUser = $res['user']; + $currentUserIsSuper = $res['super']; + + //if user does not have the SUPER privilege we need to use the root user and grant the SUPER priv. to normal user. + if (!$currentUserIsSuper && !$checkOnly) { + $res = $appCache->checkGrantsForUser( true ); + $res = $appCache->setSuperForUser( $currentUser ); + $currentUserIsSuper = true; } - return $aSchema; + + logging("Creating table"); + //now check if table APPCACHEVIEW exists, and it have correct number of fields, etc. + if (!$checkOnly) { + $res = $appCache->checkAppCacheView(); + } + + logging(", triggers"); + //now check if we have the triggers installed + $triggers = array(); + $triggers[] = $appCache->triggerAppDelegationInsert($lang, $checkOnly); + $triggers[] = $appCache->triggerAppDelegationUpdate($lang, $checkOnly); + $triggers[] = $appCache->triggerApplicationUpdate($lang, $checkOnly); + $triggers[] = $appCache->triggerApplicationDelete($lang, $checkOnly); + + if (!$checkOnly) { + logging(", filling cache view"); + //build using the method in AppCacheView Class + $res = $appCache->fillAppCacheView($lang); + logging("."); + } + logging("\n"); + //set status in config table + $confParams = Array( + 'LANG' => $lang, + 'STATUS'=> 'active' + ); + $oConf->aConfig = $confParams; + $oConf->saveConfig('APP_CACHE_VIEW_ENGINE', '', '', ''); + + // removing casesList configuration records. TODO: removing these lines that resets all the configurations records + $oCriteria = new Criteria(); + $oCriteria->add(ConfigurationPeer::CFG_UID,'casesList'); + ConfigurationPeer::doDelete($oCriteria); + // end of reset } - function getSchemaChanges($aOldSchema, $aNewSchema) { - //$aChanges = array('tablesToDelete' => array(), 'tablesToAdd' => array(), 'tablesToAlter' => array()); - //Tables to delete, but this is disabled - //foreach ($aOldSchema as $sTableName => $aColumns) { - // if ( !isset($aNewSchema[$sTableName])) { - // if (!in_array($sTableName, array('KT_APPLICATION', 'KT_DOCUMENT', 'KT_PROCESS'))) { - // $aChanges['tablesToDelete'][] = $sTableName; - // } - // } - //} - - $aChanges = array('tablesToAdd' => array(), 'tablesToAlter' => array(), 'tablesWithNewIndex' => array(), 'tablesToAlterIndex'=> array()); - - //new tables to create and alter - foreach ($aNewSchema as $sTableName => $aColumns) { - if (!isset($aOldSchema[$sTableName])) { - $aChanges['tablesToAdd'][$sTableName] = $aColumns; - } - else { - //drop old columns - foreach ($aOldSchema[$sTableName] as $sColumName => $aParameters) { - if (!isset($aNewSchema[$sTableName][$sColumName])) { - if (!isset($aChanges['tablesToAlter'][$sTableName])) { - $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); - } - $aChanges['tablesToAlter'][$sTableName]['DROP'][$sColumName] = $sColumName; - } - } - - //create new columns - //foreach ($aNewSchema[$sTableName] as $sColumName => $aParameters) { - foreach ($aColumns as $sColumName => $aParameters) { - if ($sColumName != 'INDEXES') { - if (!isset($aOldSchema[$sTableName][$sColumName])) { //this column doesnt exist in oldschema - if (!isset($aChanges['tablesToAlter'][$sTableName])) { - $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); - } - $aChanges['tablesToAlter'][$sTableName]['ADD'][$sColumName] = $aParameters; - } - else { //the column exists - $newField = $aNewSchema[$sTableName][$sColumName]; - $oldField = $aOldSchema[$sTableName][$sColumName]; - //both are null, no change is required - if ( !isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = false; - //one of them is null, change IS required - if ( !isset($newField['Default']) && isset($oldField['Default']) && $oldField['Default']!= '') $changeDefaultAttr = true; - if ( isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = true; - //both are defined and they are different. - if ( isset($newField['Default']) && isset($oldField['Default']) ) { - if ( $newField['Default'] != $oldField['Default'] ) - $changeDefaultAttr = true; - else - $changeDefaultAttr = false; - } - //special cases - // BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html - if ( in_array(strtolower($newField['Type']), array('text','mediumtext') ) ) - $changeDefaultAttr = false; - - //#1067 - Invalid default value for datetime field - if ( in_array($newField['Type'], array('datetime')) && isset($newField['Default']) && $newField['Default']== '' ) - $changeDefaultAttr = false; - - //#1067 - Invalid default value for int field - if ( substr($newField['Type'], 0, 3 ) && isset($newField['Default']) && $newField['Default']== '' ) - $changeDefaultAttr = false; - - //if any difference exists, then insert the difference in aChanges - if ( $newField['Field'] != $oldField['Field'] || - $newField['Type'] != $oldField['Type'] || - $newField['Null'] != $oldField['Null'] || - $changeDefaultAttr ) { - if (!isset($aChanges['tablesToAlter'][$sTableName])) { - $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); - } - $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Field'] = $newField['Field']; - $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Type'] = $newField['Type']; - $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Null'] = $newField['Null']; - if ( isset($newField['Default']) ) - $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = $newField['Default']; - else - $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = null; - - } - } - } //only columns, no the indexes column - }//foreach $aColumns - - //now check the indexes of table - if ( isset($aNewSchema[$sTableName]['INDEXES']) ) { - foreach ( $aNewSchema[$sTableName]['INDEXES'] as $indexName => $indexFields ) { - if (!isset( $aOldSchema[$sTableName]['INDEXES'][$indexName]) ) { - if (!isset($aChanges['tablesWithNewIndex'][$sTableName])) { - $aChanges['tablesWithNewIndex'][$sTableName] = array(); - } - $aChanges['tablesWithNewIndex'][$sTableName][$indexName] = $indexFields; - } - else { - if ( $aOldSchema[$sTableName]['INDEXES'][$indexName] != $indexFields ) { - if (!isset($aChanges['tablesToAlterIndex'][$sTableName])) { - $aChanges['tablesToAlterIndex'][$sTableName] = array(); - } - $aChanges['tablesToAlterIndex'][$sTableName][$indexName] = $indexFields; - } - } - } - } - } //for-else table exists - } //for new schema - return $aChanges; - } - - function repairSchema($checkOnly = false, $progress = true) { + public function upgradeDatabase($checkOnly = false) { $dbInfo = $this->getDBInfo(); - $DB_ADAPTER = $dbInfo["DB_ADAPTER"]; - $DB_HOST = $dbInfo["DB_HOST"]; - $DB_USER = $dbInfo["DB_USER"]; - $DB_PASS = $dbInfo["DB_PASS"]; - $DB_NAME = $dbInfo["DB_NAME"]; - if (strcmp($DB_ADAPTER, "mysql") != 0) { - throw new Exception("Only MySQL is supported\n"); + if (strcmp($dbInfo["DB_ADAPTER"], "mysql") != 0) { + throw new Exception("Only MySQL is supported"); } - $currentSchema = $this->getSchemaFromFile(PATH_TRUNK . "workflow/engine/config/schema.xml", "mysql"); + $currentSchema = System::getSchema(); $workspaceSchema = $this->getSchema(); - $changes = $this->getSchemaChanges($workspaceSchema, $currentSchema); + $changes = System::compareSchema($workspaceSchema, $currentSchema); $changed = (count($changes['tablesToAdd']) > 0 || count($changes['tablesToAlter']) > 0 || count($changes['tablesWithNewIndex']) > 0 || @@ -304,16 +322,12 @@ class workspaceTools { return $changed; } - $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); - if ( !$oDataBase->isConnected() ) { - throw new Exception("Could not connect to the database"); - } + $oDataBase = $this->getDatabase(); $oDataBase->iFetchType = MYSQL_NUM; $oDataBase->logQuery ( count ($changes ) ); - if ($progress) - echo "Adding " . count($changes['tablesToAdd']) . " tables\n"; + logging( "" . count($changes['tablesToAdd']) . " tables to add"); foreach ($changes['tablesToAdd'] as $sTable => $aColumns) { $oDataBase->executeQuery($oDataBase->generateCreateTableSQL($sTable, $aColumns)); if (isset($changes['tablesToAdd'][$sTable]['INDEXES'])) { @@ -323,9 +337,7 @@ class workspaceTools { } } - - if ($progress) - echo "Altering " . count($changes['tablesToAlter']) . " tables\n"; + logging(", " . count($changes['tablesToAlter']) . " tables to alter"); foreach ($changes['tablesToAlter'] as $sTable => $aActions) { foreach ($aActions as $sAction => $aAction) { foreach ($aAction as $sColumn => $vData) { @@ -344,27 +356,135 @@ class workspaceTools { } } - - if ($progress) - echo "Adding indexes to " . count($changes['tablesWithNewIndex']) . " tables\n"; + logging(", " . count($changes['tablesWithNewIndex']) . " indexes to add"); foreach ($changes['tablesWithNewIndex'] as $sTable => $aIndexes) { foreach ($aIndexes as $sIndexName => $aIndexFields ) { $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $sIndexName, $aIndexFields )); } } - - if ($progress) - echo "Altering indexes to " . count($changes['tablesWithNewIndex']) . " tables\n"; + logging(", " . count($changes['tablesWithNewIndex']) . " indexes to alter"); foreach ($changes['tablesToAlterIndex'] as $sTable => $aIndexes) { foreach ($aIndexes as $sIndexName => $aIndexFields ) { $oDataBase->executeQuery($oDataBase->generateDropKeySQL($sTable, $sIndexName )); $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $sIndexName, $aIndexFields )); } } - $oDataBase->close(); + logging("\n"); + $this->closeDatabase(); return true; } + public function getMetadata() { + $Fields = array_merge(System::getSysInfo(), $this->getDBInfo()); + $Fields['WORKSPACE_NAME'] = $this->name; + + if(isset($this->dbHost)) { + + //TODO: This code stopped working with the refactoring + //require_once ("propel/Propel.php"); + //G::LoadClass('dbConnections'); + //$dbConns = new dbConnections(''); + //$availdb = ''; + //foreach( $dbConns->getDbServicesAvailables() as $key => $val ) { + //if(!empty($availdb)) + // $availdb .= ', '; + // $availdb .= $val['name']; + //} + + G::LoadClass('net'); + $dbNetView = new NET($this->dbHost); + $dbNetView->loginDbServer($this->dbUser, $this->dbPass); + try { + $sMySQLVersion = $dbNetView->getDbServerVersion('mysql'); + } catch( Exception $oException ) { + $sMySQLVersion = 'Unknown'; + } + + $Fields['DATABASE'] = $dbNetView->dbName($this->dbAdapter) . ' (Version ' . $sMySQLVersion . ')'; + $Fields['DATABASE_SERVER'] = $this->dbHost; + $Fields['DATABASE_NAME'] = $this->dbName; + $Fields['AVAILABLE_DB'] = "Not defined"; + //$Fields['AVAILABLE_DB'] = $availdb; + } else { + $Fields['DATABASE'] = "Not defined"; + $Fields['DATABASE_SERVER'] = "Not defined"; + $Fields['DATABASE_NAME'] = "Not defined"; + $Fields['AVAILABLE_DB'] = "Not defined"; + } + + return $Fields; + } + + /** + * Print the system information gathered from getSysInfo + * + * @return + */ + public static function printSysInfo() { + $fields = System::getSysInfo(); + + $info = array( + 'ProcessMaker Version' => $fields['PM_VERSION'], + 'System' => $fields['SYSTEM'], + 'PHP Version' => $fields['PHP'], + 'Server Address' => $fields['SERVER_ADDR'], + 'Client IP Address' => $fields['IP'], + 'Plugins' => (count($fields['PLUGINS_LIST']) > 0) ? $fields['PLUGINS_LIST'][0] : 'None' + ); + + foreach( $fields['PLUGINS_LIST'] as $k => $v ) { + if ($k == 0) + continue; + $info[] = $v; + } + + foreach ($info as $k => $v) { + if (is_numeric($k)) $k = ""; + logging(sprintf("%20s %s\n", $k, pakeColor::colorize($v, 'INFO'))); + } + } + + public function printMetadata($printSysInfo = true) { + $fields = $this->getMetadata(); + + if ($printSysInfo) { + workspaceTools::printSysInfo (); + logging("\n"); + } + + $wfDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_USER'] . ':' . $fields['DB_PASS'] . '@' . $fields['DB_HOST'] . '/' . $fields['DB_NAME']; + $rbDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_RBAC_USER'] . ':' . $fields['DB_RBAC_PASS'] . '@' . $fields['DB_RBAC_HOST'] . '/' . $fields['DB_RBAC_NAME']; + $rpDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_REPORT_USER'] . ':' . $fields['DB_REPORT_PASS'] . '@' . $fields['DB_REPORT_HOST'] . '/' . $fields['DB_REPORT_NAME']; + + $info = array( + 'Workspace Name' => $fields['WORKSPACE_NAME'], + 'Available Databases' => $fields['AVAILABLE_DB'], + 'Workflow Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_USER'], $fields['DB_PASS'], $fields['DB_HOST'], $fields['DB_NAME']), + 'RBAC Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_RBAC_USER'], $fields['DB_RBAC_PASS'], $fields['DB_RBAC_HOST'], $fields['DB_RBAC_NAME']), + 'Report Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_REPORT_USER'], $fields['DB_REPORT_PASS'], $fields['DB_REPORT_HOST'], $fields['DB_REPORT_NAME']), + 'MySql Version' => $fields['DATABASE'], + ); + + foreach ($info as $k => $v) { + if (is_numeric($k)) $k = ""; + logging(sprintf("%20s %s\n", $k, pakeColor::colorize($v, 'INFO'))); + } + } + + public function exportDatabase($path) { + $dbInfo = $this->getDBInfo(); + $databases = array("wf", "rp", "rb"); + foreach ($databases as $db) { + $dbInfo = $this->getDBCredentials($db); + $oDbMaintainer = new DataBaseMaintenance($dbInfo["host"], $dbInfo["user"], + $dbInfo["pass"]); + $oDbMaintainer->connect($dbInfo["name"]); + $oDbMaintainer->setTempDir($path . $dbInfo["name"] . "/"); + $oDbMaintainer->backupDataBaseSchema($oDbMaintainer->getTempDir() . $dbInfo["name"] . ".sql"); + $oDbMaintainer->backupSqlData(); + } + } + } ?>