Merge branch 'MDL-46091' of git://github.com/timhunt/moodle

This commit is contained in:
Eloy Lafuente (stronk7) 2016-01-19 07:32:09 +01:00
commit cf003b48bc
15 changed files with 368 additions and 77 deletions

View File

@ -368,9 +368,16 @@ class quiz_access_manager {
* @return mod_quiz_preflight_check_form the form.
*/
public function get_preflight_check_form(moodle_url $url, $attemptid) {
// This form normally wants POST submissins. However, it also needs to
// accept GET submissions. Since formslib is strict, we have to detect
// which case we are in, and set the form property appropriately.
$method = 'post';
if (!empty($_GET['_qf__mod_quiz_preflight_check_form'])) {
$method = 'get';
}
return new mod_quiz_preflight_check_form($url->out_omit_querystring(),
array('rules' => $this->rules, 'quizobj' => $this->quizobj,
'attemptid' => $attemptid, 'hidden' => $url->params()));
'attemptid' => $attemptid, 'hidden' => $url->params()), $method);
}
/**

View File

@ -38,6 +38,7 @@ class mod_quiz_preflight_check_form extends moodleform {
protected function definition() {
$mform = $this->_form;
$this->_form->updateAttributes(array('id' => 'mod_quiz_preflight_form'));
foreach ($this->_customdata['hidden'] as $name => $value) {
if ($name === 'sesskey') {
@ -54,7 +55,8 @@ class mod_quiz_preflight_check_form extends moodleform {
}
}
$this->add_action_buttons(true, get_string('continue'));
$this->add_action_buttons(true, get_string('startattempt', 'quiz'));
$mform->setDisableShortforms();
}
public function validation($data, $files) {

View File

@ -27,5 +27,7 @@
defined('MOODLE_INTERNAL') || die();
$string['confirmstartheader'] = 'Timed quiz';
$string['confirmstart'] = 'The quiz has a time limit of {$a}. Time will count down from the moment you start your attempt and you must submit before it expires. Are you sure that you wish to start now?';
$string['pluginname'] = 'Time limit quiz access rule';
$string['quiztimelimit'] = 'Time limit: {$a}';

View File

@ -63,6 +63,18 @@ class quizaccess_timelimit extends quiz_access_rule_base {
return false;
}
return $endtime - $timenow;
}
public function is_preflight_check_required($attemptid) {
// Warning only required if the attempt is not already started.
return $attemptid === null;
}
public function add_preflight_check_form_fields(mod_quiz_preflight_check_form $quizform,
MoodleQuickForm $mform, $attemptid) {
$mform->addElement('header', 'honestycheckheader',
get_string('confirmstartheader', 'quizaccess_timelimit'));
$mform->addElement('static', 'honestycheckmessage', '',
get_string('confirmstart', 'quizaccess_timelimit', format_time($this->quiz->timelimit)));
}
}

View File

@ -0,0 +1 @@
define(["jquery","core/yui"],function(a,b){var c={confirmDialogue:null,init:function(a,d,e,f){var g=a;b.use("moodle-core-notification","moodle-core-formchangechecker","io-form",function(){b.one(e)&&(c.confirmDialogue=new M.core.dialogue({headerContent:d,bodyContent:b.one(e),draggable:!0,visible:!1,center:!0,modal:!0,width:null,extraClasses:["mod_quiz_preflight_popup"]}),b.one(a).on("click",c.displayDialogue),b.one("#id_cancel").on("click",c.hideDialogue),g=c.confirmDialogue.get("boundingBox").one('[name="submitbutton"]')),f&&b.one(g).on("click",c.launchQuizPopup,c,f)})},displayDialogue:function(a){a&&a.halt(),c.confirmDialogue.show()},hideDialogue:function(a){a&&a.halt(),c.confirmDialogue.hide(a)},launchQuizPopup:function(a,c){a.halt(),M.core_formchangechecker.reset_form_dirty_state();var d=a.target.ancestor("form");window.openpopup(a,{url:d.get("action")+"?"+b.IO.stringify(d).replace(/\bcancel=/,"x="),windowname:"quizpopup",options:c,fullscreen:!0})}};return c});

View File

@ -0,0 +1,112 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This class manages the confirmation pop-up (also called the pre-flight check)
* that is sometimes shown when a use clicks the start attempt button.
*
* This is also responsible for opening the pop-up window, if the quiz requires to be in one.
*
* @module mod_quiz/preflightcheck
* @class preflightcheck
* @package mod_quiz
* @copyright 2016 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'core/yui'], function($, Y) {
/**
* @alias module:mod_quiz/preflightcheck
*/
var t = {
confirmDialogue: null,
/**
* Initialise the start attempt button.
*
* @param {String} startButtonId the id of the start attempt button that we will be enhancing.
* @param {String} confirmationTitle the title of the dialogue.
* @param {String} confirmationForm selector for the confirmation form to show in the dialogue.
* @param {String} popupoptions If not null, the quiz should be launced in a pop-up.
*/
init: function(startButton, confirmationTitle, confirmationForm, popupoptions) {
var finalStartButton = startButton;
Y.use('moodle-core-notification', 'moodle-core-formchangechecker', 'io-form', function () {
if (Y.one(confirmationForm)) {
t.confirmDialogue = new M.core.dialogue({
headerContent: confirmationTitle,
bodyContent: Y.one(confirmationForm),
draggable: true,
visible: false,
center: true,
modal: true,
width: null,
extraClasses: ['mod_quiz_preflight_popup']
});
Y.one(startButton).on('click', t.displayDialogue);
Y.one('#id_cancel').on('click', t.hideDialogue);
finalStartButton = t.confirmDialogue.get('boundingBox').one('[name="submitbutton"]');
}
if (popupoptions) {
Y.one(finalStartButton).on('click', t.launchQuizPopup, t, popupoptions);
}
});
},
/**
* Display the dialogue.
* @param {Y.EventFacade} e the event being responded to, if any.
*/
displayDialogue: function(e) {
if (e) {
e.halt();
}
t.confirmDialogue.show();
},
/**
* Hide the dialogue.
* @param {Y.EventFacade} e the event being responded to, if any.
*/
hideDialogue: function(e) {
if (e) {
e.halt();
}
t.confirmDialogue.hide(e);
},
/**
* Event handler for the quiz start attempt button.
*/
launchQuizPopup: function(e, popupoptions) {
e.halt();
M.core_formchangechecker.reset_form_dirty_state();
var form = e.target.ancestor('form');
window.openpopup(e, {
url: form.get('action') + '?' + Y.IO.stringify(form).replace(/\bcancel=/, 'x='),
windowname: 'quizpopup',
options: popupoptions,
fullscreen: true,
});
}
};
return t;
});

