$status, 'message' => $message)); } else { echo 'STATUS=', $status, "\n"; echo 'MESSAGE=', str_replace("\n", " -- ", $message); } exit; } define('UPDATE_DONE', 'UPDATE_DONE'); // Process completed successfully. This is a success return code. define('UPDATE_NOOP', 'UPDATE_NOOP'); // Nothing had to be done, everything is up to date. This is also a success code. define('UPDATE_RETRY', 'UPDATE_RETRY'); // Install/update process failed, but should be retried later. define('UPDATE_FAILED', 'UPDATE_FAILED'); // Fatal error occured, retry will not resolve the issue. /* * Helper functions for dealing with the database */ function tableHasColumn($table, $column) { $table = preg_replace('/\W/', '', $table); $column = preg_replace('/\W/', '', $column); $res = Database::simpleQuery("DESCRIBE `$table`", array(), true); if ($res !== false) { while ($row = $res->fetch(PDO::FETCH_ASSOC)) { if ((is_array($column) && in_array($row['Field'], $column)) || (is_string($column) && $row['Field'] === $column)) return true; } } return false; } function tableDropColumn($table, $column) { $table = preg_replace('/\W/', '', $table); $column = preg_replace('/\W/', '', $column); $res = Database::simpleQuery("DESCRIBE `$table`", array(), true); if ($res !== false) { while ($row = $res->fetch(PDO::FETCH_ASSOC)) { if ((is_array($column) && in_array($row['Field'], $column)) || (is_string($column) && $row['Field'] === $column)) Database::exec("ALTER TABLE `$table` DROP `{$row['Field']}`"); } } } function tableExists($table) { $res = Database::simpleQuery("SHOW TABLES", array(), true); while ($row = $res->fetch(PDO::FETCH_NUM)) { if ($row[0] === $table) return true; } return false; } function tableRename($old, $new) { $res = Database::simpleQuery("RENAME TABLE $old TO $new", []); return $res; } /** * Get all constraints from given table+column to another table+column. * * @param string $table source table, being constrained * @param string $column source column * @param string $refTable referenced table, dictating the constraints * @param string $refColumn referenced column * @return false|string[] list of constraints matching the request, false on error */ function tableGetContraints($table, $column, $refTable, $refColumn) { $db = 'openslx'; if (defined('CONFIG_SQL_DB')) { $db = CONFIG_SQL_DB; } elseif (defined('CONFIG_SQL_DSN')) { if (preg_match('/dbname\s*=\s*([^;\s]+)\s*(;|$)/i', CONFIG_SQL_DSN, $out)) { $db = $out[1]; define('CONFIG_SQL_DB', $db); } } $res = Database::simpleQuery('SELECT `CONSTRAINT_NAME` FROM information_schema.KEY_COLUMN_USAGE' . ' WHERE `TABLE_SCHEMA` = :db AND `TABLE_NAME` = :table AND `COLUMN_NAME` = :column' . ' AND `REFERENCED_TABLE_NAME` = :refTable AND `REFERENCED_COLUMN_NAME` = :refColumn', compact('db', 'table', 'column', 'refTable', 'refColumn')); if ($res === false) return false; return $res->fetchAll(PDO::FETCH_COLUMN, 0); } /** * Drop constraint from a table. * * @param string $table table name * @param string $constraint constraint name * @return bool success indicator */ function tableDeleteConstraint($table, $constraint) { return Database::exec("ALTER TABLE `$table` DROP FOREIGN KEY `$constraint`") !== false; } function tableCreate($table, $structure, $fatalOnError = true) { if (tableExists($table)) { return UPDATE_NOOP; } $ret = Database::exec("CREATE TABLE IF NOT EXISTS `{$table}` ( {$structure} ) ENGINE=InnoDB DEFAULT CHARSET=utf8"); if ($ret !== false) { return UPDATE_DONE; } if ($fatalOnError) { finalResponse(UPDATE_FAILED, 'DB-Error: ' . Database::lastError()); } return UPDATE_FAILED; } /* * Rest of install script.... */ if (!isset($_SERVER['REMOTE_ADDR']) || isset($_REQUEST['direct'])) { define('DIRECT_MODE', true); } else { define('DIRECT_MODE', false); } define('AJAX', ((isset($_REQUEST['async'])) || (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'))); error_reporting(E_ALL); chdir(dirname($_SERVER['SCRIPT_FILENAME'])); // Autoload classes from ./inc which adhere to naming scheme .inc.php spl_autoload_register(function ($class) { $file = 'inc/' . preg_replace('/[^a-z0-9]/', '', mb_strtolower($class)) . '.inc.php'; if (!file_exists($file)) return; require_once $file; }); if (!is_readable('config.php')) { finalResponse(UPDATE_FAILED, 'config.php does not exist!'); } require_once 'config.php'; if (CONFIG_SQL_PASS === '%MYSQL_OPENSLX_PASS%') { finalResponse(UPDATE_FAILED, 'mysql credentials not configured yet!'); } // Explicitly connect to the database so it won't call Util::traceError() on failure if (!Database::init(true)) { finalResponse(UPDATE_RETRY, 'Connecting to the database failed'); } // Good to go so far /** * @param \Module $module * @return bool */ function hasUpdateScript($module) { return is_readable($module->getDir() . '/install.inc.php'); } function runUpdateScript($module) { require_once $module->getDir() . '/install.inc.php'; } // Build dependency tree Module::init(); $modules = Module::getEnabled(); if (empty($modules)) { finalResponse(UPDATE_NOOP, 'No active modules, nothing to do'); } if (DIRECT_MODE) { // // Direct mode - plain $new = array(); foreach ($modules as $entry) { if (hasUpdateScript($entry)) { $new[] = $entry; } } $modules = $new; if (empty($modules)) { finalResponse(UPDATE_NOOP, 'No modules with install scripts, nothing to do'); } // Get array where the key maps a module identifier to the next module object $assoc = array(); $count = count($modules); for ($i = 0; $i < $count; ++$i) { $assoc[$modules[$i]->getIdentifier()] = $modules[($i + 1) % $count]; } if (!empty($argv[1])) { $last = $argv[1]; } else { $last = Request::any('last', '', 'string'); } if (!empty($last) && isset($assoc[$last])) { $module = $assoc[$last]; } if (!isset($module)) { $module = $modules[0]; } echo 'MODULE=', $module->getIdentifier(), "\n"; runUpdateScript($module); } else { // // Interactive web based mode $mod = Request::any('module', false, 'string'); if ($mod !== false) { // Execute specific module $module = Module::get($mod, true); if ($module === false) { finalResponse(UPDATE_NOOP, 'Given module does not exist!'); } if (!hasUpdateScript($module)) { finalResponse(UPDATE_NOOP, 'Given module has no install script'); } runUpdateScript($module); finalResponse(UPDATE_DONE, 'Module did not report status; assuming OK'); } // Show the page that shows status and triggers jobs echo << Install/Update SLXadmin

Modules

HERE; foreach ($modules as $module) { $id = $module->getIdentifier(); echo ""; } echo <<

HERE; }
ModuleStatus
{$id}Waiting...