示例#1
0
/**
 * Redirects the user to another page, after printing a notice
 *
 * @param string $url The url to take the user to
 * @param string $message The text message to display to the user about the redirect, if any
 * @param string $delay How long before refreshing to the new page at $url?
 * @todo '&' needs to be encoded into '&' for XHTML compliance,
 *      however, this is not true for javascript. Therefore we
 *      first decode all entities in $url (since we cannot rely on)
 *      the correct input) and then encode for where it's needed
 *      echo "<script type='text/javascript'>alert('Redirect $url');</script>";
 */
function redirect($url, $message = '', $delay = -1)
{
    global $CFG, $THEME, $SESSION, $PAGE;
    if (!empty($CFG->usesid) && !isset($_COOKIE[session_name()])) {
        $url = $SESSION->sid_process_url($url);
    }
    $message = clean_text($message);
    $encodedurl = preg_replace("/\\&(?![a-zA-Z0-9#]{1,8};)/", "&amp;", $url);
    $encodedurl = preg_replace('/^.*href="([^"]*)".*$/', "\\1", clean_text('<a href="' . $encodedurl . '" />'));
    $url = str_replace('&amp;', '&', $encodedurl);
    /// At developer debug level. Don't redirect if errors have been printed on screen.
    /// Currenly only works in PHP 5.2+; we do not want strict PHP5 errors
    $lasterror = error_get_last();
    $error = defined('DEBUGGING_PRINTED') or !empty($lasterror) && $lasterror['type'] & DEBUG_DEVELOPER;
    $errorprinted = debugging('', DEBUG_ALL) && $CFG->debugdisplay && $error;
    if ($errorprinted) {
        $message = "<strong>Error output, so disabling automatic redirect.</strong></p><p>" . $message;
    }
    $performanceinfo = '';
    if (defined('MDL_PERF') || (!empty($CFG->perfdebug) and $CFG->perfdebug > 7)) {
        if (defined('MDL_PERFTOLOG') && !function_exists('register_shutdown_function')) {
            $perf = get_performance_info();
            error_log("PERF: " . $perf['txt']);
        }
    }
    /// when no message and header printed yet, try to redirect
    if (empty($message) and !$PAGE->headerprinted) {
        // 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]+:|', $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;
            }
        }
        $delay = 0;
        //try header redirection first
        @header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other');
        //302 might not work for POST requests, 303 is ignored by obsolete clients
        @header('Location: ' . $url);
        //another way for older browsers and already sent headers (eg trailing whitespace in config.php)
        echo '<meta http-equiv="refresh" content="' . $delay . '; url=' . $encodedurl . '" />';
        print_js_call('document.location.replace', array($url));
        die;
    }
    if ($delay == -1) {
        $delay = 3;
        // if no delay specified wait 3 seconds
    }
    if (!$PAGE->headerprinted) {
        // this type of redirect might not be working in some browsers - such as lynx :-(
        print_header('', '', '', '', $errorprinted ? '' : '<meta http-equiv="refresh" content="' . $delay . '; url=' . $encodedurl . '" />');
        $delay += 3;
        // double redirect prevention, it was sometimes breaking upgrades before 1.7
    } else {
        print_container_end_all(false, $THEME->open_header_containers);
    }
    echo '<div id="redirect">';
    echo '<div id="message">' . $message . '</div>';
    echo '<div id="continue">( <a href="' . $encodedurl . '">' . get_string('continue') . '</a> )</div>';
    echo '</div>';
    if (!$errorprinted) {
        print_delayed_js_call($delay, 'document.location.replace', array($url));
    }
    $CFG->docroot = false;
    // to prevent the link to moodle docs from being displayed on redirect page.
    print_footer('none');
    die;
}
 protected function get_button_update_script($question)
 {
     return print_js_call('quiz_init_nav_button', array($this->get_button_id($question), $question->id), true);
 }
