Source for file module_choice.php

Documentation is available at module_choice.php

  1. <?php
  2.     // This file is part of the Sloodle project (www.sloodle.org)
  3.     
  4.     /**
  5.     * This file defines a choice module for Sloodle.
  6.     *
  7.     * @package sloodle
  8.     * @copyright Copyright (c) 2008 Sloodle (various contributors)
  9.     * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
  10.     *
  11.     * @contributor Peter R. Bloomfield
  12.     */
  13.     
  14.     /** The Sloodle module base. */
  15.     require_once(SLOODLE_LIBROOT.'/modules/module_base.php');
  16.     /** General Sloodle functions. */
  17.     require_once(SLOODLE_LIBROOT.'/general.php');
  18.     
  19.     /** Include the standard Moodle choice module library. */
  20.     require_once($CFG->dirroot.'/mod/choice/lib.php');
  21.     
  22.     /**
  23.     * The Sloodle choice module class.
  24.     * @package sloodle
  25.     */
  26.     class SloodleModuleChoice extends SloodleModule
  27.     {
  28.     // DATA //
  29.     
  30.         /**
  31.         * Internal for Moodle only - course module instance.
  32.         * Corresponds to one record from the Moodle 'course_modules' table.
  33.         * @var object 
  34.         * @access private
  35.         */
  36.         var $cm = null;
  37.     
  38.         /**
  39.         * Internal only - Moodle choice module instance database object.
  40.         * Corresponds to one record from the Moodle 'choice' table.
  41.         * @var object 
  42.         * @access private
  43.         */
  44.         var $moodle_choice_instance = null;
  45.  
  46.         /**
  47.         * The number of (non-admin) users on the course who have not yet answered this choice.
  48.         * @var int 
  49.         * @access private
  50.         */
  51.         var $numunanswered = 0;
  52.         
  53.         /**
  54.         * The options available for this choice, as an associative array of IDs to {@link SloodleChoiceOption} objects.
  55.         * @var array 
  56.         * @access public
  57.         */
  58.         var $options = array();
  59.                 
  60.         
  61.     // FUNCTIONS //
  62.     
  63.         /**
  64.         * Constructor
  65.         */
  66.         function SloodleModuleChoice(&$_session)
  67.         {
  68.             $constructor get_parent_class($this);
  69.             parent::$constructor($_session);
  70.         }
  71.         
  72.         /**
  73.         * Loads data from the database.
  74.         * Note: even if the function fails, it may still have overwritten some or all existing data in the object.
  75.         * @param mixed $id The site-wide unique identifier for all modules. Type depends on VLE. On Moodle, it is an integer course module identifier ('id' field of 'course_modules' table)
  76.         * @return bool True if successful, or false otherwise
  77.         */
  78.         function load($id)
  79.         {
  80.             // Make sure the ID is valid
  81.             $id = (int)$id;
  82.             if ($id <= 0return false;
  83.             
  84.             // Fetch the course module data
  85.             if (!($this->cm = get_coursemodule_from_id('choice'$id))) {
  86.                 sloodle_debug("Failed to load course module instance #$id.<br/>");
  87.                 return false;
  88.             }
  89.             // Make sure the module is visible
  90.             if ($this->cm->visible == 0{
  91.                 sloodle_debug("Error: course module instance #$id not visible.<br/>");
  92.                 return false;
  93.             }
  94.             
  95.             // Load from the primary table: choice instance
  96.             if (!($this->moodle_choice_instance = get_record('choice''id'$this->cm->instance))) {
  97.                 sloodle_debug("Failed to load choice with instance ID #{$cm->instance}.<br/>");
  98.                 return false;
  99.             }
  100.             
  101.             // Fetch options
  102.             $this->options = array();
  103.             if ($options get_records('choice_options''choiceid'$this->moodle_choice_instance->id)) {
  104.                 foreach ($options as $opt{
  105.                     // Create our option object and add our data
  106.                     $this->options[$opt->idnew SloodleChoiceOption();
  107.                     $this->options[$opt->id]->id $opt->id;
  108.                     $this->options[$opt->id]->text $opt->text;
  109.                     $this->options[$opt->id]->maxselections $opt->maxanswers;
  110.                     $this->options[$opt->id]->numselections = (int)count_records('choice_answers''optionid'$opt->id);
  111.                     $this->options[$opt->id]->timemodified = (int)$opt->timemodified;
  112.                 }
  113.             }
  114.             
  115.             // Determine how many people on the course have not yet answered
  116.             $users get_course_users($this->cm->course);
  117.             if (!is_array($users)) return false;
  118.             $num_users count($users);
  119.             $numanswers = (int)count_records('choice_answers''choiceid'$this->moodle_choice_instance->id);
  120.             $this->numunanswered = max(0$num_users $numanswers);
  121.             
  122.             return true;
  123.         }
  124.         
  125.         /**
  126.         * Selects an option in this choice on behalf of the specified user.
  127.         * Logs the user in to the VLE if necessary.
  128.         * If a general error occurs, FALSE will be returned.
  129.         * Otherwise, an integer {@link http://slisweb.sjsu.edu/sl/index.php/Sloodle_status_codes status code} will be returned.
  130.         * The following status codes are typical responses:
  131.         *  * 10011 = added new choice selection
  132.         *  * 10012 = updated existing choice selection
  133.         *  * 10013 = user previously selected same option
  134.         *  * -10011 = User already made a selection, and re-selection is not allowed
  135.         *  * -10012 = max number of selections for this option already made
  136.         *  * -10013 = choice is not yet open
  137.         *  * -10014 = choice is already closed
  138.         *
  139.         * @param mixed $optionid The unique site-wide identifier of the option to be selected
  140.         * @param mixed $user A SloodleUser identifying the current user; if omitted, the current {@link SloodleSession} will be used.
  141.         * @return integer|false
  142.         */
  143.         function select_option($optionid$user null)
  144.         {
  145.             // Fetch a user if necessary
  146.             if ($user === null{
  147.                 // Make sure we have a session user
  148.                 if (!isset($this->_session->user)) return false;
  149.                 $user $this->_session->user;
  150.             }
  151.             // Make sure we have a user loaded and logged-in
  152.             if (!$user->is_user_loaded()) return false;
  153.             if (!$user->login()) return false;
  154.             
  155.             // Make sure the user is permitted to select from this choice
  156.             if (!has_capability('mod/choice:choose'get_context_instance(CONTEXT_MODULE$this->cm->id))) return -331;
  157.             // Make sure the choice is open
  158.             if ($this->is_early()) return -10013;
  159.             if ($this->is_late()) return -10014;
  160.             
  161.             // Has the user already made a selection for this choice?
  162.             $update_selection false;
  163.             $previous_selection get_record('choice_answers''choiceid'$this->moodle_choice_instance->id'userid'$user->get_user_id());
  164.             if ($previous_selection{
  165.                 // Was it a selection of the same option?
  166.                 if ($previous_selection->optionid == $optionid{
  167.                     // Yes - that's fine. Nothing to do.
  168.                     return 10013;
  169.                 }
  170.                 // No - are re-selections allowed?
  171.                 if (!$this->allow_update()) {
  172.                     // No - stop here
  173.                     return -10011;
  174.                 }
  175.                 $update_selection true;
  176.             }
  177.             
  178.             // Fetch the option record
  179.             $option get_record('choice_options''id'$optionid'choiceid'$this->moodle_choice_instance->id);
  180.             if (!$optionreturn false;
  181.             
  182.             // Make sure the maximum selections for the given option have not yet been made
  183.             if (!empty($this->moodle_choice_instance->limitanswers)) {
  184.                 $numselections count_records('choice_answers''optionid'$optionid);
  185.                 if (!$numselectionsreturn false;
  186.                 if ($numselections >= $option->maxanswersreturn -10012;
  187.             }
  188.             
  189.             // If necessary, delete the existing selection
  190.             if ($update_selectiondelete_records('choice_answers''choiceid'$this->moodle_choice_instance->id'userid'$user->get_user_id());
  191.             
  192.             // Select the new option
  193.             $selection new stdClass();
  194.             $selection->choiceid $this->moodle_choice_instance->id;
  195.             $selection->userid $user->get_user_id();
  196.             $selection->optionid $optionid;
  197.             $selection->timemodified time();
  198.             if (!insert_record('choice_answers'$selection)) return false;
  199.             
  200.             // Success!
  201.             if ($update_selectionreturn 10012;
  202.             return 10011;
  203.         }
  204.         
  205.         
  206.     // ACCESSORS //
  207.     
  208.         /**
  209.         * Gets the name of this module instance.
  210.         * @return string The name of this controller
  211.         */
  212.         function get_name()
  213.         {
  214.             return $this->moodle_choice_instance->name;
  215.         }
  216.         
  217.         /**
  218.         * Gets the intro description of this module instance, if available.
  219.         * @return string The intro description of this controller
  220.         */
  221.         function get_intro()
  222.         {
  223.             return $this->moodle_choice_instance->text;
  224.         }
  225.         
  226.         /**
  227.         * Gets the identifier of the course this controller belongs to.
  228.         * @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer).
  229.         */
  230.         function get_course_id()
  231.         {
  232.             return (int)$this->moodle_choice_instance->course;
  233.         }
  234.         
  235.         /**
  236.         * Gets the time at which this instance was created, or 0 if unknown.
  237.         * @return int Timestamp
  238.         */
  239.         function get_creation_time()
  240.         {
  241.             return 0;
  242.         }
  243.         
  244.         /**
  245.         * Gets the time at which this instance was last modified, or 0 if unknown.
  246.         * @return int Timestamp
  247.         */
  248.         function get_modification_time()
  249.         {
  250.             return (int)$this->moodle_choice_instance->timemodified;
  251.         }
  252.         
  253.         
  254.         /**
  255.         * Gets the short type name of this instance.
  256.         * @return string 
  257.         */
  258.         function get_type()
  259.         {
  260.             return 'choice';
  261.         }
  262.  
  263.         /**
  264.         * Gets the full type name of this instance, according to the current language pack, if available.
  265.         * Note: should be overridden by sub-classes.
  266.         * @return string Full type name if possible, or the short name otherwise.
  267.         */
  268.         function get_type_full()
  269.         {
  270.             return get_string('modulename''choice');
  271.         }
  272.         
  273.         /**
  274.         * Gets the time at which this choice opens.
  275.         * @return int Timestamp. 0 if choice has no opening time.
  276.         */
  277.         function get_opening_time()
  278.         {
  279.             return (int)$this->moodle_choice_instance->timeopen;
  280.         }
  281.         
  282.         /**
  283.         * Gets the time at which this choice closes.
  284.         * @return int Timestamp. 0 if choice has no closing time.
  285.         */
  286.         function get_closing_time()
  287.         {
  288.             return (int)$this->moodle_choice_instance->timeclose;
  289.         }
  290.         
  291.         /**
  292.         * Determines if the choice is currently open.
  293.         * @param int $timestamp The time to test. Uses the current time if none is given.
  294.         * @return bool 
  295.         */
  296.         function is_open($timestamp null)
  297.         {
  298.             // Use the current time if necessary
  299.             if ($timestamp === null$timestamp time();
  300.             // Check against the opening and closing times
  301.             $open $this->get_opening_time();
  302.             $close $this->get_closing_time();
  303.             if ($open && $open $timestampreturn false;
  304.             if ($close && $close $timestampreturn false;
  305.             return true;
  306.         }
  307.         
  308.         /**
  309.         * Determines if the choice has not opened yet.
  310.         * @param int $timestamp The time to test. Uses the current time if none is given.
  311.         * @return bool 
  312.         */
  313.         function is_early($timestamp null)
  314.         {
  315.             // Use the current time if necessary
  316.             if ($timestamp === null$timestamp time();
  317.             // Check against the opening time
  318.             $open $this->get_opening_time();
  319.             if ($open == 0return false// No opening time - can never be early
  320.             return ($open $timestamp);
  321.         }
  322.         
  323.         /**
  324.         * Determines if the choice has already closed.
  325.         * @param int $timestamp The time to test. Uses the current time if none is given.
  326.         * @return bool 
  327.         */
  328.         function is_late($timestamp null)
  329.         {
  330.             // Use the current time if necessary
  331.             if ($timestamp === null$timestamp time();
  332.             // Check against the closing time
  333.             $close $this->get_closing_time();
  334.             if ($close == 0return false// No opening time - can never be early
  335.             return ($close $timestamp);
  336.         }
  337.         
  338.         /**
  339.         * Checks if users are allowed to re-select their answer in this choice.
  340.         * @return bool 
  341.         */
  342.         function allow_update()
  343.         {
  344.             return !empty($this->moodle_choice_instance->allowupdate);
  345.         }
  346.         
  347.         /**
  348.         * Checks if results are to be shown.
  349.         * (Some choices only allow results after the choice is closed).
  350.         * @return bool 
  351.         */
  352.         function can_show_results()
  353.         {
  354.             if ($this->moodle_choice_instance->showresults == CHOICE_SHOWRESULTS_ALWAYSreturn true;
  355.             if ($this->moodle_choice_instance->showresults == CHOICE_SHOWRESULTS_AFTER_CLOSE && $this->is_late()) return true;
  356.             return false;
  357.         }
  358.         
  359.         /**
  360.         * Gets the number of people who have not yet answered the choice.
  361.         * Counts all users on the course, including students and teachers.
  362.         * @return int 
  363.         */
  364.         function get_num_unanswered()
  365.         {
  366.             return $this->numunanswered;
  367.         }
  368.  
  369.     }
  370.     
  371.     
  372.     /**
  373.     * Class to represent a single available option for a choice.
  374.     * @package sloodle
  375.     */
  376.     class SloodleChoiceOption
  377.     {
  378.         /**
  379.         * The ID of the option (should be unique across the site).
  380.         * @var mixed 
  381.         * @access public
  382.         */
  383.         var $id = 0;
  384.         
  385.         /**
  386.         * The text of this option.
  387.         * @var string 
  388.         * @access public
  389.         */
  390.         var $text = '';
  391.         
  392.         /**
  393.         * Number of selections so far of this option.
  394.         * @var int 
  395.         * @access public
  396.         */
  397.         var $numselections = 0;
  398.         
  399.         /**
  400.         * Maximum allowed number of selections for this option.
  401.         * Note: will be -1 if there is no limit.
  402.         * @var int 
  403.         * @access public
  404.         */
  405.         var $maxselections = -1;
  406.         
  407.         /**
  408.         * Timestamp of when this option was last modified.
  409.         * $var int
  410.         * @access public
  411.         */
  412.         var $timemodified = 0;
  413.     }
  414.  
  415.  
  416. ?>

Documentation generated on Mon, 07 Jul 2008 12:32:55 +0100 by phpDocumentor 1.4.0