require_capability('moodle/course:manageactivities', $context); require_capability('mod/lti:addcoursetool', $context); $redirecturl = null; $returndata = null; if (empty($errormsg) && !empty($items)) { try { $returndata = lti_tool_configuration_from_content_item($id, $messagetype, $version, $consumerkey, $items); } catch (moodle_exception $e) { $errormsg = $e->getMessage(); } } $pageurl = new moodle_url('/mod/lti/contentitem_return.php'); $PAGE->set_url($pageurl); $PAGE->set_pagelayout('popup'); echo $OUTPUT->header(); // Call JS module to redirect the user to the course page or close the dialogue on error/cancel. $PAGE->requires->js_call_amd('mod_lti/contentitem_return', 'init', [$returndata]); echo $OUTPUT->footer(); // Add messages to notification stack for rendering later. if ($errormsg) { // Content item selection has encountered an error. \core\notification::error($errormsg); } else { if (!empty($returndata)) { // Means success. if (!$msg) { $msg = get_string('successfullyfetchedtoolconfigurationfromcontent', 'lti'); } \core\notification::success($msg); } }
/** * Returns course-specific information to be output immediately above content on any course page * (for the current course) * * @param bool $onlyifnotcalledbefore output content only if it has not been output before * @return string */ public function course_content_header($onlyifnotcalledbefore = false) { global $CFG; static $functioncalled = false; if ($functioncalled && $onlyifnotcalledbefore) { // we have already output the content header return ''; } // Output any session notification. $notifications = \core\notification::fetch(); $bodynotifications = ''; foreach ($notifications as $notification) { $bodynotifications .= $this->render_from_template($notification->get_template_name(), $notification->export_for_template($this)); } $output = html_writer::span($bodynotifications, 'notifications', array('id' => 'user-notifications')); if ($this->page->course->id == SITEID) { // return immediately and do not include /course/lib.php if not necessary return $output; } require_once $CFG->dirroot . '/course/lib.php'; $functioncalled = true; $courseformat = course_get_format($this->page->course); if (($obj = $courseformat->course_content_header()) !== null) { $output .= html_writer::div($courseformat->get_renderer($this->page)->render($obj), 'course-content-header'); } return $output; }
/** * Redirects the user to another page, after printing a notice. * * This function calls the OUTPUT redirect method, echo's the output and then dies to ensure nothing else happens. * * <strong>Good practice:</strong> You should call this method before starting page * output by using any of the OUTPUT methods. * * @param moodle_url|string $url A moodle_url to redirect to. Strings are not to be trusted! * @param string $message The message to display to the user * @param int $delay The delay before redirecting * @param string $messagetype The type of notification to show the message in. See constants on \core\output\notification. * @throws moodle_exception */ function redirect($url, $message='', $delay=null, $messagetype = \core\output\notification::NOTIFY_INFO) { global $OUTPUT, $PAGE, $CFG; if (CLI_SCRIPT or AJAX_SCRIPT) { // This is wrong - developers should not use redirect in these scripts but it should not be very likely. throw new moodle_exception('redirecterrordetected', 'error'); } if ($delay === null) { $delay = -1; } // Prevent debug errors - make sure context is properly initialised. if ($PAGE) { $PAGE->set_context(null); $PAGE->set_pagelayout('redirect'); // No header and footer needed. $PAGE->set_title(get_string('pageshouldredirect', 'moodle')); } if ($url instanceof moodle_url) { $url = $url->out(false); } $debugdisableredirect = false; do { if (defined('DEBUGGING_PRINTED')) { // Some debugging already printed, no need to look more. $debugdisableredirect = true; break; } if (core_useragent::is_msword()) { // Clicking a URL from MS Word sends a request to the server without cookies. If that // causes a redirect Word will open a browser pointing the new URL. If not, the URL that // was clicked is opened. Because the request from Word is without cookies, it almost // always results in a redirect to the login page, even if the user is logged in in their // browser. This is not what we want, so prevent the redirect for requests from Word. $debugdisableredirect = true; break; } if (empty($CFG->debugdisplay) or empty($CFG->debug)) { // No errors should be displayed. break; } if (!function_exists('error_get_last') or !$lasterror = error_get_last()) { break; } if (!($lasterror['type'] & $CFG->debug)) { // Last error not interesting. break; } // Watch out here, @hidden() errors are returned from error_get_last() too. if (headers_sent()) { // We already started printing something - that means errors likely printed. $debugdisableredirect = true; break; } if (ob_get_level() and ob_get_contents()) { // There is something waiting to be printed, hopefully it is the errors, // but it might be some error hidden by @ too - such as the timezone mess from setup.php. $debugdisableredirect = true; break; } } while (false); // Technically, HTTP/1.1 requires Location: header to contain the absolute path. // (In practice browsers accept relative paths - but still, might as well do it properly.) // This code turns relative into absolute. if (!preg_match('|^[a-z]+:|i', $url)) { // Get host name http://www.wherever.com. $hostpart = preg_replace('|^(.*?[^:/])/.*$|', '$1', $CFG->wwwroot); if (preg_match('|^/|', $url)) { // URLs beginning with / are relative to web server root so we just add them in. $url = $hostpart.$url; } else { // URLs not beginning with / are relative to path of current script, so add that on. $url = $hostpart.preg_replace('|\?.*$|', '', me()).'/../'.$url; } // Replace all ..s. while (true) { $newurl = preg_replace('|/(?!\.\.)[^/]*/\.\./|', '/', $url); if ($newurl == $url) { break; } $url = $newurl; } } // Sanitise url - we can not rely on moodle_url or our URL cleaning // because they do not support all valid external URLs. $url = preg_replace('/[\x00-\x1F\x7F]/', '', $url); $url = str_replace('"', '%22', $url); $encodedurl = preg_replace("/\&(?![a-zA-Z0-9#]{1,8};)/", "&", $url); $encodedurl = preg_replace('/^.*href="([^"]*)".*$/', "\\1", clean_text('<a href="'.$encodedurl.'" />', FORMAT_HTML)); $url = str_replace('&', '&', $encodedurl); if (!empty($message)) { if (!$debugdisableredirect && !headers_sent()) { // A message has been provided, and the headers have not yet been sent. // Display the message as a notification on the subsequent page. \core\notification::add($message, $messagetype); $message = null; $delay = 0; } else { if ($delay === -1 || !is_numeric($delay)) { $delay = 3; } $message = clean_text($message); } } else { $message = get_string('pageshouldredirect'); $delay = 0; } // Make sure the session is closed properly, this prevents problems in IIS // and also some potential PHP shutdown issues. \core\session\manager::write_close(); if ($delay == 0 && !$debugdisableredirect && !headers_sent()) { // 302 might not work for POST requests, 303 is ignored by obsolete clients. @header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other'); @header('Location: '.$url); echo bootstrap_renderer::plain_redirect_message($encodedurl); exit; } // Include a redirect message, even with a HTTP redirect, because that is recommended practice. if ($PAGE) { $CFG->docroot = false; // To prevent the link to moodle docs from being displayed on redirect page. echo $OUTPUT->redirect_message($encodedurl, $message, $delay, $debugdisableredirect, $messagetype); exit; } else { echo bootstrap_renderer::early_redirect_message($encodedurl, $message, $delay); exit; } }
/** * Prints the page headers, breadcrumb trail, page heading, (optional) dropdown navigation menu and * (optional) navigation tabs for any gradebook page. All gradebook pages MUST use these functions * in favour of the usual print_header(), print_header_simple(), print_heading() etc. * !IMPORTANT! Use of tabs.php file in gradebook pages is forbidden unless tabs are switched off at * the site level for the gradebook ($CFG->grade_navmethod = GRADE_NAVMETHOD_DROPDOWN). * * @param int $courseid Course id * @param string $active_type The type of the current page (report, settings, * import, export, scales, outcomes, letters) * @param string $active_plugin The plugin of the current page (grader, fullview etc...) * @param string $heading The heading of the page. Tries to guess if none is given * @param boolean $return Whether to return (true) or echo (false) the HTML generated by this function * @param string $bodytags Additional attributes that will be added to the <body> tag * @param string $buttons Additional buttons to display on the page * @param boolean $shownavigation should the gradebook navigation drop down (or tabs) be shown? * @param string $headerhelpidentifier The help string identifier if required. * @param string $headerhelpcomponent The component for the help string. * @param stdClass $user The user object for use with the user context header. * * @return string HTML code or nothing if $return == false */ function print_grade_page_head($courseid, $active_type, $active_plugin=null, $heading = false, $return=false, $buttons=false, $shownavigation=true, $headerhelpidentifier = null, $headerhelpcomponent = null, $user = null) { global $CFG, $OUTPUT, $PAGE; // Put a warning on all gradebook pages if the course has modules currently scheduled for background deletion. require_once($CFG->dirroot . '/course/lib.php'); if (course_modules_pending_deletion($courseid)) { \core\notification::add(get_string('gradesmoduledeletionpendingwarning', 'grades'), \core\output\notification::NOTIFY_WARNING); } if ($active_type === 'preferences') { // In Moodle 2.8 report preferences were moved under 'settings'. Allow backward compatibility for 3rd party grade reports. $active_type = 'settings'; } $plugin_info = grade_get_plugin_info($courseid, $active_type, $active_plugin); // Determine the string of the active plugin $stractive_plugin = ($active_plugin) ? $plugin_info['strings']['active_plugin_str'] : $heading; $stractive_type = $plugin_info['strings'][$active_type]; if (empty($plugin_info[$active_type]->id) || !empty($plugin_info[$active_type]->parent)) { $title = $PAGE->course->fullname.': ' . $stractive_type . ': ' . $stractive_plugin; } else { $title = $PAGE->course->fullname.': ' . $stractive_plugin; } if ($active_type == 'report') { $PAGE->set_pagelayout('report'); } else { $PAGE->set_pagelayout('admin'); } $PAGE->set_title(get_string('grades') . ': ' . $stractive_type); $PAGE->set_heading($title); if ($buttons instanceof single_button) { $buttons = $OUTPUT->render($buttons); } $PAGE->set_button($buttons); if ($courseid != SITEID) { grade_extend_settings($plugin_info, $courseid); } // Set the current report as active in the breadcrumbs. if ($active_plugin !== null && $reportnav = $PAGE->settingsnav->find($active_plugin, navigation_node::TYPE_SETTING)) { $reportnav->make_active(); } $returnval = $OUTPUT->header(); if (!$return) { echo $returnval; } // Guess heading if not given explicitly if (!$heading) { $heading = $stractive_plugin; } if ($shownavigation) { $navselector = null; if ($courseid != SITEID && ($CFG->grade_navmethod == GRADE_NAVMETHOD_COMBO || $CFG->grade_navmethod == GRADE_NAVMETHOD_DROPDOWN)) { // It's absolutely essential that this grade plugin selector is shown after the user header. Just ask Fred. $navselector = print_grade_plugin_selector($plugin_info, $active_type, $active_plugin, true); if ($return) { $returnval .= $navselector; } else if (!isset($user)) { echo $navselector; } } $output = ''; // Add a help dialogue box if provided. if (isset($headerhelpidentifier)) { $output = $OUTPUT->heading_with_help($heading, $headerhelpidentifier, $headerhelpcomponent); } else { if (isset($user)) { $output = $OUTPUT->context_header( array( 'heading' => html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $courseid)), fullname($user)), 'user' => $user, 'usercontext' => context_user::instance($user->id) ), 2 ) . $navselector; } else { $output = $OUTPUT->heading($heading); } } if ($return) { $returnval .= $output; } else { echo $output; } if ($courseid != SITEID && ($CFG->grade_navmethod == GRADE_NAVMETHOD_COMBO || $CFG->grade_navmethod == GRADE_NAVMETHOD_TABS)) { $returnval .= grade_print_tabs($active_type, $active_plugin, $plugin_info, $return); } } $returnval .= print_natural_aggregation_upgrade_notice($courseid, context_course::instance($courseid), $PAGE->url, $return); if ($return) { return $returnval; } }
/** * Returns the list of notifications against the current session. * * @return array * @since Moodle 3.1 */ public static function fetch_notifications($contextid) { global $PAGE; self::validate_parameters(self::fetch_notifications_parameters(), ['contextid' => $contextid]); $context = \context::instance_by_id($contextid); $PAGE->set_context($context); return \core\notification::fetch_as_array($PAGE->get_renderer('core')); }
$upt->track('enrolments', get_string('addedtogroupnot', '', s($gname)), 'error'); } } catch (moodle_exception $e) { $upt->track('enrolments', get_string('addedtogroupnot', '', s($gname)), 'error'); continue; } } } $validation[$user->username] = core_user::validate($user); } $upt->close(); // close table if (!empty($validation)) { foreach ($validation as $username => $result) { if ($result !== true) { \core\notification::warning(get_string('invaliduserdata', 'tool_uploaduser', s($username))); } } } $cir->close(); $cir->cleanup(true); echo $OUTPUT->box_start('boxwidthnarrow boxaligncenter generalbox', 'uploadresults'); echo '<p>'; if ($optype != UU_USER_UPDATE) { echo get_string('userscreated', 'tool_uploaduser') . ': ' . $usersnew . '<br />'; } if ($optype == UU_USER_UPDATE or $optype == UU_USER_ADD_UPDATE) { echo get_string('usersupdated', 'tool_uploaduser') . ': ' . $usersupdated . '<br />'; } if ($allowdeletes) { echo get_string('usersdeleted', 'tool_uploaduser') . ': ' . $deletes . '<br />';
/** * Finish displaying the regrade progress page. * @param moodle_url $nexturl where to send the user after the regrade. * @uses exit. This method never returns. */ protected function finish_regrade($nexturl) { global $OUTPUT; \core\notification::success(get_string('regradecomplete', 'quiz_overview')); echo $OUTPUT->continue_button($nexturl); echo $OUTPUT->footer(); die; }
/** * Display the edit step form for the specified step. * * @param int $id The step to edit. */ protected function edit_step($id) { global $PAGE; if (isset($id)) { $step = step::instance($id); } else { $step = new step(); $step->set_tourid(required_param('tourid', PARAM_INT)); } $tour = $step->get_tour(); if (!empty($tour->get_config(self::CONFIG_SHIPPED_TOUR))) { notification::add(get_string('modifyshippedtourwarning', 'tool_usertours'), notification::WARNING); } $PAGE->navbar->add($tour->get_name(), $tour->get_view_link()); if (isset($id)) { $PAGE->navbar->add($step->get_title(), $step->get_edit_link()); } else { $PAGE->navbar->add(get_string('newstep', 'tool_usertours'), $step->get_edit_link()); } $form = new forms\editstep($step->get_edit_link(), $step); if ($form->is_cancelled()) { redirect($step->get_tour()->get_view_link()); } else { if ($data = $form->get_data()) { $step->handle_form_submission($form, $data); $step->get_tour()->reset_step_sortorder(); redirect($step->get_tour()->get_view_link()); } else { if (empty($id)) { $this->header(get_string('newstep', 'tool_usertours')); } else { $this->header(get_string('editstep', 'tool_usertours', $step->get_title())); } $form->set_data($step->prepare_data_for_form()); $form->display(); $this->footer(); } } }
/** * Test that session notifications are persisted across session clears. */ public function test_session_persistance() { global $PAGE, $SESSION; // Initially there won't be any notifications. $this->assertCount(0, $SESSION->notifications); // Adding a notification should make one available to fetch. \core\notification::success('Notification created'); $this->assertCount(1, $SESSION->notifications); // Re-creating the session will not empty the notification bag. \core\session\manager::init_empty_session(); $this->assertCount(1, $SESSION->notifications); }
redirect($PAGE->url); } } break; case 'renamecombine': // Allows to rename the tag and if the tag with the new name already exists these tags will be combined. if ($tagid && ($newname = required_param('newname', PARAM_TAG))) { require_sesskey(); $tag = core_tag_tag::get($tagid, '*', MUST_EXIST); $targettag = core_tag_tag::get_by_name($tag->tagcollid, $newname, '*'); if ($targettag) { $targettag->combine_tags(array($tag)); \core\notification::success(get_string('combined', 'core_tag')); } else { $tag->update(array('rawname' => $newname)); \core\notification::success(get_string('changessaved', 'core_tag')); } } redirect($PAGE->url); break; case 'addstandardtag': require_sesskey(); $tagobjects = array(); if ($tagcoll) { $tagslist = optional_param('tagslist', '', PARAM_RAW); $newtags = preg_split('/\\s*,\\s*/', trim($tagslist), -1, PREG_SPLIT_NO_EMPTY); $tagobjects = core_tag_tag::create_if_missing($tagcoll->id, $newtags, true); } foreach ($tagobjects as $tagobject) { if (!$tagobject->isstandard) { $tagobject->update(array('isstandard' => 1));
} else { if (!empty($data->gopreviouspage)) { $prevpage = $feedbackcompletion->get_previous_page($gopage); redirect(new moodle_url($PAGE->url, array('gopage' => intval($prevpage)))); } } } } } // Print the page header. $strfeedbacks = get_string("modulenameplural", "feedback"); $strfeedback = get_string("modulename", "feedback"); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($feedback->name)); if ($feedbackcompletion->is_empty()) { \core\notification::error(get_string('no_items_available_yet', 'feedback')); } else { if ($cansubmit) { if (!empty($data->savevalues) || !empty($data->gonextpage)) { // Display information after the submit. if ($feedback->page_after_submit) { echo $OUTPUT->box($feedbackcompletion->page_after_submit(), 'generalbox boxaligncenter'); } if ($feedbackcompletion->can_view_analysis()) { echo '<p align="center">'; $analysisurl = new moodle_url('/mod/feedback/analysis.php', array('id' => $cm->id, 'courseid' => $courseid)); echo html_writer::link($analysisurl, get_string('completed_feedbacks', 'feedback')); echo '</p>'; } if ($feedback->site_after_submit) { $url = feedback_encode_target_url($feedback->site_after_submit);