示例#3
0
 /**
  * Display the table.
  */
 public function display()
 {
     echo '<table class="' . implode(' ', $this->classes) . '" id="' . $this->id . '">' . "\n<thead>\n";
     echo '<tr><th class="name" align="left" scope="col">' . get_string('capability', 'role') . '</th>';
     $this->add_header_cells();
     echo "</tr>\n</thead>\n<tbody>\n";
     /// Loop over capabilities.
     $contextlevel = 0;
     $component = '';
     foreach ($this->capabilities as $capability) {
         if ($this->skip_row($capability)) {
             continue;
         }
         /// Prints a breaker if component or name or context level has changed
         if (component_level_changed($capability, $component, $contextlevel)) {
             $this->print_heading_row($capability);
         }
         $contextlevel = $capability->contextlevel;
         $component = $capability->component;
         /// Start the row.
         echo '<tr class="' . implode(' ', array_unique(array_merge(array('rolecap'), $this->get_row_classes($capability)))) . '">';
         /// Table cell for the capability name.
         echo '<td class="name"><span class="cap-desc">' . get_capability_docs_link($capability) . '<span class="cap-name">' . $capability->name . '</span></span></td>';
         /// Add the cells specific to this table.
         $this->add_row_cells($capability);
         /// End the row.
         echo "</tr>\n";
     }
     /// End of the table.
     echo "</tbody>\n</table>\n";
     if (count($this->capabilities) > cabability_table_base::NUM_CAPS_FOR_SEARCH) {
         print_js_call('cap_table_filter.init', array($this->id, get_string('search'), get_string('clear')));
     }
 }
 function get_content()
 {
     global $CFG;
     if ($this->content !== NULL) {
         return $this->content;
     }
     if (isguestuser() or !isloggedin()) {
         // these users can not change any settings
         $this->content = '';
         return '';
     }
     require_once $CFG->libdir . '/adminlib.php';
     $adminroot = admin_get_root(false, false);
     // settings not required - only pages
     if ($current = $adminroot->locate($this->section, true)) {
         $this->pathtosection = $current->path;
         array_pop($this->pathtosection);
     }
     // we need to do this instead of $this->build_tree($adminroot) because the top-level folder
     // is redundant (and ideally ignored). (the top-level folder is "administration".)
     $entries = array_keys($adminroot->children);
     asort($entries);
     foreach ($entries as $entry) {
         $this->build_tree($adminroot->children[$entry]);
     }
     if ($this->tempcontent !== '') {
         require_js(array('yui_yahoo', 'yui_event'));
         require_js('blocks/admin_tree/admintree.js');
         $this->content = new object();
         $this->content->text = '<div class="admintree">' . $this->tempcontent . "</div>\n";
         $this->content->text .= print_js_call('admin_tree.init', array($this->divcounter - 1, $this->expandnodes, $CFG->pixpath, get_string('folderopened'), get_string('folderclosed')), true);
         // only do search if you have moodle/site:config
         if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
             $this->content->footer = '<div class="adminsearchform">' . '<form action="' . $CFG->wwwroot . '/' . $CFG->admin . '/search.php" method="get"><div>' . '<label for="query" class="accesshide">' . get_string('searchinsettings', 'admin') . '</label>' . '<input type="text" name="query" id="query" size="8" value="' . s($adminroot->search) . '" />' . '<input type="submit" value="' . get_string('search') . '" /></div>' . '</form></div>';
         } else {
             $this->content->footer = '';
         }
     } else {
         $this->content = new object();
         $this->content->text = '';
     }
     return $this->content;
 }
示例#5
0
 /**
  * Send the user back to the quiz view page. Normally this is just a redirect, but
  * If we were in a secure window, we close this window, and reload the view window we came from.
  *
  * @param boolean $canpreview This affects whether we have to worry about secure window stuff.
  */
 public function back_to_view_page($canpreview, $message = '')
 {
     global $CFG;
     $url = $this->_quizobj->view_url();
     if ($this->securewindow_required($canpreview)) {
         print_header();
         print_box_start();
         if ($message) {
             echo '<p>' . $message . '</p><p>' . get_string('windowclosing', 'quiz') . '</p>';
             $delay = 5;
         } else {
             echo '<p>' . get_string('pleaseclose', 'quiz') . '</p>';
             $delay = 0;
         }
         print_box_end();
         print_js_call('quiz_secure_window.close', array($url, $delay));
         print_footer('empty');
         die;
     } else {
         redirect($url, $message);
     }
 }
