/** quick and dirty logfile viewer * * this constructs a table of the HTML-variety with the contents of the logtable. * fields displayed are: datim, IP-address, username, logpriority and message * we use a LEFT JOIN in order to get to a meaningful username rather than a numeric user_id * an attempt is made to start with the last page of the logs because that would probably * be the most interesting part. We paginate the log in order to keep it manageable. * * <Rant><br> * I used to use the built-in constants like LOG_INFO and LOG_DEBUG to allow for different levels * of logging (see {@link logger()}). To my complete surprise logging didn't work at all on * Windows (it did on Linux). The reason was that LOG_DEBUG and LOG_INFO and LOG_NOTICE are all * defined to be the same value. WTF? Any test based on LOG_DEBUG and LOG_INFO being different * would fail, hence no logging at all. The mind boggles! So, instead of using built-in constants * I had to define my own and do a global search&replace. Aaarghhhhhh!!!!<br> * </Rant><br> * * @param object &$output collects output to show to user * @return void output displayed via $output * @todo should we allow for fancy selection mechanisms on the logfile or is that over the top? */ function task_logview(&$output) { global $CFG, $WAS_SCRIPT_NAME, $DB; static $priorities = array(WLOG_EMERG => 'LOG_EMERG', WLOG_ALERT => 'LOG_ALERT', WLOG_CRIT => 'LOG_CRIT', WLOG_ERR => 'LOG_ERR', WLOG_WARNING => 'LOG_WARNING', WLOG_NOTICE => 'LOG_NOTICE', WLOG_INFO => 'LOG_INFO', WLOG_DEBUG => 'LOG_DEBUG'); // 0 -- at least we allow the user to navigate away if something goes wrong $output->set_helptopic('logview'); show_tools_menu($output, TASK_LOGVIEW); // 1A -- how many messages are there anyway? $table = 'log_messages'; $where = ''; // could be used to select per user, per priority, etc. For now: always select everything if (($record = db_select_single_record($table, 'COUNT(log_message_id) AS messages', $where)) === FALSE) { $output->add_content('<h2>' . t('menu_logview', 'admin') . '</h2>'); $output->add_content(t('logview_error', 'admin')); $output->add_message(t('logview_error', 'admin')); logger(sprintf('%s(): cannot retrieve log message count: %s', __FUNCTION__, db_errormessage())); return; } // 1B -- if there are no message we leave if (($num_messages = intval($record['messages'])) < 1) { $output->add_content('<h2>' . t('menu_logview', 'admin') . '</h2>'); $output->add_content(t('logview_no_messages', 'admin')); $output->add_message(t('logview_no_messages', 'admin')); logger(sprintf('%s(): no messages to show', __FUNCTION__), WLOG_DEBUG); return; } // 2 -- which part of the logs do they want to see? (calculate/retrieve offset and limit) $limit = get_parameter_int('limit', $CFG->pagination_height); $limit = max(1, $limit); // make sure 1 <= $limit $offset = intval(floor($num_messages / $limit)) * $limit; // attempt to start at begin of LAST page $offset = get_parameter_int('offset', max($offset, 0)); $offset = max(min($num_messages - 1, $offset), 0); // make sure 0 <= $offset < $num_messages // 3 -- show the pagination in the page header (if necessary) if ($num_messages <= $limit && $offset == 0) { // listing fits on a single screen $header = '<h2>' . t('menu_logview', 'admin') . '</h2>'; } else { // pagination necessary, tell user where we are $param = array('{FIRST}' => strval($offset + 1), '{LAST}' => strval(min($num_messages, $offset + $limit)), '{TOTAL}' => strval($num_messages)); $header = '<h2>' . t('menu_logview', 'admin') . ' ' . t('pagination_count_of_total', 'admin', $param) . '</h2>'; $parameters = array('job' => JOB_TOOLS, 'task' => TASK_LOGVIEW); $output->add_pagination($WAS_SCRIPT_NAME, $parameters, $num_messages, $limit, $offset, $CFG->pagination_width); } // 4 -- retrieve the selected messages (including optional username via LEFT JOIN) $sql = sprintf('SELECT l.datim, l.remote_addr, l.priority, l.user_id, u.username, l.message ' . 'FROM %slog_messages l LEFT JOIN %susers u USING (user_id) ' . 'ORDER BY l.datim, l.log_message_id', $DB->prefix, $DB->prefix); if (($DBResult = $DB->query($sql, $limit, $offset)) === FALSE) { $output->add_message(t('logview_error', 'admin')); logger(sprintf('%s(): cannot retrieve log messages: %s', __FUNCTION__, db_errormessage())); return; } $records = $DBResult->fetch_all_assoc(); $DBResult->close(); // 5A -- setup a table with a header $index = $offset + 1; $output->add_content($header); $class = 'header'; $attributes = array('class' => $class, 'align' => 'right'); $output->add_content('<p>'); $output->add_content(html_table(array('cellpadding' => '3'))); $output->add_content(' ' . html_table_row($attributes)); $output->add_content(' ' . html_table_head($attributes, t('logview_nr', 'admin'))); $attributes['align'] = 'left'; $output->add_content(' ' . html_table_head($attributes, t('logview_datim', 'admin'))); $output->add_content(' ' . html_table_head($attributes, t('logview_remote_addr', 'admin'))); $output->add_content(' ' . html_table_head($attributes, t('logview_user_id', 'admin'))); $output->add_content(' ' . html_table_head($attributes, t('logview_priority', 'admin'))); $output->add_content(' ' . html_table_head($attributes, t('logview_message', 'admin'))); $output->add_content(' ' . html_table_row_close()); // 5B -- step through the recordset and dump into the table foreach ($records as $record) { $class = $class == 'odd' ? 'even' : 'odd'; $priority = isset($priorities[$record['priority']]) ? $priorities[$record['priority']] : strval(intval($record['priority'])); $attributes = array('class' => $class); $output->add_content(' ' . html_table_row($attributes)); $attributes['align'] = 'right'; $output->add_content(' ' . html_table_cell($attributes, strval($index++))); $attributes['align'] = 'left'; $output->add_content(' ' . html_table_cell($attributes, htmlspecialchars($record['datim']))); $output->add_content(' ' . html_table_cell($attributes, htmlspecialchars($record['remote_addr']))); $output->add_content(' ' . html_table_cell($attributes, htmlspecialchars($record['username']))); $output->add_content(' ' . html_table_cell($attributes, $priority)); $output->add_content(' ' . html_table_cell($attributes, htmlspecialchars($record['message']))); $output->add_content(' ' . html_table_row_close()); } // 5C -- all done $output->add_content(html_table_close()); $output->add_content('<p>'); }
/** handle the editing/saving of the main configuration information * * this routine handles editing of the main configuration parameters. * It either displays the edit dialog or saves the modified data and * shows the configuration manager introduction screen. * * Note that we do NOT try to redirect the user via a header() after * a succesful save. It would be handy because this particular * save action may have had impact on the global configuration, * which is already read at this point. By redirecting we would * make a fresh start, with the new parameters. * However, we lose the easy ability to tell the user that the data * was saved (via $output->add_message()). So, either no feedback * or obsolete global config in core. Hmmmm. I settle for the feedback * and the 'wrong' settings. * * @param object &$output collects the html output * @return void results are returned as output in $output * @uses ConfigAssistant() */ function modulemanager_process(&$output, $task) { global $CFG, $WAS_SCRIPT_NAME; // 0 -- sanity check $modules = modulemanager_get_modules(); $module_id = get_parameter_int('module', 0); if (!isset($modules[$module_id])) { logger(sprintf('%s(): unknown module; id = %d', __FUNCTION__, $module_id)); $output->add_message(t('error_invalid_parameters', 'admin')); modulemanager_show_intro($output); modulemanager_show_menu($output); return; } // 1 -- prepare include_once $CFG->progdir . '/lib/configassistant.class.php'; $table = 'modules_properties'; $keyfield = 'module_property_id'; $prefix = 'config_'; $domain = 'm_' . $modules[$module_id]['name']; $where = array('module_id' => $module_id); $assistant = new ConfigAssistant($table, $keyfield, $prefix, $domain, $where); $href = href($WAS_SCRIPT_NAME, array('job' => JOB_MODULEMANAGER, 'task' => TASK_MODULEMANAGER_SAVE, 'module' => $module_id)); // 2 -- what do we need to do? if ($task == TASK_MODULEMANAGER_SAVE) { // save data (or cancel if they want to cancel) if (isset($_POST['button_save'])) { if ($assistant->save_data($output)) { modulemanager_show_intro($output); modulemanager_show_menu($output, $module_id); } else { $output->add_content('<h2>' . t($prefix . 'header', $domain) . '</h2>'); $output->add_content(t($prefix . 'explanation', $domain)); $assistant->show_dialog($output, $href); } } else { $output->add_message(t('cancelled', 'admin')); modulemanager_show_intro($output); modulemanager_show_menu($output, $module_id); } } else { // no save yet, simply show dialog $output->add_content('<h2>' . t($prefix . 'header', $domain) . '</h2>'); $output->add_content(t($prefix . 'explanation', $domain)); $assistant->show_dialog($output, $href); modulemanager_show_menu($output, $module_id); } }
/** show confirmation dialog for multiple file delete OR perform actual file delete * * this routine either shows a list of files to be deleted, asking the user for confirmation * or actually deletes the specified files if the user did confirm the delete. * We bail out if the user pressed the cancel button in the confirmation dialog. * The real work is done in workhorse routines in order to combine the single-file-delete * and the batch-delete into a single confirmation routine. For actual deletion, however, * we always return here and not in the single file delete (see {$link task_remove_file()}). * * @uses show_dialog_confirm_delete_files() * @return void output sent to browser via $this->output and perhaps files deleted */ function task_remove_multiple_files() { // 0 -- essential sanity check alias change directory $newdir = get_parameter_string(PARAM_PATH, $this->current_directory); if (($path = $this->valid_path($newdir)) === FALSE) { $this->output->add_message(t('invalid_path', 'admin', array('{PATH}' => htmlspecialchars($newdir)))); $this->task_list_directory(); return; } $this->current_directory = $path; $this->sort = get_parameter_int(PARAM_SORT, SORTBY_FILE_ASC); // 1 -- do they want to bail out? if (isset($_POST['button_cancel'])) { $this->output->add_message(t('cancelled', 'admin')); $this->task_list_directory(); return; } // 2 -- construct a list of files to delete $entries = $this->get_entries($path); $n = isset($_POST[PARAM_FILENAMES]) ? intval($_POST[PARAM_FILENAMES]) : 0; $entries_to_delete = array(); for ($i = 0; $i < $n; ++$i) { $fieldname = sprintf('%s%d', PARAM_FILENAME, $i); if (isset($_POST[$fieldname])) { $filename = magic_unquote($_POST[$fieldname]); if (isset($entries[$filename]) && $entries[$filename]['is_file']) { $entries_to_delete[$filename] = $entries[$filename]; } else { logger(sprintf('%s.%s(): weird attempt to delete %s/%s', __CLASS__, __FUNCTION__, $path, $filename)); } } } // 3 -- what needs to be done? $n = count($entries_to_delete); // 3A -- nothing to do if ($n <= 0) { $this->output->add_message(t('filemanager_nothing_to_delete', 'admin')); $this->task_list_directory(); return; } if ($n == 1) { $entry = reset($entries_to_delete); $params = array('{FILENAME}' => $entry['vpath']); } else { $params = array('{COUNT}' => strval($n)); } // 3B -- confirmation dialog or actual deletion? if (isset($_POST['confirm']) && intval($_POST['confirm']) != 0) { if ($this->delete_files($path, $entries_to_delete) === FALSE) { $this->output->add_message(t($n == 1 ? 'filemanager_failure_delete_file' : 'filemanager_failure_delete_files', 'admin', $params)); } else { $this->output->add_message(t($n == 1 ? 'filemanager_success_delete_file' : 'filemanager_success_delete_files', 'admin', $params)); } $this->task_list_directory(); } else { $this->show_dialog_confirm_delete_files($path, $entries_to_delete); } }
/** validate and save modified data to database * * this saves data from both the edit and the edit theme dialog if data validates. * If the data does NOT validate, the edit screen is displayed again * otherwise the area overview is displayed again. * * @return void results are returned as output in $this->output * @uses $WAS_SCRIPT_NAME * @uses $CFG * @uses $USER */ function area_save() { global $CFG, $WAS_SCRIPT_NAME, $USER; $area_id = get_parameter_int('area', 0); $areas = get_area_records(); // 0 - basic sanity if ($areas === FALSE || !isset($areas[$area_id])) { // are they trying to trick us, specifying an invalid area? logger("areamanager: weird: user tried to save data to non-existing area '{$area_id}'"); $this->output->add_message(t('invalid_area', 'admin', array('{AREA}' => strval($area_id)))); $this->area_overview(); return; } // 1 -- are we allowed to perform the edit and thus the save operation? if (!$USER->has_area_permissions(PERMISSION_AREA_EDIT_AREA, $area_id)) { logger("areamanager: user attempted to save data to area '{$area_id}' without permission"); $msg = t('icon_area_edit_access_denied', 'admin'); $this->output->add_message($msg); $this->output->add_popup_bottom($msg); $this->area_overview(); return; } // 2 -- if the user cancelled the operation, there is no point in hanging 'round if (isset($_POST['button_cancel'])) { $this->output->add_message(t('cancelled', 'admin')); $this->area_overview(); return; } // 3 -- we need to know which dialog we're dealing with if (!isset($_POST['dialog'])) { logger("areamanager: weird: 'dialog' not set in area_save() (area='{$area_id}')", WLOG_DEBUG); $this->area_overview(); return; } $dialog = intval($_POST['dialog']); if ($dialog == AREAMANAGER_DIALOG_EDIT_THEME) { $theme_id = $areas[$area_id]['theme_id']; $themes = $this->get_theme_records(); $theme_name = $themes[$theme_id]['name']; include_once $CFG->progdir . '/lib/configassistant.class.php'; $table = 'themes_areas_properties'; $keyfield = 'theme_area_property_id'; $prefix = ''; $language_domain = 't_' . $theme_name; $where = array('area_id' => $area_id, 'theme_id' => $theme_id); $hidden_fields = array(array('type' => F_INTEGER, 'name' => 'dialog', 'value' => AREAMANAGER_DIALOG_EDIT_THEME, 'hidden' => TRUE)); $assistant = new ConfigAssistant($table, $keyfield, $prefix, $language_domain, $where, $hidden_fields); if (!$assistant->save_data($this->output)) { $href = href($WAS_SCRIPT_NAME, $this->a_param(AREAMANAGER_CHORE_SAVE, $area_id)); $assistant->show_dialog($this->output, $href); // since they blew it, we will not show the edit menu at this point; // user should concentrate on getting input data right (or use cancel) } else { $this->area_overview(); } } elseif ($dialog == AREAMANAGER_DIALOG_EDIT) { $dialogdef = $this->get_dialogdef_edit_area($area_id); if (!dialog_validate($dialogdef)) { // there were errors, show them to the user and do it again foreach ($dialogdef as $k => $item) { if (isset($item['errors']) && $item['errors'] > 0) { $this->output->add_message($item['error_messages']); } } $this->output->add_content('<h2>' . t('areamanager_edit_area_header', 'admin') . '</h2>'); $this->output->add_content(t('areamanager_edit_area_explanation', 'admin')); $href = href($WAS_SCRIPT_NAME, $this->a_param(AREAMANAGER_CHORE_SAVE, $area_id)); $this->output->add_content(dialog_quickform($href, $dialogdef)); // no edit menu, let user concentrate on task at hand ie errorfree data input return; } $now = strftime('%Y-%m-%d %T'); $fields = array('mtime' => $now, 'muser_id' => $USER->user_id); $theme_id = 0; foreach ($dialogdef as $k => $item) { if (isset($item['name'])) { switch ($item['name']) { case 'area_title': $fields['title'] = $item['value']; break; // This field should not be editable and thus should not be saved //case 'area_is_private': // $fields['is_private'] = ($item['value'] == 1) ? TRUE : FALSE; // break; // This field should not be editable and thus should not be saved //case 'area_is_private': // $fields['is_private'] = ($item['value'] == 1) ? TRUE : FALSE; // break; case 'area_is_active': $fields['is_active'] = $item['value'] == 1 ? TRUE : FALSE; break; case 'area_theme_id': $theme_id = intval($item['value']); $fields['theme_id'] = $theme_id; break; // This field should not be editable and thus should not be saved //case 'area_path': // $fields['path'] = $item['value']; // break; // This field should not be editable and thus should not be saved //case 'area_path': // $fields['path'] = $item['value']; // break; case 'area_metadata': $fields['metadata'] = $item['value']; break; case 'area_sort_order': $fields['sort_order'] = intval($item['value']); break; default: break; } } } $where = array('area_id' => $area_id); $params = array('{AREA}' => $area_id, '{AREA_FULL_NAME}' => $fields['title']); if (db_update('areas', $fields, $where) === FALSE) { logger("areamanager: area data save failed for area '{$area_id}': " . db_errormessage()); $this->output->add_message(t('areamanager_save_area_failure', 'admin', $params)); } elseif (intval($areas[$area_id]['theme_id']) != $theme_id && $this->count_existing_theme_properties($area_id, $theme_id) <= 0) { // If the user changed the theme AND if there is no theme config yet, make sure there is one if ($this->reset_theme_defaults($area_id, $theme_id)) { logger("areamanager: success saving area AND theme properties in area '{$area_id}', theme '{$theme_id}'", WLOG_DEBUG); $this->output->add_message(t('areamanager_save_area_success', 'admin', $params)); } else { logger("areamanager: theme '{$theme_id}' data save failed for area '{$area_id}': " . db_errormessage()); $this->output->add_message(t('areamanager_save_area_failure', 'admin', $params)); } } else { logger("areamanager: success saving changed properties in area '{$area_id}'", WLOG_DEBUG); $this->output->add_message(t('areamanager_save_area_success', 'admin', $params)); } $areas = get_area_records(TRUE); // TRUE means force reread of area records $this->area_overview(); } else { logger("areamanager: weird: invalid dialog '{$dialog}' in area_save (area={$area_id})", WLOG_DEBUG); $this->area_overview(); } }
function task_save_content() { global $USER; // 1A -- do we have a sane value for node_id? $node_id = get_parameter_int('node', 0); $anode = array('{NODE}' => strval($node_id)); if ($node_id == 0 || !isset($this->tree[$node_id])) { // are they trying to trick us, specifying a node from another area? logger(__FUNCTION__ . "(): weird: user saves content of node '{$node_id}' working in area '{$this->area_id}'?"); $this->output->add_message(t('invalid_node', 'admin', $anode)); $this->task_treeview(); return; } // 1B -- is it a page? if (!$this->tree[$node_id]['is_page']) { logger(__CLASS__ . ": weird: cannot save content of a section (section '{$node_id}')"); $this->task_treeview(); return; } // 2 -- are we allowed? if (!$this->permission_edit_node_content($node_id)) { $msg = t('task_edit_page_access_denied', 'admin', array('{NODE}' => $node_id)); $this->output->add_message($msg); $this->output->add_popup_bottom($msg); $this->show_tree(); $this->show_area_menu($this->area_id); return; } // 3 -- make certain we still have the lock $lockinfo = array(); if (!lock_record_node($node_id, $lockinfo)) { // failed to get a lock, tell user about who DID obtain the lock + show tree again $is_page = TRUE; $msg = message_from_lockinfo($lockinfo, $node_id, $is_page); $this->output->add_message($msg); $this->output->add_popup_bottom($msg); $this->show_tree(); $this->show_area_menu($this->area_id); return; } // 4 -- execute module save function $module_id = intval($this->tree[$node_id]['record']['module_id']); $viewonly = db_bool_is(TRUE, $this->tree[$node_id]['record']['is_readonly']); if ($this->module_save($node_id, $module_id, $viewonly, $edit_again)) { // success with save, bye now lock_release_node($node_id); $anode = array('{NODE_FULL_NAME}' => $this->node_full_name($node_id)); $msg = t('page_saved', 'admin', $anode); $this->output->add_message($msg); $this->show_tree(); $this->show_area_menu($this->area_id); $embargo = is_under_embargo($this->tree, $node_id); logger(sprintf(__CLASS__ . ": success saving content node '%d'%s", $node_id, $embargo ? ' (embargo)' : '')); if (!$embargo) { $nodes = $this->get_node_id_and_ancestors($node_id); $anode['{AREA}'] = $this->area_id; $message = t('page_content_edited', 'admin', $anode); $this->queue_area_node_alert($this->area_id, $nodes, $message, $USER->full_name); } } elseif ($edit_again) { if ($this->module_show_edit($node_id, $module_id, $viewonly, $edit_again)) { $this->output->set_funnel_mode(TRUE); // no distractions // Note that we also do NOT show the edit menu: we try to let the user concentrate // on the task at hand; the only escape route is 'Cancel'... // Also note that we still have the record lock; that won't change because we // will be editing the page again. Cancel'ing will also release the lock. } else { lock_release_node($node_id); $anode = array('{NODE_FULL_NAME}' => $this->node_full_name($node_id)); $msg = t('error_editing_node_content', 'admin', $anode); $this->output->add_message($msg); $this->output->add_popup_bottom($msg); $this->show_tree(); $this->show_area_menu($this->area_id); } } else { // operation is cancelled lock_release_node($node_id); $this->output->add_message(t('cancelled', 'admin')); $this->show_tree(); $this->show_area_menu($this->area_id); } return; }
/** add javascript code that implements a url selection (used in integration with CKEditor/FCKeditor) * * This adds a JavaScript-function to the currently generated output page * which takes care of returning a URL from a file/image/flash browser * to either the (older) FCKeditor or (newer) CKEditor. Since both editors * use the same filebrowsers we need to discriminate betweek FCKeditor and * CKEditor. This is done by looking at the parameters: the CKEditor provides * the number of an anonymous function in the parameter 'CKEditorFuncNum'. * If this parameter is set we use the (integer) value for the callback to * CKEditor. If it is not set we assume the old interface with FCKeditor. * * Note that our actual file browser is supposed to remember this parameter, * otherwise the file browser will assume FCKeditor after navigating to * another page within the file browser. See also {@link filemanager.class.php} * We remember the parameter via a session variable which is easier than * propagating this number by adding it to every link within the file browser. * However, we do update this function number every time the parameter * 'CKEditorFuncNum' is specified, ie. on the first call to a file browser * from CKEditor, ie. whenerver the user starts browsing the server. * * @param object &$output collects the html output * @param string $m left margin for increased readability * @return void generated JavaScript-code added to HTML-headers */ function add_javascript_select_url_function(&$output, $m = '') { $funcnum = get_parameter_int('CKEditorFuncNum'); if (!is_null($funcnum)) { $_SESSION['CKEditorFuncNum'] = $funcnum; } elseif (isset($_SESSION['CKEditorFuncNum'])) { $funcnum = $_SESSION['CKEditorFuncNum']; } $javascript_code = array('<script type="text/javascript"><!--', ' function select_url(url) {', is_null($funcnum) ? ' window.opener.SetUrl(url);' : sprintf(' window.opener.CKEDITOR.tools.callFunction(%d, url);', $funcnum), ' window.close();', ' }', ' //--></script>'); foreach ($javascript_code as $line) { $output->add_html_header($m . $line); } return; }
/** save the modified content data of this module linked to node $node_id * * this validates and saves the data that was submitted by the user. * * See also {@link mailpage_show_edit()} for the complications of having a single * routine to deal with two different dialogs. * If validation of dialog 1 fails, or storing the data doesn't work, * the flag $edit_again is set to TRUE and the return value is FALSE. * Validation and storage of data from dialog 2 _always_ returns $edit_again * TRUE because we want to return in dialog #1 after finishing dialog #2. * * If the user has cancelled the operation, the flag $edit_again is set to FALSE * and the return value is also FALSE. * * If the modified data is stored successfully, the return value is TRUE (and * the value of $edit_again is a don't care). Note that this also only applies * to the main dialoag (dialog #1). * * Here is a summary of return values. * * - retval = TRUE ==> data saved successfully * - retval = FALSE && edit_again = TRUE ==> re-edit the data, show the edit dialog again * - retval = FALSE && edit_again = FALSE ==> cancelled, do nothing * * @param object &$output collects the html output (if any) * @param int $area_id the area in which $node_id resides * @param int $node_id the node to which the content is connected * @param array $module the module record straight from the database * @param bool $viewonly if TRUE, editing and hence saving is not allowed * @param bool &$edit_again set to TRUE if we need to edit the content again, FALSE otherwise * @return bool TRUE on success + output stored via $output, FALSE otherwise */ function mailpage_save(&$output, $area_id, $node_id, $module, $viewonly, &$edit_again) { global $USER; $node_id = intval($node_id); $addresses = mailpage_get_addresses($node_id); $sort_order = 10 * (1 + sizeof($addresses)); // $addresses are always renumbered so this is the first largest sord_order $address_id = get_parameter_int('address', NULL); if (is_null($address_id)) { // main config needs to be saved $edit_again = FALSE; // assume we do NOT need to edit again // 1 -- bail out if cancelled or viewonly if (isset($_POST['button_cancel']) || $viewonly) { return FALSE; } // 2 -- redo if invalid data was submitted $dialogdef = mailpage_get_dialogdef_config($output, $viewonly, $node_id); if (!mailpage_dialog_validate($dialogdef, $node_id, $addresses)) { // there were errors, show them to the user and do it again foreach ($dialogdef as $k => $item) { if (isset($item['errors']) && $item['errors'] > 0) { $output->add_message($item['error_messages']); } } $edit_again = TRUE; return FALSE; } // 3 -- actually save the settings $retval = TRUE; // assume success $now = strftime('%Y-%m-%d %T'); $table = 'mailpages'; $fields = array('header' => trim($dialogdef['header']['value']), 'introduction' => trim($dialogdef['introduction']['value']), 'message' => trim($dialogdef['message']['value']), 'mtime' => $now, 'muser_id' => $USER->user_id); $where = array('node_id' => $node_id); if (db_update($table, $fields, $where) === FALSE) { logger(sprintf('%s(): error saving config values: %s', __FUNCTION__, db_errormessage())); $edit_again = TRUE; $retval = FALSE; $output->add_message(t('error_saving_data', 'm_mailpage')); } return $retval; } // // At this point we need to either save a new record, update an existing record, // delete an existing record or simply cancel and return to the main config dialog. // The logic depends on the submit button that was used and the value of $address_id. // $dialogdef = mailpage_get_dialogdef_address($output, $viewonly, $node_id, $address_id, $sort_order); if (!dialog_validate($dialogdef, $node_id, $addresses)) { // there were errors, show them to the user and do it again foreach ($dialogdef as $k => $item) { if (isset($item['errors']) && $item['errors'] > 0) { $output->add_message($item['error_messages']); } } $edit_again = TRUE; return FALSE; } $edit_again = TRUE; // we abuse this flag to return to the main config dialog instead of page mgr if (isset($_POST['button_cancel']) || $viewonly) { return FALSE; } $table = 'mailpages_addresses'; $fields = array('node_id' => $node_id, 'sort_order' => intval($dialogdef['sort_order']['value']), 'name' => trim($dialogdef['name']['value']), 'email' => trim($dialogdef['email']['value']), 'description' => trim($dialogdef['description']['value']), 'thankyou' => trim($dialogdef['thankyou']['value'])); if ($address_id <= 0) { // new record needs to be saved. if (db_insert_into($table, $fields) === FALSE) { logger(sprintf('%s(): error adding address: %s', __FUNCTION__, db_errormessage())); $output->add_message(t('error_saving_data', 'm_mailpage')); } } elseif (isset($addresses[$address_id])) { // OK, that is an existing record $where = array('mailpage_address_id' => $address_id); if (isset($_POST['button_save'])) { // Go save the record if (db_update($table, $fields, $where) === FALSE) { logger(sprintf('%s(): error updating address: %s', __FUNCTION__, db_errormessage())); $output->add_message(t('error_saving_data', 'm_mailpage')); } } elseif (isset($_POST['button_delete'])) { // Go delete this record if (db_delete($table, $where) === FALSE) { logger(sprintf('%s(): error deleting address: %s', __FUNCTION__, db_errormessage())); $output->add_message(t('error_deleting_data', 'm_mailpage')); } } } return FALSE; // Dirty trick to return to the main config dialog }
/** show a dialog for modifying page manager permissions for a group/capacity * * @return void results are returned as output in $this->output * @uses $WAS_SCRIPT_NAME * @uses $CFG */ function capacity_pagemanager() { global $WAS_SCRIPT_NAME, $CFG; $group_id = get_parameter_int('group', NULL); $capacity_code = get_parameter_int('capacity', NULL); // 0 -- sanity check if (!$this->valid_group_capacity($group_id, $capacity_code)) { $this->groups_overview(); return; } // 1 -- maybe change the state of the open/closed areas if (!isset($_SESSION['aclmanager_open_areas'])) { $_SESSION['aclmanager_open_areas'] = FALSE; // default: everything is closed } $area_id = get_parameter_int('area', NULL); $_SESSION['aclmanager_open_areas'] = $this->areas_expand_collapse($_SESSION['aclmanager_open_areas'], $area_id); // 2 -- which acl to use? if (($acl_id = $this->calc_acl_id($group_id, $capacity_code)) === FALSE) { $this->capacity_overview(); return; } // // 3A -- construct necessary parameters for dialog // $a_params = $this->a_params(TASK_GROUP_CAPACITY_SAVE, $group_id, $capacity_code); $limit = get_parameter_int('limit', $CFG->pagination_height); $offset = get_parameter_int('offset', 0); if ($limit != $CFG->pagination_height) { $a_params['limit'] = $limit; } if ($offset != 0) { $a_params['offset'] = $offset; } // // 3B -- setup Aclmanager to do the dirty work // include_once $CFG->progdir . '/lib/aclmanager.class.php'; $acl = new AclManager($this->output, $acl_id, ACL_TYPE_PAGEMANAGER); $acl->set_action($a_params); $params = $this->get_group_capacity_names($group_id, $capacity_code); $acl->set_header(t('groupmanager_capacity_pagemanager_header', 'admin', $params)); $acl->set_intro(t('groupmanager_capacity_pagemanager_explanation', 'admin', $params)); $acl->set_dialog(GROUPMANAGER_DIALOG_CAPACITY_PAGEMANAGER); // Enable pagination for this one: the list of nodes can be very very long so split up in smaller screens. $a_params = $this->a_params(TASK_GROUP_CAPACITY_PAGEMANAGER, $group_id, $capacity_code); $acl->enable_pagination($a_params, $limit, $offset); // Also enable the expand/collapse feature $acl->enable_area_view($a_params, $_SESSION['aclmanager_open_areas']); // // 4 -- show dialog + menu // $acl->show_dialog(); $this->show_menu_groupcapacity($group_id, $capacity_code, TASK_GROUP_CAPACITY_PAGEMANAGER); }
/** get the number of the area the user requested or null if not specified * * See discussion of {@link get_requested_node()}. * * @return int|null integer indicating the area or null if none specified */ function get_requested_area() { return get_parameter_int('area', NULL); }
/** show a dialog for modifying page manager permissions for a user * * @return void results are returned as output in $this->output * @uses $WAS_SCRIPT_NAME * @uses $CFG */ function user_pagemanager() { global $WAS_SCRIPT_NAME, $CFG; // // 0 -- sanity check // $user_id = get_parameter_int('user', NULL); if (is_null($user_id)) { logger("usermanager->user_pagemanager(): unspecified parameter user"); $this->output->add_message(t('error_invalid_parameters', 'admin')); $this->users_overview(); return; } // // 1 -- maybe change the state of the open/closed areas // if (!isset($_SESSION['aclmanager_open_areas'])) { $_SESSION['aclmanager_open_areas'] = FALSE; // default: everything is closed } $area_id = get_parameter_int('area', NULL); $_SESSION['aclmanager_open_areas'] = $this->areas_expand_collapse($_SESSION['aclmanager_open_areas'], $area_id); // // 2 -- which acl to use? // if (($acl_id = $this->calc_acl_id($user_id)) === FALSE) { $this->user_edit(); return; } // // 3A -- construct necessary parameters for dialog // $related_acls = calc_user_related_acls($user_id); $a_params = $this->a_params(TASK_USER_SAVE, $user_id); $params = $this->get_user_names($user_id); $limit = get_parameter_int('limit', $CFG->pagination_height); $offset = get_parameter_int('offset', 0); if ($limit != $CFG->pagination_height) { $a_params['limit'] = $limit; } if ($offset != 0) { $a_params['offset'] = $offset; } // // 3B -- setup Aclmanager to do the dirty work // include_once $CFG->progdir . '/lib/aclmanager.class.php'; $acl = new AclManager($this->output, $acl_id, ACL_TYPE_PAGEMANAGER); $acl->set_related_acls($related_acls); $acl->set_action($a_params); $acl->set_header(t('usermanager_pagemanager_header', 'admin', $params)); $acl->set_intro(t('usermanager_pagemanager_explanation', 'admin', $params)); $acl->set_dialog(USERMANAGER_DIALOG_PAGEMANAGER); // Enable pagination for this one: the list of nodes can be very very long so split up in smaller screens. $a_params = $this->a_params(TASK_USER_PAGEMANAGER, $user_id); $acl->enable_pagination($a_params, $limit, $offset); // Also enable the expand/collapse feature $acl->enable_area_view($a_params, $_SESSION['aclmanager_open_areas']); // // 4 -- show dialog + menu // $acl->show_dialog(); $this->show_menu_user($user_id, TASK_USER_PAGEMANAGER); }
/** task dispatcher * * this routine decides what to do and calls the appropriate workhorse routine(s) * * @return bool TRUE on success, FALSE otherwise * @todo check permissions (ACL) to prevent leaking a private area path to anonymous visitors? */ function run() { global $CFG; $m = ' '; // 1 -- determine the directory path and other configuration information $this->get_snapshots_configuration($this->node_id); // 2A -- get a list of available files from $snapshots_path $this->snapshots = $this->get_snapshots($this->snapshots_path); $snapshots_count = sizeof($this->snapshots); // 2B -- if there are none we bail out but DO show the header+introduction if ($snapshots_count <= 0) { if (!empty($this->header)) { $this->theme->add_content($m . html_tag('h3', array('class' => 'snapshots_header'), $this->header)); } if (!empty($this->introduction)) { $this->theme->add_content($m . html_tag('div', array('class' => 'snapshots_introduction'), $this->introduction)); } $msg = t('no_snapshots_available', $this->domain); $this->theme->add_message($msg); $this->theme->add_content($m . '<h3>' . $msg . '</h3>'); return TRUE; } // 3A -- get ready to do some real work $stylesheet = 'program/modules/snapshots/snapshots.css'; $this->theme->add_stylesheet($stylesheet); $this->javascript_include_once('/modules/snapshots/slideshow.js'); $this->javascript_add_img_array(); // 3B -- what do they want? $snapshot_index = get_parameter_int('snapshot', NULL); if (!is_null($snapshot_index) && 0 < $snapshot_index && $snapshot_index <= $snapshots_count) { $retval = $this->view_snapshot($snapshot_index); } else { // if no specific image was specified, we allow the user to choose the variant, // while using the value from the database as a (sensible) default. $variant = get_parameter_int('variant', $this->variant); switch ($variant) { case 1: $retval = $this->view_thumbnails(); break; case 2: $retval = $this->view_snapshot(1); break; case 3: $retval = $this->view_slideshow(); break; default: $retval = $this->view_thumbnails(); // shouldn't happen break; } } return $retval; }