View File

@ -371,23 +371,13 @@ class quiz {
// Bits of content =========================================================
/**
* @param bool $unfinished whether there is currently an unfinished attempt active.
* @return string if the quiz policies merit it, return a warning string to
* be displayed in a javascript alert on the start attempt button.
* @param bool $notused not used.
* @return string an empty string.
* @deprecated since 3.1. This sort of functionality is now entirely handled by quiz access rules.
*/
public function confirm_start_attempt_message($unfinished) {
if ($unfinished) {
return '';
}
if ($this->quiz->timelimit && $this->quiz->attempts) {
return get_string('confirmstartattempttimelimit', 'quiz', $this->quiz->attempts);
} else if ($this->quiz->timelimit) {
return get_string('confirmstarttimelimit', 'quiz');
} else if ($this->quiz->attempts) {
return get_string('confirmstartattemptlimit', 'quiz', $this->quiz->attempts);
}
public function confirm_start_attempt_message($notused) {
debugging('confirm_start_attempt_message is deprecated. ' .
'This sort of functionality is now entirely handled by quiz access rules.');
return '';
}

View File

@ -202,9 +202,6 @@ $string['confirmclose'] = 'Once you submit, you will no longer be able to change
$string['confirmremovequestion'] = 'Are you sure you want to remove this {$a} question?';
$string['confirmremovesectionheading'] = 'Are you sure you want to remove the \'{$a}\' section heading?';
$string['confirmserverdelete'] = 'Are you sure you want to remove the server <b>{$a}</b> from the list?';
$string['confirmstartattemptlimit'] = 'Number of attempts allowed: {$a}. You are about to start a new attempt. Do you wish to proceed?';
$string['confirmstartattempttimelimit'] = 'This quiz has a time limit and is limited to {$a} attempt(s). You are about to start a new attempt. Do you wish to proceed?';
$string['confirmstarttimelimit'] = 'The quiz has a time limit. Are you sure that you wish to start?';
$string['connectionok'] = 'Network connection restored. You may continue safely.';
$string['connectionerror'] = 'Network connection lost. (Autosave failed).

View File

@ -272,23 +272,6 @@ M.mod_quiz.secure_window = {
e.halt();
},
/**
* Event handler for the quiz start attempt button.
*/
start_attempt_action: function(e, args) {
if (args.startattemptwarning == '') {
openpopup(e, args);
} else {
M.util.show_confirm_dialog(e, {
message: args.startattemptwarning,
callback: function() {
openpopup(e, args);
},
continuelabel: M.util.get_string('startattempt', 'quiz')
});
}
},
init_close_button: function(Y, url) {
Y.on('click', function(e) {
M.mod_quiz.secure_window.close(url, 0)

View File

@ -422,9 +422,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
$output .= $this->heading(format_string($quizobj->get_quiz_name(), true,
array("context" => $quizobj->get_context())));
$output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm());
ob_start();
$mform->display();
$output .= ob_get_clean();
$output .= $mform->render();
$output .= $this->footer();
return $output;
}
@ -798,9 +796,8 @@ class mod_quiz_renderer extends plugin_renderer_base {
if ($viewobj->buttontext) {
$output .= $this->start_attempt_button($viewobj->buttontext,
$viewobj->startattempturl, $viewobj->startattemptwarning,
$viewobj->startattempturl, $viewobj->preflightcheckform,
$viewobj->popuprequired, $viewobj->popupoptions);
}
if ($viewobj->showbacktocourse) {
@ -815,43 +812,44 @@ class mod_quiz_renderer extends plugin_renderer_base {
/**
* Generates the view attempt button
*
* @param int $course The course ID
* @param array $quiz Array containging quiz date
* @param int $cm The Course Module ID
* @param int $context The page Context ID
* @param mod_quiz_view_object $viewobj
* @param string $buttontext
* @param string $buttontext the label to display on the button.
* @param moodle_url $url The URL to POST to in order to start the attempt.
* @param mod_quiz_preflight_check_form $preflightcheckform deprecated.
* @param bool $popuprequired whether the attempt needs to be opened in a pop-up.
* @param array $popupoptions the options to use if we are opening a popup.
* @return string HTML fragment.
*/
public function start_attempt_button($buttontext, moodle_url $url,
$startattemptwarning, $popuprequired, $popupoptions) {
mod_quiz_preflight_check_form $preflightcheckform = null,
$popuprequired = false, $popupoptions = null) {
if (is_string($preflightcheckform)) {
// Calling code was not updated since the API change.
debugging('The third argument to start_attempt_button should now be the ' .
'mod_quiz_preflight_check_form from ' .
'quiz_access_manager::get_preflight_check_form, not a warning message string.');
}
$button = new single_button($url, $buttontext);
$button->class .= ' quizstartbuttondiv';
$warning = '';
if ($popuprequired) {
$this->page->requires->js_module(quiz_get_js_module());
$this->page->requires->js('/mod/quiz/module.js');
$popupaction = new popup_action('click', $url, 'quizpopup', $popupoptions);
$button->class .= ' quizsecuremoderequired';
$button->add_action(new component_action('click',
'M.mod_quiz.secure_window.start_attempt_action', array(
'url' => $url->out(false),
'windowname' => 'quizpopup',
'options' => $popupaction->get_js_options(),
'fullscreen' => true,
'startattemptwarning' => $startattemptwarning,
)));
$warning = html_writer::tag('noscript', $this->heading(get_string('noscript', 'quiz')));
} else if ($startattemptwarning) {
$button->add_action(new confirm_action($startattemptwarning, null,
get_string('startattempt', 'quiz')));
$popupjsoptions = null;
if ($popuprequired && $popupoptions) {
$action = new popup_action('click', $url, 'popup', $popupoptions);
$popupjsoptions = $action->get_js_options();
}
return $this->render($button) . $warning;
if ($preflightcheckform) {
$checkform = $preflightcheckform->render();
} else {
$checkform = null;
}
$this->page->requires->js_call_amd('mod_quiz/preflightcheck', 'init',
array('.quizstartbuttondiv input[type=submit]', get_string('startattempt', 'quiz'),
'#mod_quiz_preflight_form', $popupjsoptions));
return $this->render($button) . $checkform;
}
/**
@ -1316,10 +1314,11 @@ class mod_quiz_view_object {
/** @var string $buttontext caption for the start attempt button. If this is null, show no
* button, or if it is '' show a back to the course button. */
public $buttontext;
/** @var string $startattemptwarning alert to show the user before starting an attempt. */
public $startattemptwarning;
/** @var moodle_url $startattempturl URL to start an attempt. */
public $startattempturl;
/** @var moodleform|null $preflightcheckform confirmation form that must be
* submitted before an attempt is started, if required. */
public $preflightcheckform;
/** @var moodle_url $startattempturl URL for any Back to the course button. */
public $backtocourseurl;
/** @var bool $showbacktocourse should we show a back to the course button? */
@ -1330,4 +1329,16 @@ class mod_quiz_view_object {
public $popupoptions;
/** @var bool $quizhasquestions whether the quiz has any questions. */
public $quizhasquestions;
public function __get($field) {
switch ($field) {
case 'startattemptwarning':
debugging('startattemptwarning has been deprecated. It is now always blank.');
return '';
default:
debugging('Unknown property ' . $field);
return null;
}
}
}

View File

@ -125,8 +125,8 @@ if ($lastattempt && ($lastattempt->state == quiz_attempt::IN_PROGRESS ||
}
// Check access.
$output = $PAGE->get_renderer('mod_quiz');
if (!$quizobj->is_preview_user() && $messages) {
$output = $PAGE->get_renderer('mod_quiz');
print_error('attempterror', 'quiz', $quizobj->view_url(),
$output->access_messages($messages));
}
@ -137,7 +137,7 @@ if ($accessmanager->is_preflight_check_required($currentattemptid)) {
$quizobj->start_attempt_url($page), $currentattemptid);
if ($mform->is_cancelled()) {
$accessmanager->back_to_view_page($output);
$accessmanager->back_to_view_page($PAGE->get_renderer('mod_quiz'));
} else if (!$mform->get_data()) {
@ -145,6 +145,7 @@ if ($accessmanager->is_preflight_check_required($currentattemptid)) {
$PAGE->set_url($quizobj->start_attempt_url($page));
$PAGE->set_title($quizobj->get_quiz_name());
$accessmanager->setup_attempt_page($PAGE);
$output = $PAGE->get_renderer('mod_quiz');
if (empty($quizobj->get_quiz()->showblocks)) {
$PAGE->blocks->show_only_fake_blocks();
}

View File

@ -345,6 +345,47 @@ table.quizattemptsummary .noreviewmessage {
.jsenabled .quizstartbuttondiv.quizsecuremoderequired input {
display: inline;
}
.quizattempt #mod_quiz_preflight_form {
display: none;
}
#mod_quiz_preflight_form .femptylabel .fitemtitle {
display: none;
}
#mod_quiz_preflight_form .femptylabel .felement {
margin: 0;
padding: 0;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup {
width: 600px;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-wrap {
overflow: hidden;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd {
padding: 0;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd #mod_quiz_preflight_form legend {
padding: 0 10px;
margin: 0;
border: 0 none;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd #mod_quiz_preflight_form .fitem {
margin-left: 10px;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd #mod_quiz_preflight_form #fgroup_id_buttonar {
padding: 10px 0 0;
margin: 0;
}
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-content .moodle-dialogue-ft {
margin: 0;
}
/* Standard Moodle rule that needs to be more specific here. */
.moodle-dialogue-bd #mod_quiz_preflight_form fieldset.hidden {
display: inherit;
visibility: inherit;
}
body.path-mod-quiz .gradedattempt,
body.path-mod-quiz table tbody tr.gradedattempt > td {

View File

@ -0,0 +1,115 @@
@mod @mod_quiz
Feature: The various checks that may happen when an attept is started
As a student
In order to start a quiz with confidence
I need to be waned if there is a time limit, or various similar things
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student | Student | One | student@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| student | C1 | student |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | TF1 | Text of the first question |
@javascript
Scenario: Start a quiz with no time limit
Given the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
When I log in as "student"
And I follow "Course 1"
And I follow "Quiz 1"
And I press "Attempt quiz now"
Then I should see "Text of the first question"
@javascript
Scenario: Start a quiz with time limit and password
Given the following "activities" exist:
| activity | name | intro | course | idnumber | timelimit | quizpassword |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
When I log in as "student"
And I follow "Course 1"
And I follow "Quiz 1"
And I press "Attempt quiz now"
Then I should see "To attempt this quiz you need to know the quiz password" in the "Start attempt" "dialogue"
And I should see "The quiz has a time limit of 1 hour. Time will " in the "Start attempt" "dialogue"
And I set the field "Quiz password" to "Frog"
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
And I should see "Text of the first question"
@javascript
Scenario: Cancel starting a quiz with time limit and password
Given the following "activities" exist:
| activity | name | intro | course | idnumber | timelimit | quizpassword |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
When I log in as "student"
And I follow "Course 1"
And I follow "Quiz 1"
And I press "Attempt quiz now"
And I click on "Cancel" "button" in the "Start attempt" "dialogue"
Then I should see "Quiz 1 description"
And "Attempt quiz now" "button" should be visible
@javascript
Scenario: Start a quiz with time limit and password, get the password wrong first time
Given the following "activities" exist:
| activity | name | intro | course | idnumber | timelimit | quizpassword |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
When I log in as "student"
And I follow "Course 1"
And I follow "Quiz 1"
And I press "Attempt quiz now"
And I set the field "Quiz password" to "Toad"
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
Then I should see "Quiz 1 description"
And I should see "To attempt this quiz you need to know the quiz password"
And I should see "The quiz has a time limit of 1 hour. Time will "
And I should see "The password entered was incorrect"
And I set the field "Quiz password" to "Frog"
And I press "Start attempt"
And I should see "Text of the first question"
@javascript
Scenario: Start a quiz with time limit and password, get the password wrong first time then cancel
Given the following "activities" exist:
| activity | name | intro | course | idnumber | timelimit | quizpassword |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
When I log in as "student"
And I follow "Course 1"
And I follow "Quiz 1"
And I press "Attempt quiz now"
And I set the field "Quiz password" to "Toad"
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
And I should see "Quiz 1 description"
And I should see "To attempt this quiz you need to know the quiz password"
And I should see "The quiz has a time limit of 1 hour. Time will "
And I should see "The password entered was incorrect"
And I set the field "Quiz password" to "Frog"
And I press "Cancel"
Then I should see "Quiz 1 description"
And "Attempt quiz now" "button" should be visible

View File

@ -1,9 +1,18 @@
This files describes API changes in the quiz code.
=== 3.1 ===
* quiz_attempt::question_print_comment_fields() has been removed. It was broken
since at least Moodle 2.0.
* quiz::confirm_start_attempt_message and mod_quiz_view_object::$startattemptwarning
have been deprecated. This functionality is now entirely handled within the
quiz access rule plugins.
* The third argument to mod_quiz_renderer::start_attempt_button has been changed
from a warning string to a mod_quiz_preflight_check_form.
=== 2.9 ===
* There have been changes in classes/output/edit_renderer.php for MDL-40990.
@ -100,6 +109,7 @@ This files describes API changes in the quiz code.
trigger the event outside this function. Note that the appropriate start event is
fired automatically by the quiz_attempt_save_started function.
=== 2.7 ===
* The old quiz.questions database column (comma-separated list of question ids)
@ -130,6 +140,7 @@ This files describes API changes in the quiz code.
quiz_delete_empty_page: has had its arguments changed to $quiz and $pagenumber.
quiz_has_question_use: now takes $quiz and $slot, not $questionid.
=== 2.6 ===
* As part of improving the page usability and accessibility, we updated the

View File

@ -93,6 +93,7 @@ $viewobj->canreviewmine = $canreviewmine;
$attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true);
$lastfinishedattempt = end($attempts);
$unfinished = false;
$unfinishedattemptid = null;
if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) {
$attempts[] = $unfinishedattempt;
@ -105,6 +106,7 @@ if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id))
if (!$unfinished) {
$lastfinishedattempt = $unfinishedattempt;
}
$unfinishedattemptid = $unfinishedattempt->id;
$unfinishedattempt = null; // To make it clear we do not use this again.
}
$numattempts = count($attempts);
@ -177,7 +179,11 @@ $viewobj->canedit = has_capability('mod/quiz:manage', $context);
$viewobj->editurl = new moodle_url('/mod/quiz/edit.php', array('cmid' => $cm->id));
$viewobj->backtocourseurl = new moodle_url('/course/view.php', array('id' => $course->id));
$viewobj->startattempturl = $quizobj->start_attempt_url();
$viewobj->startattemptwarning = $quizobj->confirm_start_attempt_message($unfinished);
if ($accessmanager->is_preflight_check_required($unfinishedattemptid)) {
$viewobj->preflightcheckform = $accessmanager->get_preflight_check_form(
$viewobj->startattempturl, $unfinishedattemptid);
}
$viewobj->popuprequired = $accessmanager->attempt_must_be_in_popup();
$viewobj->popupoptions = $accessmanager->get_popup_options();