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

Source for file fileUpload.lib.php

Documentation is available at fileUpload.lib.php

  1. <?php
  2. /*
  3. ==============================================================================
  4.     Dokeos - elearning and course management software
  5.  
  6.     Copyright (c) 2004 Dokeos S.A.
  7.     Copyright (c) 2003 Ghent University (UGent)
  8.     Copyright (c) 2001 Universite catholique de Louvain (UCL)
  9.     Copyright (c) various contributors
  10.  
  11.     For a full list of contributors, see "credits.txt".
  12.     The full license can be read in "license.txt".
  13.  
  14.     This program is free software; you can redistribute it and/or
  15.     modify it under the terms of the GNU General Public License
  16.     as published by the Free Software Foundation; either version 2
  17.     of the License, or (at your option) any later version.
  18.  
  19.     See the GNU General Public License for more details.
  20.  
  21.     Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
  22. ==============================================================================
  23. */
  24. /**
  25. ==============================================================================
  26.     FILE UPLOAD LIBRARY
  27.  
  28. *    This is the file upload library for Dokeos.
  29. *    Include/require it in your code to use its functionality.
  30. *
  31. *    @package dokeos.library
  32. *    @todo test and reorganise
  33. ==============================================================================
  34. */
  35.  
  36. /*
  37. ==============================================================================
  38. List of functions
  39. replace_dangerous_char($filename, $strict = 'loose')
  40. function php2phps ($fileName)
  41. function htaccess2txt($filename)
  42. function disable_dangerous_file($filename)
  43. function unique_name($path,$name)
  44. function get_document_title($name)
  45. function process_uploaded_file($uploaded_file)
  46. function handle_uploaded_document($_course,$uploaded_file,$base_work_dir,$upload_path,$user_id,$to_group_id,$to_user_id,$maxFilledSpace,$unzip=0,$what_if_file_exists='')
  47. function enough_size($fileSize, $dir, $maxDirSpace) //depreciated
  48. function enough_space($file_size, $max_dir_space)
  49. function dir_total_space($dirPath) //depreciated
  50. function documents_total_space()
  51. function add_ext_on_mime($fileName,$fileType)
  52. function treat_uploaded_file($uploadedFile, $baseWorkDir, $uploadPath, $maxFilledSpace, $uncompress= '') //depreciated
  53. function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_filled_space)
  54. function clean_up_files_in_zip($p_event, &$p_header)
  55. function clean_up_path(&$path)
  56. function add_document($_course,$path,$filetype,$filesize,$title)
  57. function update_existing_document($_course,$document_id,$filesize)
  58. function item_property_update_on_folder($_course,$path,$user_id)
  59. function get_levels($filename)
  60. function set_default_settings($upload_path,$filename,$filetype="file")
  61. function search_img_from_html($htmlFile)
  62. function create_unexisting_directory($_course,$user_id,$base_work_dir,$desired_dir_name)
  63. function move_uploaded_file_collection_into_directory($_course, $uploaded_file_collection, $base_work_dir, $missing_files_dir,$user_id,$max_filled_space)
  64. function replace_img_path_in_html_file($originalImgPath, $newImgPath, $htmlFile)
  65. function create_link_file($filePath, $url)
  66. function api_replace_links_in_html($upload_path, $full_file_name)
  67. function api_replace_links_in_string($upload_path, $buffer)
  68. function check_for_missing_files($file)
  69. function build_missing_files_form($missing_files,$upload_path,$file_name)
  70.     Still experimental:
  71. function api_replace_parameter($upload_path, $buffer, $param_name="src")
  72. ==============================================================================
  73. */
  74.  
  75.  
  76. /**
  77.  * replaces "forbidden" characters in a filename string
  78.  *
  79.  * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  80.  * @author - Ren� Haentjens, UGent (RH)
  81.  * @param  string $filename
  82.  * @param  string $strict (optional) remove all non-ASCII
  83.  * @return the cleaned filename
  84.  */
  85.  
  86. function replace_dangerous_char($filename$strict 'loose')
  87. {
  88.     $filename ereg_replace("\.+$"""substr(strtr(ereg_replace(
  89.         "[^!-~\x80-\xFF]""_"trim($filename))'\/:*?"<>|\'',
  90.         /* Keep C1 controls for UTF-8 streams */  '-----_---_')0250));
  91.     if ($strict != 'strict'return $filename;
  92.  
  93.     return ereg_replace("[^!-~]""x"$filename);
  94. }
  95.  
  96. /**
  97.  * Replaces all accentuated characters by non-accentuated characters for filenames, as
  98.  * well as special HTML characters by their HTML entity's first letter.
  99.  * 
  100.  * Although this method is not absolute, it gives good results in general. It first
  101.  * transforms the string to HTML entities (&ocirc;, @oslash;, etc) then removes the
  102.  * HTML character part to result in simple characters (o, o, etc).
  103.  * In the case of special characters (out of alphabetical value) like &nbsp; and &lt;,
  104.  * it will still replace them by the first letter of the HTML entity (n, l, ...) but it
  105.  * is still an acceptable method, knowing we're filtering filenames here...
  106.  * @param    string    The accentuated string
  107.  * @return    string    The escaped string, not absolutely correct but satisfying
  108.  */
  109. function replace_accents($string){
  110.     $string htmlentities($string,ENT_QUOTES);
  111.     return preg_replace("/&([a-z])[a-z]+;/i","$1",$string);
  112. }
  113.  
  114. //------------------------------------------------------------------------------
  115.  
  116. /**
  117.  * change the file name extension from .php to .phps
  118.  * Useful to secure a site !!
  119.  *
  120.  * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  121.  * @param  fileName (string) name of a file
  122.  * @return the filenam phps'ized
  123.  */
  124.  
  125. function php2phps ($fileName)
  126. {
  127.     $fileName preg_replace('/\.(php.?|phtml.?)(\.){0,1}.*$/i''.phps'$fileName);
  128.     return $fileName;
  129. }
  130.  
  131. //------------------------------------------------------------------------------
  132.  
  133. /**
  134.  * Renames .htaccess & .HTACCESS tot htaccess.txt
  135.  *
  136.  * @param string $filename 
  137.  * @return string 
  138.  */
  139. function htaccess2txt($filename)
  140. {
  141.     $filename str_replace('.htaccess''htaccess.txt'$filename);
  142.     $filename str_replace('.HTACCESS''htaccess.txt'$filename);
  143.     return $filename;
  144. }
  145.  
  146. //------------------------------------------------------------------------------
  147.  
  148.  
  149. /**
  150.  * this function executes our safety precautions
  151.  * more functions can be added
  152.  *
  153.  * @param string $filename 
  154.  * @return string 
  155.  * @see php2phps()
  156.  * @see htaccess2txt()
  157.  */
  158. function disable_dangerous_file($filename)
  159. {
  160.     $filename php2phps($filename);
  161.     $filename htaccess2txt($filename);
  162.     return $filename;
  163. }
  164.  
  165. //------------------------------------------------------------------------------
  166.  
  167. /**
  168.  * this function generates a unique name for a file on a given location
  169.  * filenames are changed to name_#.ext
  170.  *
  171.  * @param string $path 
  172.  * @param string $name 
  173.  * @return new unique name
  174.  */
  175. function unique_name($path,$name)
  176. {
  177.     $ext substr(strrchr($name".")0);
  178.     $name_no_ext substr($name0strlen($namestrlen(strstr($name,$ext)));
  179.     $n 0;
  180.     $unique '';
  181.     while(file_exists($path $name_no_ext $unique $ext))
  182.     {
  183.         $unique '_' . ++$n;
  184.     }
  185.     return $name_no_ext $unique $ext;
  186. }
  187.  
  188. //------------------------------------------------------------------------------
  189.  
  190. /**
  191.  * Returns the name without extension, used for the title
  192.  *
  193.  * @param string $name 
  194.  * @return name without the extension
  195.  */
  196. function get_document_title($name)
  197. {
  198.     //if they upload .htaccess...
  199.     $name disable_dangerous_file($name);
  200.     $ext substr(strrchr($name".")0);
  201.     $name_no_ext substr($name0strlen($namestrlen(strstr($name,$ext)));
  202.     $filename addslashes($name_no_ext);
  203.     return $filename;
  204. }
  205.  
  206. //------------------------------------------------------------------------------
  207.  
  208. /**
  209.  * This checks if the upload succeeded
  210.  *
  211.  * @param array $uploaded_file ($_FILES)
  212.  * @return true if upload succeeded
  213.  */
  214. function process_uploaded_file($uploaded_file)
  215. {
  216. /* phpversion is needed to determine if error codes are sent with the file upload */
  217. $phpversion intval(str_replace("."""phpversion()));
  218.  
  219. /* as of version 4.2.0 php gives error codes if something went wrong with the upload */
  220. if ($phpversion >= 420)
  221. {
  222.     //0; There is no error, the file uploaded with success.
  223.     //1; The uploaded file exceeds the upload_max_filesize directive in php.ini.
  224.     if ($uploaded_file['error'== 1)
  225.     {
  226.         Display::display_error_message(get_lang('UplExceedMaxServerUpload')ini_get('upload_max_filesize'))//server config
  227.         return false;
  228.     }
  229.     //2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
  230.     //not used at the moment, but could be handy if we want to limit the size of an upload (e.g. image upload in html editor).
  231.     elseif ($uploaded_file['error'== 2)
  232.     {
  233.         Display::display_error_message(get_lang('UplExceedMaxPostSize')round($_POST['MAX_FILE_SIZE']/1024." KB");
  234.         return false;
  235.     }
  236.     //3; The uploaded file was only partially uploaded.
  237.     elseif ($uploaded_file['error'== 3)
  238.     {
  239.         Display::display_error_message(get_lang('$UplPartialUpload')." ".get_lang('PleaseTryAgain'));
  240.         return false;
  241.     }
  242.     //4; No file was uploaded.
  243.     elseif ($uploaded_file['error'== 4)
  244.     {
  245.         Display::display_error_message(get_lang('UplNoFileUploaded')." "get_lang('UplSelectFileFirst'));
  246.         return false;
  247.     }
  248. }
  249. /* older php versions */
  250. else {
  251.     /* is there an uploaded file? */
  252.     if (!is_uploaded_file($uploaded_file['tmp_name']))
  253.     {
  254.         Display::display_error_message(get_lang('UplNoFileUploaded'));
  255.         return false;
  256.     }
  257.     /* file upload size limitations */
  258.     $max_upload_file_size (ini_get('upload_max_filesize')*1024*1024);
  259.     if (($uploaded_file['size'])>$max_upload_file_size)
  260.     {
  261.         Display::display_error_message(get_lang('UplFileTooBig'));
  262.         return false;
  263.     }
  264.     /* tmp_name gets set to none if something went wrong */
  265.     if ($uploaded_file['tmp_name'== "none")
  266.     {
  267.         Display::display_error_message(get_lang('UplUploadFailed'));
  268.         return false;
  269.     }
  270. }
  271. return true;
  272. }
  273.  
  274. //------------------------------------------------------------------------------
  275.  
  276. /**
  277.  * this function does the save-work for the documents.
  278.  * it handles the uploaded file and adds the properties to the database
  279.  * if unzip=1 and the file is a zipfile, it is extracted
  280.  * if we decide to save ALL kinds of documents in one database,
  281.  * we could extend this with a $type='document', 'scormdocument',...
  282.  *
  283.  * @param array $_course 
  284.  * @param array $uploaded_file ($_FILES)
  285.  * @param string $base_work_dir 
  286.  * @param string $upload_path 
  287.  * @param int $user_id 
  288.  * @param int $to_group_id, 0 for everybody
  289.  * @param int $to_user_id, NULL for everybody
  290.  * @param int $maxFilledSpace 
  291.  * @param int $unzip 1/0
  292.  * @param string $what_if_file_exists overwrite, rename or warn if exists (default)
  293.  * @param boolean Optional output parameter. So far only use for unzip_uploaded_document function. If no output wanted on success, set to false.
  294.  * @return path of the saved file
  295.  */
  296. function handle_uploaded_document($_course,$uploaded_file,$base_work_dir,$upload_path,$user_id,$to_group_id=0,$to_user_id=NULL,$maxFilledSpace='',$unzip=0,$what_if_file_exists='',$output=true)
  297. {
  298.     if(!$user_iddie("Not a valid user.");
  299.  
  300.     //strip slashes
  301.     $uploaded_file['name']=stripslashes($uploaded_file['name']);
  302.     //add extension to files without one (if possible)
  303.     $uploaded_file['name']=add_ext_on_mime($uploaded_file['name'],$uploaded_file['type']);
  304.  
  305.     //check if there is enough space to save the file
  306.     if (!enough_space($uploaded_file['size']$maxFilledSpace))
  307.     {
  308.         Display::display_error_message(get_lang('UplNotEnoughSpace'));
  309.         return false;
  310.     }
  311.     //if the want to unzip, check if the file has a .zip (or ZIP,Zip,ZiP,...) extension
  312.     if ($unzip == && preg_match("/.zip$/"strtolower($uploaded_file['name'])) )
  313.     {
  314.         return unzip_uploaded_document($uploaded_file$upload_path$base_work_dir$maxFilledSpace$output$to_group_id);
  315.         //display_message("Unzipping file");
  316.     }
  317.     //we can only unzip ZIP files (no gz, tar,...)
  318.     elseif ($unzip == && !preg_match("/.zip$/"strtolower($uploaded_file['name'])) )
  319.     {
  320.         Display::display_error_message(get_lang('UplNotAZip')." ".get_lang('PleaseTryAgain'));
  321.         return false;
  322.     }
  323.     else
  324.     {
  325.     //clean up the name and prevent dangerous files
  326.     //remove strange characters
  327.     $clean_name replace_dangerous_char($uploaded_file['name']);
  328.     $clean_name replace_accents($clean_name);
  329.     //no "dangerous" files
  330.     $clean_name disable_dangerous_file($clean_name);
  331.     if(!filter_extension($clean_name))
  332.     {
  333.         Display::display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
  334.         return false;
  335.     }
  336.     else
  337.     {
  338.         //extension is good
  339.         //echo "<br/>clean name = ".$clean_name;
  340.         //echo "<br/>upload_path = ".$upload_path;
  341.         //if the upload path differs from / (= root) it will need a slash at the end
  342.         if ($upload_path!='/')
  343.             $upload_path $upload_path.'/';
  344.         //echo "<br/>upload_path = ".$upload_path;
  345.         $file_path $upload_path.$clean_name;
  346.         //echo "<br/>file path = ".$file_path;
  347.         //full path to where we want to store the file with trailing slash
  348.         $where_to_save $base_work_dir.$upload_path;
  349.         //at least if the directory doesn't exist, tell so
  350.         if(!is_dir($where_to_save)){
  351.             Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')');
  352.             return false;
  353.         }
  354.         //echo "<br/>where to save = ".$where_to_save;
  355.         // full path of the destination
  356.         $store_path $where_to_save.$clean_name;
  357.         //echo "<br/>store path = ".$store_path;
  358.         //name of the document without the extension (for the title)
  359.         $document_name get_document_title($uploaded_file['name']);
  360.         //size of the uploaded file (in bytes)
  361.         $file_size $uploaded_file['size'];
  362.         
  363.         $files_perm api_get_setting('permissions_for_new_files');
  364.         $files_perm octdec(!empty($files_perm)?$files_perm:'0770');
  365.         
  366.             //what to do if the target file exists
  367.             switch ($what_if_file_exists)
  368.                 {
  369.                 //overwrite the file if it exists
  370.                 case 'overwrite':
  371.     
  372.                     //check if the target file exists, so we can give another message
  373.                     if (file_exists($store_path))
  374.                     {
  375.                         $file_exists true;
  376.                     }
  377.                     else
  378.                     {
  379.                         $file_exists false;
  380.                     }
  381.                     if (@move_uploaded_file($uploaded_file['tmp_name']$store_path))
  382.                     {
  383.                         chmod($store_path,$files_perm);
  384.                         if($file_exists)
  385.                         {
  386.                             //UPDATE DATABASE!
  387.                             $document_id DocumentManager::get_document_id($_course,$file_path);
  388.                             if ($document_id)
  389.                             {
  390.                                 //update filesize
  391.                                 update_existing_document($_course,$document_id,$uploaded_file['size']);
  392.                                 //update document item_property
  393.                                 api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentUpdated',$user_id,$to_group_id,$to_user_id);
  394.                             }
  395.                             //if the file is in a folder, we need to update all parent folders
  396.                             item_property_update_on_folder($_course,$upload_path,$user_id);
  397.                             //display success message with extra info to user
  398.                             if($output){
  399.                                 Display::display_confirmation_message(get_lang('UplUploadSucceeded')."<br/>".$file_path .' 'get_lang('UplFileOverwritten'),false);
  400.                             }
  401.                             return $file_path;
  402.                         }
  403.                         else
  404.                         {
  405.                             //put the document data in the database
  406.                             $document_id add_document($_course,$file_path,'file',$file_size,$document_name);
  407.                             if ($document_id)
  408.                             {
  409.                                 //put the document in item_property update
  410.                                 api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentAdded',$user_id,$to_group_id,$to_user_id);
  411.                             }
  412.                             //if the file is in a folder, we need to update all parent folders
  413.                             item_property_update_on_folder($_course,$upload_path,$user_id);
  414.                             //display success message to user
  415.                             Display::display_confirmation_message(get_lang('UplUploadSucceeded')."<br/>".$file_path,false);
  416.                             return $file_path;
  417.                         }
  418.                     }
  419.                     else
  420.                     {
  421.                         Display::display_error_message(get_lang('UplUnableToSaveFile'));
  422.                         return false;
  423.                     }
  424.                     break;
  425.     
  426.                 //rename the file if it exists
  427.                 case 'rename':
  428.                     $new_name unique_name($where_to_save$clean_name);
  429.                     $store_path $where_to_save.$new_name;
  430.                     $new_file_path $upload_path.$new_name;
  431.     
  432.                     if (@move_uploaded_file($uploaded_file['tmp_name']$store_path))
  433.                     {
  434.                         chmod($store_path,$files_perm);
  435.                         
  436.                         //put the document data in the database
  437.                         $document_id add_document($_course,$new_file_path,'file',$file_size,$document_name);
  438.                         if ($document_id)
  439.                         {
  440.                             //update document item_property
  441.                             api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentAdded',$user_id,$to_group_id,$to_user_id);
  442.                         }
  443.                         //if the file is in a folder, we need to update all parent folders
  444.                         item_property_update_on_folder($_course,$upload_path,$user_id);
  445.                         //display success message to user
  446.                         if($output){
  447.                             Display::display_confirmation_message(get_lang('UplUploadSucceeded')"<br>" .get_lang('UplFileSavedAs'$new_file_path,false);
  448.                         }
  449.                         return $new_file_path;
  450.                     }
  451.                     else
  452.                     {
  453.                         Display::display_error_message(get_lang('UplUnableToSaveFile'));
  454.                         return false;
  455.                     }
  456.                     break;
  457.     
  458.                 //only save the file if it doesn't exist or warn user if it does exist
  459.                 default:
  460.                     if (file_exists($store_path))
  461.                     {
  462.                         Display::display_error_message($clean_name.' '.get_lang('UplAlreadyExists'));
  463.                     }
  464.                     else
  465.                     {
  466.                         if (@move_uploaded_file($uploaded_file['tmp_name']$store_path))
  467.                         {                            
  468.                             chmod($store_path,$files_perm);
  469.                                 
  470.                             //put the document data in the database
  471.                             $document_id add_document($_course,$file_path,'file',$file_size,$document_name);
  472.                             if ($document_id)
  473.                             {
  474.                                 //update document item_property
  475.                                 api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentAdded',$user_id,$to_group_id,$to_user_id);
  476.                             }
  477.                             //if the file is in a folder, we need to update all parent folders
  478.                             item_property_update_on_folder($_course,$upload_path,$user_id);
  479.                             //display success message to user
  480.                             if($output){
  481.                                 Display::display_confirmation_message(get_lang('UplUploadSucceeded')."<br/>".$file_path,false);
  482.                             }
  483.                             return $file_path;
  484.                         }
  485.                         else
  486.                         {
  487.                             Display::display_error_message(get_lang('UplUnableToSaveFile'));
  488.                             return false;
  489.                         }
  490.                     }
  491.                     break;
  492.                 }
  493.         }
  494.     }
  495. }
  496.  
  497. //------------------------------------------------------------------------------
  498.  
  499. /**
  500.  * Check if there is enough place to add a file on a directory
  501.  * on the base of a maximum directory size allowed
  502.  * @deprecated use enough_space instead!
  503.  * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  504.  * @param  fileSize (int) - size of the file in byte
  505.  * @param  dir (string) - Path of the directory
  506.  *            whe the file should be added
  507.  * @param  maxDirSpace (int) - maximum size of the diretory in byte
  508.  * @return boolean true if there is enough space,
  509.  *                 boolean false otherwise
  510.  *
  511.  * @see    - enough_size() uses  dir_total_space() function
  512.  */
  513.  
  514. function enough_size($fileSize$dir$maxDirSpace)
  515. {
  516.     if ($maxDirSpace)
  517.     {
  518.         $alreadyFilledSpace dir_total_space($dir);
  519.  
  520.         if ( ($fileSize $alreadyFilledSpace$maxDirSpace)
  521.         {
  522.             return false;
  523.         }
  524.     }
  525.  
  526.     return true;
  527. }
  528.  
  529. //------------------------------------------------------------------------------
  530.  
  531. /**
  532.  * Check if there is enough place to add a file on a directory
  533.  * on the base of a maximum directory size allowed
  534.  *
  535.  * @author Bert Vanderkimpen
  536.  * @param  int file_size size of the file in byte
  537.  * @param array $_course 
  538.  * @param  int max_dir_space maximum size
  539.  * @return boolean true if there is enough space, false otherwise
  540.  *
  541.  * @see enough_space() uses  documents_total_space() function
  542.  */
  543.  
  544. function enough_space($file_size$max_dir_space)
  545. {
  546.     if ($max_dir_space)
  547.     {
  548.         $already_filled_space documents_total_space();
  549.         if ( ($file_size $already_filled_space$max_dir_space)
  550.         {
  551.             return false;
  552.         }
  553.     }
  554.  
  555.     return true;
  556. }
  557.  
  558. //------------------------------------------------------------------------------
  559.  
  560. /**
  561.  * Compute the size already occupied by a directory and is subdirectories
  562.  *
  563.  * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  564.  * @param  dirPath (string) - size of the file in byte
  565.  * @return int - return the directory size in bytes
  566.  */
  567.  
  568. function dir_total_space($dirPath)
  569. {
  570.     $save_dir getcwd();
  571.     chdir ($dirPath;
  572.     $handle opendir($dirPath);
  573.  
  574.     while ($element readdir($handle) )
  575.     {
  576.         if $element == "." || $element == "..")
  577.         {
  578.             continue// skip the current and parent directories
  579.         }
  580.         if is_file($element) )
  581.         {
  582.             $sumSize += filesize($element);
  583.         }
  584.         if is_dir($element) )
  585.         {
  586.             $dirList[$dirPath."/".$element;
  587.         }
  588.     }
  589.  
  590.     closedir($handle;
  591.  
  592.     if sizeof($dirList0)
  593.     {
  594.         foreach($dirList as $j)
  595.         {
  596.             $sizeDir dir_total_space($j);    // recursivity
  597.             $sumSize += $sizeDir;
  598.         }
  599.     }
  600.     chdir($save_dir);//return to initial position
  601.     return $sumSize;
  602. }
  603.  
  604. //------------------------------------------------------------------------------
  605.  
  606. /**
  607.  * Calculate the total size of all documents in a course
  608.  *
  609.  * @author Bert vanderkimpen
  610.  * @param  int $to_group_id (to calculate group document space)
  611.  * @return int total size
  612.  */
  613.  
  614. function documents_total_space($to_group_id='0')
  615. {
  616.     $TABLE_ITEMPROPERTY Database::get_course_table(TABLE_ITEM_PROPERTY);
  617.     $TABLE_DOCUMENT Database::get_course_table(TABLE_DOCUMENT);
  618.  
  619.     $sql "SELECT SUM(size)
  620.     FROM  ".$TABLE_ITEMPROPERTY."  AS props, ".$TABLE_DOCUMENT."  AS docs
  621.     WHERE docs.id = props.ref
  622.     AND props.tool = '".TOOL_DOCUMENT."'
  623.     AND props.to_group_id='".$to_group_id."'
  624.     AND props.visibility <> 2";
  625.  
  626.     $result api_sql_query($sql,__FILE__,__LINE__);
  627.  
  628.     if($result && mysql_num_rows($result)!=0)
  629.     {
  630.         $row mysql_fetch_row($result);
  631.  
  632.         return $row[0];
  633.     }
  634.     else
  635.     {
  636.         return 0;
  637.     }
  638. }
  639.  
  640. //------------------------------------------------------------------------------
  641.  
  642. /**
  643.  * Try to add an extension to files without extension
  644.  * Some applications on Macintosh computers don't add an extension to the files.
  645.  * This subroutine try to fix this on the basis of the MIME type sent
  646.  * by the browser.
  647.  *
  648.  * Note : some browsers don't send the MIME Type (e.g. Netscape 4).
  649.  *        We don't have solution for this kind of situation
  650.  *
  651.  * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  652.  * @author - Bert Vanderkimpen
  653.  * @param  fileName (string) - Name of the file
  654.  * @param  fileType (string) - Type of the file
  655.  * @return fileName (string)
  656.  *
  657.  */
  658.  
  659. function add_ext_on_mime($fileName,$fileType)
  660. {
  661.     /*
  662.      * Check if the file has an extension AND if the browser has sent a MIME Type
  663.      */
  664.  
  665.     if(!ereg("([[:alnum:]]|[[[:punct:]])+\.[[:alnum:]]+$"$fileName)
  666.         && $fileType)
  667.     {
  668.         /*
  669.          * Build a "MIME-types / extensions" connection table
  670.          */
  671.  
  672.         static $mimeType array();
  673.  
  674.         $mimeType["application/msword";             $extension[=".doc";
  675.         $mimeType["application/rtf";                $extension[=".rtf";
  676.         $mimeType["application/vnd.ms-powerpoint";  $extension[=".ppt";
  677.         $mimeType["application/vnd.ms-excel";       $extension[=".xls";
  678.         $mimeType["application/pdf";                $extension[=".pdf";
  679.         $mimeType["application/postscript";         $extension[=".ps";
  680.         $mimeType["application/mac-binhex40";       $extension[=".hqx";
  681.         $mimeType["application/x-gzip";             $extension[="tar.gz";
  682.         $mimeType["application/x-shockwave-flash";  $extension[=".swf";
  683.         $mimeType["application/x-stuffit";          $extension[=".sit";
  684.         $mimeType["application/x-tar";              $extension[=".tar";
  685.         $mimeType["application/zip";                $extension[=".zip";
  686.         $mimeType["application/x-tar";              $extension[=".tar";
  687.         $mimeType["text/html";                      $extension[=".htm";
  688.         $mimeType["text/plain";                     $extension[=".txt";
  689.         $mimeType["text/rtf";                       $extension[=".rtf";
  690.         $mimeType["img/gif";                        $extension[=".gif";
  691.         $mimeType["img/jpeg";                       $extension[=".jpg";
  692.         $mimeType["img/png";                        $extension[=".png";
  693.         $mimeType["audio/midi";                     $extension[=".mid";
  694.         $mimeType["audio/mpeg";                     $extension[=".mp3";
  695.         $mimeType["audio/x-aiff";                   $extension[=".aif";
  696.         $mimeType["audio/x-pn-realaudio";           $extension[=".rm";
  697.         $mimeType["audio/x-pn-realaudio-plugin";    $extension[=".rpm";
  698.         $mimeType["audio/x-wav";                    $extension[=".wav";
  699.         $mimeType["video/mpeg";                     $extension[=".mpg";
  700.         $mimeType["video/quicktime";                $extension[=".mov";
  701.         $mimeType["video/x-msvideo";                $extension[=".avi";
  702.         //test on PC (files with no extension get application/octet-stream)
  703.         //$mimeType[] = "application/octet-stream";      $extension[] =".ext";
  704.  
  705.         /*
  706.          * Check if the MIME type sent by the browser is in the table
  707.          */
  708.  
  709.         foreach($mimeType as $key=>$type)
  710.         {
  711.             if ($type == $fileType)
  712.             {
  713.                 $fileName .=  $extension[$key];
  714.                 break;
  715.             }
  716.         }
  717.  
  718.         unset($mimeType$extension$type$key)// Delete to eschew possible collisions
  719.     }
  720.  
  721.     return $fileName;
  722. }
  723.  
  724. //------------------------------------------------------------------------------
  725.  
  726. /**
  727.  *
  728.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  729.  *
  730.  * @param  array $uploadedFile - follows the $_FILES Structure
  731.  * @param  string $baseWorkDir - base working directory of the module
  732.  * @param  string $uploadPath  - destination of the upload.
  733.  *                                This path is to append to $baseWorkDir
  734.  * @param  int $maxFilledSpace - amount of bytes to not exceed in the base
  735.  *                                working directory
  736.  *
  737.  * @return boolean true if it succeds, false otherwise
  738.  */
  739. function treat_uploaded_file($uploadedFile$baseWorkDir$uploadPath$maxFilledSpace$uncompress'')
  740. {
  741.     $uploadedFile['name']=stripslashes($uploadedFile['name']);
  742.  
  743.     if (!enough_size($uploadedFile['size']$baseWorkDir$maxFilledSpace))
  744.     {
  745.         return api_failure::set_failure('not_enough_space');
  746.     }
  747.  
  748.     if ($uncompress == 'unzip' && preg_match("/.zip$/"strtolower($uploadedFile['name'])) )
  749.     {
  750.         return unzip_uploaded_file($uploadedFile$uploadPath$baseWorkDir$maxFilledSpace);
  751.     }
  752.     else
  753.     {
  754.         $fileName trim($uploadedFile['name']);
  755.  
  756.         // CHECK FOR NO DESIRED CHARACTERS
  757.         $fileName replace_dangerous_char($fileName);
  758.  
  759.         // TRY TO ADD AN EXTENSION TO FILES WITOUT EXTENSION
  760.         $fileName add_ext_on_mime($fileName,$uploadedFile['type']);
  761.  
  762.         // HANDLE PHP FILES
  763.         $fileName php2phps($fileName);
  764.  
  765.         // COPY THE FILE TO THE DESIRED DESTINATION
  766.         if(move_uploaded_file($uploadedFile['tmp_name']$baseWorkDir.$uploadPath."/".$fileName))
  767.                 set_default_settings($uploadPath,$fileName);
  768.  
  769.         return true;
  770.     }
  771. }
  772. /**
  773.  * Manages all the unzipping process of an uploaded file
  774.  *
  775.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  776.  *
  777.  * @param  array  $uploadedFile - follows the $_FILES Structure
  778.  * @param  string $uploadPath   - destination of the upload.
  779.  *                                 This path is to append to $baseWorkDir
  780.  * @param  string $baseWorkDir  - base working directory of the module
  781.  * @param  int $maxFilledSpace  - amount of bytes to not exceed in the base
  782.  *                                 working directory
  783.  *
  784.  * @return boolean true if it succeeds false otherwise
  785.  */
  786.  
  787. function unzip_uploaded_file($uploadedFile$uploadPath$baseWorkDir$maxFilledSpace)
  788. {
  789.     $zipFile new pclZip($uploadedFile['tmp_name']);
  790.  
  791.     // Check the zip content (real size and file extension)
  792.  
  793.     $zipContentArray $zipFile->listContent();
  794.  
  795.     $okScorm=false;
  796.  
  797.     foreach($zipContentArray as $thisContent)
  798.     {
  799.         if preg_match('~.(php.*|phtml)$~i'$thisContent['filename']) )
  800.         {
  801.             return api_failure::set_failure('php_file_in_zip_file');
  802.         }
  803.         elseif(stristr($thisContent['filename'],'imsmanifest.xml'))
  804.         {
  805.             $okScorm=true;
  806.         }
  807.         elseif(stristr($thisContent['filename'],'LMS'))
  808.         {
  809.             $okPlantynScorm1=true;
  810.         }
  811.         elseif(stristr($thisContent['filename'],'REF'))
  812.         {
  813.             $okPlantynScorm2=true;
  814.         }
  815.         elseif(stristr($thisContent['filename'],'SCO'))
  816.         {
  817.             $okPlantynScorm3=true;
  818.         }
  819.         elseif(stristr($thisContent['filename'],'AICC'))
  820.         {
  821.             $okAiccScorm=true;
  822.         }
  823.  
  824.         $realFileSize += $thisContent['size'];
  825.     }
  826.  
  827.     if ((($okPlantynScorm1==trueand ($okPlantynScorm2==trueand ($okPlantynScorm3==true)) or ($okAiccScorm==true))
  828.     {
  829.         $okScorm=true;
  830.     }
  831.  
  832.     if(!$okScorm && defined('CHECK_FOR_SCORM'&& CHECK_FOR_SCORM)
  833.     {
  834.         return api_failure::set_failure('not_scorm_content');
  835.     }
  836.  
  837.     if (enough_size($realFileSize$baseWorkDir$maxFilledSpace) )
  838.     {
  839.         return api_failure::set_failure('not_enough_space');
  840.     }
  841.  
  842.     // it happens on Linux that $uploadPath sometimes doesn't start with '/'
  843.     if($uploadPath[0!= '/')
  844.     {
  845.         $uploadPath='/'.$uploadPath;
  846.     }
  847.  
  848.     if($uploadPath[strlen($uploadPath)-1== '/')
  849.     {
  850.         $uploadPath=substr($uploadPath,0,-1);
  851.     }
  852.  
  853.     /*
  854.     --------------------------------------
  855.         Uncompressing phase
  856.     --------------------------------------
  857.     */
  858.     /*
  859.         The first version, using OS unzip, is not used anymore
  860.         because it does not return enough information.
  861.         We need to process each individual file in the zip archive to
  862.         - add it to the database
  863.         - parse & change relative html links
  864.     */
  865.     if (PHP_OS == 'Linux' && get_cfg_var('safe_mode'&& false)    // *** UGent, changed by OC ***
  866.     {
  867.         // Shell Method - if this is possible, it gains some speed
  868.         exec("unzip -d \"".$baseWorkDir.$uploadPath."/\"".$uploadedFile['name']." "
  869.              .$uploadedFile['tmp_name']);
  870.     }
  871.     else
  872.     {
  873.         // PHP method - slower...
  874.         $save_dir getcwd();
  875.         chdir($baseWorkDir.$uploadPath);
  876.         $unzippingState $zipFile->extract();
  877.         for($j=0;$j<count($unzippingState);$j++)
  878.         {
  879.             $state=$unzippingState[$j];
  880.  
  881.             //fix relative links in html files
  882.             $extension strrchr($state["stored_filename"]".");
  883.         }
  884.  
  885.         if($dir=@opendir($baseWorkDir.$uploadPath))
  886.         {
  887.             while($file=readdir($dir))
  888.             {
  889.                 if($file != '.' && $file != '..')
  890.                 {
  891.                     $filetype="file";
  892.  
  893.                     if(is_dir($baseWorkDir.$uploadPath.'/'.$file)) $filetype="folder";
  894.  
  895.                     $safe_file=replace_dangerous_char($file,'strict');
  896.  
  897.                     @rename($baseWorkDir.$uploadPath.'/'.$file,$baseWorkDir.$uploadPath.'/'.$safe_file);
  898.  
  899.                     set_default_settings($uploadPath,$safe_file,$filetype);
  900.                 }
  901.             }
  902.  
  903.             closedir($dir);
  904.         }
  905.         chdir($save_dir)//back to previous dir position
  906.     }
  907.  
  908.     return true;
  909. }
  910. //------------------------------------------------------------------------------
  911.  
  912. /**
  913.  * Manages all the unzipping process of an uploaded document
  914.  * This uses the item_property table for properties of documents
  915.  *
  916.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  917.  * @author Bert Vanderkimpen
  918.  *
  919.  * @param  array  $uploadedFile - follows the $_FILES Structure
  920.  * @param  string $uploadPath   - destination of the upload.
  921.  *                                 This path is to append to $baseWorkDir
  922.  * @param  string $baseWorkDir  - base working directory of the module
  923.  * @param  int $maxFilledSpace  - amount of bytes to not exceed in the base
  924.  *                                 working directory
  925.  * @param        boolean    Output switch. Optional. If no output not wanted on success, set to false.
  926.  *
  927.  * @return boolean true if it succeeds false otherwise
  928.  */
  929.  
  930. function unzip_uploaded_document($uploaded_file$upload_path$base_work_dir$max_filled_space$output true$to_group_id=0)
  931. {
  932.     global $_course;
  933.     global $_user;
  934.     global $to_user_id;
  935.     global $to_group_id;
  936.  
  937.     $zip_file new pclZip($uploaded_file['tmp_name']);
  938.  
  939.     // Check the zip content (real size and file extension)
  940.  
  941.     $zip_content_array $zip_file->listContent();
  942.  
  943.     foreach((array) $zip_content_array as $this_content)
  944.     {
  945.         $real_filesize += $this_content['size'];
  946.     }
  947.  
  948.     if (enough_space($real_filesize$max_filled_space) )
  949.     {
  950.         Display::display_error_message(get_lang('UplNotEnoughSpace'));
  951.         return false;
  952.     }
  953.  
  954.     // it happens on Linux that $uploadPath sometimes doesn't start with '/'
  955.     if($upload_path[0!= '/')
  956.     {
  957.         $upload_path='/'.$upload_path;
  958.     }
  959.     /*
  960.     --------------------------------------
  961.         Uncompressing phase
  962.     --------------------------------------
  963.     */
  964.     //get into the right directory
  965.     $save_dir getcwd();
  966.     chdir($base_work_dir.$upload_path);
  967.     //we extract using a callback function that "cleans" the path
  968.     $unzipping_state $zip_file->extract(PCLZIP_CB_PRE_EXTRACT'clean_up_files_in_zip');
  969.     // Add all documents in the unzipped folder to the database
  970.     add_all_documents_in_folder_to_database($_course,$_user['user_id'],$base_work_dir,$upload_path == '/' '' $upload_path$to_group_id);
  971.     
  972.     return true;
  973.     /*
  974.     if ($upload_path != '/')
  975.         $upload_path = $upload_path.'/';
  976.     if($unzipping_state!=0)
  977.     {
  978.         for($j=0;$j<count($unzipping_state);$j++)
  979.         {
  980.             $state=$unzipping_state[$j];
  981.             $filename = $state['stored_filename'];
  982.             //echo("<br>filename = ".$filename."<br>");
  983.             $filename2 = $state['filename'];
  984.             //echo("<br>filename2 = ".$filename2."<br>");
  985.             $filetype="file";
  986.             //if(is_dir($filename))
  987.             if($state['folder']==1)
  988.             {
  989.                 $filetype="folder";
  990.                 $endchar=substr($filename,strlen($filename)-1,1);
  991.                 if($endchar=="\\" || $endchar=="/")
  992.                     $filename=substr($filename,0,strlen($filename)-1);
  993.             }
  994.  
  995.             //store document in database
  996.             if($state['status']=="ok" || $state['status']=="already_a_directory")
  997.             {
  998.                 //echo $base_work_dir.$upload_path.clean_up_path($state["stored_filename"])." (".$filetype.")<br/>";
  999.                 $cleaned_up_filename = clean_up_path($filename);
  1000.                 $file_path = $upload_path.$cleaned_up_filename;
  1001.                 echo("file path = ".$file_path."<br>");
  1002.  
  1003.                 //this is a quick fix for zipfiles that have files in folders but the folder is not stored in the zipfile
  1004.                 //if the path has folders, check if they already are in the database
  1005.                 if(dirname('/'.$cleaned_up_filename)!='/' AND dirname('/'.$cleaned_up_filename)!='\\')
  1006.                 {
  1007.                     $folder_id=DocumentManager::get_document_id($_course,$upload_path.dirname($cleaned_up_filename));
  1008.                     if(!$folder_id)
  1009.                     {
  1010.                         echo($upload_path.dirname($cleaned_up_filename).' not found in database!<br>');
  1011.                         $folder_id = add_document($_course,$upload_path.dirname($cleaned_up_filename),'folder',0,basename(dirname($cleaned_up_filename)));
  1012.                         if($folder_id)
  1013.                         {
  1014.                             api_item_property_update($_course,TOOL_DOCUMENT,$folder_id,'FolderAdded',$_user['user_id'],$to_group_id,$to_user_id);
  1015.                             //echo('folder '.$upload_path.dirname($cleaned_up_filename)." added<br>\n");
  1016.                         }
  1017.                     }
  1018.                 }
  1019.  
  1020.                 $store_path = $base_work_dir.$file_path;
  1021.                 //echo("store path = ".$store_path."<br>");
  1022.                 $document_name = get_document_title(basename($filename));
  1023.                 //echo("document_name = ".$document_name."<br><br>");
  1024.                 //put the document data in the database
  1025.                 //if the file/dir does not exist, just add it
  1026.                 //if(!file_exists($store_path)) <- not working, as the file is already extracted
  1027.                 //so we check if the document is already in the database
  1028.                 $document_id = DocumentManager::get_document_id($_course,$file_path);
  1029.                 if(!$document_id)
  1030.                 {
  1031.                 $document_id = add_document($_course,$file_path,$filetype,$state['size'],$document_name);
  1032.                     if ($document_id)
  1033.                     {
  1034.                         $lastedit_type = ($filetype=='folder')?'FolderAdded':'DocumentAdded';
  1035.                         //update item property for document
  1036.                         api_item_property_update($_course,TOOL_DOCUMENT,$document_id,$lastedit_type,$_user['user_id'],$to_group_id,$to_user_id);
  1037.                     }
  1038.                 }
  1039.                 //file/dir exists -> update
  1040.                 else
  1041.                 {
  1042.                     $lastedit_type = ($filetype=='folder')?'FolderUpdated':'DocumentUpdated';
  1043.                     //update the document in item_property
  1044.                     api_item_property_update($_course,TOOL_DOCUMENT,$document_id,$lastedit_type,$_user['user_id'],$to_group_id,$to_user_id);
  1045.                 }
  1046.  
  1047.             }
  1048.         }
  1049.     //print_r_pre($zip_content_array);
  1050.     //if the file is in a folder, we need to update all parent folders
  1051.     item_property_update_on_folder($_course,$upload_path,$_user['user_id']);
  1052.     //display success message to user
  1053.     chdir($save_dir); //return to previous dir position
  1054.     if($output){
  1055.         Display::display_normal_message(get_lang('UplZipExtractSuccess'));
  1056.     }
  1057.     return true;
  1058.     }
  1059.     else {
  1060.         //zip file could not be extracted -> corrupt file
  1061.         Display::display_error_message(get_lang('UplZipCorrupt'));
  1062.         return false;
  1063.     }
  1064.     */
  1065. }
  1066.  
  1067. //------------------------------------------------------------------------------
  1068.  
  1069. /**
  1070.  * this function is a callback function that is used while extracting a zipfile
  1071.  * http://www.phpconcept.net/pclzip/man/en/index.php?options-pclzip_cb_pre_extract
  1072.  *
  1073.  * @param $p_event 
  1074.  * @param $p_header 
  1075.  * @return (If the function returns 1, then the extraction is resumed)
  1076.  */
  1077. function clean_up_files_in_zip($p_event&$p_header)
  1078. {
  1079.     $res clean_up_path($p_header['filename']);
  1080.     return $res;
  1081. }
  1082.  
  1083. //------------------------------------------------------------------------------
  1084.  
  1085. /**
  1086.  * this function cleans up a given path
  1087.  * by eliminating dangerous file names and cleaning them
  1088.  *
  1089.  * @param string $path 
  1090.  * @return $path 
  1091.  * @see disable_dangerous_file()
  1092.  * @see replace_dangerous_char()
  1093.  */
  1094. function clean_up_path(&$path)
  1095. {
  1096.     //split the path in folders and files
  1097.     $path_array explode('/',$path);
  1098.     //clean up every foler and filename in the path
  1099.     $val '';
  1100.     foreach($path_array as $key => $val)
  1101.     {
  1102.         //we don't want to lose the dots in ././folder/file (cfr. zipfile)
  1103.         if($path_array[$key]!='.')
  1104.             $path_array[$keydisable_dangerous_filereplace_dangerous_char($val) );
  1105.     }
  1106.     //join the "cleaned" path (modified in-place as passed by reference)
  1107.     $path implode('/',$path_array);
  1108.     $res filter_extension($path);
  1109.     return $res;
  1110. }
  1111.  
  1112. /**
  1113.  * Check if the file is dangerous, based on extension and/or mimetype.
  1114.  * The list of extensions accepted/rejected can be found from
  1115.  * api_get_setting('upload_extensions_exclude') and api_get_setting('upload_extensions_include')
  1116.  * @param    string     filename passed by reference. The filename will be modified if filter rules say so! (you can include path but the filename should look like 'abc.html')
  1117.  * @return    int        0 to skip file, 1 to keep file
  1118.  */
  1119. function filter_extension(&$filename)
  1120. {
  1121.     if(substr($filename,-1)=='/'){return 1;//authorize directories
  1122.     $blacklist api_get_setting('upload_extensions_list_type');
  1123.     if($blacklist!='whitelist')//if = blacklist
  1124.     {
  1125.         $extensions split(';',strtolower(api_get_setting('upload_extensions_blacklist')));
  1126.         $skip api_get_setting('upload_extensions_skip');
  1127.         $ext strrchr($filename".");
  1128.         $ext substr($ext,1);
  1129.         if(empty($ext)){return 1;}//we're in blacklist mode, so accept empty extensions
  1130.         if(in_array(strtolower($ext),$extensions))
  1131.         {
  1132.             if($skip=='true')
  1133.             {
  1134.                 return 0;
  1135.             }
  1136.             else
  1137.             {
  1138.                 $new_ext api_get_setting('upload_extensions_replace_by');
  1139.                 $filename str_replace(".".$ext,".".$new_ext,$filename);
  1140.                 return 1;
  1141.             }
  1142.         }
  1143.         else
  1144.         {
  1145.             return 1;
  1146.         }
  1147.     }
  1148.     else
  1149.     {
  1150.         $extensions split(';',strtolower(api_get_setting('upload_extensions_whitelist')));
  1151.         $skip api_get_setting('upload_extensions_skip');
  1152.         $ext strrchr($filename".");
  1153.         $ext substr($ext,1);
  1154.         if(empty($ext)){return 1;}//accept empty extensions
  1155.         if(!in_array(strtolower($ext),$extensions))
  1156.         {
  1157.             if($skip=='true')
  1158.             {
  1159.                 return 0;
  1160.             }
  1161.             else
  1162.             {
  1163.                 $new_ext api_get_setting('upload_extensions_replace_by');
  1164.                 $filename str_replace(".".$ext,".".$new_ext,$filename);
  1165.                 return 1;
  1166.             }
  1167.         }
  1168.         else
  1169.         {
  1170.             return 1;
  1171.         }
  1172.     }
  1173. }
  1174.  
  1175. //------------------------------------------------------------------------------
  1176.  
  1177. /**
  1178.  * Adds a new document to the database
  1179.  *
  1180.  * @param array $_course 
  1181.  * @param string $path 
  1182.  * @param string $filetype 
  1183.  * @param int $filesize 
  1184.  * @param string $title 
  1185.  * @return id if inserted document
  1186.  */
  1187. function add_document($_course,$path,$filetype,$filesize,$title,$comment=NULL$readonly=0)
  1188. {
  1189.     $table_document Database::get_course_table(TABLE_DOCUMENT,$_course['dbName']);
  1190.     $sql="INSERT INTO $table_document
  1191.     (`path`,`filetype`,`size`,`title`, `comment`, readonly)
  1192.     VALUES ('$path','$filetype','$filesize','".
  1193.     Database::escape_string($title)."', '$comment',$readonly)";
  1194.     if(api_sql_query($sql,__FILE__,__LINE__))
  1195.     {
  1196.         //display_message("Added to database (id ".mysql_insert_id().")!");
  1197.         return mysql_insert_id();
  1198.     }
  1199.     else
  1200.     {
  1201.         //display_error("The uploaded file could not be added to the database (".mysql_error().")!");
  1202.         return false;
  1203.     }
  1204. }
  1205.  
  1206. //------------------------------------------------------------------------------
  1207.  
  1208. /*
  1209. function get_document_id() moved to document.lib.php
  1210. */
  1211.  
  1212. //------------------------------------------------------------------------------
  1213.  
  1214. /**
  1215.  * Update an existing document in the database
  1216.  * as the file exists, we only need to change the size
  1217.  *
  1218.  * @param array $_course 
  1219.  * @param int $document_id 
  1220.  * @param int $filesize 
  1221.  * @param int $readonly 
  1222.  * @return boolean true /false
  1223.  */
  1224. function update_existing_document($_course,$document_id,$filesize,$readonly=0)
  1225.     $document_table Database::get_course_table(TABLE_DOCUMENT,$_course['dbName']);
  1226.     $sql="UPDATE $document_table SET size = '$filesize' , readonly = '$readonly' WHERE id='$document_id'";
  1227.     if(api_sql_query($sql,__FILE__,__LINE__))
  1228.     {
  1229.         return true;
  1230.     }
  1231.     else
  1232.     {
  1233.         return false;
  1234.     }
  1235. }
  1236.  
  1237.  
  1238. /**
  1239.  * this function updates the last_edit_date, last edit user id on all folders in a given path
  1240.  *
  1241.  * @param array $_course 
  1242.  * @param string $path 
  1243.  * @param int $user_id 
  1244.  */
  1245. function item_property_update_on_folder($_course,$path,$user_id)
  1246. {
  1247.     //display_message("Start update_lastedit_on_folder");
  1248.     //if we are in the root, just return... no need to update anything
  1249.     if ($path=='/')
  1250.         return;
  1251.  
  1252.     //if the given path ends with a / we remove it
  1253.     $endchar=substr($path,strlen($path)-1,1);
  1254.     if($endchar=='/')
  1255.     $path=substr($path,0,strlen($path)-1);
  1256.     $TABLE_ITEMPROPERTY Database::get_course_table(TABLE_ITEM_PROPERTY,$_course['dbName']);
  1257.  
  1258.     //get the time
  1259.     $time date("Y-m-d H:i:s"time());
  1260.  
  1261.     //get all paths in the given path
  1262.     // /folder/subfolder/subsubfolder/file
  1263.     // if file is updated, subsubfolder, subfolder and folder are updated
  1264.  
  1265.     $exploded_path explode('/',$path);
  1266.  
  1267.     foreach ($exploded_path as $key => $value{
  1268.         //we don't want a slash before our first slash
  1269.         if($key!=0){
  1270.             $newpath .= "/".$value;
  1271.  
  1272.             //echo "path= ".$newpath."<br>";
  1273.             //select ID of given folder
  1274.             $folder_id DocumentManager::get_document_id($_course,$newpath);
  1275.  
  1276.             if($folder_id)
  1277.             {
  1278.                 $sql "UPDATE $TABLE_ITEMPROPERTY SET `lastedit_date`='$time',`lastedit_type`='DocumentInFolderUpdated', `lastedit_user_id`='$user_id' WHERE tool='".TOOL_DOCUMENT."' AND ref='$folder_id'";
  1279.                 api_sql_query($sql,__FILE__,__LINE__);
  1280.             }
  1281.         }
  1282.     }
  1283. }
  1284. //------------------------------------------------------------------------------
  1285.  
  1286. /**
  1287.  * Returns the directory depth of the file.
  1288.  *
  1289.  * @author    Olivier Cauberghe <olivier.cauberghe@ugent.be>
  1290.  * @param    path+filename eg: /main/document/document.php
  1291.  * @return    The directory depth
  1292.  */
  1293. function get_levels($filename)
  1294. {
  1295.     $levels=explode("/",$filename);
  1296.     if(empty($levels[count($levels)-1])) unset($levels[count($levels)-1]);
  1297.     return count($levels);
  1298. }
  1299.  
  1300. /*
  1301.     function file_set_default_settings
  1302.  
  1303.     moved to fileManage.lib.php,
  1304.     class FileManager
  1305. */
  1306.  
  1307. //------------------------------------------------------------------------------
  1308.  
  1309. /**
  1310.  * Adds file to document table in database
  1311.  * @deprecated, use file_set_default_settings instead
  1312.  *
  1313.  * @author    Olivier Cauberghe <olivier.cauberghe@ugent.be>
  1314.  * @param    path,filename 
  1315.  * @action    Adds an entry to the document table with the default settings.
  1316.  */
  1317. function set_default_settings($upload_path,$filename,$filetype="file")
  1318. {
  1319.     global $dbTable,$_configuration;
  1320.     global $default_visibility;
  1321.  
  1322.     if (!$default_visibility)
  1323.         $default_visibility="v";
  1324.  
  1325.     $upload_path=str_replace('\\','/',$upload_path);
  1326.     $upload_path=str_replace("//","/",$upload_path);
  1327.  
  1328.     if($upload_path == '/')
  1329.     {
  1330.         $upload_path='';
  1331.     }
  1332.     elseif(!empty($upload_path&& $upload_path[0!= '/')
  1333.     {
  1334.         $upload_path="/$upload_path";
  1335.     }
  1336.  
  1337.     $endchar=substr($filename,strlen($filename)-1,1);
  1338.  
  1339.     if($endchar == '/')
  1340.     {
  1341.         $filename=substr($filename,0,-1);
  1342.     }
  1343.  
  1344.     //$dbTable already has `backticks`!
  1345.     //$query="select count(*) as bestaat from `$dbTable` where path='$upload_path/$filename'";
  1346.     $query="select count(*) as bestaat from $dbTable where path='$upload_path/$filename'";
  1347.     $result=api_sql_query($query,__FILE__,__LINE__);
  1348.     $row=mysql_fetch_array($result);
  1349.     if($row["bestaat"]>0)
  1350.         //$query="update `$dbTable` set path='$upload_path/$filename',visibility='$default_visibility', filetype='$filetype' where path='$upload_path/$filename'";
  1351.         $query="update $dbTable set path='$upload_path/$filename',visibility='$default_visibility', filetype='$filetype' where path='$upload_path/$filename'";
  1352.     else //$query="INSERT INTO `$dbTable` (path,visibility,filetype) VALUES('$upload_path/$filename','$default_visibility','$filetype')";
  1353.         $query="INSERT INTO $dbTable (path,visibility,filetype) VALUES('$upload_path/$filename','$default_visibility','$filetype')";
  1354.     api_sql_query($query,__FILE__,__LINE__);
  1355. }
  1356.  
  1357. //------------------------------------------------------------------------------
  1358.  
  1359. /**
  1360.  * retrieve the image path list in a html file
  1361.  *
  1362.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  1363.  * @param  string $htmlFile 
  1364.  * @return array -  images path list
  1365.  */
  1366.  
  1367. function search_img_from_html($htmlFile)
  1368. {
  1369.     $imgFilePath array();
  1370.  
  1371.     $fp fopen($htmlFile"r"or die('<center>can not open file</center>');
  1372.  
  1373.     // search and store occurences of the <IMG> tag in an array
  1374.  
  1375.     $buffer fread$fpfilesize($htmlFile) ) or die('<center>can not read file</center>');;
  1376.  
  1377.     $matches array();
  1378.     if preg_match_all('~<[[:space:]]*img[^>]*>~i'$buffer$matches) )
  1379.     {
  1380.         $imgTagList $matches[0];
  1381.     }
  1382.  
  1383.     fclose ($fp)unset($buffer);
  1384.  
  1385.     // Search the image file path from all the <IMG> tag detected
  1386.  
  1387.     if sizeof($imgTagList)  0)
  1388.     {
  1389.         foreach($imgTagList as $thisImgTag)
  1390.         {
  1391.             if preg_match('~src[[:space:]]*=[[:space:]]*[\"]{1}([^\"]+)[\"]{1}~i',
  1392.                             $thisImgTag$matches) )
  1393.             {
  1394.                 $imgPathList[$matches[1];
  1395.             }
  1396.         }
  1397.  
  1398.         $imgPathList array_unique($imgPathList);        // remove duplicate entries
  1399.     }
  1400.  
  1401.     return $imgPathList;
  1402.  
  1403. }
  1404.  
  1405. //------------------------------------------------------------------------------
  1406.  
  1407. /**
  1408.  * creates a new directory trying to find a directory name
  1409.  * that doesn't already exist
  1410.  * (we could use unique_name() here...)
  1411.  *
  1412.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  1413.  * @author Bert Vanderkimpen
  1414.  * @param array $_course current course information
  1415.  * @param int $user_id current user id
  1416.  * @param string $desiredDirName complete path of the desired name
  1417.  * @return string actual directory name if it succeeds,
  1418.  *          boolean false otherwise
  1419.  */
  1420.  
  1421. function create_unexisting_directory($_course,$user_id,$to_group_id,$to_user_id,$base_work_dir,$desired_dir_name$title null)
  1422. {
  1423.     $nb '';
  1424.     while file_exists($base_work_dir.$desired_dir_name.$nb) )
  1425.     {
  1426.         $nb += 1;
  1427.     }
  1428.     if$title == null)
  1429.     {
  1430.         $title basename($desired_dir_name);
  1431.     }
  1432.     if mkdir($base_work_dir.$desired_dir_name.$nb))
  1433.     {
  1434.         $perm api_get_setting('permissions_for_new_directories');
  1435.         $perm octdec(!empty($perm)?$perm:'0770');
  1436.         chmod($base_work_dir.$desired_dir_name.$nb,$perm);
  1437.         $document_id add_document($_course$desired_dir_name.$nb,'folder',0,$title);
  1438.         if ($document_id)
  1439.         {
  1440.         //update document item_property
  1441.         api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'FolderCreated',$user_id,$to_group_id,$to_user_id);
  1442.         return $desired_dir_name.$nb;
  1443.         }
  1444.     }
  1445.     else
  1446.     {
  1447.     return false;
  1448.     }
  1449. }
  1450.  
  1451. //------------------------------------------------------------------------------
  1452.  
  1453. /**
  1454.  * Handles uploaded missing images
  1455.  *
  1456.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  1457.  * @author Bert Vanderkimpen
  1458.  * @param array $_course 
  1459.  * @param array $uploaded_file_collection - follows the $_FILES Structure
  1460.  * @param string $base_work_dir 
  1461.  * @param string $missing_files_dir 
  1462.  * @param int $user_id 
  1463.  * @param int $max_filled_space 
  1464.  */
  1465.  
  1466. function move_uploaded_file_collection_into_directory($_course$uploaded_file_collection$base_work_dir$missing_files_dir,$user_id,$to_group_id,$to_user_id,$max_filled_space)
  1467. {
  1468.     $number_of_uploaded_images count($uploaded_file_collection['name']);
  1469.     for ($i=0$i $number_of_uploaded_images$i++)
  1470.         {
  1471.         $missing_file['name'$uploaded_file_collection['name'][$i];
  1472.         $missing_file['type'$uploaded_file_collection['type'][$i];
  1473.         $missing_file['tmp_name'$uploaded_file_collection['tmp_name'][$i];
  1474.         $missing_file['error'$uploaded_file_collection['error'][$i];
  1475.         $missing_file['size'$uploaded_file_collection['size'][$i];
  1476.  
  1477.         $upload_ok process_uploaded_file($missing_file);
  1478.             if($upload_ok)
  1479.             {
  1480.             $new_file_list[handle_uploaded_document($_course,$missing_file,$base_work_dir,$missing_files_dir,$user_id,$to_group_id,$to_user_id,$max_filled_space,0,'overwrite');
  1481.             }
  1482.         unset($missing_file);
  1483.         }
  1484.     return $new_file_list;
  1485. }
  1486.  
  1487. //------------------------------------------------------------------------------
  1488.  
  1489. //------------------------------------------------------------------------------
  1490.  
  1491. /*
  1492.  * Open the old html file and replace the src path into the img tag
  1493.  * This also works for files in subdirectories.
  1494.  * @param $originalImgPath is an array
  1495.  * @param $newImgPath is an array
  1496.  */
  1497. function replace_img_path_in_html_file($originalImgPath$newImgPath$htmlFile)
  1498. {
  1499.     global $_course;
  1500.  
  1501.     /*
  1502.      * Open the file
  1503.      */
  1504.     $fp fopen($htmlFile"r");
  1505.     $buffer fread ($fpfilesize ($htmlFile));
  1506.  
  1507.     /*
  1508.      * Fix the image tags
  1509.      */
  1510.     for ($i 0$fileNb count($originalImgPath)$i $fileNb $i++)
  1511.     {
  1512.         $replace_what $originalImgPath[$i];
  1513.         /*
  1514.         we only need the directory and the filename
  1515.         /path/to/file_html_files/missing_file.gif -> file_html_files/missing_file.gif
  1516.         */
  1517.         $exploded_file_path explode('/',$newImgPath[$i]);
  1518.         $replace_by $exploded_file_path[count($exploded_file_path)-2].'/'.$exploded_file_path[count($exploded_file_path)-1];
  1519.         //$message .= "Element [$i] <b>" . $replace_what . "</b> replaced by <b>" . $replace_by . "</b><br>"; //debug
  1520.         //api_display_debug_info($message);
  1521.  
  1522.         $buffer str_replace$replace_what$replace_by$buffer);
  1523.     }
  1524.  
  1525.     $new_html_content .= $buffer;
  1526.  
  1527.     fclose ($fpor die ('<center>cannot close file</center>');;
  1528.  
  1529.     /*
  1530.      * Write the resulted new file
  1531.      */
  1532.     $fp fopen($htmlFile'w')      or die('<center>cannot open file</center>');
  1533.     fwrite($fp$new_html_content)   or die('<center>cannot write in file</center>');
  1534. }
  1535.  
  1536. //------------------------------------------------------------------------------
  1537.  
  1538. /**
  1539.  * Creates a file containing an html redirection to a given url
  1540.  *
  1541.  * @author Hugues Peeters <hugues.peeters@claroline.net>
  1542.  * @param string $filePath 
  1543.  * @param string $url 
  1544.  * @return void 
  1545.  */
  1546.  
  1547. function create_link_file($filePath$url)
  1548. {
  1549.     $fileContent '<html>'
  1550.                   .'<head>'
  1551.                   .'<meta http-equiv="refresh" content="1;url='.$url.'">'
  1552.                   .'</head>'
  1553.                   .'<body>'
  1554.                   .'</body>'
  1555.                   .'</html>';
  1556.  
  1557.      $fp fopen ($filePath'w'or die ('can not create file');
  1558.      fwrite($fp$fileContent);
  1559. }
  1560.  
  1561. //------------------------------------------------------------------------------
  1562.  
  1563. /**
  1564.     Open html file $full_file_name;
  1565.     Parse the hyperlinks; and
  1566.     Write the result back in the html file.
  1567.  
  1568.     @author Roan Embrechts
  1569.     @version 0.1
  1570.  */
  1571. function api_replace_links_in_html($upload_path$full_file_name)
  1572. {
  1573.     //Open the file
  1574.     $fp fopen($full_file_name"r");
  1575.     $buffer fread ($fpfilesize ($full_file_name));
  1576.  
  1577.     //Parse the contents
  1578.     $new_html_content api_replace_links_in_string($upload_path$buffer);
  1579.  
  1580.     //Write the result
  1581.     $fp fopen($full_file_name"w");
  1582.     fwrite($fp$new_html_content);
  1583. }
  1584.  
  1585. //------------------------------------------------------------------------------
  1586.  
  1587. /**
  1588.     @deprecated, use api_replace_parameter instead
  1589.  
  1590.     Parse the buffer string provided as parameter
  1591.     Replace the a href tags so they are displayed correctly.
  1592.     - works for files in root and subdirectories
  1593.     - replace relative hyperlinks to use showinframes.php?file= ...
  1594.     - add target="_top" to all absolute hyperlinks
  1595.     - leave local anchors untouched (e.g. #CHAPTER1)
  1596.     - leave links with download.php and showinframes.php untouched
  1597.  
  1598.     @author Roan Embrechts
  1599.     @version 0.6
  1600. */
  1601. function api_replace_links_in_string($upload_path$buffer)
  1602. {
  1603.     // Search for hyperlinks
  1604.     $matches array();
  1605.     if preg_match_all("/<a[\s]*href[^<]*>/i"$buffer$matches) )
  1606.     {
  1607.         $tag_list $matches[0];
  1608.     }
  1609.  
  1610.     // Search the filepath of all detected <a href> tags
  1611.     if (sizeof($tag_list)  0)
  1612.     {
  1613.         $file_path_list=array();
  1614.         $href_list=array();
  1615.  
  1616.         foreach($tag_list as $this_tag)
  1617.         {
  1618.             /* Match case insensitive, the stuff between the two ~ :
  1619.                 a href = <exactly one quote><one or more non-quotes><exactly one ">
  1620.                 e.g. a href="www.google.be", A HREF =   "info.html"
  1621.                 to match ["] escape the " or else PHP interprets it
  1622.                 [\"]{1} --> matches exactly one "
  1623.                 +    1 or more (like * is 0 or more)
  1624.                 [\s]* matches whitespace
  1625.                 $matches contains captured subpatterns
  1626.                 the only one here is ([^\"]+) --> matches[1]
  1627.             */
  1628.             if preg_match("~a href[\s]*=[\s]*[\"]{1}([^\"]+)[\"]{1}~i",
  1629.                             $this_tag$matches) )
  1630.             {
  1631.                 $file_path_list[$matches[1];//older
  1632.                 $href_list[$matches[0];//to also add target="_top"
  1633.             }
  1634.         }
  1635.  
  1636.  
  1637.     }
  1638.  
  1639.     // replace the original hyperlinks
  1640.     // by the correct ones
  1641.     for ($count 0$count sizeof($href_list)$count++)
  1642.     {
  1643.         $replaceWhat[$count$href_list[$count];
  1644.  
  1645.         $is_absolute_hyperlink strpos($replaceWhat[$count]"http");
  1646.         $is_local_anchor strpos($replaceWhat[$count]"#");
  1647.         if ($is_absolute_hyperlink == false && $is_local_anchor == false )
  1648.         {
  1649.             //this is a relative hyperlink
  1650.             if (
  1651.                 (strpos($replaceWhat[$count]"showinframes.php"== false&&
  1652.                 (strpos($replaceWhat[$count]"download.php"== false)
  1653.                 )
  1654.             {
  1655.                 //fix the link to use showinframes.php
  1656.                 $replaceBy[$count"a href = \"showinframes.php?file=" $upload_path."/".$file_path_list[$count]."\" target=\"_top\"";
  1657.             }
  1658.             else
  1659.             {
  1660.                 //url already fixed, leave as is
  1661.                 $replaceBy[$count$replaceWhat[$count];
  1662.             }
  1663.         }
  1664.         else if ($is_absolute_hyperlink)
  1665.         {
  1666.             $replaceBy[$count"a href=\"" $file_path_list[$count"\" target =\"_top\"";
  1667.         }
  1668.         else
  1669.         {
  1670.             //don't change anything
  1671.             $replaceBy[$count$replaceWhat[$count];
  1672.         }
  1673.         //Display::display_normal_message("link replaced by " . $replaceBy[$count]); //debug
  1674.     }
  1675.  
  1676.     $buffer str_replace($replaceWhat$replaceBy$buffer);
  1677.     return $buffer;
  1678. }
  1679.  
  1680. //------------------------------------------------------------------------------
  1681.  
  1682. /**
  1683.     EXPERIMENTAL - function seems to work, needs more testing
  1684.  
  1685.     @param $upload_path is the path where the document is stored, like "/archive/"
  1686.     if it is the root level, the function expects "/"
  1687.     otherwise "/path/"
  1688.  
  1689.     This function parses all tags with $param_name parameters.
  1690.     so the tags are displayed correctly.
  1691.  
  1692.     --------------
  1693.     Algorithm v1.0
  1694.     --------------
  1695.         given a string and a parameter,
  1696.         * OK find all tags in that string with the specified parameter (like href or src)
  1697.         * OK for every one of these tags, find the src|href|... part to edit it
  1698.         * OK change the src|href|... part to use download.php (or showinframes.php)
  1699.         * OK do some special stuff for hyperlinks
  1700.  
  1701.         Exceptions
  1702.         * OK if download.php or showinframes.php is already in the tag, leave it alone
  1703.         * OK if mailto is in the tag, leave it alone
  1704.         * OK if the src|href param contains http://, it's absolute --> leave it alone
  1705.  
  1706.         Special for hyperlinks (a href...)
  1707.         * OK add target="_top"
  1708.         * OK use showinframes.php instead of download.php
  1709.  
  1710.     @author Roan Embrechts
  1711.     @version 1.1
  1712. */
  1713. function api_replace_parameter($upload_path$buffer$param_name="src")
  1714. {
  1715.     /*
  1716.      *    Search for tags with $param_name as a parameter
  1717.      */
  1718.     /*
  1719.     // [\s]*    matches whitespace
  1720.     // [\"=a-z] matches ", = and a-z
  1721.     // ([\s]*[a-z]*)*    matches all whitespace and normal alphabet
  1722.     //                    characters a-z combinations but seems too slow
  1723.     //    perhaps ([\s]*[a-z]*) a maximum number of times ?
  1724.     // [\s]*[a-z]*[\s]*    matches many tags
  1725.     // the ending "i" means to match case insensitive (a matches a and A)
  1726.     */
  1727.     $matches array();
  1728.     if preg_match_all("/<[a-z]+[^<]*".$param_name."[^<]*>/i"$buffer$matches) )
  1729.     {
  1730.         $tag_list $matches[0];
  1731.     }
  1732.  
  1733.     /*
  1734.      *    Search the filepath of parameter $param_name in all detected tags
  1735.      */
  1736.     if (sizeof($tag_list0)
  1737.     {
  1738.         $file_path_list=array();
  1739.         $href_list=array();
  1740.  
  1741.         foreach($tag_list as $this_tag)
  1742.         {
  1743.             //Display::display_normal_message(htmlentities($this_tag)); //debug
  1744.             if preg_match("~".$param_name."[\s]*=[\s]*[\"]{1}([^\"]+)[\"]{1}~i",
  1745.                         $this_tag$matches) )
  1746.  
  1747.             {
  1748.                 $file_path_list[$matches[1];//older
  1749.                 $href_list[$matches[0];//to also add target="_top"
  1750.             }
  1751.         }
  1752.     }
  1753.  
  1754.     /*
  1755.      *    Replace the original tags by the correct ones
  1756.      */
  1757.     for ($count 0$count sizeof($href_list)$count++)
  1758.     {
  1759.         $replaceWhat[$count$href_list[$count];
  1760.  
  1761.         $is_absolute_hyperlink strpos($replaceWhat[$count]'http');
  1762.         $is_local_anchor strpos($replaceWhat[$count]'#');
  1763.         if ($is_absolute_hyperlink == false && $is_local_anchor == false )
  1764.         {
  1765.             if (
  1766.                 (strpos($replaceWhat[$count]'showinframes.php'== false&&
  1767.                 (strpos($replaceWhat[$count]'download.php'== false&&
  1768.                 (strpos($replaceWhat[$count]'mailto'== false)
  1769.                 )
  1770.             {
  1771.                 //fix the link to use download.php or showinframes.php
  1772.                 if preg_match("/<a([\s]*[\"\/:'=a-z0-9]*){5}href[^<]*>/i"$tag_list[$count]) )
  1773.                 {
  1774.                     $replaceBy[$count" $param_name =\"showinframes.php?file=$upload_path.$file_path_list[$count]."\" target=\"_top\" ";
  1775.                 }
  1776.                 else
  1777.                 {
  1778.                     $replaceBy[$count" $param_name =\"download.php?doc_url=$upload_path.$file_path_list[$count]."\" ";
  1779.                 }
  1780.             }
  1781.             else
  1782.             {
  1783.                 //"mailto" or url already fixed, leave as is
  1784.                 //$message .= "Already fixed or contains mailto: ";
  1785.                 $replaceBy[$count$replaceWhat[$count];
  1786.             }
  1787.         }
  1788.         else if ($is_absolute_hyperlink)
  1789.         {
  1790.             //$message .= "Absolute hyperlink, don't change, add target=_top: ";
  1791.             $replaceBy[$count" $param_name=\"$file_path_list[$count"\" target =\"_top\"";
  1792.         }
  1793.         else
  1794.         {
  1795.             //don't change anything
  1796.             //$message .= "Local anchor, don't change: ";
  1797.             $replaceBy[$count$replaceWhat[$count];
  1798.         }
  1799.         //$message .= "In tag $count, <b>" . htmlentities($tag_list[$count])
  1800.         //    . "</b>, parameter <b>" . $replaceWhat[$count] . "</b> replaced by <b>" . $replaceBy[$count] . "</b><br>"; //debug
  1801.     }
  1802.     //if (isset($message) && $message == true) api_display_debug_info($message); //debug
  1803.     $buffer str_replace($replaceWhat$replaceBy$buffer);
  1804.     return $buffer;
  1805. }
  1806.  
  1807. //------------------------------------------------------------------------------
  1808.  
  1809. /**
  1810.  * Checks the extension of a file, if it's .htm or .html
  1811.  * we use search_img_from_html to get all image paths in the file
  1812.  *
  1813.  * @param string $file 
  1814.  * @return array paths
  1815.  * @see check_for_missing_files() uses search_img_from_html()
  1816.  */
  1817. function check_for_missing_files($file)
  1818. {
  1819.     if (strrchr($file'.'== '.htm' || strrchr($file'.'== '.html')
  1820.     {
  1821.         $img_file_path search_img_from_html($file);
  1822.         return $img_file_path;
  1823.     }
  1824.     return false;
  1825. }
  1826.  
  1827. //------------------------------------------------------------------------------
  1828.  
  1829. /**
  1830.  * This builds a form that asks for the missing images in a html file
  1831.  * maybe we should do this another way?
  1832.  *
  1833.  * @param array $missing_files 
  1834.  * @param string $upload_path 
  1835.  * @param string $file_name 
  1836.  * @return string the form
  1837.  */
  1838. function build_missing_files_form($missing_files,$upload_path,$file_name)
  1839. {
  1840.         //do we need a / or not?
  1841.         $added_slash ($upload_path=='/')?'':'/';
  1842.         //build the form
  1843.         $form .= "<p><strong>".get_lang('MissingImagesDetected')."</strong></p>\n"
  1844.                 ."<form method=\"post\" action=\"".api_get_self()."\" enctype=\"multipart/form-data\">\n"
  1845.                 //related_file is the path to the file that has missing images
  1846.                 ."<input type=\"hidden\" name=\"related_file\" value=\"".$upload_path.$added_slash.$file_name."\" />\n"
  1847.                 ."<input type=\"hidden\" name=\"upload_path\" value=\"".$upload_path."\" />\n"
  1848.                 ."<table border=\"0\">\n";
  1849.                 foreach($missing_files as $this_img_file_path )
  1850.                 {
  1851.                 $form .= "<tr>\n"
  1852.                        ."<td>".basename($this_img_file_path)." : </td>\n"
  1853.                        ."<td>"
  1854.                        ."<input type=\"file\" name=\"img_file[]\"/>"
  1855.                        ."<input type=\"hidden\" name=\"img_file_path[]\" value=\"".$this_img_file_path."\" />"
  1856.                        ."</td>\n"
  1857.                        ."</tr>\n";
  1858.                 }
  1859.                 $form .= "</table>\n"
  1860.                         ."<input type=\"submit\" name=\"cancel_submit_image\" value=\"".get_lang('Cancel')."\"/>\n"
  1861.                         ."<input type=\"submit\" name=\"submit_image\" value=\"".get_lang('Ok')."\"/><br/>"
  1862.                         ."</form>\n";
  1863.                 return $form;
  1864. }
  1865.  
  1866. //------------------------------------------------------------------------------
  1867.  
  1868. /**
  1869.  * This recursive function can be used during the upgrade process form older versions of Dokeos
  1870.  * It crawls the given directory, checks if the file is in the DB and adds it if it's not
  1871.  *
  1872.  * @param string $base_work_dir 
  1873.  * @param string $current_path, needed for recursivity
  1874.  */
  1875. function add_all_documents_in_folder_to_database($_course,$user_id,$base_work_dir,$current_path='',$to_group_id=0)
  1876. {
  1877.  
  1878. $path $base_work_dir.$current_path;
  1879. //open dir
  1880. $handle=opendir($path);
  1881.     //run trough
  1882.     while($file=readdir($handle))
  1883.     {
  1884.        if ($file=='.' || $file=='..'continue;
  1885.  
  1886.        $completepath="$path/$file";
  1887.        //directory?
  1888.        
  1889.        if (is_dir($completepath))
  1890.        {
  1891.            $title=get_document_title($file);
  1892.            $safe_file=replace_dangerous_char($file);
  1893.         @rename($path.'/'.$file$path.'/'.$safe_file);
  1894.         //if we can't find the file, add it
  1895.         if(!DocumentManager::get_document_id($_course$current_path.'/'.$safe_file))
  1896.         {
  1897.             $document_id=add_document($_course,$current_path.'/'.$safe_file,'folder',0,$title);
  1898.             api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentAdded',$user_id$to_group_id);
  1899.             //echo $current_path.'/'.$safe_file." added!<br/>";
  1900.  
  1901.         }
  1902.         //recursive
  1903.         add_all_documents_in_folder_to_database($_course,$user_id,$base_work_dir,$current_path.'/'.$safe_file$to_group_id);
  1904.         }
  1905.         //file!
  1906.         else
  1907.         {
  1908.             //rename
  1909.             $safe_file=disable_dangerous_file(replace_dangerous_char($file));
  1910.             @rename($base_work_dir.$current_path.'/'.$file,$base_work_dir.$current_path.'/'.$safe_file);
  1911.             
  1912.             if(!DocumentManager::get_document_id($_course$current_path.'/'.$safe_file))
  1913.             {
  1914.             $title=get_document_title($file);
  1915.             $size filesize($base_work_dir.$current_path.'/'.$safe_file);
  1916.             $document_id add_document($_course,$current_path.'/'.$safe_file,'file',$size,$title);
  1917.             api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentAdded',$user_id,$to_group_id);
  1918.             //echo $current_path.'/'.$safe_file." added!<br/>";
  1919.             }
  1920.         }
  1921.     }
  1922. }
  1923.  
  1924. // could be usefull in some cases...
  1925. function remove_accents($string){
  1926.     $string strtr $string"�����������������������������������������������������""AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
  1927.     return $string;
  1928. }
  1929. ?>

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