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.                 // Get response data (this uses the standard choice function, in "moodle/mod/choice/lib.php")
  105.                 $allresponses choice_get_response_data($this->moodle_choice_instance$this->cm0);
  106.  
  107.                 foreach ($options as $opt{
  108.                     // Create our option object and add our data
  109.                     $this->options[$opt->idnew SloodleChoiceOption();
  110.                     $this->options[$opt->id]->id $opt->id;
  111.                     $this->options[$opt->id]->text $opt->text;
  112.                     $this->options[$opt->id]->maxselections $opt->maxanswers;
  113.                     $this->options[$opt->id]->timemodified = (int)$opt->timemodified;
  114.  
  115.                     // Count the number of selections made
  116.                     $numsels 0;
  117.                     if (isset($allresponses[$opt->id])) $numsels count($allresponses[$opt->id]);
  118.                     $this->options[$opt->id]->numselections $numsels;
  119.                 }
  120.             }
  121.             
  122.             // Determine how many people on the course have not yet answered
  123.             $users get_course_users($this->cm->course);
  124.             if (!is_array($users)) $users array();
  125.             $num_users count($users);
  126.             $numanswers = (int)count_records('choice_answers''choiceid'$this->moodle_choice_instance->id);
  127.             $this->numunanswered = max(0$num_users $numanswers);
  128.             
  129.             return true;
  130.         }
  131.         
  132.         /**
  133.         * Selects an option in this choice on behalf of the specified user.
  134.         * Logs the user in to the VLE if necessary.
  135.         * If a general error occurs, FALSE will be returned.
  136.         * Otherwise, an integer {@link http://slisweb.sjsu.edu/sl/index.php/Sloodle_status_codes status code} will be returned.
  137.         * The following status codes are typical responses:
  138.         *  * 10011 = added new choice selection
  139.         *  * 10012 = updated existing choice selection
  140.         *  * 10013 = user previously selected same option
  141.         *  * -10011 = User already made a selection, and re-selection is not allowed
  142.         *  * -10012 = max number of selections for this option already made
  143.         *  * -10013 = choice is not yet open
  144.         *  * -10014 = choice is already closed
  145.         *
  146.         * @param mixed $optionid The unique site-wide identifier of the option to be selected
  147.         * @param mixed $user A SloodleUser identifying the current user; if omitted, the current {@link SloodleSession} will be used.
  148.         * @return integer|false
  149.         */
  150.         function select_option($optionid$user null)
  151.         {
  152.             // Fetch a user if necessary
  153.             if ($user === null{
  154.                 // Make sure we have a session user
  155.                 if (!isset($this->_session->user)) return false;
  156.                 $user $this->_session->user;
  157.             }
  158.             // Make sure we have a user loaded and logged-in
  159.             if (!$user->is_user_loaded()) return false;
  160.             if (!$user->login()) return false;
  161.             
  162.             // Make sure the user is permitted to select from this choice
  163.             if (!has_capability('mod/choice:choose'get_context_instance(CONTEXT_MODULE$this->cm->id))) return -331;
  164.             // Make sure the choice is open
  165.             if ($this->is_early()) return -10013;
  166.             if ($this->is_late()) return -10014;
  167.             
  168.             // Has the user already made a selection for this choice?
  169.             $update_selection false;
  170.             $previous_selection get_record('choice_answers''choiceid'$this->moodle_choice_instance->id'userid'$user->get_user_id());
  171.             if ($previous_selection{
  172.                 // Was it a selection of the same option?
  173.                 if ($previous_selection->optionid == $optionid{
  174.                     // Yes - that's fine. Nothing to do.
  175.                     return 10013;
  176.                 }
  177.                 // No - are re-selections allowed?
  178.                 if (!$this->allow_update()) {
  179.                     // No - stop here
  180.                     return -10011;
  181.                 }
  182.                 $update_selection true;
  183.             }
  184.             
  185.             // Fetch the option record
  186.             $option get_record('choice_options''id'$optionid'choiceid'$this->moodle_choice_instance->id);
  187.             if (!$optionreturn false;
  188.             
  189.             // Make sure the maximum selections for the given option have not yet been made
  190.             if (!empty($this->moodle_choice_instance->limitanswers)) {
  191.                 $numselections count_records('choice_answers''optionid'$optionid);
  192.                 if (!$numselectionsreturn false;
  193.                 if ($numselections >= $option->maxanswersreturn -10012;
  194.             }
  195.             
  196.             // If necessary, delete the existing selection
  197.             if ($update_selectiondelete_records('choice_answers''choiceid'$this->moodle_choice_instance->id'userid'$user->get_user_id());
  198.             
  199.             // Select the new option
  200.             $selection new stdClass();
  201.             $selection->choiceid $this->moodle_choice_instance->id;
  202.             $selection->userid $user->get_user_id();
  203.             $selection->optionid $optionid;
  204.             $selection->timemodified time();
  205.             if (!insert_record('choice_answers'$selection)) return false;
  206.             
  207.             // Success!
  208.             if ($update_selectionreturn 10012;
  209.             return 10011;
  210.         }
  211.         
  212.         
  213.     // ACCESSORS //
  214.     
  215.         /**
  216.         * Gets the name of this module instance.
  217.         * @return string The name of this controller
  218.         */
  219.         function get_name()
  220.         {
  221.             return $this->moodle_choice_instance->name;
  222.         }
  223.         
  224.         /**
  225.         * Gets the intro description of this module instance, if available.
  226.         * @return string The intro description of this controller
  227.         */
  228.         function get_intro()
  229.         {
  230.             return $this->moodle_choice_instance->text;
  231.         }
  232.         
  233.         /**
  234.         * Gets the identifier of the course this controller belongs to.
  235.         * @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer).
  236.         */
  237.         function get_course_id()
  238.         {
  239.             return (int)$this->moodle_choice_instance->course;
  240.         }
  241.         
  242.         /**
  243.         * Gets the time at which this instance was created, or 0 if unknown.
  244.         * @return int Timestamp
  245.         */
  246.         function get_creation_time()
  247.         {
  248.             return 0;
  249.         }
  250.         
  251.         /**
  252.         * Gets the time at which this instance was last modified, or 0 if unknown.
  253.         * @return int Timestamp
  254.         */
  255.         function get_modification_time()
  256.         {
  257.             return (int)$this->moodle_choice_instance->timemodified;
  258.         }
  259.         
  260.         
  261.         /**
  262.         * Gets the short type name of this instance.
  263.         * @return string 
  264.         */
  265.         function get_type()
  266.         {
  267.             return 'choice';
  268.         }
  269.  
  270.         /**
  271.         * Gets the full type name of this instance, according to the current language pack, if available.
  272.         * Note: should be overridden by sub-classes.
  273.         * @return string Full type name if possible, or the short name otherwise.
  274.         */
  275.         function get_type_full()
  276.         {
  277.             return get_string('modulename''choice');
  278.         }
  279.         
  280.         /**
  281.         * Gets the time at which this choice opens.
  282.         * @return int Timestamp. 0 if choice has no opening time.
  283.         */
  284.         function get_opening_time()
  285.         {
  286.             return (int)$this->moodle_choice_instance->timeopen;
  287.         }
  288.         
  289.         /**
  290.         * Gets the time at which this choice closes.
  291.         * @return int Timestamp. 0 if choice has no closing time.
  292.         */
  293.         function get_closing_time()
  294.         {
  295.             return (int)$this->moodle_choice_instance->timeclose;
  296.         }
  297.         
  298.         /**
  299.         * Determines if the choice is currently open.
  300.         * @param int $timestamp The time to test. Uses the current time if none is given.
  301.         * @return bool 
  302.         */
  303.         function is_open($timestamp null)
  304.         {
  305.             // Use the current time if necessary
  306.             if ($timestamp === null$timestamp time();
  307.             // Check against the opening and closing times
  308.             $open $this->get_opening_time();
  309.             $close $this->get_closing_time();
  310.             if ($open && $open $timestampreturn false;
  311.             if ($close && $close $timestampreturn false;
  312.             return true;
  313.         }
  314.         
  315.         /**
  316.         * Determines if the choice has not opened yet.
  317.         * @param int $timestamp The time to test. Uses the current time if none is given.
  318.         * @return bool 
  319.         */
  320.         function is_early($timestamp null)
  321.         {
  322.             // Use the current time if necessary
  323.             if ($timestamp === null$timestamp time();
  324.             // Check against the opening time
  325.             $open $this->get_opening_time();
  326.             if ($open == 0return false// No opening time - can never be early
  327.             return ($open $timestamp);
  328.         }
  329.         
  330.         /**
  331.         * Determines if the choice has already closed.
  332.         * @param int $timestamp The time to test. Uses the current time if none is given.
  333.         * @return bool 
  334.         */
  335.         function is_late($timestamp null)
  336.         {
  337.             // Use the current time if necessary
  338.             if ($timestamp === null$timestamp time();
  339.             // Check against the closing time
  340.             $close $this->get_closing_time();
  341.             if ($close == 0return false// No opening time - can never be early
  342.             return ($close $timestamp);
  343.         }
  344.         
  345.         /**
  346.         * Checks if users are allowed to re-select their answer in this choice.
  347.         * @return bool 
  348.         */
  349.         function allow_update()
  350.         {
  351.             return !empty($this->moodle_choice_instance->allowupdate);
  352.         }
  353.         
  354.         /**
  355.         * Checks if results are to be shown.
  356.         * (Some choices only allow results after the choice is closed).
  357.         * @return bool 
  358.         */
  359.         function can_show_results()
  360.         {
  361.             if ($this->moodle_choice_instance->showresults == CHOICE_SHOWRESULTS_ALWAYSreturn true;
  362.             if ($this->moodle_choice_instance->showresults == CHOICE_SHOWRESULTS_AFTER_CLOSE && $this->is_late()) return true;
  363.             return false;
  364.         }
  365.         
  366.         /**
  367.         * Gets the number of people who have not yet answered the choice.
  368.         * Counts all users on the course, including students and teachers.
  369.         * @return int 
  370.         */
  371.         function get_num_unanswered()
  372.         {
  373.             return $this->numunanswered;
  374.         }
  375.  
  376.     }
  377.     
  378.     
  379.     /**
  380.     * Class to represent a single available option for a choice.
  381.     * @package sloodle
  382.     */
  383.     class SloodleChoiceOption
  384.     {
  385.         /**
  386.         * The ID of the option (should be unique across the site).
  387.         * @var mixed 
  388.         * @access public
  389.         */
  390.         var $id = 0;
  391.         
  392.         /**
  393.         * The text of this option.
  394.         * @var string 
  395.         * @access public
  396.         */
  397.         var $text = '';
  398.         
  399.         /**
  400.         * Number of selections so far of this option.
  401.         * @var int 
  402.         * @access public
  403.         */
  404.         var $numselections = 0;
  405.         
  406.         /**
  407.         * Maximum allowed number of selections for this option.
  408.         * Note: will be -1 if there is no limit.
  409.         * @var int 
  410.         * @access public
  411.         */
  412.         var $maxselections = -1;
  413.         
  414.         /**
  415.         * Timestamp of when this option was last modified.
  416.         * $var int
  417.         * @access public
  418.         */
  419.         var $timemodified = 0;
  420.     }
  421.  
  422.  
  423. ?>

Documentation generated on Fri, 17 Jul 2009 11:01:57 +0100 by phpDocumentor 1.4.0