示例#6
0
/**
 * Print (or return) the start of a collapisble region, that has a caption that can
 * be clicked to expand or collapse the region. If JavaScript is off, then the region
 * will always be exanded.
 *
 * @param string $classes class names added to the div that is output.
 * @param string $id id added to the div that is output. Must not be blank.
 * @param string $caption text displayed at the top. Clicking on this will cause the region to expand or contract.
 * @param string $userpref the name of the user preference that stores the user's preferred deafault state.
 *      (May be blank if you do not wish the state to be persisted.
 * @param boolean $default Inital collapsed state to use if the user_preference it not set.
 * @param boolean $return if true, return the HTML as a string, rather than printing it.
 * @return mixed if $return is false, returns nothing, otherwise returns a string of HTML.
 */
function print_collapsible_region_start($classes, $id, $caption, $userpref = false, $default = false, $return = false)
{
    global $CFG;
    // Include required JavaScript libraries.
    require_js(array('yui_yahoo', 'yui_dom-event', 'yui_event', 'yui_animation'));
    // Work out the initial state.
    if (is_string($userpref)) {
        user_preference_allow_ajax_update($userpref, PARAM_BOOL);
        $collapsed = get_user_preferences($userpref, $default);
    } else {
        $collapsed = $default;
        $userpref = false;
    }
    if ($collapsed) {
        $classes .= ' collapsed';
    }
    $output = '';
    $output .= '<div id="' . $id . '" class="collapsibleregion ' . $classes . '">';
    $output .= '<div id="' . $id . '_sizer">';
    $output .= '<div id="' . $id . '_caption" class="collapsibleregioncaption">';
    $output .= $caption . ' ';
    $output .= '</div><div id="' . $id . '_inner" class="collapsibleregioninner">';
    $output .= print_js_call('new collapsible_region', array($id, $userpref, get_string('clicktohideshow')), true);
    if ($return) {
        return $output;
    } else {
        echo $output;
    }
}
示例#7
0
print_string('remove');
?>
" />
        </p>
      </td>
      <td id='potentialcell'>
          <p>
            <label for="addselect"><?php 
print_string('potentialmembs', 'group');
?>
</label>
          </p>
          <?php 
$potentialmembersselector->display();
?>
      </td>
    </tr>
    <tr><td colspan="3" id='backcell'>
        <input type="submit" name="cancel" value="<?php 
print_string('backtogroups', 'group');
?>
" />
    </td></tr>
    </table>
    </div>
    </form>
</div>

<?php 
print_js_call('init_add_remove_members_page');
print_footer($course);
示例#8
0
/**
 *
 */
