initAddModule(); AddModule_Base::preprocess(); } if ($action === 'module') { // Action: "delmodule" (delete module) if (Request::post('del', 'no') !== 'no') { $this->delModule(); } if (Request::post('download', 'no') !== 'no') { $this->downloadModule(); } if (Request::post('rebuild', 'no') !== 'no') { $this->rebuildModule(); } } // Action: "addconfig" (compose config from one or more modules) if ($action === 'addconfig') { $this->initAddConfig(); AddConfig_Base::preprocess(); } if ($action === 'config') { // Action: "delconfig" (delete config) if (Request::post('del', 'no') !== 'no') { $this->delConfig(); } // Action "activate" (set sysconfig as active) if (Request::post('activate', 'no') !== 'no') { $this->activateConfig(); } // Action "rebuild" (rebuild config.tgz from its modules) if (Request::post('rebuild', 'no') !== 'no') { $this->rebuildConfig(); } } } /** * Render module; called by main script when this module page should render * its content. */ protected function doRender() { Render::setTitle(Dictionary::translate('lang_location')); $action = Request::any('action', 'list'); switch ($action) { case 'addmodule': AddModule_Base::render(); return; case 'addconfig': AddConfig_Base::render(); return; case 'list': $this->listConfigs(); return; case 'module': $listid = Request::post('list'); if ($listid !== false) { $this->listModuleContents($listid); return; } break; case 'config': $listid = Request::post('list'); if ($listid !== false) { $this->listConfigContents($listid); return; } break; } Message::addError('invalid-action', $action); } /** * If modules need updates (blue refresh buttons), we query their state * via ajax, in case they are about to generate. This happens for example * if you edit a module and a bunch of configs depend on it and will be * rebuilt. */ protected function doAjax() { if (Request::post('action') === 'status') { $mods = Request::post('mods'); $confs = Request::post('confs'); $outMods = array(); $outConfs = array(); $mods = explode(',', $mods); $confs = explode(',', $confs); // Mods $string = '0'; foreach ($mods as $mod) { if (is_numeric($mod)) $string .= ',' . $mod; } $res = Database::simpleQuery("SELECT moduleid FROM configtgz_module WHERE moduleid in ($string) AND status = 'OK'"); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $outMods[] = $row['moduleid']; } // Confs $string = '0'; foreach ($confs as $conf) { if (is_numeric($conf)) $string .= ',' . $conf; } $res = Database::simpleQuery("SELECT configid FROM configtgz WHERE configid in ($string) AND status = 'OK'"); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $outConfs[] = $row['configid']; } Header('Content-Type: application/json'); die(json_encode(array('mods' => $outMods, 'confs' => $outConfs))); } } /** * List all configurations and configuration modules. */ private function listConfigs() { // Configs $res = Database::simpleQuery("SELECT configtgz.configid, configtgz.title, configtgz.filepath, configtgz.status, GROUP_CONCAT(configtgz_x_module.moduleid) AS modlist" . " FROM configtgz" . " INNER JOIN configtgz_x_module USING (configid)" . " GROUP BY configid" . " ORDER BY title ASC"); $configs = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $configs[] = array( 'configid' => $row['configid'], 'config' => $row['title'], 'modlist' => $row['modlist'], 'current' => readlink(CONFIG_HTTP_DIR . '/default/config.tgz') === $row['filepath'], 'needrebuild' => ($row['status'] !== 'OK') ); } // Config modules $res = Database::simpleQuery("SELECT moduleid, title, moduletype, status FROM configtgz_module ORDER BY moduletype ASC, title ASC"); $modules = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $modules[] = array( 'moduleid' => $row['moduleid'], 'moduletype' => $row['moduletype'], 'module' => $row['title'], 'iscustom' => ($row['moduletype'] === 'CustomModule' || $row['moduletype'] === 'Branding'), 'needrebuild' => ($row['status'] !== 'OK') ); } Render::addTemplate('sysconfig/_page', array( 'configs' => $configs, 'modules' => $modules, 'havemodules' => (count($modules) > 0) )); Render::addScriptTop('custom'); Render::addFooter(''); } private function listModuleContents($moduleid) { // fetch the data $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); if ($row === false) { Message::addError('config-invalid', $moduleid); Util::redirect('?do=SysConfig'); } // find files in that archive $status = Taskmanager::submit('ListArchive', array( 'file' => $row['filepath'] )); if (isset($status['id'])) $status = Taskmanager::waitComplete($status, 4000); if (!Taskmanager::isFinished($status) || Taskmanager::isFailed($status)) { Taskmanager::addErrorMessage($status); Util::redirect('?do=SysConfig'); } // Sort files for better display $dirs = array(); foreach ($status['data']['entries'] as $file) { if ($file['isdir']) continue; $dirs[dirname($file['name'])][] = $file; } ksort($dirs); $list = array(); foreach ($dirs as $dir => $files) { $list[] = array( 'name' => $dir, 'isdir' => true ); sort($files); foreach ($files as $file) { $file['size'] = Util::readableFileSize($file['size']); $list[] = $file; } } // render the template Render::addDialog(Dictionary::translate('lang_contentOf') . ' ' . $row['title'], false, 'sysconfig/custom-filelist', array( 'files' => $list, )); } private function listConfigContents($configid) { // get config name $config = Database::queryFirst("SELECT title FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid)); if ($config === false) { Message::addError('config-invalid', $configid); Util::redirect('?do=SysConfig'); } // fetch the data $res = Database::simpleQuery("SELECT module.moduleid, module.title AS moduletitle" . " FROM configtgz_module module" . " INNER JOIN configtgz_x_module USING (moduleid)" . " WHERE configtgz_x_module.configid = :configid" . " ORDER BY module.title ASC", array('configid' => $configid)); $modules = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $modules[] = array( 'module' => $row['moduletitle'], 'moduleid' => $row['moduleid'] ); } // render the template Render::addDialog(Dictionary::translate('lang_contentOf') . ' ' . $config['title'], false, 'sysconfig/config-module-list', array( 'modules' => $modules )); } private function activateConfig() { $configid = Request::post('activate', 'MISSING'); $row = Database::queryFirst("SELECT title, filepath FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid)); if ($row === false) { Message::addError('config-invalid', $configid); Util::redirect('?do=SysConfig'); } $task = Taskmanager::submit('LinkConfigTgz', array( 'destination' => $row['filepath'] )); if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { $task = Taskmanager::waitComplete($task['id']); } if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { Message::addError('task-error', $task['data']['error']); } elseif ($task['statusCode'] === TASK_FINISHED) { Message::addSuccess('config-activated', $row['title']); Event::activeConfigChanged(); } Util::redirect('?do=SysConfig'); } private function rebuildConfig() { $configid = Request::post('rebuild', 'MISSING'); $config = ConfigTgz::get($configid); if ($config === false) { Message::addError('config-invalid', $configid); Util::redirect('?do=SysConfig'); } $ret = $config->generate(false, 350); // TODO if ($ret === true) Message::addSuccess('module-rebuilt', $config->title()); elseif ($ret === false) Message::addError('module-rebuild-failed', $config->title()); else Message::addInfo('module-rebuilding', $config->title()); Util::redirect('?do=SysConfig'); } private function delModule() { $moduleid = Request::post('del', 'MISSING'); $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); if ($row === false) { Message::addError('config-invalid', $moduleid); Util::redirect('?do=SysConfig'); } $existing = Database::queryFirst("SELECT title FROM configtgz_x_module" . " INNER JOIN configtgz USING (configid)" . " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); if ($existing !== false) { Message::addError('module-in-use', $row['title'], $existing['title']); Util::redirect('?do=SysConfig'); } $task = Taskmanager::submit('DeleteFile', array( 'file' => $row['filepath'] )); if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { $task = Taskmanager::waitComplete($task['id']); } if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { Message::addWarning('task-error', $task['data']['error']); } elseif ($task['statusCode'] === TASK_FINISHED) { Message::addSuccess('module-deleted', $row['title']); } Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); Util::redirect('?do=SysConfig'); } private function downloadModule() { $moduleid = Request::post('download', 'MISSING'); $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); if ($row === false) { Message::addError('config-invalid', $moduleid); Util::redirect('?do=SysConfig'); } if (!Util::sendFile($row['filepath'], $row['title'] . '.tgz')) Util::redirect('?do=SysConfig'); exit(0); } private function rebuildModule() { $moduleid = Request::post('rebuild', 'MISSING'); $module = ConfigModule::get($moduleid); if ($module === false) { Message::addError('config-invalid', $moduleid); Util::redirect('?do=SysConfig'); } $ret = $module->generate(false, 250); if ($ret === true) Message::addSuccess('module-rebuilt', $module->title()); elseif ($ret === false) Message::addError('module-rebuild-failed', $module->title()); else Message::addInfo('module-rebuilding', $module->title()); Util::redirect('?do=SysConfig'); } private function delConfig() { $configid = Request::post('del', 'MISSING'); $config = ConfigTgz::get($configid); if ($config === false) { Message::addError('config-invalid', $configid); Util::redirect('?do=SysConfig'); } $config->delete(); Util::redirect('?do=SysConfig'); } private function initAddModule() { ConfigModule::loadDb(); require_once 'modules/sysconfig/addmodule.inc.php'; $step = Request::any('step', 'AddModule_Start'); if (!class_exists($step) && preg_match('/^([a-zA-Z0-9]+)_/', $step, $out)) { require_once 'modules/sysconfig/addmodule_' . strtolower($out[1]) . '.inc.php'; } AddModule_Base::setStep($step); } private function initAddConfig() { ConfigModule::loadDb(); require_once 'modules/sysconfig/addconfig.inc.php'; $step = Request::any('step', 0); if ($step === 0) $step = 'AddConfig_Start'; AddConfig_Base::setStep($step); } }