2006-02-24 10:21:40 +00:00
< ? php // $Id$
/**
2007-05-03 10:10:01 +00:00
* Functions used to show question editing interface
2007-03-19 17:22:46 +00:00
*
*
* @ author Martin Dougiamas and many others . This has recently been extensively
* rewritten by members of the Serving Mathematics project
* { @ link http :// maths . york . ac . uk / serving_maths }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU Public License
* @ package questionbank
*/
2006-02-24 10:21:40 +00:00
2006-05-02 12:26:03 +00:00
require_once ( $CFG -> libdir . '/questionlib.php' );
2006-02-24 10:21:40 +00:00
2006-06-12 13:54:01 +00:00
define ( 'DEFAULT_QUESTIONS_PER_PAGE' , 20 );
2007-05-03 05:17:07 +00:00
function get_module_from_cmid ( $cmid ){
global $CFG ;
if ( ! $cmrec = get_record_sql ( " SELECT cm.*, md.name as modname
FROM { $CFG -> prefix } course_modules cm ,
{ $CFG -> prefix } modules md
WHERE cm . id = '$cmid' AND
md . id = cm . module " )) {
2008-04-04 02:54:20 +00:00
print_error ( 'cmunknown' );
2007-05-03 05:17:07 +00:00
} elseif ( ! $modrec = get_record ( $cmrec -> modname , 'id' , $cmrec -> instance )) {
2008-04-04 02:54:20 +00:00
print_error ( 'cmunknown' );
2007-05-03 05:17:07 +00:00
}
$modrec -> instance = $modrec -> id ;
2007-06-15 10:25:09 +00:00
$modrec -> cmid = $cmrec -> id ;
2007-11-20 14:46:50 +00:00
$cmrec -> name = $modrec -> name ;
2007-08-09 21:51:09 +00:00
2007-05-03 05:17:07 +00:00
return array ( $modrec , $cmrec );
}
2006-05-02 12:26:03 +00:00
/**
* Function to read all questions for category into big array
*
* @ param int $category category number
2006-05-13 08:49:46 +00:00
* @ param bool $noparent if true only questions with NO parent will be selected
* @ param bool $recurse include subdirectories
2007-03-28 11:58:44 +00:00
* @ param bool $export set true if this is called by questionbank export
2006-05-02 12:26:03 +00:00
* @ author added by Howard Miller June 2004
*/
2007-03-28 11:58:44 +00:00
function get_questions_category ( $category , $noparent = false , $recurse = true , $export = true ) {
2006-05-02 12:26:03 +00:00
global $QTYPES ;
// questions will be added to an array
$qresults = array ();
// build sql bit for $noparent
$npsql = '' ;
if ( $noparent ) {
$npsql = " and parent='0' " ;
}
2006-05-13 08:49:46 +00:00
// get (list) of categories
if ( $recurse ) {
$categorylist = question_categorylist ( $category -> id );
}
else {
$categorylist = $category -> id ;
}
2006-05-02 12:26:03 +00:00
// get the list of questions for the category
2006-05-13 08:49:46 +00:00
if ( $questions = get_records_select ( " question " , " category IN ( $categorylist ) $npsql " , " qtype, name ASC " )) {
2006-05-02 12:26:03 +00:00
// iterate through questions, getting stuff we need
foreach ( $questions as $question ) {
$questiontype = $QTYPES [ $question -> qtype ];
2007-03-28 11:58:44 +00:00
$question -> export_process = $export ;
2006-05-02 12:26:03 +00:00
$questiontype -> get_question_options ( $question );
$qresults [] = $question ;
}
}
return $qresults ;
}
2007-08-09 21:51:09 +00:00
function question_can_delete_cat ( $todelete ){
global $CFG ;
2007-08-11 14:28:36 +00:00
$record = get_record_sql ( " SELECT count(*) as count, c1.contextid as contextid FROM { $CFG -> prefix } question_categories c1,
{ $CFG -> prefix } question_categories c2 WHERE c2 . id = $todelete
2007-08-09 21:51:09 +00:00
AND c1 . contextid = c2 . contextid GROUP BY c1 . contextid " );
$contextid = $record -> contextid ;
$count = $record -> count ;
if ( $count < 2 ) {
2008-04-23 13:42:50 +00:00
error ( 'You can\'t delete that category it is the default category for this context.' );
2007-08-09 21:51:09 +00:00
} else {
require_capability ( 'moodle/question:managecategory' , get_context_instance_by_id ( $contextid ));
}
}
2006-05-02 12:26:03 +00:00
/**
* prints a form to choose categories
*/
2007-08-09 21:51:09 +00:00
function question_category_form ( $contexts , $pageurl , $current , $recurse = 1 , $showhidden = false , $showquestiontext = false ) {
2006-02-24 10:35:28 +00:00
global $CFG ;
2006-02-24 10:21:40 +00:00
/// Get all the existing categories now
2007-08-09 21:51:09 +00:00
$catmenu = question_category_options ( $contexts , false , 0 , true );
2006-03-03 15:20:48 +00:00
2007-08-09 21:51:09 +00:00
$strcategory = get_string ( 'category' , 'quiz' );
$strshow = get_string ( 'show' , 'quiz' );
$streditcats = get_string ( 'editcategories' , 'quiz' );
2006-02-24 10:21:40 +00:00
2007-08-09 21:51:09 +00:00
popup_form ( 'edit.php?' . $pageurl -> get_query_string () . '&category=' , $catmenu , 'catmenu' , $current , '' , '' , '' , false , 'self' , " <strong> $strcategory </strong> " );
2007-01-08 07:58:22 +00:00
2007-05-22 13:24:51 +00:00
echo '<form method="get" action="edit.php" id="displayoptions">' ;
2007-01-08 07:58:22 +00:00
echo " <fieldset class='invisiblefieldset'> " ;
2007-05-04 10:46:33 +00:00
echo $pageurl -> hidden_params_out ( array ( 'recurse' , 'showhidden' , 'showquestiontext' ));
2007-02-20 01:48:09 +00:00
question_category_form_checkbox ( 'recurse' , $recurse );
question_category_form_checkbox ( 'showhidden' , $showhidden );
question_category_form_checkbox ( 'showquestiontext' , $showquestiontext );
echo '<noscript><div class="centerpara"><input type="submit" value="' . get_string ( 'go' ) . '" />' ;
echo '</div></noscript></fieldset></form>' ;
}
/**
* Private funciton to help the preceeding function .
*/
function question_category_form_checkbox ( $name , $checked ) {
echo '<div><input type="hidden" id="' . $name . '_off" name="' . $name . '" value="0" />' ;
echo '<input type="checkbox" id="' . $name . '_on" name="' . $name . '" value="1"' ;
if ( $checked ) {
2006-02-24 10:21:40 +00:00
echo ' checked="checked"' ;
}
2007-01-06 19:22:58 +00:00
echo ' onchange="getElementById(\'displayoptions\').submit(); return true;" />' ;
2007-02-20 01:48:09 +00:00
echo '<label for="' . $name . '_on">' ;
print_string ( $name , 'quiz' );
echo " </label></div> \n " ;
2006-02-24 10:21:40 +00:00
}
/**
* Prints the table of questions in a category with interactions
*
* @ param object $course The course object
* @ param int $categoryid The id of the question category to be displayed
2007-05-03 05:17:07 +00:00
* @ param int $cm The course module record if we are in the context of a particular module , 0 otherwise
2006-02-24 10:21:40 +00:00
* @ param int $recurse This is 1 if subcategories should be included , 0 otherwise
* @ param int $page The number of the page to be displayed
* @ param int $perpage Number of questions to show per page
* @ param boolean $showhidden True if also hidden questions should be displayed
2007-04-11 22:57:46 +00:00
* @ param boolean $showquestiontext whether the text of each question should be shown in the list
2006-02-24 10:21:40 +00:00
*/
2007-08-09 21:51:09 +00:00
function question_list ( $contexts , $pageurl , $categoryandcontext , $cm = null ,
2007-05-04 10:46:33 +00:00
$recurse = 1 , $page = 0 , $perpage = 100 , $showhidden = false , $sortorder = 'typename' , $sortorderdecoded = 'qtype, name ASC' ,
2007-08-09 21:51:09 +00:00
$showquestiontext = false , $addcontexts = array ()) {
2008-02-28 12:53:02 +00:00
global $USER , $CFG , $THEME , $COURSE ;
2007-08-09 21:51:09 +00:00
list ( $categoryid , $contextid ) = explode ( ',' , $categoryandcontext );
2008-02-28 12:53:02 +00:00
$qtypemenu = question_type_menu ();
2007-05-24 07:10:22 +00:00
2006-02-24 10:21:40 +00:00
$strcategory = get_string ( " category " , " quiz " );
$strquestion = get_string ( " question " , " quiz " );
$straddquestions = get_string ( " addquestions " , " quiz " );
$strimportquestions = get_string ( " importquestions " , " quiz " );
$strexportquestions = get_string ( " exportquestions " , " quiz " );
$strnoquestions = get_string ( " noquestions " , " quiz " );
$strselect = get_string ( " select " , " quiz " );
$strselectall = get_string ( " selectall " , " quiz " );
$strselectnone = get_string ( " selectnone " , " quiz " );
$strcreatenewquestion = get_string ( " createnewquestion " , " quiz " );
$strquestionname = get_string ( " questionname " , " quiz " );
$strdelete = get_string ( " delete " );
$stredit = get_string ( " edit " );
2007-08-09 21:51:09 +00:00
$strmove = get_string ( 'moveqtoanothercontext' , 'question' );
$strview = get_string ( " view " );
2006-02-24 10:21:40 +00:00
$straction = get_string ( " action " );
$strrestore = get_string ( 'restore' );
$strtype = get_string ( " type " , " quiz " );
$strcreatemultiple = get_string ( " createmultiple " , " quiz " );
$strpreview = get_string ( " preview " , " quiz " );
if ( ! $categoryid ) {
2007-01-08 07:58:22 +00:00
echo " <p style= \" text-align:center; \" ><b> " ;
2006-02-24 10:21:40 +00:00
print_string ( " selectcategoryabove " , " quiz " );
echo " </b></p> " ;
return ;
}
2007-08-09 21:51:09 +00:00
if ( ! $category = get_record ( 'question_categories' , 'id' , $categoryid , 'contextid' , $contextid )) {
2007-04-11 22:57:46 +00:00
notify ( 'Category not found!' );
2006-02-24 10:21:40 +00:00
return ;
}
2007-08-09 21:51:09 +00:00
$catcontext = get_context_instance_by_id ( $contextid );
$canadd = has_capability ( 'moodle/question:add' , $catcontext );
//check for capabilities on all questions in category, will also apply to sub cats.
$caneditall = has_capability ( 'moodle/question:editall' , $catcontext );
$canuseall = has_capability ( 'moodle/question:useall' , $catcontext );
$canmoveall = has_capability ( 'moodle/question:moveall' , $catcontext );
2007-05-03 05:17:07 +00:00
if ( $cm AND $cm -> modname == 'quiz' ) {
$quizid = $cm -> instance ;
} else {
$quizid = 0 ;
2007-04-11 22:57:46 +00:00
}
2007-08-09 21:51:09 +00:00
$returnurl = $pageurl -> out ();
$questionurl = new moodle_url ( " $CFG->wwwroot /question/question.php " ,
array ( 'returnurl' => $returnurl ));
if ( $cm !== null ){
$questionurl -> param ( 'cmid' , $cm -> id );
} else {
$questionurl -> param ( 'courseid' , $COURSE -> id );
}
$questionmoveurl = new moodle_url ( " $CFG->wwwroot /question/contextmoveq.php " ,
array ( 'returnurl' => $returnurl ));
if ( $cm !== null ){
$questionmoveurl -> param ( 'cmid' , $cm -> id );
} else {
$questionmoveurl -> param ( 'courseid' , $COURSE -> id );
}
2007-01-09 09:07:16 +00:00
echo '<div class="boxaligncenter">' ;
2006-08-18 21:23:15 +00:00
$formatoptions = new stdClass ;
2006-03-19 19:49:37 +00:00
$formatoptions -> noclean = true ;
2007-08-09 21:51:09 +00:00
echo format_text ( $category -> info , FORMAT_MOODLE , $formatoptions , $COURSE -> id );
2006-02-24 10:21:40 +00:00
echo '<table><tr>' ;
2007-08-09 21:51:09 +00:00
if ( $canadd ) {
2006-02-24 10:21:40 +00:00
echo '<td valign="top" align="right">' ;
2007-08-09 21:51:09 +00:00
popup_form ( $questionurl -> out ( false , array ( 'category' => $category -> id )) . '&qtype=' , $qtypemenu , " addquestion " , " " , " choose " , " " , " " , false , " self " , " <strong> $strcreatenewquestion </strong> " );
2007-02-20 01:48:09 +00:00
echo '</td><td valign="top" align="right">' ;
2006-02-24 10:21:40 +00:00
helpbutton ( " questiontypes " , $strcreatenewquestion , " quiz " );
2007-04-11 22:57:46 +00:00
echo '</td>' ;
2006-02-24 10:21:40 +00:00
}
else {
2007-04-11 22:57:46 +00:00
echo '<td>' ;
2007-08-09 21:51:09 +00:00
print_string ( 'nopermissionadd' , 'question' );
2007-04-11 22:57:46 +00:00
echo '</td>' ;
2006-02-24 10:21:40 +00:00
}
2007-04-11 22:57:46 +00:00
echo '</tr></table>' ;
2007-01-09 09:07:16 +00:00
echo '</div>' ;
2006-02-24 10:21:40 +00:00
2006-03-01 07:03:57 +00:00
$categorylist = ( $recurse ) ? question_categorylist ( $category -> id ) : $category -> id ;
2006-02-24 10:21:40 +00:00
// hide-feature
$showhidden = $showhidden ? '' : " AND hidden = '0' " ;
2006-02-28 09:26:00 +00:00
if ( ! $totalnumber = count_records_select ( 'question' , " category IN ( $categorylist ) AND parent = '0' $showhidden " )) {
2007-01-08 07:58:22 +00:00
echo " <p style= \" text-align:center; \" > " ;
2006-02-24 10:21:40 +00:00
print_string ( " noquestions " , " quiz " );
echo " </p> " ;
return ;
}
2007-05-04 10:46:33 +00:00
if ( ! $questions = get_records_select ( 'question' , " category IN ( $categorylist ) AND parent = '0' $showhidden " , $sortorderdecoded , '*' , $page * $perpage , $perpage )) {
2006-02-24 10:21:40 +00:00
// There are no questions on the requested page.
$page = 0 ;
2007-05-04 10:46:33 +00:00
if ( ! $questions = get_records_select ( 'question' , " category IN ( $categorylist ) AND parent = '0' $showhidden " , $sortorderdecoded , '*' , 0 , $perpage )) {
2006-02-24 10:21:40 +00:00
// There are no questions at all
2007-01-08 07:58:22 +00:00
echo " <p style= \" text-align:center; \" > " ;
2006-02-24 10:21:40 +00:00
print_string ( " noquestions " , " quiz " );
echo " </p> " ;
return ;
}
}
2007-05-03 10:10:01 +00:00
print_paging_bar ( $totalnumber , $page , $perpage , $pageurl , 'qpage' );
2006-02-24 10:21:40 +00:00
2007-08-09 21:51:09 +00:00
echo question_sort_options ( $pageurl , $sortorder );
2007-05-03 05:17:07 +00:00
echo '<form method="post" action="edit.php">' ;
2007-02-20 01:48:09 +00:00
echo '<fieldset class="invisiblefieldset" style="display: block;">' ;
2006-02-24 10:21:40 +00:00
echo '<input type="hidden" name="sesskey" value="' . $USER -> sesskey . '" />' ;
2007-11-20 15:54:34 +00:00
echo $pageurl -> hidden_params_out ();
2007-02-20 01:48:09 +00:00
echo '<table id="categoryquestions" style="width: 100%"><tr>' ;
echo " <th style= \" white-space:nowrap; \" class= \" header \" scope= \" col \" > $straction </th> " ;
2007-08-09 21:51:09 +00:00
echo " <th style= \" white-space:nowrap; text-align: left; \" class= \" header \" scope= \" col \" > $strquestionname </th>
2007-02-20 01:48:09 +00:00
< th style = \ " white-space:nowrap; text-align: right; \" class= \" header \" scope= \" col \" > $strtype </th> " ;
2006-02-24 10:21:40 +00:00
echo " </tr> \n " ;
foreach ( $questions as $question ) {
2007-02-20 01:48:09 +00:00
$nameclass = '' ;
$textclass = '' ;
if ( $question -> hidden ) {
$nameclass = 'dimmed_text' ;
$textclass = 'dimmed_text' ;
}
if ( $showquestiontext ) {
$nameclass .= ' header' ;
}
if ( $nameclass ) {
$nameclass = 'class="' . $nameclass . '"' ;
}
if ( $textclass ) {
$textclass = 'class="' . $textclass . '"' ;
}
2007-08-09 21:51:09 +00:00
2007-02-20 01:48:09 +00:00
echo " <tr> \n <td style= \" white-space:nowrap; \" $nameclass > \n " ;
2007-08-09 21:51:09 +00:00
$canuseq = question_has_capability_on ( $question , 'use' , $question -> category );
2007-05-07 16:57:23 +00:00
if ( function_exists ( 'module_specific_actions' )) {
2007-08-09 21:51:09 +00:00
echo module_specific_actions ( $pageurl , $question -> id , $cm -> id , $canuseq );
2006-02-24 10:21:40 +00:00
}
2007-08-09 21:51:09 +00:00
2006-08-21 08:40:06 +00:00
// preview
2007-08-09 21:51:09 +00:00
if ( $canuseq ) {
2007-08-14 04:22:05 +00:00
$quizorcourseid = $quizid ? ( '&quizid=' . $quizid ) : ( '&courseid=' . $COURSE -> id );
link_to_popup_window ( '/question/preview.php?id=' . $question -> id . $quizorcourseid , 'questionpreview' ,
2007-08-09 21:51:09 +00:00
" <img src= \" $CFG->pixpath /t/preview.gif \" class= \" iconsmall \" alt= \" $strpreview\ " /> " ,
0 , 0 , $strpreview , QUESTION_PREVIEW_POPUP_OPTIONS );
}
2006-08-21 08:40:06 +00:00
// edit, hide, delete question, using question capabilities, not quiz capabilieies
2007-08-09 21:51:09 +00:00
if ( question_has_capability_on ( $question , 'edit' , $question -> category ) || question_has_capability_on ( $question , 'move' , $question -> category )) {
echo " <a title= \" $stredit\ " href = \ " " . $questionurl -> out ( false , array ( 'id' => $question -> id )) . " \" ><img
2007-01-08 07:58:22 +00:00
src = \ " $CFG->pixpath /t/edit.gif \" alt= \" $stredit\ " /></ a >& nbsp ; " ;
2007-08-09 21:51:09 +00:00
} elseif ( question_has_capability_on ( $question , 'view' , $question -> category )){
echo " <a title= \" $strview\ " href = \ " " . $questionurl -> out ( false , array ( 'id' => $question -> id )) . " \" ><img
src = \ " $CFG->pixpath /i/info.gif \" alt= \" $strview\ " /></ a >& nbsp ; " ;
}
if ( question_has_capability_on ( $question , 'move' , $question -> category ) && question_has_capability_on ( $question , 'view' , $question -> category )) {
echo " <a title= \" $strmove\ " href = \ " " . $questionurl -> out ( false , array ( 'id' => $question -> id , 'movecontext' => 1 )) . " \" ><img
src = \ " $CFG->pixpath /t/move.gif \" alt= \" $strmove\ " /></ a >& nbsp ; " ;
}
if ( question_has_capability_on ( $question , 'edit' , $question -> category )) {
2006-02-24 10:21:40 +00:00
// hide-feature
if ( $question -> hidden ) {
2007-05-03 05:17:07 +00:00
echo " <a title= \" $strrestore\ " href = \ " edit.php? " . $pageurl -> get_query_string () . " &unhide= $question->id &sesskey= $USER->sesskey\ " >< img
2007-01-08 07:58:22 +00:00
src = \ " $CFG->pixpath /t/restore.gif \" alt= \" $strrestore\ " /></ a > " ;
2006-02-24 10:21:40 +00:00
} else {
2007-05-03 05:17:07 +00:00
echo " <a title= \" $strdelete\ " href = \ " edit.php? " . $pageurl -> get_query_string () . " &deleteselected= $question->id &q $question->id =1 \" ><img
2007-01-08 07:58:22 +00:00
src = \ " $CFG->pixpath /t/delete.gif \" alt= \" $strdelete\ " /></ a > " ;
2006-02-24 10:21:40 +00:00
}
}
2007-08-09 21:51:09 +00:00
if ( $caneditall || $canmoveall || $canuseall ){
echo " <input title= \" $strselect\ " type = \ " checkbox \" name= \" q $question->id\ " value = \ " 1 \" /> " ;
}
2006-02-24 10:21:40 +00:00
echo " </td> \n " ;
2007-03-13 16:20:41 +00:00
echo " <td $nameclass > " . format_string ( $question -> name ) . " </td> \n " ;
2007-02-20 01:48:09 +00:00
echo " <td $nameclass style='text-align: right'> \n " ;
2007-04-11 22:57:46 +00:00
print_question_icon ( $question );
2006-02-24 10:21:40 +00:00
echo " </td> \n " ;
echo " </tr> \n " ;
2007-02-20 01:48:09 +00:00
if ( $showquestiontext ){
echo '<tr><td colspan="3" ' . $textclass . '>' ;
$formatoptions = new stdClass ;
$formatoptions -> noclean = true ;
$formatoptions -> para = false ;
echo format_text ( $question -> questiontext , $question -> questiontextformat ,
2007-08-09 21:51:09 +00:00
$formatoptions , $COURSE -> id );
2007-02-20 01:48:09 +00:00
echo " </td></tr> \n " ;
}
2006-02-24 10:21:40 +00:00
}
2007-02-20 01:48:09 +00:00
echo " </table> \n " ;
2007-08-09 21:51:09 +00:00
$paging = print_paging_bar ( $totalnumber , $page , $perpage , $pageurl , 'qpage' , false , true );
2006-06-12 13:54:01 +00:00
if ( $totalnumber > DEFAULT_QUESTIONS_PER_PAGE ) {
if ( $perpage == DEFAULT_QUESTIONS_PER_PAGE ) {
2007-05-03 10:10:01 +00:00
$showall = '<a href="edit.php?' . $pageurl -> get_query_string ( array ( 'qperpage' => 1000 )) . '">' . get_string ( 'showall' , 'moodle' , $totalnumber ) . '</a>' ;
2006-06-12 13:54:01 +00:00
} else {
2007-05-03 10:10:01 +00:00
$showall = '<a href="edit.php?' . $pageurl -> get_query_string ( array ( 'qperpage' => DEFAULT_QUESTIONS_PER_PAGE )) . '">' . get_string ( 'showperpage' , 'moodle' , DEFAULT_QUESTIONS_PER_PAGE ) . '</a>' ;
2007-02-20 01:48:09 +00:00
}
if ( $paging ) {
$paging = substr ( $paging , 0 , strrpos ( $paging , '</div>' ));
$paging .= " <br /> $showall </div> " ;
} else {
2007-08-09 21:51:09 +00:00
$paging = " <div class='paging'> $showall </div> " ;
2006-06-12 13:54:01 +00:00
}
2006-03-19 19:23:07 +00:00
}
2007-02-20 01:48:09 +00:00
echo $paging ;
2006-02-24 10:21:40 +00:00
2007-08-09 21:51:09 +00:00
if ( $caneditall || $canmoveall || $canuseall ){
2007-09-19 17:44:52 +00:00
echo '<a href="javascript:select_all_in(\'TABLE\',null,\'categoryquestions\');">' . $strselectall . '</a> /' .
' <a href="javascript:deselect_all_in(\'TABLE\',null,\'categoryquestions\');">' . $strselectnone . '</a>' ;
2007-08-09 21:51:09 +00:00
echo '<br />' ;
echo '<strong> ' . get_string ( 'withselected' , 'quiz' ) . ':</strong><br />' ;
2006-12-22 00:54:03 +00:00
2007-08-09 21:51:09 +00:00
if ( function_exists ( 'module_specific_buttons' )) {
echo module_specific_buttons ( $cm -> id );
}
// print delete and move selected question
if ( $caneditall ) {
echo '<input type="submit" name="deleteselected" value="' . $strdelete . " \" /> \n " ;
}
if ( $canmoveall && count ( $addcontexts )) {
echo '<input type="submit" name="move" value="' . get_string ( 'moveto' , 'quiz' ) . " \" /> \n " ;
question_category_select_menu ( $addcontexts , false , 0 , " $category->id , $category->contextid " );
}
2006-02-24 10:21:40 +00:00
2007-08-09 21:51:09 +00:00
if ( function_exists ( 'module_specific_controls' ) && $canuseall ) {
echo module_specific_controls ( $totalnumber , $recurse , $category , $cm -> id );
}
2006-02-24 10:21:40 +00:00
}
2007-01-09 09:07:16 +00:00
echo '</fieldset>' ;
echo " </form> \n " ;
2006-02-24 10:21:40 +00:00
}
2007-08-09 21:51:09 +00:00
function question_sort_options ( $pageurl , $sortorder ){
global $USER ;
//sort options
$html = " <div class= \" mdl-align \" > " ;
$html .= '<form method="post" action="edit.php">' ;
$html .= '<fieldset class="invisiblefieldset" style="display: block;">' ;
$html .= '<input type="hidden" name="sesskey" value="' . $USER -> sesskey . '" />' ;
$html .= $pageurl -> hidden_params_out ( array ( 'qsortorder' ));
$sortoptions = array ( 'alpha' => get_string ( " sortalpha " , " quiz " ),
'typealpha' => get_string ( " sorttypealpha " , " quiz " ),
'age' => get_string ( " sortage " , " quiz " ));
$html .= choose_from_menu ( $sortoptions , 'qsortorder' , $sortorder , false , 'this.form.submit();' , '0' , true );
$html .= '<noscript><div><input type="submit" value="' . get_string ( " sortsubmit " , " quiz " ) . '" /></div></noscript>' ;
$html .= '</fieldset>' ;
$html .= " </form> \n " ;
$html .= " </div> \n " ;
return $html ;
}
2007-05-03 05:17:07 +00:00
2007-08-09 21:51:09 +00:00
function question_showbank_actions ( $pageurl , $cm ){
2007-10-03 04:42:57 +00:00
global $CFG , $COURSE ;
2007-08-09 21:51:09 +00:00
/// Now, check for commands on this page and modify variables as necessary
2008-04-23 13:45:38 +00:00
if ( optional_param ( 'move' , false , PARAM_BOOL ) and confirm_sesskey ()) { /// Move selected questions to new category
2007-08-09 21:51:09 +00:00
$category = required_param ( 'category' , PARAM_SEQUENCE );
list ( $tocategoryid , $contextid ) = explode ( ',' , $category );
if ( ! $tocategory = get_record ( 'question_categories' , 'id' , $tocategoryid , 'contextid' , $contextid )) {
2008-04-23 13:42:50 +00:00
error ( 'Could not find category record' );
2007-05-03 05:17:07 +00:00
}
2007-08-09 21:51:09 +00:00
$tocontext = get_context_instance_by_id ( $contextid );
require_capability ( 'moodle/question:add' , $tocontext );
2008-04-23 13:45:38 +00:00
$rawdata = ( array ) data_submitted ();
2007-08-09 21:51:09 +00:00
$questionids = array ();
2008-04-23 13:45:38 +00:00
foreach ( $rawdata as $key => $value ) { // Parse input for question ids
2007-05-04 08:33:28 +00:00
if ( preg_match ( '!^q([0-9]+)$!' , $key , $matches )) {
2007-05-03 10:10:01 +00:00
$key = $matches [ 1 ];
2007-08-09 21:51:09 +00:00
$questionids [] = $key ;
}
}
if ( $questionids ){
$questionidlist = join ( $questionids , ',' );
$sql = " SELECT q.*, c.contextid FROM { $CFG -> prefix } question q, { $CFG -> prefix } question_categories c WHERE q.id IN ( $questionidlist ) AND c.id = q.category " ;
if ( ! $questions = get_records_sql ( $sql )){
print_error ( 'questiondoesnotexist' , 'question' , $pageurl -> out ());
}
$checkforfiles = false ;
foreach ( $questions as $question ){
//check capabilities
question_require_capability_on ( $question , 'move' );
$fromcontext = get_context_instance_by_id ( $question -> contextid );
if ( get_filesdir_from_context ( $fromcontext ) != get_filesdir_from_context ( $tocontext )){
$checkforfiles = true ;
}
}
$returnurl = $pageurl -> out ( false , array ( 'category' => " $tocategoryid , $contextid " ));
if ( ! $checkforfiles ){
foreach ( $questionids as $questionid ){
//move question
if ( ! set_field ( 'question' , 'category' , $tocategory -> id , 'id' , $questionid )) {
2008-04-23 13:42:50 +00:00
error ( 'Could not update category field' );
2007-08-09 21:51:09 +00:00
}
}
redirect ( $returnurl );
} else {
$movecontexturl = new moodle_url ( $CFG -> wwwroot . '/question/contextmoveq.php' ,
array ( 'returnurl' => $returnurl ,
'ids' => $questionidlist ,
'tocatid' => $tocategoryid ));
if ( $cm ){
$movecontexturl -> param ( 'cmid' , $cm -> id );
} else {
$movecontexturl -> param ( 'courseid' , $COURSE -> id );
2007-05-03 05:17:07 +00:00
}
2007-08-09 21:51:09 +00:00
redirect ( $movecontexturl -> out ());
2007-05-03 05:17:07 +00:00
}
}
}
2008-04-23 13:45:38 +00:00
if ( optional_param ( 'deleteselected' , false , PARAM_BOOL )) { // delete selected questions from the category
if (( $confirm = optional_param ( 'confirm' , '' , PARAM_ALPHANUM )) and confirm_sesskey ()) { // teacher has already confirmed the action
2007-05-03 05:17:07 +00:00
$deleteselected = required_param ( 'deleteselected' );
2008-04-23 13:45:38 +00:00
if ( $confirm == md5 ( $deleteselected )) {
2007-05-03 05:17:07 +00:00
if ( $questionlist = explode ( ',' , $deleteselected )) {
// for each question either hide it if it is in use or delete it
foreach ( $questionlist as $questionid ) {
2007-08-09 21:51:09 +00:00
question_require_capability_on ( $questionid , 'edit' );
2008-04-23 13:45:38 +00:00
if ( record_exists ( 'quiz_question_instances' , 'question' , $questionid )) {
2007-05-03 05:17:07 +00:00
if ( ! set_field ( 'question' , 'hidden' , 1 , 'id' , $questionid )) {
2007-08-09 21:51:09 +00:00
question_require_capability_on ( $questionid , 'edit' );
2008-04-23 13:42:50 +00:00
error ( 'Was not able to hide question' );
2007-05-03 05:17:07 +00:00
}
} else {
delete_question ( $questionid );
}
}
}
redirect ( $pageurl -> out ());
} else {
2008-04-23 13:42:50 +00:00
error ( " Confirmation string was incorrect " );
2007-05-03 05:17:07 +00:00
}
}
}
// Unhide a question
2008-04-23 13:45:38 +00:00
if (( $unhide = optional_param ( 'unhide' , '' , PARAM_INT )) and confirm_sesskey ()) {
2007-08-09 21:51:09 +00:00
question_require_capability_on ( $unhide , 'edit' );
2007-05-03 05:17:07 +00:00
if ( ! set_field ( 'question' , 'hidden' , 0 , 'id' , $unhide )) {
2008-04-23 13:42:50 +00:00
error ( " Failed to unhide the question. " );
2007-05-03 05:17:07 +00:00
}
redirect ( $pageurl -> out ());
}
2007-08-09 21:51:09 +00:00
}
2008-04-23 13:45:38 +00:00
2007-08-09 21:51:09 +00:00
/**
* Shows the question bank editing interface .
*
* The function also processes a number of actions :
*
* Actions affecting the question pool :
* move Moves a question to a different category
* deleteselected Deletes the selected questions from the category
* Other actions :
* category Chooses the category
* displayoptions Sets display options
*
* @ author Martin Dougiamas and many others . This has recently been extensively
* rewritten by Gustav Delius and other members of the Serving Mathematics project
* { @ link http :// maths . york . ac . uk / serving_maths }
* @ param moodle_url $pageurl object representing this pages url .
*/
function question_showbank ( $tabname , $contexts , $pageurl , $cm , $page , $perpage , $sortorder , $sortorderdecoded , $cat , $recurse , $showhidden , $showquestiontext ){
global $COURSE ;
2008-04-23 13:45:38 +00:00
if ( optional_param ( 'deleteselected' , false , PARAM_BOOL )){ // teacher still has to confirm
2007-08-09 21:51:09 +00:00
// make a list of all the questions that are selected
2008-04-23 13:45:38 +00:00
$rawquestions = ( array ) data_submitted ();
2007-08-09 21:51:09 +00:00
$questionlist = '' ; // comma separated list of ids of questions to be deleted
$questionnames = '' ; // string with names of questions separated by <br /> with
// an asterix in front of those that are in use
$inuse = false ; // set to true if at least one of the questions is in use
foreach ( $rawquestions as $key => $value ) { // Parse input for question ids
if ( preg_match ( '!^q([0-9]+)$!' , $key , $matches )) {
2008-04-23 13:45:38 +00:00
$key = $matches [ 1 ];
$questionlist .= $key . ',' ;
2007-08-09 21:51:09 +00:00
question_require_capability_on ( $key , 'edit' );
2008-04-23 13:45:38 +00:00
if ( record_exists ( 'quiz_question_instances' , 'question' , $key )) {
2007-08-09 21:51:09 +00:00
$questionnames .= '* ' ;
$inuse = true ;
}
$questionnames .= get_field ( 'question' , 'name' , 'id' , $key ) . '<br />' ;
}
}
if ( ! $questionlist ) { // no questions were selected
redirect ( $pageurl -> out ());
}
$questionlist = rtrim ( $questionlist , ',' );
// Add an explanation about questions in use
if ( $inuse ) {
$questionnames .= '<br />' . get_string ( 'questionsinuse' , 'quiz' );
}
notice_yesno ( get_string ( " deletequestionscheck " , " quiz " , $questionnames ),
$pageurl -> out_action ( array ( 'deleteselected' => $questionlist , 'confirm' => md5 ( $questionlist ))),
$pageurl -> out_action ());
echo '</td></tr>' ;
echo '</table>' ;
print_footer ( $COURSE );
exit ;
}
2007-05-03 05:17:07 +00:00
// starts with category selection form
print_box_start ( 'generalbox questionbank' );
print_heading ( get_string ( 'questionbank' , 'question' ), '' , 2 );
2007-08-09 21:51:09 +00:00
question_category_form ( $contexts -> having_one_edit_tab_cap ( $tabname ), $pageurl , $cat , $recurse , $showhidden , $showquestiontext );
2007-05-03 05:17:07 +00:00
// continues with list of questions
2007-08-09 21:51:09 +00:00
question_list ( $contexts -> having_one_edit_tab_cap ( $tabname ), $pageurl , $cat , isset ( $cm ) ? $cm : null ,
$recurse , $page , $perpage , $showhidden , $sortorder , $sortorderdecoded , $showquestiontext ,
$contexts -> having_cap ( 'moodle/question:add' ));
2007-05-03 05:17:07 +00:00
print_box_end ();
}
2007-05-03 10:10:01 +00:00
/**
* Common setup for all pages for editing questions .
2007-08-09 21:51:09 +00:00
* @ param string $edittab code for this edit tab
2007-05-03 10:10:01 +00:00
* @ param boolean $requirecmid require cmid ? default false
* @ param boolean $requirecourseid require courseid , if cmid is not given ? default true
2007-08-09 21:51:09 +00:00
* @ return array $thispageurl , $contexts , $cmid , $cm , $module , $pagevars
2007-05-03 10:10:01 +00:00
*/
2007-08-09 21:51:09 +00:00
function question_edit_setup ( $edittab , $requirecmid = false , $requirecourseid = true ){
global $COURSE , $QUESTION_EDITTABCAPS ;
//$thispageurl is used to construct urls for all question edit pages we link to from this page. It contains an array
2007-05-04 10:46:33 +00:00
//of parameters that are passed from page to page.
2007-05-03 10:10:01 +00:00
$thispageurl = new moodle_url ();
if ( $requirecmid ){
$cmid = required_param ( 'cmid' , PARAM_INT );
} else {
$cmid = optional_param ( 'cmid' , 0 , PARAM_INT );
}
if ( $cmid ){
2007-08-09 21:51:09 +00:00
list ( $module , $cm ) = get_module_from_cmid ( $cmid );
2007-05-03 10:10:01 +00:00
$courseid = $cm -> course ;
$thispageurl -> params ( compact ( 'cmid' ));
2007-08-09 21:51:09 +00:00
require_login ( $courseid , false , $cm );
$thiscontext = get_context_instance ( CONTEXT_MODULE , $cmid );
2007-05-03 10:10:01 +00:00
} else {
$module = null ;
$cm = null ;
if ( $requirecourseid ){
$courseid = required_param ( 'courseid' , PARAM_INT );
} else {
$courseid = optional_param ( 'courseid' , 0 , PARAM_INT );
}
if ( $courseid ){
$thispageurl -> params ( compact ( 'courseid' ));
2007-08-09 21:51:09 +00:00
require_login ( $courseid , false );
$thiscontext = get_context_instance ( CONTEXT_COURSE , $courseid );
} else {
$thiscontext = null ;
2007-05-03 10:10:01 +00:00
}
}
2007-08-09 21:51:09 +00:00
if ( $thiscontext ){
$contexts = new question_edit_contexts ( $thiscontext );
$contexts -> require_one_edit_tab_cap ( $edittab );
} else {
$contexts = null ;
}
2007-05-04 10:46:33 +00:00
$pagevars [ 'qpage' ] = optional_param ( 'qpage' , - 1 , PARAM_INT );
2007-08-09 21:51:09 +00:00
2007-05-07 04:55:55 +00:00
//pass 'cat' from page to page and when 'category' comes from a drop down menu
2007-08-09 21:51:09 +00:00
//then we also reset the qpage so we go to page 1 of
2007-05-07 04:55:55 +00:00
//a new cat.
2007-08-09 21:51:09 +00:00
$pagevars [ 'cat' ] = optional_param ( 'cat' , 0 , PARAM_SEQUENCE ); // if empty will be set up later
if ( $category = optional_param ( 'category' , 0 , PARAM_SEQUENCE )){
2008-02-05 12:14:46 +00:00
if ( $pagevars [ 'cat' ] != $category ){ // is this a move to a new category?
$pagevars [ 'cat' ] = $category ;
$pagevars [ 'qpage' ] = 0 ;
}
2007-05-07 04:55:55 +00:00
}
if ( $pagevars [ 'cat' ]){
$thispageurl -> param ( 'cat' , $pagevars [ 'cat' ]);
}
2007-05-03 10:10:01 +00:00
if ( $pagevars [ 'qpage' ] > - 1 ) {
$thispageurl -> param ( 'qpage' , $pagevars [ 'qpage' ]);
} else {
$pagevars [ 'qpage' ] = 0 ;
}
2007-05-04 10:46:33 +00:00
$pagevars [ 'qperpage' ] = optional_param ( 'qperpage' , - 1 , PARAM_INT );
2007-05-03 10:10:01 +00:00
if ( $pagevars [ 'qperpage' ] > - 1 ) {
$thispageurl -> param ( 'qperpage' , $pagevars [ 'qperpage' ]);
} else {
$pagevars [ 'qperpage' ] = DEFAULT_QUESTIONS_PER_PAGE ;
}
2007-08-09 21:51:09 +00:00
2007-05-04 10:46:33 +00:00
$sortoptions = array ( 'alpha' => 'name, qtype ASC' ,
'typealpha' => 'qtype, name ASC' ,
'age' => 'id ASC' );
if ( $sortorder = optional_param ( 'qsortorder' , '' , PARAM_ALPHA )) {
$pagevars [ 'qsortorderdecoded' ] = $sortoptions [ $sortorder ];
$pagevars [ 'qsortorder' ] = $sortorder ;
$thispageurl -> param ( 'qsortorder' , $sortorder );
2007-05-03 10:10:01 +00:00
} else {
2007-05-07 04:55:55 +00:00
$pagevars [ 'qsortorderdecoded' ] = $sortoptions [ 'typealpha' ];
$pagevars [ 'qsortorder' ] = 'typealpha' ;
2007-08-09 21:51:09 +00:00
}
2007-05-04 10:46:33 +00:00
2007-08-09 21:51:09 +00:00
$defaultcategory = question_make_default_categories ( $contexts -> all ());
$contextlistarr = array ();
foreach ( $contexts -> having_one_edit_tab_cap ( $edittab ) as $context ){
$contextlistarr [] = " ' $context->id ' " ;
}
$contextlist = join ( $contextlistarr , ' ,' );
if ( ! empty ( $pagevars [ 'cat' ])){
$catparts = explode ( ',' , $pagevars [ 'cat' ]);
if ( ! $catparts [ 0 ] || ( FALSE !== array_search ( $catparts [ 1 ], $contextlistarr )) || ! count_records_select ( " question_categories " , " id = ' " . $catparts [ 0 ] . " ' AND contextid = $catparts[1] " )) {
2008-04-04 02:54:20 +00:00
print_error ( 'invalidcategory' , 'quiz' );
2007-08-09 21:51:09 +00:00
}
} else {
$category = $defaultcategory ;
$pagevars [ 'cat' ] = " $category->id , $category->contextid " ;
2007-05-04 10:46:33 +00:00
}
if (( $recurse = optional_param ( 'recurse' , - 1 , PARAM_BOOL )) != - 1 ) {
$pagevars [ 'recurse' ] = $recurse ;
$thispageurl -> param ( 'recurse' , $recurse );
} else {
$pagevars [ 'recurse' ] = 1 ;
}
2007-08-09 21:51:09 +00:00
2007-05-04 10:46:33 +00:00
if (( $showhidden = optional_param ( 'showhidden' , - 1 , PARAM_BOOL )) != - 1 ) {
$pagevars [ 'showhidden' ] = $showhidden ;
$thispageurl -> param ( 'showhidden' , $showhidden );
} else {
$pagevars [ 'showhidden' ] = 0 ;
}
2007-08-09 21:51:09 +00:00
2007-05-04 10:46:33 +00:00
if (( $showquestiontext = optional_param ( 'showquestiontext' , - 1 , PARAM_BOOL )) != - 1 ) {
$pagevars [ 'showquestiontext' ] = $showquestiontext ;
$thispageurl -> param ( 'showquestiontext' , $showquestiontext );
} else {
$pagevars [ 'showquestiontext' ] = 0 ;
}
2007-08-09 21:51:09 +00:00
2007-05-07 05:53:20 +00:00
//category list page
$pagevars [ 'cpage' ] = optional_param ( 'cpage' , 1 , PARAM_INT );
if ( $pagevars [ 'cpage' ] != 1 ){
$thispageurl -> param ( 'cpage' , $pagevars [ 'cpage' ]);
}
2007-05-04 10:46:33 +00:00
2007-08-09 21:51:09 +00:00
return array ( $thispageurl , $contexts , $cmid , $cm , $module , $pagevars );
}
class question_edit_contexts {
var $allcontexts ;
/**
* @ param current context
*/
function question_edit_contexts ( $thiscontext ){
$pcontextids = get_parent_contexts ( $thiscontext );
$contexts = array ( $thiscontext );
foreach ( $pcontextids as $pcontextid ){
$contexts [] = get_context_instance_by_id ( $pcontextid );
}
$this -> allcontexts = $contexts ;
}
/**
* @ return array all parent contexts
*/
function all (){
return $this -> allcontexts ;
}
/**
* @ return object lowest context which must be either the module or course context
*/
function lowest (){
return $this -> allcontexts [ 0 ];
}
/**
* @ param string $cap capability
* @ return array parent contexts having capability , zero based index
*/
function having_cap ( $cap ){
$contextswithcap = array ();
foreach ( $this -> allcontexts as $context ){
if ( has_capability ( $cap , $context )){
$contextswithcap [] = $context ;
}
}
return $contextswithcap ;
}
/**
* @ param array $caps capabilities
* @ return array parent contexts having at least one of $caps , zero based index
*/
function having_one_cap ( $caps ){
$contextswithacap = array ();
foreach ( $this -> allcontexts as $context ){
foreach ( $caps as $cap ){
if ( has_capability ( $cap , $context )){
$contextswithacap [] = $context ;
break ; //done with caps loop
}
}
}
return $contextswithacap ;
}
/**
* @ param string $tabname edit tab name
* @ return array parent contexts having at least one of $caps , zero based index
*/
function having_one_edit_tab_cap ( $tabname ){
global $QUESTION_EDITTABCAPS ;
return $this -> having_one_cap ( $QUESTION_EDITTABCAPS [ $tabname ]);
}
/**
* Has at least one parent context got the cap $cap ?
*
* @ param string $cap capability
* @ return boolean
*/
function have_cap ( $cap ){
return ( count ( $this -> having_cap ( $cap )));
}
/**
* Has at least one parent context got one of the caps $caps ?
*
* @ param string $cap capability
* @ return boolean
*/
function have_one_cap ( $caps ){
foreach ( $caps as $cap ){
if ( $this -> have_cap ( $cap )){
return true ;
}
}
return false ;
}
/**
* Has at least one parent context got one of the caps for actions on $tabname
*
* @ param string $tabname edit tab name
* @ return boolean
*/
function have_one_edit_tab_cap ( $tabname ){
global $QUESTION_EDITTABCAPS ;
return $this -> have_one_cap ( $QUESTION_EDITTABCAPS [ $tabname ]);
}
/**
* Throw error if at least one parent context hasn ' t got the cap $cap
*
* @ param string $cap capability
*/
function require_cap ( $cap ){
if ( ! $this -> have_cap ( $cap )){
print_error ( 'nopermissions' , '' , '' , $cap );
}
}
/**
* Throw error if at least one parent context hasn ' t got one of the caps $caps
*
* @ param array $cap capabilities
*/
function require_one_cap ( $caps ){
if ( ! $this -> have_one_cap ( $caps )){
$capsstring = join ( $caps , ', ' );
print_error ( 'nopermissions' , '' , '' , $capsstring );
}
}
/**
* Throw error if at least one parent context hasn ' t got one of the caps $caps
*
* @ param string $tabname edit tab name
*/
function require_one_edit_tab_cap ( $tabname ){
if ( ! $this -> have_one_edit_tab_cap ( $tabname )){
print_error ( 'nopermissions' , '' , '' , 'access question edit tab ' . $tabname );
}
}
}
//capabilities for each page of edit tab.
//this determines which contexts' categories are available. At least one
//page is displayed if user has one of the capability on at least one context
$QUESTION_EDITTABCAPS = array (
'editq' => array ( 'moodle/question:add' ,
'moodle/question:editmine' ,
'moodle/question:editall' ,
'moodle/question:viewmine' ,
'moodle/question:viewall' ,
'moodle/question:usemine' ,
'moodle/question:useall' ,
'moodle/question:movemine' ,
'moodle/question:moveall' ),
'questions' => array ( 'moodle/question:add' ,
'moodle/question:editmine' ,
'moodle/question:editall' ,
'moodle/question:viewmine' ,
'moodle/question:viewall' ,
'moodle/question:movemine' ,
'moodle/question:moveall' ),
'categories' => array ( 'moodle/question:managecategory' ),
'import' => array ( 'moodle/question:add' ),
'export' => array ( 'moodle/question:viewall' , 'moodle/question:viewmine' ));
/**
* Make sure user is logged in as required in this context .
*/
function require_login_in_context ( $contextorid = null ){
if ( ! is_object ( $contextorid )){
$context = get_context_instance_by_id ( $contextorid );
} else {
$context = $contextorid ;
}
if ( $context && ( $context -> contextlevel == CONTEXT_COURSE )) {
require_login ( $context -> instanceid );
} else if ( $context && ( $context -> contextlevel == CONTEXT_MODULE )) {
if ( $cm = get_record ( 'course_modules' , 'id' , $context -> instanceid )) {
if ( ! $course = get_record ( 'course' , 'id' , $cm -> course )) {
2008-04-04 02:54:20 +00:00
print_error ( 'Incorrect course.' );
2007-08-09 21:51:09 +00:00
}
require_course_login ( $course , true , $cm );
} else {
2008-04-04 02:54:20 +00:00
print_error ( 'Incorrect course module id.' );
2007-08-09 21:51:09 +00:00
}
} else if ( $context && ( $context -> contextlevel == CONTEXT_SYSTEM )) {
if ( ! empty ( $CFG -> forcelogin )) {
require_login ();
}
} else {
require_login ();
}
2007-05-03 10:10:01 +00:00
}
2007-08-11 14:28:36 +00:00
?>