function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode, $canreply = NULL, $canrate = false)
{
    global $USER, $CFG, $DB;
    if (!empty($USER->id)) {
        $ownpost = $USER->id == $post->userid;
    } else {
        $ownpost = false;
    }
    $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
    if ($canreply === NULL) {
        $reply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext);
    } else {
        $reply = $canreply;
    }
    // $cm holds general cache for forum functions
    $cm->cache = new object();
    $cm->cache->groups = groups_get_all_groups($course->id, 0, $cm->groupingid);
    $cm->cache->usersgroups = array();
    $posters = array();
    // preload all posts - TODO: improve...
    if ($mode == FORUM_MODE_FLATNEWEST) {
        $sort = "p.created DESC";
    } else {
        $sort = "p.created ASC";
    }
    $forumtracked = forum_tp_is_tracked($forum);
    $posts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked);
    $post = $posts[$post->id];
    foreach ($posts as $pid => $p) {
        $posters[$p->userid] = $p->userid;
    }
    // preload all groups of ppl that posted in this discussion
    if ($postersgroups = groups_get_all_groups($course->id, $posters, $cm->groupingid, 'gm.id, gm.groupid, gm.userid')) {
        foreach ($postersgroups as $pg) {
            if (!isset($cm->cache->usersgroups[$pg->userid])) {
                $cm->cache->usersgroups[$pg->userid] = array();
            }
            $cm->cache->usersgroups[$pg->userid][$pg->groupid] = $pg->groupid;
        }
        unset($postersgroups);
    }
    $ratings = NULL;
    $ratingsmenuused = false;
    $ratingsformused = false;
    if ($forum->assessed and isloggedin()) {
        if ($scale = make_grades_menu($forum->scale)) {
            $ratings = new object();
            $ratings->scale = $scale;
            $ratings->assesstimestart = $forum->assesstimestart;
            $ratings->assesstimefinish = $forum->assesstimefinish;
            $ratings->allow = $canrate;
            if ($ratings->allow) {
                echo '<form id="form" method="post" action="rate.php">';
                echo '<div class="ratingform">';
                echo '<input type="hidden" name="forumid" value="' . $forum->id . '" />';
                $ratingsformused = true;
            }
            // preload all ratings - one query only and minimal memory
            $cm->cache->ratings = array();
            $cm->cache->myratings = array();
            if ($postratings = forum_get_all_discussion_ratings($discussion)) {
                foreach ($postratings as $pr) {
                    if (!isset($cm->cache->ratings[$pr->postid])) {
                        $cm->cache->ratings[$pr->postid] = array();
                    }
                    $cm->cache->ratings[$pr->postid][$pr->id] = $pr->rating;
                    if ($pr->userid == $USER->id) {
                        $cm->cache->myratings[$pr->postid] = $pr->rating;
                    }
                }
                unset($postratings);
            }
        }
    }
    $post->forum = $forum->id;
    // Add the forum id to the post object, later used by forum_print_post
    $post->forumtype = $forum->type;
    $post->subject = format_string($post->subject);
    $postread = !empty($post->postread);
    if (forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, false, $ratings, '', '', $postread, true, $forumtracked)) {
        $ratingsmenuused = true;
    }
    switch ($mode) {
        case FORUM_MODE_FLATOLDEST:
        case FORUM_MODE_FLATNEWEST:
        default:
            if (forum_print_posts_flat($course, $cm, $forum, $discussion, $post, $mode, $ratings, $reply, $forumtracked, $posts)) {
                $ratingsmenuused = true;
            }
            break;
        case FORUM_MODE_THREADED:
            if (forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, 0, $ratings, $reply, $forumtracked, $posts)) {
                $ratingsmenuused = true;
            }
            break;
        case FORUM_MODE_NESTED:
            if (forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $ratings, $reply, $forumtracked, $posts)) {
                $ratingsmenuused = true;
            }
            break;
    }
    if ($ratingsformused) {
        if ($ratingsmenuused) {
            echo '<div class="ratingsubmit">';
            echo '<input type="submit" id="forumpostratingsubmit" value="' . get_string('sendinratings', 'forum') . '" />';
            if (ajaxenabled() && !empty($CFG->forum_ajaxrating)) {
                /// AJAX enabled, standard submission form
                print_js_call('init_rate_ajax');
            }
            if ($forum->scale < 0) {
                if ($scale = $DB->get_record("scale", array("id" => abs($forum->scale)))) {
                    print_scale_menu_helpbutton($course->id, $scale);
                }
            }
            echo '</div>';
        }
        echo '</div>';
        echo '</form>';
    }
}
示例#9
0
      </td>
      <td id="potentialcell">
          <p><label for="addselect"><?php 
    print_string('potusers', 'role');
    ?>
</label></p>
          <?php 
    $potentialuserselector->display();
    ?>
      </td>
    </tr>
  </table>
</div></form>

<?php 
    print_js_call('init_add_assign_page');
    if (!empty($errors)) {
        $msg = '<p>';
        foreach ($errors as $e) {
            $msg .= $e . '<br />';
        }
        $msg .= '</p>';
        print_simple_box_start('center');
        notify($msg);
        print_simple_box_end();
    }
    /// Print a form to swap roles, and a link back to the all roles list.
    echo '<div class="backlink">';
    popup_form($baseurl . '&amp;roleid=', $nameswithcounts, 'switchrole', $roleid, '', '', '', false, 'self', get_string('assignanotherrole', 'role'));
    echo '<p><a href="' . $baseurl . '">' . get_string('backtoallroles', 'role') . '</a></p>';
    echo '</div>';
