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

Source for file learnpath.class.php

Documentation is available at learnpath.class.php

  1. <?php //$id:$
  2. /**
  3.  * This (abstract?) class defines the parent attributes and methods for the dokeos learnpaths and scorm
  4.  * learnpaths. It is used by the scorm class as well as the dokeos_lp class.
  5.  * @package dokeos.learnpath
  6.  * @author    Yannick Warnier <ywarnier@beeznest.org>
  7.  * @license    GNU/GPL - See Dokeos license directory for details
  8.  */
  9. /**
  10.  * Defines the learnpath parent class
  11.  * @package dokeos.learnpath
  12.  */
  13. class learnpath {
  14.  
  15.     var $attempt = 0//the number for the current ID view
  16.     var $cc//course (code) this learnpath is located in
  17.     var $current//id of the current item the user is viewing
  18.     var $current_score//the score of the current item
  19.     var $current_time_start//the time the user loaded this resource (this does not mean he can see it yet)
  20.     var $current_time_stop//the time the user closed this resource
  21.     var $default_status = 'not attempted';
  22.     var $encoding = 'ISO-8859-1';
  23.     var $error = '';
  24.     var $extra_information = ''//this string can be used by proprietary SCORM contents to store data about the current learnpath
  25.     var $force_commit = false//for SCORM only - if set to true, will send a scorm LMSCommit() request on each LMSSetValue()
  26.     var $index//the index of the active learnpath_item in $ordered_items array
  27.     var $items = array();
  28.     var $last//item_id of last item viewed in the learning path
  29.     var $last_item_seen = 0//in case we have already come in this learnpath, reuse the last item seen if authorized
  30.     var $license//which license this course has been given - not used yet on 20060522
  31.     var $lp_id//DB ID for this learnpath
  32.     var $lp_view_id//DB ID for lp_view
  33.     var $log_file//file where to log learnpath API msg
  34.     var $maker//which maker has conceived the content (ENI, Articulate, ...)
  35.     var $message = '';
  36.     var $mode='embedded'//holds the video display mode (fullscreen or embedded) 
  37.     var $name//learnpath name (they generally have one)
  38.     var $ordered_items = array()//list of the learnpath items in the order they are to be read
  39.     var $path = ''//path inside the scorm directory (if scorm)
  40.     var $theme// the current theme of the learning path  
  41.     
  42.     // Tells if all the items of the learnpath can be tried again. Defaults to "no" (=1)
  43.     var $prevent_reinit = 1;
  44.     
  45.     // Describes the mode of progress bar display
  46.     var $progress_bar_mode = '%'
  47.     
  48.     // Percentage progress as saved in the db
  49.     var $progress_db = '0'
  50.     var $proximity//wether the content is distant or local or unknown
  51.     var $refs_list = array()//list of items by ref => db_id. Used only for prerequisites match. 
  52.     //!!!This array (refs_list) is built differently depending on the nature of the LP. 
  53.     //If SCORM, uses ref, if Dokeos, uses id to keep a unique value
  54.     var $type//type of learnpath. Could be 'dokeos', 'scorm', 'scorm2004', 'aicc', ... 
  55.     //TODO check if this type variable is useful here (instead of just in the controller script)
  56.     var $user_id//ID of the user that is viewing/using the course
  57.     var $update_queue = array();
  58.     var $scorm_debug = 0;
  59.     
  60.     var $arrMenu = array()//array for the menu items
  61.  
  62.     var $debug = 0//logging level
  63.  
  64.  
  65.  
  66.     /**
  67.      * Class constructor. Needs a database handler, a course code and a learnpath id from the database.
  68.      * Also builds the list of items into $this->items.
  69.      * @param    string        Course code
  70.      * @param    integer        Learnpath ID
  71.      * @param    integer        User ID
  72.      * @return    boolean        True on success, false on error
  73.      */
  74.     function learnpath($course$lp_id$user_id{
  75.         //check params
  76.         //check course code
  77.         if($this->debug>0){error_log('New LP - In learnpath::learnpath('.$course.','.$lp_id.','.$user_id.')',0);}
  78.         if(empty($course)){
  79.             $this->error = 'Course code is empty';
  80.             return false;
  81.         }
  82.         else
  83.         {
  84.             $main_table Database::get_main_table(TABLE_MAIN_COURSE);
  85.             //$course = Database::escape_string($course);
  86.             $course $this->escape_string($course);
  87.             $sql "SELECT * FROM $main_table WHERE code = '$course'";
  88.             if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - Querying course: '.$sql,0);}
  89.             //$res = Database::query($sql);
  90.             $res api_sql_query($sql__FILE____LINE__);
  91.             if(Database::num_rows($res)>0)
  92.             {
  93.                 $this->cc = $course;
  94.             }
  95.             else
  96.             {
  97.                 $this->error = 'Course code does not exist in database ('.$sql.')';
  98.                 return false;
  99.                }
  100.         }
  101.         //check learnpath ID
  102.         if(empty($lp_id))
  103.         {
  104.             $this->error = 'Learnpath ID is empty';
  105.             return false;
  106.         }
  107.         else
  108.         {            
  109.             //TODO make it flexible to use any course_code (still using env course code here)
  110.             $lp_table Database::get_course_table('lp');
  111.  
  112.             //$id = Database::escape_integer($id);
  113.             $lp_id $this->escape_string($lp_id);
  114.             $sql "SELECT * FROM $lp_table WHERE id = '$lp_id'";
  115.             if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - Querying lp: '.$sql,0);}
  116.             //$res = Database::query($sql);
  117.             $res api_sql_query($sql__FILE____LINE__);
  118.             if(Database::num_rows($res)>0)
  119.             {
  120.                 $this->lp_id = $lp_id;
  121.                 $row Database::fetch_array($res);
  122.                 $this->type = $row['lp_type'];
  123.                 $this->name = stripslashes($row['name']);
  124.                 $this->encoding = $row['default_encoding'];
  125.                 $this->proximity = $row['content_local'];
  126.                 $this->theme = $row['theme'];
  127.                 $this->maker = $row['content_maker'];
  128.                 $this->prevent_reinit = $row['prevent_reinit'];
  129.                 $this->license = $row['content_license'];
  130.                 $this->scorm_debug = $row['debug'];
  131.                    $this->js_lib $row['js_lib'];
  132.                    $this->path = $row['path'];
  133.                    if($this->type == 2){
  134.                     if($row['force_commit'== 1){
  135.                         $this->force_commit = true;
  136.                     }
  137.                 }
  138.                 $this->mode = $row['default_view_mod'];
  139.             }
  140.             else
  141.             {
  142.                 $this->error = 'Learnpath ID does not exist in database ('.$sql.')';
  143.                 return false;
  144.             }
  145.         }
  146.         //check user ID
  147.         if(empty($user_id)){
  148.             $this->error = 'User ID is empty';
  149.             return false;
  150.         }
  151.         else
  152.         {
  153.             //$main_table = Database::get_main_user_table();
  154.             $main_table Database::get_main_table(TABLE_MAIN_USER);
  155.             //$user_id = Database::escape_integer($user_id);
  156.             $user_id $this->escape_string($user_id);
  157.             $sql "SELECT * FROM $main_table WHERE user_id = '$user_id'";
  158.             if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - Querying user: '.$sql,0);}
  159.             //$res = Database::query($sql);
  160.             $res api_sql_query($sql__FILE____LINE__);
  161.             if(Database::num_rows($res)>0)
  162.             {
  163.                 $this->user_id = $user_id;
  164.             }
  165.             else
  166.             {
  167.                 $this->error = 'User ID does not exist in database ('.$sql.')';
  168.                 return false;
  169.             }
  170.         }
  171.         //end of variables checking
  172.         
  173.         //now get the latest attempt from this user on this LP, if available, otherwise create a new one
  174.         $lp_table Database::get_course_table(TABLE_LP_VIEW);
  175.         //selecting by view_count descending allows to get the highest view_count first
  176.         $sql "SELECT * FROM $lp_table WHERE lp_id = '$lp_id' AND user_id = '$user_id' ORDER BY view_count DESC";
  177.         if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - querying lp_view: '.$sql,0);}
  178.         //$res = Database::query($sql);
  179.         $res api_sql_query($sql__FILE____LINE__);
  180.         $view_id 0//used later to query lp_item_view
  181.         if(Database::num_rows($res)>0)
  182.         {
  183.             if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - Found previous view',0);}
  184.             $row Database::fetch_array($res);
  185.             $this->attempt = $row['view_count'];
  186.             $this->lp_view_id = $row['id'];
  187.             $this->last_item_seen = $row['last_item'];
  188.             $this->progress_db = $row['progress'];
  189.         }
  190.         else
  191.         {
  192.             if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - NOT Found previous view',0);}
  193.             $this->attempt = 1;
  194.             $sql_ins "INSERT INTO $lp_table (lp_id,user_id,view_count) VALUES ($lp_id,$user_id,1)";
  195.             $res_ins api_sql_query($sql_ins__FILE____LINE__);
  196.             $this->lp_view_id = Database::get_last_insert_id();
  197.             if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - inserting new lp_view: '.$sql_ins,0);}
  198.         }
  199.  
  200.         //initialise items
  201.         $lp_item_table Database::get_course_table(TABLE_LP_ITEM);
  202.         $sql "SELECT * FROM $lp_item_table WHERE lp_id = '".$this->lp_id."' ORDER BY parent_item_id, display_order";
  203.         $res api_sql_query($sql__FILE____LINE__);
  204.         
  205.         while($row Database::fetch_array($res))
  206.         {
  207.             $oItem '';
  208.                //$this->ordered_items[] = $row['id'];
  209.                switch($this->type){
  210.                 
  211.                    case 3//aicc
  212.                        $oItem new aiccItem('db',$row['id']);
  213.                        if(is_object($oItem)){
  214.                            $my_item_id $oItem->get_id();
  215.                            $oItem->set_lp_view($this->lp_view_id);
  216.                            $oItem->set_prevent_reinit($this->prevent_reinit);
  217.                            // Don't use reference here as the next loop will make the pointed object change
  218.                            $this->items[$my_item_id$oItem;                           
  219.                            $this->refs_list[$oItem->ref]=$my_item_id;
  220.                            if($this->debug>2){error_log('New LP - learnpath::learnpath() - aicc object with id '.$my_item_id.' set in items[]',0);}
  221.                        }
  222.                     break;
  223.                    case 2:
  224.  
  225.                        require_once('scorm.class.php');
  226.                        require_once('scormItem.class.php');
  227.                        $oItem new scormItem('db',$row['id']);                   
  228.                        if(is_object($oItem)){
  229.                            $my_item_id $oItem->get_id();
  230.                            $oItem->set_lp_view($this->lp_view_id);
  231.                            $oItem->set_prevent_reinit($this->prevent_reinit);
  232.                            // Don't use reference here as the next loop will make the pointed object change
  233.                            $this->items[$my_item_id$oItem;
  234.                            $this->refs_list[$oItem->ref]=$my_item_id;
  235.                            if($this->debug>2){error_log('New LP - object with id '.$my_item_id.' set in items[]',0);}
  236.                        }
  237.                        break;
  238.  
  239.                    case 1:
  240.  
  241.                    default:
  242.                        require_once('learnpathItem.class.php');
  243.                        $oItem new learnpathItem($row['id'],$user_id);
  244.                        if(is_object($oItem)){
  245.                            $my_item_id $oItem->get_id();
  246.                            //$oItem->set_lp_view($this->lp_view_id); moved down to when we are sure the item_view exists
  247.                            $oItem->set_prevent_reinit($this->prevent_reinit);
  248.                            // Don't use reference here as the next loop will make the pointed object change
  249.                            $this->items[$my_item_id$oItem;
  250.                            $this->refs_list[$my_item_id]=$my_item_id;
  251.                            if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - object with id '.$my_item_id.' set in items[]',0);}
  252.                        }
  253.                        break;
  254.                }
  255.  
  256.             //items is a list of pointers to all items, classified by DB ID, not SCO id
  257.             if($row['parent_item_id'== OR empty($this->items[$row['parent_item_id']])){
  258.                    $this->items[$row['id']]->set_level(0);
  259.                }else{
  260.                    $level $this->items[$row['parent_item_id']]->get_level()+1;
  261.                    $this->items[$row['id']]->set_level($level);
  262.                    if(is_object($this->items[$row['parent_item_id']])){
  263.                        //items is a list of pointers from item DB ids to item objects
  264.                        $this->items[$row['parent_item_id']]->add_child($row['id']);
  265.                    }else{
  266.                        if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - The parent item ('.$row['parent_item_id'].') of item '.$row['id'].' could not be found',0);}
  267.                    }
  268.                }
  269.  
  270.             //get last viewing vars
  271.             $lp_item_view_table Database::get_course_table(TABLE_LP_ITEM_VIEW);
  272.             //this query should only return one or zero result
  273.             $sql "SELECT * " .
  274.                     "FROM $lp_item_view_table .
  275.                     "WHERE lp_view_id = ".$this->lp_view_id." " .
  276.                     "AND lp_item_id = ".$row['id']." ORDER BY view_count DESC ";
  277.             if($this->debug>2){error_log('New LP - learnpath::learnpath() - Selecting item_views: '.$sql,0);}
  278.             //get the item status
  279.             $res2 api_sql_query($sql__FILE____LINE__);
  280.             if(Database::num_rows($res2)>0)
  281.             {
  282.                 //if this learnpath has already been used by this user, get his last attempt count and
  283.                 //the last item seen back into this object
  284.                 //$max = 0;
  285.                 $row2 Database::fetch_array($res2);
  286.                 if($this->debug>2){error_log('New LP - learnpath::learnpath() - Got item_view: '.print_r($row2,true),0);}
  287.                 $this->items[$row['id']]->set_status($row2['status'])
  288.                 if(empty($row2['status'])){
  289.                     $this->items[$row['id']]->set_status($this->default_status)
  290.                 }
  291.                 //$this->attempt = $row['view_count'];
  292.                 //$this->last_item = $row['id'];                
  293.             }
  294.             else //no item found in lp_item_view for this view
  295.             {
  296.                 //first attempt from this user. Set attempt to 1 and last_item to 0 (first item available)
  297.                 //TODO  if the learnpath has not got attempts activated, always use attempt '1'
  298.                 //$this->attempt = 1;
  299.                 //$this->last_item = 0;
  300.                 $this->items[$row['id']]->set_status($this->default_status);
  301.                 //Add that row to the lp_item_view table so that we have something to show in the stats page
  302.                 $sql_ins "INSERT INTO $lp_item_view_table .
  303.                         "(lp_item_id, lp_view_id, view_count, status) VALUES " .
  304.                         "(".$row['id'].",".$this->lp_view_id.",1,'not attempted')";
  305.                 if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - Inserting blank item_view : '.$sql_ins,0);}
  306.                 $res_ins api_sql_query($sql_ins__FILE____LINE__);
  307.             }
  308.             //setting the view in the item object
  309.             $this->items[$row['id']]->set_lp_view($this->lp_view_id);
  310.         }
  311.         $this->ordered_items = $this->get_flat_ordered_items_list($this->get_id(),0);
  312.         $this->max_ordered_items 0;
  313.         foreach($this->ordered_items as $index=>$dummy){
  314.             if($index $this->max_ordered_items AND !empty($dummy)){
  315.                 $this->max_ordered_items $index;
  316.             }
  317.         }
  318.         //TODO define the current item better
  319.         $this->first();
  320.         if($this->debug>2){error_log('New LP - learnpath::learnpath() '.__LINE__.' - End of learnpath constructor for learnpath '.$this->get_id(),0);}
  321.     }
  322.     
  323.     /**
  324.      * Function rewritten based on old_add_item() from Yannick Warnier. Due the fact that users can decide where the item should come, I had to overlook this function and
  325.      * I found it better to rewrite it. Old function is still available. Added also the possibility to add a description.
  326.      *
  327.      * @param int $parent 
  328.      * @param int $previous 
  329.      * @param string $type 
  330.      * @param int $id 
  331.      * @param string $title 
  332.      * @param string $description 
  333.      * @return int 
  334.      */
  335.     function add_item($parent$previous$type 'dokeos_chapter'$id$title$description$prerequisites=0)
  336.     {
  337.         global $charset;
  338.         
  339.         if($this->debug>0){error_log('New LP - In learnpath::add_item('.$parent.','.$previous.','.$type.','.$id.','.$title.')',0);}
  340.         
  341.         $tbl_lp_item Database::get_course_table('lp_item');
  342.         $parent intval($parent);
  343.         $previous intval($previous);
  344.         $type $this->escape_string($type);
  345.         $id intval($id);
  346.         
  347.         $title $this->escape_string(mb_convert_encoding($title,$this->encoding,$charset));
  348.         $description $this->escape_string(mb_convert_encoding($description,$this->encoding,$charset))
  349.         
  350.         $sql_count "
  351.             SELECT COUNT(id) AS num
  352.             FROM " $tbl_lp_item "
  353.             WHERE
  354.                 lp_id = " $this->get_id(" AND
  355.                 parent_item_id = " $parent;
  356.         
  357.         $res_count api_sql_query($sql_count__FILE____LINE__);
  358.            $row Database::fetch_array($res_count);
  359.            
  360.            $num $row['num'];
  361.            
  362.            if($num 0)
  363.            {
  364.             if($previous == 0)
  365.             {
  366.                 $sql "
  367.                        SELECT
  368.                            id,
  369.                            next_item_id,
  370.                            display_order
  371.                        FROM " $tbl_lp_item "
  372.                        WHERE
  373.                            lp_id = " $this->get_id(" AND
  374.                            parent_item_id = " $parent " AND
  375.                            previous_item_id = 0 OR previous_item_id=".$parent;
  376.                 
  377.                 $result api_sql_query($sql__FILE____LINE__);
  378.                    $row Database::fetch_array($result);
  379.                    
  380.                    $tmp_previous 0;
  381.                    $next $row['id'];
  382.                    $display_order 0;
  383.             }
  384.             else
  385.             {
  386.                    $previous = (int) $previous;
  387.                    
  388.                    $sql "
  389.                        SELECT
  390.                            id,
  391.                            previous_item_id,
  392.                            next_item_id,
  393.                            display_order
  394.                        FROM " $tbl_lp_item "
  395.                        WHERE
  396.                            lp_id = " $this->get_id(" AND
  397.                            id = " $previous;
  398.                    
  399.                    $result api_sql_query($sql__FILE____LINE__);
  400.                    $row Database::fetch_array($result);
  401.                    
  402.                    $tmp_previous $row['id'];
  403.                    $next $row['next_item_id'];
  404.                    
  405.                    $display_order $row['display_order'];
  406.             }
  407.            }
  408.            else
  409.         {
  410.                $tmp_previous 0;
  411.                $next 0;
  412.                $display_order 0;
  413.         }
  414.         
  415.         $new_item_id = -1;
  416.         $id $this->escape_string($id);
  417.         
  418.         if($type == 'quiz')
  419.         {
  420.             $sql 'SELECT SUM(ponderation)
  421.                     FROM '.Database :: get_course_table(TABLE_QUIZ_QUESTION).' as quiz_question
  422.                     INNER JOIN  '.Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION).' as quiz_rel_question
  423.                         ON quiz_question.id = quiz_rel_question.question_id
  424.                         AND quiz_rel_question.exercice_id = '.$id;
  425.             $rsQuiz api_sql_query($sql__FILE____LINE__);
  426.             $max_score Database::result($rsQuiz00);
  427.         }
  428.         else
  429.         {
  430.             $max_score 100;
  431.         }
  432.         
  433.         if($prerequisites!=0){
  434.             $sql_ins "
  435.                 INSERT INTO " $tbl_lp_item " (
  436.                     lp_id,
  437.                     item_type,
  438.                     ref,
  439.                     title,
  440.                     description,
  441.                     path,
  442.                     max_score,
  443.                     parent_item_id,
  444.                     previous_item_id,
  445.                     next_item_id,
  446.                     display_order, 
  447.                     prerequisite
  448.                 ) VALUES (
  449.                     " $this->get_id(",
  450.                     '" $type "',
  451.                     '',
  452.                     '" $title "',
  453.                     '" $description "',
  454.                     '" $id "',
  455.                     '" $max_score"',
  456.                     " $parent ",
  457.                     " $previous ",
  458.                     " $next ",
  459.                     " ($display_order 1",
  460.                     " $prerequisites "
  461.                 )";
  462.         }
  463.         
  464.         else{
  465.             //insert new item
  466.             $sql_ins "
  467.                 INSERT INTO " $tbl_lp_item " (
  468.                     lp_id,
  469.                     item_type,
  470.                     ref,
  471.                     title,
  472.                     description,
  473.                     path,
  474.                     max_score,
  475.                     parent_item_id,
  476.                     previous_item_id,
  477.                     next_item_id,
  478.                     display_order
  479.                 ) VALUES (
  480.                     " $this->get_id(",
  481.                     '" $type "',
  482.                     '',
  483.                     '" $title "',
  484.                     '" $description "',
  485.                     '" $id "',
  486.                     '" $max_score"',
  487.                     " $parent ",
  488.                     " $previous ",
  489.                     " $next ",
  490.                     " ($display_order 1"
  491.                 )";
  492.         }
  493.         
  494.         if($this->debug>2){error_log('New LP - Inserting dokeos_chapter: '.$sql_ins,0);}
  495.  
  496.         $res_ins api_sql_query($sql_ins__FILE____LINE__);
  497.         
  498.         if($res_ins 0)
  499.         {
  500.             $new_item_id Database::get_last_insert_id($res_ins);
  501.             
  502.             //update the item that should come after the new item
  503.             $sql_update_next "
  504.                 UPDATE " $tbl_lp_item "
  505.                 SET previous_item_id = " $new_item_id "
  506.                 WHERE id = " $next;
  507.             
  508.             $res_update_next api_sql_query($sql_update_next__FILE____LINE__);
  509.             
  510.             //update the item that should be before the new item
  511.             $sql_update_previous "
  512.                 UPDATE " $tbl_lp_item "
  513.                 SET next_item_id = " $new_item_id "
  514.                 WHERE id = " $tmp_previous;
  515.             
  516.             $res_update_previous api_sql_query($sql_update_previous__FILE____LINE__);
  517.                        
  518.             //update all the items after the new item
  519.             $sql_update_order "
  520.                 UPDATE " $tbl_lp_item "
  521.                 SET display_order = display_order + 1
  522.                 WHERE
  523.                     lp_id = " $this->get_id(" AND
  524.                     id <> " $new_item_id " AND
  525.                     parent_item_id = " $parent " AND
  526.                     display_order > " $display_order;
  527.             
  528.             $res_update_previous api_sql_query($sql_update_order__FILE____LINE__);
  529.             
  530.             //update the item that should come after the new item
  531.             $sql_update_ref "
  532.                 UPDATE " $tbl_lp_item "
  533.                 SET ref = " $new_item_id "
  534.                 WHERE id = " $new_item_id;
  535.             
  536.             api_sql_query($sql_update_ref__FILE____LINE__);
  537.             
  538.         }
  539.         
  540.         return $new_item_id;
  541.     }
  542.    
  543.     /**
  544.      * Static admin function allowing addition of a learnpath to a course.
  545.      * @param    string    Course code
  546.      * @param    string    Learnpath name
  547.      * @param    string    Learnpath description string, if provided
  548.      * @param    string    Type of learnpath (default = 'guess', others = 'dokeos', 'aicc',...)
  549.      * @param    string    Type of files origin (default = 'zip', others = 'dir','web_dir',...)
  550.      * @param    string    Zip file containing the learnpath or directory containing the learnpath
  551.      * @return    integer    The new learnpath ID on success, 0 on failure
  552.      */
  553.     function add_lp($course,$name,$description='',$learnpath='guess',$origin='zip',$zipname='')
  554.     {
  555.         //if($this->debug>0){error_log('New LP - In learnpath::add_lp()',0);}
  556.         //TODO
  557.         $tbl_lp Database::get_course_table('lp');
  558.         //check course code exists
  559.         //check lp_name doesn't exist, otherwise append something
  560.         $i 0;
  561.         $name learnpath::escape_string(htmlentities($name))//Kevin Van Den Haute: added htmlentities()
  562.         $check_name "SELECT * FROM $tbl_lp WHERE name = '$name'";
  563.         //if($this->debug>2){error_log('New LP - Checking the name for new LP: '.$check_name,0);}
  564.         $res_name api_sql_query($check_name__FILE____LINE__);
  565.         while(Database::num_rows($res_name)){
  566.             //there is already one such name, update the current one a bit
  567.             $i++;
  568.             $name $name.' - '.$i;
  569.             $check_name "SELECT * FROM $tbl_lp WHERE name = '$name'";
  570.             //if($this->debug>2){error_log('New LP - Checking the name for new LP: '.$check_name,0);}
  571.             $res_name api_sql_query($check_name__FILE____LINE__);
  572.         }
  573.         //new name does not exist yet; keep it
  574.         //escape description
  575.         $description learnpath::escape_string(htmlentities($description))//Kevin: added htmlentities()
  576.         $type 1;
  577.         switch($learnpath){
  578.             case 'guess':
  579.                 break;
  580.             case 'dokeos':
  581.                 $type 1;
  582.                 break;
  583.             case 'aicc':
  584.                 break;
  585.         }
  586.         switch($origin){
  587.             case 'zip':
  588.                 //check zipname string. If empty, we are currently creating a new Dokeos learnpath
  589.                 break;
  590.             case 'manual':
  591.             default:
  592.                 $get_max "SELECT MAX(display_order) FROM $tbl_lp";
  593.                 $res_max api_sql_query($get_max__FILE____LINE__);
  594.                 if(Database::num_rows($res_max)<1){
  595.                     $dsp 1;
  596.                 }else{
  597.                     $row Database::fetch_array($res_max);
  598.                     $dsp $row[0]+1;
  599.                 }
  600.                 $sql_insert "INSERT INTO $tbl_lp .
  601.                         "(lp_type,name,description,path,default_view_mod," .
  602.                         "default_encoding,display_order,content_maker," .
  603.                         "content_local,js_lib) " .
  604.                         "VALUES ($type,'$name','$description','','embedded',.
  605.                         "'UTF-8','$dsp','Dokeos',.
  606.                         "'local','')";
  607.                 //if($this->debug>2){error_log('New LP - Inserting new lp '.$sql_insert,0);}
  608.                 $res_insert api_sql_query($sql_insert__FILE____LINE__);
  609.                 $id Database::get_last_insert_id();
  610.                 if($id>0){
  611.                     //insert into item_property
  612.                     api_item_property_update(api_get_course_info(),TOOL_LEARNPATH,$id,'LearnpathAdded',api_get_user_id());
  613.                     return $id;
  614.                 }
  615.                 break;
  616.         }
  617.     }
  618.  
  619.     /**
  620.      * Appends a message to the message attribute
  621.      * @param    string    Message to append.
  622.      */
  623.     function append_message($string)
  624.     {
  625.         if($this->debug>0){error_log('New LP - In learnpath::append_message()',0);}
  626.         $this->message .= $string;
  627.     }
  628.  
  629.     /**
  630.      * Autocompletes the parents of an item in case it's been completed or passed
  631.      * @param    integer    Optional ID of the item from which to look for parents
  632.      */
  633.     function autocomplete_parents($item)
  634.     {
  635.         if($this->debug>0){error_log('New LP - In learnpath::autocomplete_parents()',0);}
  636.         if(empty($item)){
  637.             $item $this->current;
  638.         }
  639.         $parent_id $this->items[$item]->get_parent();
  640.         if($this->debug>2){error_log('New LP - autocompleting parent of item '.$item.' (item '.$parent_id.')',0);}
  641.         if(is_object($this->items[$item]and !empty($parent_id))
  642.         {//if $item points to an object and there is a parent
  643.             if($this->debug>2){error_log('New LP - '.$item.' is an item, proceed',0);}
  644.             $current_item =$this->items[$item];
  645.             $parent =$this->items[$parent_id]//get the parent
  646.             //new experiment including failed and browsed in completed status
  647.             $current_status $current_item->get_status();
  648.             if($current_item->is_done(|| $current_status=='browsed' || $current_status=='failed')
  649.             {
  650.                 //if the current item is completed or passes or succeeded
  651.                 $completed true;
  652.                 if($this->debug>2){error_log('New LP - Status of current item is alright',0);}
  653.                 foreach($parent->get_children(as $child)
  654.                 {
  655.                     //check all his brothers (his parent's children) for completion status
  656.                     if($child!= $item)
  657.                     {
  658.                         if($this->debug>2){error_log('New LP - Looking at brother with ID '.$child.', status is '.$this->items[$child]->get_status(),0);}
  659.                         //if($this->items[$child]->status_is(array('completed','passed','succeeded')))
  660.                         //Trying completing parents of failed and browsed items as well
  661.                         if($this->items[$child]->status_is(array('completed','passed','succeeded','browsed','failed')))
  662.                         {
  663.                             //keep completion status to true
  664.                         }else{
  665.                             if($this->debug>2){error_log('New LP - Found one incomplete child of '.$parent_id.': '.$child.' is '.$this->items[$child]->get_status(),0);}
  666.                             $completed false;
  667.                         }
  668.                     }
  669.                 }
  670.                 if($completed == true)
  671.                 //if all the children were completed
  672.                     $parent->set_status('completed');
  673.                     $parent->save(false,$this->prerequisites_match($parent->get_id()));
  674.                     $this->update_queue[$parent->get_id()$parent->get_status();
  675.                     if($this->debug>2){error_log('New LP - Added parent to update queue '.print_r($this->update_queue,true),0);}
  676.                     $this->autocomplete_parents($parent->get_id())//recursive call
  677.                 }
  678.             }else{
  679.                 //error_log('New LP - status of current item is not enough to get bothered with it',0);
  680.             }
  681.         }
  682.     }
  683.  
  684.     /**
  685.      * Autosaves the current results into the database for the whole learnpath
  686.      */
  687.     function autosave()
  688.     {
  689.         if($this->debug>0){error_log('New LP - In learnpath::autosave()',0);}
  690.         //TODO add aditionnal save operations for the learnpath itself
  691.     }
  692.  
  693.     /**
  694.      * Clears the message attribute
  695.      */
  696.     function clear_message()
  697.     {
  698.         if($this->debug>0){error_log('New LP - In learnpath::clear_message()',0);}
  699.         $this->message = '';
  700.     }
  701.     /**
  702.      * Closes the current resource
  703.      *
  704.      * Stops the timer
  705.      * Saves into the database if required
  706.      * Clears the current resource data from this object
  707.      * @return    boolean    True on success, false on failure
  708.      */
  709.  
  710.     function close()
  711.     {
  712.         if($this->debug>0){error_log('New LP - In learnpath::close()',0);}
  713.         if(empty($this->lp_id))
  714.         {
  715.             $this->error = 'Trying to close this learnpath but no ID is set';
  716.             return false;
  717.         }
  718.         $this->current_time_stop = time();
  719.         if($this->save)
  720.         {
  721.             $learnpath_view_table Database::get_course_table(TABLE_LP_VIEW);
  722.             /*
  723.             $sql = "UPDATE $learnpath_view_table " .
  724.                     "SET " .
  725.                     "stop_time = ".$this->current_time_stop.", " .
  726.                     "score = ".$this->current_score.", ".
  727.                     "WHERE learnpath_id = '".$this->lp_id."'";
  728.             //$res = Database::query($sql);
  729.             $res = api_sql_query($res);
  730.             if(mysql_affected_rows($res)<1)
  731.             {
  732.                 $this->error = 'Could not update learnpath_view table while closing learnpath';
  733.                 return false;
  734.             }
  735.             */            
  736.         }
  737.         $this->ordered_items = array();
  738.         $this->index=0;
  739.         unset($this->lp_id);
  740.         //unset other stuff
  741.         return true;
  742.     }
  743.  
  744.     /**
  745.      * Static admin function allowing removal of a learnpath
  746.      * @param    string    Course code
  747.      * @param    integer    Learnpath ID
  748.      * @param    string    Whether to delete data or keep it (default: 'keep', others: 'remove')
  749.      * @return    boolean    True on success, false on failure (might change that to return number of elements deleted)
  750.      */
  751.     function delete($course=null,$id=null,$delete='keep')
  752.     {
  753.         //TODO implement a way of getting this to work when the current object is not set
  754.         //In clear: implement this in the item class as well (abstract class) and use the given ID in queries
  755.         //if(empty($course)){$course = api_get_course_id();}
  756.         //if(empty($id)){$id = $this->get_id();}
  757.         //If an ID is specifically given and the current LP is not the same,
  758.         //prevent delete
  759.         if(!empty($id&& ($id != $this->lp_id)){return false;}
  760.         
  761.         //if($this->debug>0){error_log('New LP - In learnpath::delete()',0);}
  762.         foreach($this->items as $id => $dummy)
  763.         {
  764.             $this->items[$id]->delete();
  765.         }
  766.         $lp Database::get_course_table('lp');
  767.         $lp_view Database::get_course_table('lp_view');
  768.         $sql_del_view "DELETE FROM $lp_view WHERE lp_id = ".$this->lp_id;
  769.         //if($this->debug>2){error_log('New LP - Deleting views bound to lp '.$this->lp_id.': '.$sql_del_view,0);}
  770.         $res_del_view api_sql_query($sql_del_view__FILE____LINE__);
  771.     $this->toggle_publish($this->lp_id,'i');
  772.         //if($this->debug>2){error_log('New LP - Deleting lp '.$this->lp_id.' of type '.$this->type,0);}
  773.         if($this->type == OR $this->type==3){
  774.             //this is a scorm learning path, delete the files as well
  775.             $sql "SELECT path FROM $lp WHERE id = ".$this->lp_id;
  776.             $res api_sql_query($sql__FILE____LINE__);
  777.             if(Database::num_rows($res)>0){
  778.                 $row Database::fetch_array($res);
  779.                 $path $row['path'];
  780.                 $sql "SELECT id FROM $lp WHERE path = '$path' AND id != ".$this->lp_id;
  781.                 $res api_sql_query($sql__FILE____LINE__);
  782.                 if(Database::num_rows($res)>0)
  783.                 //another learning path uses this directory, so don't delete it 
  784.                     if($this->debug>2){error_log('New LP - In learnpath::delete(), found other LP using path '.$path.', keeping directory',0);}
  785.                 }else{
  786.                     //no other LP uses that directory, delete it
  787.                      $course_rel_dir  api_get_course_path().'/scorm/'//scorm dir web path starting from /courses
  788.                     $course_scorm_dir api_get_path(SYS_COURSE_PATH).$course_rel_dir//absolute system path for this course
  789.                     if($delete == 'remove' && is_dir($course_scorm_dir.$pathand !empty($course_scorm_dir)){
  790.                         if($this->debug>2){error_log('New LP - In learnpath::delete(), found SCORM, deleting directory: '.$course_scorm_dir.$path,0);}
  791.                         exec('rm -rf '.$course_scorm_dir.$path);
  792.                     }
  793.                 }
  794.             }
  795.         }
  796.         $sql_del_lp "DELETE FROM $lp WHERE id = ".$this->lp_id;
  797.         //if($this->debug>2){error_log('New LP - Deleting lp '.$this->lp_id.': '.$sql_del_lp,0);}
  798.         $res_del_lp api_sql_query($sql_del_lp__FILE____LINE__);
  799.         $this->update_display_order();//updates the display order of all lps
  800.         //TODO: also delete items and item-views
  801.     }
  802.  
  803.     /**
  804.      * Removes all the children of one item - dangerous!
  805.      * @param    integer    Element ID of which children have to be removed
  806.      * @return    integer    Total number of children removed
  807.      */
  808.     function delete_children_items($id){
  809.         if($this->debug>0){error_log('New LP - In learnpath::delete_children_items('.$id.')',0);}
  810.         $num 0;
  811.         if(empty($id|| $id != strval(intval($id))){return false;}
  812.         $lp_item Database::get_course_table('lp_item');
  813.         $sql "SELECT * FROM $lp_item WHERE parent_item_id = $id";
  814.         $res api_sql_query($sql__FILE____LINE__);
  815.         while($row Database::fetch_array($res)){
  816.             $num += $this->delete_children_items($row['id']);
  817.             $sql_del "DELETE FROM $lp_item WHERE id = ".$row['id'];
  818.             $res_del api_sql_query($sql_del__FILE____LINE__);
  819.             $num++;
  820.         }
  821.         return $num;
  822.     }
  823.  
  824.     /**
  825.      * Removes an item from the current learnpath
  826.      * @param    integer    Elem ID (0 if first)
  827.      * @param    integer    Whether to remove the resource/data from the system or leave it (default: 'keep', others 'remove')
  828.      * @return    integer    Number of elements moved
  829.      * @todo implement resource removal
  830.      */
  831.     function delete_item($id$remove='keep')
  832.     {
  833.         if($this->debug>0){error_log('New LP - In learnpath::delete_item()',0);}
  834.         //TODO - implement the resource removal
  835.         if(empty($id|| $id != strval(intval($id))){return false;}
  836.         //first select item to get previous, next, and display order
  837.         $lp_item Database::get_course_table('lp_item');
  838.         $sql_sel "SELECT * FROM $lp_item WHERE id = $id";
  839.         $res_sel api_sql_query($sql_sel,__FILE__,__LINE__);
  840.         if(Database::num_rows($res_sel)<1){return false;}
  841.         $row Database::fetch_array($res_sel);
  842.         $previous $row['previous_item_id'];
  843.         $next $row['next_item_id'];
  844.         $display $row['display_order'];
  845.         $parent $row['parent_item_id'];
  846.         $lp $row['lp_id'];
  847.         //delete children items
  848.         $num $this->delete_children_items($id);
  849.         if($this->debug>2){error_log('New LP - learnpath::delete_item() - deleted '.$num.' children of element '.$id,0);}
  850.         //now delete the item
  851.         $sql_del "DELETE FROM $lp_item WHERE id = $id";
  852.         if($this->debug>2){error_log('New LP - Deleting item: '.$sql_del,0);}
  853.         $res_del api_sql_query($sql_del,__FILE__,__LINE__);
  854.         //now update surrounding items
  855.         $sql_upd "UPDATE $lp_item SET next_item_id = $next WHERE id = $previous";
  856.         $res_upd api_sql_query($sql_upd,__FILE__,__LINE__);
  857.         $sql_upd "UPDATE $lp_item SET previous_item_id = $previous WHERE id = $next";
  858.         $res_upd api_sql_query($sql_upd,__FILE__,__LINE__);
  859.         //now update all following items with new display order
  860.         $sql_all "UPDATE $lp_item SET display_order = display_order-1 WHERE lp_id = $lp AND parent_item_id = $parent AND display_order > $display";
  861.         $res_all api_sql_query($sql_all,__FILE__,__LINE__);
  862.     }
  863.  
  864.     /**
  865.      * Updates an item's content in place
  866.      * @param    integer    Element ID
  867.      * @param    string    New content
  868.      * @return    boolean    True on success, false on error
  869.      */
  870.     function edit_item($id$parent$previous$title$description$prerequisites=0)
  871.     {
  872.         if($this->debug > 0){error_log('New LP - In learnpath::edit_item()'0);}
  873.  
  874.         if(empty($idor ($id != strval(intval($id))) or empty($title))return false}
  875.         
  876.         $tbl_lp_item Database::get_course_table('lp_item');
  877.         
  878.         $sql_select "
  879.             SELECT *
  880.             FROM " $tbl_lp_item "
  881.             WHERE id = " $id;
  882.         $res_select api_sql_query($sql_select__FILE____LINE__);
  883.         $row_select Database::fetch_array($res_select);
  884.         
  885.         $same_parent    ($row_select['parent_item_id'== $parenttrue false;
  886.         $same_previous    ($row_select['previous_item_id'== $previoustrue false;
  887.         
  888.         if($same_parent && $same_previous)
  889.         {
  890.             //only update title and description
  891.             $sql_update "
  892.                 UPDATE " $tbl_lp_item "
  893.                 SET
  894.                     title = '" $this->escape_string(htmlentities($title)) "',
  895.                     prerequisite = '".$prerequisites."',
  896.                     description = '" $this->escape_string(htmlentities($description)) "'
  897.                 WHERE id = " $id;
  898.             $res_update api_sql_query($sql_update__FILE____LINE__);
  899.         }
  900.         else
  901.         {
  902.             $old_parent         $row_select['parent_item_id'];
  903.             $old_previous     $row_select['previous_item_id'];
  904.             $old_next         $row_select['next_item_id'];
  905.             $old_order         $row_select['display_order'];
  906.             $old_prerequisite$row_select['prerequisite'];
  907.             
  908.             /* BEGIN -- virtually remove the current item id */
  909.             /* for the next and previous item it is like the current item doesn't exist anymore */
  910.             
  911.             if($old_previous != 0)
  912.             {
  913.                 $sql_update_next "
  914.                     UPDATE " $tbl_lp_item "
  915.                     SET next_item_id = " $old_next "
  916.                     WHERE id = " $old_previous;
  917.                 $res_update_next api_sql_query($sql_update_next__FILE____LINE__);
  918.                 //echo '<p>' . $sql_update_next . '</p>';
  919.             }
  920.             
  921.             if($old_next != 0)
  922.             {
  923.                 $sql_update_previous "
  924.                     UPDATE " $tbl_lp_item "
  925.                     SET previous_item_id = " $old_previous "
  926.                     WHERE id = " $old_next;
  927.                 $res_update_previous api_sql_query($sql_update_previous__FILE____LINE__);
  928.                 
  929.                 //echo '<p>' . $sql_update_previous . '</p>';
  930.             }
  931.             
  932.             //display_order - 1 for every item with a display_order bigger then the display_order of the current item
  933.             $sql_update_order "
  934.                 UPDATE " $tbl_lp_item "
  935.                 SET display_order = display_order - 1
  936.                 WHERE
  937.                     display_order > " $old_order " AND
  938.                     parent_item_id = " $old_parent;
  939.             $res_update_order api_sql_query($sql_update_order__FILE____LINE__);
  940.             
  941.             //echo '<p>' . $sql_update_order . '</p>';
  942.             
  943.             /* END -- virtually remove the current item id */
  944.             
  945.             /* BEGIN -- update the current item id to his new location */
  946.             
  947.             if($previous == 0)
  948.             {
  949.                 //select the data of the item that should come after the current item
  950.                 $sql_select_old "
  951.                     SELECT
  952.                         id,
  953.                         display_order
  954.                     FROM " $tbl_lp_item "
  955.                     WHERE
  956.                         lp_id = " $this->lp_id . " AND
  957.                         parent_item_id = " $parent " AND
  958.                         previous_item_id = " $previous;
  959.                 $res_select_old api_sql_query($sql_select_old__FILE____LINE__);
  960.                 $row_select_old Database::fetch_array($res_select_old);
  961.                 
  962.                 //echo '<p>' . $sql_select_old . '</p>';
  963.                 
  964.                 //if the new parent didn't have children before
  965.                 if(Database::num_rows($res_select_old== 0)
  966.                 {
  967.                     $new_next    0;
  968.                     $new_order    1;
  969.                 }
  970.                 else
  971.                 {
  972.                     $new_next    $row_select_old['id'];
  973.                     $new_order    $row_select_old['display_order'];
  974.                 }
  975.                 
  976.                 //echo 'New next_item_id of current item: ' . $new_next . '<br />';
  977.                 //echo 'New previous_item_id of current item: ' . $previous . '<br />';
  978.                 //echo 'New display_order of current item: ' . $new_order . '<br />';
  979.                 
  980.                 
  981.             }
  982.             else
  983.             {
  984.                 //select the data of the item that should come before the current item
  985.                 $sql_select_old "
  986.                     SELECT
  987.                         next_item_id,
  988.                         display_order
  989.                     FROM " $tbl_lp_item "
  990.                     WHERE id = " $previous;
  991.                 $res_select_old api_sql_query($sql_select_old__FILE____LINE__);
  992.                 $row_select_old Database::fetch_array($res_select_old);
  993.                 
  994.                 //echo '<p>' . $sql_select_old . '</p>';
  995.                 
  996.                 //echo 'New next_item_id of current item: ' . $row_select_old['next_item_id'] . '<br />';
  997.                 //echo 'New previous_item_id of current item: ' . $previous . '<br />';
  998.                 //echo 'New display_order of current item: ' . ($row_select_old['display_order'] + 1) . '<br />';
  999.                 
  1000.                 $new_next    $row_select_old['next_item_id'];
  1001.                 $new_order    $row_select_old['display_order'1;
  1002.             }
  1003.             
  1004.             //update the current item with the new data
  1005.             $sql_update "
  1006.                 UPDATE " $tbl_lp_item "
  1007.                 SET
  1008.                     title = '" $this->escape_string(htmlentities($title)) "',
  1009.                     description = '" $this->escape_string(htmlentities($description)) "',
  1010.                     parent_item_id = " $parent ",
  1011.                     previous_item_id = " $previous ",
  1012.                     next_item_id = " $new_next ",
  1013.                     display_order = " $new_order "
  1014.                 WHERE id = " $id;
  1015.             $res_update_next api_sql_query($sql_update__FILE____LINE__);
  1016.             //echo '<p>' . $sql_update . '</p>';
  1017.             
  1018.             if($previous != 0)
  1019.             {
  1020.                 //update the previous item's next_item_id
  1021.                 $sql_update_previous "
  1022.                     UPDATE " $tbl_lp_item "
  1023.                     SET next_item_id = " $id "
  1024.                     WHERE id = " $previous;
  1025.                 $res_update_next api_sql_query($sql_update_previous__FILE____LINE__);
  1026.                 //echo '<p>' . $sql_update_previous . '</p>';
  1027.             }
  1028.             
  1029.             if($new_next != 0)
  1030.             {
  1031.                    //update the next item's previous_item_id
  1032.                 $sql_update_next "
  1033.                     UPDATE " $tbl_lp_item "
  1034.                     SET previous_item_id = " $id "
  1035.                     WHERE id = " $new_next;
  1036.                   $res_update_next api_sql_query($sql_update_next__FILE____LINE__);
  1037.                   //echo '<p>' . $sql_update_next . '</p>';
  1038.             }
  1039.             
  1040.             if($old_prerequisite!=$prerequisites){
  1041.                 $sql_update_next "
  1042.                     UPDATE " $tbl_lp_item "
  1043.                     SET prerequisite = " $prerequisites "
  1044.                     WHERE id = " $id;
  1045.                 $res_update_next api_sql_query($sql_update_next__FILE____LINE__);
  1046.             }
  1047.             
  1048.             //update all the items with the same or a bigger display_order than 
  1049.             //the current item
  1050.             $sql_update_order "
  1051.                    UPDATE " $tbl_lp_item "
  1052.                    SET display_order = display_order + 1
  1053.                    WHERE
  1054.                        lp_id = " $this->get_id(" AND
  1055.                        id <> " $id " AND
  1056.                        parent_item_id = " $parent " AND
  1057.                        display_order >= " $new_order;
  1058.             
  1059.             $res_update_next api_sql_query($sql_update_order__FILE____LINE__);
  1060.             //echo '<p>' . $sql_update_order . '</p>';
  1061.             
  1062.             /* END -- update the current item id to his new location */
  1063.         }
  1064.     }
  1065.     
  1066.     /**
  1067.  
  1068.      * Updates an item's prereq in place
  1069.  
  1070.      * @param    integer    Element ID
  1071.  
  1072.      * @param    string    Prerequisite Element ID
  1073.      * 
  1074.      * @param    string    Prerequisite item type
  1075.      * 
  1076.      * @param    string    Prerequisite min score
  1077.      * 
  1078.      * @param    string    Prerequisite max score
  1079.  
  1080.      * @return    boolean    True on success, false on error
  1081.  
  1082.      */
  1083.  
  1084.     function edit_item_prereq($id$prerequisite_id$mastery_score 0$max_score 100)
  1085.  
  1086.     {
  1087.         if($this->debug>0){error_log('New LP - In learnpath::edit_item_prereq('.$id.','.$prerequisite_id.','.$mastery_score.','.$max_score.')',0);}
  1088.  
  1089.         if(empty($idor ($id != strval(intval($id))) or empty($prerequisite_id))return false}
  1090.  
  1091.         $prerequisite_id $this->escape_string($prerequisite_id);
  1092.  
  1093.         $tbl_lp_item Database::get_course_table('lp_item');
  1094.         
  1095.         if(!is_numeric($mastery_score|| $mastery_score 0)
  1096.             $mastery_score 0;
  1097.         
  1098.         if(!is_numeric($max_score|| $max_score 0)
  1099.             $max_score 100;
  1100.         
  1101.         if($mastery_score $max_score)
  1102.             $max_score $mastery_score;
  1103.         
  1104.         if(!is_numeric($prerequisite_id))
  1105.             $prerequisite_id 'NULL';
  1106.             
  1107.         $sql_upd "
  1108.             UPDATE " $tbl_lp_item "
  1109.             SET prerequisite = ".$prerequisite_id." WHERE id = ".$id;
  1110.         $res_upd api_sql_query($sql_upd ,__FILE____LINE__);
  1111.  
  1112.         if($prerequisite_id!='NULL' && $prerequisite_id!='')
  1113.         {
  1114.             $sql_upd " UPDATE ".$tbl_lp_item." SET         
  1115.                     mastery_score = " $mastery_score .
  1116.                     //", max_score = " . $max_score . " " . //max score cannot be changed in the form anyway - see display_item_prerequisites_form()
  1117.                     " WHERE ref = '" $prerequisite_id."'" //will this be enough to ensure unicity?
  1118.             
  1119.             $res_upd api_sql_query($sql_upd ,__FILE____LINE__);
  1120.         }
  1121.         //TODO update the item object (can be ignored for now because refreshed)
  1122.  
  1123.         return true;
  1124.  
  1125.     }
  1126.  
  1127.     /**
  1128.  
  1129.      * Escapes a string with the available database escape function
  1130.  
  1131.      * @param    string    String to escape
  1132.  
  1133.      * @return    string    String escaped
  1134.  
  1135.      */
  1136.  
  1137.     function escape_string($string){
  1138.  
  1139.         //if($this->debug>0){error_log('New LP - In learnpath::escape_string('.$string.')',0);}
  1140.  
  1141.         return Database::escape_string($string);
  1142.  
  1143.     }
  1144.  
  1145.     /**
  1146.  
  1147.      * Static admin function exporting a learnpath into a zip file
  1148.  
  1149.      * @param    string    Export type (scorm, zip, cd)
  1150.  
  1151.      * @param    string    Course code
  1152.  
  1153.      * @param    integer Learnpath ID
  1154.  
  1155.      * @param    string    Zip file name
  1156.  
  1157.      * @return    string    Zip file path (or false on error)
  1158.  
  1159.      */
  1160.  
  1161.     function export_lp($type$course$id$zipname)
  1162.  
  1163.     {
  1164.  
  1165.         //if($this->debug>0){error_log('New LP - In learnpath::export_lp()',0);}
  1166.  
  1167.         //TODO
  1168.  
  1169.         if(empty($typeOR empty($courseOR empty($idOR empty($zipname)){return false;}
  1170.  
  1171.         $url '';
  1172.  
  1173.         switch($type){
  1174.  
  1175.             case 'scorm':
  1176.                 
  1177.                 break;
  1178.  
  1179.             case 'zip':
  1180.  
  1181.                 break;
  1182.  
  1183.             case 'cdrom':
  1184.  
  1185.                 break;
  1186.  
  1187.         }
  1188.  
  1189.         return $url;
  1190.  
  1191.     }
  1192.  
  1193.     /**
  1194.  
  1195.      * Gets all the chapters belonging to the same parent as the item/chapter given
  1196.  
  1197.      * Can also be called as abstract method
  1198.  
  1199.      * @param    integer    Item ID
  1200.  
  1201.      * @return    array    A list of all the "brother items" (or an empty array on failure)
  1202.  
  1203.      */
  1204.  
  1205.     function get_brother_chapters($id){
  1206.  
  1207.         if($this->debug>0){error_log('New LP - In learnpath::get_brother_chapters()',0);}
  1208.  
  1209.         if(empty($idOR $id != strval(intval($id)))return array();}
  1210.  
  1211.         $lp_item Database::get_course_table('lp_item');
  1212.  
  1213.         $sql_parent "SELECT * FROM $lp_item WHERE id = $id AND item_type='dokeos_chapter'";
  1214.  
  1215.         $res_parent api_sql_query($sql_parent,__FILE__,__LINE__);
  1216.  
  1217.         if(Database::num_rows($res_parent)>0){
  1218.  
  1219.             $row_parent Database::fetch_array($res_parent);
  1220.  
  1221.             $parent $row_parent['parent_item_id'];
  1222.  
  1223.             $sql_bros "SELECT * FROM $lp_item WHERE parent_item_id = $parent AND id = $id AND item_type='dokeos_chapter' ORDER BY display_order";
  1224.  
  1225.             $res_bros api_sql_query($sql_bros,__FILE__,__LINE__);
  1226.  
  1227.             $list array();
  1228.  
  1229.             while ($row_bro Database::fetch_array($res_bros)){
  1230.  
  1231.                 $list[$row_bro;
  1232.  
  1233.             }
  1234.  
  1235.             return $list;
  1236.  
  1237.         }
  1238.  
  1239.         return array();
  1240.  
  1241.     }
  1242.  
  1243.     /**
  1244.  
  1245.      * Gets all the items belonging to the same parent as the item given
  1246.  
  1247.      * Can also be called as abstract method
  1248.  
  1249.      * @param    integer    Item ID
  1250.  
  1251.      * @return    array    A list of all the "brother items" (or an empty array on failure)
  1252.  
  1253.      */
  1254.  
  1255.     function get_brother_items($id){
  1256.  
  1257.         if($this->debug>0){error_log('New LP - In learnpath::get_brother_items('.$id.')',0);}
  1258.  
  1259.         if(empty($idOR $id != strval(intval($id)))return array();}
  1260.  
  1261.         $lp_item Database::get_course_table('lp_item');
  1262.  
  1263.         $sql_parent "SELECT * FROM $lp_item WHERE id = $id";
  1264.  
  1265.         $res_parent api_sql_query($sql_parent,__FILE__,__LINE__);
  1266.  
  1267.         if(Database::num_rows($res_parent)>0){
  1268.  
  1269.             $row_parent Database::fetch_array($res_parent);
  1270.  
  1271.             $parent $row_parent['parent_item_id'];
  1272.  
  1273.             $sql_bros "SELECT * FROM $lp_item WHERE parent_item_id = $parent ORDER BY display_order";
  1274.  
  1275.             $res_bros api_sql_query($sql_bros,__FILE__,__LINE__);
  1276.  
  1277.             $list array();
  1278.  
  1279.             while ($row_bro Database::fetch_array($res_bros)){
  1280.  
  1281.                 $list[$row_bro;
  1282.  
  1283.             }
  1284.  
  1285.             return $list;
  1286.  
  1287.         }
  1288.  
  1289.         return array();
  1290.  
  1291.     }
  1292.  
  1293.     /**
  1294.  
  1295.      * Gets the number of items currently completed
  1296.  
  1297.      * @return integer The number of items currently completed
  1298.  
  1299.      */
  1300.  
  1301.     function get_complete_items_count()
  1302.  
  1303.     {
  1304.  
  1305.         if($this->debug>0){error_log('New LP - In learnpath::get_complete_items_count()',0);}
  1306.  
  1307.            $i 0;
  1308.  
  1309.         foreach($this->items as $id => $dummy){
  1310.  
  1311.             //if($this->items[$id]->status_is(array('completed','passed','succeeded'))){
  1312.             //Trying failed and browsed considered "progressed" as well
  1313.             if($this->items[$id]->status_is(array('completed','passed','succeeded','browsed','failed'))&&$this->items[$id]->get_type()!='dokeos_chapter'&&$this->items[$id]->get_type()!='dir'){
  1314.  
  1315.                 $i++;
  1316.  
  1317.             }
  1318.  
  1319.         }
  1320.  
  1321.         return $i;
  1322.  
  1323.     }
  1324.  
  1325.     /**
  1326.      * Gets the current item ID
  1327.      * @return    integer    The current learnpath item id
  1328.      */
  1329.     function get_current_item_id()
  1330.     {
  1331.         $current 0;
  1332.         if($this->debug>0){error_log('New LP - In learnpath::get_current_item_id()',0);}
  1333.         if(!empty($this->current))
  1334.         {
  1335.             $current $this->current;
  1336.         }
  1337.         if($this->debug>2){error_log('New LP - In learnpath::get_current_item_id() - Returning '.$current,0);}
  1338.         return $current;
  1339.     }
  1340.     /**
  1341.      * Gets the total number of items available for viewing in this SCORM
  1342.      * @return    integer    The total number of items
  1343.      */
  1344.     function get_total_items_count()
  1345.     {
  1346.         if($this->debug>0){error_log('New LP - In learnpath::get_total_items_count()',0);}
  1347.         return count($this->items);
  1348.     }
  1349.     /**
  1350.      * Gets the total number of items available for viewing in this SCORM but without chapters
  1351.      * @return    integer    The total no-chapters number of items
  1352.      */
  1353.     {
  1354.         if($this->debug>0){error_log('New LP - In learnpath::get_total_items_count_without_chapters()',0);}
  1355.         $total=0;
  1356.         foreach($this->items as $temp=>$temp2){
  1357.             if(!in_array($temp2->get_type()array('dokeos_chapter','chapter','dir'))) $total++;
  1358.         }
  1359.         return $total;
  1360.     }
  1361.     /**
  1362.      * Gets the first element URL.
  1363.      * @return    string    URL to load into the viewer
  1364.      */
  1365.     function first()
  1366.     {
  1367.         if($this->debug>0){error_log('New LP - In learnpath::first()',0);}
  1368.         //test if the last_item_seen exists and is not a dir
  1369.         if(!empty($this->last_item_seen)
  1370.             && !empty($this->items[$this->last_item_seen])
  1371.             && $this->items[$this->last_item_seen]->get_type(!= 'dir'
  1372.             && $this->items[$this->last_item_seen]->get_type(!= 'dokeos_chapter'
  1373.             && $this->items[$this->last_item_seen]->is_done(!= true
  1374.         ){
  1375.             if($this->debug>2){error_log('New LP - In learnpath::first() - Last item seen is '.$this->last_item_seen.' of type '.$this->items[$this->last_item_seen]->get_type(),0);}
  1376.             $index = -1;
  1377.             foreach($this->ordered_items as $myindex => $item_id){
  1378.                 if($item_id == $this->last_item_seen){
  1379.                     $index $myindex;    
  1380.                     break;
  1381.                 }
  1382.             }
  1383.             if($index==-1){
  1384.                 //index hasn't changed, so item not found - panic (this shouldn't happen)
  1385.                 if($this->debug>2){error_log('New LP - Last item ('.$this->last_item_seen.') was found in items but not in ordered_items, panic!',0);}
  1386.                 return false;
  1387.             }else{
  1388.                 $this->last = $this->last_item_seen;
  1389.                 $this->current = $this->last_item_seen;
  1390.                 $this->index = $index;
  1391.             }
  1392.         }else{
  1393.             if($this->debug>2){error_log('New LP - In learnpath::first() - No last item seen',0);}
  1394.             $index 0;
  1395.             //loop through all ordered items and stop at the first item that is
  1396.             //not a directory *and* that has not been completed yet
  1397.             while (!empty($this->ordered_items[$index]
  1398.                     AND
  1399.                     is_a($this->items[$this->ordered_items[$index]],'learnpathItem')
  1400.                 AND 
  1401.                 (
  1402.                     $this->items[$this->ordered_items[$index]]->get_type(== 'dir'
  1403.                       OR $this->items[$this->ordered_items[$index]]->get_type(== 'dokeos_chapter'
  1404.                       OR $this->items[$this->ordered_items[$index]]->is_done(=== true
  1405.                 )
  1406.                 AND $index $this->max_ordered_items)
  1407.             {
  1408.                    $index ++;
  1409.             }
  1410.             $this->last = $this->current;
  1411.             //current is 
  1412.             $this->current = $this->ordered_items[$index];
  1413.             $this->index = $index;
  1414.             if($this->debug>2){error_log('New LP - In learnpath::first() - No last item seen. New last = '.$this->last.'('.$this->ordered_items[$index].')',0);}
  1415.         }
  1416.         if($this->debug>2){error_log('New LP - In learnpath::first() - First item is '.$this->get_current_item_id());}
  1417.     }
  1418.  
  1419.     /**
  1420.  
  1421.      * Gets the information about an item in a format usable as JavaScript to update
  1422.  
  1423.      * the JS API by just printing this content into the <head> section of the message frame
  1424.  
  1425.      * @param    integer        Item ID
  1426.  
  1427.      * @return    string 
  1428.  
  1429.      */
  1430.  
  1431.     function get_js_info($item_id=''){
  1432.  
  1433.         if($this->debug>0){error_log('New LP - In learnpath::get_js_info('.$item_id.')',0);}
  1434.  
  1435.         $info '';
  1436.  
  1437.         $item_id $this->escape_string($item_id);
  1438.  
  1439.         if(!empty($item_id&& is_object($this->items[$item_id])){
  1440.  
  1441.             //if item is defined, return values from DB
  1442.  
  1443.             $oItem $this->items[$item_id];
  1444.  
  1445.             $info .= '<script language="javascript">';
  1446.  
  1447.             $info .= "top.set_score(".$oItem->get_score().");\n";
  1448.  
  1449.             $info .= "top.set_max(".$oItem->get_max().");\n";
  1450.  
  1451.             $info .= "top.set_min(".$oItem->get_min().");\n";
  1452.  
  1453.             $info .= "top.set_lesson_status('".$oItem->get_status()."');";
  1454.  
  1455.             $info .= "top.set_session_time('".$oItem->get_scorm_time('js')."');";
  1456.  
  1457.             $info .= "top.set_suspend_data('".$oItem->get_suspend_data()."');";
  1458.  
  1459.             $info .= "top.set_saved_lesson_status('".$oItem->get_status()."');";
  1460.  
  1461.             $info .= "top.set_flag_synchronized();";
  1462.  
  1463.             $info .= '</script>';
  1464.  
  1465.             if($this->debug>2){error_log('New LP - in learnpath::get_js_info('.$item_id.') - returning: '.$info,0);}
  1466.  
  1467.             return $info;
  1468.  
  1469.         }else{
  1470.  
  1471.             //if item_id is empty, just update to default SCORM data
  1472.  
  1473.             $info .= '<script language="javascript">';
  1474.  
  1475.             $info .= "top.set_score(".learnpathItem::get_score().");\n";
  1476.  
  1477.             $info .= "top.set_max(".learnpathItem::get_max().");\n";
  1478.  
  1479.             $info .= "top.set_min(".learnpathItem::get_min().");\n";
  1480.  
  1481.             $info .= "top.set_lesson_status('".learnpathItem::get_status()."');";
  1482.  
  1483.             $info .= "top.set_session_time('".learnpathItem::get_scorm_time('js')."');";
  1484.  
  1485.             $info .= "top.set_suspend_data('".learnpathItem::get_suspend_data()."');";
  1486.  
  1487.             $info .= "top.set_saved_lesson_status('".learnpathItem::get_status()."');";
  1488.  
  1489.             $info .= "top.set_flag_synchronized();";
  1490.  
  1491.             $info .= '</script>';
  1492.  
  1493.             if($this->debug>2){error_log('New LP - in learnpath::get_js_info('.$item_id.') - returning: '.$info,0);}
  1494.  
  1495.             return $info;
  1496.  
  1497.         }
  1498.  
  1499.     }
  1500.     /**
  1501.      * Gets the js library from the database
  1502.      * @return    string    The name of the javascript library to be used
  1503.      */
  1504.     function get_js_lib(){
  1505.         $lib '';
  1506.         if(!empty($this->js_lib)){
  1507.             $lib $this->js_lib;
  1508.         }
  1509.         return $lib;
  1510.     }
  1511.     /**
  1512.  
  1513.      * Gets the learnpath database ID
  1514.  
  1515.      * @return    integer    Learnpath ID in the lp table
  1516.  
  1517.      */
  1518.  
  1519.     function get_id()
  1520.  
  1521.     {
  1522.  
  1523.         if($this->debug>0){error_log('New LP - In learnpath::get_id()',0);}
  1524.  
  1525.         if(!empty($this->lp_id))
  1526.  
  1527.         {
  1528.  
  1529.             return $this->lp_id;
  1530.  
  1531.         }else{
  1532.  
  1533.             return 0;
  1534.  
  1535.         }
  1536.  
  1537.     }
  1538.  
  1539.     /**
  1540.  
  1541.      * Gets the last element URL.
  1542.  
  1543.      * @return string URL to load into the viewer
  1544.  
  1545.      */
  1546.  
  1547.     function get_last()
  1548.  
  1549.     {
  1550.  
  1551.         if($this->debug>0){error_log('New LP - In learnpath::get_last()',0);}
  1552.  
  1553.         $this->index = count($this->ordered_items)-1;
  1554.  
  1555.         return $this->ordered_items[$this->index];
  1556.  
  1557.     }
  1558.  
  1559.     /**
  1560.  
  1561.      * Gets the navigation bar for the learnpath display screen
  1562.  
  1563.      * @return    string    The HTML string to use as a navigation bar
  1564.  
  1565.      */
  1566.  
  1567.     function get_navigation_bar()
  1568.  
  1569.     {
  1570.  
  1571.         if($this->debug>0){error_log('New LP - In learnpath::get_navigation_bar()',0);}
  1572.  
  1573.         //TODO find a good value for the following variables
  1574.  
  1575.         $file '';
  1576.  
  1577.         $openDir '';
  1578.  
  1579.         $edoceo '';
  1580.  
  1581.         $time 0;
  1582.  
  1583.         $navbar '';
  1584.  
  1585.         $RequestUri '';
  1586.  
  1587.         $mycurrentitemid $this->get_current_item_id();
  1588.  
  1589.         if($this->mode == 'fullscreen'){
  1590.  
  1591.             $navbar '<table cellpadding="0" cellspacing="0" align="left">'."\n".
  1592.  
  1593.                   '  <tr> '."\n" .
  1594.  
  1595.                   '    <td>'."\n" .
  1596.  
  1597.                   '      <div class="buttons">'."\n" .
  1598.  
  1599.                    '        <a href="lp_controller.php?action=stats" onclick="window.parent.API.save_asset();return true;" target="content_name_blank" title="stats" id="stats_link"><img border="0" src="../img/lp_stats.gif" title="'.get_lang('ScormMystatus').'"></a>&nbsp;'."\n" .
  1600.  
  1601.                   '        <a href="" onclick="dokeos_xajax_handler.switch_item('.$mycurrentitemid.',\'previous\');return false;" title="previous"><img border="0" src="../img/lp_leftarrow.gif" title="'.get_lang('ScormPrevious').'"></a>&nbsp;'."\n" .
  1602.  
  1603.                   '        <a href="" onclick="dokeos_xajax_handler.switch_item('.$mycurrentitemid.',\'next\');return false;" title="next"  ><img border="0" src="../img/lp_rightarrow.gif" title="'.get_lang('ScormNext').'"></a>&nbsp;'."\n" .
  1604.  
  1605.                   '        <a href="lp_controller.php?action=mode&mode=embedded" target="_top" title="embedded mode"><img border="0" src="../img/view_choose.gif" title="'.get_lang('ScormExitFullScreen').'"></a>'."\n" .
  1606.  
  1607.                   //'        <a href="lp_controller.php?action=list" target="_top" title="learnpaths list"><img border="0" src="../img/exit.png" title="Exit"></a>'."\n" .
  1608.  
  1609.                   '      </div>'."\n" .
  1610.  
  1611.                   '    </td>'."\n" .
  1612.  
  1613.                   '  </tr>'."\n" .
  1614.  
  1615.                   '</table>'."\n" ;
  1616.  
  1617.             
  1618.  
  1619.         }else{
  1620.  
  1621.             $navbar '<table cellpadding="0" cellspacing="0" align="left">'."\n".
  1622.  
  1623.                   '  <tr> '."\n" .
  1624.  
  1625.                   '    <td>'."\n" .
  1626.  
  1627.                   '      <div class="buttons">'."\n" .
  1628.  
  1629.                   '        <a href="lp_controller.php?action=stats" onclick="window.parent.API.save_asset();return true;" target="content_name" title="stats" id="stats_link"><img border="0" src="../img/lp_stats.gif" title="'.get_lang('ScormMystatus').'"></a>&nbsp;'."\n" .
  1630.  
  1631.                   '        <a href="" onclick="dokeos_xajax_handler.switch_item('.$mycurrentitemid.',\'previous\');return false;" title="previous"><img border="0" src="../img/lp_leftarrow.gif" title="'.get_lang('ScormPrevious').'"></a>&nbsp;'."\n" .
  1632.  
  1633.                   '        <a href="" onclick="dokeos_xajax_handler.switch_item('.$mycurrentitemid.',\'next\');return false;" title="next"  ><img border="0" src="../img/lp_rightarrow.gif" title="'.get_lang('ScormNext').'"></a>&nbsp;'."\n" .
  1634.  
  1635.                   '        <a href="lp_controller.php?action=mode&mode=fullscreen" target="_top" title="fullscreen"><img border="0" src="../img/view_fullscreen.gif" width="18" height="18" title="'.get_lang('ScormFullScreen').'"></a>'."\n" .
  1636.  
  1637.                   '      </div>'."\n" .
  1638.  
  1639.                   '    </td>'."\n" .
  1640.  
  1641.                   '  </tr>'."\n" .
  1642.  
  1643.                   '</table>'."\n" ;
  1644.  
  1645.         }
  1646.  
  1647.         return $navbar;
  1648.  
  1649.     }
  1650.  
  1651.     /**
  1652.  
  1653.      * Gets the next resource in queue (url).
  1654.  
  1655.      * @return    string    URL to load into the viewer
  1656.  
  1657.      */
  1658.  
  1659.     function get_next_index()
  1660.  
  1661.     {
  1662.         if($this->debug>0){error_log('New LP - In learnpath::get_next_index()',0);}
  1663.         //TODO
  1664.         $index $this->index;
  1665.         $index ++;
  1666.         if($this->debug>2){error_log('New LP - Now looking at ordered_items['.($index).'] - type is '.$this->items[$this->ordered_items[$index]]->type,0);}
  1667.         while(!empty($this->ordered_items[$index]AND ($this->items[$this->ordered_items[$index]]->get_type(== 'dir' || $this->items[$this->ordered_items[$index]]->get_type(== 'dokeos_chapter'AND $index $this->max_ordered_items)
  1668.         {
  1669.             $index ++;
  1670.             if($index == $this->max_ordered_items)
  1671.             {
  1672.                 return $this->index;
  1673.             }
  1674.         }
  1675.         if(empty($this->ordered_items[$index])){
  1676.             return $this->index;
  1677.         }
  1678.         if($this->debug>2){error_log('New LP - index is now '.$index,0);}
  1679.         return $index;
  1680.     }
  1681.     /**
  1682.      * Gets item_id for the next element
  1683.      * @return    integer    Next item (DB) ID
  1684.      */
  1685.     function get_next_item_id()
  1686.     {
  1687.         if($this->debug>0){error_log('New LP - In learnpath::get_next_item_id()',0);}
  1688.         $new_index $this->get_next_index();
  1689.         if(!empty($new_index))
  1690.         {
  1691.             if(isset($this->ordered_items[$new_index]))
  1692.             {
  1693.                 if($this->debug>2){error_log('New LP - In learnpath::get_next_index() - Returning '.$this->ordered_items[$new_index],0);}
  1694.                 return $this->ordered_items[$new_index];
  1695.             }
  1696.         }
  1697.         if($this->debug>2){error_log('New LP - In learnpath::get_next_index() - Problem - Returning 0',0);}
  1698.         return 0;
  1699.     }
  1700.     /**
  1701.      * Returns the package type ('scorm','aicc','scorm2004','dokeos','ppt'...)
  1702.      * 
  1703.      * Generally, the package provided is in the form of a zip file, so the function
  1704.      * has been written to test a zip file. If not a zip, the function will return the
  1705.      * default return value: ''
  1706.      * @param    string    the path to the file
  1707.      * @param    string     the original name of the file
  1708.      * @return    string    'scorm','aicc','scorm2004','dokeos' or '' if the package cannot be recognized
  1709.      */
  1710.     function get_package_type($file_path,$file_name){
  1711.          
  1712.          //get name of the zip file without the extension
  1713.         $file_info pathinfo($file_name);
  1714.         $filename $file_info['basename'];//name including extension
  1715.         $extension $file_info['extension'];//extension only
  1716.         
  1717.         if(!empty($_POST['ppt2lp']&& !in_array($extension,array('dll','exe')))
  1718.         {
  1719.             return 'oogie';
  1720.         }
  1721.         if(!empty($_POST['woogie']&& !in_array($extension,array('dll','exe')))
  1722.         {
  1723.             return 'woogie';
  1724.         }
  1725.         
  1726.         
  1727.         $file_base_name str_replace('.'.$extension,'',$filename)//filename without its extension
  1728.     
  1729.         $zipFile new pclZip($file_path);
  1730.         // Check the zip content (real size and file extension)
  1731.         $zipContentArray $zipFile->listContent();
  1732.         $package_type='';
  1733.         $at_root false;
  1734.         $manifest '';
  1735.  
  1736.         //the following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?)
  1737.         foreach($zipContentArray as $thisContent)
  1738.         {
  1739.             if preg_match('~.(php.*|phtml)$~i'$thisContent['filename']) )
  1740.             {
  1741.                 //New behaviour: Don't do anything. These files will be removed in scorm::import_package
  1742.             }
  1743.             elseif(stristr($thisContent['filename'],'imsmanifest.xml')!==FALSE)
  1744.             {
  1745.                 $manifest $thisContent['filename']//just the relative directory inside scorm/
  1746.                 $package_type 'scorm';
  1747.                 break;//exit the foreach loop
  1748.             }
  1749.             elseif(preg_match('/aicc\//i',$thisContent['filename'])!=false)
  1750.             {//if found an aicc directory... (!= false means it cannot be false (error) or 0 (no match))
  1751.                 $package_type='aicc';
  1752.                 //break;//don't exit the loop, because if we find an imsmanifest afterwards, we want it, not the AICC
  1753.             }
  1754.             else
  1755.             {
  1756.                 $package_type '';
  1757.             }
  1758.         }
  1759.         return $package_type;
  1760.     }
  1761.     /**
  1762.  
  1763.      * Gets the previous resource in queue (url). Also initialises time values for this viewing
  1764.  
  1765.      * @return string URL to load into the viewer
  1766.  
  1767.      */
  1768.  
  1769.     function get_previous_index()
  1770.  
  1771.     {
  1772.  
  1773.         if($this->debug>0){error_log('New LP - In learnpath::get_previous_index()',0);}
  1774.  
  1775.         $index $this->index;
  1776.  
  1777.         if(isset($this->ordered_items[$index-1])){
  1778.  
  1779.             $index --;
  1780.  
  1781.             while(isset($this->ordered_items[$index]AND ($this->items[$this->ordered_items[$index]]->get_type(== 'dir' || $this->items[$this->ordered_items[$index]]->get_type(== 'dokeos_chapter'))
  1782.  
  1783.             {
  1784.  
  1785.                 $index --;
  1786.  
  1787.                 if($index 0){
  1788.  
  1789.                     return $this->index;
  1790.  
  1791.                 }
  1792.  
  1793.             }
  1794.  
  1795.         }else{
  1796.  
  1797.             if($this->debug>2){error_log('New LP - get_previous_index() - there was no previous index available, reusing '.$index,0);}
  1798.  
  1799.             //no previous item
  1800.  
  1801.         }
  1802.  
  1803.         return $index;
  1804.  
  1805.     }
  1806.  
  1807.     /**
  1808.      * Gets item_id for the next element
  1809.      * @return    integer    Previous item (DB) ID
  1810.      */
  1811.     function get_previous_item_id()
  1812.     {
  1813.         $new_index $this->get_previous_index();
  1814.         return $this->ordered_items[$new_index];
  1815.     }
  1816.  
  1817.     /**
  1818.      * Gets the progress value from the progress_db attribute
  1819.      * @return    integer    Current progress value
  1820.      */
  1821.     function get_progress()
  1822.     {
  1823.         if($this->debug>0){error_log('New LP - In learnpath::get_progress()',0);}
  1824.         if(!empty($this->progress_db))
  1825.         {
  1826.             return $this->progress_db;
  1827.         }
  1828.         return 0;
  1829.     }
  1830.     /**
  1831.      * Gets the progress value from the progress field in the database (allows use as abstract method)
  1832.      * @param    integer    Learnpath ID
  1833.      * @param    integer    User ID
  1834.      * @param    string    Mode of display ('%','abs' or 'both')
  1835.      * @param    string    Course database name (optional, defaults to '')
  1836.      * @param    boolean    Whether to return null if no record was found (true), or 0 (false) (optional, defaults to false)
  1837.      * @return    integer    Current progress value as found in the database
  1838.      */
  1839.     function get_db_progress($lp_id,$user_id,$mode='%'$course_db=''$sincere=false)
  1840.     {
  1841.         //if($this->debug>0){error_log('New LP - In learnpath::get_db_progress()',0);}
  1842.         $table Database::get_course_table('lp_view'$course_db);
  1843.         $sql "SELECT * FROM $table WHERE lp_id = $lp_id AND user_id = $user_id";
  1844.         $res api_sql_query($sql,__FILE__,__LINE__);
  1845.         $view_id 0;
  1846.         if(Database::num_rows($res)>0)
  1847.         {
  1848.             $row Database::fetch_array($res);
  1849.             $progress $row['progress'];
  1850.             $view_id $row['id'];
  1851.         }
  1852.         else
  1853.         {
  1854.             if($sincere)
  1855.             {
  1856.                 return null;
  1857.             }
  1858.         }
  1859.         if(!$progress)
  1860.         {
  1861.             $progress '0';
  1862.         }
  1863.         if($mode == '%')
  1864.         {
  1865.                 return $progress.'%';
  1866.         }
  1867.         else
  1868.         {
  1869.             //get the number of items completed and the number of items total
  1870.             $tbl Database::get_course_table('lp_item'$course_db);
  1871.             $sql "SELECT count(*) FROM $tbl WHERE lp_id = ".$lp_id.
  1872.                     AND item_type NOT IN('dokeos_chapter','chapter','dir')";
  1873.             $res api_sql_query($sql__FILE____LINE__);
  1874.             $row Database::fetch_array($res);
  1875.             $total $row[0];
  1876.             $tbl_item_view Database::get_course_table('lp_item_view'$course_db);
  1877.             $tbl_item Database::get_course_table('lp_item'$course_db);
  1878.             
  1879.             //$sql = "SELECT count(distinct(lp_item_id)) FROM $tbl WHERE lp_view_id = ".$view_id." AND status IN ('passed','completed','succeeded')";
  1880.             //trying as also counting browsed and failed items
  1881.             $sql "SELECT count(distinct(lp_item_id)) 
  1882.                     FROM $tbl_item_view as item_view
  1883.                     INNER JOIN $tbl_item as item
  1884.                         ON item.id = item_view.lp_item_id
  1885.                         AND item_type NOT IN('dokeos_chapter','chapter','dir')
  1886.                     WHERE lp_view_id = ".$view_id.
  1887.                     AND status IN ('passed','completed','succeeded','browsed','failed')";
  1888.             $res api_sql_query($sql__FILE____LINE__);
  1889.             $row Database::fetch_array($res);
  1890.             $completed $row[0];
  1891.             if($mode == 'abs')
  1892.             {
  1893.                 return $completed.'/'.$total;
  1894.             }
  1895.             elseif($mode == 'both')
  1896.             {
  1897.                 if($progress<($completed/($total?$total:1)))
  1898.                 {
  1899.                     $progress number_format(($completed/($total?$total:1))*100,0);
  1900.                 }
  1901.                 return $progress.'% ('.$completed.'/'.$total.')';
  1902.             }
  1903.         }
  1904.         return $progress;
  1905.     }
  1906.     /**
  1907.      * Gets a progress bar for the learnpath by counting the number of items in it and the number of items
  1908.      * completed so far.
  1909.      * @param    string    Mode in which we want the values
  1910.      * @param    integer    Progress value to display (optional but mandatory if used in abstract context)
  1911.      * @param    string    Text to display near the progress value (optional but mandatory in abstract context)
  1912.      * @return    string    HTML string containing the progress bar
  1913.      */
  1914.     function get_progress_bar($mode='',$percentage=-1,$text_add='')
  1915.     {
  1916.         global $lp_theme_css;
  1917.         
  1918.         // Setting up the CSS path of the current style if exists   
  1919.         if (!empty($lp_theme_css))
  1920.         {    
  1921.             $css_path=api_get_path(WEB_CODE_PATH).'css/'.$lp_theme_css.'/images/';
  1922.         }
  1923.         else 
  1924.         {
  1925.             $css_path='../img/';    
  1926.         }  
  1927.             
  1928.         //if($this->debug>0){error_log('New LP - In learnpath::get_progress_bar()',0);}
  1929.         if(is_object($this&& ($percentage=='-1' OR $text_add==''))
  1930.         {
  1931.             list ($percentage$text_add$this->get_progress_bar_text($mode);
  1932.         }
  1933.         $text $percentage.$text_add;
  1934.         $size str_replace('%','',$percentage);
  1935.         $output '' 
  1936.         //.htmlentities(get_lang('ScormCompstatus'),ENT_QUOTES,'ISO-8859-1')."<br />"
  1937.         .'<table border="0" cellpadding="0" cellspacing="0"><tr><td>'
  1938.         .'<img id="progress_img_limit_left" src="'.$css_path.'bar_1.gif" width="1" height="12">'
  1939.         .'<img id="progress_img_full" src="'.$css_path.'bar_1u.gif" width="'.$size.'px" height="12" id="full_portion">'
  1940.         .'<img id="progress_img_limit_middle" src="'.$css_path.'bar_1m.gif" width="1" height="12">';
  1941.         
  1942.         if($percentage <= 98)
  1943.         {
  1944.             $output .= '<img id="progress_img_empty" src="'.$css_path.'bar_1r.gif" width="'.(100-$size).'px" height="12" id="empty_portion">';
  1945.         }
  1946.         else
  1947.         {
  1948.             $output .= '<img id="progress_img_empty" src="'.$css_path.'bar_1r.gif" width="0" height="12" id="empty_portion">';
  1949.         }
  1950.         
  1951.         $output .= '<img id="progress_bar_img_limit_right" src="'.$css_path.'bar_1.gif" width="1" height="12"></td></tr></table>'
  1952.         .'<div class="progresstext" id="progress_text">'.$text.'</div>';
  1953.         return $output;
  1954.     }
  1955.     /**
  1956.      * Gets the progress bar info to display inside the progress bar. Also used by scorm_api.php
  1957.      * @param    string    Mode of display (can be '%' or 'abs').abs means we display a number of completed elements per total elements
  1958.      *  //@param    integer    Additional steps to fake as completed
  1959.      * @return    list    Percentage or number and symbol (% or /xx)
  1960.      */
  1961.     function get_progress_bar_text($mode='',$add=0)
  1962.     {
  1963.         if($this->debug>0){error_log('New LP - In learnpath::get_progress_bar_text()',0);}
  1964.         if(empty($mode)){$mode $this->progress_bar_mode;}
  1965.         $total_items $this->get_total_items_count_without_chapters();
  1966.         if($this->debug>2){error_log('New LP - Total items available in this learnpath: '.$total_items,0);}
  1967.         $i $this->get_complete_items_count();
  1968.         if($this->debug>2){error_log('New LP - Items completed so far: '.$i,0);}
  1969.         if($add != 0){
  1970.             $i += $add;
  1971.             if($this->debug>2){error_log('New LP - Items completed so far (+modifier): '.$i,0);}
  1972.         }
  1973.         $text '';
  1974.         if($i>$total_items){
  1975.             $i $total_items;
  1976.         }
  1977.         if($mode == '%'){
  1978.             if($total_items>0){
  1979.                 $percentage ((float)$i/(float)$total_items)*100;
  1980.             }
  1981.             else
  1982.             {
  1983.                 $percentage 0;
  1984.             }
  1985.             $percentage number_format($percentage,0);
  1986.             $text '%';
  1987.         }elseif($mode == 'abs'){
  1988.             $percentage $i;
  1989.             $text =  '/'.$total_items;
  1990.         }
  1991.         return array($percentage,$text);
  1992.     }
  1993.     /**
  1994.      * Gets the progress bar mode
  1995.      * @return    string    The progress bar mode attribute
  1996.      */
  1997.      function get_progress_bar_mode()
  1998.      {
  1999.         if($this->debug>0){error_log('New LP - In learnpath::get_progress_bar_mode()',0);}
  2000.          if(!empty($this->progress_bar_mode))
  2001.         {
  2002.             return $this->progress_bar_mode;
  2003.         }else{
  2004.             return '%';
  2005.         }
  2006.      }
  2007.     /**
  2008.      * Gets the learnpath proximity (remote or local)
  2009.      * @return    string    Learnpath proximity
  2010.      */
  2011.     function get_proximity()
  2012.     {
  2013.         if($this->debug>0){error_log('New LP - In learnpath::get_proximity()',0);}
  2014.         if(!empty($this->proximity)){return $this->proximity;}else{return '';}
  2015.     }
  2016.     
  2017.      /**
  2018.      * Gets the learnpath theme (remote or local)
  2019.      * @return    string    Learnpath theme
  2020.      */
  2021.     function get_theme()
  2022.     {
  2023.         if($this->debug>0){error_log('New LP - In learnpath::get_theme()',0);}
  2024.         if(!empty($this->theme)){return $this->theme;}else{return '';}
  2025.     }
  2026.     
  2027.     /**
  2028.      * Generate a new prerequisites string for a given item. If this item was a sco and
  2029.      * its prerequisites were strings (instead of IDs), then transform those strings into
  2030.      * IDs, knowing that SCORM IDs are kept in the "ref" field of the lp_item table.
  2031.      * Prefix all item IDs that end-up in the prerequisites string by "ITEM_" to use the
  2032.      * same rule as the scorm_export() method
  2033.      * @param    integer        Item ID
  2034.      * @return    string        Prerequisites string ready for the export as SCORM
  2035.      */
  2036.     function get_scorm_prereq_string($item_id)
  2037.     {
  2038.         if($this->debug>0){error_log('New LP - In learnpath::get_scorm_prereq_string()',0);}
  2039.         if(!is_object($this->items[$item_id])){return false;}
  2040.         $oItem $this->items[$item_id];
  2041.         $prereq $oItem->get_prereq_string();
  2042.         if(empty($prereq))
  2043.         {
  2044.             return '';
  2045.         }
  2046.         if(preg_match('/^\d+$/',$prereq&& is_object($this->items[$prereq]))
  2047.         {    //if the prerequisite is a simple integer ID and this ID exists as an item ID,
  2048.             //then simply return it (with the ITEM_ prefix) 
  2049.             return 'ITEM_'.$prereq;
  2050.         }
  2051.         else
  2052.         {
  2053.             if(isset($this->refs_list[$prereq]))
  2054.             {
  2055.                 //it's a simple string item from which the ID can be found in the refs list
  2056.                 //so we can transform it directly to an ID for export
  2057.                 return 'ITEM_'.$this->refs_list[$prereq];
  2058.             }
  2059.             else
  2060.             {
  2061.                 //last case, if it's a complex form, then find all the IDs (SCORM strings)
  2062.                 //and replace them, one by one, by the internal IDs (dokeos db)
  2063.                 //TODO modify the '*' replacement to replace the multiplier in front of it
  2064.                 //by a space as well
  2065.                 $find    array('&','|','~','=','<>','{','}','*','(',')');
  2066.                 $replace array(' ',' ',' ',' ',' ',' ',' ',' ',' ',' ');
  2067.                 $prereq_mod str_replace($find,$replace,$prereq);
  2068.                 $ids split(' ',$prereq_mod);
  2069.                 foreach($ids as $id)
  2070.                 {
  2071.                     $id trim($id);
  2072.                     if(isset($this->refs_list[$id]))
  2073.                     {
  2074.                         $prereq preg_replace('/[^a-zA-Z_0-9]('.$id.')[^a-zA-Z_0-9]/','ITEM_'.$this->refs_list[$id],$prereq);
  2075.                     }
  2076.                 }
  2077.                 error_log('New LP - In learnpath::get_scorm_prereq_string(): returning modified string: '.$prereq,0);
  2078.                 return $prereq;
  2079.             }
  2080.         }
  2081.     }
  2082.     /**
  2083.      * Returns the XML DOM document's node
  2084.      * @param    resource    Reference to a list of objects to search for the given ITEM_*
  2085.      * @param    string        The identifier to look for
  2086.      * @return    mixed        The reference to the element found with that identifier. False if not found
  2087.      */
  2088.      function get_scorm_xml_node(&$children,$id)
  2089.      {
  2090.         for($i=0;$i<$children->length;$i++){
  2091.             $item_temp $children->item($i);
  2092.             if ($item_temp -> nodeName == 'item')
  2093.             {
  2094.                 if($item_temp->getAttribute('identifier'== $id)
  2095.                 {
  2096.                     return $item_temp;
  2097.                 }
  2098.             }
  2099.             $subchildren $item_temp->childNodes;
  2100.             if($subchildren->length>0)
  2101.             {
  2102.                 $val $this->get_scorm_xml_node($subchildren,$id);
  2103.                 if(is_object($val))
  2104.                 {
  2105.                     return $val;
  2106.                 }
  2107.             }
  2108.         }
  2109.         return false;
  2110.     }
  2111.     
  2112.     /**
  2113.      * Returns a usable array of stats related to the current learnpath and user
  2114.      * @return array    Well-formatted array containing status for the current learnpath
  2115.      */
  2116.     function get_stats()
  2117.     {
  2118.         if($this->debug>0){error_log('New LP - In learnpath::get_stats()',0);}
  2119.         //TODO
  2120.     }
  2121.     /**
  2122.      * Static method. Can be re-implemented by children. Gives an array of statistics for
  2123.      * the given course (for all learnpaths and all users)
  2124.      * @param    string    Course code
  2125.      * @return array    Well-formatted array containing status for the course's learnpaths
  2126.      */
  2127.     function get_stats_course($course)
  2128.     {
  2129.         //if($this->debug>0){error_log('New LP - In learnpath::get_stats_course()',0);}
  2130.         //TODO
  2131.     }
  2132.     /**
  2133.      * Static method. Can be re-implemented by children. Gives an array of statistics for
  2134.      * the given course and learnpath (for all users)
  2135.      * @param    string    Course code
  2136.      * @param    integer    Learnpath ID
  2137.      * @return array    Well-formatted array containing status for the specified learnpath
  2138.      */
  2139.     function get_stats_lp($course,$lp)
  2140.     {
  2141.         //if($this->debug>0){error_log('New LP - In learnpath::get_stats_lp()',0);}
  2142.         //TODO
  2143.     }
  2144.     /**
  2145.      * Static method. Can be re-implemented by children. Gives an array of statistics for
  2146.      * the given course, learnpath and user.
  2147.      * @param    string    Course code
  2148.      * @param    integer    Learnpath ID
  2149.      * @param    integer    User ID
  2150.      * @return array    Well-formatted array containing status for the specified learnpath and user
  2151.      */
  2152.     function get_stats_lp_user($course,$lp,$user)
  2153.     {
  2154.         //if($this->debug>0){error_log('New LP - In learnpath::get_stats_lp_user()',0);}
  2155.         //TODO
  2156.     }
  2157.     /**
  2158.      * Static method. Can be re-implemented by children. Gives an array of statistics for
  2159.      * the given course and learnpath (for all users)
  2160.      * @param    string    Course code
  2161.      * @param    integer    User ID
  2162.      * @return array    Well-formatted array containing status for the user's learnpaths
  2163.      */
  2164.     function get_stats_user($course,$user)
  2165.     {
  2166.         //if($this->debug>0){error_log('New LP - In learnpath::get_stats_user()',0);}
  2167.         //TODO
  2168.     }
  2169.     /**
  2170.      * Gets the status list for all LP's items
  2171.         * @return    array    Array of [index] => [item ID => current status]
  2172.      */
  2173.     function get_items_status_list(){
  2174.         if($this->debug>0){error_log('New LP - In learnpath::get_items_status_list()',0);}
  2175.         $list array();
  2176.         foreach($this->ordered_items as $item_id)
  2177.         {
  2178.             $list[]array($item_id => $this->items[$item_id]->get_status());
  2179.         }
  2180.         return $list;
  2181.     }
  2182.     /**
  2183.      * Return the number of interactions for the given learnpath Item View ID.
  2184.      * This method can be used as static.
  2185.      * @param    integer    Item View ID
  2186.      * @return    integer    Number of interactions
  2187.      */
  2188.     function get_interactions_count_from_db($lp_iv_id=0){
  2189.         if(empty($lp_iv_id)){return -1;}
  2190.         $table Database::get_course_table('lp_iv_interaction');
  2191.         $sql "SELECT count(*) FROM $table WHERE lp_iv_id = $lp_iv_id";
  2192.         $res api_sql_query($sql,__FILE__,__LINE__);
  2193.         $row Database::fetch_array($res);
  2194.         $num $row[0];
  2195.         return $num;
  2196.     }
  2197.     /**
  2198.      * Return the interactions as an array for the given lp_iv_id.
  2199.      * This method can be used as static.
  2200.      * @param    integer    Learnpath Item View ID
  2201.      * @return    array 
  2202.      * @todo     Translate labels
  2203.      */
  2204.     function get_iv_interactions_array($lp_iv_id=0){
  2205.         $list array();
  2206.         $table Database::get_course_table('lp_iv_interaction');
  2207.         $sql "SELECT * FROM $table WHERE lp_iv_id = $lp_iv_id ORDER BY order_id ASC";
  2208.         $res api_sql_query($sql,__FILE__,__LINE__);
  2209.         $num Database::num_rows($res);
  2210.         if($num>0){
  2211.             $list[array(
  2212.                 "order_id"=>htmlentities(get_lang('Order')),
  2213.                 "id"=>htmlentities(get_lang('InteractionID')),
  2214.                 "type"=>htmlentities(get_lang('Type')),
  2215.                 "time"=>htmlentities(get_lang('TimeFinished')),
  2216.                 "correct_responses"=>htmlentities(get_lang('CorrectAnswers')),
  2217.                 "student_response"=>htmlentities(get_lang('StudentResponse')),
  2218.                 "result"=>htmlentities(get_lang('Result')),
  2219.                 "latency"=>htmlentities(get_lang('LatencyTimeSpent')));
  2220.             while ($row Database::fetch_array($res)){
  2221.                 $list[array(
  2222.                     "order_id"=>($row['order_id']+1),
  2223.                     "id"=>urldecode($row['interaction_id']),//urldecode because they often have %2F or stuff like that
  2224.                     "type"=>$row['interaction_type'],
  2225.                     "time"=>$row['completion_time'],
  2226.                     //"correct_responses"=>$row['correct_responses'],
  2227.                     //hide correct responses from students
  2228.                     "correct_responses"=>'',
  2229.                     "student_response"=>$row['student_response'],
  2230.                     "result"=>$row['result'],
  2231.                     "latency"=>$row['latency']);
  2232.             }
  2233.         }
  2234.         return $list;    
  2235.     }
  2236.     /**
  2237.      * Return the number of objectives for the given learnpath Item View ID.
  2238.      * This method can be used as static.
  2239.      * @param    integer    Item View ID
  2240.      * @return    integer    Number of objectives
  2241.      */
  2242.     function get_objectives_count_from_db($lp_iv_id=0){
  2243.         if(empty($lp_iv_id)){return -1;}
  2244.         $table Database::get_course_table('lp_iv_objective');
  2245.         $sql "SELECT count(*) FROM $table WHERE lp_iv_id = $lp_iv_id";
  2246.         $res api_sql_query($sql,__FILE__,__LINE__);
  2247.         $row Database::fetch_array($res);
  2248.         $num $row[0];
  2249.         return $num;
  2250.     }
  2251.     /**
  2252.      * Return the objectives as an array for the given lp_iv_id.
  2253.      * This method can be used as static.
  2254.      * @param    integer    Learnpath Item View ID
  2255.      * @return    array 
  2256.      * @todo     Translate labels
  2257.      */
  2258.     function get_iv_objectives_array($lp_iv_id=0){
  2259.         $list array();
  2260.         $table Database::get_course_table('lp_iv_objective');
  2261.         $sql "SELECT * FROM $table WHERE lp_iv_id = $lp_iv_id ORDER BY order_id ASC";
  2262.         $res api_sql_query($sql,__FILE__,__LINE__);
  2263.         $num Database::num_rows($res);
  2264.         if($num>0){
  2265.             $list[array(
  2266.                 "order_id"=>htmlentities(get_lang('Order')),
  2267.                 "objective_id"=>htmlentities(get_lang('ObjectiveID')),
  2268.                 "score_raw"=>htmlentities(get_lang('ObjectiveRawScore')),
  2269.                 "score_max"=>htmlentities(get_lang('ObjectiveMaxScore')),
  2270.                 "score_min"=>htmlentities(get_lang('ObjectiveMinScore')),
  2271.                 "status"=>htmlentities(get_lang('ObjectiveStatus')));
  2272.             while ($row Database::fetch_array($res)){
  2273.                 $list[array(
  2274.                     "order_id"=>($row['order_id']+1),
  2275.                     "objective_id"=>urldecode($row['objective_id']),//urldecode because they often have %2F or stuff like that
  2276.                     "score_raw"=>$row['score_raw'],
  2277.                     "score_max"=>$row['score_max'],
  2278.                     "score_min"=>$row['score_min'],
  2279.                     "status"=>$row['status']);
  2280.             }
  2281.         }
  2282.         return $list;    
  2283.     }
  2284.  
  2285.     /**
  2286.      * Generate and return the table of contents for this learnpath. The (flat) table returned can be
  2287.      * used by get_html_toc() to be ready to display
  2288.      * @return    array    TOC as a table with 4 elements per row: title, link, status and level
  2289.      */
  2290.     function get_toc()
  2291.     {
  2292.         if($this->debug>0){error_log('New LP - In learnpath::get_toc()',0);}
  2293.         $toc array();
  2294.         //echo "<pre>".print_r($this->items,true)."</pre>";
  2295.         foreach($this->ordered_items as $item_id)
  2296.         {
  2297.             if($this->debug>2){error_log('New LP - learnpath::get_toc(): getting info for item '.$item_id,0);}
  2298.             //TODO change this link generation and use new function instead
  2299.             $toc[array(
  2300.                 'id'=>$item_id,
  2301.                 'title'=>$this->items[$item_id]->get_title(),
  2302.                 //'link'=>get_addedresource_link_in_learnpath('document',$item_id,1),
  2303.                 'status'=>$this->items[$item_id]->get_status(),
  2304.                 'level'=>$this->items[$item_id]->get_level(),
  2305.                 'type' =>$this->items[$item_id]->get_type(),
  2306.                 'description'=>$this->items[$item_id]->get_description(),
  2307.                 );
  2308.         }
  2309.         if($this->debug>2){error_log('New LP - In learnpath::get_toc() - TOC array: '.print_r($toc,true),0);}
  2310.         return $toc;
  2311.     }
  2312.     /**
  2313.      * Gets the learning path type
  2314.      * @param    boolean        Return the name? If false, return the ID. Default is false.
  2315.      * @return    mixed        Type ID or name, depending on the parameter
  2316.      */
  2317.     function get_type($get_name false)
  2318.     {
  2319.         $res false;
  2320.         if($this->debug>0){error_log('New LP - In learnpath::get_type()',0);}
  2321.         if(!empty($this->type))
  2322.         {
  2323.             if($get_name)
  2324.             {
  2325.                 //get it from the lp_type table in main db
  2326.             }else{
  2327.                 $res $this->type;
  2328.             }
  2329.         }
  2330.         if($this->debug>2){error_log('New LP - In learnpath::get_type() - Returning '.($res==false?'false':$res),0);}
  2331.         return $res;
  2332.     }
  2333.     /**
  2334.      * Gets the learning path type as static method
  2335.      * @param    boolean        Return the name? If false, return the ID. Default is false.
  2336.      * @return    mixed        Type ID or name, depending on the parameter
  2337.      */
  2338.     function get_type_static($lp_id=0)
  2339.     {
  2340.         $tbl_lp Database::get_course_table('lp');
  2341.         $sql "SELECT lp_type FROM $tbl_lp WHERE id = '".$lp_id."'";
  2342.         $res api_sql_query($sql__FILE____LINE__)
  2343.         if($res===false)return null;}
  2344.         if(Database::num_rows($res)<=0){return null;}
  2345.         $row Database::fetch_array($res);
  2346.         return $row['lp_type'];
  2347.     }
  2348.  
  2349.     /**
  2350.      * Gets a flat list of item IDs ordered for display (level by level ordered by order_display)
  2351.      * This method can be used as abstract and is recursive
  2352.      * @param    integer    Learnpath ID
  2353.      * @param    integer    Parent ID of the items to look for
  2354.      * @return    mixed    Ordered list of item IDs or false on error
  2355.      */
  2356.     function get_flat_ordered_items_list($lp,$parent=0){
  2357.         //if($this->debug>0){error_log('New LP - In learnpath::get_flat_ordered_items_list('.$lp.','.$parent.')',0);}
  2358.         $list array();
  2359.         if(empty($lp)){return false;}
  2360.         $tbl_lp_item Database::get_course_table('lp_item');
  2361.         $sql "SELECT * FROM $tbl_lp_item WHERE lp_id = $lp AND parent_item_id = $parent ORDER BY display_order";
  2362.         $res api_sql_query($sql,__FILE__,__LINE__);
  2363.         while($row Database::fetch_array($res)){
  2364.             $sublist learnpath::get_flat_ordered_items_list($lp,$row['id']);
  2365.             $list[$row['id'];
  2366.             foreach($sublist as $item){
  2367.                 $list[$item;
  2368.             }
  2369.         }
  2370.         return $list;
  2371.     }
  2372.     /**
  2373.      * Uses the table generated by get_toc() and returns an HTML-formatted string ready to display
  2374.      * @return    string    HTML TOC ready to display
  2375.      */
  2376.     /*function get_html_toc()
  2377.     {
  2378.         if($this->debug>0){error_log('New LP - In learnpath::get_html_toc()',0);}
  2379.         $list = $this->get_toc();
  2380.         //echo $this->current;
  2381.         //$parent = $this->items[$this->current]->get_parent();
  2382.         //if(empty($parent)){$parent = $this->ordered_items[$this->items[$this->current]->get_previous_index()];}
  2383.         $html = '<div class="inner_lp_toc">'."\n" ;
  2384.         //        " onchange=\"javascript:document.getElementById('toc_$parent').focus();\">\n";
  2385.         require_once('resourcelinker.inc.php');
  2386.         
  2387.         //temp variables
  2388.         $mycurrentitemid = $this->get_current_item_id();
  2389.         
  2390.         foreach($list as $item)
  2391.         {
  2392.             if($this->debug>2){error_log('New LP - learnpath::get_html_toc(): using item '.$item['id'],0);}
  2393.             //TODO complete this
  2394.             $icon_name = array('not attempted' => '../img/notattempted.gif',
  2395.                                 'incomplete'   => '../img/incomplete.gif',
  2396.                                 'failed'       => '../img/failed.gif',
  2397.                                 'completed'    => '../img/completed.gif',
  2398.                                 'passed'       => '../img/passed.gif',
  2399.                                 'succeeded'    => '../img/succeeded.gif',
  2400.                                 'browsed'      => '../img/completed.gif');
  2401.             
  2402.             $style = 'scorm_item';
  2403.             if($item['id'] == $this->current){
  2404.                 $style = 'scorm_item_highlight';
  2405.             }
  2406.             //the anchor will let us center the TOC on the currently viewed item &^D
  2407.             $html .= '<a name="atoc_'.$item['id'].'" /><div class="'.$style.'" style="padding-left: '.($item['level']/2).'em; padding-right:'.($item['level']/2).'em" id="toc_'.$item['id'].'" >' .
  2408.                     '<img id="toc_img_'.$item['id'].'" class="scorm_status_img" src="'.$icon_name[$item['status']].'" alt="'.substr($item['status'],0,1).'" />';
  2409.             
  2410.             //$title = htmlspecialchars($item['title'],ENT_QUOTES,$this->encoding);
  2411.             $title = $item['title'];
  2412.             if(empty($title)){
  2413.                 $title = rl_get_resource_name(api_get_course_id(),$this->get_id(),$item['id']);
  2414.                 $title = htmlspecialchars($title,ENT_QUOTES,$this->encoding);
  2415.             }
  2416.             if(empty($title))$title = '-';
  2417.             
  2418.             if($item['type']!='dokeos_chapter' and $item['type']!='dir'){
  2419.                     //$html .= "<a href='lp_controller.php?".api_get_cidReq()."&action=content&lp_id=".$this->get_id()."&item_id=".$item['id']."' target='lp_content_frame_name'>".$title."</a>" ;
  2420.                     $url = $this->get_link('http',$item['id']);
  2421.                     //$html .= '<a href="'.$url.'" target="content_name" onclick="top.load_item('.$item['id'].',\''.$url.'\');">'.$title.'</a>' ;
  2422.                     //$html .= '<a href="" onclick="top.load_item('.$item['id'].',\''.$url.'\');return false;">'.$title.'</a>' ;
  2423.                     $html .= '<a href="" onclick="dokeos_xajax_handler.switch_item(' .
  2424.                             $mycurrentitemid.',' .
  2425.                             $item['id'].');' .
  2426.                             'return false;" >'.$title.'</a>' ;
  2427.             }else{
  2428.                     $html .= $title;
  2429.             }
  2430.             $html .= "</div>\n";
  2431.         }
  2432.         $html .= "</div>\n";
  2433.         return $html;
  2434.     }*/
  2435.     
  2436.     
  2437.     /**
  2438.      * Uses the table generated by get_toc() and returns an HTML-formatted string ready to display
  2439.      * @return    string    HTML TOC ready to display
  2440.      */
  2441.     function get_html_toc()
  2442.     {
  2443.         if($this->debug>0){error_log('New LP - In learnpath::get_html_toc()',0);}
  2444.         $list $this->get_toc();
  2445.         $mych api_get_setting('platform_charset')
  2446.         
  2447.         //echo $this->current;
  2448.         //$parent = $this->items[$this->current]->get_parent();
  2449.         //if(empty($parent)){$parent = $this->ordered_items[$this->items[$this->current]->get_previous_index()];}
  2450.         $html.= '<div class="inner_lp_toc">'."\n" ;
  2451.         $html.= '<div class="scorm_title">&nbsp;&nbsp;&nbsp;&nbsp;'.mb_convert_encoding($this->get_name(),$this->encoding,$mych).'</div>';
  2452.         
  2453.         // build, display
  2454.         if(api_is_allowed_to_edit())
  2455.         {
  2456.             $html.="<p>&nbsp;&nbsp;&nbsp;&nbsp;<a  target='_parent' href='lp_controller.php?".api_get_cidreq()."&action=build&lp_id=".$this->lp_id."' style= target='_parent'>".mb_convert_encoding(get_lang("Build"),$this->encoding,$mych)."</a>&nbsp;&#124;&nbsp;<a href='lp_controller.php?".api_get_cidreq()."&action=admin_view&lp_id=".$this->lp_id."' target='_parent'>".mb_convert_encoding(get_lang("BasicOverview"),$this->encoding,$mych)."</a>&nbsp;&#124;&nbsp;".mb_convert_encoding(get_lang("Display"),$this->encoding,$mych)."</p>";
  2457.             unset($mych);
  2458.         }
  2459.         //        " onchange=\"javascript:document.getElementById('toc_$parent').focus();\">\n";
  2460.         require_once('resourcelinker.inc.php');
  2461.         
  2462.         //temp variables
  2463.         $mycurrentitemid $this->get_current_item_id();
  2464.         $color_counter=0;
  2465.         $i=0;
  2466.         foreach($list as $item)
  2467.         {
  2468.             if($this->debug>2){error_log('New LP - learnpath::get_html_toc(): using item '.$item['id'],0);}
  2469.             //TODO complete this
  2470.             $icon_name array('not attempted' => '../img/notattempted.gif',
  2471.                                 'incomplete'   => '../img/incomplete.gif',
  2472.                                 'failed'       => '../img/failed.gif',
  2473.                                 'completed'    => '../img/completed.gif',
  2474.                                 'passed'       => '../img/passed.gif',
  2475.                                 'succeeded'    => '../img/succeeded.gif',
  2476.                                 'browsed'      => '../img/completed.gif');
  2477.             
  2478.             $style 'scorm_item';            
  2479.             $scorm_color_background='scorm_item';
  2480.             $style_item ='scorm_item';
  2481.             $current=false;
  2482.             
  2483.             if($item['id'== $this->current)
  2484.             {
  2485.                 $style 'scorm_item_highlight';
  2486.                 $scorm_color_background ='scorm_item_highlight';
  2487.             }    
  2488.             else 
  2489.             
  2490.                 if ($color_counter%2==0)
  2491.                 {
  2492.                     $scorm_color_background='scorm_item_1';             
  2493.                 }
  2494.                 else
  2495.                 {
  2496.                     $scorm_color_background='scorm_item_2'
  2497.                 }
  2498.             
  2499.             if ($scorm_color_background!='')
  2500.             {
  2501.                 $html .= '<div id="toc_'.$item['id'].'" class="'.$scorm_color_background.'">';
  2502.             }
  2503.             
  2504.             //the anchor will let us center the TOC on the currently viewed item &^D
  2505.             if($item['type']!='dokeos_module' AND $item['type']!='dokeos_chapter')
  2506.             {               
  2507.                 $html .= '<a name="atoc_'.$item['id'].'" />';                                
  2508.                 $html .= '<div class="'.$style_item.'" style="padding-left: '.($item['level']*1.5).'em; padding-right:'.($item['level']/2).'em"             title="'.$item['description'].'" >';
  2509.             }            
  2510.             else
  2511.             {  
  2512.                 $html .= '<div class="'.$style_item.'" style="padding-left: '.($item['level']*2).'em; padding-right:'.($item['level']*1.5).'em"             title="'.$item['description'].'" >';
  2513.                }
  2514.                 
  2515.             $title=$item['title'];        
  2516.                 
  2517.             if(empty($title))
  2518.             {
  2519.                 $title rl_get_resource_name(api_get_course_id(),$this->get_id(),$item['id']);                
  2520.             }
  2521.             
  2522.             $title html_entity_decode($title,ENT_QUOTES,$this->encoding);    
  2523.         
  2524.             if($item['type']!='dokeos_chapter' and $item['type']!='dir' AND $item['type']!='dokeos_module')
  2525.             {
  2526.                 //$html .= "<a href='lp_controller.php?".api_get_cidreq()."&action=content&lp_id=".$this->get_id()."&item_id=".$item['id']."' target='lp_content_frame_name'>".$title."</a>" ;
  2527.                 $url $this->get_link('http',$item['id']);
  2528.                 //$html .= '<a href="'.$url.'" target="content_name" onclick="top.load_item('.$item['id'].',\''.$url.'\');">'.$title.'</a>' ;
  2529.                 //$html .= '<a href="" onclick="top.load_item('.$item['id'].',\''.$url.'\');return false;">'.$title.'</a>' ;
  2530.                 
  2531.                 //<img align="absbottom" width="13" height="13" src="../img/lp_document.png">&nbsp;
  2532.                 $html .= '<a href="" onclick="dokeos_xajax_handler.switch_item(' .
  2533.                         $mycurrentitemid.',' .
  2534.                         $item['id'].');' .
  2535.                         'return false;" >'.stripslashes($title).'</a>' ;
  2536.             }
  2537.             elseif($item['type']=='dokeos_module' || $item['type']=='dokeos_chapter')
  2538.             {
  2539.                 $html .= "<img align='absbottom' width='13' height='13' src='../img/lp_dokeos_module.png'>&nbsp;".stripslashes($title);
  2540.             }            
  2541.             elseif($item['type']=='dir')
  2542.             {
  2543.                 $html .= stripslashes($title);
  2544.             }           
  2545.             
  2546.             $html .= "<img id='toc_img_".$item['id']."' src='".$icon_name[$item['status']]."' alt='".substr($item['status'],0,1)."' />";         
  2547.             $html .= "</div>";
  2548.             
  2549.             if ($scorm_color_background!='')
  2550.             {
  2551.                 $html .= '</div>';
  2552.             }
  2553.             
  2554.             
  2555.             
  2556.             
  2557.         $color_counter++;
  2558.         }
  2559.         $html .= "</div>\n";
  2560.         return $html;
  2561.     }
  2562.     /**
  2563.      * Gets the learnpath maker name - generally the editor's name
  2564.      * @return    string    Learnpath maker name
  2565.      */
  2566.     function get_maker()
  2567.     {
  2568.         if($this->debug>0){error_log('New LP - In learnpath::get_maker()',0);}
  2569.         if(!empty($this->maker)){return $this->maker;}else{return '';}
  2570.     }    
  2571.     /**
  2572.      * Gets the user-friendly message stored in $this->message
  2573.      * @return    string    Message
  2574.      */
  2575.     function get_message(){
  2576.  
  2577.         if($this->debug>0){error_log('New LP - In learnpath::get_message()',0);}
  2578.         return $this->message;
  2579.     }
  2580.     /**
  2581.      * Gets the learnpath name/title
  2582.      * @return    string    Learnpath name/title
  2583.      */
  2584.     function get_name()
  2585.     {
  2586.         if($this->debug>0){error_log('New LP - In learnpath::get_name()',0);}
  2587.         if(!empty($this->name)){return $this->name;}else{return 'N/A';}
  2588.     }
  2589.     /**
  2590.      * Gets a link to the resource from the present location, depending on item ID.
  2591.      * @param    string    Type of link expected
  2592.      * @param    integer    Learnpath item ID
  2593.      * @return    string    Link to the lp_item resource
  2594.      */
  2595.     function get_link($type='http',$item_id=null)
  2596.     {
  2597.         if($this->debug>0){error_log('New LP - In learnpath::get_link('.$type.','.$item_id.')',0);}
  2598.         if(empty($item_id))
  2599.         {
  2600.             if($this->debug>2){error_log('New LP - In learnpath::get_link() - no item id given in learnpath::get_link(), using current: '.$this->get_current_item_id(),0);}
  2601.             $item_id $this->get_current_item_id();
  2602.         }
  2603.  
  2604.         if(empty($item_id)){
  2605.             if($this->debug>2){error_log('New LP - In learnpath::get_link() - no current item id found in learnpath object',0);}
  2606.             //still empty, this means there was no item_id given and we are not in an object context or
  2607.             //the object property is empty, return empty link
  2608.             $item_id $this->first();
  2609.             return '';
  2610.         }
  2611.  
  2612.         $file '';
  2613.         $lp_table Database::get_course_table(TABLE_LP_MAIN);
  2614.         $lp_item_table Database::get_course_table(TABLE_LP_ITEM);
  2615.         $sel "SELECT l.lp_type as ltype, l.path as lpath, li.item_type as litype, li.path as lipath, li.parameters as liparams " .
  2616.                 "FROM $lp_table l, $lp_item_table li WHERE li.id = $item_id AND li.lp_id = l.id";
  2617.         if($this->debug>2){error_log('New LP - In learnpath::get_link() - selecting item '.$sel,0);}
  2618.         $res api_sql_query($sel__FILE____LINE__);
  2619.         if(Database::num_rows($res)>0)
  2620.         {
  2621.             $row Database::fetch_array($res);
  2622.             //var_dump($row);
  2623.             $lp_type $row['ltype'];
  2624.             $lp_path $row['lpath'];
  2625.             $lp_item_type $row['litype'];
  2626.             $lp_item_path $row['lipath'];
  2627.             $lp_item_params $row['liparams'];
  2628.             if(empty($lp_item_params))
  2629.             {
  2630.                 list($lp_item_path,$lp_item_paramsexplode('?',$lp_item_path);
  2631.             }
  2632.             //$lp_item_params = '?'.$lp_item_params;
  2633.             
  2634.             //add ? if none - left commented to give freedom to scorm implementation
  2635.             //if(substr($lp_item_params,0,1)!='?'){
  2636.             //    $lp_item_params = '?'.$lp_item_params;
  2637.             //}
  2638.             $sys_course_path api_get_path(SYS_COURSE_PATH).api_get_course_path();
  2639.             if($type == 'http'){
  2640.                 $course_path api_get_path(WEB_COURSE_PATH).api_get_course_path()//web path
  2641.             }else{
  2642.                 $course_path $sys_course_path//system path
  2643.             }
  2644.             //now go through the specific cases to get the end of the path
  2645.             switch($lp_type){
  2646.                 case 1:
  2647.                     if($lp_item_type == 'dokeos_chapter'){
  2648.                         $file 'lp_content.php?type=dir';
  2649.                     }else{
  2650.                         require_once('resourcelinker.inc.php');
  2651.                         $file rl_get_resource_link_for_learnpath(api_get_course_id(),$this->get_id(),$item_id);
  2652.                         $tmp_array=explode("/",$file);
  2653.                         $document_name=$tmp_array[count($tmp_array)-1];
  2654.                         if(strpos($document_name,'_DELETED_')){
  2655.                             $file 'blank.php?error=document_deleted';
  2656.                         }
  2657.                     }
  2658.                     break;
  2659.                 case 2:
  2660.                        if($this->debug>2){error_log('New LP - In learnpath::get_link() '.__LINE__.' - Item type: '.$lp_item_type,0);}
  2661.                     if($lp_item_type!='dir'){
  2662.                         //Quite complex here:
  2663.                         //we want to make sure 'http://' (and similar) links can 
  2664.                         //be loaded as is (withouth the Dokeos path in front) but
  2665.                         //some contents use this form: resource.htm?resource=http://blablabla
  2666.                         //which means we have to find a protocol at the path's start, otherwise
  2667.                         //it should not be considered as an external URL
  2668.                         
  2669.                         //if($this->prerequisites_match($item_id)){
  2670.                             if(preg_match('#^[a-zA-Z]{2,5}://#',$lp_item_path)!=0){
  2671.                                 if($this->debug>2){error_log('New LP - In learnpath::get_link() '.__LINE__.' - Found match for protocol in '.$lp_item_path,0);}
  2672.                                 //distant url, return as is
  2673.                                 $file $lp_item_path;
  2674.                             }else{
  2675.                                 if($this->debug>2){error_log('New LP - In learnpath::get_link() '.__LINE__.' - No starting protocol in '.$lp_item_path,0);}
  2676.                                 //prevent getting untranslatable urls
  2677.                                 $lp_item_path preg_replace('/%2F/','/',$lp_item_path);
  2678.                                 $lp_item_path preg_replace('/%3A/',':',$lp_item_path);
  2679.                                 //prepare the path
  2680.                                 $file $course_path.'/scorm/'.$lp_path.'/'.$lp_item_path;
  2681.                                 //TODO fix this for urls with protocol header
  2682.                                 $file str_replace('//','/',$file);
  2683.                                 $file str_replace(':/','://',$file);
  2684.                                 if(substr($lp_path,-1)=='/')
  2685.                                 {
  2686.                                     $lp_path substr($lp_path,0,-1);
  2687.                                 }
  2688.  
  2689.                                 if(!is_file(realpath($sys_course_path.'/scorm/'.$lp_path.'/'.$lp_item_path)))
  2690.                                 {//if file not found
  2691.                                     $decoded html_entity_decode($lp_item_path);
  2692.                                     list($decodedexplode('?',$decoded);
  2693.                                     if(!is_file(realpath($sys_course_path.'/scorm/'.$lp_path.'/'.$decoded)))
  2694.                                     {
  2695.                                         require_once('resourcelinker.inc.php');
  2696.                                         $file rl_get_resource_link_for_learnpath(api_get_course_id(),$this->get_id(),$item_id);
  2697.                                         $tmp_array=explode("/",$file);
  2698.                                         $document_name=$tmp_array[count($tmp_array)-1];
  2699.                                         if(strpos($document_name,'_DELETED_')){
  2700.                                             $file 'blank.php?error=document_deleted';
  2701.                                         }
  2702.  
  2703.                                     }
  2704.                                     else
  2705.                                     {
  2706.                                         $file $course_path.'/scorm/'.$lp_path.'/'.$decoded;
  2707.                                     }
  2708.                                 }
  2709.                             }
  2710.                         //}else{
  2711.                             //prerequisites did not match
  2712.                             //$file = 'blank.php';
  2713.                         //}
  2714.                         //We want to use parameters if they were defined in the imsmanifest
  2715.                         if($file!='blank.php')
  2716.                         {
  2717.                             $file.= (strstr($file,'?')===false?'?':'').$lp_item_params;
  2718.                         }
  2719.                     }else{
  2720.                         $file 'lp_content.php?type=dir';
  2721.                     }
  2722.                     break;
  2723.                 case 3:
  2724.                     if($this->debug>2){error_log('New LP - In learnpath::get_link() '.__LINE__.' - Item type: '.$lp_item_type,0);}
  2725.                     //formatting AICC HACP append URL
  2726.                     $aicc_append '?aicc_sid='.urlencode(session_id()).'&aicc_url='.urlencode(api_get_path(WEB_CODE_PATH).'newscorm/aicc_hacp.php').'&';
  2727.                     if($lp_item_type!='dir'){
  2728.                         //Quite complex here:
  2729.                         //we want to make sure 'http://' (and similar) links can 
  2730.                         //be loaded as is (withouth the Dokeos path in front) but
  2731.                         //some contents use this form: resource.htm?resource=http://blablabla
  2732.                         //which means we have to find a protocol at the path's start, otherwise
  2733.                         //it should not be considered as an external URL
  2734.                         
  2735.                         if(preg_match('#^[a-zA-Z]{2,5}://#',$lp_item_path)!=0){
  2736.                             if($this->debug>2){error_log('New LP - In learnpath::get_link() '.__LINE__.' - Found match for protocol in '.$lp_item_path,0);}
  2737.                             //distant url, return as is
  2738.                             $file $lp_item_path;
  2739.                             /*
  2740.                             if(stristr($file,'<servername>')!==false){
  2741.                                 $file = str_replace('<servername>',$course_path.'/scorm/'.$lp_path.'/',$lp_item_path);
  2742.                             }
  2743.                             */
  2744.                             $file .= $aicc_append;
  2745.                         }else{
  2746.                             if($this->debug>2){error_log('New LP - In learnpath::get_link() '.__LINE__.' - No starting protocol in '.$lp_item_path,0);}
  2747.                             //prevent getting untranslatable urls
  2748.                             $lp_item_path preg_replace('/%2F/','/',$lp_item_path);
  2749.                             $lp_item_path preg_replace('/%3A/',':',$lp_item_path);
  2750.                             //prepare the path - lp_path might be unusable because it includes the "aicc" subdir name
  2751.                             $file $course_path.'/scorm/'.$lp_path.'/'.$lp_item_path;
  2752.                             //TODO fix this for urls with protocol header
  2753.                             $file str_replace('//','/',$file);
  2754.                             $file str_replace(':/','://',$file);
  2755.                             $file .= $aicc_append;
  2756.                         }
  2757.                     }else{
  2758.                         $file 'lp_content.php?type=dir';
  2759.                     }
  2760.                     break;
  2761.                 case 4:
  2762.                     break;
  2763.                 default:
  2764.                     break;    
  2765.             }
  2766.         }
  2767.         if($this->debug>2){error_log('New LP - In learnpath::get_link() - returning "'.$file.'" from get_link',0);}
  2768.         return $file;
  2769.     }
  2770.  
  2771.     /**
  2772.      * Gets the latest usable view or generate a new one
  2773.      * @param    integer    Optional attempt number. If none given, takes the highest from the lp_view table
  2774.      * @return    integer    DB lp_view id
  2775.      */
  2776.     function get_view($attempt_num=0)
  2777.     {
  2778.         if($this->debug>0){error_log('New LP - In learnpath::get_view()',0);}
  2779.         $search '';
  2780.         //use $attempt_num to enable multi-views management (disabled so far)
  2781.         if($attempt_num != AND intval(strval($attempt_num)) == $attempt_num)
  2782.         {
  2783.             $search 'AND view_count = '.$attempt_num;
  2784.         }
  2785.         //when missing $attempt_num, search for a unique lp_view record for this lp and user
  2786.         $lp_view_table Database::get_course_table('lp_view');
  2787.         $sql "SELECT id, view_count FROM $lp_view_table .
  2788.                 "WHERE lp_id = ".$this->get_id()." " .
  2789.                 "AND user_id = ".$this->get_user_id()." " .
  2790.                 $search .
  2791.                 " ORDER BY view_count DESC";
  2792.         $res api_sql_query($sql__FILE____LINE__);
  2793.         if(Database::num_rows($res)>0)
  2794.         {
  2795.             $row Database::fetch_array($res);
  2796.             $this->lp_view_id = $row['id'];
  2797.         }else{
  2798.             //no database record, create one
  2799.             $sql "INSERT INTO $lp_view_table(lp_id,user_id,view_count).
  2800.                     "VALUES (".$this->get_id().",".$this->get_user_id().",1)";
  2801.             $res api_sql_query($sql__FILE____LINE__);
  2802.             $id Database::get_last_insert_id();
  2803.             $this->lp_view_id = $id;
  2804.         }
  2805.         return $this->lp_view_id;
  2806.     }
  2807.  
  2808.     /**
  2809.      * Gets the current view id
  2810.      * @return    integer    View ID (from lp_view)
  2811.      */
  2812.     function get_view_id()
  2813.     {
  2814.         if($this->debug>0){error_log('New LP - In learnpath::get_view_id()',0);}
  2815.            if(!empty($this->lp_view_id))
  2816.         {
  2817.             return $this->lp_view_id;
  2818.         }else{
  2819.             return 0;
  2820.         }
  2821.     }
  2822.  
  2823.     /**
  2824.      * Gets the update queue
  2825.      * @return    array    Array containing IDs of items to be updated by JavaScript
  2826.      */
  2827.     function get_update_queue()
  2828.     {
  2829.         if($this->debug>0){error_log('New LP - In learnpath::get_update_queue()',0);}
  2830.         return $this->update_queue;
  2831.     }
  2832.     /**
  2833.      * Gets the user ID
  2834.      * @return    integer    User ID
  2835.      */
  2836.     function get_user_id()
  2837.     {
  2838.         if($this->debug>0){error_log('New LP - In learnpath::get_user_id()',0);}
  2839.         if(!empty($this->user_id))
  2840.         {
  2841.             return $this->user_id;
  2842.         }else{
  2843.             return false;
  2844.         }
  2845.     }
  2846.     /**
  2847.      * Logs a message into a file
  2848.      * @param    string     Message to log
  2849.      * @return    boolean    True on success, false on error or if msg empty
  2850.      */
  2851.     function log($msg)
  2852.     {
  2853.         if($this->debug>0){error_log('New LP - In learnpath::log()',0);}
  2854.         //TODO
  2855.         $this->error .= $msg."\n";
  2856.         return true;
  2857.     }
  2858.     /**
  2859.      * Moves an item up and down at its level
  2860.      * @param    integer    Item to move up and down
  2861.      * @param    string    Direction 'up' or 'down'
  2862.      * @return    integer    New display order, or false on error
  2863.      */
  2864.     function move_item($id$direction){
  2865.         if($this->debug>0){error_log('New LP - In learnpath::move_item('.$id.','.$direction.')',0);}
  2866.         if(empty($idor empty($direction)){return false;}
  2867.         $tbl_lp_item Database::get_course_table('lp_item');
  2868.         $sql_sel "
  2869.             SELECT *
  2870.             FROM " $tbl_lp_item "
  2871.             WHERE id = " $id;
  2872.         $res_sel api_sql_query($sql_sel,__FILE__,__LINE__);
  2873.         //check if elem exists
  2874.         if(Database::num_rows($res_sel)<1){return false;}
  2875.         //gather data
  2876.         $row Database::fetch_array($res_sel);
  2877.         $previous $row['previous_item_id'];
  2878.         $next $row['next_item_id'];
  2879.         $display $row['display_order'];
  2880.         $parent $row['parent_item_id'];
  2881.         $lp $row['lp_id'];
  2882.         //update the item (switch with previous/next one)
  2883.         switch($direction)
  2884.         {
  2885.             case 'up':
  2886.                 if($this->debug>2){error_log('Movement up detected',0);}
  2887.                 if($display <= 1){/*do nothing*/}
  2888.                 else{
  2889.                      $sql_sel2 "SELECT * 
  2890.                         FROM $tbl_lp_item 
  2891.                         WHERE id = $previous";
  2892.  
  2893.                     if($this->debug>2){error_log('Selecting previous: '.$sql_sel2,0);}
  2894.                     $res_sel2 api_sql_query($sql_sel2,__FILE__,__LINE__);
  2895.                     if(Database::num_rows($res_sel2)<1){$previous_previous 0;}
  2896.                     //gather data
  2897.                     $row2 Database::fetch_array($res_sel2);
  2898.                     $previous_previous $row2['previous_item_id'];
  2899.                      //update previous_previous item (switch "next" with current)
  2900.                      if($previous_previous != 0)
  2901.                      {
  2902.                         $sql_upd2 "UPDATE $tbl_lp_item SET next_item_id = $id WHERE id = $previous_previous";
  2903.                         if($this->debug>2){error_log($sql_upd2,0);}
  2904.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);
  2905.                      }
  2906.                      //update previous item (switch with current)
  2907.                     if($previous != 0)
  2908.                     {
  2909.                         $sql_upd2 "UPDATE $tbl_lp_item SET next_item_id = $next, previous_item_id = $id, display_order = display_order +1 WHERE id = $previous";
  2910.                         if($this->debug>2){error_log($sql_upd2,0);}
  2911.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);
  2912.                     }
  2913.  
  2914.                     //update current item (switch with previous)
  2915.                     if($id != 0){
  2916.                         $sql_upd2 "UPDATE $tbl_lp_item SET next_item_id = $previous, previous_item_id = $previous_previous, display_order = display_order-1 WHERE id = $id";
  2917.                         if($this->debug>2){error_log($sql_upd2,0);}
  2918.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);
  2919.                     }
  2920.                     //update next item (new previous item)
  2921.                     if($next != 0){
  2922.                         $sql_upd2 "UPDATE $tbl_lp_item SET previous_item_id = $previous WHERE id = $next";
  2923.                         if($this->debug>2){error_log($sql_upd2,0);}
  2924.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);
  2925.                     }
  2926.                     $display $display-1;                    
  2927.                 }
  2928.                 break;
  2929.  
  2930.             case 'down':
  2931.                 if($this->debug>2){error_log('Movement down detected',0);}
  2932.                 if($next == 0){/*do nothing*/}
  2933.                 else{
  2934.                      $sql_sel2 "SELECT * FROM $tbl_lp_item WHERE id = $next";
  2935.                     if($this->debug>2){error_log('Selecting next: '.$sql_sel2,0);}
  2936.                     $res_sel2 api_sql_query($sql_sel2,__FILE__,__LINE__);
  2937.                     if(Database::num_rows($res_sel2)<1){$next_next 0;}
  2938.                     //gather data
  2939.                     $row2 Database::fetch_array($res_sel2);
  2940.                     $next_next $row2['next_item_id'];
  2941.                     //update previous item (switch with current)
  2942.                     if($previous != 0)
  2943.                     {
  2944.                         $sql_upd2 "UPDATE $tbl_lp_item SET next_item_id = $next WHERE id = $previous";
  2945.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);
  2946.                     }
  2947.                     //update current item (switch with previous)
  2948.                     if($id != 0)
  2949.                     {
  2950.                         $sql_upd2 "UPDATE $tbl_lp_item SET previous_item_id = $next, next_item_id = $next_next, display_order = display_order+1 WHERE id = $id";
  2951.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);
  2952.                     }
  2953.  
  2954.                     //update next item (new previous item)
  2955.                     if($next != 0)
  2956.                     {
  2957.                         $sql_upd2 "UPDATE $tbl_lp_item SET previous_item_id = $previous, next_item_id = $id, display_order = display_order-1 WHERE id = $next";
  2958.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);                    
  2959.                     }
  2960.  
  2961.                     //update next_next item (switch "previous" with current)
  2962.                     if($next_next != 0)
  2963.                     {
  2964.                         $sql_upd2 "UPDATE $tbl_lp_item SET previous_item_id = $id WHERE id = $next_next";
  2965.                         $res_upd2 api_sql_query($sql_upd2__FILE____LINE__);                    
  2966.                     }
  2967.                     $display $display+1;                    
  2968.                 }
  2969.  
  2970.                 break;
  2971.             default:
  2972.                 return false;
  2973.         }
  2974.         return $display;
  2975.     }
  2976.     /**
  2977.      * Move a learnpath up (display_order)
  2978.      * @param    integer    Learnpath ID
  2979.      */
  2980.     function move_up($lp_id)
  2981.     {
  2982.         $lp_table Database::get_course_table(TABLE_LP_MAIN);
  2983.         $sql "SELECT * FROM $lp_table ORDER BY display_order";
  2984.         $res api_sql_query($sql__FILE____LINE__);
  2985.         if($res === falsereturn false;
  2986.         $lps array();
  2987.         $lp_order array();
  2988.         $num Database::num_rows($res);
  2989.         //first check the order is correct, globally (might be wrong because
  2990.         //of versions < 1.8.4)
  2991.         if($num>0)
  2992.         {
  2993.             $i 1;
  2994.             while($row Database::fetch_array($res))
  2995.             {
  2996.                 if($row['display_order'!= $i)
  2997.                 {    //if we find a gap in the order, we need to fix it
  2998.                     $need_fix true;
  2999.                     $sql_u "UPDATE $lp_table SET display_order = $i WHERE id = ".$row['id'];
  3000.                     $res_u api_sql_query($sql_u__FILE____LINE__);
  3001.                 }
  3002.                 $row['display_order'$i;
  3003.                 $lps[$row['id']] $row;
  3004.                 $lp_order[$i$row['id'];
  3005.                 $i++;
  3006.             }
  3007.         }
  3008.         if($num>1//if there's only one element, no need to sort
  3009.         {
  3010.             $order $lps[$lp_id]['display_order'];
  3011.             if($order>1//if it's the first element, no need to move up
  3012.             {
  3013.                 $sql_u1 "UPDATE $lp_table SET display_order = $order WHERE id = ".$lp_order[$order-1];
  3014.                 $res_u1 api_sql_query($sql_u1__FILE____LINE__);
  3015.                 $sql_u2 "UPDATE $lp_table SET display_order = ".($order-1)." WHERE id = ".$lp_id;
  3016.                 $res_u2 api_sql_query($sql_u2__FILE____LINE__);                
  3017.             }
  3018.         }
  3019.     }
  3020.     /**
  3021.      * Move a learnpath down (display_order)
  3022.      * @param    integer    Learnpath ID
  3023.      */
  3024.     function move_down($lp_id)
  3025.     {
  3026.         $lp_table Database::get_course_table(TABLE_LP_MAIN);
  3027.         $sql "SELECT * FROM $lp_table ORDER BY display_order";
  3028.         $res api_sql_query($sql__FILE____LINE__);
  3029.         if($res === falsereturn false;
  3030.         $lps array();
  3031.         $lp_order array();
  3032.         $num Database::num_rows($res);
  3033.         $max 0;
  3034.         //first check the order is correct, globally (might be wrong because
  3035.         //of versions < 1.8.4)
  3036.         if($num>0)
  3037.         {
  3038.             $i 1;
  3039.             while($row Database::fetch_array($res))
  3040.             {
  3041.                 $max $i;
  3042.                 if($row['display_order'!= $i)
  3043.                 {    //if we find a gap in the order, we need to fix it
  3044.                     $need_fix true;
  3045.                     $sql_u "UPDATE $lp_table SET display_order = $i WHERE id = ".$row['id'];
  3046.                     $res_u api_sql_query($sql_u__FILE____LINE__);
  3047.                 }
  3048.                 $row['display_order'$i;
  3049.                 $lps[$row['id']] $row;
  3050.                 $lp_order[$i$row['id'];
  3051.                 $i++;
  3052.             }
  3053.         }
  3054.         if($num>1//if there's only one element, no need to sort
  3055.         {
  3056.             $order $lps[$lp_id]['display_order'];
  3057.             if($order<$max//if it's the first element, no need to move up
  3058.             {
  3059.                 $sql_u1 "UPDATE $lp_table SET display_order = $order WHERE id = ".$lp_order[$order+1];
  3060.                 $res_u1 api_sql_query($sql_u1__FILE____LINE__);
  3061.                 $sql_u2 "UPDATE $lp_table SET display_order = ".($order+1)." WHERE id = ".$lp_id;
  3062.                 $res_u2 api_sql_query($sql_u2__FILE____LINE__);                
  3063.             }
  3064.         }
  3065.     }
  3066.     /**
  3067.      * Updates learnpath attributes to point to the next element
  3068.      * The last part is similar to set_current_item but processing the other way around
  3069.      */
  3070.     function next()
  3071.     {
  3072.         if($this->debug>0){error_log('New LP - In learnpath::next()',0);}
  3073.         $this->last = $this->get_current_item_id();
  3074.         $this->items[$this->last]->save(false,$this->prerequisites_match($this->last));
  3075.         $this->autocomplete_parents($this->last);
  3076.         $new_index $this->get_next_index();
  3077.         if($this->debug>2){error_log('New LP - New index: '.$new_index,0);}
  3078.         $this->index = $new_index;
  3079.         if($this->debug>2){error_log('New LP - Now having orderedlist['.$new_index.'] = '$this->ordered_items[$new_index],0);}
  3080.         $this->current = $this->ordered_items[$new_index];
  3081.         if($this->debug>2){error_log('New LP - new item id is '.$this->current.'-'.$this->get_current_item_id(),0);}
  3082.     }
  3083.  
  3084.     /**
  3085.      * Open a resource = initialise all local variables relative to this resource. Depending on the child
  3086.      * class, this might be redefined to allow several behaviours depending on the document type.
  3087.      * @param integer Resource ID
  3088.      * @return boolean True on success, false otherwise
  3089.      */
  3090.  
  3091.     function open($id)
  3092.     {
  3093.         if($this->debug>0){error_log('New LP - In learnpath::open()',0);}
  3094.         //TODO
  3095.         //set the current resource attribute to this resource
  3096.         //switch on element type (redefine in child class?)
  3097.         //set status for this item to "opened"
  3098.         //start timer
  3099.         //initialise score
  3100.         $this->index = 0//or = the last item seen (see $this->last)
  3101.     }
  3102.  
  3103.     /**
  3104.      * Check that all prerequisites are fulfilled. Returns true and an empty string on succes, returns false
  3105.      * and the prerequisite string on error.
  3106.      * This function is based on the rules for aicc_script language as described in the SCORM 1.2 CAM documentation page 108.
  3107.      * @param    integer    Optional item ID. If none given, uses the current open item.
  3108.      * @return    boolean    True if prerequisites are matched, false otherwise
  3109.      * @return    string    Empty string if true returned, prerequisites string otherwise.
  3110.      */
  3111.     function prerequisites_match($item null)
  3112.     {
  3113.         if($this->debug>0){error_log('New LP - In learnpath::prerequisites_match()',0);}
  3114.         if(empty($item)){$item $this->current;}
  3115.         if(is_object($this->items[$item]))
  3116.         {
  3117.             $prereq_string $this->items[$item]->get_prereq_string();
  3118.             if(empty($prereq_string)){return true;}
  3119.             //clean spaces
  3120.             $prereq_string str_replace(' ','',$prereq_string);
  3121.             if($this->debug>0){error_log('Found prereq_string: '.$prereq_string,0);}
  3122.             //now send to the parse_prereq() function that will check this component's prerequisites
  3123.             $result $this->items[$item]->parse_prereq($prereq_string,$this->items,$this->refs_list,$this->get_user_id());
  3124.             
  3125.             if($result === false)
  3126.             {
  3127.                 $this->set_error_msg($this->items[$item]->prereq_alert);
  3128.             }
  3129.         }else{
  3130.             $result true;
  3131.             if($this->debug>1){error_log('New LP - $this->items['.$item.'] was not an object',0);}
  3132.         }
  3133.  
  3134.         if($this->debug>1){error_log('New LP - End of prerequisites_match(). Error message is now '.$this->error,0);}
  3135.         return $result;
  3136.     }
  3137.  
  3138.     /**
  3139.      * Updates learnpath attributes to point to the previous element
  3140.      * The last part is similar to set_current_item but processing the other way around
  3141.      */
  3142.  
  3143.     function previous()
  3144.     {
  3145.         if($this->debug>0){error_log('New LP - In learnpath::previous()',0);}
  3146.         $this->last = $this->get_current_item_id();
  3147.         $this->items[$this->last]->save(false,$this->prerequisites_match($this->last));
  3148.         $this->autocomplete_parents($this->last);
  3149.         $new_index $this->get_previous_index();
  3150.         $this->index = $new_index;
  3151.         $this->current = $this->ordered_items[$new_index];
  3152.     }    
  3153.  
  3154.     /**
  3155.      * Publishes a learnpath. This basically means show or hide the learnpath
  3156.      * to normal users.
  3157.      * Can be used as abstract
  3158.      * @param    integer    Learnpath ID
  3159.      * @param    string    New visibility
  3160.      */
  3161.  
  3162.     function toggle_visibility($lp_id,$set_visibility=1)
  3163.     {
  3164.         //if($this->debug>0){error_log('New LP - In learnpath::toggle_visibility()',0);}
  3165.         $action 'visible';
  3166.         if($set_visibility != 1)
  3167.         {
  3168.             $action 'invisible';
  3169.         }
  3170.         return api_item_property_update(api_get_course_info(),TOOL_LEARNPATH,$lp_id,$action,api_get_user_id());
  3171.     }
  3172.     /**
  3173.      * Publishes a learnpath. This basically means show or hide the learnpath
  3174.      * on the course homepage
  3175.      * Can be used as abstract
  3176.      * @param    integer    Learnpath ID
  3177.      * @param    string    New visibility
  3178.      */
  3179.  
  3180.     function toggle_publish($lp_id,$set_visibility='v')
  3181.     {
  3182.         //if($this->debug>0){error_log('New LP - In learnpath::toggle_publish()',0);}
  3183.         $tbl_lp Database::get_course_table('lp');
  3184.         $sql="SELECT * FROM $tbl_lp where id=$lp_id";
  3185.         $result=api_sql_query($sql,__FILE__,__LINE__);
  3186.         $row=Database::fetch_array($result);
  3187.         $name=domesticate($row['name']);
  3188.         if($set_visibility == 'i'
  3189.             $s=$name." ".get_lang('_no_published')
  3190.             $dialogBox=$s
  3191.             $v=0
  3192.         }
  3193.         if($set_visibility == 'v')
  3194.         
  3195.             $s=$name." ".get_lang('_published');    
  3196.             $dialogBox=$s
  3197.             $v=1
  3198.         }
  3199.  
  3200.         $tbl_tool Database::get_course_table(TABLE_TOOL_LIST);
  3201.         $link 'newscorm/lp_controller.php?action=view&lp_id='.$lp_id;
  3202.         $sql="SELECT * FROM $tbl_tool where name='$name' and image='scormbuilder.gif' and link LIKE '$link%'";
  3203.         $result=api_sql_query($sql,__FILE__,__LINE__);
  3204.         $num=Database::num_rows($result);
  3205.         $row2=Database::fetch_array($result);
  3206.         //if($this->debug>2){error_log('New LP - '.$sql.' - '.$num,0);}
  3207.         if(($set_visibility == 'i'&& ($num>0))
  3208.         {
  3209.             $sql ="DELETE FROM $tbl_tool WHERE (name='$name' and image='scormbuilder.gif' and link LIKE '$link%')";
  3210.         }
  3211.         elseif(($set_visibility == 'v'&& ($num==0))
  3212.         {
  3213.             $sql ="INSERT INTO $tbl_tool (name, link, image, visibility, admin, address, added_tool) VALUES ('$name','newscorm/lp_controller.php?action=view&lp_id=$lp_id','scormbuilder.gif','$v','0','pastillegris.gif',0)";
  3214.         }
  3215.         else
  3216.         {
  3217.             //parameter and database incompatible, do nothing
  3218.         }
  3219.         $result=api_sql_query($sql,__FILE__,__LINE__);
  3220.         //if($this->debug>2){error_log('New LP - Leaving learnpath::toggle_visibility: '.$sql,0);}
  3221.     }
  3222.     /**
  3223.      * Restart the whole learnpath. Return the URL of the first element.
  3224.      * Make sure the results are saved with anoter method. This method should probably be
  3225.      * redefined in children classes.
  3226.      * @return string URL to load in the viewer
  3227.      */
  3228.     function restart()
  3229.     {
  3230.         if($this->debug>0){error_log('New LP - In learnpath::restart()',0);}
  3231.         //TODO
  3232.         //call autosave method to save the current progress
  3233.         //$this->index = 0;
  3234.          $lp_view_table Database::get_course_table('lp_view');
  3235.            $sql "INSERT INTO $lp_view_table (lp_id, user_id, view_count) .
  3236.                    "VALUES (".$this->lp_id.",".$this->get_user_id().",".($this->attempt+1).")";
  3237.            if($this->debug>2){error_log('New LP - Inserting new lp_view for restart: '.$sql,0);}
  3238.           $res api_sql_query($sql__FILE____LINE__);         
  3239.         if($view_id Database::get_last_insert_id($res))
  3240.         {
  3241.              $this->lp_view_id = $view_id;
  3242.              $this->attempt = $this->attempt+1;
  3243.          }else{
  3244.              $this->error = 'Could not insert into item_view table...';
  3245.              return false;
  3246.          }
  3247.          $this->autocomplete_parents($this->current);
  3248.          foreach($this->items as $index=>$dummy){
  3249.              $this->items[$index]->restart();
  3250.              $this->items[$index]->set_lp_view($this->lp_view_id);
  3251.          }
  3252.          $this->first();
  3253.          return true;
  3254.     }
  3255.     /**
  3256.      * Saves the current item
  3257.      * @return    boolean 
  3258.      */
  3259.     function save_current(){
  3260.         if($this->debug>0){error_log('New LP - In learnpath::save_current()',0);}
  3261.         //TODO do a better check on the index pointing to the right item (it is supposed to be working
  3262.         // on $ordered_items[] but not sure it's always safe to use with $items[])
  3263.         if($this->debug>2){error_log('New LP - save_current() saving item '.$this->current,0);}
  3264.         if($this->debug>2){error_log(''.print_r($this->items,true),0);}
  3265.         if(is_object($this->items[$this->current])){
  3266.             //$res = $this->items[$this->current]->save(false);
  3267.             $res $this->items[$this->current]->save(false,$this->prerequisites_match($this->current));
  3268.             $this->autocomplete_parents($this->current);
  3269.             $status $this->items[$this->current]->get_status();
  3270.             $this->append_message('new_item_status: '.$status);
  3271.              $this->update_queue[$this->current$status;
  3272.             return $res;
  3273.         }
  3274.         return false;
  3275.     }
  3276.     /**
  3277.      * Saves the given item
  3278.      * @param    integer    Item ID. Optional (will take from $_REQUEST if null)
  3279.      * @param    boolean    Save from url params (true) or from current attributes (false). Optional. Defaults to true
  3280.      * @return    boolean 
  3281.      */
  3282.     function save_item($item_id=null,$from_outside=true){
  3283.         if($this->debug>0){error_log('New LP - In learnpath::save_item('.$item_id.','.$from_outside.')',0);}
  3284.         //TODO do a better check on the index pointing to the right item (it is supposed to be working
  3285.         // on $ordered_items[] but not sure it's always safe to use with $items[])
  3286.         if(empty($item_id)){
  3287.             $item_id $this->escape_string($_REQUEST['id']);
  3288.         }
  3289.         if(empty($item_id))
  3290.         {
  3291.             $item_id $this->get_current_item_id();
  3292.         }
  3293.         if($this->debug>2){error_log('New LP - save_current() saving item '.$item_id,0);}
  3294.         if(is_object($this->items[$item_id])){
  3295.             $res $this->items[$item_id]->save($from_outside,$this->prerequisites_match($item_id));
  3296.             //$res = $this->items[$item_id]->save($from_outside);
  3297.             $this->autocomplete_parents($item_id);
  3298.             $status $this->items[$item_id]->get_status();
  3299.             $this->append_message('new_item_status: '.$status);
  3300.             $this->update_queue[$item_id$status;
  3301.             return $res;
  3302.         }
  3303.         return false;
  3304.     }
  3305.     /**
  3306.      * Saves the last item seen's ID only in case
  3307.      */
  3308.     function save_last(){
  3309.  
  3310.         if($this->debug>0){error_log('New LP - In learnpath::save_last()',0);}
  3311.  
  3312.            $table Database::get_course_table('lp_view');
  3313.  
  3314.         if(isset($this->current)){
  3315.  
  3316.             if($this->debug>2){error_log('New LP - Saving current item ('.$this->current.') for later review',0);}
  3317.  
  3318.             $sql "UPDATE $table SET last_item = ".$this->get_current_item_id()." " .
  3319.  
  3320.                     "WHERE lp_id = ".$this->get_id()." AND user_id = ".$this->get_user_id();
  3321.  
  3322.             if($this->debug>2){error_log('New LP - Saving last item seen : '.$sql,0);}
  3323.  
  3324.             $res api_sql_query($sql,__FILE__,__LINE__);
  3325.  
  3326.         }
  3327.  
  3328.         //save progress
  3329.  
  3330.         list($progress,$text$this->get_progress_bar_text('%');
  3331.  
  3332.         if($progress>=AND $progress<=100){
  3333.  
  3334.             $progress= (int)$progress;
  3335.  
  3336.             $sql "UPDATE $table SET progress = $progress .
  3337.  
  3338.                     "WHERE lp_id = ".$this->get_id()." AND " .
  3339.  
  3340.                             "user_id = ".$this->get_user_id();
  3341.  
  3342.             $res api_sql_query($sql,__FILE____LINE__)//ignore errors as some tables might not have the progress field just yet
  3343.  
  3344.             $this->progress_db = $progress;
  3345.  
  3346.         }
  3347.  
  3348.     }
  3349.     /**
  3350.      * Sets the current item ID (checks if valid and authorized first)
  3351.      * @param    integer    New item ID. If not given or not authorized, defaults to current
  3352.      */
  3353.     function set_current_item($item_id=null)
  3354.     {
  3355.         if($this->debug>0){error_log('New LP - In learnpath::set_current_item('.$item_id.')',0);}
  3356.         if(empty($item_id)){
  3357.             if($this->debug>2){error_log('New LP - No new current item given, ignore...',0);}
  3358.             //do nothing
  3359.         }else{
  3360.                if($this->debug>2){error_log('New LP - New current item given is '.$item_id.'...',0);}
  3361.             $item_id $this->escape_string($item_id);
  3362.             //TODO check in database here
  3363.             $this->last = $this->current;
  3364.             $this->current = $item_id;
  3365.             //TODO update $this->index as well
  3366.             foreach($this->ordered_items as $index => $item)
  3367.             {
  3368.                 if($item == $this->current)
  3369.                 {
  3370.                     $this->index = $index;
  3371.                        break;
  3372.                 }
  3373.             }
  3374.             if($this->debug>2){error_log('New LP - set_current_item('.$item_id.') done. Index is now : '.$this->index,0);}
  3375.         }
  3376.     }
  3377.     /**
  3378.      * Sets the encoding
  3379.      * @param    string    New encoding
  3380.      */
  3381.     function set_encoding($enc='ISO-8859-1'){
  3382.         if($this->debug>0){error_log('New LP - In learnpath::set_encoding()',0);}
  3383.         $enc strtoupper($enc);
  3384.          $encodings array('UTF-8','ISO-8859-1','ISO-8859-15','SHIFT-JIS');
  3385.         if(in_array($enc,$encodings)){
  3386.              $lp $this->get_id();
  3387.              if($lp!=0){
  3388.                  $tbl_lp Database::get_course_table('lp');
  3389.                  $sql "UPDATE $tbl_lp SET default_encoding = '$enc' WHERE id = ".$lp;
  3390.                  $res api_sql_query($sql__FILE____LINE__);
  3391.                  return $res;
  3392.              }
  3393.         }
  3394.         return false;
  3395.     }
  3396.     /**
  3397.      * Sets the JS lib setting in the database directly.
  3398.      * This is the JavaScript library file this lp needs to load on startup
  3399.      * @param    string    Proximity setting
  3400.      */
  3401.      function set_jslib($lib=''){
  3402.         if($this->debug>0){error_log('New LP - In learnpath::set_jslib()',0);}
  3403.          $lp $this->get_id();
  3404.          if($lp!=0){
  3405.              $tbl_lp Database::get_course_table('lp');
  3406.              $sql "UPDATE $tbl_lp SET js_lib = '$lib' WHERE id = ".$lp;
  3407.              $res api_sql_query($sql__FILE____LINE__);
  3408.              return $res;
  3409.          }else{
  3410.              return false;
  3411.          }
  3412.      }
  3413.     /**
  3414.      * Sets the name of the LP maker (publisher) (and save)
  3415.      * @param    string    Optional string giving the new content_maker of this learnpath
  3416.      */
  3417.     function set_maker($name=''){
  3418.  
  3419.         if($this->debug>0){error_log('New LP - In learnpath::set_maker()',0);}
  3420.  
  3421.         if(empty($name))return false;
  3422.  
  3423.         
  3424.  
  3425.         $this->maker = $this->escape_string($name);
  3426.  
  3427.         $lp_table Database::get_course_table('lp');
  3428.  
  3429.         $lp_id $this->get_id();
  3430.  
  3431.         $sql "UPDATE $lp_table SET content_maker = '".$this->maker."' WHERE id = '$lp_id'";
  3432.  
  3433.         if($this->debug>2){error_log('New LP - lp updated with new content_maker : '.$this->maker,0);}
  3434.  
  3435.         //$res = Database::query($sql);
  3436.  
  3437.         $res api_sql_query($sql__FILE____LINE__);
  3438.  
  3439.         return true;
  3440.  
  3441.     }    
  3442.  
  3443.     /**
  3444.  
  3445.      * Sets the name of the current learnpath (and save)
  3446.  
  3447.      * @param    string    Optional string giving the new name of this learnpath
  3448.  
  3449.      */
  3450.  
  3451.     function set_name($name=''){
  3452.  
  3453.         if($this->debug>0){error_log('New LP - In learnpath::set_name()',0);}
  3454.  
  3455.         if(empty($name))return false;
  3456.  
  3457.         
  3458.  
  3459.         $this->name = $this->escape_string($name);
  3460.  
  3461.         $lp_table Database::get_course_table('lp');
  3462.  
  3463.         $lp_id $this->get_id();
  3464.  
  3465.         $sql "UPDATE $lp_table SET name = '".$this->name."' WHERE id = '$lp_id'";
  3466.  
  3467.         if($this->debug>2){error_log('New LP - lp updated with new name : '.$this->name,0);}
  3468.  
  3469.         //$res = Database::query($sql);
  3470.  
  3471.         $res api_sql_query($sql__FILE____LINE__);
  3472.         
  3473.         // if the lp is visible on the homepage, change his name there
  3474.         if(mysql_affected_rows())
  3475.         
  3476.             $table Database :: get_course_table(TABLE_TOOL_LIST);
  3477.             $sql 'UPDATE '.$table.' SET
  3478.                         name = "'.$this->name.'"
  3479.                     WHERE link = "newscorm/lp_controller.php?action=view&lp_id='.$lp_id.'"';
  3480.             api_sql_query($sql__FILE____LINE__);
  3481.         }
  3482.  
  3483.         return true;
  3484.  
  3485.     }
  3486.     
  3487.        /**
  3488.      * Sets the theme of the LP (local/remote) (and save)
  3489.      * @param    string    Optional string giving the new theme of this learnpath
  3490.      * @return bool returns true if theme name is not empty
  3491.      */
  3492.     function set_theme($name=''){
  3493.         if($this->debug>0){error_log('New LP - In learnpath::set_theme()',0);}
  3494.         if(empty($name))return false;
  3495.         
  3496.         $this->theme = $this->escape_string($name);
  3497.         $lp_table Database::get_course_table('lp');
  3498.         $lp_id $this->get_id();
  3499.         $sql "UPDATE $lp_table SET theme = '".$this->theme."' WHERE id = '$lp_id'";
  3500.         if($this->debug>2){error_log('New LP - lp updated with new theme : '.$this->theme,0);}
  3501.         //$res = Database::query($sql);
  3502.         $res api_sql_query($sql__FILE____LINE__);
  3503.         return true;
  3504.     }    
  3505.  
  3506.     /**
  3507.      * Sets the location/proximity of the LP (local/remote) (and save)
  3508.      * @param    string    Optional string giving the new location of this learnpath
  3509.      */
  3510.     function set_proximity($name=''){
  3511.         if($this->debug>0){error_log('New LP - In learnpath::set_proximity()',0);}
  3512.         if(empty($name))return false;
  3513.         
  3514.         $this->proximity = $this->escape_string($name);
  3515.         $lp_table Database::get_course_table('lp');
  3516.         $lp_id $this->get_id();
  3517.         $sql "UPDATE $lp_table SET content_local = '".$this->proximity."' WHERE id = '$lp_id'";
  3518.         if($this->debug>2){error_log('New LP - lp updated with new proximity : '.$this->proximity,0);}
  3519.         //$res = Database::query($sql);
  3520.         $res api_sql_query($sql__FILE____LINE__);
  3521.         return true;
  3522.     }   
  3523.     /**
  3524.      * Sets the previous item ID to a given ID. Generally, this should be set to the previous 'current' item
  3525.      * @param    integer    DB ID of the item
  3526.      */
  3527.     function set_previous_item($id)
  3528.     {
  3529.         if($this->debug>0){error_log('New LP - In learnpath::set_previous_item()',0);}
  3530.         $this->last = $id;
  3531.     }
  3532.     /**
  3533.      * Sets the object's error message
  3534.      * @param    string    Error message. If empty, reinits the error string
  3535.      * @return     void 
  3536.      */
  3537.     function set_error_msg($error='')
  3538.     {
  3539.         if($this->debug>0){error_log('New LP - In learnpath::set_error_msg()',0);}
  3540.         if(empty($error)){
  3541.             $this->error = '';
  3542.         }else{
  3543.             $this->error .= $error;
  3544.         }
  3545.     }
  3546.     /**
  3547.      * Launches the current item if not 'sco' (starts timer and make sure there is a record ready in the DB)
  3548.      * 
  3549.      */
  3550.     function start_current_item($allow_new_attempt=false){
  3551.         if($this->debug>0){error_log('New LP - In learnpath::start_current_item()',0);}
  3552.         if($this->current != AND
  3553.             is_object($this->items[$this->current]))
  3554.         {
  3555.             $type $this->get_type();
  3556.             $item_type $this->items[$this->current]->get_type();
  3557.             if(
  3558.                 ($type == && $item_type!='sco')
  3559.                 OR
  3560.                 ($type == && $item_type!='au')
  3561.                 OR
  3562.                 ($type == && $item_type!=TOOL_QUIZ && $item_type!=TOOL_HOTPOTATOES)
  3563.             )
  3564.             {
  3565.                 $this->items[$this->current]->open($allow_new_attempt);
  3566.                             
  3567.                 $this->autocomplete_parents($this->current);
  3568.                 $prereq_check $this->prerequisites_match($this->current);
  3569.                 $this->items[$this->current]->save(false,$prereq_check);
  3570.                 //$this->update_queue[$this->last] = $this->items[$this->last]->get_status();
  3571.             }else{
  3572.                 //if sco, then it is supposed to have been updated by some other call
  3573.             }
  3574.         }
  3575.         if($this->debug>0){error_log('New LP - End of learnpath::start_current_item()',0);}
  3576.         return true;
  3577.     }
  3578.  
  3579.     /**
  3580.  
  3581.      * Stops the processing and counters for the old item (as held in $this->last)
  3582.  
  3583.      * @param 
  3584.  
  3585.      */
  3586.  
  3587.     function stop_previous_item(){
  3588.  
  3589.         if($this->debug>0){error_log('New LP - In learnpath::stop_previous_item()',0);}
  3590.  
  3591.         if($this->last != AND $this->last!=$this->current AND is_object($this->items[$this->last]))
  3592.         {
  3593.             if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - '.$this->last.' is object',0);}
  3594.             switch($this->get_type()){
  3595.                 case '3':
  3596.                     if($this->items[$this->last]->get_type()!='au')
  3597.                     {
  3598.                         if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - '.$this->last.' in lp_type 3 is <> au',0);}
  3599.                         $this->items[$this->last]->close();
  3600.                         //$this->autocomplete_parents($this->last);
  3601.                           //$this->update_queue[$this->last] = $this->items[$this->last]->get_status();
  3602.                     }else{
  3603.                         if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - Item is an AU, saving is managed by AICC signals',0);}
  3604.                     }
  3605.                 case '2':
  3606.                     if($this->items[$this->last]->get_type()!='sco')
  3607.                     {
  3608.                         if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - '.$this->last.' in lp_type 2 is <> sco',0);}
  3609.                         $this->items[$this->last]->close();
  3610.                         //$this->autocomplete_parents($this->last);
  3611.                           //$this->update_queue[$this->last] = $this->items[$this->last]->get_status();
  3612.                     }else{
  3613.                         if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - Item is a SCO, saving is managed by SCO signals',0);}
  3614.                     }
  3615.                     break;
  3616.                 case '1':
  3617.                 default:
  3618.                     if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - '.$this->last.' in lp_type 1 is asset',0);}
  3619.                     $this->items[$this->last]->close();
  3620.                     break;
  3621.             }
  3622.         }else{
  3623.             if($this->debug>2){error_log('New LP - In learnpath::stop_previous_item() - No previous element found, ignoring...',0);}
  3624.             return false;
  3625.         }
  3626.         return true;
  3627.     }
  3628.  
  3629.     /**
  3630.  
  3631.      * Updates the default view mode from fullscreen to embedded and inversely
  3632.  
  3633.      * @return    string The current default view mode ('fullscreen' or 'embedded')
  3634.  
  3635.      */
  3636.  
  3637.     function update_default_view_mode()
  3638.  
  3639.     {
  3640.  
  3641.         if($this->debug>0){error_log('New LP - In learnpath::update_default_view_mode()',0);}
  3642.  
  3643.         $lp_table Database::get_course_table('lp');
  3644.  
  3645.         $sql "SELECT * FROM $lp_table WHERE id = ".$this->get_id();
  3646.  
  3647.         $res api_sql_query($sql__FILE____LINE__);
  3648.  
  3649.         if(Database::num_rows($res)>0){
  3650.  
  3651.             $row Database::fetch_array($res);
  3652.  
  3653.             $view_mode $row['default_view_mod'];
  3654.  
  3655.             if($view_mode == 'fullscreen'){
  3656.  
  3657.                 $view_mode 'embedded';
  3658.  
  3659.             }elseif($view_mode == 'embedded'){
  3660.  
  3661.                 $view_mode 'fullscreen';
  3662.  
  3663.             }
  3664.  
  3665.             $sql "UPDATE $lp_table SET default_view_mod = '$view_mode' WHERE id = ".$this->get_id();
  3666.  
  3667.             $res api_sql_query($sql__FILE____LINE__);
  3668.  
  3669.                $this->mode = $view_mode;
  3670.  
  3671.             return $view_mode;
  3672.  
  3673.         }else{
  3674.  
  3675.             if($this->debug>2){error_log('New LP - Problem in update_default_view() - could not find LP '.$this->get_id().' in DB',0);}
  3676.  
  3677.         }
  3678.  
  3679.         return -1;
  3680.  
  3681.     }
  3682.  
  3683.     /**
  3684.  
  3685.      * Updates the default behaviour about auto-commiting SCORM updates
  3686.  
  3687.      * @return    boolean    True if auto-commit has been set to 'on', false otherwise
  3688.  
  3689.      */
  3690.  
  3691.     function update_default_scorm_commit(){
  3692.  
  3693.         if($this->debug>0){error_log('New LP - In learnpath::update_default_scorm_commit()',0);}
  3694.  
  3695.         $lp_table Database::get_course_table('lp');
  3696.  
  3697.         $sql "SELECT * FROM $lp_table WHERE id = ".$this->get_id();
  3698.  
  3699.         $res api_sql_query($sql__FILE____LINE__);
  3700.  
  3701.         if(Database::num_rows($res)>0){
  3702.  
  3703.             $row Database::fetch_array($res);
  3704.  
  3705.             $force $row['force_commit'];
  3706.  
  3707.             if($force == 1){
  3708.  
  3709.                 $force 0;
  3710.  
  3711.                 $force_return false;
  3712.  
  3713.             }elseif($force == 0){
  3714.  
  3715.                 $force 1;
  3716.  
  3717.                 $force_return true;
  3718.  
  3719.             }
  3720.  
  3721.             $sql "UPDATE $lp_table SET force_commit = $force WHERE id = ".$this->get_id();
  3722.  
  3723.             $res api_sql_query($sql__FILE____LINE__);
  3724.  
  3725.             $this->force_commit = $force_return;
  3726.  
  3727.             return $force_return;
  3728.  
  3729.         }else{
  3730.  
  3731.             if($this->debug>2){error_log('New LP - Problem in update_default_scorm_commit() - could not find LP '.$this->get_id().' in DB',0);}
  3732.  
  3733.         }
  3734.  
  3735.         return -1;
  3736.  
  3737.     }
  3738.  
  3739.     /**
  3740.      * Updates the order of learning paths (goes through all of them by order and fills the gaps)
  3741.      * @return    bool    True on success, false on failure
  3742.      */
  3743.     function update_display_order()
  3744.     {
  3745.         $lp_table Database::get_course_table(TABLE_LP_MAIN);
  3746.         $sql "SELECT * FROM $lp_table ORDER BY display_order";
  3747.         $res api_sql_query($sql__FILE____LINE__);
  3748.         if($res === falsereturn false;
  3749.         $lps array();
  3750.         $lp_order array();
  3751.         $num Database::num_rows($res);
  3752.         //first check the order is correct, globally (might be wrong because
  3753.         //of versions < 1.8.4)
  3754.         if($num>0)
  3755.         {
  3756.             $i 1;
  3757.             while($row Database::fetch_array($res))
  3758.             {
  3759.                 if($row['display_order'!= $i)
  3760.                 {    //if we find a gap in the order, we need to fix it
  3761.                     $need_fix true;
  3762.                     $sql_u "UPDATE $lp_table SET display_order = $i WHERE id = ".$row['id'];
  3763.                     $res_u api_sql_query($sql_u__FILE____LINE__);
  3764.                 }
  3765.                 $i++;
  3766.             }
  3767.         }
  3768.         return true;
  3769.     }
  3770.  
  3771.     /**
  3772.  
  3773.      * Updates the "prevent_reinit" value that enables control on reinitialising items on second view
  3774.  
  3775.      * @return    boolean    True if prevent_reinit has been set to 'on', false otherwise (or 1 or 0 in this case)
  3776.  
  3777.      */
  3778.  
  3779.     function update_reinit(){
  3780.  
  3781.         if($this->debug>0){error_log('New LP - In learnpath::update_reinit()',0);}
  3782.  
  3783.         $lp_table Database::get_course_table('lp');
  3784.  
  3785.         $sql "SELECT * FROM $lp_table WHERE id = ".$this->get_id();
  3786.  
  3787.         $res api_sql_query($sql__FILE____LINE__);
  3788.  
  3789.         if(Database::num_rows($res)>0){
  3790.  
  3791.             $row Database::fetch_array($res);
  3792.  
  3793.             $force $row['prevent_reinit'];
  3794.  
  3795.             if($force == 1){
  3796.  
  3797.                 $force 0;
  3798.  
  3799.             }elseif($force == 0){
  3800.  
  3801.                 $force 1;
  3802.  
  3803.             }
  3804.  
  3805.             $sql "UPDATE $lp_table SET prevent_reinit = $force WHERE id = ".$this->get_id();
  3806.  
  3807.             $res api_sql_query($sql,__FILE__,__LINE__);
  3808.  
  3809.             $this->prevent_reinit = $force;
  3810.  
  3811.             return $force;
  3812.  
  3813.         }else{
  3814.  
  3815.             if($this->debug>2){error_log('New LP - Problem in update_reinit() - could not find LP '.$this->get_id().' in DB',0);}
  3816.  
  3817.         }
  3818.  
  3819.         return -1;
  3820.  
  3821.     }
  3822.  
  3823.     /**
  3824.  
  3825.      * Updates the "scorm_debug" value that shows or hide the debug window
  3826.  
  3827.      * @return    boolean    True if scorm_debug has been set to 'on', false otherwise (or 1 or 0 in this case)
  3828.  
  3829.      */
  3830.  
  3831.     function update_scorm_debug(){
  3832.  
  3833.         if($this->debug>0){error_log('New LP - In learnpath::update_scorm_debug()',0);}
  3834.  
  3835.         $lp_table Database::get_course_table('lp');
  3836.  
  3837.         $sql "SELECT * FROM $lp_table WHERE id = ".$this->get_id();
  3838.  
  3839.         $res api_sql_query($sql__FILE____LINE__);
  3840.  
  3841.         if(Database::num_rows($res)>0){
  3842.  
  3843.             $row Database::fetch_array($res);
  3844.  
  3845.             $force $row['debug'];
  3846.  
  3847.             if($force == 1){
  3848.  
  3849.                 $force 0;
  3850.  
  3851.             }elseif($force == 0){
  3852.  
  3853.                 $force 1;
  3854.  
  3855.             }
  3856.  
  3857.             $sql "UPDATE $lp_table SET debug = $force WHERE id = ".$this->get_id();
  3858.  
  3859.             $res api_sql_query($sql,__FILE__,__LINE__);
  3860.  
  3861.             $this->scorm_debug = $force;
  3862.  
  3863.             return $force;
  3864.  
  3865.         }else{
  3866.  
  3867.             if($this->debug>2){error_log('New LP - Problem in update_scorm_debug() - could not find LP '.$this->get_id().' in DB',0);}
  3868.  
  3869.         }
  3870.  
  3871.         return -1;
  3872.  
  3873.     }
  3874.     
  3875.    /**
  3876.     * Function that makes a call to the function sort_tree_array and create_tree_array
  3877.     *
  3878.     * @author Kevin Van Den Haute
  3879.     * 
  3880.     * @param unknown_type $array 
  3881.     */
  3882.     function tree_array($array)
  3883.     {
  3884.         $array $this->sort_tree_array($array);
  3885.         $this->create_tree_array($array);
  3886.     }
  3887.  
  3888.     /**
  3889.      * Creates an array with the elements of the learning path tree in it
  3890.      *
  3891.      * @author Kevin Van Den Haute
  3892.      * 
  3893.      * @param array $array 
  3894.      * @param int $parent 
  3895.      * @param int $depth 
  3896.      * @param array $tmp 
  3897.      */
  3898.     function create_tree_array($array$parent 0$depth = -1$tmp array())
  3899.     {
  3900.         if(is_array($array))
  3901.         {
  3902.             for($i 0$i count($array)$i++)
  3903.             {    
  3904.                 if($array[$i]['parent_item_id'== $parent)
  3905.                 {
  3906.                     if(!in_array($array[$i]['parent_item_id']$tmp))
  3907.                     {
  3908.                         $tmp[$array[$i]['parent_item_id'];
  3909.                         $depth++;
  3910.                     }
  3911.                     
  3912.                     $this->arrMenu[array(
  3913.                         'id' => $array[$i]['id'],
  3914.                         'item_type' => $array[$i]['item_type'],
  3915.                         'title' => $array[$i]['title'],
  3916.                         'path' => $array[$i]['path'],
  3917.                         'description' => $array[$i]['description'],
  3918.                         'parent_item_id' => $array[$i]['parent_item_id'],
  3919.                         'previous_item_id' => $array[$i]['previous_item_id'],
  3920.                         'next_item_id' => $array[$i]['next_item_id'],
  3921.                         'min_score' => $array[$i]['min_score'],
  3922.                         'max_score' => $array[$i]['max_score'],
  3923.                         'mastery_score' => $array[$i]['mastery_score'],
  3924.                         'display_order' => $array[$i]['display_order'],
  3925.                         'prerequisite' => $array[$i]['prerequisite'],
  3926.                         'depth' => $depth
  3927.                         );
  3928.                     
  3929.                     $this->create_tree_array($array$array[$i]['id']$depth$tmp);
  3930.                 }
  3931.             }
  3932.         }
  3933.     }
  3934.     
  3935.     /**
  3936.      * Sorts a multi dimensional array by parent id and display order
  3937.      * @author Kevin Van Den Haute
  3938.      * 
  3939.      * @param array $array (array with al the learning path items in it)
  3940.      * 
  3941.      * @return array 
  3942.      */
  3943.     function sort_tree_array($array)
  3944.     {
  3945.         foreach($array as $key => $row)
  3946.         {
  3947.             $parent[$key]    $row['parent_item_id'];
  3948.             $position[$key]    $row['display_order'];
  3949.         }
  3950.         
  3951.         if(count($array0)
  3952.             array_multisort($parentSORT_ASC$positionSORT_ASC$array);
  3953.         
  3954.         return $array;
  3955.     }
  3956.     
  3957.     
  3958.     
  3959.     /**
  3960.      * Function that creates a table structure with a learning path his modules, chapters and documents.
  3961.      * Also the actions for the modules, chapters and documents are in this table.
  3962.      *
  3963.      * @author Kevin Van Den Haute
  3964.      * 
  3965.      * @param int $lp_id 
  3966.      * 
  3967.      * @return string 
  3968.      */
  3969.     function overview()
  3970.     {
  3971.         global $charset;
  3972.         $return '';
  3973.         
  3974.         $tbl_lp_item Database::get_course_table('lp_item');
  3975.         
  3976.         $sql "
  3977.             SELECT *
  3978.             FROM " $tbl_lp_item "
  3979.             WHERE
  3980.                 lp_id = " $this->lp_id;
  3981.         
  3982.         $result api_sql_query($sql__FILE____LINE__);        
  3983.         $arrLP array();        
  3984.         $mycharset=api_get_setting('platform_charset');        
  3985.         
  3986.         while($row Database::fetch_array($result))
  3987.         {
  3988.                 
  3989.             $row['title'mb_convert_encoding($row['title']$mycharset,$this->encoding);
  3990.             
  3991.             $arrLP[array(
  3992.             'id' => $row['id'],
  3993.             'item_type' => $row['item_type'],
  3994.             'title' => $row['title'],
  3995.             'description' => $row['description'],
  3996.             'parent_item_id' => $row['parent_item_id'],
  3997.             'previous_item_id' => $row['previous_item_id'],
  3998.             'next_item_id' => $row['next_item_id'],
  3999.             'display_order' => $row['display_order']);        
  4000.         }
  4001.          
  4002.         $this->tree_array($arrLP);        
  4003.         $arrLP $this->arrMenu;        
  4004.         unset($this->arrMenu);     
  4005.         
  4006.         if(api_is_allowed_to_edit())
  4007.             $return .= '<p><a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=build&amp;lp_id=' $this->lp_id . '">'.get_lang("Advanced").'</a>&nbsp;&#124;&nbsp;'.get_lang("BasicOverview").'&nbsp;&#124;&nbsp;<a href="lp_controller.php?cidReq='.$_GET['cidReq'].'&action=view&lp_id='.$this->lp_id.'">'.get_lang("Display").'</a></p>';
  4008.         
  4009.         $return .= '<table class="data_table">' "\n";
  4010.         
  4011.             $return .= "\t" '<tr>' "\n";
  4012.             
  4013.                 $return .= "\t" '<th width="75%">'.get_lang("Title").'</th>' "\n";
  4014.                 //$return .= "\t" . '<th>'.get_lang("Description").'</th>' . "\n";
  4015.                 $return .= "\t" '<th>'.get_lang("Move").'</th>' "\n";
  4016.                 $return .= "\t" '<th>'.get_lang("Actions").'</th>' "\n";
  4017.             
  4018.             $return .= "\t" '</tr>' "\n";
  4019.             
  4020.             for($i 0$i count($arrLP)$i++)
  4021.             {
  4022.                 $title=$arrLP[$i]['title'];
  4023.                 
  4024.                 if($arrLP[$i]['description'== '')
  4025.                     $arrLP[$i]['description''&nbsp;';
  4026.                 
  4027.                 if (($i 2)==0$oddclass="row_odd"else $oddclass="row_even"}
  4028.                 
  4029.                 $return .= "\t" '<tr class="'.$oddclass.'">' "\n";
  4030.                     
  4031.                     $return .= "\t\t" '<td style="padding-left:' $arrLP[$i]['depth'10 'px;"><img align="left" src="../img/lp_' $arrLP[$i]['item_type''.png" style="margin-right:3px;" />' $title '</td>' "\n";
  4032.                     //$return .= "\t\t" . '<td>' . stripslashes($arrLP[$i]['description']) . '</td>' . "\n";
  4033.                     
  4034.                     if(api_is_allowed_to_edit())
  4035.                     {
  4036.                         $return .= "\t\t" '<td>' "\n";
  4037.                             
  4038.                             if($arrLP[$i]['previous_item_id'!= 0)
  4039.                             {
  4040.                                 $return .= "\t\t\t" '<a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=move_item&amp;direction=up&amp;id=' $arrLP[$i]['id''&amp;lp_id=' $this->lp_id . '">';
  4041.                                     $return .= '<img alt="" src="../img/arrow_up_' ($arrLP[$i]['depth'3'.gif" />';
  4042.                                 $return .= '</a>' "\n";
  4043.                             }
  4044.                             else
  4045.                                 $return .= "\t\t\t" '<img alt="" src="../img/blanco.png" title="" />' "\n";
  4046.                             
  4047.                             if($arrLP[$i]['next_item_id'!= 0)
  4048.                             {
  4049.                                 $return .= "\t\t\t" '<a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=move_item&amp;direction=down&amp;id=' $arrLP[$i]['id''&amp;lp_id=' $this->lp_id . '">';
  4050.                                     $return .= '<img src="../img/arrow_down_' ($arrLP[$i]['depth'3'.gif" />';
  4051.                                 $return .= '</a>' "\n";
  4052.                             }
  4053.                             else
  4054.                                 $return .= "\t\t\t" '<img alt="" src="../img/blanco.png" title="" />' "\n";
  4055.                             
  4056.                         $return .= "\t\t" '</td>' "\n";
  4057.                         
  4058.                         $return .= "\t\t" '<td>' "\n";
  4059.                         
  4060.                         if($arrLP[$i]['item_type'!= 'dokeos_chapter' && $arrLP[$i]['item_type'!= 'dokeos_module')
  4061.                         {
  4062.                             $return .= "\t\t\t" '<a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=edit_item&amp;view=build&amp;id=' $arrLP[$i]['id''&amp;lp_id=' $this->lp_id . '">';
  4063.                                 $return .= '<img alt="" src="../img/edit.gif" title="' get_lang('_edit_learnpath_module''" />';
  4064.                             $return .= '</a>' "\n";
  4065.                         }
  4066.                         else
  4067.                         {
  4068.                             $return .= "\t\t\t" '<a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=edit_item&amp;id=' $arrLP[$i]['id''&amp;lp_id=' $this->lp_id . '">';
  4069.                                 $return .= '<img alt="" src="../img/edit.gif" title="' get_lang('_edit_learnpath_module''" />';
  4070.                             $return .= '</a>' "\n";
  4071.                         }
  4072.                         
  4073.                         $return .= "\t\t\t" '<a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=delete_item&amp;id=' $arrLP[$i]['id''&amp;lp_id=' $this->lp_id . '" onclick="return confirmation(\'' addslashes($title)'\');">';
  4074.                             $return .= '<img alt="" src="../img/delete.gif" title="' get_lang('_delete_learnpath_module''" />';
  4075.                         $return .= '</a>' "\n";
  4076.                         
  4077.                         $return .= "\t\t" '</td>' "\n";
  4078.                     }
  4079.                     
  4080.                 $return .= "\t" '</tr>' "\n";
  4081.             }
  4082.             
  4083.             if(count($arrLP== 0)
  4084.             {
  4085.                 $return .= "\t" '<tr>' "\n";
  4086.                     $return .= "\t\t" '<td colspan="4">'.get_lang("NoItemsInLp").'</td>' "\n";
  4087.                 $return .= "\t" '</tr>' "\n";
  4088.             }        
  4089.         $return .= '</table>' "\n";        
  4090.         return $return;
  4091.     }
  4092.     
  4093.     /**
  4094.      * This functions builds the LP tree based on data from the database.
  4095.      *
  4096.      * @return string 
  4097.      * @uses dtree.js :: necessary javascript for building this tree
  4098.      */
  4099.     function build_tree()
  4100.     {
  4101.         $return "<script type=\"text/javascript\">\n";
  4102.         
  4103.         $return .= "\tm = new dTree('m');\n\n";
  4104.         
  4105.         $return .= "\tm.config.folderLinks        = true;\n";
  4106.         $return .= "\tm.config.useCookies        = true;\n";
  4107.         $return .= "\tm.config.useIcons            = true;\n";
  4108.         $return .= "\tm.config.useLines            = true;\n";
  4109.         $return .= "\tm.config.useSelection        = true;\n";
  4110.         $return .= "\tm.config.useStatustext    = false;\n\n";
  4111.         
  4112.         $menu    0;
  4113.         $parent    '';
  4114.         
  4115.         $return .= "\tm.add(" $menu ", -1, '" addslashes($this->name"');\n";
  4116.         
  4117.         $tbl_lp_item Database::get_course_table('lp_item');
  4118.         
  4119.         $sql "
  4120.             SELECT *
  4121.             FROM " $tbl_lp_item "
  4122.             WHERE
  4123.                 lp_id = " $this->lp_id;
  4124.         
  4125.         $result api_sql_query($sql__FILE____LINE__);        
  4126.         $arrLP array();    
  4127.         $mycharset=api_get_setting('platform_charset');        
  4128.                 
  4129.         while($row Database::fetch_array($result))
  4130.         {
  4131.             
  4132.             if($this->encoding!=$mycharset)
  4133.             {
  4134.                 $row['title'mb_convert_encoding($row['title']$mycharset,$this->encoding);
  4135.             }        
  4136.             
  4137.             $arrLP[array(
  4138.                 'id' => $row['id'],
  4139.                 'item_type' => $row['item_type'],
  4140.                 'title' => $row['title'],
  4141.                 'path' => $row['path'],
  4142.                 'description' => $row['description'],
  4143.                 'parent_item_id' => $row['parent_item_id'],
  4144.                 'previous_item_id' => $row['previous_item_id'],
  4145.                 'next_item_id' => $row['next_item_id'],
  4146.                 'display_order' => $row['display_order']);
  4147.         }
  4148.  
  4149.         $this->tree_array($arrLP);
  4150.         
  4151.         $arrLP $this->arrMenu;
  4152.         
  4153.         unset($this->arrMenu);
  4154.         $title='';
  4155.         for($i 0$i count($arrLP)$i++)
  4156.         {
  4157.             $title addslashes($arrLP[$i]['title'])
  4158.             $menu_page api_get_self('?cidReq=' $_GET['cidReq''&amp;action=view_item&amp;id=' $arrLP[$i]['id''&amp;lp_id=' $_SESSION['oLP']->lp_id;
  4159.             if(file_exists("../img/lp_" $arrLP[$i]['item_type'".png"))
  4160.             {
  4161.                 $return .= "\tm.add(" $arrLP[$i]['id'", " $arrLP[$i]['parent_item_id'", '" $title "', '" $menu_page "', '', '', '../img/lp_" $arrLP[$i]['item_type'".png', '../img/lp_" $arrLP[$i]['item_type'".png');\n";
  4162.             }
  4163.             else if(file_exists("../img/lp_" $arrLP[$i]['item_type'".gif"))
  4164.             {
  4165.                 $return .= "\tm.add(" $arrLP[$i]['id'", " $arrLP[$i]['parent_item_id'", '" $title "', '" $menu_page "', '', '', '../img/lp_" $arrLP[$i]['item_type'".gif', '../img/lp_" $arrLP[$i]['item_type'".gif');\n";
  4166.             }
  4167.             else
  4168.             {
  4169.                 $return .= "\tm.add(" $arrLP[$i]['id'", " $arrLP[$i]['parent_item_id'", '" $title "', '" $menu_page "', '', '', '../img/lp_document.png', '../img/lp_document.png');\n";
  4170.             }
  4171.             if($menu $arrLP[$i]['id'])
  4172.                 $menu $arrLP[$i]['id'];
  4173.         }
  4174.         
  4175.         $return .= "\n\tdocument.write(m);\n";
  4176.         $return .= "\t if(!m.selectedNode) m.s(1);";
  4177.         $return .= "</script>\n";
  4178.         
  4179.         return $return;
  4180.     }
  4181.     
  4182.     /**
  4183.      * Create a new document //still needs some finetuning
  4184.      *
  4185.      * @param array $_course 
  4186.      * @return string 
  4187.      */
  4188.     function create_document($_course)
  4189.     {
  4190.         $dir = isset($_GET['dir']$_GET['dir'$_POST['dir']// please do not modify this dirname formatting
  4191.         
  4192.         if(strstr($dir'..'))
  4193.             $dir '/';
  4194.         
  4195.         if($dir[0== '.')
  4196.             $dir substr($dir1);
  4197.         
  4198.         if($dir[0!= '/')
  4199.             $dir '/'.$dir;
  4200.         
  4201.         if($dir[strlen($dir1!= '/')
  4202.             $dir .= '/';
  4203.         
  4204.         $filepath api_get_path('SYS_COURSE_PATH'$_course['path''/document' $dir;
  4205.         
  4206.         if(!is_dir($filepath))
  4207.         {
  4208.             $filepath api_get_path('SYS_COURSE_PATH'$_course['path''/document/';
  4209.             
  4210.             $dir '/';
  4211.         }
  4212.         
  4213.         //stripslashes before calling replace_dangerous_char() because $_POST['title']
  4214.         //is already escaped twice when it gets here
  4215.         $title        replace_dangerous_char(stripslashes($_POST['title']));
  4216.         $title      disable_dangerous_file($title);
  4217.         $title      replace_accents($title);
  4218.         
  4219.         $filename    $title;
  4220.         $content    $_POST['content_lp'];
  4221.         
  4222.         $tmp_filename $filename;
  4223.                                     
  4224.         $i=0;
  4225.         while(file_exists($filepath $tmp_filename '.html'))
  4226.             $tmp_filename $filename '_' . ++$i;
  4227.                                     
  4228.         $filename $tmp_filename '.html';
  4229.         
  4230.         $content stripslashes(text_filter($content));
  4231.         
  4232.         //if flv player, change absolute paht temporarely to prevent from erasing it in the following lines
  4233.         $content str_replace('flv=h','flv=h|',$content);
  4234.         $content str_replace('flv=/','flv=/|',$content);        
  4235.         
  4236.         $content str_replace(api_get_path('WEB_COURSE_PATH')api_get_path(REL_PATH).'courses/'$content);
  4237.         
  4238.         // for flv player : change back the url to absolute
  4239.         $content str_replace('flv=h|','flv=h',$content);
  4240.         $content str_replace('flv=/|','flv=/',$content);
  4241.         
  4242.         
  4243.         // for flv player : to prevent edition problem with firefox, we have to use a strange tip (don't blame me please)
  4244.         $content str_replace('</body>','<style type="text/css">body{}</style></body>',$content);
  4245.         
  4246.         
  4247.         if(!file_exists($filepath $filename))
  4248.         {
  4249.             if($fp @fopen($filepath $filename'w'))
  4250.             {    
  4251.                 fputs($fp$content);
  4252.                 fclose($fp);
  4253.                                             
  4254.                 $file_size filesize($filepath $filename);
  4255.                 $save_file_path $dir $filename;
  4256.                                             
  4257.                 $document_id add_document($_course$save_file_path'file'$file_size$filename '.html');
  4258.                                             
  4259.                 if($document_id)
  4260.                 {
  4261.                     api_item_property_update($_courseTOOL_DOCUMENT$document_id'DocumentAdded'api_get_user_id());
  4262.                                     
  4263.                     //update parent folders
  4264.                     //item_property_update_on_folder($_course, $_GET['dir'], $_user['user_id']);
  4265.                                     
  4266.                     $new_comment (isset($_POST['comment'])) trim($_POST['comment']'';
  4267.                     $new_title (isset($_POST['title'])) trim($_POST['title']'';
  4268.                                                 
  4269.                     if($new_comment || $new_title)
  4270.                     {
  4271.                         $tbl_doc Database::get_course_table(TABLE_DOCUMENT);
  4272.                         $ct '';
  4273.                         
  4274.                         if($new_comment)
  4275.                             $ct .= ", comment='" $new_comment "'";
  4276.                         
  4277.                         if($new_title)
  4278.                             $ct .= ", title='" $new_title ".html    '";
  4279.                         
  4280.                         $sql_update "
  4281.                             UPDATE " $tbl_doc "
  4282.                             SET " substr($ct1"
  4283.                             WHERE id = " $document_id;
  4284.                         api_sql_query($sql_update__FILE____LINE__);
  4285.                     }
  4286.                 }
  4287.                                             
  4288.                 return $document_id;
  4289.             }
  4290.         }
  4291.     }
  4292.     
  4293.     /**
  4294.      * Enter description here...
  4295.      *
  4296.      * @param array $_course 
  4297.      */
  4298.     function edit_document($_course)
  4299.     {
  4300.         global $_configuration;
  4301.         
  4302.         
  4303.         $dir = isset($_GET['dir']$_GET['dir'$_POST['dir']// please do not modify this dirname formatting
  4304.         
  4305.         if(strstr($dir'..'))
  4306.             $dir '/';
  4307.         
  4308.         if($dir[0== '.')
  4309.             $dir substr($dir1);
  4310.         
  4311.         if($dir[0!= '/')
  4312.             $dir '/'.$dir;
  4313.         
  4314.         if($dir[strlen($dir1!= '/')
  4315.             $dir .= '/';
  4316.         
  4317.         $filepath api_get_path('SYS_COURSE_PATH'$_course['path''/document'.$dir;
  4318.         
  4319.         if(!is_dir($filepath))
  4320.         {
  4321.             $filepath api_get_path('SYS_COURSE_PATH'$_course['path''/document/';
  4322.             
  4323.             $dir '/';
  4324.         }
  4325.         
  4326.         $table_doc Database::get_course_table(TABLE_DOCUMENT);
  4327.         
  4328.         $sql "
  4329.             SELECT path
  4330.             FROM " $table_doc "
  4331.             WHERE id = " $_POST['path'];
  4332.         $res api_sql_query($sql__FILE____LINE__);
  4333.         $row Database::fetch_array($res);
  4334.         $content    stripslashes($_POST['content_lp']);
  4335.         $file        $filepath $row['path'];
  4336.         
  4337.         
  4338.         if($fp @fopen($file'w'))
  4339.         {
  4340.             $content text_filter($content);
  4341.             $content str_replace(api_get_path('WEB_COURSE_PATH')$_configuration['url_append'].'/courses/'$content);
  4342.             
  4343.             fputs($fp$content);
  4344.             fclose($fp);
  4345.         }
  4346.     }
  4347.     
  4348.     /**
  4349.      * Displays the selected item, with a panel for manipulating the item
  4350.      *
  4351.      * @param int $item_id 
  4352.      * @param string $msg 
  4353.      * @return string 
  4354.      */
  4355.     function display_item($item_id$iframe true$msg '')
  4356.     {
  4357.         global $_course//will disappear
  4358.         
  4359.         $return '';
  4360.         
  4361.         if(is_numeric($item_id))
  4362.         {
  4363.             $tbl_lp_item    Database::get_course_table('lp_item');
  4364.             $tbl_doc        Database::get_course_table(TABLE_DOCUMENT);
  4365.             $sql "
  4366.                 SELECT
  4367.                     lp.*
  4368.                 FROM " $tbl_lp_item " as lp
  4369.                 WHERE
  4370.                     lp.id = " $item_id;
  4371.             
  4372.             $result api_sql_query($sql__FILE____LINE__);
  4373.             
  4374.             while($row Database::fetch_array($result))
  4375.             {
  4376.                 $return .= $this->display_manipulate($item_id$row['item_type']);
  4377.                 
  4378.                 $return .= '<div style="padding:10px;">';
  4379.                 
  4380.                 if($msg != '')
  4381.                     $return .= $msg;
  4382.                 
  4383.                 if($this->encoding=='UTF-8')
  4384.                 {
  4385.                     $row['title'utf8_decode($row['title']);
  4386.                 }                
  4387.                 
  4388.                 $return .= '<p class="lp_title">' stripslashes($row['title']'</p>';
  4389.                 //$return .= '<p class="lp_text">' . ((trim($row['description']) == '') ? 'no description' : stripslashes($row['description'])) . '</p>';
  4390.                 
  4391.                 //$return .= '<hr />';
  4392.                 
  4393.                 if($row['item_type'== TOOL_DOCUMENT)
  4394.                 {
  4395.                     $tbl_doc Database :: get_course_table(TABLE_DOCUMENT);
  4396.                     $sql_doc "SELECT path FROM " $tbl_doc " WHERE id = " $row['path'];
  4397.                     $result=api_sql_query($sql_doc__FILE____LINE__);
  4398.                     $path_file=Database::result($result,0,0);                    
  4399.                     $path_parts pathinfo($path_file);
  4400.                     
  4401.                     if(in_array($path_parts['extension'],array('html','txt','png''jpg''JPG''jpeg''JPEG''gif''swf')))
  4402.                     {
  4403.                         $return .= $this->display_document($row['path']truetrue);
  4404.                     }
  4405.                 }
  4406.                     
  4407.                 $return .= '</div>';
  4408.             }
  4409.         }
  4410.         
  4411.         return $return;
  4412.     }
  4413.     
  4414.     /**
  4415.      * Shows the needed forms for editing a specific item
  4416.      *
  4417.      * @param int $item_id 
  4418.      * @return string 
  4419.      */
  4420.     function display_edit_item($item_id)
  4421.     {
  4422.         global $_course//will disappear
  4423.     
  4424.         $return '';
  4425.         
  4426.         if(is_numeric($item_id))
  4427.         {
  4428.             $tbl_lp_item Database::get_course_table('lp_item');
  4429.             
  4430.             $sql "
  4431.                 SELECT *
  4432.                 FROM " $tbl_lp_item "
  4433.                 WHERE id = " $item_id;
  4434.             
  4435.             $res api_sql_query($sql__FILE____LINE__);
  4436.             $row Database::fetch_array($res);
  4437.  
  4438.             switch($row['item_type'])
  4439.             {
  4440.                 case 'dokeos_chapter'case 'dir' case 'asset' case 'sco' :
  4441.                     if(isset($_GET['view']&& $_GET['view'== 'build')
  4442.                     {
  4443.                         $return .= $this->display_manipulate($item_id$row['item_type']);
  4444.                         $return .= $this->display_item_form($row['item_type']get_lang("EditCurrentChapter").' :''edit'$item_id$row);
  4445.                     }
  4446.                     else
  4447.                     {
  4448.                         $return .= $this->display_item_small_form($row['item_type']get_lang("EditCurrentChapter").' :'$row);
  4449.                     }
  4450.                     
  4451.                     break;
  4452.                     
  4453.                 case TOOL_DOCUMENT:
  4454.                 
  4455.                     $tbl_doc Database::get_course_table(TABLE_DOCUMENT);
  4456.             
  4457.                     $sql_step "
  4458.                         SELECT
  4459.                             lp.*,
  4460.                             doc.path as dir
  4461.                         FROM " $tbl_lp_item " as lp
  4462.                         LEFT JOIN " $tbl_doc " as doc ON doc.id = lp.path
  4463.                         WHERE
  4464.                             lp.id = " $item_id;
  4465.                     $res_step api_sql_query($sql_step__FILE____LINE__);
  4466.                     $row_step Database::fetch_array($res_step);
  4467.                     
  4468.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4469.                     $return .= $this->display_document_form('edit'$item_id$row_step);
  4470.                     
  4471.                     break;
  4472.                 
  4473.                 case TOOL_LINK:
  4474.                     
  4475.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4476.                     $return .= $this->display_link_form('edit'$item_id$row);
  4477.                     
  4478.                     break;
  4479.                 
  4480.                 case 'dokeos_module':
  4481.                 
  4482.                     if(isset($_GET['view']&& $_GET['view'== 'build')
  4483.                     {
  4484.                         $return .= $this->display_manipulate($item_id$row['item_type']);
  4485.                         $return .= $this->display_item_form($row['item_type']get_lang("EditCurrentModule").' :''edit'$item_id$row);
  4486.                     }
  4487.                     else
  4488.                     {
  4489.                         $return .= $this->display_item_small_form($row['item_type']get_lang("EditCurrentModule").' :'$row);
  4490.                     }
  4491.         
  4492.                     break;
  4493.                 
  4494.                 case TOOL_QUIZ:
  4495.                     
  4496.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4497.                     $return .= $this->display_quiz_form('edit'$item_id$row);
  4498.                     
  4499.                     break;
  4500.                     
  4501.                     case TOOL_HOTPOTATOES:
  4502.  
  4503.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4504.                     $return .= $this->display_hotpotatoes_form('edit'$item_id$row);
  4505.  
  4506.                     break;
  4507.             
  4508.                 
  4509.                 case TOOL_STUDENTPUBLICATION:
  4510.                     
  4511.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4512.                     $return .= $this->display_student_publication_form('edit'$item_id$row);
  4513.                     
  4514.                     break;
  4515.                     
  4516.                 case TOOL_FORUM:
  4517.                     
  4518.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4519.                     $return .= $this->display_forum_form('edit'$item_id$row);
  4520.                     
  4521.                     break;
  4522.                     
  4523.                 case TOOL_THREAD:
  4524.                     
  4525.                     $return .= $this->display_manipulate($item_id$row['item_type']);
  4526.                     $return .= $this->display_thread_form('edit'$item_id$row);
  4527.                     
  4528.                     break;
  4529.             }
  4530.         }
  4531.         
  4532.         return $return;
  4533.     }
  4534.     
  4535.     /**
  4536.      * Function that displays a list with al the resources that could be added to the learning path
  4537.      *
  4538.      * @return string 
  4539.      */
  4540.     function display_resources()
  4541.     {
  4542.         global $_course//TODO: don't use globals
  4543.         
  4544.         $return '<div style="margin:3px 12px;">' "\n";
  4545.         
  4546.             $return .= '<p class="lp_title" style="margin-top:0;">'.get_lang("CreateNewStep").'</p>';
  4547.         
  4548.             $return .= '<div style="margin-left:7px;"><a href="' .api_get_self()'?cidReq=' $_GET['cidReq''&amp;action=add_item&amp;type=' TOOL_DOCUMENT '&amp;lp_id=' $_SESSION['oLP']->lp_id '">'.get_lang("NewDocument").'</a></div>';
  4549.             
  4550.             $return .= '<p class="lp_title" style="margin-top:10px;">'.get_lang("UseAnExistingResource").'</p>';
  4551.             
  4552.             /* get all the docs */
  4553.             $return .= $this->get_documents();
  4554.             
  4555.             /* get all the exercises */
  4556.             $return .= $this->get_exercises();
  4557.             
  4558.             /* get all the links */
  4559.             $return .= $this->get_links();
  4560.             
  4561.             /* get al the student publications */
  4562.             $return .= $this->get_student_publications();
  4563.             
  4564.             /* get al the forums */
  4565.             $return .= $this->get_forums();
  4566.         
  4567.         $return .= '</div>' "\n";
  4568.         
  4569.         return $return;
  4570.     }
  4571.     
  4572.     /**
  4573.      * Returns the extension of a document
  4574.      *
  4575.      * @param unknown_type $filename 
  4576.      * @return unknown 
  4577.      */
  4578.     function get_extension($filename)
  4579.     {
  4580.         $explode explode('.'$filename);
  4581.         
  4582.         return $explode[count($explode1];
  4583.     }
  4584.     
  4585.     /**
  4586.      * Displays a document by id
  4587.      *
  4588.      * @param unknown_type $id 
  4589.      * @return unknown 
  4590.      */
  4591.     function display_document($id$show_title false$iframe true$edit_link false)
  4592.     {
  4593.         global $_course//temporary
  4594.             
  4595.         $return '';
  4596.         
  4597.         $tbl_doc Database::get_course_table(TABLE_DOCUMENT);
  4598.         
  4599.         $sql_doc "
  4600.             SELECT *
  4601.             FROM " $tbl_doc "
  4602.             WHERE id = " $id;
  4603.         $res_doc api_sql_query($sql_doc__FILE____LINE__);    
  4604.         $row_doc Database::fetch_array($res_doc);
  4605.         
  4606.         //if($show_title)
  4607.             //$return .= '<p class="lp_title">' . $row_doc['title'] . ($edit_link ? ' [ <a href="' .api_get_self(). '?cidReq=' . $_GET['cidReq'] . '&amp;action=add_item&amp;type=' . TOOL_DOCUMENT . '&amp;file=' . $_GET['file'] . '&amp;edit=true&amp;lp_id=' . $_GET['lp_id'] . '">Edit this document</a> ]' : '') . '</p>';
  4608.         
  4609.         //TODO: add a path filter
  4610.         if($iframe){
  4611.             $return .= '<iframe frameborder="0" src="' api_get_path(WEB_COURSE_PATH$_course['path''/document' str_replace('%2F','/',urlencode($row_doc['path'])) '?'.api_get_cidreq().'" style="background:#FFFFFF; border:1px solid #CCCCCC; height:490px; width:100%; margin-top: 20px;"></iframe>';
  4612.         }
  4613.         else{
  4614.             $return .= file_get_contents(api_get_path(SYS_COURSE_PATH$_course['path''/document' $row_doc['path']);
  4615.         }
  4616.         
  4617.         return $return;
  4618.     }
  4619.     
  4620.     /**
  4621.      * Enter description here...
  4622.      *
  4623.      * @param unknown_type $action 
  4624.      * @param unknown_type $id 
  4625.      * @param unknown_type $extra_info 
  4626.      * @return unknown 
  4627.      */
  4628.     function display_quiz_form($action 'add'$id 0$extra_info '')
  4629.     {
  4630.         global $charset;
  4631.         
  4632.         $tbl_lp_item Database::get_course_table(TABLE_LP_ITEM);
  4633.         $tbl_quiz Database::get_course_table(TABLE_QUIZ_TEST);
  4634.         
  4635.         if($id != && is_array($extra_info))
  4636.         {
  4637.             $item_title            stripslashes($extra_info['title']);
  4638.             $item_description    stripslashes($extra_info['description']);
  4639.         }
  4640.         elseif(is_numeric($extra_info))
  4641.         {
  4642.             $sql_quiz "
  4643.                 SELECT
  4644.                     title,
  4645.                     description
  4646.                 FROM " $tbl_quiz "
  4647.                 WHERE id = " $extra_info;
  4648.             
  4649.             $result api_sql_query($sql_quiz__FILE____LINE__);
  4650.             $row Database::fetch_array($result);
  4651.             
  4652.             $item_title $row['title'];
  4653.             $item_description $row['description'];
  4654.         }
  4655.         else
  4656.         {
  4657.             $item_title            '';
  4658.             $item_description    '';
  4659.         }
  4660.                 
  4661.         $return '<div style="margin:3px 12px;">';
  4662.             
  4663.             if($id != && is_array($extra_info))
  4664.                 $parent $extra_info['parent_item_id'];
  4665.             else
  4666.                 $parent 0;
  4667.             
  4668.             $sql "
  4669.                 SELECT *
  4670.                 FROM " $tbl_lp_item "
  4671.                 WHERE
  4672.                     lp_id = " $this->lp_id;
  4673.             
  4674.             $result api_sql_query($sql__FILE____LINE__);
  4675.             
  4676.             $arrLP array();
  4677.             
  4678.             while($row Database::fetch_array($result))
  4679.             {
  4680.                 $arrLP[array(
  4681.                     'id' => $row['id'],
  4682.                     'item_type' => $row['item_type'],
  4683.                     'title' => $row['title'],
  4684.                     'path' => $row['path'],
  4685.                     'description' => $row['description'],
  4686.                     'parent_item_id' => $row['parent_item_id'],
  4687.                     'previous_item_id' => $row['previous_item_id'],
  4688.                     'next_item_id' => $row['next_item_id'],
  4689.                     'display_order' => $row['display_order'],
  4690.                     'prerequisite' => $row['prerequisite']);
  4691.             }
  4692.             
  4693.             $this->tree_array($arrLP);
  4694.             
  4695.             $arrLP $this->arrMenu;
  4696.             
  4697.             unset($this->arrMenu);
  4698.             
  4699.             if($action == 'add')
  4700.                 $return .= '<p class="lp_title">'.get_lang("CreateTheExercise").'&nbsp;:</p>' "\n";
  4701.             elseif($action == 'move')
  4702.                 $return .= '<p class="lp_title">'.get_lang("MoveTheCurrentExercise").'&nbsp;:</p>' "\n";
  4703.             else
  4704.                 $return .= '<p class="lp_title">'.get_lang("EditCurrentExecice").'&nbsp;:</p>' "\n";
  4705.             
  4706.             if(isset($_GET['edit']&& $_GET['edit'== 'true')
  4707.             {
  4708.                 $return .= '<div class="lp_message" style="margin-bottom:15px;">';
  4709.                 
  4710.                     $return .= '<p class="lp_title">'.get_lang("Warning").' !</p>';
  4711.                     $return .= get_lang("WarningEditingDocument");
  4712.                 
  4713.                 $return .= '</div>';
  4714.             }
  4715.             
  4716.             $return .= '<form method="POST">' "\n";
  4717.             
  4718.                 $return .= "\t" '<table cellpadding="0" cellspacing="0" class="lp_form">' "\n";
  4719.                 
  4720.                     $return .= "\t\t" '<tr>' "\n";
  4721.                     
  4722.                         $return .= "\t\t\t" '<td class="label"><label for="idParent">'.get_lang("Parent").'&nbsp;:</label></td>' "\n";
  4723.                         $return .= "\t\t\t" '<td class="input">' "\n";
  4724.                         
  4725.                             $return .= "\t\t\t\t" '<select id="idParent" name="parent" onchange="load_cbo(this.value);" size="1">';
  4726.                             
  4727.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">' $this->name . '</option>';
  4728.                                 
  4729.                                 $arrHide array($id);
  4730.                                 
  4731.                                 for($i 0$i count($arrLP)$i++)
  4732.                                 {
  4733.                                     if($action != 'add')
  4734.                                     {
  4735.                                         if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide))
  4736.                                         {
  4737.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  4738.                                         }
  4739.                                         else
  4740.                                         {
  4741.                                             $arrHide[$arrLP[$i]['id'];
  4742.                                         }
  4743.                                     }
  4744.                                     else
  4745.                                     {
  4746.                                         if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir')
  4747.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  4748.                                     }
  4749.                                 }
  4750.                                 if (is_array($arrLP))
  4751.                                 {
  4752.                                     reset($arrLP);    
  4753.                                 }
  4754.                                 
  4755.                             $return .= "\t\t\t\t" '</select>';
  4756.                         
  4757.                         $return .= "\t\t\t" '</td>' "\n";
  4758.                     
  4759.                     $return .= "\t\t" '</tr>' "\n";
  4760.                                     
  4761.                     $return .= "\t\t" '<tr>' "\n";
  4762.                         
  4763.                         $return .= "\t\t\t" '<td class="label"><label for="idPosition">'.get_lang("Position").'&nbsp;:</label></td>' "\n";
  4764.                         $return .= "\t\t\t" '<td class="input">' "\n";
  4765.                         
  4766.                             $return .= "\t\t\t\t" '<select id="idPosition" name="previous" size="1">';
  4767.                             
  4768.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">'.get_lang('FirstPosition').'</option>';
  4769.                                 
  4770.                                 for($i 0$i count($arrLP)$i++)
  4771.                                 {
  4772.                                     if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  4773.                                     {
  4774.                                         if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  4775.                                             $selected 'selected="selected" ';
  4776.                                         elseif($action == 'add')
  4777.                                             $selected 'selected="selected" ';
  4778.                                         else
  4779.                                             $selected '';
  4780.                                         
  4781.                                         $return .= "\t\t\t\t\t" '<option ' $selected 'value="' $arrLP[$i]['id''">'.get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'"</option>';
  4782.                                     }
  4783.                                 }
  4784.                                 
  4785.                             $return .= "\t\t\t\t" '</select>';
  4786.                         
  4787.                         $return .= "\t\t\t" '</td>' "\n";
  4788.                     
  4789.                     $return .= "\t\t" '</tr>' "\n";
  4790.                     
  4791.                     if($action != 'move')
  4792.                     {
  4793.                         $return .= "\t\t" '<tr>' "\n";
  4794.                             
  4795.                             $return .= "\t\t\t" '<td class="label"><label for="idTitle">'.get_lang("Title").'&nbsp;:</label></td>' "\n";
  4796.                             $return .= "\t\t\t" '<td class="input"><input id="idTitle" name="title" type="text" value="' $item_title '" /></td>' "\n";
  4797.                         
  4798.                         $return .= "\t\t" '</tr>' "\n";
  4799.                         
  4800.                         
  4801.                         $id_prerequisite=0;
  4802.                         if (is_array($arrLP ))
  4803.                         {
  4804.                             foreach($arrLP as $key=>$value){
  4805.                                 if($value['id']==$id){
  4806.                                     $id_prerequisite=$value['prerequisite'];
  4807.                                     break;
  4808.                                 }
  4809.                             }
  4810.                         }                        
  4811.                         $arrHide=array();
  4812.                         for($i 0$i count($arrLP)$i++)
  4813.                         {
  4814.                             if($arrLP[$i]['id'!= $id && $arrLP[$i]['item_type'!= 'dokeos_chapter')
  4815.                             {
  4816.                                 if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  4817.                                     $s_selected_position=$arrLP[$i]['id'];
  4818.                                 elseif($action == 'add')
  4819.                                     $s_selected_position=0;
  4820.                                 $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  4821.                                 
  4822.                             }
  4823.                         }
  4824.                         
  4825.                         $return .= "\t\t" '<tr>' "\n";
  4826.                             
  4827.                         $return .= "\t\t\t" '<td class="label"><label for="idPrerequisites">'.get_lang("Prerequisites").'&nbsp;:</label></td>' "\n";
  4828.                             $return .= "\t\t\t" '<td class="input"><select name="prerequisites" id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"><option value="0">'.get_lang("NoPrerequisites").'</option>';
  4829.                             
  4830.                             foreach($arrHide as $key => $value){
  4831.                                 if($key==$s_selected_position && $action == 'add'){
  4832.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  4833.                                 }
  4834.                                 elseif($key==$id_prerequisite && $action == 'edit'){
  4835.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  4836.                                 }
  4837.                                 else{
  4838.                                     $return .= '<option value="'.$key.'">'.$value['value'].'</option>';
  4839.                                 }
  4840.                             }
  4841.                             
  4842.                             $return .= "</select></td>";
  4843.                         
  4844.                         $return .= "\t\t" '</tr>' "\n";
  4845.                         
  4846.                         $return .= "\t\t" '<tr>' "\n";
  4847.                             
  4848.                             //Remove temporaly the test description
  4849.                             //$return .= "\t\t\t" . '<td class="label"><label for="idDescription">'.get_lang("Description").' :</label></td>' . "\n";
  4850.                             //$return .= "\t\t\t" . '<td class="input"><textarea id="idDescription" name="description" rows="4">' . $item_description . '</textarea></td>' . "\n";
  4851.                         
  4852.                         $return .= "\t\t" '</tr>' "\n";
  4853.                     }
  4854.                     
  4855.                     $return .= "\t\t" '<tr>' "\n";
  4856.                         
  4857.                         $return .= "\t\t\t" '<td colspan="2"><input class="button" name="submit_button" type="submit" value="'.get_lang('Ok').'" /></td>' "\n";
  4858.                     
  4859.                     $return .= "\t\t" '</tr>' "\n";
  4860.                 
  4861.                 $return .= "\t" '</table>' "\n";    
  4862.                 
  4863.                 if($action == 'move')
  4864.                 {
  4865.                     $return .= "\t" '<input name="title" type="hidden" value="' $item_title '" />' "\n";
  4866.                     $return .= "\t" '<input name="description" type="hidden" value="' $item_description '" />' "\n";
  4867.                 }
  4868.                 
  4869.                 if(is_numeric($extra_info))
  4870.                 {
  4871.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info '" />' "\n";
  4872.                 }
  4873.                 elseif(is_array($extra_info))
  4874.                 {
  4875.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info['path''" />' "\n";
  4876.                 }
  4877.                 
  4878.                 $return .= "\t" '<input name="type" type="hidden" value="'.TOOL_QUIZ.'" />' "\n";
  4879.                 $return .= "\t" '<input name="post_time" type="hidden" value="' time('" />' "\n";
  4880.                 
  4881.             $return .= '</form>' "\n";
  4882.         
  4883.         $return .= '</div>' "\n";
  4884.         return $return;
  4885.     }
  4886.  
  4887. /**
  4888.  * Addition of Hotpotatoes tests
  4889.  * @param    string    Action
  4890.  * @param    integer    Internal ID of the item
  4891.  * @param    mixed    Extra information - can be an array with title and description indexes
  4892.  * @return  string    HTML structure to display the hotpotatoes addition formular
  4893.  */
  4894.     function display_hotpotatoes_form($action 'add'$id 0$extra_info '')
  4895.     {
  4896.         global $charset;
  4897.         $uploadPath DIR_HOTPOTATOES//defined in main_api
  4898.         $tbl_lp_item Database::get_course_table('lp_item');
  4899.  
  4900.         if($id != && is_array($extra_info))
  4901.         {
  4902.             $item_title            stripslashes($extra_info['title']);
  4903.             $item_description    stripslashes($extra_info['description']);
  4904.         }
  4905.         elseif(is_numeric($extra_info))
  4906.         {
  4907.             $TBL_DOCUMENT Database::get_course_table(TABLE_DOCUMENT);
  4908.  
  4909.             $sql_hot "SELECT * FROM ".$TBL_DOCUMENT."
  4910.             WHERE path LIKE '".$uploadPath."/%/%htm%'
  4911.             ORDER BY id ASC";
  4912.         
  4913.                 
  4914.               $res_hot api_sql_query($sql_hot__FILE____LINE__);
  4915.  
  4916.             $row Database::fetch_array($res_hot);
  4917.  
  4918.             $item_title $row['title'];
  4919.             $item_description $row['description'];
  4920.         }
  4921.         else
  4922.         {
  4923.             $item_title            '';
  4924.             $item_description    '';
  4925.         }
  4926.                 
  4927.         $item_title=mb_convert_encoding($item_title,$charset,$this->encoding);
  4928.         $item_description=mb_convert_encoding($item_description,$charset,$this->encoding);
  4929.         
  4930.         $return '<div style="margin:3px 12px;">';
  4931.  
  4932.             if($id != && is_array($extra_info))
  4933.                 $parent $extra_info['parent_item_id'];
  4934.             else
  4935.                 $parent 0;
  4936.  
  4937.             $sql "
  4938.                 SELECT *
  4939.                 FROM " $tbl_lp_item "
  4940.                 WHERE
  4941.                     lp_id = " $this->lp_id;
  4942.  
  4943.             $result api_sql_query($sql__FILE____LINE__);
  4944.  
  4945.             $arrLP array();
  4946.  
  4947.             while($row Database::fetch_array($result))
  4948.             {
  4949.                 $arrLP[array(
  4950.                     'id' => $row['id'],
  4951.                     'item_type' => $row['item_type'],
  4952.                     'title' => $row['title'],
  4953.                     'path' => $row['path'],
  4954.                     'description' => $row['description'],
  4955.                     'parent_item_id' => $row['parent_item_id'],
  4956.                     'previous_item_id' => $row['previous_item_id'],
  4957.                     'next_item_id' => $row['next_item_id'],
  4958.                     'display_order' => $row['display_order'],
  4959.                     'prerequisite' => $row['prerequisite']);
  4960.             }
  4961.  
  4962.             $this->tree_array($arrLP);
  4963.  
  4964.             $arrLP $this->arrMenu;
  4965.  
  4966.             unset($this->arrMenu);
  4967.  
  4968.             if($action == 'add')
  4969.                 $return .= '<p class="lp_title">'.get_lang("CreateTheExercise").'&nbsp;:</p>' "\n";
  4970.             elseif($action == 'move')
  4971.                 $return .= '<p class="lp_title">'.get_lang("MoveTheCurrentExercise").'&nbsp;:</p>' "\n";
  4972.             else
  4973.                 $return .= '<p class="lp_title">'.get_lang("EditCurrentExecice").'&nbsp;:</p>' "\n";
  4974.  
  4975.             if(isset($_GET['edit']&& $_GET['edit'== 'true')
  4976.             {
  4977.                 $return .= '<div class="lp_message" style="margin-bottom:15px;">';
  4978.  
  4979.                     $return .= '<p class="lp_title">'.get_lang("Warning").' !</p>';
  4980.                     $return .= get_lang("WarningEditingDocument");
  4981.  
  4982.                 $return .= '</div>';
  4983.             }
  4984.  
  4985.             $return .= '<form method="POST">' "\n";
  4986.  
  4987.                 $return .= "\t" '<table cellpadding="0" cellspacing="0" class="lp_form">' "\n";
  4988.  
  4989.                     $return .= "\t\t" '<tr>' "\n";
  4990.  
  4991.                         $return .= "\t\t\t" '<td class="label"><label for="idParent">'.get_lang("Parent").' :</label></td>' "\n";
  4992.                         $return .= "\t\t\t" '<td class="input">' "\n";
  4993.  
  4994.                             $return .= "\t\t\t\t" '<select id="idParent" name="parent" onchange="load_cbo(this.value);" size="1">';
  4995.  
  4996.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">' $this->name . '</option>';
  4997.  
  4998.                                 $arrHide array($id);
  4999.  
  5000.                                 for($i 0$i count($arrLP)$i++)
  5001.                                 {
  5002.                                     if($action != 'add')
  5003.                                     {
  5004.                                         if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide))
  5005.                                         {
  5006.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  5007.                                         }
  5008.                                         else
  5009.                                         {
  5010.                                             $arrHide[$arrLP[$i]['id'];
  5011.                                         }
  5012.                                     }
  5013.                                     else
  5014.                                     {
  5015.                                         if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir')
  5016.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  5017.                                     }
  5018.                                 }
  5019.  
  5020.                                 reset($arrLP);
  5021.  
  5022.                             $return .= "\t\t\t\t" '</select>';
  5023.  
  5024.                         $return .= "\t\t\t" '</td>' "\n";
  5025.  
  5026.                     $return .= "\t\t" '</tr>' "\n";
  5027.  
  5028.                     $return .= "\t\t" '<tr>' "\n";
  5029.  
  5030.                         $return .= "\t\t\t" '<td class="label"><label for="idPosition">'.get_lang("Position").' :</label></td>' "\n";
  5031.                         $return .= "\t\t\t" '<td class="input">' "\n";
  5032.  
  5033.                             $return .= "\t\t\t\t" '<select id="idPosition" name="previous" size="1">';
  5034.  
  5035.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">'.get_lang('FirstPosition').'</option>';
  5036.  
  5037.                                 for($i 0$i count($arrLP)$i++)
  5038.                                 {
  5039.                                     if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  5040.                                     {
  5041.                                         if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5042.                                             $selected 'selected="selected" ';
  5043.                                         elseif($action == 'add')
  5044.                                             $selected 'selected="selected" ';
  5045.                                         else
  5046.                                             $selected '';
  5047.  
  5048.                                         $return .= "\t\t\t\t\t" '<option ' $selected 'value="' $arrLP[$i]['id''">'.get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'"</option>';
  5049.                                     }
  5050.                                 }
  5051.  
  5052.                             $return .= "\t\t\t\t" '</select>';
  5053.  
  5054.                         $return .= "\t\t\t" '</td>' "\n";
  5055.  
  5056.                     $return .= "\t\t" '</tr>' "\n";
  5057.  
  5058.                     if($action != 'move')
  5059.                     {
  5060.                         $return .= "\t\t" '<tr>' "\n";
  5061.  
  5062.                             $return .= "\t\t\t" '<td class="label"><label for="idTitle">'.get_lang("Title").' :</label></td>' "\n";
  5063.                             $return .= "\t\t\t" '<td class="input"><input id="idTitle" name="title" type="text" value="' $item_title '" /></td>' "\n";
  5064.  
  5065.                         $return .= "\t\t" '</tr>' "\n";
  5066.  
  5067.  
  5068.                         $id_prerequisite=0;
  5069.                         foreach($arrLP as $key=>$value){
  5070.                             if($value['id']==$id){
  5071.                                 $id_prerequisite=$value['prerequisite'];
  5072.                                 break;
  5073.                             }
  5074.                         }
  5075.  
  5076.                         $arrHide=array();
  5077.                         for($i 0$i count($arrLP)$i++)
  5078.                         {
  5079.                             if($arrLP[$i]['id'!= $id && $arrLP[$i]['item_type'!= 'dokeos_chapter')
  5080.                             {
  5081.                                 if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5082.                                     $s_selected_position=$arrLP[$i]['id'];
  5083.                                 elseif($action == 'add')
  5084.                                     $s_selected_position=0;
  5085.                                 $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  5086.  
  5087.                             }
  5088.                         }
  5089.  
  5090.                         $return .= "\t\t" '<tr>' "\n";
  5091.  
  5092.                             $return .= "\t\t\t" '<td class="label"><label for="idPrerequisites">'.get_lang("Prerequisites").' :</label></td>' "\n";
  5093.                             $return .= "\t\t\t" '<td class="input"><select name="prerequisites" id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"><option value="0">'.get_lang("NoPrerequisites").'</option>';
  5094.  
  5095.                             foreach($arrHide as $key => $value){
  5096.                                 if($key==$s_selected_position && $action == 'add'){
  5097.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  5098.                                 }
  5099.                                 elseif($key==$id_prerequisite && $action == 'edit'){
  5100.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  5101.                                 }
  5102.                                 else{
  5103.                                     $return .= '<option value="'.$key.'">'.$value['value'].'</option>';
  5104.                                 }
  5105.                             }
  5106.  
  5107.                             $return .= "</select></td>";
  5108.  
  5109.                         $return .= "\t\t" '</tr>' "\n";
  5110.  
  5111.                         $return .= "\t\t" '<tr>' "\n";
  5112.  
  5113.                             //Remove temporaly the test description
  5114.                             //$return .= "\t\t\t" . '<td class="label"><label for="idDescription">'.get_lang("Description").' :</label></td>' . "\n";
  5115.                             //$return .= "\t\t\t" . '<td class="input"><textarea id="idDescription" name="description" rows="4">' . $item_description . '</textarea></td>' . "\n";
  5116.  
  5117.                         $return .= "\t\t" '</tr>' "\n";
  5118.                     }
  5119.  
  5120.                     $return .= "\t\t" '<tr>' "\n";
  5121.  
  5122.                         $return .= "\t\t\t" '<td colspan="2"><input class="button" name="submit_button" type="submit" value="'.get_lang('Ok').'" /></td>' "\n";
  5123.  
  5124.                     $return .= "\t\t" '</tr>' "\n";
  5125.  
  5126.                 $return .= "\t" '</table>' "\n";
  5127.  
  5128.                 if($action == 'move')
  5129.                 {
  5130.                     $return .= "\t" '<input name="title" type="hidden" value="' $item_title '" />' "\n";
  5131.                     $return .= "\t" '<input name="description" type="hidden" value="' $item_description '" />' "\n";
  5132.                 }
  5133.  
  5134.                 if(is_numeric($extra_info))
  5135.                 {
  5136.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info '" />' "\n";
  5137.                 }
  5138.                 elseif(is_array($extra_info))
  5139.                 {
  5140.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info['path''" />' "\n";
  5141.                 }
  5142.  
  5143.                 $return .= "\t" '<input name="type" type="hidden" value="'.TOOL_HOTPOTATOES.'" />' "\n";
  5144.                 $return .= "\t" '<input name="post_time" type="hidden" value="' time('" />' "\n";
  5145.  
  5146.             $return .= '</form>' "\n";
  5147.  
  5148.         $return .= '</div>' "\n";
  5149.         return $return;
  5150.     }
  5151.  
  5152. //fin du hotpot form
  5153.  
  5154.  
  5155.     
  5156. /**
  5157.      * Enter description here...
  5158.      *
  5159.      * @param unknown_type $action 
  5160.      * @param unknown_type $id 
  5161.      * @param unknown_type $extra_info 
  5162.      * @return unknown 
  5163.      */
  5164.     function display_forum_form($action 'add'$id 0$extra_info '')
  5165.     {
  5166.         global $charset;
  5167.         
  5168.         $tbl_lp_item Database::get_course_table('lp_item');
  5169.         $tbl_forum Database::get_course_table(TABLE_FORUM);
  5170.         
  5171.         if($id != && is_array($extra_info))
  5172.         {
  5173.             $item_title            stripslashes($extra_info['title']);
  5174.         }
  5175.         elseif(is_numeric($extra_info))
  5176.         {
  5177.             $sql_forum "
  5178.                 SELECT
  5179.                     forum_title as title, forum_comment as comment 
  5180.                 FROM " $tbl_forum "
  5181.                 WHERE forum_id = " $extra_info;
  5182.             
  5183.             $result api_sql_query($sql_forum__FILE____LINE__);
  5184.             $row Database::fetch_array($result);
  5185.             
  5186.             $item_title $row['title'];
  5187.             $item_description $row['comment'];
  5188.         }
  5189.         else
  5190.         {
  5191.             $item_title            '';
  5192.             $item_description     '';
  5193.         }
  5194.         
  5195.         $item_title=mb_convert_encoding($item_title,$charset,$this->encoding);
  5196.         $item_description=mb_convert_encoding($item_description,$charset,$this->encoding);
  5197.                 
  5198.         $return '<div style="margin:3px 12px;">';
  5199.             
  5200.             if($id != && is_array($extra_info))
  5201.                 $parent $extra_info['parent_item_id'];
  5202.             else
  5203.                 $parent 0;
  5204.             
  5205.             $sql "
  5206.                 SELECT *
  5207.                 FROM " $tbl_lp_item "
  5208.                 WHERE
  5209.                     lp_id = " $this->lp_id;
  5210.             
  5211.             $result api_sql_query($sql__FILE____LINE__);
  5212.             
  5213.             $arrLP array();
  5214.             
  5215.             while($row Database::fetch_array($result))
  5216.             {
  5217.                 $arrLP[array(
  5218.                     'id' => $row['id'],
  5219.                     'item_type' => $row['item_type'],
  5220.                     'title' => $row['title'],
  5221.                     'path' => $row['path'],
  5222.                     'description' => $row['description'],
  5223.                     'parent_item_id' => $row['parent_item_id'],
  5224.                     'previous_item_id' => $row['previous_item_id'],
  5225.                     'next_item_id' => $row['next_item_id'],
  5226.                     'display_order' => $row['display_order'],
  5227.                     'prerequisite' => $row['prerequisite']);
  5228.             }
  5229.             
  5230.             $this->tree_array($arrLP);            
  5231.             $arrLP $this->arrMenu;
  5232.             unset($this->arrMenu);
  5233.             
  5234.             if($action == 'add')
  5235.                 $return .= '<p class="lp_title">'.get_lang("CreateTheForum").'&nbsp;:</p>' "\n";
  5236.             elseif($action == 'move')
  5237.                 $return .= '<p class="lp_title">'.get_lang("MoveTheCurrentForum").'&nbsp;:</p>' "\n";
  5238.             else
  5239.                 $return .= '<p class="lp_title">'.get_lang("EditCurrentForum").'&nbsp;:</p>' "\n";
  5240.             
  5241.             $return .= '<form method="POST">' "\n";
  5242.             
  5243.                 $return .= "\t" '<table cellpadding="0" cellspacing="0" class="lp_form">' "\n";
  5244.                 
  5245.                     $return .= "\t\t" '<tr>' "\n";
  5246.                     
  5247.                         $return .= "\t\t\t" '<td class="label"><label for="idParent">'.get_lang("Parent").'&nbsp;:</label></td>' "\n";
  5248.                         $return .= "\t\t\t" '<td class="input">' "\n";
  5249.                         
  5250.                             $return .= "\t\t\t\t" '<select id="idParent" name="parent" onchange="load_cbo(this.value);" size="1">';
  5251.                             
  5252.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">' $this->name . '</option>';
  5253.                                 
  5254.                                 $arrHide array($id);
  5255.                                 
  5256.                                 for($i 0$i count($arrLP)$i++)
  5257.                                 {
  5258.                                     if($action != 'add')
  5259.                                     {
  5260.                                         if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide))
  5261.                                         {
  5262.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  5263.                                         }
  5264.                                         else
  5265.                                         {
  5266.                                             $arrHide[$arrLP[$i]['id'];
  5267.                                         }
  5268.                                     }
  5269.                                     else
  5270.                                     {
  5271.                                         if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir')
  5272.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  5273.                                     }
  5274.                                 }
  5275.                                 
  5276.                                 reset($arrLP);
  5277.                                 
  5278.                             $return .= "\t\t\t\t" '</select>';
  5279.                         
  5280.                         $return .= "\t\t\t" '</td>' "\n";
  5281.                     
  5282.                     $return .= "\t\t" '</tr>' "\n";
  5283.                                     
  5284.                     $return .= "\t\t" '<tr>' "\n";
  5285.                         
  5286.                         $return .= "\t\t\t" '<td class="label"><label for="idPosition">'.get_lang("Position").'&nbsp;:</label></td>' "\n";
  5287.                         $return .= "\t\t\t" '<td class="input">' "\n";
  5288.                         
  5289.                             $return .= "\t\t\t\t" '<select id="idPosition" name="previous" size="1">';
  5290.                             
  5291.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">'.get_lang('FirstPosition').'</option>';
  5292.                                 
  5293.                                 for($i 0$i count($arrLP)$i++)
  5294.                                 {
  5295.                                     if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  5296.                                     {
  5297.                                         if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5298.                                             $selected 'selected="selected" ';
  5299.                                         elseif($action == 'add')
  5300.                                             $selected 'selected="selected" ';
  5301.                                         else
  5302.                                             $selected '';
  5303.                                         
  5304.                                         $return .= "\t\t\t\t\t" '<option ' $selected 'value="' $arrLP[$i]['id''">'.get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'"</option>';
  5305.                                     }
  5306.                                 }
  5307.                                 
  5308.                             $return .= "\t\t\t\t" '</select>';
  5309.                         
  5310.                         $return .= "\t\t\t" '</td>' "\n";
  5311.                     
  5312.                     $return .= "\t\t" '</tr>' "\n";
  5313.                     
  5314.                     if($action != 'move')
  5315.                     {
  5316.                         $return .= "\t\t" '<tr>' "\n";
  5317.                             
  5318.                             $return .= "\t\t\t" '<td class="label"><label for="idTitle">'.get_lang("Title").'&nbsp;:</label></td>' "\n";
  5319.                             $return .= "\t\t\t" '<td class="input"><input id="idTitle" name="title" type="text" value="' $item_title '" /></td>' "\n";
  5320.                         
  5321.                         $return .= "\t\t" '</tr>' "\n";
  5322.                         
  5323.                         $return .= "\t\t" '<tr>' "\n";
  5324.                             
  5325.                             //Remove temporaly the test description
  5326.                             //$return .= "\t\t\t" . '<td class="label"><label for="idDescription">'.get_lang("Description").' :</label></td>' . "\n";
  5327.                             //$return .= "\t\t\t" . '<td class="input"><textarea id="idDescription" name="description" rows="4">' . $item_description . '</textarea></td>' . "\n";
  5328.                         
  5329.                         $return .= "\t\t" '</tr>' "\n";
  5330.                         
  5331.                         $id_prerequisite=0;
  5332.                         foreach($arrLP as $key=>$value){
  5333.                             if($value['id']==$id){
  5334.                                 $id_prerequisite=$value['prerequisite'];
  5335.                                 break;
  5336.                             }
  5337.                         }
  5338.                         
  5339.                         $arrHide=array();
  5340.                         for($i 0$i count($arrLP)$i++)
  5341.                         {
  5342.                             if($arrLP[$i]['id'!= $id && $arrLP[$i]['item_type'!= 'dokeos_chapter')
  5343.                             {
  5344.                                 if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5345.                                     $s_selected_position=$arrLP[$i]['id'];
  5346.                                 elseif($action == 'add')
  5347.                                     $s_selected_position=0;
  5348.                                 $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  5349.                                 
  5350.                             }
  5351.                         }
  5352.                         
  5353.                         $return .= "\t\t" '<tr>' "\n";
  5354.                             
  5355.                             $return .= "\t\t\t" '<td class="label"><label for="idPrerequisites">'.get_lang('Prerequisites').'&nbsp;:</label></td>' "\n";
  5356.                             $return .= "\t\t\t" '<td class="input"><select name="prerequisites" id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"><option value="0">'.get_lang("NoPrerequisites").'</option>';
  5357.                             
  5358.                             foreach($arrHide as $key => $value){
  5359.                                 if($key==$s_selected_position && $action == 'add'){
  5360.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  5361.                                 }
  5362.                                 elseif($key==$id_prerequisite && $action == 'edit'){
  5363.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  5364.                                 }
  5365.                                 else{
  5366.                                     $return .= '<option value="'.$key.'">'.$value['value'].'</option>';
  5367.                                 }
  5368.                             }
  5369.                             
  5370.                             $return .= "</select></td>";
  5371.                         
  5372.                         $return .= "\t\t" '</tr>' "\n";
  5373.                         
  5374.                     }
  5375.                     
  5376.                     $return .= "\t\t" '<tr>' "\n";
  5377.                         
  5378.                         $return .= "\t\t\t" '<td colspan="2"><input class="button" name="submit_button" type="submit" value="'.get_lang('Ok').'" /></td>' "\n";
  5379.                     
  5380.                     $return .= "\t\t" '</tr>' "\n";
  5381.                 
  5382.                 $return .= "\t" '</table>' "\n";    
  5383.                 
  5384.                 if($action == 'move')
  5385.                 {
  5386.                     $return .= "\t" '<input name="title" type="hidden" value="' $item_title '" />' "\n";
  5387.                     $return .= "\t" '<input name="description" type="hidden" value="' $item_description '" />' "\n";
  5388.                 }
  5389.                 
  5390.                 if(is_numeric($extra_info))
  5391.                 {
  5392.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info '" />' "\n";
  5393.                 }
  5394.                 elseif(is_array($extra_info))
  5395.                 {
  5396.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info['path''" />' "\n";
  5397.                 }
  5398.                 
  5399.                 $return .= "\t" '<input name="type" type="hidden" value="'.TOOL_FORUM.'" />' "\n";
  5400.                 $return .= "\t" '<input name="post_time" type="hidden" value="' time('" />' "\n";
  5401.                 
  5402.             $return .= '</form>' "\n";
  5403.         
  5404.         $return .= '</div>' "\n";
  5405.         return $return;
  5406.     }
  5407.     
  5408. function display_thread_form($action 'add'$id 0$extra_info '')
  5409. {
  5410.     global $charset;
  5411.         echo '
  5412.         <style>
  5413.     
  5414.         div.row div.label {
  5415.             width:110px;
  5416.         }
  5417.         
  5418.         div.row div.formw {
  5419.             width: 82%;
  5420.         }
  5421.         </style>';
  5422.         
  5423.         $tbl_lp_item Database::get_course_table('lp_item');
  5424.         $tbl_forum Database::get_course_table(TABLE_FORUM_THREAD);
  5425.         
  5426.         if($id != && is_array($extra_info))
  5427.         {
  5428.             $item_title            stripslashes($extra_info['title']);
  5429.         }
  5430.         elseif(is_numeric($extra_info))
  5431.         {
  5432.             $sql_forum "
  5433.                 SELECT
  5434.                     thread_title as title
  5435.                 FROM " $tbl_forum "
  5436.                 WHERE thread_id = " $extra_info;
  5437.             
  5438.             $result api_sql_query($sql_forum__FILE____LINE__);
  5439.             $row Database::fetch_array($result);
  5440.             
  5441.             $item_title $row['title'];
  5442.             $item_description '';
  5443.         }
  5444.         else
  5445.         {
  5446.             $item_title            '';
  5447.             $item_description    '';
  5448.         }
  5449.         $item_title=mb_convert_encoding($item_title,$charset,$this->encoding);
  5450.         $item_description=mb_convert_encoding($item_description,$charset,$this->encoding);
  5451.         
  5452.         $return '<div style="margin:3px 12px;">';
  5453.             
  5454.             if($id != && is_array($extra_info))
  5455.                 $parent $extra_info['parent_item_id'];
  5456.             else
  5457.                 $parent 0;
  5458.             
  5459.             $sql "
  5460.                 SELECT *
  5461.                 FROM " $tbl_lp_item "
  5462.                 WHERE
  5463.                     lp_id = " $this->lp_id;
  5464.             
  5465.             $result api_sql_query($sql__FILE____LINE__);
  5466.             
  5467.             $arrLP array();
  5468.             
  5469.             while($row Database::fetch_array($result))
  5470.             {
  5471.                 $arrLP[array(
  5472.                     'id' => $row['id'],
  5473.                     'item_type' => $row['item_type'],
  5474.                     'title' => $row['title'],
  5475.                     'path' => $row['path'],
  5476.                     'description' => $row['description'],
  5477.                     'parent_item_id' => $row['parent_item_id'],
  5478.                     'previous_item_id' => $row['previous_item_id'],
  5479.                     'next_item_id' => $row['next_item_id'],
  5480.                     'display_order' => $row['display_order'],
  5481.                     'prerequisite' => $row['prerequisite']);
  5482.             }
  5483.             
  5484.             $this->tree_array($arrLP);
  5485.             
  5486.             $arrLP $this->arrMenu;
  5487.             
  5488.             unset($this->arrMenu);
  5489.             
  5490.             if($action == 'add')
  5491.                 $return .= '<p class="lp_title">'.get_lang("CreateTheForum").'&nbsp;:</p>' "\n";
  5492.             elseif($action == 'move')
  5493.                 $return .= '<p class="lp_title">'.get_lang("MoveTheCurrentForum").'&nbsp;:</p>' "\n";
  5494.             else
  5495.                 $return .= '<p class="lp_title">'.get_lang("EditCurrentForum").'&nbsp;:</p>' "\n";
  5496.             
  5497.             $return .= '<form method="POST">' "\n";
  5498.             
  5499.                 $return .= "\t" '<table cellpadding="0" cellspacing="0" class="lp_form">' "\n";
  5500.                 
  5501.                     $return .= "\t\t" '<tr>' "\n";
  5502.                     
  5503.                         $return .= "\t\t\t" '<td class="label"><label for="idParent">'.get_lang("Parent").'&nbsp;:</label></td>' "\n";
  5504.                         $return .= "\t\t\t" '<td class="input">' "\n";
  5505.                         
  5506.                             $return .= "\t\t\t\t" '<select id="idParent" name="parent" onchange="load_cbo(this.value);" size="1">';
  5507.                             
  5508.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">' $this->name . '</option>';
  5509.                                 
  5510.                                 $arrHide array($id);
  5511.                                 
  5512.                                 for($i 0$i count($arrLP)$i++)
  5513.                                 {
  5514.                                     if($action != 'add')
  5515.                                     {
  5516.                                         if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide))
  5517.                                         {
  5518.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  5519.                                         }
  5520.                                         else
  5521.                                         {
  5522.                                             $arrHide[$arrLP[$i]['id'];
  5523.                                         }
  5524.                                     }
  5525.                                     else
  5526.                                     {
  5527.                                         if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir')
  5528.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  5529.                                     }
  5530.                                 }
  5531.                                 
  5532.                                 reset($arrLP);
  5533.                                 
  5534.                             $return .= "\t\t\t\t" '</select>';
  5535.                         
  5536.                         $return .= "\t\t\t" '</td>' "\n";
  5537.                     
  5538.                     $return .= "\t\t" '</tr>' "\n";
  5539.                                     
  5540.                     $return .= "\t\t" '<tr>' "\n";
  5541.                         
  5542.                         $return .= "\t\t\t" '<td class="label"><label for="idPosition">'.get_lang("Position").'&nbsp;:</label></td>' "\n";
  5543.                         $return .= "\t\t\t" '<td class="input">' "\n";
  5544.                         
  5545.                             $return .= "\t\t\t\t" '<select id="idPosition" name="previous" size="1">';
  5546.                             
  5547.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">'.get_lang('FirstPosition').'</option>';
  5548.                                 
  5549.                                 for($i 0$i count($arrLP)$i++)
  5550.                                 {
  5551.                                     if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  5552.                                     {
  5553.                                         if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5554.                                             $selected 'selected="selected" ';
  5555.                                         elseif($action == 'add')
  5556.                                             $selected 'selected="selected" ';
  5557.                                         else
  5558.                                             $selected '';
  5559.                                         
  5560.                                         $return .= "\t\t\t\t\t" '<option ' $selected 'value="' $arrLP[$i]['id''">'.get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'"</option>';
  5561.                                     }
  5562.                                 }
  5563.                                 
  5564.                             $return .= "\t\t\t\t" '</select>';
  5565.                         
  5566.                         $return .= "\t\t\t" '</td>' "\n";
  5567.                     
  5568.                     $return .= "\t\t" '</tr>' "\n";
  5569.                     
  5570.                     if($action != 'move')
  5571.                     {
  5572.                         $return .= "\t\t" '<tr>' "\n";
  5573.                             
  5574.                             $return .= "\t\t\t" '<td class="label"><label for="idTitle">'.get_lang("Title").'&nbsp;:</label></td>' "\n";
  5575.                             $return .= "\t\t\t" '<td class="input"><input id="idTitle" name="title" type="text" value="' $item_title '" /></td>' "\n";
  5576.                         
  5577.                         $return .= "\t\t" '</tr>' "\n";
  5578.                         
  5579.                         $return .= "\t\t" '<tr>' "\n";
  5580.                             
  5581.                             //Remove temporaly the test description
  5582.                             //$return .= "\t\t\t" . '<td class="label"><label for="idDescription">'.get_lang("Description").' :</label></td>' . "\n";
  5583.                             //$return .= "\t\t\t" . '<td class="input"><textarea id="idDescription" name="description" rows="4">' . $item_description . '</textarea></td>' . "\n";
  5584.                         
  5585.                         $return .= "\t\t" '</tr>' "\n";
  5586.                         
  5587.                         $id_prerequisite=0;
  5588.                         foreach($arrLP as $key=>$value){
  5589.                             if($value['id']==$id){
  5590.                                 $id_prerequisite=$value['prerequisite'];
  5591.                                 break;
  5592.                             }
  5593.                         }
  5594.                         
  5595.                         $arrHide=array();
  5596.                         for($i 0$i count($arrLP)$i++)
  5597.                         {
  5598.                             if($arrLP[$i]['id'!= $id && $arrLP[$i]['item_type'!= 'dokeos_chapter')
  5599.                             {
  5600.                                 if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5601.                                     $s_selected_position=$arrLP[$i]['id'];
  5602.                                 elseif($action == 'add')
  5603.                                     $s_selected_position=0;
  5604.                                 $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  5605.                                 
  5606.                             }
  5607.                         }
  5608.                         
  5609.                         $return .= "\t\t" '<tr>' "\n";
  5610.                             
  5611.                             $return .= "\t\t\t" '<td class="label"><label for="idPrerequisites">'.get_lang("Prerequisites").'&nbsp;:</label></td>' "\n";
  5612.                             $return .= "\t\t\t" '<td class="input"><select name="prerequisites" id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"><option value="0">'.get_lang("NoPrerequisites").'</option>';
  5613.                             
  5614.                             foreach($arrHide as $key => $value){
  5615.                                 if($key==$s_selected_position && $action == 'add'){
  5616.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  5617.                                 }
  5618.                                 elseif($key==$id_prerequisite && $action == 'edit'){
  5619.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  5620.                                 }
  5621.                                 else{
  5622.                                     $return .= '<option value="'.$key.'">'.$value['value'].'</option>';
  5623.                                 }
  5624.                             }
  5625.                             
  5626.                             $return .= "</select></td>";
  5627.                         
  5628.                         $return .= "\t\t" '</tr>' "\n";
  5629.                         
  5630.                     }
  5631.                     
  5632.                     $return .= "\t\t" '<tr>' "\n";
  5633.                         
  5634.                         $return .= "\t\t\t" '<td colspan="2"><input class="button" name="submit_button" type="submit" value="'.get_lang('Ok').'" /></td>' "\n";
  5635.                     
  5636.                     $return .= "\t\t" '</tr>' "\n";
  5637.                 
  5638.                 $return .= "\t" '</table>' "\n";    
  5639.                 
  5640.                 if($action == 'move')
  5641.                 {
  5642.                     $return .= "\t" '<input name="title" type="hidden" value="' $item_title '" />' "\n";
  5643.                     $return .= "\t" '<input name="description" type="hidden" value="' $item_description '" />' "\n";
  5644.                 }
  5645.                 
  5646.                 if(is_numeric($extra_info))
  5647.                 {
  5648.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info '" />' "\n";
  5649.                 }
  5650.                 elseif(is_array($extra_info))
  5651.                 {
  5652.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info['path''" />' "\n";
  5653.                 }
  5654.                 
  5655.                 $return .= "\t" '<input name="type" type="hidden" value="'.TOOL_THREAD.'" />' "\n";
  5656.                 $return .= "\t" '<input name="post_time" type="hidden" value="' time('" />' "\n";
  5657.                 
  5658.             $return .= '</form>' "\n";
  5659.         
  5660.         $return .= '</div>' "\n";
  5661.         return $return;
  5662.     }
  5663.     
  5664.     /**
  5665.      * Enter description here...
  5666.      *
  5667.      * @param unknown_type $item_type 
  5668.      * @param unknown_type $title 
  5669.      * @param unknown_type $action 
  5670.      * @param unknown_type $id 
  5671.      * @param unknown_type $extra_info 
  5672.      * @return unknown 
  5673.      */
  5674.     function display_item_form($item_type$title ''$action 'add'$id 0$extra_info 'new')
  5675.     {
  5676.         global $_course;
  5677.         global $charset;
  5678.                 
  5679.         $tbl_lp_item Database::get_course_table('lp_item');
  5680.     
  5681.         if($id != && is_array($extra_info))
  5682.         {
  5683.             $item_title            $extra_info['title'];
  5684.             $item_description    $extra_info['description'];
  5685.             $item_path api_get_path(WEB_COURSE_PATH$_course['path'].'/scorm/'.$this->path.'/'.stripslashes($extra_info['path']);
  5686.         }
  5687.         else
  5688.         {
  5689.             $item_title            '';
  5690.             $item_description    '';
  5691.         }
  5692.         
  5693.         $return '<div style="margin:10px 12px;">';
  5694.             
  5695.         if($id != && is_array($extra_info))
  5696.             $parent $extra_info['parent_item_id'];
  5697.         else
  5698.             $parent 0;
  5699.         
  5700.         $sql "
  5701.             SELECT *
  5702.             FROM " $tbl_lp_item "
  5703.             WHERE lp_id = " $this->lp_id" AND id != " $id"    ";
  5704.         
  5705.         if($item_type == 'module')
  5706.             $sql .= " AND parent_item_id = 0";
  5707.         
  5708.         $result api_sql_query($sql__FILE____LINE__);        
  5709.         $arrLP array();
  5710.                 
  5711.         while($row Database::fetch_array($result))
  5712.         {
  5713.             $arrLP[array(
  5714.                 'id' => $row['id'],
  5715.                 'item_type' => $row['item_type'],
  5716.                 'title' => $row['title'],
  5717.                 'path' => $row['path'],
  5718.                 'description' => $row['description'],
  5719.                 'parent_item_id' => $row['parent_item_id'],
  5720.                 'previous_item_id' => $row['previous_item_id'],
  5721.                 'next_item_id' => $row['next_item_id'],
  5722.                 'display_order' => $row['display_order']);
  5723.         }
  5724.                 
  5725.         $this->tree_array($arrLP);        
  5726.         $arrLP $this->arrMenu;        
  5727.         unset($this->arrMenu);
  5728.             
  5729.         $return .= '<p class="lp_title">' $title '</p>' "\n";
  5730.         require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');        
  5731.         $form new FormValidator('form','POST',api_get_self()."?".$_SERVER["QUERY_STRING"]);
  5732.         
  5733.         $defaults["title"]=mb_convert_encoding($item_title,$charset,$this->encoding);
  5734.         $defaults["description"]=mb_convert_encoding($item_description,$charset,$this->encoding)
  5735.  
  5736.         $form->addElement('html',$return);
  5737.                     
  5738.         //$arrHide = array($id);
  5739.         
  5740.         $arrHide[0]['value']=$this->name;
  5741.         $arrHide[0]['padding']=3;
  5742.         
  5743.         if($item_type != 'module' && $item_type != 'dokeos_module')
  5744.         {
  5745.             for($i 0$i count($arrLP)$i++)
  5746.             {
  5747.                 if($action != 'add')
  5748.                 {
  5749.                     if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide))
  5750.                     {
  5751.                         $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  5752.                         $arrHide[$arrLP[$i]['id']]['padding']=3$arrLP[$i]['depth'10;
  5753.                         if($parent == $arrLP[$i]['id'])
  5754.                         {
  5755.                             $s_selected_parent=$arrHide[$arrLP[$i]['id']];
  5756.                         }
  5757.                     }
  5758.                 }
  5759.                 else
  5760.                 {
  5761.                     if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir')
  5762.                     {
  5763.                         $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  5764.                         $arrHide[$arrLP[$i]['id']]['padding']=3$arrLP[$i]['depth'10;
  5765.                         if($parent == $arrLP[$i]['id'])
  5766.                         {
  5767.                             $s_selected_parent=$arrHide[$arrLP[$i]['id']];
  5768.                         }
  5769.                     }
  5770.                 }
  5771.             }
  5772.             
  5773.             $parent_select &$form->addElement('select''parent'get_lang("Parent")."&nbsp;:"'''style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;" onchange="load_cbo(this.value);"');
  5774.  
  5775.             foreach($arrHide as $key => $value)
  5776.             {
  5777.                 $parent_select->addOption($value['value'],$key,'style="padding-left:'.$value['padding'].'px;"');
  5778.             }
  5779.             $parent_select -> setSelected($s_selected_parent);            
  5780.         }
  5781.         if(is_array($arrLP)) reset($arrLP)}
  5782.         
  5783.         $arrHide=array();
  5784.  
  5785.         //POSITION
  5786.         for($i 0$i count($arrLP)$i++)
  5787.         {
  5788.             if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  5789.             {
  5790.                 if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  5791.                     $s_selected_position=$arrLP[$i]['id'];
  5792.                 elseif($action == 'add')
  5793.                     $s_selected_position=$arrLP[$i]['id'];                
  5794.  
  5795.                 $arrHide[$arrLP[$i]['id']]['value']=get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  5796.                 
  5797.             }
  5798.         }
  5799.         
  5800.         $position &$form->addElement('select''previous'get_lang("Position")."&nbsp;:"'''id="idPosition" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"');
  5801.         
  5802.         $position->addOption(get_lang('FirstPosition'),0,'style="padding-left:'.$value['padding'].'px;"');
  5803.         
  5804.         foreach($arrHide as $key => $value)
  5805.         {
  5806.             $position->addOption($value['value'],$key,'style="padding-left:'.$value['padding'].'px;"');
  5807.         }
  5808.         
  5809.         if(!empty($s_selected_position)) $position->setSelected($s_selected_position)}
  5810.         
  5811.         if(is_array($arrLP)) reset($arrLP)}
  5812.         
  5813.         if($action != 'move')
  5814.         {
  5815.             $form->addElement('text','title'get_lang('Title').'&nbsp;:','id="idTitle" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; padding:1px 2px; width:300px;"');
  5816.             //$form->addElement('textarea','description',get_lang("Description").' :', 'id="idDescription"  style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; padding:1px 2px; width:300px;"');
  5817.         }
  5818.         else
  5819.         {
  5820.             $form->addElement('hidden','title');
  5821.         }
  5822.         
  5823.         $form->addElement('submit''submit_button'get_lang('Ok')'style="padding:1px 2px; width:75px;"');
  5824.         
  5825.         if($item_type == 'module' || $item_type == 'dokeos_module')
  5826.         {
  5827.             $form->addElement('hidden''parent''0');
  5828.         }        
  5829.  
  5830.         $extension pathinfo($item_pathPATHINFO_EXTENSION);
  5831.         if(($item_type=='asset' || $item_type=='sco'&& ($extension == 'html' || $extension == 'htm'))
  5832.         {
  5833.             if($item_type=='sco')
  5834.             {
  5835.                 $form->addElement('html','<script type="text/javascript">alert("'.get_lang('WarningWhenEditingScorm').'")</script>');
  5836.             }
  5837.             $renderer $form->defaultRenderer();
  5838.             $renderer->setElementTemplate('<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{label}<br />{element}','content_lp');
  5839.             $form->addElement('html_editor','content_lp','');
  5840.             //$form->addElement('html_editor','content_lp','');
  5841.             $defaults["content_lp"]=file_get_contents($item_path);
  5842.         }
  5843.  
  5844.         $form->addElement('hidden''type''dokeos_'.$item_type);
  5845.         $form->addElement('hidden''post_time'time());        
  5846.         $form->setDefaults($defaults);
  5847.         $form->addElement('html','</div>');
  5848.         return $form->return_form();
  5849.     }
  5850.     
  5851.     
  5852.     /**
  5853.      * Enter description here...
  5854.      *
  5855.      * @param unknown_type $action 
  5856.      * @param unknown_type $id 
  5857.      * @param unknown_type $extra_info 
  5858.      * @return unknown 
  5859.      */
  5860.     function display_document_form($action 'add'$id 0$extra_info 'new')
  5861.     {
  5862.         global $charset;
  5863.         echo '
  5864.         <style>
  5865.             div.row div.formw {                   
  5866.             width: 80%;                             
  5867.                    }
  5868.                       </style>';
  5869.             
  5870.         $tbl_lp_item Database::get_course_table('lp_item');
  5871.         $tbl_doc Database::get_course_table(TABLE_DOCUMENT);
  5872.         
  5873.         $path_parts pathinfo($extra_info['dir']);        
  5874.         $no_display_edit_textarea=false;
  5875.         
  5876.         //If action==edit document
  5877.         //We don't display the document form if it's not an editable document (html or txt file)
  5878.         if($action=="edit"){
  5879.             if(is_array($extra_info)){
  5880.                 if($path_parts['extension']!="txt" && $path_parts['extension']!="html"){
  5881.                     $no_display_edit_textarea=true;
  5882.                 }
  5883.             }
  5884.         }
  5885.         
  5886.         $no_display_add=false;
  5887.         
  5888.         //If action==add an existing document
  5889.         //We don't display the document form if it's not an editable document (html or txt file)
  5890.         if($action=="add"){
  5891.             if(is_numeric($extra_info)){
  5892.                 
  5893.                 $sql_doc "SELECT path FROM " $tbl_doc "WHERE id = " $extra_info;
  5894.                 $result=api_sql_query($sql_doc__FILE____LINE__);
  5895.                 $path_file=Database::result($result,0,0);                
  5896.                 
  5897.                 $path_parts pathinfo($path_file);
  5898.                 
  5899.                 if($path_parts['extension']!="txt" && $path_parts['extension']!="html"){
  5900.                     $no_display_add=true;
  5901.                 }
  5902.             }
  5903.         }
  5904.         
  5905.         if($id != && is_array($extra_info))
  5906.         {
  5907.             $item_title            stripslashes($extra_info['title']);
  5908.             $item_description    stripslashes($extra_info['description']);    
  5909.             if(empty($item_title))
  5910.             {                
  5911.                 $path_parts pathinfo($extra_info['path']);
  5912.                 $item_title stripslashes($path_parts['filename']);
  5913.             }
  5914.         }
  5915.         elseif(is_numeric($extra_info))
  5916.         {
  5917.             $sql_doc "
  5918.                 SELECT path, title
  5919.                 FROM " $tbl_doc "
  5920.                 WHERE id = " $extra_info;
  5921.             
  5922.             $result api_sql_query($sql_doc__FILE____LINE__);
  5923.             $row Database::fetch_array($result);
  5924.             
  5925.             $explode explode('.'$row['title']);
  5926.             
  5927.             if(count($explode)>1){
  5928.                 for($i 0$i count($explode1$i++)
  5929.                     $item_title .= $explode[$i];
  5930.             }
  5931.             else{
  5932.                 $item_title=$row['title'];
  5933.             }
  5934.             
  5935.             $item_title str_replace('_'' '$item_title);
  5936.             
  5937.             if(empty($item_title))
  5938.             {
  5939.                 $path_parts pathinfo($row['path']);
  5940.                 $item_title stripslashes($path_parts['filename']);
  5941.             }
  5942.             
  5943.         }
  5944.         else
  5945.         {
  5946.             $item_title            '';
  5947.             $item_description    '';
  5948.         }
  5949.             
  5950.         $return '<div style="margin:3px 12px;">';
  5951.             
  5952.             if($id != && is_array($extra_info))
  5953.                 $parent $extra_info['parent_item_id'];
  5954.             else
  5955.                 $parent 0;
  5956.             
  5957.             $sql "
  5958.                 SELECT *
  5959.                 FROM " $tbl_lp_item "
  5960.                 WHERE
  5961.                     lp_id = " $this->lp_id;
  5962.             
  5963.             $result api_sql_query($sql__FILE____LINE__);
  5964.             
  5965.             $arrLP array();
  5966.             
  5967.             while($row Database::fetch_array($result))
  5968.             {
  5969.                 $arrLP[array(
  5970.                     'id' => $row['id'],
  5971.                     'item_type' => $row['item_type'],
  5972.                     'title' => $row['title'],
  5973.                     'path' => $row['path'],
  5974.                     'description' => $row['description'],
  5975.                     'parent_item_id' => $row['parent_item_id'],
  5976.                     'previous_item_id' => $row['previous_item_id'],
  5977.                     'next_item_id' => $row['next_item_id'],
  5978.                     'display_order' => $row['display_order'],
  5979.                     'prerequisite' => $row['prerequisite']);
  5980.             }
  5981.             
  5982.             $this->tree_array($arrLP);
  5983.             
  5984.             $arrLP $this->arrMenu;
  5985.             
  5986.             unset($this->arrMenu);
  5987.             
  5988.             if($action == 'add')
  5989.             {
  5990.                 $return .= '<p class="lp_title">'.get_lang("CreateTheDocument").'&nbsp;:</p>' "\n";
  5991.             }
  5992.             elseif($action == 'move')
  5993.             {
  5994.                 $return .= '<p class="lp_title">'.get_lang("MoveTheCurrentDocument").'&nbsp;:</p>' "\n";
  5995.             }
  5996.             else
  5997.             {
  5998.                 $return .= '<p class="lp_title">'.get_lang("EditTheCurrentDocument").'&nbsp;:</p>' "\n";
  5999.             }
  6000.  
  6001.             $return .= '</div>';
  6002.  
  6003.             if(isset($_GET['edit']&& $_GET['edit'== 'true')
  6004.             {
  6005.                 $return .= '<div class="lp_message" style="margin-bottom:15px;">';                
  6006.                 $return .= '<p class="lp_title">'.get_lang("Warning").' !</p>';
  6007.                 $return .= get_lang("WarningEditingDocument");                
  6008.                 $return .= '</div>';
  6009.             }
  6010.             /*
  6011.             if($no_display_add==true){
  6012.                 $return .= '<div class="lp_message" style="margin-bottom:15px;">';
  6013.                 $return .= get_lang("CantEditDocument");
  6014.                 $return .= '</div>';
  6015.                 return $return;
  6016.             }
  6017.             */
  6018.             require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
  6019.             
  6020.             $form new FormValidator('form','POST',api_get_self()."?".$_SERVER["QUERY_STRING"]);
  6021.             $defaults["title"]=mb_convert_encoding($item_title,$charset,$this->encoding);
  6022.             $defaults["description"]=mb_convert_encoding($item_description,$charset,$this->encoding);            
  6023.             
  6024.         
  6025.             $form->addElement('html',$return);
  6026.                         
  6027.             //$arrHide = array($id);
  6028.             
  6029.             $arrHide[0]['value']=$this->name;
  6030.             $arrHide[0]['padding']=3;
  6031.             
  6032.             for($i 0$i count($arrLP)$i++)
  6033.             {
  6034.                 if($action != 'add'){
  6035.                     if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide)){
  6036.                         $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  6037.                         $arrHide[$arrLP[$i]['id']]['padding']=3$arrLP[$i]['depth'10;
  6038.                         if($parent == $arrLP[$i]['id']){
  6039.                             $s_selected_parent=$arrHide[$arrLP[$i]['id']];
  6040.                         }
  6041.                     }
  6042.                 }
  6043.                 else{
  6044.                     if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'){
  6045.                         $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  6046.                         $arrHide[$arrLP[$i]['id']]['padding']=3$arrLP[$i]['depth'10;
  6047.                         if($parent == $arrLP[$i]['id']){
  6048.                             $s_selected_parent=$arrHide[$arrLP[$i]['id']];
  6049.                         }
  6050.                     }
  6051.                 }
  6052.             }
  6053.             $parent_select &$form->addElement('select''parent'get_lang("Parent")."&nbsp;:"'''style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;" onchange="load_cbo(this.value);"');
  6054.  
  6055.             foreach($arrHide as $key => $value)
  6056.             {
  6057.                 $parent_select->addOption($value['value'],$key,'style="padding-left:'.$value['padding'].'px;"');
  6058.             }
  6059.             $parent_select -> setSelected($parent);
  6060.             if(is_array($arrLP))
  6061.             {
  6062.                 reset($arrLP);
  6063.             }
  6064.             
  6065.             $arrHide=array();
  6066.             
  6067.             //POSITION
  6068.             for($i 0$i count($arrLP)$i++)
  6069.             {
  6070.                 if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  6071.                 {
  6072.                     if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  6073.                         $s_selected_position=$arrLP[$i]['id'];
  6074.                     elseif($action == 'add')
  6075.                         $s_selected_position=$arrLP[$i]['id'];
  6076.                     
  6077.                     $arrHide[$arrLP[$i]['id']]['value']=get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding).'"';
  6078.                     
  6079.                 }
  6080.             }
  6081.             
  6082.             $position &$form->addElement('select''previous'get_lang("Position")."&nbsp;:"'''id="idPosition" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; padding:1px 2px; width:300px;"');
  6083.             $position->addOption(get_lang("FirstPosition"),0,'style="padding-left:3px;"');
  6084.             
  6085.             foreach($arrHide as $key => $value)
  6086.             {
  6087.                 $position->addOption($value['value'],$key,'style="padding-left:'.$value['padding'].'px;"');
  6088.             }
  6089.             $position -> setSelected($s_selected_position);
  6090.             if(is_array($arrLP))
  6091.             {
  6092.                 reset($arrLP);
  6093.             }
  6094.             
  6095.             if($action != 'move')
  6096.             {
  6097.                 $form->addElement('text','title'get_lang('Title').'&nbsp;:','id="idTitle" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:295px;"');
  6098.  
  6099.                 
  6100.                 $id_prerequisite=0;
  6101.                 if(is_array($arrLP))
  6102.                 {
  6103.                     foreach($arrLP as $key=>$value){
  6104.                         if($value['id']==$id){
  6105.                             $id_prerequisite=$value['prerequisite'];
  6106.                             break;
  6107.                         }
  6108.                     }
  6109.                 }
  6110.  
  6111.                 $select_prerequisites=$form->addElement('select''prerequisites'get_lang('Prerequisites').'&nbsp;:''''id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"');
  6112.                 $select_prerequisites->addOption(get_lang("NoPrerequisites"),0,'style="padding-left:3px;"');
  6113.                 
  6114.                 $arrHide=array();
  6115.  
  6116.                 for($i 0$i count($arrLP)$i++)
  6117.                 {
  6118.                     if($arrLP[$i]['id'!= $id && $arrLP[$i]['item_type'!= 'dokeos_chapter')
  6119.                     {
  6120.                         if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  6121.                             $s_selected_position=$arrLP[$i]['id'];
  6122.                         elseif($action == 'add')
  6123.                             $s_selected_position=$arrLP[$i]['id'];
  6124.                         
  6125.                         $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  6126.                         
  6127.                     }
  6128.                 }
  6129.                 
  6130.                 foreach($arrHide as $key => $value){
  6131.                     $select_prerequisites->addOption($value['value'],$key,'style="padding-left:'.$value['padding'].'px;"');
  6132.                     if($key==$s_selected_position && $action == 'add'){
  6133.                         $select_prerequisites -> setSelected(0);
  6134.                     }
  6135.                     elseif($key==$id_prerequisite && $action == 'edit'){
  6136.                         $select_prerequisites -> setSelected($id_prerequisite);
  6137.                     }
  6138.                 }
  6139.                 
  6140.                 if(!$no_display_add)
  6141.                 {
  6142.                     if(($extra_info == 'new' || $extra_info['item_type'== TOOL_DOCUMENT || $_GET['edit'== 'true'))
  6143.                     {
  6144.                         
  6145.                         if(isset($_POST['content']))
  6146.                             $content stripslashes($_POST['content']);
  6147.                         elseif(is_array($extra_info)){
  6148.                             //If it's an html document or a text file
  6149.                             if(!$no_display_edit_textarea){
  6150.                                 $content $this->display_document($extra_info['path']falsefalse);
  6151.                             }
  6152.                         }
  6153.                         elseif(is_numeric($extra_info))
  6154.                             $content $this->display_document($extra_infofalsefalse);
  6155.                         else
  6156.                             $content '';
  6157.                         
  6158.                         $form->addElement('submit''submit_button'get_lang('Ok')'style="padding:1px 2px; width:75px;"');
  6159.                         
  6160.                         if(!$no_display_edit_textarea)
  6161.                         {
  6162.                             $renderer $form->defaultRenderer();
  6163.                             $renderer->setElementTemplate('<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{label}<br />{element}','content_lp');
  6164.  
  6165.                             $form->addElement('html','<div style="margin:3px 12px">');
  6166.                             $form->addElement('html_editor','content_lp','');
  6167.                             $form->addElement('html','</div>');
  6168.                             $defaults["content_lp"]=$content;
  6169.                         }
  6170.                         
  6171.                     }
  6172.                     
  6173.                     elseif(is_numeric($extra_info))
  6174.                     {
  6175.             
  6176.                         $form->addElement('submit''submit_button'get_lang('Ok')'style="padding:1px 2px; width:75px;"');
  6177.             
  6178.                         $return $this->display_document($extra_infotruetruetrue);
  6179.                         $form->addElement('html',$return);
  6180.                     }
  6181.                 }
  6182.                 
  6183.             }
  6184.             if($action == 'move')
  6185.             {
  6186.                 $form->addElement('hidden''title'$item_title);
  6187.                 $form->addElement('hidden''description'$item_description);
  6188.             }
  6189.             if(is_numeric($extra_info))
  6190.             {
  6191.                 $form->addElement('submit''submit_button'get_lang('Ok')'style="padding:1px 2px; width:75px;"');
  6192.                 $form->addElement('hidden''path'$extra_info);
  6193.             }
  6194.             elseif(is_array($extra_info))
  6195.             {
  6196.                 $form->addElement('submit''submit_button'get_lang('Ok')'style="padding:1px 2px; width:75px;"');
  6197.                 $form->addElement('hidden''path'$extra_info['path']);
  6198.             }
  6199.             
  6200.             $form->addElement('hidden''type'TOOL_DOCUMENT);
  6201.             $form->addElement('hidden''post_time'time());
  6202.             
  6203.     
  6204.      
  6205.         $form->setDefaults($defaults);    
  6206.         
  6207.         
  6208.         return $form->return_form();
  6209.     }
  6210.     
  6211.     /**
  6212.      * Enter description here...
  6213.      *
  6214.      * @param unknown_type $action 
  6215.      * @param unknown_type $id 
  6216.      * @param unknown_type $extra_info 
  6217.      */
  6218.     function display_link_form($action 'add'$id 0$extra_info '')
  6219.     {
  6220.         global $charset;
  6221.         $tbl_lp_item Database::get_course_table('lp_item');
  6222.         $tbl_link Database::get_course_table(TABLE_LINK);
  6223.         
  6224.         if($id != && is_array($extra_info))
  6225.         {
  6226.             $item_title            stripslashes($extra_info['title']);
  6227.             $item_description    stripslashes($extra_info['description']);
  6228.         }
  6229.         elseif(is_numeric($extra_info))
  6230.         {
  6231.             $sql_link "
  6232.                 SELECT
  6233.                     title,
  6234.                     description,
  6235.                     url
  6236.                 FROM " $tbl_link "
  6237.                 WHERE id = " $extra_info;
  6238.             
  6239.             $result api_sql_query($sql_link__FILE____LINE__);
  6240.             $row Database::fetch_array($result);
  6241.             
  6242.             $item_title $row['title'];
  6243.             
  6244.             $item_description $row['description'];
  6245.             $item_url $row['url'];
  6246.         }
  6247.         else
  6248.         {
  6249.             $item_title            '';
  6250.             $item_description    '';
  6251.         }
  6252.         $item_title=mb_convert_encoding($item_title,$charset,$this->encoding);
  6253.         $item_description=mb_convert_encoding($item_description,$charset,$this->encoding);
  6254.                 
  6255.         $return '<div style="margin:3px 12px;">';
  6256.             
  6257.             if($id != && is_array($extra_info))
  6258.                 $parent $extra_info['parent_item_id'];
  6259.             else
  6260.                 $parent 0;
  6261.             
  6262.             $sql "
  6263.                 SELECT *
  6264.                 FROM " $tbl_lp_item "
  6265.                 WHERE
  6266.                     lp_id = " $this->lp_id;
  6267.             
  6268.             $result api_sql_query($sql__FILE____LINE__);
  6269.             
  6270.             $arrLP array();
  6271.             
  6272.             while($row Database::fetch_array($result))
  6273.             {
  6274.                 $arrLP[array(
  6275.                     'id' => $row['id'],
  6276.                     'item_type' => $row['item_type'],
  6277.                     'title' => $row['title'],
  6278.                     'path' => $row['path'],
  6279.                     'description' => $row['description'],
  6280.                     'parent_item_id' => $row['parent_item_id'],
  6281.                     'previous_item_id' => $row['previous_item_id'],
  6282.                     'next_item_id' => $row['next_item_id'],
  6283.                     'display_order' => $row['display_order'],
  6284.                     'prerequisite' => $row['prerequisite']);
  6285.             }
  6286.             
  6287.             $this->tree_array($arrLP);            
  6288.             $arrLP $this->arrMenu;            
  6289.             unset($this->arrMenu);
  6290.             
  6291.             if($action == 'add')
  6292.                 $return .= '<p class="lp_title">'.get_lang("CreateTheLink").'&nbsp;:</p>' "\n";
  6293.             elseif($action == 'move')
  6294.                 $return .= '<p class="lp_title">'.get_lang("MoveCurrentLink").'&nbsp;:</p>' "\n";
  6295.             else
  6296.                 $return .= '<p class="lp_title">'.get_lang("EditCurrentLink").'&nbsp;:</p>' "\n";
  6297.             
  6298.             $return .= '<form method="POST">' "\n";
  6299.             
  6300.                 $return .= "\t" '<table cellpadding="0" cellspacing="0" class="lp_form">' "\n";
  6301.                 
  6302.                     $return .= "\t\t" '<tr>' "\n";
  6303.                     
  6304.                         $return .= "\t\t\t" '<td class="label"><label for="idParent">'.get_lang("Parent").' :</label></td>' "\n";
  6305.                         $return .= "\t\t\t" '<td class="input">' "\n";
  6306.                         
  6307.                             $return .= "\t\t\t\t" '<select id="idParent" name="parent" onchange="load_cbo(this.value);" size="1">';
  6308.                             
  6309.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">' $this->name . '</option>';
  6310.                                 
  6311.                                 $arrHide array($id);
  6312.                                 
  6313.                                 for($i 0$i count($arrLP)$i++)
  6314.                                 {
  6315.                                     if($action != 'add')
  6316.                                     {
  6317.                                         if(($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir'&& !in_array($arrLP[$i]['id']$arrHide&& !in_array($arrLP[$i]['parent_item_id']$arrHide))
  6318.                                         {
  6319.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  6320.                                         }
  6321.                                         else
  6322.                                         {
  6323.                                             $arrHide[$arrLP[$i]['id'];
  6324.                                         }
  6325.                                     }
  6326.                                     else
  6327.                                     {
  6328.                                         if($arrLP[$i]['item_type'== 'dokeos_module' || $arrLP[$i]['item_type'== 'dokeos_chapter' || $arrLP[$i]['item_type'== 'dir')
  6329.                                             $return .= "\t\t\t\t\t" '<option ' (($parent == $arrLP[$i]['id']'selected="selected" ' '''style="padding-left:' ($arrLP[$i]['depth'10'px;" value="' $arrLP[$i]['id''">' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'</option>';
  6330.                                     }
  6331.                                 }
  6332.                                 
  6333.                                 reset($arrLP);
  6334.                                 
  6335.                             $return .= "\t\t\t\t" '</select>';
  6336.                         
  6337.                         $return .= "\t\t\t" '</td>' "\n";
  6338.                     
  6339.                     $return .= "\t\t" '</tr>' "\n";
  6340.                                     
  6341.                     $return .= "\t\t" '<tr>' "\n";
  6342.                         
  6343.                         $return .= "\t\t\t" '<td class="label"><label for="idPosition">'.get_lang("Position").' :</label></td>' "\n";
  6344.                         $return .= "\t\t\t" '<td class="input">' "\n";
  6345.                         
  6346.                             $return .= "\t\t\t\t" '<select id="idPosition" name="previous" size="1">';
  6347.                             
  6348.                                 $return .= "\t\t\t\t\t" '<option class="top" value="0">'.get_lang("FirstPosition").'</option>';
  6349.                                 
  6350.                                 for($i 0$i count($arrLP)$i++)
  6351.                                 {
  6352.                                     if($arrLP[$i]['parent_item_id'== $parent && $arrLP[$i]['id'!= $id)
  6353.                                     {
  6354.                                         if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  6355.                                             $selected 'selected="selected" ';
  6356.                                         elseif($action == 'add')
  6357.                                             $selected 'selected="selected" ';
  6358.                                         else
  6359.                                             $selected '';
  6360.                                         
  6361.                                         $return .= "\t\t\t\t\t" '<option ' $selected 'value="' $arrLP[$i]['id''">'.get_lang("After").' "' mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding'"</option>';
  6362.                                     }
  6363.                                 }
  6364.                                 
  6365.                             $return .= "\t\t\t\t" '</select>';
  6366.                         
  6367.                         $return .= "\t\t\t" '</td>' "\n";
  6368.                     
  6369.                     $return .= "\t\t" '</tr>' "\n";
  6370.                     
  6371.                     if($action != 'move')
  6372.                     {
  6373.                         $return .= "\t\t" '<tr>' "\n";
  6374.                             
  6375.                             $return .= "\t\t\t" '<td class="label"><label for="idTitle">'.get_lang("Title").' :</label></td>' "\n";
  6376.                             $return .= "\t\t\t" '<td class="input"><input id="idTitle" name="title" type="text" value="' $item_title '" /></td>' "\n";
  6377.                         
  6378.                         $return .= "\t\t" '</tr>' "\n";
  6379.                         
  6380.                         $return .= "\t\t" '<tr>' "\n";
  6381.                             
  6382.                             $return .= "\t\t\t" '<td class="label"><label for="idDescription">'.get_lang("Description").' :</label></td>' "\n";
  6383.                             $return .= "\t\t\t" '<td class="input"><textarea id="idDescription" name="description" rows="4">' $item_description '</textarea></td>' "\n";
  6384.                         
  6385.                         $return .= "\t\t" '</tr>' "\n";
  6386.                         
  6387.                         $return .= "\t\t" '<tr>' "\n";
  6388.                             
  6389.                             $return .= "\t\t\t" '<td class="label"><label for="idURL">'.get_lang("Url").' :</label></td>' "\n";
  6390.                             $return .= "\t\t\t" '<td class="input"><input' (is_numeric($extra_info' disabled="disabled"' ''' id="idURL" name="url" type="text" value="' $item_url '" /></td>' "\n";
  6391.                         
  6392.                         $return .= "\t\t" '</tr>' "\n";
  6393.                         
  6394.                         $id_prerequisite=0;
  6395.                         foreach($arrLP as $key=>$value){
  6396.                             if($value['id']==$id){
  6397.                                 $id_prerequisite=$value['prerequisite'];
  6398.                                 break;
  6399.                             }
  6400.                         }
  6401.                         
  6402.                         $arrHide=array();
  6403.                         for($i 0$i count($arrLP)$i++)
  6404.                         {
  6405.                             if($arrLP[$i]['id'!= $id && $arrLP[$i]['item_type'!= 'dokeos_chapter')
  6406.                             {
  6407.                                 if($extra_info['previous_item_id'== $arrLP[$i]['id'])
  6408.                                     $s_selected_position=$arrLP[$i]['id'];
  6409.                                 elseif($action == 'add')
  6410.                                     $s_selected_position=0;
  6411.                                 $arrHide[$arrLP[$i]['id']]['value']=mb_convert_encoding($arrLP[$i]['title'],$charset,$this->encoding);
  6412.                                 
  6413.                             }
  6414.                         }
  6415.                         
  6416.                         $return .= "\t\t" '<tr>' "\n";
  6417.                             
  6418.                             $return .= "\t\t\t" '<td class="label"><label for="idPrerequisites">'.get_lang("Prerequisites").' :</label></td>' "\n";
  6419.                             $return .= "\t\t\t" '<td class="input"><select name="prerequisites" id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"><option value="0">'.get_lang("NoPrerequisites").'</option>';
  6420.                             
  6421.                             foreach($arrHide as $key => $value)
  6422.                             {
  6423.                                 if($key==$s_selected_position && $action == 'add')
  6424.                                 {
  6425.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  6426.                                 }
  6427.                                 elseif($key==$id_prerequisite && $action == 'edit'){
  6428.                                     $return .= '<option value="'.$key.'" selected="selected">'.$value['value'].'</option>';
  6429.                                 }
  6430.                                 else{
  6431.                                     $return .= '<option value="'.$key.'">'.$value['value'].'</option>';
  6432.                                 }
  6433.                             }
  6434.                             
  6435.                             $return .= "</select></td>";
  6436.                         
  6437.                         $return .= "\t\t" '</tr>' "\n";
  6438.                                 
  6439.                     }
  6440.                     
  6441.                     $return .= "\t\t" '<tr>' "\n";
  6442.                         
  6443.                         $return .= "\t\t\t" '<td colspan="2"><input class="button" name="submit_button" type="submit" value="'.get_lang("Ok").'" /></td>' "\n";
  6444.                     
  6445.                     $return .= "\t\t" '</tr>' "\n";
  6446.                 
  6447.                 $return .= "\t" '</table>' "\n";    
  6448.                 
  6449.                 if($action == 'move')
  6450.                 {
  6451.                     $return .= "\t" '<input name="title" type="hidden" value="' $item_title '" />' "\n";
  6452.                     $return .= "\t" '<input name="description" type="hidden" value="' $item_description '" />' "\n";
  6453.                 }
  6454.                 
  6455.                 if(is_numeric($extra_info))
  6456.                 {
  6457.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info '" />' "\n";
  6458.                 }
  6459.                 elseif(is_array($extra_info))
  6460.                 {
  6461.                     $return .= "\t" '<input name="path" type="hidden" value="' $extra_info['path''" />' "\n";
  6462.                 }
  6463.                 
  6464.                 $return .= "\t" '<input name="type" type="hidden" value="'.TOOL_LINK.'" />' "\n";
  6465.                 $return .= "\t" '<input name="post_time" type="hidden" value="' time('" />' "\n";
  6466.                 
  6467.             $return .= '</form>' "\n";
  6468.         
  6469.         $return .= '</div>' "\n";
  6470.         
  6471.         return $return;
  6472.     }
  6473.     
  6474.     /**
  6475.      * Enter description here...
  6476.      *
  6477.      * @param unknown_type $action 
  6478.      * @param unknown_type $id 
  6479.      * @param unknown_type $extra_info 
  6480.      * @return unknown 
  6481.      */
  6482.     function display_student_publication_form($action 'add'$id 0$extra_info '')
  6483.     {
  6484.         global $charset;
  6485.         
  6486.         $tbl_lp_item Database::get_course_table('lp_item');
  6487.         $tbl_publication Database::get_course_table(TABLE_STUDENT_PUBLICATION);
  6488.         
  6489.         if($id != && is_array($extra_info))
  6490.         {
  6491.             $item_title            stripslashes($extra_info['title']);
  6492.             $item_description    stripslashes($extra_info['description']);
  6493.         }
  6494.         elseif(is_numeric($extra_info))
  6495.         {
  6496.             $sql_publication "
  6497.                 SELECT
  6498.                     title,
  6499.                     description
  6500.                 FROM " $tbl_publication "
  6501.                 WHERE id = " $extra_info;
  6502.             
  6503.             $result api_sql_query(