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

Source for file learnpath_functions.inc.php

Documentation is available at learnpath_functions.inc.php

  1. <?php
  2. /*
  3. ============================================================================== 
  4.     Dokeos - elearning and course management software
  5.     
  6.     Copyright (c) 2004-2005 Dokeos S.A.
  7.     Copyright (c) 2003 Ghent University (UGent)
  8.     Copyright (c) 2001 Universite catholique de Louvain (UCL)
  9.     Copyright (c) Denes Nagy
  10.     Copyright (c) Yannick Warnier
  11.     
  12.     For a full list of contributors, see "credits.txt".
  13.     The full license can be read in "license.txt".
  14.     
  15.     This program is free software; you can redistribute it and/or
  16.     modify it under the terms of the GNU General Public License
  17.     as published by the Free Software Foundation; either version 2
  18.     of the License, or (at your option) any later version.
  19.     
  20.     See the GNU General Public License for more details.
  21.     
  22.     Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
  23.     Mail: info@dokeos.com
  24. ==============================================================================
  25. */
  26. /**
  27. ==============================================================================
  28. * This is a function library for the learning path.
  29. *
  30. * Due to the face that the learning path has been built upon the resoucelinker,
  31. * naming conventions have changed at least 2 times. You can see here in order the :
  32. * 1. name used in the first version of the resourcelinker
  33. * 2. name used in the first version of the LP
  34. * 3. name used in the second (current) version of the LP
  35. *
  36. *       1.       2.        3.
  37. *   Category = Chapter = Module
  38. *   Item (?) = Item    = Step
  39. *
  40. @author  Denes Nagy <darkden@evk.bke.hu>, main author
  41. @author  Roan Embrechts, some code cleaning
  42. @author    Yannick Warnier <yannick.warnier@dokeos.com>, multi-level learnpath behaviour + new SCORM tool
  43. @access  public
  44. @package dokeos.learnpath
  45. @todo rename functions to coding conventions: not deleteitem but delete_item, etc
  46. @todo rewrite functions to comply with phpDocumentor
  47. @todo remove code duplication
  48. ============================================================================== 
  49. */
  50.  
  51. /**
  52.  * This function deletes an item
  53.  * @param integer     $id: the item we want to delete
  54.  * @return boolean    True if item was deleted, false if not found or error
  55.  ***/
  56. function deleteitem($id)
  57. {
  58.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  59.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  60.     //get the display order for this item before it is deleted
  61.     $sql "SELECT display_order, parent_item_id FROM $tbl_lp_item WHERE id=$id";
  62.     $result api_sql_query($sql__FILE____LINE__);
  63.     if (mysql_num_rows($result== 0)
  64.     {
  65.         return false;
  66.     }
  67.     $row mysql_fetch_row($result);
  68.     $display_order $row[0];
  69.     $parent_item_id $row[1];
  70.     // delete the item
  71.     $sql "DELETE FROM $tbl_learnpath_item WHERE id='$id'";
  72.     $result api_sql_query($sql__FILE____LINE__);
  73.     if ($result === false)
  74.     {
  75.         return false;
  76.     }
  77.     // update the other items and chapters
  78.     $sql "UPDATE $tbl_learnpath_item SET display_order = display_order-1 WHERE display_order > $display_order AND parent_item_id = $parent_item_id";
  79.     $result api_sql_query($sql__FILE____LINE__);
  80.     $sql "UPDATE $tbl_learnpath_chapter SET display_order = display_order-1 WHERE display_order > $display_order AND parent_item_id = $parent_item_id";
  81.     $result api_sql_query($sql__FILE____LINE__);
  82.     //return
  83.     return true;
  84. }
  85.  
  86. /**
  87.  * This function deletes a module(chapter) and all its steps(items).
  88.  *
  89.  * @param integer id of the chapter we want to delete
  90.  * @return boolean    True on success and false if not found or error
  91.  ***/
  92. function deletemodule($parent_item_id)
  93. {
  94.     global $learnpath_id;
  95.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  96.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  97.  
  98.     //Added for multi-level behaviour - slightly recursive
  99.     $sql "SELECT * FROM $tbl_learnpath_chapter WHERE lp_id=$learnpath_id";
  100.     $result api_sql_query($sql__FILE____LINE__);
  101.     while ($row mysql_fetch_array($result))
  102.     {
  103.         if ($row['parent_item_id'== $parent_item_id)
  104.         {
  105.             //delete every subchapter
  106.             if (deletemodule($row['id']=== false)
  107.             {
  108.                 return false;
  109.             }
  110.         }
  111.     }
  112.  
  113.     //get this chapter's display order
  114.     $sql "SELECT display_order, parent_item_id FROM $tbl_learnpath_chapter WHERE id=$parent_item_id and lp_id=$learnpath_id";
  115.     $result api_sql_query($sql__FILE____LINE__);
  116.     if (mysql_num_rows($result== 0)
  117.     {
  118.         return false;
  119.     }
  120.     $row mysql_fetch_row($result);
  121.  
  122.     $display_order $row[0];
  123.     $parent_id $row[1];
  124.  
  125.     //delete the chapter itself
  126.     $sql "DELETE FROM $tbl_learnpath_chapter WHERE (id=$parent_item_id and lp_id=$learnpath_id)";
  127.     $result api_sql_query($sql__FILE____LINE__);
  128.     //delete items from that chapter
  129.     $sql2 "DELETE FROM $tbl_learnpath_item WHERE parent_item_id=$parent_item_id";
  130.     $result api_sql_query($sql2__FILE____LINE__);
  131.  
  132.     //update all other chapters accordingly
  133.     $sql "UPDATE $tbl_learnpath_item SET display_order = display_order-1 WHERE display_order > $display_order AND parent_item_id = $parent_id";
  134.     $result api_sql_query($sql__FILE____LINE__);
  135.     $sql "UPDATE $tbl_learnpath_chapter SET display_order = display_order-1 WHERE display_order > $display_order AND parent_item_id = $parent_id";
  136.     $result api_sql_query($sql__FILE____LINE__);
  137.  
  138.     return true;
  139. }
  140.  
  141. /**
  142.  * This function deletes an entire path.
  143.  *
  144.  * @param integer     $id: the path we want to delete
  145.  * @return    void 
  146.  ***/
  147. function deletepath($path_id)
  148. {
  149.     $tbl_learnpath_main Database :: get_course_table(TABLE_LEARNPATH_MAIN);
  150.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  151.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  152.  
  153.     $sql "DELETE FROM $tbl_learnpath_main WHERE lp_id='$path_id'";
  154.     $result api_sql_query($sql__FILE____LINE__);
  155.  
  156.     //@TODO check how this function is used before uncommenting the following
  157.     //also delete all elements inside that path
  158.     $sql "SELECT * FROM $tbl_learnpath_chapter WHERE lp_id=$path_id";
  159.     $result api_sql_query($sql__FILE____LINE__);
  160.     while ($row mysql_fetch_array($result))
  161.     {
  162.         deletemodule($row['id']);
  163.     }
  164. }
  165.  
  166. /**
  167.  * This function moves an item.
  168.  *
  169.  * @param string    $direction: move the given chapter up or down
  170.  * @param integer   Item ID
  171.  * @param integer   $moduleid: the id of the chapter the element resides in
  172.  * @return    boolean    Returns false on error
  173.  * @note    With this new version, the moveitem deals with items AND directories (not the base-level modules). This is a lot more complicated but is a temporary step towards new database structure as 'everything is an item'
  174.  ***/
  175. function moveitem($direction$id$moduleid$type 'item')
  176. {
  177.     global $learnpath_id;
  178.     $tbl_learnpath_item     Database::get_course_table(TABLE_LEARNPATH_ITEM);
  179.     $tbl_learnpath_chapter  Database::get_course_table(TABLE_LEARNPATH_CHAPTER);
  180.  
  181.     $tree get_learnpath_tree($learnpath_id);
  182.     $orig_order 0;
  183.     $orig_type '';
  184.     $orig_id $id;
  185.     foreach ($tree[$moduleidas $row)
  186.     {
  187.         //if this is the element we want (be it a chapter or an item), get its data
  188.         if (($row['id'== $id&& ($row['type'== $type))
  189.         {
  190.             $orig_order $row['display_order'];
  191.             $orig_type $row['type'];
  192.             break;
  193.         }
  194.     }
  195.  
  196.     $dest_order 0;
  197.     $dest_type '';
  198.     $dest_id 0;
  199.     if ($direction == "up")
  200.     {
  201.         if (!empty ($tree[$moduleid][$orig_order -1]))
  202.         {
  203.             $dest_order $orig_order -1;
  204.             $dest_type $tree[$moduleid][$orig_order -1]['type'];
  205.             $dest_id $tree[$moduleid][$orig_order -1]['id'];
  206.         }
  207.         else
  208.         {
  209.             return false;
  210.         }
  211.     }
  212.     else
  213.     {
  214.         //move down
  215.         if (!empty ($tree[$moduleid][$orig_order +1]))
  216.         {
  217.             $dest_order $orig_order +1;
  218.             $dest_type $tree[$moduleid][$orig_order +1]['type'];
  219.             $dest_id $tree[$moduleid][$orig_order +1]['id'];
  220.         }
  221.         else
  222.         {
  223.             return false;
  224.         }
  225.     }
  226.  
  227.     $sql1 '';
  228.     $sql2 '';
  229.     if ($orig_type == 'chapter')
  230.     {
  231.         $sql1 "UPDATE $tbl_learnpath_chapter SET display_order = ".$dest_order." WHERE (id=$orig_id and parent_item_id=$moduleid)";
  232.     }
  233.     elseif ($orig_type == 'item')
  234.     {
  235.         $sql1 "UPDATE $tbl_learnpath_item SET display_order = ".$dest_order." WHERE (id=$orig_id and parent_item_id=$moduleid)";
  236.     }
  237.     else
  238.     {
  239.         return false;
  240.     }
  241.  
  242.     if ($dest_type == 'chapter')
  243.     {
  244.         $sql2 "UPDATE $tbl_learnpath_chapter SET display_order = ".$orig_order." WHERE (id='$dest_id' and parent_item_id=$moduleid)";
  245.     }
  246.     elseif ($dest_type == 'item')
  247.     {
  248.         $sql2 "UPDATE $tbl_learnpath_item SET display_order = ".$orig_order." WHERE (id='$dest_id' and parent_item_id=$moduleid)";
  249.     }
  250.     else
  251.     {
  252.         return false;
  253.     }
  254.     api_sql_query($sql1__FILE____LINE__);
  255.     api_sql_query($sql2__FILE____LINE__);
  256. }
  257.  
  258. /**
  259.  * This function moves a module (also called chapter or category).
  260.  *
  261.  * @param   string $direction: move the given chapter up or down
  262.  * @param   integer $id: the id of the chapter we want to move
  263.  * @return    void 
  264.  ***/
  265. function movemodule($direction$id)
  266. {
  267.     global $learnpath_id;
  268.     $tbl_learnpath_chapter Database :: get_course_learnpath_chapter_table();
  269.     if ($direction == "up")
  270.     {
  271.         $sortDirection "DESC";
  272.     }
  273.     else
  274.     {
  275.         $sortDirection "ASC";
  276.     }
  277.  
  278.     // Select all chapters of first level (parent_item_id = 0)
  279.     $sql "SELECT * FROM $tbl_learnpath_chapter where (lp_id=$learnpath_id AND parent_item_id = 0) ORDER BY display_order $sortDirection";
  280.     $result api_sql_query($sql__FILE____LINE__);
  281.     $previousrow "";
  282.  
  283.     // see similar comment in moveitem() function
  284.     // @TODO: this only works for chapters in multi-level mode. Why not gather
  285.     // this function and moveitem to keep only one multi-uses function?
  286.     while ($row mysql_fetch_array($result))
  287.     {
  288.         // step 2: performing the move (only happens when passed trhough step 1 at least once)
  289.         if (!empty ($this_cat_order))
  290.         {
  291.             $next_cat_order $row["display_order"];
  292.             $next_cat_id $row["id"];
  293.  
  294.             $sql1 "UPDATE $tbl_learnpath_chapter SET display_order = '$next_cat_order' WHERE (id='$this_cat_id' and lp_id=$learnpath_id)";
  295.             $sql2 "UPDATE $tbl_learnpath_chapter SET display_order = '$this_cat_order' WHERE (id='$next_cat_id' and lp_id=$learnpath_id)";
  296.             api_sql_query($sql1__FILE____LINE__);
  297.             api_sql_query($sql2__FILE____LINE__);
  298.             unset ($this_cat_order);
  299.             unset ($this_cat_id);
  300.             unset ($next_cat_order);
  301.             unset ($next_cat_id);
  302.             break;
  303.         }
  304.  
  305.         // step 1: looking for the order of the row we want to move
  306.         if ($row["id"== $id)
  307.         {
  308.             $this_cat_order $row["display_order"];
  309.             $this_cat_id $id;
  310.         }
  311.     }
  312.  
  313. }
  314.  
  315. /**
  316.  * Inserts a new element in a learnpath table (item or chapter)
  317.  * @param        string    Element type ('chapter' or 'item')
  318.  * @param        string    Chapter name
  319.  * @param        string    Chapter description (optional)
  320.  * @param        integer    Parent chapter ID (default: 0)
  321.  * @param        integer Learnpath ID
  322.  * @param        mixed        If type 'item', then array(prereq_id=>value, prereq_..)
  323.  * @return    integer    The new chapter ID, or false on failure
  324.  * @TODO    Finish this function before it is used. Currently only chapters can be added using it.
  325.  * @note This function is currently never used!
  326.  */
  327. function insert_item($type 'item'$name$chapter_description ''$parent_id 0$learnpath_id 0$params null)
  328. {
  329.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  330.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  331.  
  332.     // getting the last order number from the chapters table, in this learnpath, for the parent chapter given
  333.     $sql "SELECT * FROM $tbl_learnpath_chapter 
  334.             WHERE lp_id=$learnpath_id 
  335.             AND parent_item_id = $parent_id
  336.             ORDER BY display_order DESC";
  337.     $result api_sql_query($sql__FILE____LINE__);
  338.     $row mysql_fetch_array($result);
  339.     $last_chapter_order $row["display_order"];
  340.  
  341.     // getting the last order number of the items
  342.     $sql "SELECT * FROM $tbl_learnpath_item 
  343.             AND parent_item_id = $parent_id
  344.             ORDER BY display_order DESC";
  345.     $result api_sql_query($sql__FILE____LINE__);
  346.     $row mysql_fetch_array($result);
  347.     $last_item_order $row["display_order"];
  348.     $new_order max($last_chapter_order$last_item_order1;
  349.  
  350.     if ($type === 'chapter')
  351.     {
  352.         $sql "INSERT INTO $tbl_learnpath_chapter 
  353.                         (lp_id, chapter_name, chapter_description, display_order) 
  354.                         VALUES ('".domesticate($learnpath_id)."', 
  355.                         '".domesticate(htmlspecialchars($chapter_name))."',
  356.                         '".domesticate(htmlspecialchars($chapter_description))."', 
  357.                         $new_order )";
  358.         $result api_sql_query($sql__FILE____LINE__);
  359.         if ($result === false)
  360.         {
  361.             return false;
  362.         }
  363.         $id Database :: get_last_insert_id();
  364.     }
  365.     elseif ($type === 'item')
  366.     {
  367.         $sql "INSERT INTO $tbl_learnpath_item 
  368.                         (parent_item_id, item_type, item_id, display_order) 
  369.                         VALUES ('".domesticate($parent_id)."', 
  370.                         '".domesticate(htmlspecialchars($item_type))."',
  371.                         '".domesticate(htmlspecialchars($item_id))."', 
  372.                         $new_order )";
  373.         $result api_sql_query($sql__FILE____LINE__);
  374.         if ($result === false)
  375.         {
  376.             return false;
  377.         }
  378.         $id Database :: get_last_insert_id();
  379.     }
  380.     return $id;
  381. }
  382.  
  383. /**
  384.  * This function returns an array with all the learnpath categories/chapters
  385.  * @return array List of learnpath chapter titles
  386.  ***/
  387. {
  388.     #global $tbl_learnpath_chapter; 
  389.     global $learnpath_id;
  390.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  391.  
  392.     $sql "SELECT * FROM  $tbl_learnpath_chapter  WHERE (lp_id=$learnpath_id) ORDER BY display_order ASC";
  393.     $result api_sql_query($sql__FILE____LINE__);
  394.  
  395.     while ($row mysql_fetch_array($result))
  396.     {
  397.         $array_learnpath_categories[array ($row["id"]$row["chapter_name"]);
  398.     }
  399.     //$array_learnpath_categories=array($array_learnpath_categories_name,$array_learnpath_categories_id);
  400.     return $array_learnpath_categories;
  401. }
  402.  
  403. /**
  404. * Displays the learnpath chapters(=modules,categories) and their contents.
  405. @param    integer     Chapter ID to display now (enables recursive behaviour)
  406. @param    array       The array as returned by get_learnpath_tree, with all the elements of a learnpath compiled and structured into the array, by chapter id
  407. @param    integer     Level (the depth of the call - helps in display)
  408. @todo eliminate all global $lang declarations, use get_lang, improve structure.
  409. @author   Denes Nagy
  410. @author   Roan Embrechts
  411. @author   Yannick Warnier <yannick.warnier@dokeos.com> - complete redesign for multi-level learnpath chapters
  412. */
  413. function display_learnpath_chapters($parent_item_id 0$tree array ()$level 0)
  414. {
  415.     //error_log('New LP - In learnpath_functions::display_learnpath_chapters',0);
  416.     global $color2;
  417.     global $xml_output;
  418.     global $learnpath_id;
  419.     $tbl_lp_item Database::get_course_table('lp_item');
  420.     
  421.     
  422.     // @todo: coding standards: Language variables are CaMMelCaSe, all other variables should use the underscoring method.
  423.     $lang_move_down get_lang('_move_down');
  424.     $lang_move_up get_lang('lang_move_up');
  425.     $lang_edit_learnpath_module get_lang('lang_edit_learnpath_module');
  426.     $lang_delete_learnpath_module get_lang('lang_delete_learnpath_module');
  427.     $lang_nochapters get_lang('lang_nochapters');
  428.     $lang_prerequisites get_lang('lang_prerequisites');
  429.     $lang_prerequisites_limit get_lang('lang_prerequisites_limit');
  430.     $lang_add_learnpath_item get_lang('lang_add_learnpath_item');
  431.     $lang_add_item get_lang('lang_add_item');
  432.     $lang_title_and_desc get_lang('lang_title_and_desc');
  433.     $lang_change_order get_lang('lang_change_order');
  434.     $lang_add_prereqi get_lang('lang_add_prereqi');
  435.     $lang_add_title_and_desc get_lang('lang_add_title_and_desc');
  436.     $lang_delete get_lang('Delete');
  437.  
  438.     if ($parent_item_id === 0)
  439.     {
  440.         // this is the first time we use the function, define the tree and display learnpath name
  441.  
  442.         $tree get_learnpath_tree($learnpath_id);
  443.  
  444.         $num_modules count($tree);
  445.         //$num_modules=mysql_num_rows($result);
  446.         if ($num_modules == 0)
  447.         {
  448.             // do not diplay useless information
  449.             //echo "<tr><td>&nbsp;$lang_nochapters</td></tr>";
  450.         }
  451.         else
  452.         {
  453.             echo "  <tr align='center' valign='top'>\n"."    <td><b>&nbsp;$lang_title_and_desc </b></td>\n"."    <td><b>&nbsp;$lang_add_item </b></td>\n";
  454.             if (is_prereq($learnpath_id))
  455.             {
  456.                 echo "    <td bgcolor='#ddddee'><b>&nbsp;$lang_prerequisites_limit </b></td>\n";
  457.             }
  458.             else
  459.                 echo "    <td><b>&nbsp;$lang_prerequisites </b></td>\n";
  460.  
  461.             echo "    <td colspan='2'><b>&nbsp;$lang_change_order </b></td><td><b>&nbsp;$lang_add_prereqi </b></td>\n"."    <td><b>&nbsp;$lang_add_title_and_desc </b></td><td><b>&nbsp;$lang_delete </b></td>\n"."  </tr>\n";
  462.         }
  463.     }
  464.  
  465.     $i 1;
  466.     $counter 0;
  467.     $num_modules count($tree[$parent_item_id]);
  468.  
  469.     //while ($row=mysql_fetch_array($result))
  470.     if (isset ($tree[$parent_item_id]))
  471.     {
  472.         foreach ($tree[$parent_item_idas $row)
  473.         {
  474.             if ($row['item_type'=== 'dokeos_chapter')
  475.             {
  476.                 $xml_output .= "<chapter>";
  477.                 $xml_output .= "<chaptertitle>".$row["title"]."</chaptertitle>";
  478.                 $xml_output .= "<chapterdescription>".$row["description"]."</chapterdescription>";
  479.  
  480.                 $counter ++;
  481.                 if (($counter 2== 0)
  482.                 {
  483.                     $oddclass "row_odd";
  484.                 }
  485.                 else
  486.                 {
  487.                     $oddclass "row_even";
  488.                 }
  489.  
  490.                 //echo '<tr class="'.$oddclass.'">'."\n".'  <td>'.str_repeat("&nbsp;&gt;", $level)."<img src='../img/documents.gif' alt='folder'/><a href='".api_get_self()."?lp_id=$learnpath_id&item_id={$row['id']}&action=add&type=learnpathitem&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9'><b>&nbsp;".$row['title']."</b></a>"."<br /><i><div align='justify'>&nbsp;".str_repeat("&nbsp;&nbsp;&nbsp;", $level)."</i></td>\n".'  <td  align="center"><a href="'.api_get_self()."?lp_id=$learnpath_id&item_id={$row['id']}&action=add&type=learnpathitem&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9"><img src='../img/0.gif' width='13' height='13' border='0' title='$lang_add_learnpath_item'></a></td>\n"."  <td";
  491.                 echo '<tr class="'.$oddclass.'">'."\n".'  <td>'.str_repeat("&nbsp;&gt;"$level)."<img src='../img/documents.gif' alt='folder'/><a href='".api_get_self()."?lp_id=$learnpath_id&parent_item_id=".$row['id']."&action=add_sub_item'><b>&nbsp;".$row['title']."</b></a>"."<br /><i><div align='justify'>&nbsp;".str_repeat("&nbsp;&nbsp;&nbsp;"$level)."</i></td>\n".'  <td  align="center"><a href="'.api_get_self()."?lp_id=$learnpath_id&parent_item_id=".$row['id']."&action=add_sub_item\"><img src='../img/0.gif' width='13' height='13' border='0' title='$lang_add_learnpath_item'></a></td>\n"."  <td";
  492.                 if (is_prereq($learnpath_id))
  493.                 {
  494.                     echo " bgcolor='#ddddee'";
  495.                 }
  496.                 echo ">".$row['prerequisite']."</td>\n";
  497.  
  498.                 // showing the edit, delete and move icons
  499.                 if (is_allowed_to_edit())
  500.                 {
  501.                     $myaction 'move_item';
  502.                     if ($i $num_modules)
  503.                     {
  504.  
  505.                         // if we are still under the number of chapters in this section, show "move down"
  506.                         //echo "  <td align=center>"."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=".$myaction."&amp;direction=down&amp;moduleid=".$parent_item_id."&amp;id=".$row["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/down.gif\" border=\"0\" title=\"$lang_move_down\">"."</a></td>\n";
  507.                         echo "  <td align=center>"."<a href='".api_get_self()."?lp_id=$learnpath_id&action=".$myaction."&direction=down&moduleid=".$parent_item_id."&id=".$row["id"]."'>"."<img src=\"../img/down.gif\" border=\"0\" title=\"$lang_move_down\">"."</a></td>\n";
  508.                     }
  509.                     else
  510.                     {
  511.                         echo '  <td align="center">&nbsp;</td>'."\n";
  512.                     }
  513.  
  514.                     if ($i 1)
  515.                     {
  516.                         //echo '  <td align="center">'."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=".$myaction."&amp;direction=up&amp;moduleid=".$parent_item_id."&amp;id=".$row["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/up.gif\" border=\"0\" title=\"$lang_move_up\">"."</a>"."</td>\n";
  517.                         echo '  <td align="center">'."<a href='".api_get_self()."?lp_id=$learnpath_id&action=".$myaction."&direction=up&moduleid=".$parent_item_id."&id=".$row["id"]."'>"."<img src=\"../img/up.gif\" border=\"0\" title=\"$lang_move_up\">"."</a>"."</td>\n";
  518.                     }
  519.                     else
  520.                     {
  521.                         echo '  <td align="center">&nbsp;</td>'."\n";
  522.                     }
  523.  
  524.                     echo "  <td align='center'>&nbsp;</td>\n";
  525.                     //echo "  <td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=editmodule&amp;id=".$row["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/edit.gif\" border=\"0\" title=\"$lang_edit_learnpath_module\">"."</a>"."</td>\n";
  526.                     echo "  <td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&action=edititem&id=".$row["id"]."'>"."<img src=\"../img/edit.gif\" border=\"0\" title=\"$lang_edit_learnpath_module\">"."</a>"."</td>\n";
  527.                     
  528.                     //echo "  <td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=deletemodule&amp;id=".$row["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9 onclick=\"return confirmation('".$row['chapter_name']."');\">"."<img src=\"../img/delete.gif\" border=\"0\" title=\"$lang_delete_learnpath_module\">"."</a>"."</td>\n";
  529.                     echo "  <td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&action=delete_item&id=".$row["id"]."' onclick=\"return confirmation('".$row['title']."');\">"."<img src=\"../img/delete.gif\" border=\"0\" title=\"$lang_delete_learnpath_module\">"."</a>"."</td>\n";
  530.                 }
  531.  
  532.                 echo "</tr>\n";
  533.                 $i ++;
  534.  
  535.                 $xml_output .= "<items>";
  536.  
  537.                 #display_learnpath_items($row["id"]);
  538.                 display_learnpath_chapters($row['id']$tree$level +1);
  539.  
  540.                 $xml_output .= "</items>";
  541.                 $xml_output .= "</chapter>";
  542.  
  543.             }
  544.             else //if //($row['item_type'] === 'item')
  545.             {
  546.                 $row_items $row;
  547.                 echo "<tr>\n  <td colspan='2' valign='top'>";
  548.                 //require('resourcelinker.inc.php');
  549.                 display_addedresource_link_in_learnpath($row_items["item_type"]$row_items["ref"]''$row_items["id"]'builder''icon'$level);
  550.  
  551.                 if ($row_items["description"])
  552.                 {
  553.                     echo "<div align='justify'><font color='#999999'>&nbsp;&nbsp;&nbsp;{$row_items['description']}</font>";
  554.                 }
  555.  
  556.                 echo "</td>";
  557.  
  558.                 if (is_prereq($learnpath_id))
  559.                 {
  560.                     echo '<td bgcolor="#EEEEFF">';
  561.                 }
  562.                 else
  563.                 {
  564.                     echo "<td>";
  565.                 }
  566.  
  567.                 if (is_allowed_to_edit())
  568.                 {
  569.  
  570.                     if ($row_items["prerequisite"<> '')
  571.                     {
  572.                         $prereq $row_items["prerequisite"];
  573.  
  574.                         //if ($row_items["prereq_type"] == 'i')
  575.                         //{
  576.                             //item
  577.                             $sql_items2 "SELECT * FROM $tbl_lp_item WHERE id='$prereq'"//check if prereq has been deleted
  578.                             $result_items2 api_sql_query($sql_items2__FILE____LINE__);
  579.                             $number_items2 Database::num_rows($result_items2);
  580.                             if ($number_items2 == 0)
  581.                             {
  582.                                 echo "<font color='red'>$lang_prereq_deleted_error</font>";
  583.                             }
  584.                             $row_items2 mysql_fetch_array($result_items2);
  585.                             display_addedresource_link_in_learnpath($row_items2["item_type"]$row_items2["ref"]''$row_items2["id"]'builder'''0);
  586.                             if ((($row_items2["item_type"== TOOL_QUIZor ($row_items2["item_type"== 'HotPotatoes')) and ($row_items['prerequisite']))
  587.                             {
  588.                                 //echo "&nbsp;({$row_items2['title']})";
  589.                             }
  590.                         //}
  591.                         /*
  592.                         if ($row_items["prereq_type"] == 'c')
  593.                         {
  594.                             //chapter
  595.                             $sql_items2 = "SELECT * FROM $tbl_lp_item WHERE id='$prereq' AND item_type='dokeos_chapter'"; //check if prereq has been deleted
  596.                             $result_items2 = api_sql_query($sql_items2, __FILE__, __LINE__);
  597.                             $number_items2 = Database::num_rows($result_items2);
  598.                             if ($number_items2 == 0)
  599.                             {
  600.                                 echo "<font color='red'>$lang_prereq_deleted_error</font>";
  601.                             }
  602.                             $row_items2 = mysql_fetch_array($result_items2);
  603.                             echo " {$row_items2['title']}";
  604.                         }*/
  605.                     }
  606.                     echo "</font></td>";
  607.                     $xml_output .= "<element_type>".$row_items["item_type"]."</element_type>";
  608.                     $xml_output .= "<element_id>".$row_items["item_id"]."</element_id>";
  609.  
  610.                     // move
  611.                     if ($i $num_modules)
  612.                     {
  613.                         echo "<td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=moveitem&amp;type=item&amp;direction=down&amp;moduleid=".$parent_item_id."&amp;id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/down.gif\" border=\"0\" title=\"$lang_move_down\">"."</a>"."</td>";
  614.                     }
  615.                     else
  616.                     {
  617.                         echo "<td width='30' align='center'>&nbsp;</td>";
  618.                     }
  619.  
  620.                     if ($i 1)
  621.                     {
  622.                         echo "<td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=moveitem&amp;type=item&amp;direction=up&amp;moduleid=".$parent_item_id."&amp;id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/up.gif\" border=\"0\" title=\"$lang_move_up\">"."</a>";
  623.                     }
  624.                     else
  625.                     {
  626.                         echo "<td width='30' align='center'>&nbsp;</td>";
  627.                     }
  628.                     echo "</td>"."<td align='center'>";
  629.  
  630.                     // edit prereq
  631.                     echo "<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=edititemprereq&amp;id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/scormpre.gif\" border=\"0\" title=\"$lang_add_prereq\">"."</a>"."</td>";
  632.  
  633.                     // edit
  634.                     echo "<td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&amp;action=edititem&amp;id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/edit.gif\" border=\"0\" title=\"$lang_edit_learnpath_item\">"."</a>"."</td>";
  635.  
  636.                     // delete
  637.                     echo "<td align='center'>"."<a href='".api_get_self()."?lp_id=$learnpath_id&action=deleteitem&id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>"."<img src=\"../img/delete.gif\" border=\"0\" title=\"$lang_delete_learnpath_item\" onclick=\"return confirmation('".$row_items["item_type"]."');\">"."</a>";
  638.                 }
  639.                 $i ++;
  640.                 echo "</td></tr>";
  641.  
  642.             }
  643.         }
  644.     }
  645. }
  646.  
  647. /**
  648.  * Displays all learning paths.
  649.  * @return    void 
  650.  * @todo eliminate all global $lang declarations, use get_lang, improve structure.
  651.  */
  652. {
  653.     global $tbl_tool$color2;
  654.     global $xml_output$lang_edit_learnpath$lang_delete_learnpath$lang_publish$lang_no_publish$lang_add_learnpath_chapter_to_path;
  655.     $tbl_learnpath_main Database :: get_course_table(TABLE_LEARNPATH_MAIN);
  656.  
  657.     $sql "SELECT * FROM  $tbl_learnpath_main  ORDER BY learnpath_name";
  658.     $result api_sql_query($sql__FILE____LINE__);
  659.     $i 1;
  660.     $num_modules mysql_num_rows($result);
  661.  
  662.     while ($row mysql_fetch_array($result))
  663.     {
  664.         //other grey color : #E6E6E6
  665.         echo "<tr><td bgcolor=\"$color2\" width=400><b>&nbsp;";
  666.         echo "<a href='learnpath_handler.php?&lp_id={$row['lp_id']}'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9>{$row['learnpath_name']}</a>";
  667.         echo "</b><br><i><div class=text align=justify>{$row['learnpath_description']}</div></i></td>";
  668.  
  669.         // showing the edit, delete and publish icons
  670.         if (is_allowed_to_edit())
  671.         {
  672.             echo "<td bgcolor=\"$color2\" align=center><a href='learnpath_handler.php?lp_id={$row['lp_id']}&action=add&type=learnpathcategory'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src='../img/0.gif' width='13' height='13' border='0' title='$lang_add_learnpath_chapter_to_path'></a></td>";
  673.             echo "<td bgcolor=\"$color2\" align=center><a href='".api_get_self()."?action=editpath&id=".$row["lp_id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/edit.gif\" border=\"0\" title=\"$lang_edit_learnpath\"></a></td>";
  674.             echo "<td bgcolor=\"$color2\" align=center><a href='".api_get_self()."?action=deletepath&id=".$row["lp_id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/delete.gif\" border=\"0\" title=\"$lang_delete_learnpath\" onclick=\"return confirmation('".$row2['learnpath_name']."');\"></a></td>";
  675.             $id $row["lp_id"];
  676.             $sql2 "SELECT * FROM $tbl_learnpath_main where lp_id=$id";
  677.             $result2 api_sql_query($sql2__FILE____LINE__);
  678.             $row2 mysql_fetch_array($result2);
  679.             $name $row2['learnpath_name'];
  680.             $sql3 "SELECT * FROM $tbl_tool where (name=\"$name\" and image='scormbuilder.gif')";
  681.             $result3 api_sql_query($sql3__FILE____LINE__);
  682.             $row3 mysql_fetch_array($result3);
  683.             if (($row3["visibility"]== '1')
  684.             {
  685.                 echo "<td bgcolor=\"$color2\" align=center><a href='".api_get_self()."?action=publishpath&set=i&id=".$row["lp_id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/visible.gif\" border=\"0\" title=\"$lang_no_publish\"></a></td>";
  686.             }
  687.             else
  688.             {
  689.                 echo "<td bgcolor=\"$color2\" align=center><a href='".api_get_self()."?action=publishpath&set=v&id=".$row["lp_id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/invisible.gif\" border=\"0\" title=\"$lang_publish\"></a></td>";
  690.             }
  691.         }
  692.         $i ++;
  693.         echo "<tr><td>&nbsp;</td></tr>";
  694.     }
  695. }
  696.  
  697. /**
  698.  * Displays the learning path items/steps.
  699.  * @param        integer        Category ID
  700.  * @return    void 
  701.  * @todo eliminate all global $lang declarations, use get_lang, improve structure.
  702.  */
  703. function display_learnpath_items($categoryid)
  704. {
  705.     global $xml_output;
  706.     global $lang_prerequisites$lang_move_down$lang_move_up$lang_edit_learnpath_item$lang_delete_learnpath_item$learnpath_id$lang_add_prereq$lang_prereq_deleted_error$lang_pre_short$langThisItem;
  707.     $tbl_lp_item Database::get_course_table('lp_item');
  708.  
  709.     $sql_items "SELECT * FROM $tbl_lp_item WHERE parent_item_id='$categoryid' ORDER BY display_order ASC";
  710.     $result_items api_sql_query($sql_items,__FILE__,__LINE__);
  711.     $number_items Database::num_rows($result_items);
  712.     $i 1;
  713.     error_log('Selected item under '.$categoryid,0);
  714.  
  715.     while ($row_items Database::fetch_array($result_items))
  716.     {
  717.         echo "<tr><td colspan='2' valign='top'>";
  718.         display_addedresource_link_in_learnpath($row_items["item_type"]$row_items["ref"]''$row_items["id"]'builder''icon');
  719.         if ($row_items["description"])
  720.         {
  721.             echo "<div align='justify'><font color='#999999'>&nbsp;&nbsp;&nbsp;{$row_items['description']}</font>";
  722.         }
  723.         echo "</td>";
  724.         if (is_prereq($learnpath_id))
  725.         {
  726.             echo '<td bgcolor="#EEEEFF">';
  727.         }
  728.         else
  729.         {
  730.             echo "<td>";
  731.         }
  732.  
  733.         if (is_allowed_to_edit())
  734.         {
  735.             error_log('Is allowed to edit item'.$row_items['id'],0);
  736.             //TODO: fix by adding true prerequisites parsing (and cycle through)
  737.             //Over simplification here, we transform prereq_id field into prerequisite field
  738.             if ($row_items["prerequisite"<> '')
  739.             {
  740.                 $prereq $row_items["prerequisite"];
  741.  
  742.                 //if ($row_items["prereq_type"] == 'i')
  743.                 //{
  744.                     //item
  745.                     $sql_items2 "SELECT * FROM $tbl_lp_item WHERE id='$prereq'"//check if prereq has been deleted
  746.                     $result_items2 api_sql_query($sql_items2);
  747.                     $number_items2 Database::num_rows($result_items2);
  748.                     if ($number_items2 == 0)
  749.                     {
  750.                         echo "<font color=red>$lang_prereq_deleted_error</font>";
  751.                     }
  752.                     $row_items2 Database::fetch_array($result_items2);
  753.                     display_addedresource_link_in_learnpath($row_items2["item_type"]$row_items2["ref"]''$row_items2["id"]'builder''');
  754.                     if ((($row_items2["item_type"== 'Exercise'or ($row_items2["item_type"== 'HotPotatoes')) and ($row_items['prerequisites']))
  755.                     {
  756.                         echo "&nbsp;({$row_items2['title']})";
  757.                     }
  758.                 //}
  759.                 /*if ($row_items["prereq_type"] == 'c')
  760.                 {
  761.                     //chapter
  762.                     $sql_items2 = "SELECT * FROM $tbl_learnpath_chapter WHERE id='$prereq'"; //check if prereq has been deleted
  763.                     $result_items2 = api_sql_query($sql_items2,__FILE__,__LINE__);
  764.                     $number_items2 = Database::num_rows($result_items2);
  765.                     if ($number_items2 == 0)
  766.                     {
  767.                         echo "<font color=red>$lang_prereq_deleted_error</font>";
  768.                     }
  769.                     $row_items2 = Database::fetch_array($result_items2);
  770.                     echo " {$row_items2['chapter_name']}";
  771.                 }*/
  772.             }
  773.             echo "</font></td>";
  774.             $xml_output .= "<element_type>".$row_items["item_type"]."</element_type>";
  775.             $xml_output .= "<element_id>".$row_items["id"]."</element_id>";
  776.  
  777.             // move
  778.             if ($i $number_items)
  779.             {
  780.                 echo "<td align='center'><a href='".api_get_self()."?lp_id=$learnpath_id&action=moveitem&direction=down&moduleid=".$categoryid."&id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/down.gif\" border=\"0\" title=\"$lang_move_down\"></a></td>";
  781.             }
  782.             else
  783.             {
  784.                 echo "<td width='30' align='center'>&nbsp;</td>";
  785.             }
  786.  
  787.             if ($i 1)
  788.             {
  789.                 echo "<td align='center'><a href='".api_get_self()."?lp_id=$learnpath_id&action=moveitem&direction=up&moduleid=".$categoryid."&id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/up.gif\" border=\"0\" title=\"$lang_move_up\"></a>";
  790.             }
  791.             else
  792.             {
  793.                 echo "<td width='30' align='center'>&nbsp;</td>";
  794.             }
  795.             echo "</td><td align='center'>";
  796.  
  797.             // edit prereq
  798.             echo "<a href='".api_get_self()."?lp_id=$learnpath_id&action=edititemprereq&id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/scormpre.gif\" border=\"0\" title=\"$lang_add_prereq\"></a></td>";
  799.  
  800.             // edit
  801.             echo "<td align='center'><a href='".api_get_self()."?lp_id=$learnpath_id&action=edititem&id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/edit.gif\" border=\"0\" title=\"$lang_edit_learnpath_item\"></a></td>";
  802.  
  803.             // delete
  804.             echo "<td align='center'>";
  805.             echo "<a href='".api_get_self()."?lp_id=$learnpath_id&action=deleteitem&id=".$row_items["id"]."'&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9><img src=\"../img/delete.gif\" border=\"0\" title=\"$lang_delete_learnpath_item\" onclick=\"return confirmation('".$langThisItem."');\"></a>";
  806.         }
  807.         $i ++;
  808.         echo "</td></tr>";
  809.     }
  810. }
  811.  
  812. /**
  813.  * This function returns the items belonging to the chapter that contains the given item (brother items)
  814.  * @param    integer    Item id
  815.  * @return    array        Table containing the items
  816.  */
  817. function learnpath_items($itemid)
  818. {
  819.     global $xml_output;
  820.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  821.  
  822.     $sql_items "SELECT parent_item_id FROM $tbl_lp_item WHERE id='$itemid'";
  823.     $moduleid_sql api_sql_query($sql_items);
  824.     $moduleid_array mysql_fetch_array($moduleid_sql)//first row of the results
  825.     $moduleid $moduleid_array["parent_item_id"];
  826.  
  827.     $sql_items "SELECT * FROM $tbl_lp_item WHERE parent_item_id='$moduleid' ORDER BY display_order ASC";
  828.     $result_items api_sql_query($sql_items);
  829.     $ar mysql_fetch_array($result_items);
  830.     while ($ar != '')
  831.     {
  832.         $result[$ar;
  833.         $ar mysql_fetch_array($result_items);
  834.     }
  835.     return $result;
  836.  
  837. }
  838.  
  839. /**
  840.  * This function returns the chapters belonging to the path that contais the given chapter (brother chapters)
  841.  * @param    integer    Learnpath id
  842.  * @return array        Table containing the chapters
  843.  */
  844. function learnpath_chapters($learnpath_id)
  845. {
  846.     global $xml_output$learnpath_id;
  847.     //$tbl_learnpath_chapter = Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  848.     $tbl_lp_item Database::get_course_table('lp_item');
  849.     
  850.  
  851.     $sql_items "SELECT * FROM $tbl_lp_item WHERE lp_id='$learnpath_id' AND item_type='dokeos_chapter' ORDER BY display_order ASC";
  852.     //$sql_items = "SELECT * FROM $tbl_learnpath_chapter WHERE lp_id='$learnpath_id' ORDER BY display_order ASC";
  853.     $result_items api_sql_query($sql_items__FILE____LINE__);
  854.     $ar mysql_fetch_array($result_items);
  855.     while ($ar != '')
  856.     {
  857.         $result[$ar;
  858.         $ar mysql_fetch_array($result_items);
  859.     }
  860.     return $result;
  861.  
  862. }
  863.  
  864. /**
  865.  * This function tells if a learnpath contains items which are prerequisite to other items
  866.  * @param    integer    Learnpath id
  867.  * @return    boolean    True if this learnpath contains an item which is a prerequisite to something
  868.  */
  869. function is_prereq($learnpath_id)
  870. {
  871.     global $xml_output;
  872.     $tbl_lp_item Database::get_course_table('lp_item');
  873.     
  874.     $prereq false;
  875.  
  876.     $sql_items "SELECT * FROM $tbl_lp_item WHERE lp_id='$learnpath_id' AND parent_item_id=0 ORDER BY display_order ASC";
  877.     $result_items api_sql_query($sql_items,__FILE__,__LINE__);
  878.     while ($ar Database::fetch_array($result_items))
  879.     {
  880.         $c $ar['id'];
  881.         $sql_items2 "SELECT * FROM $tbl_lp_item WHERE lp_id = $learnpath_id AND parent_item_id='$c' ORDER BY display_order ASC";
  882.         $result_items2 api_sql_query($sql_items2,__FILE__,__LINE__);
  883.         while ($ar2 Database::fetch_array($result_items2))
  884.         {
  885.             if ($ar2['prerequisite'!= '')
  886.             {
  887.                 $prereq true;
  888.             }
  889.         }
  890.     }
  891.     return ($prereq);
  892. }
  893.  
  894. /**
  895.  * This function returns the prerequisite sentence
  896.  * @param    integer    Item ID
  897.  * @return    string     Prerequisite warning text
  898.  */
  899. function prereqcheck($id_in_path)
  900. {
  901.     //1 Initialise and import working vars
  902.     global $learnpath_id$_user;
  903.     global $langPrereqToEnter$langPrereqTestLimit1$langPrereqTestLimit2$langPrereqTestLimitNow$langPrereqFirstNeedTo$langPrereqModuleMinimum1$langPrereqModuleMinimum2;
  904.     $tbl_learnpath_user Database :: get_course_table(TABLE_LEARNPATH_USER);
  905.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  906.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  907.  
  908.     //2 Initialise return value
  909.     $prereq false;
  910.  
  911.     //3 Get item data from the database
  912.     $sql_items "SELECT * FROM $tbl_learnpath_item WHERE id='$id_in_path'";
  913.     $result_items api_sql_query($sql_items);
  914.     $row mysql_fetch_array($result_items);
  915.     //4 Check prerequisite's type
  916.     if ($row['prereq_type'== 'i')
  917.     {
  918.         //4.a If prerequisite is of type 'i' (item)
  919.         //4.a.1 Get data ready for use
  920.         $id_in_path3 $row['prereq_id'];
  921.         $prereq_limit $row['prereq_completion_limit'];
  922.  
  923.         //4.a.2 Get data from the user-item relation
  924.         if ($_user['user_id'== '')
  925.         {
  926.             $user_id '0';
  927.         }
  928.         else
  929.         {
  930.             $user_id $_user['user_id'];
  931.         }
  932.         $sql_items3 "SELECT * FROM $tbl_learnpath_user WHERE (learnpath_item_id='$id_in_path3' and user_id=$user_id)";
  933.         $result_items3 api_sql_query($sql_items3);
  934.         $row3 mysql_fetch_array($result_items3);
  935.  
  936.         //4.a.3 Get the link that needs to be shown for the current item (not the prereq)
  937.         $stepname display_addedresource_link_in_learnpath($row['item_type']$row['ref']''$id_in_path'builder''nolink');
  938.         //this is the step we want to open
  939.         $stepname trim($stepname)//to remove occasional line breaks and white spaces
  940.  
  941.         //4.a.4 Get the prerequisite item
  942.         $sql6 "SELECT * FROM $tbl_learnpath_item WHERE (id='$id_in_path3')";
  943.         $result6 api_sql_query($sql6);
  944.         $row6 mysql_fetch_array($result6);
  945.         //4.a.5 Get a link to the prerequisite item
  946.         $prereqname display_addedresource_link_in_learnpath($row6['item_type']$row6['ref']''$id_in_path3'builder''nolink')//this is the prereq of the step we want to open
  947.  
  948.         //4.a.5 Initialise limit value
  949.         $limitok true;
  950.         //4.a.6 Get prerequisite limit
  951.         if ($prereq_limit)
  952.         {
  953.             //4.a.6.a If the completion limit exists
  954.             if ($row3['score'$prereq_limit)
  955.             {
  956.                 //4.a.6.a.a If the completion limit hasn't been reached, then display the corresponding message
  957.                 $prereq $langPrereqToEnter.$stepname.$langPrereqTestLimit1."$prereq_limit".$langPrereqTestLimit2.$prereqname.". (".$langPrereqTestLimitNow.$row3['score'].")";
  958.             }
  959.             else
  960.             {
  961.                 //4.a.6.a.b The completion limit has been reached. Prepare to return false (no prereq hanging)
  962.                 $prereq false;
  963.             }
  964.         }
  965.         else
  966.         {
  967.             //4.a.6.b If the completion limit doesn't exist
  968.             if ($row3['status'== "completed" or $row3['status'== 'passed')
  969.             {
  970.                 //4.a.6.b.a If the prerequisite status is 'completed'
  971.                 $prereq false;
  972.             }
  973.             else
  974.             {
  975.                 //4.a.6.b.b The prerequisite status is not 'completed', return corresponding message
  976.                 $prereq $langPrereqToEnter.$stepname.$langPrereqFirstNeedTo.$prereqname.'.';
  977.             }
  978.         }
  979.  
  980.     }
  981.     elseif ($row['prereq_type'== 'c')
  982.     {
  983.         //4.b If prerequisite is of type 'c' (chapter)
  984.         //4.b.1 Get data ready to use
  985.         $id_in_path2 $row['prereq_id'];
  986.         //4.b.2 Get all items in the prerequisite chapter
  987.         $sql_items3 "SELECT * FROM $tbl_lp_item WHERE parent_item_id='$id_in_path2'";
  988.         $result_items3 api_sql_query($sql_items3);
  989.         $allcompleted true;
  990.         while ($row3 mysql_fetch_array($result_items3))
  991.         {
  992.             //4.b.3 Cycle through items in the prerequisite chapter
  993.             //4.b.3.1 Get data ready to use
  994.             $id_in_path4 $row3['id'];
  995.             if ($_user['user_id'== '')
  996.             {
  997.                 $user_id '0';
  998.             }
  999.             else
  1000.             {
  1001.                 $user_id $_user['user_id'];
  1002.             }
  1003.             //4.b.3.2 Get user-item relation
  1004.             $sql_items4 "SELECT * FROM $tbl_learnpath_user WHERE (learnpath_item_id='$id_in_path4' and user_id=$user_id)";
  1005.             $result_items4 api_sql_query($sql_items4);
  1006.             $row4 mysql_fetch_array($result_items4);
  1007.             //4.b.3.3 If any of these elements is not 'completed', the overall completion status is false
  1008.             if ($row4['status'!= "completed" and $row4['status'!= 'passed')
  1009.             {
  1010.                 $allcompleted false;
  1011.             }
  1012.         }
  1013.         if ($allcompleted)
  1014.         {
  1015.             //4.b.4.a All items were completed, prepare to return that there is no prerequisite blocking the way
  1016.             $prereq false;
  1017.         }
  1018.         else
  1019.         {
  1020.             //4.b.4.b Something was not completed. Return corresponding message
  1021.             $sql5 "SELECT * FROM $tbl_learnpath_chapter WHERE (lp_id='$learnpath_id' and id='$id_in_path2')";
  1022.             $result5 api_sql_query($sql5);
  1023.             $row5 mysql_fetch_array($result5);
  1024.             $prereqmodulename trim($row5['chapter_name']);
  1025.             $prereq $langPrereqModuleMinimum1.$prereqmodulename.$langPrereqModuleMinimum2;
  1026.         }
  1027.     }
  1028.     else
  1029.     {
  1030.         //5 If prerequisite type undefined, no prereq
  1031.         $prereq false;
  1032.     }
  1033.     //6 Return the message (or false if no prerequisite waiting)
  1034.     return ($prereq);
  1035. }
  1036.  
  1037. /**
  1038.  * Constructs the tree that will be used to build the learnpath structure
  1039.  * @params  integer     Learnpath_id
  1040.  * @return  array       Tree of the learnpath structure
  1041.  * @author  Yannick Warnier <yannick.warnier@dokeos.com>
  1042.  * @comment This is a temporary function, which exists while the chapters and items
  1043.  *           are still in separate tables in the database. This function gathers the data in a unique tree.
  1044.  ***/
  1045. function get_learnpath_tree($learnpath_id)
  1046. {
  1047.     //error_log('New LP - In learnpath_functions::get_learnpath_tree',0);
  1048.     //init elems
  1049.     #global $tbl_learnpath_item, $tbl_learnpath_chapter; 
  1050.     /*
  1051.     $tbl_learnpath_item = Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  1052.     $tbl_learnpath_chapter = Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  1053.     */
  1054.     $tbl_lp_item Database::get_course_table('lp_item');
  1055.  
  1056.     $tree array ();
  1057.     $chapters array ();
  1058.     //$chapters = array();
  1059.     //$chapters_by_parent = array();
  1060.     //$items = array();
  1061.     //$items_by_chapter = array();
  1062.     $all_items_by_chapter array ();
  1063.     $sql "SELECT * FROM $tbl_lp_item WHERE lp_id = ".$learnpath_id." AND item_type='dokeos_chapter' ORDER BY display_order";
  1064.     //error_log('New LP - learnpath_functions - get_learnpath_tree: '.$sql,0);
  1065.     $res api_sql_query($sql__FILE____LINE__);
  1066.     // format the $chapters_by_parent array so we have a suitable structure to work with
  1067.     while ($row Database::fetch_array($res))
  1068.     {
  1069.         $chapters[$row;
  1070.         //shouldn't be necessary (check no null value)
  1071.         if (empty ($row['parent_item_id']))
  1072.         {
  1073.             $row['parent_item_id'0;
  1074.         }
  1075.         //$chapters_by_parent[$row['parent_item_id']][$row['previous_item_id']] = $row;
  1076.         $all_items_by_chapter[$row['parent_item_id']][$row['display_order']] $row;
  1077.         $all_items_by_chapter[$row['parent_item_id']][$row['display_order']]['type''dokeos_chapter';
  1078.     }
  1079.  
  1080.     // now for every item in each chapter, get a suitable structure too
  1081.     foreach ($chapters as $row)
  1082.     {
  1083.         // select items from this chapter
  1084.         $sql "SELECT * FROM $tbl_lp_item WHERE lp_id = $learnpath_id AND parent_item_id = ".$row['id']." ORDER BY display_order";
  1085.         //error_log('New LP - learnpath_functions - get_learnpath_tree: '.$sql,0);
  1086.         $res api_sql_query($sql__FILE____LINE__);
  1087.         //error_log('New LP - learnpath_functions - get_learnpath_tree: Found '.Database::num_rows($res).' results',0);
  1088.         while ($myrow mysql_fetch_array($resMYSQL_ASSOC))
  1089.         {
  1090.             //$items[] = $myrow;
  1091.             //$items_by_chapter[$myrow['parent_item_id']][$myrow['display_order']] = $myrow;
  1092.             $all_items_by_chapter[$row['id']][$myrow['display_order']] $myrow;
  1093.             $all_items_by_chapter[$row['id']][$myrow['display_order']]['type''item';
  1094.         }
  1095.     }
  1096.     //array_multisort($all_items_by_chapter[0], SORT_ASC, SORT_NUMERIC);
  1097.     foreach ($all_items_by_chapter as $key => $subrow)
  1098.     {
  1099.         ksort($all_items_by_chapter[$key]);
  1100.     }
  1101.  
  1102.     //all items should now be well-ordered
  1103.     //error_log('New LP - In get_learnpath_tree, returning '.print_r($all_items_by_chapter,true),0);
  1104.     return $all_items_by_chapter;
  1105. }
  1106.  
  1107. /**
  1108.  * Gives a list of sequencial elements IDs for next/previous actions
  1109.  * @param   array   The elements tree as returned by get_learnpath_tree()
  1110.  * @param   integer The chapter id to start from
  1111.  * @param   boolean Whether to include chapters or not
  1112.  * @return  array   List of elements in the first to last order
  1113.  * @author  Yannick Warnier <yannick.warnier@dokeos.com>
  1114.  ***/
  1115. function get_ordered_items_list($tree$chapter 0$include_chapters false)
  1116. {
  1117.     $list array ();
  1118.     foreach ($tree[$chapteras $order => $elem)
  1119.     {
  1120.         if ($elem['type'== 'chapter')
  1121.         {
  1122.             if ($include_chapters === true)
  1123.             {
  1124.                 $list[array ('id' => $elem['id']'type' => $elem['type']);
  1125.             }
  1126.             $res get_ordered_items_list($tree$elem['id']$include_chapters);
  1127.             foreach ($res as $elem)
  1128.             {
  1129.                 $list[$elem;
  1130.             }
  1131.         }
  1132.         elseif ($elem['type'== 'item')
  1133.         {
  1134.             $list[array ('id' => $elem['id']'type' => $elem['type']'item_type' => $elem['item_type']'parent_item_id' => $elem['parent_item_id']'item_id' => $elem['item_id']);
  1135.         }
  1136.     }
  1137.     return $list;
  1138. }
  1139.  
  1140. /**
  1141.  * Displays the structure of a chapter recursively. Takes the result of get_learnpath_tree as argument
  1142.  * @param    array        Chapter structure
  1143.  * @param    integer    Chapter ID (start point in the tree)
  1144.  * @param    integer    Learnpath ID
  1145.  * @param    integer    User ID
  1146.  * @param    boolean    Indicates if the style is wrapped (true) or extended (false)
  1147.  * @param    integer    Level reached so far in the tree depth (enables recursive behaviour)
  1148.  * @return    array        Number of items, Number of items completed
  1149.  * @author    Many changes by Yannick Warnier <yannick.warnier@dokeos.com>
  1150.  ***/
  1151. function display_toc_chapter_contents($tree$parent_item_id 0$learnpath_id$uid$wrap$level 0)
  1152. {
  1153.         #global $tbl_learnpath_user;
  1154.     $tbl_learnpath_user Database :: get_course_table(TABLE_LEARNPATH_USER);
  1155.     $num 0;
  1156.     $num_completed 0;
  1157.     foreach ($tree[$parent_item_idas $order => $elem)
  1158.     {
  1159.  
  1160.         $bold false;
  1161.         if (!empty ($_SESSION['cur_open']&& ($elem['id'== $_SESSION['cur_open']))
  1162.         {
  1163.             $bold true;
  1164.         }
  1165.         if ($elem['type'=== 'chapter')
  1166.         {
  1167.             if ($wrap)
  1168.             {
  1169.                 echo str_repeat("&nbsp;&nbsp;"$level).shorten(strip_tags($elem['chapter_name'])(35 $level))."<br />\n";
  1170.             }
  1171.             else
  1172.             {
  1173.                 echo "<tr><td colspan='3'>".str_repeat("&nbsp;&nbsp;"$level).shorten($elem['chapter_name'](35 $level))."</td></tr>\n";
  1174.             }
  1175.  
  1176.             if ($wrap)
  1177.             {
  1178.                 if ($elem['chapter_description'!= '')
  1179.                 {
  1180.                     echo "<div class='description'>".str_repeat("&nbsp;&nbsp;"$level)."&nbsp;".shorten($elem['chapter_description'](35 $level))."</div>\n";
  1181.                 }
  1182.             }
  1183.             else
  1184.             {
  1185.                 if ($elem['chapter_description'!= '')
  1186.                 {
  1187.                     echo "<tr><td colspan='3'><div class='description'>".str_repeat("&nbsp;&nbsp;"$level)."&nbsp;".shorten($elem['chapter_description'](35 $level))."</div></td></tr>\n";
  1188.                 }
  1189.             }
  1190.             list ($a$bdisplay_toc_chapter_contents($tree$elem['id']$learnpath_id$uid$wrap$level +1);
  1191.             $num += $a;
  1192.             $num_completed += $b;
  1193.  
  1194.         }
  1195.         elseif ($elem['type'=== 'item')
  1196.         {
  1197.             // If this element is an item (understand: not a directory/module)
  1198.             $sql0 "SELECT * FROM $tbl_learnpath_user WHERE (user_id='".$uid."' and learnpath_item_id='".$elem['id']."' and lp_id='".$learnpath_id."')";
  1199.             $result0 api_sql_query($sql0__FILE____LINE__);
  1200.             $row0 mysql_fetch_array($result0);
  1201.  
  1202.             $completed '';
  1203.             if (($row0['status'== 'completed'or ($row0['status'== 'passed'))
  1204.             {
  1205.                 $completed 'completed';
  1206.                 $num_completed ++;
  1207.             }
  1208.  
  1209.             if ($wrap)
  1210.             {
  1211.                 echo str_repeat("&nbsp;&nbsp;"$level)."<a name='{$elem['id']}' />\n";
  1212.             }
  1213.             else
  1214.             {
  1215.                 echo "<tr><td>".str_repeat("&nbsp;&nbsp;"$level-1)."<a name='{$elem['id']}' />\n";
  1216.             }
  1217.  
  1218.             if ($wrap)
  1219.             {
  1220.                 $icon 'wrap';
  1221.             }
  1222.  
  1223.             if ($bold)
  1224.             {
  1225.                 echo "<b>";
  1226.             }
  1227.             display_addedresource_link_in_learnpath($elem['item_type']$elem['ref']$completed$elem['id']'player'$icon);
  1228.             if ($bold)
  1229.             {
  1230.                 echo "</b>";
  1231.             }
  1232.             if ($wrap)
  1233.             {
  1234.                 echo "<br />\n";
  1235.             }
  1236.             else
  1237.             {
  1238.                 echo "</td></tr>\n";
  1239.             }
  1240.  
  1241.             $num ++;
  1242.         }
  1243.     }
  1244.     return array ($num$num_completed);
  1245. }
  1246.  
  1247. /**
  1248.  * Returns a string to display in the tracking frame within the contents.php page (for example)
  1249.  * @param   integer     Learnpath id
  1250.  * @param   integer     Current user id
  1251.  * @param   integer     Starting chapter id
  1252.  * @param   array       Tree of elements as returned by get_learnpath_tree()
  1253.  * @param   integer     Level of recursivity we have reached
  1254.  * @param   integer     Counter of elements already displayed
  1255.  * @author  Yannick Warnier <yannick.warnier@dokeos.com>
  1256.  * @note : forced display because of display_addedresource_link_in_learnpath behaviour (outputing a string would be better)
  1257.  ***/
  1258. function get_tracking_table($learnpath_id$user_id$parent_item_id 0$tree false$level 0$counter 0)
  1259. {
  1260.     $tbl_learnpath_chapter Database :: get_course_learnpath_chapter_table();
  1261.     $tbl_learnpath_item Database :: get_course_learnpath_item_table();
  1262.     $tbl_learnpath_user Database :: get_course_learnpath_user_table();
  1263.     //$mytable = '';
  1264.     $include_chapters true;
  1265.  
  1266.     if (!is_array($tree))
  1267.     {
  1268.         //get a tree of the current learnpath elements
  1269.         $tree get_learnpath_tree($learnpath_id);
  1270.     }
  1271.     foreach ($tree[$parent_item_idas $order => $elem)
  1272.     {
  1273.         if (($counter 2== 0)
  1274.         {
  1275.             $oddclass 'row_odd';
  1276.         }
  1277.         else
  1278.         {
  1279.             $oddclass 'row_even';
  1280.         }
  1281.  
  1282.         if ($elem['type'== 'chapter')
  1283.         {
  1284.             if ($include_chapters === true)
  1285.             {
  1286.                 //$mytable .= "<tr class='$oddclass'><td colspan = '3'>".str_repeat('&nbsp;',$level*2+2).$elem['chapter_name']."</td></tr>\n";
  1287.                 echo "<tr class='$oddclass'><td colspan = '3'>".str_repeat('&nbsp;'$level 2).$elem['chapter_name']."</td></tr>\n";
  1288.             }
  1289.             $counter ++;
  1290.             //$mytable .= get_tracking_table($learnpath_id, $user_id, $elem['id'], $tree, $level + 1, $counter );
  1291.             get_tracking_table($learnpath_id$user_id$elem['id']$tree$level +1$counter);
  1292.  
  1293.         }
  1294.         elseif ($elem['type'== 'item')
  1295.         {
  1296.  
  1297.             $sql "SELECT * FROM $tbl_learnpath_user "."WHERE user_id = $user_id "."AND lp_id = $learnpath_id "."AND learnpath_item_id = ".$elem['id'];
  1298.             $res api_sql_query($sql__FILE____LINE__);
  1299.             $myrow mysql_fetch_array($res);
  1300.  
  1301.             if (($myrow['status'== 'completed'|| ($myrow['status'== 'passed'))
  1302.             {
  1303.                 $color 'blue';
  1304.                 $statusmessage get_lang('Complete');
  1305.             }
  1306.             else
  1307.             {
  1308.                 $color 'black';
  1309.                 $statusmessage get_lang('Incomplete');
  1310.             }
  1311.  
  1312.             $link get_addedresource_link_in_learnpath($elem['item_type']$elem['id']$elem['item_id']);
  1313.             //$link = display_addedresource_link_in_learnpath($elem['item_type'], $elem['id'], $row['status'], $elem['item_id'], 'player', 'none');
  1314.  
  1315.             //$mytable .= "<tr class='$oddclass'>"
  1316.             echo "<tr class='$oddclass'>"."<td class='mystatus'>".str_repeat("&nbsp;"$level 2);
  1317.             //."<a href='$link?SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9' target='toc'>hop</a>"
  1318.             display_addedresource_link_in_learnpath($elem['item_type']$elem['ref']$myrow['status']$elem['id']'player''wrap');
  1319.             //we should also add the total score here
  1320.             echo "<td>"."<font color='$color'><div class='mystatus'>".$statusmessage."</div></font>"."</td>"."<td>"."<div class='mystatus' align='center'>"($myrow['score'== '-' $myrow['score'])."</div>"."</td>"."</tr>\n";
  1321.             $counter ++;
  1322.         }
  1323.     }
  1324.     //return $mytable;
  1325.     return true;
  1326. }
  1327.  
  1328. /**
  1329.  * This function returns false if there is at least one item in the path
  1330.  * @param    Learnpath ID
  1331.  * @return    boolean    True if nothing was found, false otherwise
  1332.  */
  1333. function is_empty($id)
  1334. {
  1335.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  1336.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  1337.  
  1338.     $sql "SELECT * FROM $tbl_learnpath_chapter WHERE lp_id=$id ORDER BY display_order ASC";
  1339.     $result api_sql_query($sql__FILE____LINE__);
  1340.     $num_modules mysql_num_rows($result);
  1341.     $empty true;
  1342.  
  1343.     if ($num_modules != 0)
  1344.     {
  1345.         while ($row mysql_fetch_array($result))
  1346.         {
  1347.  
  1348.             $num_items 0;
  1349.             $parent_item_id $row['id'];
  1350.             $sql2 "SELECT * FROM $tbl_learnpath_item WHERE (parent_item_id=$parent_item_id) ORDER BY display_order ASC";
  1351.             $result2 api_sql_query($sql2__FILE____LINE__);
  1352.             $num_items mysql_num_rows($result2);
  1353.             if ($num_items 0)
  1354.             {
  1355.                 $empty false;
  1356.             }
  1357.  
  1358.         }
  1359.     }
  1360.  
  1361.     return ($empty);
  1362.  
  1363. }
  1364.  
  1365. /**
  1366.  * This function writes $content to $filename
  1367.  * @param    string    Destination filename
  1368.  * @param    string    Learnpath name
  1369.  * @param    integer    Learnpath ID
  1370.  * @param    string    Content to write
  1371.  * @return    void 
  1372.  */
  1373. function exporttofile($filename$LPname$LPid$content)
  1374. {
  1375.  
  1376.     global $circle1_files//this keeps all the files which are exported [0]:filename [1]:LP name
  1377.     //the $circle1_files variable is going to be used to a deep extent in the imsmanifest.xml
  1378.     global $expdir;
  1379.  
  1380.     if (!$handle fopen($expdir.'/'.$filename'w'))
  1381.     {
  1382.         echo "Cannot open file ($filename)";
  1383.     }
  1384.     if (fwrite($handle$content=== FALSE)
  1385.     {
  1386.         echo "Cannot write to file ($filename)";
  1387.         exit;
  1388.     }
  1389.     fclose($handle);
  1390.  
  1391.     $circle1_files[0][$filename;
  1392.     $circle1_files[1][$LPname;
  1393.     $circle1_files[2][$LPid;
  1394.  
  1395. }
  1396.  
  1397. /**
  1398.  * This function exports the given Dokeos test
  1399.  * @param    integer    Test ID
  1400.  * @return string     The test itself as an HTML string
  1401.  */
  1402. function export_exercise($item_id)
  1403. {
  1404.  
  1405.     global $expdir$_course$_configuration$_SESSION$_SERVER$language_interface$langExerciseNotFound$langQuestion$langOk;
  1406.  
  1407.     $exerciseId $item_id;
  1408.  
  1409.     require_once ('../exercice/exercise.class.php');
  1410.     require_once ('../exercice/question.class.php');
  1411.     require_once ('../exercice/answer.class.php');
  1412.     require_once ('../exercice/exercise.lib.php');
  1413.  
  1414.     // answer types
  1415.     define('UNIQUE_ANSWER'1);
  1416.     define('MULTIPLE_ANSWER'2);
  1417.     define('FILL_IN_BLANKS'3);
  1418.     define('MATCHING'4);
  1419.     define('FREE_ANSWER'5);
  1420.  
  1421.     include_once (api_get_path(LIBRARY_PATH).'/text.lib.php');
  1422.  
  1423.     $TBL_EXERCISES Database :: get_course_table(TABLE_QUIZ_TEST);
  1424.  
  1425.     /*******************************/
  1426.     /* Clears the exercise session */
  1427.     /*******************************/
  1428.     if (isset ($_SESSION['objExercise']))
  1429.     {
  1430.         api_session_unregister('objExercise');
  1431.         unset ($objExercise);
  1432.     }
  1433.     if (isset ($_SESSION['objQuestion']))
  1434.     {
  1435.         api_session_unregister('objQuestion');
  1436.         unset ($objQuestion);
  1437.     }
  1438.     if (isset ($_SESSION['objAnswer']))
  1439.     {
  1440.         api_session_unregister('objAnswer');
  1441.         unset ($objAnswer);
  1442.     }
  1443.     if (isset ($_SESSION['questionList']))
  1444.     {
  1445.         api_session_unregister('questionList');
  1446.         unset ($questionList);
  1447.     }
  1448.     if (isset ($_SESSION['exerciseResult']))
  1449.     {
  1450.         api_session_unregister('exerciseResult');
  1451.         unset ($exerciseResult);
  1452.     }
  1453.  
  1454.     // if the object is not in the session
  1455.     if (!isset ($_SESSION['objExercise']))
  1456.     {
  1457.         // construction of Exercise
  1458.         $objExercise new Exercise();
  1459.  
  1460.         $sql "SELECT title,description,sound,type,random,active FROM $TBL_EXERCISES WHERE id='$exerciseId'";
  1461.         // if the specified exercise doesn't exist or is disabled
  1462.         if (!$objExercise->read($exerciseId|| (!$objExercise->selectStatus(&& !$is_allowedToEdit && ($origin != 'learnpath')))
  1463.         {
  1464.             die($langExerciseNotFound);
  1465.         }
  1466.  
  1467.         // saves the object into the session
  1468.         api_session_register('objExercise');
  1469.     }
  1470.  
  1471.     $exerciseTitle $objExercise->selectTitle();
  1472.     $exerciseDescription $objExercise->selectDescription();
  1473.     $exerciseSound $objExercise->selectSound();
  1474.     $randomQuestions $objExercise->isRandom();
  1475.     $exerciseType $objExercise->selectType();
  1476.  
  1477.     if (!isset ($_SESSION['questionList']))
  1478.     {
  1479.         // selects the list of question ID
  1480.         $questionList $randomQuestions $objExercise->selectRandomList($objExercise->selectQuestionList();
  1481.  
  1482.         // saves the question list into the session
  1483.         api_session_register('questionList');
  1484.     }
  1485.  
  1486.     $nbrQuestions sizeof($questionList);
  1487.  
  1488.     // if questionNum comes from POST and not from GET
  1489.     if (!$questionNum || $_POST['questionNum'])
  1490.     {
  1491.         // only used for sequential exercises (see $exerciseType)
  1492.         if (!$questionNum)
  1493.         {
  1494.             $questionNum 1;
  1495.         }
  1496.         else
  1497.         {
  1498.             $questionNum ++;
  1499.         }
  1500.     }
  1501.  
  1502.     $exerciseTitle api_parse_tex($exerciseTitle);
  1503.  
  1504.     $test .= "<h3>".$exerciseTitle."</h3>";
  1505.  
  1506.     if (!empty ($exerciseSound))
  1507.     {
  1508.         $test .= "<a href=\"../document/download.php?doc_url=%2Faudio%2F".$exerciseSound."\"&SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9 target=\"_blank\"><img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=".get_lang("Sound")."\" /></a>";
  1509.     }
  1510.  
  1511.     $exerciseDescription api_parse_tex($exerciseDescription);
  1512.  
  1513.     // --------- writing the .js file with to check the correct answers begin -----------------------
  1514.     $scriptfilename "Exercice".$item_id.".js";
  1515.     $s "<script type=\"text/javascript\" src='../js/".$scriptfilename."'></script>";
  1516.     $test .= $s;
  1517.  
  1518.     $content "function evaluate() {
  1519.         alert('Test evaluated.');
  1520.         }
  1521.         ";
  1522.  
  1523.     if (!$handle fopen($expdir.'/js/'.$scriptfilename'w'))
  1524.     {
  1525.         echo "Cannot open file ($scriptfilename)";
  1526.     }
  1527.     if (fwrite($handle$content=== FALSE)
  1528.     {
  1529.         echo "Cannot write to file ($filename)";
  1530.         exit;
  1531.     }
  1532.     fclose($handle);
  1533.     // --------- writing the .js file with to check the correct answers end -----------------------
  1534.  
  1535.     $s "
  1536.         <p>$exerciseDescription</p>
  1537.         <table width='100%' border='0' cellpadding='1' cellspacing='0'>
  1538.          <form method='post' action=''><input type=\"hidden\" name=\"SQMSESSID\" value=\"36812c2dea7d8d6e708d5e6a2f09b0b9\" />
  1539.          <input type='hidden' name='formSent' value='1' />
  1540.          <input type='hidden' name='exerciseType' value='".$exerciseType."' />
  1541.          <input type='hidden' name='questionNum' value='".$questionNum."' />
  1542.          <input type='hidden' name='nbrQuestions' value='".$nbrQuestions."' />
  1543.          <tr>
  1544.           <td>
  1545.           <table width='100%' cellpadding='4' cellspacing='2' border='0'>";
  1546.  
  1547.     $exerciseType 1//so to list all questions in one page
  1548.     $test .= $s;
  1549.  
  1550.     $i 0;
  1551.  
  1552.     foreach ($questionList as $questionId)
  1553.     {
  1554.         $i ++;
  1555.  
  1556.         // for sequential exercises
  1557.         if ($exerciseType == 2)
  1558.         {
  1559.             // if it is not the right question, goes to the next loop iteration
  1560.             if ($questionNum != $i)
  1561.             {
  1562.                 continue;
  1563.             }
  1564.             else
  1565.             {
  1566.                 // if the user has already answered this question
  1567.                 if (isset ($exerciseResult[$questionId]))
  1568.                 {
  1569.                     // construction of the Question object
  1570.                     $objQuestionTmp new Question();
  1571.  
  1572.                     // reads question informations
  1573.                     $objQuestionTmp->read($questionId);
  1574.  
  1575.                     $questionName $objQuestionTmp->selectTitle();
  1576.  
  1577.                     // destruction of the Question object
  1578.                     unset ($objQuestionTmp);
  1579.  
  1580.                     $test .= '<tr><td>'.get_lang("AlreadyAnswered").' &quot;'.$questionName.'&quot;</td></tr>';
  1581.  
  1582.                     break;
  1583.                 }
  1584.             }
  1585.         }
  1586.  
  1587.         $s "<tr bgcolor='#e6e6e6'><td valign='top' colspan='2'>".$langQuestion." ";
  1588.         $s .= $i;
  1589.         if ($exerciseType == 2)
  1590.             $s .= ' / '.$nbrQuestions;
  1591.         $s .= '</td></tr>';
  1592.  
  1593.         $test .= $s;
  1594.  
  1595.         //Call the showQuestion() function from exercise.lib.php. This basically displays the question in a table
  1596.         $test .= showQuestion($questionIdfalse'export');
  1597.  
  1598.     // end foreach()
  1599.  
  1600.     $s "</table></td></tr><tr><td><br/><input type='button' value='".$langOk."' onClick=\"javascript:evaluate();alert('Evaluated.');\">";
  1601.  
  1602.     $s .= "</td></tr></form></table>";
  1603.     $s .= "<script type='text/javascript'> loadPage(); </script>";
  1604.  
  1605.     $b 2;
  1606.  
  1607.     $test .= $s;
  1608.  
  1609.     return ($test);
  1610.  
  1611. }
  1612.  
  1613. /**
  1614.  * This function exports the given item
  1615.  * @param    integer    Id from learnpath_items table
  1616.  * @param    integer    Item id
  1617.  * @param    string    Itm type
  1618.  * @param    boolean    Shall the SCORM communications features be added? (true). Default: false.
  1619.  * @return    void (outputs a zip file)
  1620.  * @todo    Try using the SCORM communications addition (adding a button and several javascript calls to the SCORM API) elsewhere than just in the export feature, so it doesn't look like an incoherent feature
  1621.  */
  1622.  
  1623. function exportitem($id$item_id$item_type$add_scorm_communications false)
  1624. {
  1625.  
  1626.     global $circle1_files$expdir$_course$_SESSION$GLOBALS;
  1627.  
  1628.     global $timeNoSecFormat$dateFormatLong$language_interface$langPubl$langDone$langThisCourseDescriptionIsEmpty$lang_course_description$lang_introduction_text$_cid$langHotPotatoesFinished$lang_author$lang_date$lang_groups$lang_users$lang_ass$lang_dropbox$test$langQuestion;
  1629.  
  1630.     //    $_course=$_SESSION['course'];
  1631.     require_once (api_get_path(LIBRARY_PATH)."database.lib.php");
  1632.     //$tbl_learnpath_item     = Database::get_course_learnpath_item_table();
  1633.  
  1634.     include_once ('exercise.class.php');
  1635.     include_once ('question.class.php');
  1636.     include_once ('answer.class.php');
  1637.     include_once ('exercise.lib.php');
  1638.  
  1639.     include_once ('../lang/english/announcements.inc.php')//this line is here only for $langPubl in announcements
  1640.     include_once ("../lang/".$language_interface."/announcements.inc.php")//this line is here only for $langPubl in announcements
  1641.     include_once ('../lang/english/course_description.inc.php')//this line is here only for $langThisCourseDescriptionIsEmpty
  1642.     include_once ("../lang/".$language_interface."/course_description.inc.php")//                 -||-
  1643.     include_once ('../lang/english/resourcelinker.inc.php');
  1644.     include_once ("../lang/".$language_interface."/resourcelinker.inc.php");
  1645.     include_once ('../lang/english/learnpath.inc.php');
  1646.     include_once ("../lang/".$language_interface."/learnpath.inc.php");
  1647.     include_once ('../lang/english/exercice.inc.php');
  1648.     include_once ("../lang/".$language_interface."/exercice.inc.php");
  1649.  
  1650.     include_once (api_get_path(LIBRARY_PATH).'text.lib.php');
  1651.     include_once ("../resourcelinker/resourcelinker.inc.php");
  1652.     include_once (api_get_path(LIBRARY_PATH)."events.lib.inc.php");
  1653.  
  1654.     $LPname display_addedresource_link_in_learnpath($item_type$item_id''$id'builder''nolink');
  1655.  
  1656.     $expcontent "<!-- 
  1657.         This is an exported file from Dokeos Learning Path belonging to a Scorm compliant content package.
  1658.         Do not modify or replace individually.
  1659.             
  1660.         Export module author : Denes Nagy <darkden@evk.bke.hu>
  1661.     
  1662.         -->
  1663.             
  1664.         ";
  1665.     //files needed for communicating with the scos
  1666.     $scocomfiles "<script type='text/javascript' src='../js/APIWrapper.js'></script>"."<script type='text/javascript' src='../js/SCOFunctions.js'></script>";
  1667.     $expcontent .= '<html><head><link rel="stylesheet" href="../css/default.css" type="text/css" media="screen,projection" />'.$scocomfiles.'</head><body>';
  1668.  
  1669.     $donebutton .= "<script type='text/javascript'>
  1670.             /* <![CDATA[ */
  1671.             loadPage();
  1672.             var   studentName = '!';
  1673.             var   lmsStudentName = doLMSGetValue(  'cmi.core.student_name' );
  1674.             if ( lmsStudentName  != '' )
  1675.             {
  1676.                studentName = ' ' + lmsStudentName +   '!';
  1677.             }
  1678.             /* ]]> */
  1679.             </script>
  1680.             <br /><br />
  1681.             <form><input type=\"hidden\" name=\"SQMSESSID\" value=\"36812c2dea7d8d6e708d5e6a2f09b0b9\" />
  1682.                 <table cols='3'    width='100%' align='center'>
  1683.                     <tr>
  1684.                     <td    align='middle'><input type = 'button' value    = '  ".$langDone."  ' onclick = \"doQuit('completed')\" id='button2' name='button2'></td>
  1685.                     </tr>
  1686.                 </table>
  1687.             </form>";
  1688.  
  1689.     /** 
  1690.      * switch between the different element types, namely:
  1691.      * - Agenda
  1692.      * - Ad_Valvas
  1693.      * - Course_description
  1694.      * - Document
  1695.      * - Introduction_text
  1696.      * - HotPotatoes
  1697.      * - Exercise
  1698.      * - Post
  1699.      * - Forum                        ]
  1700.      * - Thread                    ]
  1701.      * - Dropbox                ]
  1702.      * - Assignments    ]  Theses elements are all replaced by a simple message in the exported document
  1703.      * - Groups                    ]
  1704.      * - Users                        ]
  1705.      * - Link _self  
  1706.      * - Link _blank
  1707.      */
  1708.     switch ($item_type)
  1709.     {
  1710.  
  1711.         //------------------------AGENDA BEGIN-------------------
  1712.         case "Agenda" :
  1713.             //1 Get agenda event data from the database table
  1714.             $TABLEAGENDA Database :: get_course_table(TABLE_AGENDA);
  1715.             $sql "SELECT * FROM ".$TABLEAGENDA." where (id=$item_id)";
  1716.             $result api_sql_query($sql__FILE____LINE__);
  1717.  
  1718.             //2 Prepare table output
  1719.             $expcontent .= "<table id=\"agenda_list\" >";
  1720.             $barreMois "";
  1721.  
  1722.             //3 For each event corresponding to this agenda, do the following:
  1723.             while ($myrow mysql_fetch_array($result))
  1724.             {
  1725.                 //3.1 Make the blue month bar appear only once.
  1726.                 if ($barreMois != date("m"strtotime($myrow["start_date"])))
  1727.                 {
  1728.                     //3.1.1 Update the check value for the month bar
  1729.                     $barreMois date("m"strtotime($myrow["start_date"]));
  1730.                     //3.1.2    Display the month bar
  1731.                     $expcontent .= "<tr><td id=\"title\" colspan=\"2\" class=\"month\" valign=\"top\">".ucfirst(format_locale_date("%B %Y"strtotime($myrow["start_date"])))."</td></tr>";
  1732.                 }
  1733.  
  1734.                 //3.2 Display the agenda items (of this month): the date, hour and title
  1735.                 $db_date = (int) date(dstrtotime($myrow["start_date"]));
  1736.                 if ($_GET["day"<> $db_date)
  1737.                 //3.2.1.a If the day given in the URL (might not be set) is different from this element's day, use style 'data'
  1738.                     $expcontent .= "<tr><td class=\"data\" colspan='2'>";
  1739.                 }
  1740.                 else
  1741.                 //3.2.1.b Else (same day) use style 'datanow'
  1742.                     $expcontent .= "<tr><td class=\"datanow\" colspan='2'>";
  1743.                 }
  1744.                 //3.2.2 Mark an anchor for this date
  1745.                 $expcontent .= "<a name=\"".(int) date(dstrtotime($myrow["start_date"]))."\"></a>"// anchoring
  1746.                 //3.2.3 Write the date and time of this event to the export string
  1747.                 $expcontent .= ucfirst(format_locale_date($dateFormatLongstrtotime($myrow["start_date"])))."&nbsp;&nbsp;&nbsp;";
  1748.                 $expcontent .= ucfirst(strftime($timeNoSecFormatstrtotime($myrow["start_time"])))."";
  1749.                 //3.2.4 If a duration is set, write it, otherwise ignore
  1750.                 if ($myrow["duration"== "")
  1751.                 {
  1752.                     $expcontent .= "<br />";
  1753.                 }
  1754.                 else
  1755.                 {
  1756.                     $expcontent .= " / ".$lang_lasting." ".$myrow["duration"]."<br/>";
  1757.                 }
  1758.                 //3.2.5 Write the title
  1759.                 $expcontent .= $myrow["title"];
  1760.                 $expcontent .= "</td></tr>";
  1761.                 //3.2.6 Prepare the content of the agenda item
  1762.                 $content $myrow["content"];
  1763.                 //3.2.7 Make clickable???
  1764.                 $content make_clickable($content);
  1765.                 $content api_parse_tex($content);
  1766.                 //3.2.8 Write the prepared content to the export string
  1767.                 $expcontent .= "<tr><td class=\"text\" colspan='2'>";
  1768.                 $expcontent .= $content;
  1769.                 $expcontent .= "</td></tr>";
  1770.  
  1771.                 // displaying the agenda item of this month: the added resources
  1772.                 //     this part is not included into LP export
  1773.                 /*if (check_added_resources("Agenda", $myrow["id"]))
  1774.                 {
  1775.                 $content.= "<tr><td colspan='2'>";
  1776.                 $content.= "<i>".get_lang('AddedResources')."</i><br/>";
  1777.                 display_added_resources("Agenda", $myrow["id"]);
  1778.                 $content.= "</td></tr>";
  1779.                 }*/
  1780.  
  1781.             }
  1782.             //4 Finish the export string
  1783.             $expcontent .= "<tr></table>";
  1784.  
  1785.             break;
  1786.             //------------------------ANNOUNCEMENT BEGIN-------------------
  1787.         case "Ad_Valvas" :
  1788.             //1 Get the announcement data from the database
  1789.             $tbl_announcement Database::get_course_table(TABLE_ANNOUNCEMENT);
  1790.             $sql "SELECT * FROM $tbl_announcement where id='$item_id'";
  1791.             $result api_sql_query($sql__FILE____LINE__);
  1792.  
  1793.             //2 Initialise export string
  1794.             $expcontent .= "<table class=\"data_table\">";
  1795.  
  1796.             //3 For each announcement matching the query
  1797.             while ($myrow mysql_fetch_array($result))
  1798.             {
  1799.                 //3.1 Get the __ field data
  1800.                 $content $myrow[1];
  1801.                 //$content = nl2br($content);
  1802.                 //3.2 Prepare the data for export
  1803.                 $content make_clickable($content);
  1804.                 $content api_parse_tex($content);
  1805.  
  1806.                 //3.3 Get a UNIX(?<-mktime) Timestamp of the end_date for this announcement
  1807.                 $last_post_datetime $myrow['end_date']// post time format  datetime de mysql
  1808.                 list ($last_post_date$last_post_timesplit(" "$last_post_datetime);
  1809.                 list ($year$month$dayexplode("-"$last_post_date);
  1810.                 list ($hour$minexplode(":"$last_post_time);
  1811.                 $announceDate mktime($hour$min0$month$day$year);
  1812.  
  1813.                 //3.4 Compare the end date to the last login date of the user (mark it in red if he has not already read it)
  1814.                 if ($announceDate $_SESSION['user_last_login_datetime'])
  1815.                 {
  1816.                     $colorBecauseNew " color=\"red\" ";
  1817.                 }
  1818.                 else
  1819.                 {
  1820.                     $colorBecauseNew "  ";
  1821.                 }
  1822.  
  1823.                 //3.5 Write this content to the export string (formatted HTML array)
  1824.                 $expcontent .= "<tr>\n"."<td class=\"cell_header\">\n"."<font ".$colorBecauseNew.">".$langPubl." : ".ucfirst(format_locale_date($dateFormatLongstrtotime($last_post_date)))."</font>\n"."</td>\n"."</tr>\n"."<tr>\n"."<td>\n".$content."</td>\n"."</tr>\n";
  1825.  
  1826.             // while loop
  1827.  
  1828.             //4 Finish the export string
  1829.             $expcontent .= "</table>";
  1830.  
  1831.             break;
  1832.             //------------------------Course_description BEGIN-------------------
  1833.         case "Course_description" :
  1834.             //1 Get course description data from database
  1835.             $tbl_course_description Database :: get_course_table(TABLE_COURSE_DESCRIPTION);
  1836.             $result api_sql_query("SELECT id, title, content FROM ".$tbl_course_description." ORDER BY id"__FILE____LINE__);
  1837.  
  1838.             //2 Check this element
  1839.             if (mysql_num_rows($result))
  1840.             {
  1841.                 //2.a This course has one (or more) description in the database
  1842.                 $expcontent .= "<hr noshade=\"noshade\" size=\"1\" />";
  1843.                 //2.a.1 For each description available for this course
  1844.                 while ($row mysql_fetch_array($result))
  1845.                 {
  1846.                     //2.a.1.1 Write title to export string
  1847.                     $expcontent .= "<h4>".$row['title']."</h4>";
  1848.                     //2.a.1.2 Prepare content
  1849.                     $content make_clickable(nl2br($row['content']));
  1850.                     $content api_parse_tex($content);
  1851.                     //2.a.1.3 Write content to the export string
  1852.                     $expcontent .= $content;
  1853.                 }
  1854.             }
  1855.             else
  1856.             {
  1857.                 //2.b This course has no description available
  1858.                 $expcontent .= "<br /><h4>$langThisCourseDescriptionIsEmpty</h4>";
  1859.             }
  1860.  
  1861.             break;
  1862.             //------------------------DOCUMENT BEGIN-------------------
  1863.         case "Document" :
  1864.             //1 Get the document data from the database
  1865.             $tbl_document Database::get_course_table(TABLE_DOCUMENT);
  1866.             $sql_query "SELECT * FROM $tbl_document WHERE id=$item_id";
  1867.             $sql_result api_sql_query($sql_query__FILE____LINE__);
  1868.             $myrow mysql_fetch_array($sql_result);
  1869.             //2 Get the origin path of the document to treat it internally
  1870.             $orig api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'.$myrow["path"];
  1871.             //3 Make some kind of strange transformation to get the destination filepath ???
  1872.             $pathname explode("/"$myrow["path"]);
  1873.             $last count($pathname1;
  1874.             $filename 'data/'.$filename.$pathname[$last];
  1875.             $copyneeded true;
  1876.  
  1877.             //htm files do not need to be copied as the ok button is inserted into them, 
  1878.             //so don't copy directly
  1879.             $extension explode("."$pathname[$last]);
  1880.             //This old condition was WRONG for names like design.html.old. Instead, we now get the extension 
  1881.             // by using preg_match to match case-insensitive (probably faster than 4 conditions)
  1882.             //if (($extension[1]=='htm') or ($extension[1]=='html') or ($extension[1]=='HTM') or ($extension[1]=='HTML')) {
  1883.             //4 Check the file extension
  1884.             if (preg_match('/.*(\.htm(l)?)$/i'$pathname[$last]))
  1885.             {
  1886.                 //4.a If this file ends with ".htm(l)", we consider it's an HTML file
  1887.                 //src tag check begin
  1888.                 //we now check if there is any src attribute in htm(l) files, if yes, we have to also export
  1889.                 //the target file (swf, mp3, video,...) of that src tag
  1890.                 //In case of absolute links (http://) this is not neccessary, but makes no error.
  1891.                 //however still missing : relative links case with subdirs -> the necessary dirs are not created in the exported package
  1892.  
  1893.                 //4.a.1 Get the file contents into $file
  1894.                 $file file_get_contents($orig);
  1895.  
  1896.                 //4.a.2 Get all the src links in this file
  1897.                 //preg_match_all("|((?i)src=\".*\" )|U",$file,$match);                
  1898.                 $match GetSRCTags($orig);
  1899.  
  1900.                 //4.a.3 For each src tag found, do the following:
  1901.                 for ($i 0$i count($match)$i ++)
  1902.                 {
  1903.                     //4.a.3.1 Get the tag (split from the key)
  1904.                     list ($key$srctageach($match);
  1905.                     $src $srctag;
  1906.  
  1907.                     //4.a.3.2 Check the link kind (web or absolute/relative)
  1908.                     if (stristr($src"http"=== false)
  1909.                     {
  1910.                         //4.a.3.2.a Do something only if relative (otherwise the user will be able to see it too anyway)
  1911.                         //4.a.3.2.a.1 Get a proper URL and remove all './'
  1912.                         $src urldecode($src)//mp3
  1913.                         //$src=str_replace('./','',$src);
  1914.                         $src preg_replace('/^\.\//'''$src);
  1915.                         //4.a.3.2.a.2 Remove the player link from the URL (only use the mp3 file)
  1916.                         $src str_replace('mp3player.swf?son='''$src)//mp3
  1917.                         //4.a.3.2.a.3 Remove funny link parts
  1918.                         $src str_replace('?0'''$src)//mp3
  1919.                         //the previous lines are used when creating docs with Dokeos Document tool's htmlarea
  1920.                         //rows marked by 'mp3' are needed because the mp3 plugin inserts the swf-mp3 links in a very strange way
  1921.                         //and we can decode them with those 3 lines, hoping this will not cause errors in case of other htmls,
  1922.                         //created by any other software                                                
  1923.                         //4.a.3.2.a.4 Prepare source and destination paths
  1924.                         $source api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'.dirname($myrow['path']).'/'.$src;
  1925.                         $dest $expdir.'/data/'.$src;
  1926.                         //CopyNCreate($source,$dest);
  1927.                         rcopy($source$dest);
  1928.                     //else...?
  1929.                 }
  1930.  
  1931.                 //src tag check end
  1932.  
  1933.                 //sco communication insertion begin
  1934.                 //4.a.4 If we want to add SCORM actions and a "Done" button, do the following:
  1935.                 if ($add_scorm_communications === true)
  1936.                 {
  1937.                     if ($bodyclose strpos($file'</body>'))
  1938.                     {
  1939.                         $file substr_replace($file$scocomfiles.$donebutton$bodyclose7);
  1940.                     }
  1941.                     elseif ($htmlclose strpos($file'</html>'))
  1942.                     {
  1943.                         $file substr_replace($file$scocomfiles.$donebutton$htmlclose7);
  1944.                         $file .= '</html>';
  1945.                     }
  1946.                     else
  1947.                     {
  1948.                         $file .= $scocomfiles.$donebutton;
  1949.                     }
  1950.                 //sco communication insertion end    
  1951.  
  1952.                 //4.a.5 Replace the file's name by adding the element's ID before htm
  1953.                 // This will not work with uppercase HTML though. Maybe use the preg_replace syntax proposed...
  1954.                 $filename str_replace('.htm'$id.'.htm'$filename);
  1955.                 //$filename=preg_replace('/.*(\.htm(l)?)$/i',$id.$1,$filename);
  1956.                 //4.a.6 Export these contents to a file and set the circle1_files array for later reuse
  1957.                 exporttofile($filename$LPname$id$file);
  1958.  
  1959.                 //The file has been copied, so ask not to copy it again
  1960.                 $copyneeded false;
  1961.  
  1962.             //if (htm(l) files) end
  1963.  
  1964.             //5 If we still need to copy the file (e.g. it was not an HTML file), then copy and set circle1_files for later reuse
  1965.             if ($copyneeded)
  1966.             {
  1967.                 copy($orig$expdir.'/'.$filename);
  1968.                 $circle1_files[0][$filename;
  1969.                 $circle1_files[1][$LPname;
  1970.                 $circle1_files[2][$id;
  1971.             }
  1972.  
  1973.             //echo $orig;
  1974.             return;
  1975.  
  1976.             //------------------------Introduction_text BEGIN-------------------
  1977.         case "Introduction_text" :
  1978.             //1 Get the introduction text data from the database
  1979.             $TBL_INTRO Database :: get_course_tool_intro_table();
  1980.             $result api_sql_query("SELECT * FROM ".$TBL_INTRO." WHERE id=1");
  1981.             $myrow mysql_fetch_array($result);
  1982.             $intro $myrow["intro_text"];
  1983.             //2 Write introduction text to the export string
  1984.             $expcontent .= "<br />".$intro;
  1985.             break;
  1986.  
  1987.             //------------------------HotPotatoes BEGIN-------------------
  1988.         case "HotPotatoes" :
  1989.             //1 Get HotPotatoes data from the document table
  1990.             $tbl_document Database::get_course_table(TABLE_DOCUMENT);
  1991.             $result api_sql_query("SELECT * FROM $tbl_document WHERE id=$item_id"__FILE____LINE__);
  1992.             $myrow mysql_fetch_array($result);
  1993.             //2 Get the document path
  1994.             $testfile api_get_path(SYS_COURSE_PATH).$_course['path']."/document".urldecode($myrow['path']);
  1995.             //3 Get the document contents into a string
  1996.             $content file_get_contents($testfile);
  1997.             //4 Get the document filename (just the file, no path) - would probably be better to use PHP native function
  1998.             $pathname explode("/"$myrow["path"]);
  1999.             $last count($pathname1;
  2000.             $filename 'data/'.$filename.$pathname[$last];
  2001.  
  2002.             //4beta - get all linked files and copy them (procedure copied from documents type)
  2003.             //Get all the src links in this file
  2004.             $match GetSRCTags($testfile);
  2005.             //For each src tag found, do the following:
  2006.             foreach ($match as $src)
  2007.             {
  2008.                 //Check the link kind (web or absolute/relative)
  2009.                 if (stristr($src"http"=== false)
  2010.                 {
  2011.                     //Do something only if relative (otherwise the user will be able to see it too anyway)
  2012.                     //Get a proper URL and remove all './'
  2013.                     $src urldecode($src)//mp3
  2014.                     $src str_replace('./'''$src);
  2015.                     //Remove the player link from the URL (only use the mp3 file)
  2016.                     $src str_replace('mp3player.swf?son='''$src)//mp3
  2017.                     //Remove funny link parts
  2018.                     $src str_replace('?0'''$src)//mp3
  2019.                     //The previous lines are used when creating docs with Dokeos Document tool's htmlarea
  2020.                     //rows marked by 'mp3' are needed because the mp3 plugin inserts the swf-mp3 links in a very strange way
  2021.                     //and we can decode them with those 3 lines, hoping this will not cause errors in case of other htmls,
  2022.                     //created by any other software                                                
  2023.                     //Prepare source and destination paths
  2024.                     $source api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'.dirname($myrow['path']).'/'.$src;
  2025.                     $dest $expdir.'/data/'.$src;
  2026.                     //CopyNCreate($source,$dest);
  2027.                     rcopy($source$dest);
  2028.                 //else...?
  2029.             }
  2030.  
  2031.             //5 Prepare the special "close window" for this test
  2032.             $closewindow "<html><head><link rel='stylesheet' type='text/css' href='../css/default.css'></head><body>"."<br /><div class='message'>$langHotPotatoesFinished</div></body></html>";
  2033.  
  2034.             //Finish is the function of HP to save scores, we insert our scorm function calls to its beginning
  2035.             //'Score' is the variable that tracks the score in HP tests
  2036.             //6
  2037.             $mit "function Finish(){";
  2038.  
  2039.             $js_content "var SaveScoreVariable = 0; // This variable is included by Dokeos LP export\n"."function mySaveScore() // This function is included by Dokeos LP export\n"."{\n"."   if (SaveScoreVariable==0)\n"."        {\n"."       SaveScoreVariable = 1;\n".
  2040.                 //the following function are implemented in SCOFunctions.js
  2041.     "      exitPageStatus = true;\n"."      computeTime();\n"."      doLMSSetValue( 'cmi.core.score.raw', Score );\n"."      doLMSSetValue( 'cmi.core.lesson_status', 'completed' );\n"."      doLMSCommit();\n"."      doLMSFinish();\n".
  2042.                 //                "      document.write('".$closewindow."');\n".
  2043.         //if you insert the previous row, the test does not appear correctly !!!!
  2044.     "        }\n"."}\n"."function Finish(){\n"." mySaveScore();";
  2045.  
  2046.             $start "<script type='text/javascript'> loadPage(); </script>";
  2047.             //7 Replace the current MIT function call by our set of functions. In clear, transform HP to SCORM
  2048.             $content str_replace($mit$js_content$content);
  2049.             //8 Finally, add the API loading calls (although that might have been done first)
  2050.             $content str_replace("</script>""</script>".$scocomfiles.$start$content);
  2051.  
  2052.             //9 Change the filename to add the database ID and export to a new file, 
  2053.             //  setting the circle1_files array for later reuse
  2054.             $filename str_replace('.htm'$id.'.htm'$filename);
  2055.             exporttofile($filename$LPname$id$content);
  2056.  
  2057.             return;
  2058.  
  2059.             //------------------------Dokeos test BEGIN-------------------
  2060.         case "Exercise" :
  2061.             //1 Use the export_exercise() function to do the job of constructing the question's HTML table
  2062.             $expcontent .= export_exercise($item_id);
  2063.             break;
  2064.             //------------------------POST BEGIN---------------------------------------
  2065.         case "Post" :
  2066.             //1 Get the forum post data from the database
  2067.             $tbl_posts =Database::get_course_table(TABLE_FORUM_POST);
  2068.             $tbl_posts_text =Database::get_course_table(TOOL_FORUM_POST_TEXT_TABLE);
  2069.             $result api_sql_query("SELECT * FROM $tbl_posts where post_id=$item_id"__FILE____LINE__);
  2070.             $myrow mysql_fetch_array($result);
  2071.             // grabbing the title of the post
  2072.             $sql_titel "SELECT * FROM $tbl_posts_text WHERE post_id=".$myrow["post_id"];
  2073.             $result_titel api_sql_query($sql_titel__FILE____LINE__);
  2074.             $myrow_titel mysql_fetch_array($result_titel);
  2075.  
  2076.             $posternom $myrow['nom'];
  2077.             $posterprenom $myrow['prenom'];
  2078.             $posttime $myrow['post_time'];
  2079.             $posttext $myrow_titel['post_text'];
  2080.             $posttitle $myrow_titel['post_title'];
  2081.             $posttext str_replace('"'"'"$posttext);
  2082.  
  2083.             //2 Export contents as an HTML table
  2084.             $expcontent .= "<table border='0' cellpadding='3' cellspacing='1' width='100%'>
  2085.                             <tr>
  2086.                                 <td colspan='2' bgcolor='#e6e6e6'><b>$posttitle</b><br />$posttext</td>
  2087.                             </tr>
  2088.                             <tr>
  2089.                                 <td colspan='2'></td>
  2090.                             </tr>
  2091.                             <tr>
  2092.                                 <td bgcolor='#cccccc' align='left'>$lang_author : $posterprenom $posternom</td>
  2093.                                 <td align='right' bgcolor='#cccccc'>$lang_date : $posttime</td>
  2094.                             </tr>
  2095.                             <tr><td colspan='2' height='10'></td></tr>
  2096.                         </table>";
  2097.             break;
  2098.             //------------------------NOT IMPLEMENTED ITEMS BEGIN-------------------
  2099.         case "Forum" :
  2100.         case "Thread" :
  2101.         case "Dropbox" :
  2102.         case "Assignments" :
  2103.         case "Groups" :
  2104.         case "Users" :
  2105.             //1 Instead of building something, put an info message
  2106.             $langItemMissing1 "There was a ";
  2107.             $langItemMissing2 "page (step) here in the original Dokeos Learning Path.";
  2108.             $expcontent .= "<div class='message'>$langItemMissing1 $item_type $langItemMissing2</div>";
  2109.             break;
  2110.             //------------------------Link BEGIN-------------------------------------
  2111.         case "Link _self" :
  2112.         case "Link _blank" :
  2113.             //1 Get the link data from the database
  2114.             $TABLETOOLLINK Database :: get_course_link_table();
  2115.             $result api_sql_query("SELECT * FROM $TABLETOOLLINK WHERE id=$item_id"__FILE____LINE__);
  2116.             $myrow mysql_fetch_array($result);
  2117.             $thelink $myrow["url"];
  2118.             //2 Check the link type (open in blank page or in current page)
  2119.             if ($item_type == "Link _blank")
  2120.             {
  2121.                 $target "_blank";
  2122.             }
  2123.             //3 Write the link to the export string
  2124.             $expcontent .= "<a href='$thelink?SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9' target='".$target."'>$LPname</a>";
  2125.             //4 Change the element type for later changes (this is lost, however, so useless here)
  2126.             $item_type "Link"//to put this to the filename
  2127.             //$LPname="<a href='$thelink?SQMSESSID=36812c2dea7d8d6e708d5e6a2f09b0b9' target=".$target.">$LPname</a>";
  2128.             //i am still not sure about Link export : to export them as files or they can appear in the TOC at once ?
  2129.             //to enable the second possibility, unrem the row $LPname=...
  2130.             break;
  2131.     }
  2132.  
  2133.     //now we add the Done button and the initialize function : loadpage()
  2134.     //not in the case of Documents, HotP
  2135.     if ($item_type != 'Exercise' and ($add_scorm_communications === true))
  2136.     {
  2137.         $expcontent .= $donebutton;
  2138.     }
  2139.     //End the export string with valid HTML tags
  2140.     $expcontent .= "</body></html>";
  2141.  
  2142.     //Prepare new file name
  2143.     $filename $item_type.$id.".htm";
  2144.     //Write the export content to the new file
  2145.     exporttofile('data/'.$filename$LPname$id$expcontent);
  2146.  
  2147. }
  2148.  
  2149. /**
  2150.  * This function exports the given item's description into a separate file
  2151.  * @param    integer    Item id
  2152.  * @param    string    Item type
  2153.  * @param    string    Description
  2154.  * @return void 
  2155.  */
  2156. function exportdescription($id$item_type$description)
  2157. {
  2158.  
  2159.     global $expdir;
  2160.  
  2161.     $filename $item_type.$id.".desc";
  2162.     $expcontent $description;
  2163.     exporttofile($expdir.$filename'description_of_'.$item_type.$id'description_of_item_'.$id$expcontent);
  2164. }
  2165.  
  2166. /**
  2167.  * This function deletes an entire directory
  2168.  * @param    string    The directory path
  2169.  * @return boolean    True on success, false on failure
  2170.  */
  2171. function deldir($dir)
  2172. {
  2173.     $dh opendir($dir);
  2174.     while ($file readdir($dh))
  2175.     {
  2176.         if ($file != "." && $file != "..")
  2177.         {
  2178.             $fullpath $dir."/".$file;
  2179.             if (!is_dir($fullpath))
  2180.             {
  2181.                 unlink($fullpath);
  2182.             }
  2183.             else
  2184.             {
  2185.                 deldir($fullpath);
  2186.             }
  2187.         }
  2188.     }
  2189.  
  2190.     closedir($dh);
  2191.  
  2192.     if (rmdir($dir))
  2193.     {
  2194.         return true;
  2195.     }
  2196.     else
  2197.     {
  2198.         return false;
  2199.     }
  2200. }
  2201.  
  2202. /**
  2203.  * This functions exports the given path. This is the opener function, which is called first
  2204.  * @param    integer     The path id
  2205.  * @return    resource    A zip file, containing a hopefully Scorm compliant course made from the LP. This might happen when we don't actually exit the function first :-)
  2206.  */
  2207. function exportpath($learnpath_id)
  2208. {
  2209.     //1 Initialise variables
  2210.     global $_course$circle1_files$LPnamesafe$LPname$expdir;
  2211.     //$tbl_learnpath_main, $tbl_learnpath_chapter, $tbl_learnpath_item, 
  2212.     $tbl_learnpath_main Database :: get_course_table(TABLE_LEARNPATH_MAIN);
  2213.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  2214.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  2215.  
  2216.     //where applicable, add a scorm "Done" button at the end of all contents
  2217.     $add_scorm_button true;
  2218.  
  2219.     //2 Get the name of the LP
  2220.     include_once (api_get_path(LIBRARY_PATH)."fileUpload.lib.php");
  2221.     $sql "SELECT * FROM $tbl_learnpath_main WHERE (lp_id=$learnpath_id)";
  2222.     $result api_sql_query($sql__FILE____LINE__);
  2223.     $row mysql_fetch_array($result);
  2224.     $LPname $row['learnpath_name'];
  2225.     $LPnamesafe replace_dangerous_char($LPname'strict');
  2226.  
  2227.     //3 Get a temporary dir for creating the zip file    
  2228.     $expdir api_get_path('SYS_COURSE_PATH').$_course['path']."/temp/".$LPnamesafe;
  2229.     $fromdir '../scorm/export/'//this dir contains some standard files
  2230.  
  2231.     deldir($expdir)//make sure the temp dir is cleared
  2232.     mkdir($expdir);
  2233.     mkdir($expdir.'/css');
  2234.     mkdir($expdir.'/data');
  2235.     mkdir($expdir.'/js');
  2236.     mkdir($expdir.'/data/images');
  2237.     mkdir($expdir.'/data/audio');
  2238.     mkdir($expdir.'/data/videos');
  2239.  
  2240.         $circle1 array (//this array contains the types of elements we want to export
  2241.     'Chapter''Agenda''Ad_Valvas''Course_description''Document''Introduction_text''Link _self''Link _blank''Forum''Thread''Post''Exercise''HotPotatoes''Assignments''Dropbox''Users''Groups');
  2242.     //$circle2=array('');
  2243.  
  2244.     //4 Get the first level chapters - YW added parent_item_id condition for multi-level paths
  2245.     $sql "SELECT * FROM $tbl_learnpath_chapter 
  2246.             WHERE (lp_id=$learnpath_id and parent_item_id=0) 
  2247.             ORDER BY display_order ASC";
  2248.     //to get all the elements, we should use the function that builds the table of content get_learnpath_tree
  2249.     //WHERE (lp_id=$learnpath_id) 
  2250.     //ORDER BY parent_item_id, display_order ASC";
  2251.     $result api_sql_query($sql__FILE____LINE__);
  2252.  
  2253.     //5 export the items listed in Circle I one by one
  2254.     while ($row mysql_fetch_array($result))
  2255.     {
  2256.         //5.1 Get items data from the database for this chapter
  2257.         $parent_item_id $row['id'];
  2258.         //$sql2a="SELECT * FROM $tbl_learnpath_chapter WHERE (lp_id=$learnpath_id and parent_item_id=$parent_item_id) ORDER BY display_order ASC";
  2259.         //$result2a=api_sql_query($sql,__FILE__,__LINE__);         
  2260.         $sql2b "SELECT * FROM $tbl_learnpath_item WHERE (parent_item_id=$parent_item_id) ORDER BY display_order ASC";
  2261.         $result2b api_sql_query($sql2b__FILE____LINE__);
  2262.  
  2263.         while ($row2 mysql_fetch_array($result2b))
  2264.         {
  2265.             //5.1.1 Check if the element is in the circle1 array
  2266.             $tobeexported false;
  2267.             for ($i 0$i count($circle1&& !$tobeexported$i ++)
  2268.             {
  2269.                 //if the type is found in the circle1 array, ask for export
  2270.                 if ($circle1[$i== $row2['item_type'])
  2271.                 {
  2272.                     $tobeexported true;
  2273.                 }
  2274.             }
  2275.             //5.1.2 If applicable, export the item to an HTML file (see exportitem function for more details)
  2276.             if ($tobeexported)
  2277.             {
  2278.                 exportitem($row2['id']$row2['item_id']$row2['item_type']$add_scorm_button);
  2279.                 /*if ($row2['description']) {   //put the description of items to a separate file (.desc)
  2280.                     exportdescription($row2['id'],$row2['item_type'],$row2['description']);
  2281.                 }*/
  2282.             }
  2283.         //end of items loop
  2284.     //end of first-level chapters loop
  2285.  
  2286.     //6 export the other necceassary files
  2287.     $filename 'default.css';
  2288.     copy('../css/'.$filename$expdir.'/css/'.$filename);
  2289.     $filename 'ims_xml.xsd';
  2290.     copy($fromdir.$filename$expdir.'/'.$filename);
  2291.     $filename 'imscp_v1p1.xsd';
  2292.     copy($fromdir.$filename$expdir.'/'.$filename);
  2293.     $filename 'imsmd_v1p2.xsd';
  2294.     copy($fromdir.$filename$expdir.'/'.$filename);
  2295.     $filename 'APIWrapper.js';
  2296.     copy($fromdir.$filename$expdir.'/js/'.$filename);
  2297.     $filename 'SCOFunctions.js';
  2298.     copy($fromdir.$filename$expdir.'/js/'.$filename);
  2299.  
  2300.     //in case circle1_files is not defined, build it
  2301.     //$circle1_files
  2302.     //7 create imsmanifest.xml
  2303.     createimsmanifest($circle1_files$learnpath_id);
  2304.  
  2305.     //8 put the files in the exportdir into a zip and force download
  2306.     include_once (api_get_path(LIBRARY_PATH)."pclzip/pclzip.lib.php");
  2307.     //create zipfile of given directory
  2308.     $zip_folder new PclZip(api_get_path('SYS_COURSE_PATH').$_course['path']."/temp/".$LPnamesafe.".zip");
  2309.  
  2310.     $zip_folder->create(api_get_path('SYS_COURSE_PATH').$_course['path']."/temp/".$LPnamesafe."/"PCLZIP_OPT_REMOVE_PATHapi_get_path('SYS_COURSE_PATH').$_course['path']."/temp/");
  2311.     //api_get_path('SYS_COURSE_PATH').$_course['path']."/temp/".$LPnamesafe); // whitout folder
  2312.  
  2313.     // modified by imandak80
  2314.  
  2315.     /*    copy(api_get_path('SYS_COURSE_PATH').$_course['path']."/temp/".$LPnamesafe.".zip",
  2316.              api_get_path('SYS_COURSE_PATH').$_course['path']."/document/".$LPnamesafe.".zip");
  2317.     */
  2318.  
  2319.     $zipfoldername api_get_path('SYS_COURSE_PATH').$_course['path']."/temp/".$LPnamesafe;
  2320.     $zipfilename $zipfoldername.".zip";
  2321.     DocumentManager :: file_send_for_download($zipfilenamefalsebasename($LPnamesafe.".zip"));
  2322.  
  2323.     //9 Delete the temporary zip file and directory
  2324.     include_once (api_get_path(LIBRARY_PATH)."fileManage.lib.php");
  2325.     // in fileManage.lib.php
  2326.     my_delete($zipfilename);
  2327.     my_delete($zipfoldername);
  2328.  
  2329.     //exit;
  2330.  
  2331.     //0 Return the circle_files hash (array)
  2332.     return ($circle1_files)//has been used before...
  2333. }
  2334.  
  2335. /**
  2336.  * Export SCORM content into a zip file
  2337.  *
  2338.  * Basically, all this function does is put the scorm directory back into a zip file (like the one
  2339.  * that was most probably used to import the course at first)
  2340.  * @param    string    Name of the SCORM path (or the directory under which it resides)
  2341.  * @param    array        Not used right now. Should replace the use of global $_course
  2342.  * @return    void 
  2343.  * @author    imandak80
  2344.  */
  2345. function exportSCORM($scormname$course)
  2346. {
  2347.     global $_course;
  2348.  
  2349.     //initialize
  2350.     $tmpname api_get_path('SYS_COURSE_PATH').$_course['path']."/scorm";
  2351.     $zipfoldername $tmpname.$scormname;
  2352.     $zipfilename $zipfoldername.".zip";
  2353.  
  2354.     //create zipfile of given directory
  2355.     include_once (api_get_path(LIBRARY_PATH)."pclzip/pclzip.lib.php");
  2356.     $zip_folder new PclZip($zipfilename);
  2357.     $list 1;
  2358.     //$list = $zip_folder->create($zipfoldername."/",PCLZIP_OPT_REMOVE_PATH,$tmpname.$scormname."/"); // whitout folder
  2359.     $list $zip_folder->create($zipfoldername."/"PCLZIP_OPT_REMOVE_PATH$tmpname);
  2360.     if ($list == 0)
  2361.     {
  2362.         //  echo "Error  : ".$zip_folder->errorInfo(true);
  2363.     }
  2364.  
  2365.     //send to client    
  2366.     DocumentManager :: file_send_for_download($zipfilenamefalsebasename($scormname.".zip"));
  2367.  
  2368.     //clear
  2369.     include_once (api_get_path(LIBRARY_PATH)."fileManage.lib.php");
  2370.     my_delete($zipfilename);
  2371. }
  2372.  
  2373. /**
  2374.  * This function returns an xml tag
  2375.  * $data behaves as the content in case of full tags
  2376.  * $data is an array of attributes in case of returning an opening tag
  2377.  * @param    string 
  2378.  * @param    string 
  2379.  * @param    array 
  2380.  * @param    string 
  2381.  * @return string 
  2382.  */
  2383. function xmltagwrite($tagname$which$data$linebreak "yes")
  2384. {
  2385.     switch ($which)
  2386.     {
  2387.         case "open" :
  2388.             $tag "<".$tagname;
  2389.             $i 0;
  2390.             while ($data[0][$i])
  2391.             {
  2392.                 $tag .= " ".$data[0][$i]."=\"".$data[1][$i]."\"";
  2393.                 $i ++;
  2394.             }
  2395.             if ($tagname == 'file')
  2396.             {
  2397.                 $closing '/';
  2398.             }
  2399.             $tag .= $closing.">";
  2400.             if ($linebreak != 'no_linebreak')
  2401.             {
  2402.                 $tag .= "\n";
  2403.             }
  2404.             break;
  2405.         case "close" :
  2406.             $tag "</".$tagname.">";
  2407.             if ($linebreak != 'no_linebreak')
  2408.             {
  2409.                 $tag .= "\n";
  2410.             }
  2411.             break;
  2412.         case "full" :
  2413.             $tag "<".$tagname;
  2414.             $tag .= ">".$data."</".$tagname.">";
  2415.             if ($linebreak != 'no_linebreak')
  2416.             {
  2417.                 $tag .= "\n";
  2418.             }
  2419.             break;
  2420.     }
  2421.     return $tag;
  2422. }
  2423.  
  2424. /**
  2425.  * This function writes the imsmanifest.xml and exports the chapter names
  2426.  * @param    array        Array containing filenames
  2427.  * @param    integer    Learnpath_id
  2428.  * @return    void 
  2429.  */
  2430. function createimsmanifest($circle1_files$learnpath_id)
  2431. {
  2432.     global $_course$LPname$expdir$LPnamesafe;
  2433.     //$tbl_learnpath_main, $tbl_learnpath_chapter, $tbl_learnpath_item, 
  2434.     $tbl_learnpath_main Database :: get_course_table(TABLE_LEARNPATH_MAIN);
  2435.     $tbl_learnpath_item Database :: get_course_table(TABLE_LEARNPATH_ITEM);
  2436.     $tbl_learnpath_chapter Database :: get_course_table(TABLE_LEARNPATH_CHAPTER);
  2437.  
  2438.     include_once ('../metadata/md_funcs.php')// RH: export metadata
  2439.  
  2440.     //1.1 header
  2441.     /*
  2442.         $header='<?xml version="1.0" encoding="UTF-8"?><manifest identifier="'.$LPnamesafe.'" xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2.xsd" version="IMS CP 1.1.3">'."\n";
  2443.     */
  2444.  
  2445.     //1.2
  2446.     //charset should be dependent on content
  2447.     $mycharset 'ISO-8859-1';
  2448.     $header '<?xml version="1.0" encoding="'.$mycharset.'"?>'."\n<manifest identifier='".$LPnamesafe."' version='1.1'\n xmlns='http://www.imsproject.org/xsd/imscp_rootv1p1p2'\n xmlns:adlcp='http://www.adlnet.org/xsd/adlcp_rootv1p2'\n xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n xsi:schemaLocation='http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd\n http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd\n http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd'>\n";
  2449.  
  2450.     $org .= xmltagwrite('metadata''open');
  2451.     $org .= "  ".xmltagwrite('schema''full''ADL SCORM');
  2452.     $org .= "  ".xmltagwrite('schemaversion''full''1.2');
  2453.     $org .= xmltagwrite('metadata''close');
  2454.  
  2455.     $defaultorgname 'default_org';
  2456.  
  2457.     $attributes[0][0'default';
  2458.     $attributes[1][0$defaultorgname;
  2459.     $org .= xmltagwrite('organizations''open'$attributes);
  2460.  
  2461.     $attributes[0][0'identifier';
  2462.     $attributes[1][0$defaultorgname;
  2463.     $org .= "  ".xmltagwrite('organization''open'$attributes);
  2464.  
  2465.     $org .= "    ".xmltagwrite('title''full'$LPname);
  2466.  
  2467.     //items list
  2468.     $i 0;
  2469.     $previous_item_id '00';
  2470.     while ($circle1_files[0][$i])
  2471.     {
  2472.         //check whether we are in the border of two chapters
  2473.         //if (!$desc=strpos($circle1_files[2][$i],'scription')) {  //this is is needed if the descriptions are exported to file
  2474.  
  2475.         $sql "SELECT * FROM $tbl_learnpath_item WHERE (id=".$circle1_files[2][$i].")";
  2476.         $result api_sql_query($sql__FILE____LINE__);
  2477.         $row mysql_fetch_array($result);
  2478.         $parent_item_id $row['parent_item_id'];
  2479.  
  2480.         if ($parent_item_id != $previous_item_id)
  2481.         {
  2482.             //we create the item tag for the chapter (without indifierref)
  2483.             $sql2 "SELECT * FROM $tbl_learnpath_chapter WHERE (id=".$parent_item_id.")";
  2484.             $result2 api_sql_query($sql2__FILE____LINE__);
  2485.             $row2 mysql_fetch_array($result2);
  2486.             $chapter_name $row2['chapter_name'];
  2487.  
  2488.             $attributes '';
  2489.             $attributes[0]['identifier';
  2490.             $attributes[1]['chapter_'.$row2['id'];
  2491.             $attributes[0]['isvisible';
  2492.             $attributes[1]['1';
  2493.             if ($previous_item_id != '00')
  2494.             {
  2495.                 $org .= "    ".xmltagwrite('item''close');
  2496.             }
  2497.  
  2498.             $org .= "    ".xmltagwrite('item''open'$attributes);
  2499.             $org .= "      ".xmltagwrite('title''full'$chapter_name);
  2500.  
  2501.             if ($row2['chapter_description'!= '')
  2502.             {
  2503.                 //chapter description
  2504.                 $attributes '';
  2505.                 $attributes[0]['identifier';
  2506.                 $attributes[1]['chapter_'.$row2['id'].'_desc';
  2507.                 $attributes[0]['isvisible';
  2508.                 $attributes[1]['1';
  2509.                 $org .= "    ".xmltagwrite('item''open'$attributes);
  2510.                 $org .= "      ".xmltagwrite('title''full'' '.$row2['chapter_description']);
  2511.                 $org .= "    ".xmltagwrite('item''close');
  2512.             }
  2513.         }
  2514.         $previous_item_id $parent_item_id;
  2515.         //}
  2516.  
  2517.         $attributes ''//item output
  2518.         $attributes[0]['identifier';
  2519.         $attributes[1]['item_'.$circle1_files[2][$i];
  2520.         $attributes[0]['identifierref';
  2521.         $attributes[1]['item_ref_'.$circle1_files[2][$i];
  2522.         $attributes[0]['isvisible';
  2523.         $attributes[1]['1';
  2524.         $org .= "    ".xmltagwrite('item''open'$attributes);
  2525.         $org .= "      ".xmltagwrite('title''full'$circle1_files[1][$i]);
  2526.  
  2527.         if ($row['prereq_id'!= '')
  2528.         //item prerequisites
  2529.             $attributes '';
  2530.             $attributes[0]['type';
  2531.             $attributes[1]['aicc_script';
  2532.             $org .= "      ".xmltagwrite('adlcp:prerequisites''open'$attributes"no_linebreak");
  2533.             if ($row['prereq_type'== 'i')
  2534.             {
  2535.                 $org .= 'item_'.$row['prereq_id'];
  2536.             }
  2537.             if ($row['prereq_type'== 'c')
  2538.             {
  2539.                 $org .= 'chapter_'.$row['prereq_id'];
  2540.             }
  2541.             $org .= xmltagwrite('adlcp:prerequisites''close'$attributes);
  2542.         }
  2543.  
  2544.         if ($row['description'!= '')
  2545.         {
  2546.             //item description
  2547.             $attributes '';
  2548.             $attributes[0]['identifier';
  2549.             $attributes[1]['item_'.$circle1_files[2][$i].'_desc';
  2550.             $attributes[0]['isvisible';
  2551.             $attributes[1]['1';
  2552.             $org .= "    ".xmltagwrite('item''open'$attributes);
  2553.             $org .= "      ".xmltagwrite('title''full'' '.$row['description']);
  2554.             $org .= "    ".xmltagwrite('item''close');
  2555.         }
  2556.  
  2557.         $mds new mdstore(TRUE)// RH: export metadata; if no table, create it
  2558.         if (($mdt $mds->mds_get($row['item_type'].'.'.$row['item_id'])))
  2559.             if (($mdo strpos($mdt'<metadata>')) && ($mdc strpos($mdt'</metadata>')))
  2560.                 $org .= "    ".substr($mdt$mdo$mdc $mdo +11)."\n";
  2561.  
  2562.         $org .= "    ".xmltagwrite('item''close');
  2563.         $i ++;
  2564.     }
  2565.  
  2566.     if ($circle1_files)
  2567.     {
  2568.         $org .= "    ".xmltagwrite('item''close');
  2569.     //not needed in case of a blank path
  2570.     $org .= "  ".xmltagwrite('organization''close');
  2571.     $org .= xmltagwrite('organizations''close');
  2572.     $org .= xmltagwrite('resources''open');
  2573.  
  2574.     //resources list
  2575.     $i 0;
  2576.     while ($circle1_files[0][$i])
  2577.     {
  2578.         $attributes '';
  2579.         $attributes[0]['identifier';
  2580.         $attributes[1]['item_ref_'.$circle1_files[2][$i];
  2581.         $attributes[0]['type';
  2582.         $attributes[1]['webcontent';
  2583.         $attributes[0]['adlcp:scormtype';
  2584.         $attributes[1]['sco';
  2585.         $attributes[0]['href';
  2586.         $attributes[1][$circle1_files[0][$i];
  2587.         $org .= "  ".xmltagwrite('resource''open'$attributes);
  2588.  
  2589.         $org .= "    ".xmltagwrite('metadata''open');
  2590.         $org .= "      ".xmltagwrite('schema''full''ADL SCORM');
  2591.         $org .= "      ".xmltagwrite('schemaversion''full''1.2');
  2592.         $org .= "    ".xmltagwrite('metadata''close');
  2593.  
  2594.         $attributes '';
  2595.         $attributes[0]['href';
  2596.         $attributes[1][$circle1_files[0][$i];
  2597.         $org .= "    ".xmltagwrite('file''open'$attributes);
  2598.  
  2599.         $org .= "  ".xmltagwrite('resource''close');
  2600.         $i ++;
  2601.     }
  2602.  
  2603.     $org .= xmltagwrite('resources''close');
  2604.     $org .= xmltagwrite('manifest''close');
  2605.     $manifest $header.$org;
  2606.  
  2607.     exporttofile('imsmanifest.xml''Manifest file''0'$manifest);
  2608. }
  2609.  
  2610. /**
  2611.     * Gets the tags of the file given as parameter
  2612.     *
  2613.     * if $filename is not found, GetSRCTags(filename) will return FALSE
  2614.     * @param    string    file path
  2615.     * @return    mixed        array of strings on success, false on failure
  2616.     * @author unknown
  2617.     * @author included by imandak80
  2618.     */
  2619. function GetSRCTags($fileName)
  2620. {
  2621.     if (!($fp fopen($fileName"r")))
  2622.     {
  2623.         //if file can't be opened, return false
  2624.         return false;
  2625.     }
  2626.     //read file contents
  2627.     $contents fread($fpfilesize($fileName));
  2628.     fclose($fp);
  2629.  
  2630.     $matches array ();
  2631.     $srcList array ();
  2632.     //get all src tags contents in this file. Use multi-line search.
  2633.     preg_match_all('/src(\s)*=(\s)*[\'"]([^\'"]*)[\'"]/mi'$contents$matches)//get the img src as contained between " or '
  2634.  
  2635.     foreach ($matches[3as $match)
  2636.     {
  2637.         if (!in_array($match$srcList))
  2638.         {
  2639.             $srcList[$match;
  2640.         }
  2641.     }
  2642.     if (count($srcList== 0)
  2643.     {
  2644.         return false;
  2645.     }
  2646.     return $srcList;
  2647. }
  2648.  
  2649. /**
  2650.  * Copy file and create directories in the path if needed.
  2651.  *
  2652.  * @param    string    $source Source path
  2653.  * @param    string    $dest Destination path
  2654.  * @return boolean     true on success, false on failure
  2655.  */
  2656. function CopyNCreate($source$dest)
  2657. {
  2658.     if (strcmp($source$dest== 0)
  2659.         return false;
  2660.  
  2661.     $dir "";
  2662.     $tdest explode('/'$dest);
  2663.     for ($i 0$i sizeof($tdest1$i ++)
  2664.     {
  2665.         $dir $dir.$tdest[$i]."/";
  2666.         if (!is_dir($dir))
  2667.             if (!mkdir($dir))
  2668.                 return false;
  2669.     }
  2670.  
  2671.     if (!copy($source$dest))
  2672.         return false;
  2673.  
  2674.     return true;
  2675. }
  2676.  
  2677. function rcopy($source$dest)
  2678. {
  2679.     //error_log($source." -> ".$dest,0);
  2680.     if (!file_exists($source))
  2681.     {
  2682.         //error_log($source." does not exist",0);
  2683.         return false;
  2684.     }
  2685.  
  2686.     if (is_dir($source))
  2687.     {
  2688.         //error_log($source." is a dir",0);
  2689.         //this is a directory
  2690.         //remove trailing '/'
  2691.         if (strrpos($source'/'== sizeof($source1)
  2692.         {
  2693.             $source substr($source0size_of($source1);
  2694.         }
  2695.         if (strrpos($dest'/'== sizeof($dest1)
  2696.         {
  2697.             $dest substr($dest0size_of($dest1);
  2698.         }
  2699.  
  2700.         if (!is_dir($dest))
  2701.         {
  2702.             $res mkdir($dest);
  2703.             if ($res === true)
  2704.             {
  2705.                 return true;
  2706.             }
  2707.             else
  2708.             {
  2709.                 //remove latest part of path and try creating that
  2710.                 if (rcopy(substr($source0strrpos($source'/'))substr($dest0strrpos($dest'/'))))
  2711.                 {
  2712.                     return mkdir($dest);
  2713.                 }
  2714.                 else
  2715.                 {
  2716.                     return false;
  2717.                 }
  2718.             }
  2719.         }
  2720.         return true;
  2721.     }
  2722.     else
  2723.     {
  2724.         //this is presumably a file
  2725.         //error_log($source." is a file",0);
  2726.         if (!copy($source$dest))
  2727.         {
  2728.             //error_log("Could not simple-copy $source",0);
  2729.             $res rcopy(dirname($source)dirname($dest));
  2730.             if ($res === true)
  2731.             {
  2732.                 //error_log("Welcome dir created",0);
  2733.                 return copy($source$dest);
  2734.             }
  2735.             else
  2736.             {
  2737.                 return false;
  2738.                 //error_log("Error creating path",0);
  2739.             }
  2740.         }
  2741.         else
  2742.         {
  2743.             //error_log("Could well simple-copy $source",0);
  2744.             return true;
  2745.         }
  2746.     }
  2747. }
  2748. ?>

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