示例#10
0
 /**
  * @param boolean $optiontracker if true, initialise JavaScript for updating the user prefs.
  * @return any HTML needed here.
  */
 protected function initialise_javascript($search)
 {
     global $USER;
     $output = '';
     // Put the options into the session, to allow search.php to respond to the ajax requests.
     $options = $this->get_options();
     $hash = md5(serialize($options));
     $USER->userselectors[$hash] = $options;
     // Initialise the selector.
     $output .= print_js_call('new user_selector', array($this->name, $hash, $this->extrafields, $search, get_string('previouslyselectedusers', '', '%%SEARCHTERM%%'), get_string('nomatchingusers', '', '%%SEARCHTERM%%'), get_string('none')), true);
     return $output;
 }
示例#11
0
/**
 * If new messages are waiting for the current user, then return
 * Javascript code to create a popup window
 *
 * @return string Javascript code
 */
function message_popup_window()
{
    global $USER, $DB;
    $popuplimit = 30;
    // Minimum seconds between popups
    if (!defined('MESSAGE_WINDOW')) {
        if (isset($USER->id) and !isguestuser()) {
            if (!isset($USER->message_lastpopup)) {
                $USER->message_lastpopup = 0;
            }
            if (time() - $USER->message_lastpopup > $popuplimit) {
                /// It's been long enough
                if (get_user_preferences('message_showmessagewindow', 1) == 1) {
                    if ($DB->count_records_select('message', 'useridto = ? AND timecreated > ?', array($USER->id, $USER->message_lastpopup))) {
                        $USER->message_lastpopup = time();
                        return print_js_call('openpopup', array('/message/index.php', 'message', 'menubar=0,location=0,scrollbars,status,resizable,width=400,height=500', 0), true);
                    }
                }
            }
        }
    }
    return '';
}
示例#12
0
 protected function display_content($question, $rowclasses)
 {
     echo '<input title="' . $this->strselect . '" type="checkbox" name="q' . $question->id . '" id="checkq' . $question->id . '" value="1"/>';
     if ($this->firstrow) {
         print_js_call('question_bank.init_checkbox_column', array(get_string('selectall'), get_string('deselectall'), 'checkq' . $question->id));
         $this->firstrow = false;
     }
 }
示例#13
0
 /**
  * Render the question flag, assuming $flagsoption allows it. You will probably
  * never need to override this method.
  *
  * @param object $question the question
  * @param object $state its current state
  * @param integer $flagsoption the option that says whether flags should be displayed.
  */
 protected function print_question_flag($question, $state, $flagsoption)
 {
     global $CFG;
     switch ($flagsoption) {
         case QUESTION_FLAGSSHOWN:
             $flagcontent = $this->get_question_flag_tag($state->flagged);
             break;
         case QUESTION_FLAGSEDITABLE:
             $id = $question->name_prefix . '_flagged';
             if ($state->flagged) {
                 $checked = 'checked="checked" ';
             } else {
                 $checked = '';
             }
             $qsid = $state->questionsessionid;
             $aid = $state->attempt;
             $qid = $state->question;
             $checksum = question_get_toggleflag_checksum($aid, $qid, $qsid);
             $postdata = "qsid={$qsid}&amp;aid={$aid}&amp;qid={$qid}&amp;checksum={$checksum}&amp;sesskey=" . sesskey();
             $flagcontent = '<input type="checkbox" id="' . $id . '" name="' . $id . '" value="1" ' . $checked . ' />' . '<label id="' . $id . 'label" for="' . $id . '">' . $this->get_question_flag_tag($state->flagged, $id . 'img') . '</label>' . "\n" . print_js_call('question_flag_changer.init_flag', array($id, $postdata), true);
             break;
         default:
             $flagcontent = '';
     }
     if ($flagcontent) {
         echo '<div class="questionflag">' . $flagcontent . "</div>\n";
     }
 }
