dokeos-exercise
[ class tree: dokeos-exercise ] [ index: dokeos-exercise ] [ all elements ]

Source for file exercise.class.php

Documentation is available at exercise.class.php

  1. <?php
  2. /*
  3.     DOKEOS - elearning and course management software
  4.  
  5.     For a full list of contributors, see documentation/credits.html
  6.  
  7.     This program is free software; you can redistribute it and/or
  8.     modify it under the terms of the GNU General Public License
  9.     as published by the Free Software Foundation; either version 2
  10.     of the License, or (at your option) any later version.
  11.     See "documentation/licence.html" more details.
  12.  
  13.     Contact:
  14.         Dokeos
  15.         Rue des Palais 44 Paleizenstraat
  16.         B-1030 Brussels - Belgium
  17.         Tel. +32 (2) 211 34 56
  18. */
  19.  
  20.  
  21. /**
  22. *    Exercise class: This class allows to instantiate an object of type Exercise
  23. *    @package dokeos.exercise
  24. *     @author Olivier Brouckaert
  25. *     @version $Id: exercise.class.php 14786 2008-04-08 14:11:46Z elixir_inter $
  26. */
  27.  
  28.  
  29. if(!class_exists('Exercise')):
  30.  
  31. class Exercise
  32. {
  33.     var $id;
  34.     var $exercise;
  35.     var $description;
  36.     var $sound;
  37.     var $type;
  38.     var $random;
  39.     var $active;
  40.     var $timeLimit;
  41.  
  42.     var $questionList;  // array with the list of this exercise's questions
  43.  
  44.     /**
  45.      * constructor of the class
  46.      *
  47.      * @author - Olivier Brouckaert
  48.      */
  49.     function Exercise()
  50.     {
  51.         $this->id=0;
  52.         $this->exercise='';
  53.         $this->description='';
  54.         $this->sound='';
  55.         $this->type=1;
  56.         $this->random=0;
  57.         $this->active=1;
  58.         $this->questionList=array();
  59.         $this->timeLimit = 0;
  60.     }
  61.  
  62.     /**
  63.      * reads exercise informations from the data base
  64.      *
  65.      * @author - Olivier Brouckaert
  66.      * @param integer $id - exercise ID
  67.      * @return boolean - true if exercise exists, otherwise false
  68.      */
  69.     function read($id)
  70.     {
  71.         global $_course;
  72.  
  73.         $TBL_EXERCICE_QUESTION  Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
  74.         $TBL_EXERCICES          Database::get_course_table(TABLE_QUIZ_TEST);
  75.         $TBL_QUESTIONS          Database::get_course_table(TABLE_QUIZ_QUESTION);
  76.         #$TBL_REPONSES           = Database::get_course_table(TABLE_QUIZ_ANSWER);
  77.  
  78.         $sql="SELECT title,description,sound,type,random,active, results_disabled FROM $TBL_EXERCICES WHERE id='$id'";
  79.         $result=api_sql_query($sql,__FILE__,__LINE__);
  80.  
  81.         // if the exercise has been found
  82.         if($object=Database::fetch_object($result))
  83.         {
  84.             $this->id=$id;
  85.             $this->exercise=$object->title;
  86.             $this->description=$object->description;
  87.             $this->sound=$object->sound;
  88.             $this->type=$object->type;
  89.             $this->random=$object->random;
  90.             $this->active=$object->active;
  91.             $this->results_disabled =$object->results_disabled;
  92.  
  93.             $sql="SELECT question_id,position FROM $TBL_EXERCICE_QUESTION,$TBL_QUESTIONS WHERE question_id=id AND exercice_id='$id' ORDER BY position";
  94.             $result=api_sql_query($sql,__FILE__,__LINE__);
  95.  
  96.             // fills the array with the question ID for this exercise
  97.             // the key of the array is the question position
  98.             while($object=Database::fetch_object($result))
  99.             {
  100.                 // makes sure that the question position is unique
  101.                 while(isset($this->questionList[$object->position]))
  102.                 {
  103.                     $object->position++;
  104.                 }
  105.  
  106.                 $this->questionList[$object->position]=$object->question_id;
  107.             }
  108.             return true;
  109.         }
  110.  
  111.         // exercise not found
  112.         return false;
  113.     }
  114.  
  115.     /**
  116.      * returns the exercise ID
  117.      *
  118.      * @author - Olivier Brouckaert
  119.      * @return integer - exercise ID
  120.      */
  121.     function selectId()
  122.     {
  123.         return $this->id;
  124.     }
  125.  
  126.     /**
  127.      * returns the exercise title
  128.      *
  129.      * @author - Olivier Brouckaert
  130.      * @return string - exercise title
  131.      */
  132.     function selectTitle()
  133.     {
  134.         return $this->exercise;
  135.     }
  136.     /**
  137.      * returns the time limit
  138.      */
  139.     function selectTimeLimit()
  140.     {
  141.         return $this->timeLimit;
  142.     }
  143.  
  144.     /**
  145.      * returns the exercise description
  146.      *
  147.      * @author - Olivier Brouckaert
  148.      * @return string - exercise description
  149.      */
  150.     function selectDescription()
  151.     {
  152.         return $this->description;
  153.     }
  154.  
  155.     /**
  156.      * returns the exercise sound file
  157.      *
  158.      * @author - Olivier Brouckaert
  159.      * @return string - exercise description
  160.      */
  161.     function selectSound()
  162.     {
  163.         return $this->sound;
  164.     }
  165.  
  166.     /**
  167.      * returns the exercise type
  168.      *
  169.      * @author - Olivier Brouckaert
  170.      * @return integer - exercise type
  171.      */
  172.     function selectType()
  173.     {
  174.         return $this->type;
  175.     }
  176.  
  177.     /**
  178.      * tells if questions are selected randomly, and if so returns the draws
  179.      *
  180.      * @author - Olivier Brouckaert
  181.      * @return integer - 0 if not random, otherwise the draws
  182.      */
  183.     function isRandom()
  184.     {
  185.         return $this->random;
  186.     }
  187.     /**
  188.      * Same as isRandom() but has a name applied to values different than 0 or 1
  189.      */
  190.     function getShuffle()
  191.     {
  192.         return $this->random;
  193.     }
  194.  
  195.     /**
  196.      * returns the exercise status (1 = enabled ; 0 = disabled)
  197.      *
  198.      * @author - Olivier Brouckaert
  199.      * @return boolean - true if enabled, otherwise false
  200.      */
  201.     function selectStatus()
  202.     {
  203.         return $this->active;
  204.     }
  205.  
  206.     /**
  207.      * returns the array with the question ID list
  208.      *
  209.      * @author - Olivier Brouckaert
  210.      * @return array - question ID list
  211.      */
  212.     function selectQuestionList()
  213.     {
  214.         return $this->questionList;
  215.     }
  216.  
  217.     /**
  218.      * returns the number of questions in this exercise
  219.      *
  220.      * @author - Olivier Brouckaert
  221.      * @return integer - number of questions
  222.      */
  223.     function selectNbrQuestions()
  224.     {
  225.         return sizeof($this->questionList);
  226.     }
  227.  
  228.     /**
  229.      * selects questions randomly in the question list
  230.      *
  231.      * @author - Olivier Brouckaert
  232.      * @return array - if the exercise is not set to take questions randomly, returns the question list
  233.      *                      without randomizing, otherwise, returns the list with questions selected randomly
  234.      */
  235.     function selectRandomList()
  236.     {
  237.         // if the exercise is not a random exercise, or if there are not at least 2 questions
  238.         if(!$this->random || $this->selectNbrQuestions(2)
  239.         {
  240.             return $this->questionList;
  241.         }
  242.  
  243.         // takes all questions
  244.         if($this->random == -|| $this->random >= $this->selectNbrQuestions())
  245.         {
  246.             $draws=$this->selectNbrQuestions();
  247.         }
  248.         else
  249.         {
  250.             $draws=$this->random;
  251.         }
  252.  
  253.         srand((double)microtime()*1000000);
  254.  
  255.         $randQuestionList=array();
  256.         $alreadyChosed=array();
  257.  
  258.         // loop for the number of draws
  259.         for($i=0;$i $draws;$i++)
  260.         {
  261.             // selects a question randomly
  262.             do
  263.             {
  264.                 $rand=rand(0,$this->selectNbrQuestions()-1);
  265.             }
  266.             // if the question has already been selected, continues in the loop
  267.             while(in_array($rand,$alreadyChosed));
  268.  
  269.             $alreadyChosed[]=$rand;
  270.  
  271.             $j=0;
  272.  
  273.             foreach($this->questionList as $key=>$val)
  274.             {
  275.                 // if we have found the question chosed above
  276.                 if($j == $rand)
  277.                 {
  278.                     $randQuestionList[$key]=$val;
  279.                     break;
  280.                 }
  281.  
  282.                 $j++;
  283.             }
  284.         }
  285.  
  286.         return $randQuestionList;
  287.     }
  288.  
  289.     /**
  290.      * returns 'true' if the question ID is in the question list
  291.      *
  292.      * @author - Olivier Brouckaert
  293.      * @param integer $questionId - question ID
  294.      * @return boolean - true if in the list, otherwise false
  295.      */
  296.     function isInList($questionId)
  297.     {
  298.         return in_array($questionId,$this->questionList);
  299.     }
  300.  
  301.     /**
  302.      * changes the exercise title
  303.      *
  304.      * @author - Olivier Brouckaert
  305.      * @param string $title - exercise title
  306.      */
  307.     function updateTitle($title)
  308.     {
  309.         $this->exercise=$title;
  310.     }
  311.  
  312.     /**
  313.      * changes the exercise description
  314.      *
  315.      * @author - Olivier Brouckaert
  316.      * @param string $description - exercise description
  317.      */
  318.     function updateDescription($description)
  319.     {
  320.         $this->description=$description;
  321.     }
  322.  
  323.     /**
  324.      * changes the exercise sound file
  325.      *
  326.      * @author - Olivier Brouckaert
  327.      * @param string $sound - exercise sound file
  328.      * @param string $delete - ask to delete the file
  329.      */
  330.     function updateSound($sound,$delete)
  331.     {
  332.         global $audioPath$documentPath,$_course$_user;
  333.         $TBL_DOCUMENT Database::get_course_table(TABLE_DOCUMENT);
  334.         $TBL_ITEM_PROPERTY Database::get_course_table(TABLE_ITEM_PROPERTY);
  335.  
  336.         if($sound['size'&& (strstr($sound['type'],'audio'|| strstr($sound['type'],'video')))
  337.         {
  338.             $this->sound=$sound['name'];
  339.  
  340.             if(@move_uploaded_file($sound['tmp_name'],$audioPath.'/'.$this->sound))
  341.             {
  342.                 $query="SELECT 1 FROM $TBL_DOCUMENT "
  343.             ." WHERE path='".str_replace($documentPath,'',$audioPath).'/'.$this->sound."'";
  344.                 $result=api_sql_query($query,__FILE__,__LINE__);
  345.  
  346.                 if(!mysql_num_rows($result))
  347.                 {
  348.         /*$query="INSERT INTO $TBL_DOCUMENT(path,filetype) VALUES "
  349.             ." ('".str_replace($documentPath,'',$audioPath).'/'.$this->sound."','file')";
  350.         api_sql_query($query,__FILE__,__LINE__);*/
  351.         $id add_document($_course,str_replace($documentPath,'',$audioPath).'/'.$this->sound,'file',$sound['size'],$sound['name']);
  352.  
  353.         //$id = Database::get_last_insert_id();
  354.         //$time = time();
  355.         //$time = date("Y-m-d H:i:s", $time);
  356.         // insert into the item_property table, using default visibility of "visible"
  357.         /*$query = "INSERT INTO $TBL_ITEM_PROPERTY "
  358.                 ."(tool, ref, insert_user_id,to_group_id, insert_date, lastedit_date, lastedit_type) "
  359.                 ." VALUES "
  360.                 ."('".TOOL_DOCUMENT."', $id, $_user['user_id'], 0, '$time', '$time', 'DocumentAdded' )";
  361.         api_sql_query($query,__FILE__,__LINE__);*/
  362.         api_item_property_update($_courseTOOL_DOCUMENT$id'DocumentAdded',$_user['user_id']);
  363.         item_property_update_on_folder($_course,str_replace($documentPath,'',$audioPath),$_user['user_id']);
  364.                 }
  365.             }
  366.         }
  367.         elseif($delete && is_file($audioPath.'/'.$this->sound))
  368.         {
  369.             $this->sound='';
  370.         }
  371.     }
  372.  
  373.     /**
  374.      * changes the exercise type
  375.      *
  376.      * @author - Olivier Brouckaert
  377.      * @param integer $type - exercise type
  378.      */
  379.     function updateType($type)
  380.     {
  381.         $this->type=$type;
  382.     }
  383.  
  384.     /**
  385.      * sets to 0 if questions are not selected randomly
  386.      * if questions are selected randomly, sets the draws
  387.      *
  388.      * @author - Olivier Brouckaert
  389.      * @param integer $random - 0 if not random, otherwise the draws
  390.      */
  391.     function setRandom($random)
  392.     {
  393.         $this->random=$random;
  394.     }
  395.  
  396.     /**
  397.      * enables the exercise
  398.      *
  399.      * @author - Olivier Brouckaert
  400.      */
  401.     function enable()
  402.     {
  403.         $this->active=1;
  404.     }
  405.  
  406.     /**
  407.      * disables the exercise
  408.      *
  409.      * @author - Olivier Brouckaert
  410.      */
  411.     function disable()
  412.     {
  413.         $this->active=0;
  414.     }
  415.     
  416.     function disable_results()
  417.     {
  418.         $this->results_disabled true;
  419.     }
  420.     
  421.     function enable_results()
  422.     {
  423.         $this->results_disabled false;
  424.     }
  425.  
  426.     /**
  427.      * updates the exercise in the data base
  428.      *
  429.      * @author - Olivier Brouckaert
  430.      */
  431.     function save()
  432.     {
  433.         $TBL_EXERCICES Database::get_course_table(TABLE_QUIZ_TEST);
  434.         $TBL_QUESTIONS Database::get_course_table(TABLE_QUIZ_QUESTION);
  435.  
  436.         $id=$this->id;
  437.         $exercise=addslashes($this->exercise);
  438.         $description=addslashes($this->description);
  439.         $sound=addslashes($this->sound);
  440.         $type=$this->type;
  441.         $random=$this->random;
  442.         $active=$this->active;
  443.         $results_disabled intval($this->results_disabled);
  444.  
  445.         // exercise already exists
  446.         if($id)
  447.         {
  448.             $sql="UPDATE $TBL_EXERCICES SET title='$exercise',description='$description',sound='$sound',type='$type',random='$random',active='$active',results_disabled='$results_disabled' WHERE id='$id'";
  449.             api_sql_query($sql,__FILE__,__LINE__);
  450.         }
  451.         // creates a new exercise
  452.         else
  453.         {
  454.             $sql="INSERT INTO $TBL_EXERCICES(title,description,sound,type,random,active, results_disabled) VALUES('$exercise','$description','$sound','$type','$random','$active',$results_disabled)";
  455.             api_sql_query($sql,__FILE__,__LINE__);
  456.  
  457.             $this->id=mysql_insert_id();
  458.         }
  459.  
  460.         // updates the question position
  461.         foreach($this->questionList as $position=>$questionId)
  462.         {
  463.             $sql="UPDATE $TBL_QUESTIONS SET position='$position' WHERE id='$questionId'";
  464.             api_sql_query($sql,__FILE__,__LINE__);
  465.         }
  466.     }
  467.  
  468.     /**
  469.      * moves a question up in the list
  470.      *
  471.      * @author - Olivier Brouckaert
  472.      * @param integer $id - question ID to move up
  473.      */
  474.     function moveUp($id)
  475.     {
  476.         foreach($this->questionList as $position=>$questionId)
  477.         {
  478.             // if question ID found
  479.             if($questionId == $id)
  480.             {
  481.                 // position of question in the array
  482.                 $pos1=$position;
  483.  
  484.                 prev($this->questionList);
  485.  
  486.                 // position of previous question in the array
  487.                 $pos2=key($this->questionList);
  488.  
  489.                 // error, can't move question
  490.                 if(!$pos2)
  491.                 {
  492.                     return;
  493.                 }
  494.  
  495.                 $id2=$this->questionList[$pos2];
  496.  
  497.                 // exits foreach()
  498.                 break;
  499.             }
  500.  
  501.             // goes to next question
  502.             next($this->questionList);
  503.         }
  504.  
  505.         // permutes questions in the array
  506.         $temp=$this->questionList[$pos2];
  507.         $this->questionList[$pos2]=$this->questionList[$pos1];
  508.         $this->questionList[$pos1]=$temp;
  509.     }
  510.  
  511.     /**
  512.      * moves a question down in the list
  513.      *
  514.      * @author - Olivier Brouckaert
  515.      * @param integer $id - question ID to move down
  516.      */
  517.     function moveDown($id)
  518.     {
  519.         foreach($this->questionList as $position=>$questionId)
  520.         {
  521.             // if question ID found
  522.             if($questionId == $id)
  523.             {
  524.                 // position of question in the array
  525.                 $pos1=$position;
  526.  
  527.                 next($this->questionList);
  528.  
  529.                 // position of next question in the array
  530.                 $pos2=key($this->questionList);
  531.  
  532.                 // error, can't move question
  533.                 if(!$pos2)
  534.                 {
  535.                     return;
  536.                 }
  537.  
  538.                 $id2=$this->questionList[$pos2];
  539.  
  540.                 // exits foreach()
  541.                 break;
  542.             }
  543.  
  544.             // goes to next question
  545.             next($this->questionList);
  546.         }
  547.  
  548.         // permutes questions in the array
  549.         $temp=$this->questionList[$pos2];
  550.         $this->questionList[$pos2]=$this->questionList[$pos1];
  551.         $this->questionList[$pos1]=$temp;
  552.     }
  553.  
  554.     /**
  555.      * adds a question into the question list
  556.      *
  557.      * @author - Olivier Brouckaert
  558.      * @param integer $questionId - question ID
  559.      * @return boolean - true if the question has been added, otherwise false
  560.      */
  561.     function addToList($questionId)
  562.     {
  563.         // checks if the question ID is not in the list
  564.         if(!$this->isInList($questionId))
  565.         {
  566.             // selects the max position
  567.             if(!$this->selectNbrQuestions())
  568.             {
  569.                 $pos=1;
  570.             }
  571.             else
  572.             {
  573.                 $pos=max(array_keys($this->questionList))+1;
  574.             }
  575.  
  576.             $this->questionList[$pos]=$questionId;
  577.  
  578.             return true;
  579.         }
  580.  
  581.         return false;
  582.     }
  583.  
  584.     /**
  585.      * removes a question from the question list
  586.      *
  587.      * @author - Olivier Brouckaert
  588.      * @param integer $questionId - question ID
  589.      * @return boolean - true if the question has been removed, otherwise false
  590.      */
  591.     function removeFromList($questionId)
  592.     {
  593.         // searches the position of the question ID in the list
  594.         $pos=array_search($questionId,$this->questionList);
  595.  
  596.         // question not found
  597.         if($pos === false)
  598.         {
  599.             return false;
  600.         }
  601.         else
  602.         {
  603.             // deletes the position from the array containing the wanted question ID
  604.             unset($this->questionList[$pos]);
  605.  
  606.             return true;
  607.         }
  608.     }
  609.  
  610.     /**
  611.      * deletes the exercise from the database
  612.      * Notice : leaves the question in the data base
  613.      *
  614.      * @author - Olivier Brouckaert
  615.      */
  616.     function delete(){
  617.         $TBL_EXERCICES Database::get_course_table(TABLE_QUIZ_TEST);
  618.         $sql="UPDATE $TBL_EXERCICES SET active='-1' WHERE id='".$this->id."'";
  619.         api_sql_query($sql);
  620.     }
  621.  
  622.     /**
  623.      * Creates the form to create / edit an exercise
  624.      * @param FormValidator $form the formvalidator instance (by reference)
  625.      */
  626.     function createForm ($form)
  627.     {
  628.  
  629.         // title
  630.         $form -> addElement('text''exerciseTitle'get_lang('ExerciseName').' : ','class="input_titles"');
  631.  
  632.         // fck editor
  633.         global $fck_attribute;
  634.         $fck_attribute array();
  635.         $fck_attribute['Height''250';
  636.         $fck_attribute['Width''100%';
  637.         $fck_attribute['ToolbarSet''NewTest';
  638.         $form -> addElement ('html_editor''exerciseDescription'get_lang('ExerciseDescription').' : ');
  639.  
  640.         // type
  641.         $radios array();
  642.         $radios[FormValidator :: createElement ('radio''exerciseType'nullget_lang('SimpleExercise'),'1');
  643.         $radios[FormValidator :: createElement ('radio''exerciseType'nullget_lang('SequentialExercise'),'2');
  644.         $form -> addGroup($radiosnullget_lang('ExerciseType').' : ''<br />');
  645.  
  646.         // random
  647.         /*$random = array();
  648.         $random[] = FormValidator :: createElement ('text', 'randomQuestions', null,null,'0');
  649.         $form -> addGroup($random,null,get_lang('RandomQuestions').' : ','<br />');*/
  650.  
  651.         // submit
  652.         $form -> addElement('submit''submitExercise'get_lang('Ok'));
  653.  
  654.         // rules
  655.         $form -> addRule ('exerciseTitle'get_lang('GiveExerciseName')'required');
  656.  
  657.         // defaults
  658.         $defaults array();
  659.         if($this -> id > 0)
  660.         {
  661.             $defaults['exerciseType'$this -> selectType();
  662.             $defaults['exerciseTitle'$this -> selectTitle();
  663.             $defaults['exerciseDescription'$this -> selectDescription();
  664.             //$defaults['randomQuestions'] = $this -> isRandom();
  665.         }
  666.         else{
  667.             $defaults['exerciseType'1;
  668.             //$defaults['randomQuestions'] = 0;
  669.             $defaults['exerciseDescription''';
  670.         }
  671.  
  672.         $form -> setDefaults($defaults);
  673.  
  674.  
  675.     }
  676.  
  677.  
  678.     /**
  679.      * function which process the creation of exercises
  680.      * @param FormValidator $form the formvalidator instance
  681.      */
  682.     function processCreation($form)
  683.     {
  684.  
  685.         $this -> updateTitle($form -> getSubmitValue('exerciseTitle'));
  686.         $this -> updateDescription($form -> getSubmitValue('exerciseDescription'));
  687.         $this -> updateType($form -> getSubmitValue('exerciseType'));
  688.         $this -> setRandom($form -> getSubmitValue('randomQuestions'));
  689.         $this -> save();
  690.  
  691.     }
  692. }
  693.  
  694. endif;
  695. ?>

Documentation generated on Thu, 12 Jun 2008 13:25:07 -0500 by phpDocumentor 1.4.1