2008-12-17 16:37:35 +00:00
< ? php
2009-11-01 11:31:16 +00:00
// This file is part of Moodle - http://moodle.org/
//
2009-05-22 08:41:00 +00:00
// 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.
2009-11-01 11:31:16 +00:00
//
2009-05-22 08:41:00 +00:00
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Used for tracking conditions that apply before activities are displayed
* to students ( 'conditional availability' ) .
2009-11-01 11:31:16 +00:00
*
2009-05-22 08:41:00 +00:00
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas http :// dougiamas . com
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2008-12-17 16:37:35 +00:00
/** The activity is not displayed to students at all when conditions aren't met. */
define ( 'CONDITION_STUDENTVIEW_HIDE' , 0 );
/** The activity is displayed to students as a greyed - out name , with informational
text that explains the conditions under which it will be available . */
define ( 'CONDITION_STUDENTVIEW_SHOW' , 1 );
/** The $cm variable is expected to contain all completion-related data */
define ( 'CONDITION_MISSING_NOTHING' , 0 );
2009-11-01 11:31:16 +00:00
/** The $cm variable is expected to contain the fields from course_modules but
2008-12-17 16:37:35 +00:00
not the course_modules_availability data */
define ( 'CONDITION_MISSING_EXTRATABLE' , 1 );
/** The $cm variable is expected to contain nothing except the ID */
define ( 'CONDITION_MISSING_EVERYTHING' , 2 );
2009-05-22 08:41:00 +00:00
/**
* @ global stdClass $CONDITIONLIB_PRIVATE
* @ name $CONDITIONLIB_PRIVATE
*/
2009-05-15 13:31:41 +00:00
global $CONDITIONLIB_PRIVATE ;
$CONDITIONLIB_PRIVATE = new stdClass ;
// Caches whether completion values are used in availability conditions.
// Array of course => array of cmid => true.
$CONDITIONLIB_PRIVATE -> usedincondition = array ();
2009-05-22 08:41:00 +00:00
/**
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
*/
2008-12-17 16:37:35 +00:00
class condition_info {
2009-05-22 08:41:00 +00:00
/**
* @ var object , bool
*/
2009-04-17 14:32:50 +00:00
private $cm , $gotdata ;
2008-12-17 16:37:35 +00:00
/**
* Constructs with course - module details .
*
2009-05-22 08:41:00 +00:00
* @ global object
* @ uses CONDITION_MISSING_NOTHING
* @ uses CONDITION_MISSING_EVERYTHING
* @ uses DEBUG_DEVELOPER
* @ uses CONDITION_MISSING_EXTRATABLE
2008-12-17 16:37:35 +00:00
* @ param object $cm Moodle course - module object . May have extra fields
2009-11-01 11:31:16 +00:00
* -> conditionsgrade , -> conditionscompletion which should come from
* get_fast_modinfo . Should have -> availablefrom , -> availableuntil ,
2008-12-17 16:37:35 +00:00
* and -> showavailability , -> course ; but the only required thing is -> id .
* @ param int $expectingmissing Used to control whether or not a developer
2009-11-01 11:31:16 +00:00
* debugging message ( performance warning ) will be displayed if some of
* the above data is missing and needs to be retrieved ; a
2008-12-17 16:37:35 +00:00
* CONDITION_MISSING_xx constant
* @ param bool $loaddata If you need a 'write-only' object , set this value
* to false to prevent database access from constructor
* @ return condition_info Object which can retrieve information about the
* activity
*/
2009-04-17 14:32:50 +00:00
public function __construct ( $cm , $expectingmissing = CONDITION_MISSING_NOTHING ,
2008-12-17 16:37:35 +00:00
$loaddata = true ) {
global $DB ;
// Check ID as otherwise we can't do the other queries
2009-04-17 14:32:50 +00:00
if ( empty ( $cm -> id )) {
2008-12-17 16:37:35 +00:00
throw new coding_exception ( " Invalid parameters; course-module ID not included " );
}
// If not loading data, don't do anything else
2009-04-17 14:32:50 +00:00
if ( ! $loaddata ) {
$this -> cm = ( object ) array ( 'id' => $cm -> id );
$this -> gotdata = false ;
2008-12-17 16:37:35 +00:00
return ;
}
// Missing basic data from course_modules
2009-11-01 11:31:16 +00:00
if ( ! isset ( $cm -> availablefrom ) || ! isset ( $cm -> availableuntil ) ||
2008-12-17 16:37:35 +00:00
! isset ( $cm -> showavailability ) || ! isset ( $cm -> course )) {
2009-04-17 14:32:50 +00:00
if ( $expectingmissing < CONDITION_MISSING_EVERYTHING ) {
2009-11-01 11:31:16 +00:00
debugging ( ' Performance warning : condition_info constructor is
faster if you pass in $cm with at least basic fields
( availablefrom , availableuntil , showavailability , course ) .
2008-12-17 16:37:35 +00:00
[ This warning can be disabled , see phpdoc . ] ' ,
DEBUG_DEVELOPER );
}
2009-04-17 14:32:50 +00:00
$cm = $DB -> get_record ( 'course_modules' , array ( 'id' => $cm -> id ),
2008-12-17 16:37:35 +00:00
'id,course,availablefrom,availableuntil,showavailability' );
}
2009-04-17 14:32:50 +00:00
$this -> cm = clone ( $cm );
$this -> gotdata = true ;
2008-12-17 16:37:35 +00:00
// Missing extra data
2009-04-17 14:32:50 +00:00
if ( ! isset ( $cm -> conditionsgrade ) || ! isset ( $cm -> conditionscompletion )) {
if ( $expectingmissing < CONDITION_MISSING_EXTRATABLE ) {
2009-11-01 11:31:16 +00:00
debugging ( ' Performance warning : condition_info constructor is
2008-12-17 16:37:35 +00:00
faster if you pass in a $cm from get_fast_modinfo .
[ This warning can be disabled , see phpdoc . ] ' ,
DEBUG_DEVELOPER );
}
self :: fill_availability_conditions ( $this -> cm );
}
}
/**
2009-11-01 11:31:16 +00:00
* Adds the extra availability conditions ( if any ) into the given
2008-12-17 16:37:35 +00:00
* course - module object .
*
2009-05-22 08:41:00 +00:00
* @ global object
* @ global object
* @ param object $cm Moodle course - module data object
2008-12-17 16:37:35 +00:00
*/
public static function fill_availability_conditions ( & $cm ) {
2009-04-17 14:32:50 +00:00
if ( empty ( $cm -> id )) {
2008-12-17 16:37:35 +00:00
throw new coding_exception ( " Invalid parameters; course-module ID not included " );
}
// Does nothing if the variables are already present
2009-04-17 14:32:50 +00:00
if ( ! isset ( $cm -> conditionsgrade ) ||
2008-12-17 16:37:35 +00:00
! isset ( $cm -> conditionscompletion )) {
$cm -> conditionsgrade = array ();
$cm -> conditionscompletion = array ();
2009-04-17 14:32:50 +00:00
global $DB , $CFG ;
$conditions = $DB -> get_records_sql ( $sql = "
2009-11-01 11:31:16 +00:00
SELECT
2008-12-17 16:37:35 +00:00
cma . id as cmaid , gi .* , cma . sourcecmid , cma . requiredcompletion , cma . gradeitemid ,
cma . grademin as conditiongrademin , cma . grademax as conditiongrademax
FROM
{ course_modules_availability } cma
LEFT JOIN { grade_items } gi ON gi . id = cma . gradeitemid
WHERE
coursemoduleid = ? " ,array( $cm->id ));
2009-04-17 14:32:50 +00:00
foreach ( $conditions as $condition ) {
if ( ! is_null ( $condition -> sourcecmid )) {
$cm -> conditionscompletion [ $condition -> sourcecmid ] =
2008-12-17 16:37:35 +00:00
$condition -> requiredcompletion ;
2009-04-17 14:32:50 +00:00
} else {
$minmax = new stdClass ;
$minmax -> min = $condition -> conditiongrademin ;
$minmax -> max = $condition -> conditiongrademax ;
$minmax -> name = self :: get_grade_name ( $condition );
$cm -> conditionsgrade [ $condition -> gradeitemid ] = $minmax ;
2008-12-17 16:37:35 +00:00
}
}
}
}
2009-04-17 14:32:50 +00:00
2008-12-17 16:37:35 +00:00
/**
* Obtains the name of a grade item .
2009-05-22 08:41:00 +00:00
*
* @ global object
2008-12-17 16:37:35 +00:00
* @ param object $gradeitemobj Object from get_record on grade_items table ,
* ( can be empty if you want to just get ! missing )
* @ return string Name of item of ! missing if it didn ' t exist
*/
private static function get_grade_name ( $gradeitemobj ) {
global $CFG ;
2009-04-17 14:32:50 +00:00
if ( isset ( $gradeitemobj -> id )) {
2008-12-17 16:37:35 +00:00
require_once ( $CFG -> libdir . '/gradelib.php' );
2009-04-17 14:32:50 +00:00
$item = new grade_item ;
2009-11-01 11:31:16 +00:00
grade_object :: set_properties ( $item , $gradeitemobj );
2008-12-17 16:37:35 +00:00
return $item -> get_name ();
} else {
return '!missing' ; // Ooops, missing grade
}
}
/**
2009-05-22 08:41:00 +00:00
* @ see require_data ()
* @ return object A course - module object with all the information required to
2008-12-17 16:37:35 +00:00
* determine availability .
*/
public function get_full_course_module () {
$this -> require_data ();
return $this -> cm ;
}
/**
* Adds to the database a condition based on completion of another module .
2009-05-22 08:41:00 +00:00
*
* @ global object
2008-12-17 16:37:35 +00:00
* @ param int $cmid ID of other module
* @ param int $requiredcompletion COMPLETION_xx constant
*/
2009-04-17 14:32:50 +00:00
public function add_completion_condition ( $cmid , $requiredcompletion ) {
2008-12-17 16:37:35 +00:00
// Add to DB
global $DB ;
$DB -> insert_record ( 'course_modules_availability' ,
( object ) array ( 'coursemoduleid' => $this -> cm -> id ,
2009-04-17 14:32:50 +00:00
'sourcecmid' => $cmid , 'requiredcompletion' => $requiredcompletion ),
2008-12-17 16:37:35 +00:00
false );
// Store in memory too
2009-04-17 14:32:50 +00:00
$this -> cm -> conditionscompletion [ $cmid ] = $requiredcompletion ;
2008-12-17 16:37:35 +00:00
}
/**
* Adds to the database a condition based on the value of a grade item .
2009-05-22 08:41:00 +00:00
*
* @ global object
2008-12-17 16:37:35 +00:00
* @ param int $gradeitemid ID of grade item
* @ param float $min Minimum grade ( >= ), up to 5 decimal points , or null if none
* @ param float $max Maximum grade ( < ), up to 5 decimal points , or null if none
* @ param bool $updateinmemory If true , updates data in memory ; otherwise ,
* memory version may be out of date ( this has performance consequences ,
* so don ' t do it unless it really needs updating )
*/
2009-04-17 14:32:50 +00:00
public function add_grade_condition ( $gradeitemid , $min , $max , $updateinmemory = false ) {
2008-12-17 16:37:35 +00:00
// Normalise nulls
2009-04-17 14:32:50 +00:00
if ( $min === '' ) {
$min = null ;
2008-12-17 16:37:35 +00:00
}
2009-04-17 14:32:50 +00:00
if ( $max === '' ) {
$max = null ;
2008-12-17 16:37:35 +00:00
}
// Add to DB
global $DB ;
$DB -> insert_record ( 'course_modules_availability' ,
( object ) array ( 'coursemoduleid' => $this -> cm -> id ,
2009-04-17 14:32:50 +00:00
'gradeitemid' => $gradeitemid , 'grademin' => $min , 'grademax' => $max ),
2008-12-17 16:37:35 +00:00
false );
// Store in memory too
2009-04-17 14:32:50 +00:00
if ( $updateinmemory ) {
2008-12-17 16:37:35 +00:00
$this -> cm -> conditionsgrade [ $gradeitemid ] = ( object ) array (
2009-04-17 14:32:50 +00:00
'min' => $min , 'max' => $max );
$this -> cm -> conditionsgrade [ $gradeitemid ] -> name =
2008-12-17 16:37:35 +00:00
self :: get_grade_name ( $DB -> get_record ( 'grade_items' ,
array ( 'id' => $gradeitemid )));
}
}
/**
* Erases from the database all conditions for this activity .
2009-05-22 08:41:00 +00:00
*
* @ global object
2008-12-17 16:37:35 +00:00
*/
public function wipe_conditions () {
// Wipe from DB
global $DB ;
$DB -> delete_records ( 'course_modules_availability' ,
array ( 'coursemoduleid' => $this -> cm -> id ));
// And from memory
2009-04-17 14:32:50 +00:00
$this -> cm -> conditionsgrade = array ();
$this -> cm -> conditionscompletion = array ();
2008-12-17 16:37:35 +00:00
}
/**
* Obtains a string describing all availability restrictions ( even if
* they do not apply any more ) .
2009-05-22 08:41:00 +00:00
*
* @ global object
* @ global object
2008-12-17 16:37:35 +00:00
* @ param object $modinfo Usually leave as null for default . Specify when
2009-11-01 11:31:16 +00:00
* calling recursively from inside get_fast_modinfo . The value supplied
2008-12-17 16:37:35 +00:00
* here must include list of all CMs with 'id' and 'name'
2009-11-01 11:31:16 +00:00
* @ return string Information string ( for admin ) about all restrictions on
2008-12-17 16:37:35 +00:00
* this item
*/
public function get_full_information ( $modinfo = null ) {
2009-04-17 14:32:50 +00:00
$this -> require_data ();
global $COURSE , $DB ;
2008-12-17 16:37:35 +00:00
2009-04-17 14:32:50 +00:00
$information = '' ;
2008-12-17 16:37:35 +00:00
// Completion conditions
if ( count ( $this -> cm -> conditionscompletion ) > 0 ) {
2009-04-17 14:32:50 +00:00
if ( $this -> cm -> course == $COURSE -> id ) {
$course = $COURSE ;
2008-12-17 16:37:35 +00:00
} else {
2009-04-17 14:32:50 +00:00
$course = $DB -> get_record ( 'course' , array ( 'id' => $this -> cm -> course ), 'id,enablecompletion,modinfo' );
2008-12-17 16:37:35 +00:00
}
2009-04-17 14:32:50 +00:00
foreach ( $this -> cm -> conditionscompletion as $cmid => $expectedcompletion ) {
if ( ! $modinfo ) {
$modinfo = get_fast_modinfo ( $course );
2008-12-17 16:37:35 +00:00
}
2009-11-16 15:14:47 +00:00
if ( empty ( $modinfo -> cms [ $cmid ])) {
continue ;
}
2009-04-17 14:32:50 +00:00
$information .= get_string (
2008-12-17 16:37:35 +00:00
'requires_completion_' . $expectedcompletion ,
2009-04-17 14:32:50 +00:00
'condition' , $modinfo -> cms [ $cmid ] -> name ) . ' ' ;
2008-12-17 16:37:35 +00:00
}
}
// Grade conditions
2009-04-17 14:32:50 +00:00
if ( count ( $this -> cm -> conditionsgrade ) > 0 ) {
foreach ( $this -> cm -> conditionsgrade as $gradeitemid => $minmax ) {
2008-12-17 16:37:35 +00:00
// String depends on type of requirement. We are coy about
// the actual numbers, in case grades aren't released to
// students.
2009-04-17 14:32:50 +00:00
if ( is_null ( $minmax -> min ) && is_null ( $minmax -> max )) {
$string = 'any' ;
} else if ( is_null ( $minmax -> max )) {
$string = 'min' ;
} else if ( is_null ( $minmax -> min )) {
$string = 'max' ;
2008-12-17 16:37:35 +00:00
} else {
2009-04-17 14:32:50 +00:00
$string = 'range' ;
2008-12-17 16:37:35 +00:00
}
2009-04-17 14:32:50 +00:00
$information .= get_string ( 'requires_grade_' . $string , 'condition' , $minmax -> name ) . ' ' ;
2008-12-17 16:37:35 +00:00
}
}
// Dates
2009-04-17 16:06:29 +00:00
if ( $this -> cm -> availablefrom && $this -> cm -> availableuntil ) {
$information .= get_string ( 'requires_date_both' , 'condition' ,
( object ) array (
'from' => self :: show_time ( $this -> cm -> availablefrom , false ),
'until' => self :: show_time ( $this -> cm -> availableuntil , true )));
} else if ( $this -> cm -> availablefrom ) {
$information .= get_string ( 'requires_date' , 'condition' ,
self :: show_time ( $this -> cm -> availablefrom , false ));
} else if ( $this -> cm -> availableuntil ) {
$information .= get_string ( 'requires_date_before' , 'condition' ,
self :: show_time ( $this -> cm -> availableuntil , true ));
2008-12-17 16:37:35 +00:00
}
2009-04-17 14:32:50 +00:00
$information = trim ( $information );
2008-12-17 16:37:35 +00:00
return $information ;
}
/**
* Determines whether this particular course - module is currently available
2009-11-01 11:31:16 +00:00
* according to these criteria .
*
* - This does not include the 'visible' setting ( i . e . this might return
2008-12-17 16:37:35 +00:00
* true even if visible is false ); visible is handled independently .
* - This does not take account of the viewhiddenactivities capability .
* That should apply later .
*
2009-05-22 08:41:00 +00:00
* @ global object
* @ global object
* @ uses COMPLETION_COMPLETE
* @ uses COMPLETION_COMPLETE_FAIL
* @ uses COMPLETION_COMPLETE_PASS
* @ param string $information If the item has availability restrictions ,
2009-11-01 11:31:16 +00:00
* a string that describes the conditions will be stored in this variable ;
2008-12-17 16:37:35 +00:00
* if this variable is set blank , that means don ' t display anything
2009-11-01 11:31:16 +00:00
* @ param bool $grabthelot Performance hint : if true , caches information
2008-12-17 16:37:35 +00:00
* required for all course - modules , to make the front page and similar
* pages work more quickly ( works only for current user )
* @ param int $userid If set , specifies a different user ID to check availability for
* @ param object $modinfo Usually leave as null for default . Specify when
2009-11-01 11:31:16 +00:00
* calling recursively from inside get_fast_modinfo . The value supplied
2008-12-17 16:37:35 +00:00
* here must include list of all CMs with 'id' and 'name'
* @ return bool True if this item is available to the user , false otherwise
*/
2009-04-17 14:32:50 +00:00
public function is_available ( & $information , $grabthelot = false , $userid = 0 , $modinfo = null ) {
$this -> require_data ();
2008-12-17 16:37:35 +00:00
global $COURSE , $DB ;
2009-04-17 14:32:50 +00:00
$available = true ;
$information = '' ;
2008-12-17 16:37:35 +00:00
// Check each completion condition
if ( count ( $this -> cm -> conditionscompletion ) > 0 ) {
2009-04-17 14:32:50 +00:00
if ( $this -> cm -> course == $COURSE -> id ) {
$course = $COURSE ;
2008-12-17 16:37:35 +00:00
} else {
2009-04-17 14:32:50 +00:00
$course = $DB -> get_record ( 'course' , array ( 'id' => $this -> cm -> course ), 'id,enablecompletion,modinfo' );
2008-12-17 16:37:35 +00:00
}
2009-04-17 14:32:50 +00:00
$completion = new completion_info ( $course );
foreach ( $this -> cm -> conditionscompletion as $cmid => $expectedcompletion ) {
2009-11-16 15:14:47 +00:00
// If this depends on a deleted module, handle that situation
// gracefully.
if ( ! $modinfo ) {
$modinfo = get_fast_modinfo ( $course );
}
if ( empty ( $modinfo -> cms [ $cmid ])) {
global $PAGE ;
if ( isset ( $PAGE ) && strpos ( $PAGE -> pagetype , 'course-view-' ) === 0 ) {
debugging ( " Warning: activity { $this -> cm -> id } ' { $this -> cm -> name } ' has condition on deleted activity $cmid (to get rid of this message, edit the named activity) " );
}
continue ;
}
2008-12-17 16:37:35 +00:00
// The completion system caches its own data
2009-04-17 14:32:50 +00:00
$completiondata = $completion -> get_data (( object ) array ( 'id' => $cmid ),
$grabthelot , $userid , $modinfo );
2008-12-17 16:37:35 +00:00
2009-04-17 14:32:50 +00:00
$thisisok = true ;
if ( $expectedcompletion == COMPLETION_COMPLETE ) {
2008-12-17 16:37:35 +00:00
// 'Complete' also allows the pass, fail states
2009-04-17 14:32:50 +00:00
switch ( $completiondata -> completionstate ) {
2008-12-17 16:37:35 +00:00
case COMPLETION_COMPLETE :
case COMPLETION_COMPLETE_FAIL :
case COMPLETION_COMPLETE_PASS :
break ;
default :
2009-04-17 14:32:50 +00:00
$thisisok = false ;
2008-12-17 16:37:35 +00:00
}
} else {
// Other values require exact match
2009-04-17 14:32:50 +00:00
if ( $completiondata -> completionstate != $expectedcompletion ) {
$thisisok = false ;
2008-12-17 16:37:35 +00:00
}
}
2009-04-17 14:32:50 +00:00
if ( ! $thisisok ) {
$available = false ;
$information .= get_string (
2008-12-17 16:37:35 +00:00
'requires_completion_' . $expectedcompletion ,
'condition' , $modinfo -> cms [ $cmid ] -> name ) . ' ' ;
}
}
}
// Check each grade condition
2009-04-17 14:32:50 +00:00
if ( count ( $this -> cm -> conditionsgrade ) > 0 ) {
foreach ( $this -> cm -> conditionsgrade as $gradeitemid => $minmax ) {
$score = $this -> get_cached_grade_score ( $gradeitemid , $grabthelot , $userid );
if ( $score === false ||
2009-11-01 11:31:16 +00:00
( ! is_null ( $minmax -> min ) && $score < $minmax -> min ) ||
2008-12-17 16:37:35 +00:00
( ! is_null ( $minmax -> max ) && $score >= $minmax -> max )) {
// Grade fail
2009-04-17 14:32:50 +00:00
$available = false ;
2008-12-17 16:37:35 +00:00
// String depends on type of requirement. We are coy about
// the actual numbers, in case grades aren't released to
// students.
2009-04-17 14:32:50 +00:00
if ( is_null ( $minmax -> min ) && is_null ( $minmax -> max )) {
$string = 'any' ;
} else if ( is_null ( $minmax -> max )) {
$string = 'min' ;
} else if ( is_null ( $minmax -> min )) {
$string = 'max' ;
2008-12-17 16:37:35 +00:00
} else {
2009-04-17 14:32:50 +00:00
$string = 'range' ;
2008-12-17 16:37:35 +00:00
}
2009-04-17 14:32:50 +00:00
$information .= get_string ( 'requires_grade_' . $string , 'condition' , $minmax -> name ) . ' ' ;
2008-12-17 16:37:35 +00:00
}
}
}
// Test dates
2009-04-17 14:32:50 +00:00
if ( $this -> cm -> availablefrom ) {
if ( time () < $this -> cm -> availablefrom ) {
$available = false ;
2009-04-17 16:06:29 +00:00
$information .= get_string ( 'requires_date' , 'condition' ,
self :: show_time ( $this -> cm -> availablefrom , false ));
2008-12-17 16:37:35 +00:00
}
}
2009-04-17 14:32:50 +00:00
if ( $this -> cm -> availableuntil ) {
if ( time () >= $this -> cm -> availableuntil ) {
$available = false ;
2008-12-17 16:37:35 +00:00
// But we don't display any information about this case. This is
// because the only reason to set a 'disappear' date is usually
// to get rid of outdated information/clutter in which case there
// is no point in showing it...
// Note it would be nice if we could make it so that the 'until'
// date appears below the item while the item is still accessible,
// unfortunately this is not possible in the current system. Maybe
// later, or if somebody else wants to add it.
}
}
$information = trim ( $information );
return $available ;
}
2009-04-17 16:06:29 +00:00
/**
2009-11-01 11:31:16 +00:00
* Shows a time either as a date ( if it falls exactly on the day ) or
2009-04-17 16:06:29 +00:00
* a full date and time , according to user ' s timezone .
2009-05-22 08:41:00 +00:00
*
2009-04-17 16:06:29 +00:00
* @ param int $time Time
* @ param bool $until True if this date should be treated as the second of
* an inclusive pair - if so the time will be shown unless date is 23 : 59 : 59.
* Without this the date shows for 0 : 00 : 00.
* @ return string Date
*/
private function show_time ( $time , $until ) {
// Break down the time into fields
$userdate = usergetdate ( $time );
// Handle the 'inclusive' second date
if ( $until ) {
$dateonly = $userdate [ 'hours' ] == 23 && $userdate [ 'minutes' ] == 59 &&
$userdate [ 'seconds' ] == 59 ;
} else {
$dateonly = $userdate [ 'hours' ] == 0 && $userdate [ 'minutes' ] == 0 &&
$userdate [ 'seconds' ] == 0 ;
}
return userdate ( $time , get_string (
$dateonly ? 'strftimedate' : 'strftimedatetime' , 'langconfig' ));
}
2008-12-17 16:37:35 +00:00
/**
* @ return bool True if information about availability should be shown to
* normal users
* @ throws coding_exception If data wasn ' t loaded
*/
public function show_availability () {
$this -> require_data ();
return $this -> cm -> showavailability ;
}
2009-11-01 11:31:16 +00:00
2008-12-17 16:37:35 +00:00
/**
* Internal function cheks that data was loaded .
2009-05-22 08:41:00 +00:00
*
* @ return void throws coding_exception If data wasn ' t loaded
2008-12-17 16:37:35 +00:00
*/
private function require_data () {
2009-04-17 14:32:50 +00:00
if ( ! $this -> gotdata ) {
2008-12-17 16:37:35 +00:00
throw new coding_exception ( 'Error: cannot call when info was ' .
'constructed without data' );
}
}
/**
2009-11-01 11:31:16 +00:00
* Obtains a grade score . Note that this score should not be displayed to
* the user , because gradebook rules might prohibit that . It may be a
2008-12-17 16:37:35 +00:00
* non - final score subject to adjustment later .
*
2009-05-22 08:41:00 +00:00
* @ global object
* @ global object
* @ global object
2008-12-17 16:37:35 +00:00
* @ param int $gradeitemid Grade item ID we ' re interested in
2009-11-01 11:31:16 +00:00
* @ param bool $grabthelot If true , grabs all scores for current user on
2008-12-17 16:37:35 +00:00
* this course , so that later ones come from cache
2009-11-01 11:31:16 +00:00
* @ param int $userid Set if requesting grade for a different user ( does
2009-02-18 17:50:13 +00:00
* not use cache )
2009-11-01 11:31:16 +00:00
* @ return float Grade score as a percentage in range 0 - 100 ( e . g . 100.0
2009-02-18 17:50:13 +00:00
* or 37.21 ), or false if user does not have a grade yet
2008-12-17 16:37:35 +00:00
*/
2009-04-17 14:32:50 +00:00
private function get_cached_grade_score ( $gradeitemid , $grabthelot = false , $userid = 0 ) {
2008-12-17 16:37:35 +00:00
global $USER , $DB , $SESSION ;
2009-04-17 14:32:50 +00:00
if ( $userid == 0 || $userid = $USER -> id ) {
2008-12-17 16:37:35 +00:00
// For current user, go via cache in session
2009-04-17 14:32:50 +00:00
if ( empty ( $SESSION -> gradescorecache ) || $SESSION -> gradescorecacheuserid != $USER -> id ) {
$SESSION -> gradescorecache = array ();
$SESSION -> gradescorecacheuserid = $USER -> id ;
2009-11-01 11:31:16 +00:00
}
2009-04-17 14:32:50 +00:00
if ( ! array_key_exists ( $gradeitemid , $SESSION -> gradescorecache )) {
if ( $grabthelot ) {
2008-12-17 16:37:35 +00:00
// Get all grades for the current course
2009-04-17 14:32:50 +00:00
$rs = $DB -> get_recordset_sql ( "
2008-12-17 16:37:35 +00:00
SELECT
2009-11-01 11:31:16 +00:00
gi . id , gg . finalgrade , gg . rawgrademin , gg . rawgrademax
FROM
2008-12-17 16:37:35 +00:00
{ grade_items } gi
LEFT JOIN { grade_grades } gg ON gi . id = gg . itemid AND gg . userid = ?
WHERE
2009-04-17 14:32:50 +00:00
gi . courseid = ? " , array( $USER->id , $this->cm ->course));
foreach ( $rs as $record ) {
$SESSION -> gradescorecache [ $record -> id ] =
2008-12-17 16:37:35 +00:00
is_null ( $record -> finalgrade )
2009-02-18 17:50:13 +00:00
// No grade = false
2009-11-01 11:31:16 +00:00
? false
2009-02-18 17:50:13 +00:00
// Otherwise convert grade to percentage
: (( $record -> finalgrade - $record -> rawgrademin ) * 100 ) /
( $record -> rawgrademax - $record -> rawgrademin );
2008-12-17 16:37:35 +00:00
}
$rs -> close ();
// And if it's still not set, well it doesn't exist (eg
// maybe the user set it as a condition, then deleted the
// grade item) so we call it false
2009-04-17 14:32:50 +00:00
if ( ! array_key_exists ( $gradeitemid , $SESSION -> gradescorecache )) {
$SESSION -> gradescorecache [ $gradeitemid ] = false ;
2008-12-17 16:37:35 +00:00
}
} else {
// Just get current grade
2009-02-18 17:50:13 +00:00
$record = $DB -> get_record ( 'grade_grades' , array (
2009-04-17 14:32:50 +00:00
'userid' => $USER -> id , 'itemid' => $gradeitemid ));
2009-02-18 17:50:13 +00:00
if ( $record && ! is_null ( $record -> finalgrade )) {
$score = (( $record -> finalgrade - $record -> rawgrademin ) * 100 ) /
( $record -> rawgrademax - $record -> rawgrademin );
} else {
// Treat the case where row exists but is null, same as
// case where row doesn't exist
2009-04-17 14:32:50 +00:00
$score = false ;
2008-12-17 16:37:35 +00:00
}
$SESSION -> gradescorecache [ $gradeitemid ] = $score ;
}
}
return $SESSION -> gradescorecache [ $gradeitemid ];
} else {
// Not the current user, so request the score individually
2009-02-18 17:50:13 +00:00
$record = $DB -> get_record ( 'grade_grades' , array (
'userid' => $userid , 'itemid' => $gradeitemid ));
if ( $record && ! is_null ( $record -> finalgrade )) {
$score = (( $record -> finalgrade - $record -> rawgrademin ) * 100 ) /
( $record -> rawgrademax - $record -> rawgrademin );
} else {
// Treat the case where row exists but is null, same as
// case where row doesn't exist
2009-04-17 14:32:50 +00:00
$score = false ;
2008-12-17 16:37:35 +00:00
}
return $score ;
}
}
2009-11-01 11:31:16 +00:00
/**
* For testing only . Wipes information cached in user session .
2009-05-22 08:41:00 +00:00
*
* @ global object
*/
2008-12-17 16:37:35 +00:00
static function wipe_session_cache () {
global $SESSION ;
unset ( $SESSION -> gradescorecache );
unset ( $SESSION -> gradescorecacheuserid );
}
/**
2009-11-01 11:31:16 +00:00
* Utility function called by modedit . php ; updates the
2008-12-17 16:37:35 +00:00
* course_modules_availability table based on the module form data .
*
* @ param object $cm Course - module with as much data as necessary , min id
2009-05-22 08:41:00 +00:00
* @ param object $fromform
* @ param bool $wipefirst Defaults to true
2008-12-17 16:37:35 +00:00
*/
2009-04-17 14:32:50 +00:00
public static function update_cm_from_form ( $cm , $fromform , $wipefirst = true ) {
$ci = new condition_info ( $cm , CONDITION_MISSING_EVERYTHING , false );
if ( $wipefirst ) {
2008-12-17 16:37:35 +00:00
$ci -> wipe_conditions ();
}
2009-04-17 14:32:50 +00:00
foreach ( $fromform -> conditiongradegroup as $record ) {
2008-12-17 16:37:35 +00:00
if ( $record [ 'conditiongradeitemid' ]) {
$ci -> add_grade_condition ( $record [ 'conditiongradeitemid' ],
$record [ 'conditiongrademin' ], $record [ 'conditiongrademax' ]);
}
}
2009-04-17 14:32:50 +00:00
if ( isset ( $fromform -> conditioncompletiongroup )) {
2008-12-17 16:37:35 +00:00
foreach ( $fromform -> conditioncompletiongroup as $record ) {
if ( $record [ 'conditionsourcecmid' ]) {
$ci -> add_completion_condition ( $record [ 'conditionsourcecmid' ],
$record [ 'conditionrequiredcompletion' ]);
}
}
}
}
2009-01-15 17:09:02 +00:00
/**
* Used in course / lib . php because we need to disable the completion JS if
* a completion value affects a conditional activity .
2009-05-22 08:41:00 +00:00
*
* @ global object
2009-01-15 17:09:02 +00:00
* @ param object $course Moodle course object
* @ param object $cm Moodle course - module
* @ return bool True if this is used in a condition , false otherwise
*/
2009-04-17 14:32:50 +00:00
public static function completion_value_used_as_condition ( $course , $cm ) {
2009-01-15 17:09:02 +00:00
// Have we already worked out a list of required completion values
// for this course? If so just use that
2009-05-15 13:31:41 +00:00
global $CONDITIONLIB_PRIVATE ;
if ( ! array_key_exists ( $course -> id , $CONDITIONLIB_PRIVATE -> usedincondition )) {
2009-01-15 17:09:02 +00:00
// We don't have data for this course, build it
$modinfo = get_fast_modinfo ( $course );
2009-05-15 13:31:41 +00:00
$CONDITIONLIB_PRIVATE -> usedincondition [ $course -> id ] = array ();
foreach ( $modinfo -> cms as $othercm ) {
foreach ( $othercm -> conditionscompletion as $cmid => $expectedcompletion ) {
$CONDITIONLIB_PRIVATE -> usedincondition [ $course -> id ][ $cmid ] = true ;
2009-01-15 17:09:02 +00:00
}
}
}
2009-05-15 13:31:41 +00:00
return array_key_exists ( $cm -> id , $CONDITIONLIB_PRIVATE -> usedincondition [ $course -> id ]);
2009-01-15 17:09:02 +00:00
}
2008-12-17 16:37:35 +00:00
}