示例#14
0
        print_heading(get_string('accessnoticesheader', 'quiz'), '', 3);
        $accessmanager->print_messages($messages);
        print_box_end();
    }
} else {
    /// Just a heading.
    if ($attemptobj->get_num_attempts_allowed() != 1) {
        print_heading(format_string($attemptobj->get_quiz_name()) . ' - ' . $title);
    } else {
        print_heading(format_string($attemptobj->get_quiz_name()));
    }
}
// Start the form
echo '<form id="responseform" method="post" action="', $attemptobj->processattempt_url(), '" enctype="multipart/form-data" accept-charset="utf-8">', "\n";
echo '<div>';
print_js_call('init_quiz_form');
/// Print the navigation panel in a left column.
print_container_start();
echo '<div id="left-column">';
$attemptobj->print_navigation_panel('quiz_attempt_nav_panel', $page);
echo '</div>';
print_container_end();
/// Start the main column.
echo '<div id="middle-column">';
?>
    <style type="text/css">
<!--  
#cd {
	margin: auto;
	height: 40px;
	width: 250px;
示例#15
0
    // Select 'All', rather than each role individually.
    $selectedroleids = array('0');
} else {
    $selectedroleids = $cleanedroleids;
}
// Print the settings form.
print_box_start('generalbox boxwidthwide boxaligncenter centerpara');
echo '<form method="get" action="." id="settingsform">';
print_heading(get_string('reportsettings', 'report_capability'));
echo '<p id="intro">', get_string('intro', 'report_capability'), '</p>';
echo '<p><label for="menucapability"> ' . get_string('capabilitylabel', 'report_capability') . '</label></p>';
choose_from_menu($capabilitychoices, 'capability', $capability, 'choose', '', '', false, false, 0, '', true);
echo '<p><label for="menuroles"> ' . get_string('roleslabel', 'report_capability') . '</label></p>';
choose_from_menu($rolechoices, 'roles[]', $selectedroleids, '', '', '', false, false, 0, '', true, true);
echo '<p><input type="submit" id="settingssubmit" value="' . get_string('getreport', 'report_capability') . '" /></p>';
print_js_call('capability_report.cap_filter_init', array(get_string('search')));
echo '</form>';
print_box_end();
// If we have a capability, generate the report.
if ($capability) {
    // Work out the bits needed for the SQL WHERE clauses.
    $sqlroletest = '';
    if (count($cleanedroleids) != count($allroles)) {
        $sqlroletest = 'AND roleid IN (' . implode(',', $cleanedroleids) . ')';
    }
    // Get all the role_capabilities rows for this capability - that is, all
    // role definitions, and all role overrides.
    $rolecaps = get_records_sql("\n            SELECT id, roleid, contextid, permission\n            FROM {role_capabilities}\n            WHERE capability = '{$capability}' {$sqlroletest}");
    // In order to display a nice tree of contexts, we need to get all the
    // ancestors of all the contexts in the query we just did.
    $relevantpaths = get_records_sql_menu("\n            SELECT DISTINCT con.path, 1\n            FROM {context} con JOIN {role_capabilities} rc ON rc.contextid = con.id\n            WHERE capability = '{$capability}' {$sqlroletest}");
示例#16
0
}
/// Print all the questions.
if ($showall) {
    $thispage = 'all';
    $lastpage = true;
} else {
    $thispage = $page;
    $lastpage = $attemptobj->is_last_page($page);
}
foreach ($attemptobj->get_question_ids($thispage) as $id) {
    $attemptobj->print_question($id, true, $attemptobj->review_url($id, $page, $showall));
}
/// Close form if we opened it.
if ($options->flags == QUESTION_FLAGSEDITABLE) {
    echo '<div class="submitbtns">' . "\n" . '<input type="submit" id="savingflagssubmit" name="savingflags" value="' . get_string('saveflags', 'question') . '" />' . "</div>\n" . "\n</div></form>\n";
    print_js_call('question_flag_changer.init_flag_save_form', array('savingflagssubmit'));
}
/// Print a link to the next page.
echo '<div class="submitbtns">';
if ($lastpage) {
    $accessmanager->print_finish_review_link($attemptobj->is_preview_user());
} else {
    link_arrow_right(get_string('next'), $attemptobj->review_url(0, $page + 1));
}
echo "</div>";
// End middle column.
echo '</div>';
echo '<div class="clearer"></div>';
// Finish the page
if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
    print_footer('empty');