fileManage.lib.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * This is the file manage library for Chamilo.
  5. * Include/require it in your code to use its functionality.
  6. * @package chamilo.library
  7. */
  8. /**
  9. * Update the file or directory path in the document db document table
  10. *
  11. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  12. * @param - action (string) - action type require : 'delete' or 'update'
  13. * @param - old_path (string) - old path info stored to change
  14. * @param - new_path (string) - new path info to substitute
  15. * @desc Update the file or directory path in the document db document table
  16. *
  17. */
  18. function update_db_info($action, $old_path, $new_path = '')
  19. {
  20. $dbTable = Database::get_course_table(TABLE_DOCUMENT);
  21. $course_id = api_get_course_int_id();
  22. switch ($action) {
  23. case 'delete':
  24. $old_path = Database::escape_string($old_path);
  25. $query = "DELETE FROM $dbTable
  26. WHERE
  27. c_id = $course_id AND
  28. (
  29. path LIKE BINARY '".$old_path."' OR
  30. path LIKE BINARY '".$old_path."/%'
  31. )";
  32. Database::query($query);
  33. break;
  34. case 'update':
  35. if ($new_path[0] == '.') $new_path = substr($new_path, 1);
  36. $new_path = str_replace('//', '/', $new_path);
  37. // Attempt to update - tested & working for root dir
  38. $new_path = Database::escape_string($new_path);
  39. $query = "UPDATE $dbTable SET
  40. path = CONCAT('".$new_path."', SUBSTRING(path, LENGTH('".$old_path."')+1) )
  41. WHERE c_id = $course_id AND (path LIKE BINARY '".$old_path."' OR path LIKE BINARY '".$old_path."/%')";
  42. Database::query($query);
  43. break;
  44. }
  45. }
  46. /**
  47. * Cheks a file or a directory actually exist at this location
  48. *
  49. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  50. * @param - file_path (string) - path of the presume existing file or dir
  51. * @return - boolean TRUE if the file or the directory exists
  52. * boolean FALSE otherwise.
  53. */
  54. function check_name_exist($file_path) {
  55. clearstatcache();
  56. $save_dir = getcwd();
  57. if (!is_dir(dirname($file_path))) {
  58. return false;
  59. }
  60. chdir(dirname($file_path));
  61. $file_name = basename($file_path);
  62. if (file_exists($file_name)) {
  63. chdir($save_dir);
  64. return true;
  65. } else {
  66. chdir($save_dir);
  67. return false;
  68. }
  69. }
  70. /**
  71. * Deletes a file or a directory
  72. *
  73. * @author - Hugues Peeters
  74. * @param $file (String) - the path of file or directory to delete
  75. * @return boolean - true if the delete succeed, false otherwise.
  76. * @see - delete() uses check_name_exist() and removeDir() functions
  77. */
  78. function my_delete($file)
  79. {
  80. if (check_name_exist($file)) {
  81. if (is_file($file)) { // FILE CASE
  82. unlink($file);
  83. return true;
  84. } elseif (is_dir($file)) { // DIRECTORY CASE
  85. removeDir($file);
  86. return true;
  87. }
  88. } else {
  89. return false; // no file or directory to delete
  90. }
  91. }
  92. /**
  93. * Removes a directory recursively
  94. *
  95. * @returns true if OK, otherwise false
  96. *
  97. * @author Amary <MasterNES@aol.com> (from Nexen.net)
  98. * @author Olivier Brouckaert <oli.brouckaert@skynet.be>
  99. *
  100. * @param string $dir directory to remove
  101. */
  102. function removeDir($dir)
  103. {
  104. if (!@$opendir = opendir($dir)) {
  105. return false;
  106. }
  107. while ($readdir = readdir($opendir)) {
  108. if ($readdir != '..' && $readdir != '.') {
  109. if (is_file($dir.'/'.$readdir)) {
  110. if (!@unlink($dir.'/'.$readdir)) {
  111. return false;
  112. }
  113. } elseif (is_dir($dir.'/'.$readdir)) {
  114. if (!removeDir($dir.'/'.$readdir)) {
  115. return false;
  116. }
  117. }
  118. }
  119. }
  120. closedir($opendir);
  121. if (!@rmdir($dir)) {
  122. return false;
  123. }
  124. return true;
  125. }
  126. /**
  127. * Return true if folder is empty
  128. * @author : hubert.borderiou@grenet.fr
  129. * @param string $in_folder : folder path on disk
  130. * @return 1 if folder is empty, 0 otherwise
  131. */
  132. function folder_is_empty($in_folder)
  133. {
  134. $folder_is_empty = 0;
  135. if (is_dir($in_folder)) {
  136. $tab_folder_content = scandir($in_folder);
  137. if ((count($tab_folder_content) == 2 &&
  138. in_array(".", $tab_folder_content) &&
  139. in_array("..", $tab_folder_content)
  140. ) ||
  141. (count($tab_folder_content) < 2)
  142. ) {
  143. $folder_is_empty = 1;
  144. }
  145. }
  146. return $folder_is_empty;
  147. }
  148. /**
  149. * Renames a file or a directory
  150. *
  151. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  152. * @param - $file_path (string) - complete path of the file or the directory
  153. * @param - $new_file_name (string) - new name for the file or the directory
  154. * @return - boolean - true if succeed
  155. * - boolean - false otherwise
  156. * @see - rename() uses the check_name_exist() and php2phps() functions
  157. */
  158. function my_rename($file_path, $new_file_name) {
  159. $save_dir = getcwd();
  160. $path = dirname($file_path);
  161. $old_file_name = basename($file_path);
  162. $new_file_name = api_replace_dangerous_char($new_file_name);
  163. // If no extension, take the old one
  164. if ((strpos($new_file_name, '.') === false) && ($dotpos = strrpos($old_file_name, '.'))) {
  165. $new_file_name .= substr($old_file_name, $dotpos);
  166. }
  167. // Note: still possible: 'xx.yy' -rename-> '.yy' -rename-> 'zz'
  168. // This is useful for folder names, where otherwise '.' would be sticky
  169. // Extension PHP is not allowed, change to PHPS
  170. $new_file_name = php2phps($new_file_name);
  171. if ($new_file_name == $old_file_name) {
  172. return $old_file_name;
  173. }
  174. if (strtolower($new_file_name) != strtolower($old_file_name) && check_name_exist($path.'/'.$new_file_name)) {
  175. return false;
  176. }
  177. // On a Windows server, it would be better not to do the above check
  178. // because it succeeds for some new names resembling the old name.
  179. // But on Unix/Linux the check must be done because rename overwrites.
  180. chdir($path);
  181. $res = rename($old_file_name, $new_file_name) ? $new_file_name : false;
  182. chdir($save_dir);
  183. return $res;
  184. }
  185. /**
  186. * Moves a file or a directory to an other area
  187. *
  188. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  189. * @param - $source (String) - the path of file or directory to move
  190. * @param - $target (String) - the path of the new area
  191. * @param bool $forceMove Whether to force a move or to make a copy (safer but slower) and then delete the original
  192. * @param bool $moveContent In some cases (including migrations), we need to move the *content* and not the folder itself
  193. * @return - bolean - true if the move succeed
  194. * bolean - false otherwise.
  195. * @see - move() uses check_name_exist() and copyDirTo() functions
  196. */
  197. function move($source, $target, $forceMove = false, $moveContent = false)
  198. {
  199. if (check_name_exist($source)) {
  200. $file_name = basename($source);
  201. $isWindowsOS = api_is_windows_os();
  202. $canExec = function_exists('exec');
  203. /* File case */
  204. if (is_file($source)) {
  205. if ($forceMove && !$isWindowsOS && $canExec) {
  206. exec('mv ' . $source . ' ' . $target . '/' . $file_name);
  207. } else {
  208. copy($source, $target . '/' . $file_name);
  209. unlink($source);
  210. }
  211. return true;
  212. } elseif (is_dir($source)) {
  213. /* Directory */
  214. if ($forceMove && !$isWindowsOS && $canExec) {
  215. if ($moveContent) {
  216. $base = basename($source);
  217. exec('mv '.$source.'/* '.$target.$base.'/');
  218. exec('rm -rf '.$source);
  219. } else {
  220. exec('mv $source $target');
  221. }
  222. } else {
  223. copyDirTo($source, $target);
  224. }
  225. return true;
  226. }
  227. } else {
  228. return false;
  229. }
  230. }
  231. /**
  232. * Moves a directory and its content to an other area
  233. *
  234. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  235. * @param - $orig_dir_path (string) - the path of the directory to move
  236. * @param - $destination (string) - the path of the new area
  237. * @return - no return
  238. */
  239. function copyDirTo($orig_dir_path, $destination, $move = true)
  240. {
  241. $fs = new \Symfony\Component\Filesystem\Filesystem();
  242. if (is_dir($orig_dir_path)) {
  243. $fs->mirror($orig_dir_path, $destination);
  244. if ($move) {
  245. $fs->remove($orig_dir_path);
  246. }
  247. }
  248. }
  249. /**
  250. * Extracting extention of a filename
  251. *
  252. * @returns array
  253. * @param string $filename filename
  254. */
  255. function getextension($filename) {
  256. $bouts = explode('.', $filename);
  257. return array(array_pop($bouts), implode('.', $bouts));
  258. }
  259. /* CLASS FileManager */
  260. /**
  261. This class contains functions that you can access statically.
  262. FileManager::list_all_directories($path)
  263. FileManager::list_all_files($dir_array)
  264. FileManager::compat_load_file($file_name)
  265. FileManager::set_default_settings($upload_path, $filename, $filetype="file", $glued_table, $default_visibility='v')
  266. @author Roan Embrechts
  267. @version 1.1, July 2004
  268. * @package chamilo.library
  269. */
  270. class FileManager
  271. {
  272. /**
  273. Returns a list of all directories, except the base dir,
  274. of the current course. This function uses recursion.
  275. Convention: the parameter $path does not end with a slash.
  276. @author Roan Embrechts
  277. @version 1.0.1
  278. */
  279. function list_all_directories($path)
  280. {
  281. $result_array = array();
  282. if (is_dir($path)) {
  283. $save_dir = getcwd();
  284. chdir($path);
  285. $handle = opendir($path);
  286. while ($element = readdir($handle)) {
  287. if ($element == '.' || $element == '..') continue;
  288. // Skip the current and parent directories
  289. if (is_dir($element)) {
  290. $dir_array[] = $path.'/'.$element;
  291. }
  292. }
  293. closedir($handle);
  294. // Recursive operation if subdirectories exist
  295. $dir_number = sizeof($dir_array);
  296. if ($dir_number > 0) {
  297. for ($i = 0 ; $i < $dir_number ; $i++) {
  298. $sub_dir_array = FileManager::list_all_directories($dir_array[$i]); // Function recursivity
  299. if (is_array($dir_array) && is_array($sub_dir_array)) {
  300. $dir_array = array_merge($dir_array, $sub_dir_array); // Data merge
  301. }
  302. }
  303. }
  304. $result_array = $dir_array;
  305. chdir($save_dir) ;
  306. }
  307. return $result_array ;
  308. }
  309. /**
  310. This function receives a list of directories.
  311. It returns a list of all files in these directories
  312. @author Roan Embrechts
  313. @version 1.0
  314. */
  315. function list_all_files($dir_array)
  316. {
  317. $element_array = array();
  318. if (is_dir($dir_array)) {
  319. $save_dir = getcwd();
  320. foreach ($dir_array as $directory) {
  321. chdir($directory);
  322. $handle = opendir($directory);
  323. while ($element = readdir($handle)) {
  324. if ($element == '.' || $element == '..' || $element == '.htaccess') continue;
  325. // Skip the current and parent directories
  326. if (!is_dir($element)) {
  327. $element_array[] = $directory.'/'.$element;
  328. }
  329. }
  330. closedir($handle);
  331. chdir('..');
  332. chdir($save_dir);
  333. }
  334. }
  335. return $element_array;
  336. }
  337. /**
  338. Loads contents of file $filename into memory and returns them as a string.
  339. Function kept for compatibility with older PHP versions.
  340. Function is binary safe (is needed on Windows)
  341. */
  342. function compat_load_file($file_name)
  343. {
  344. $buffer = '';
  345. if (file_exists($file_name)) {
  346. $fp = fopen($file_name, 'rb');
  347. $buffer = fread ($fp, filesize($file_name));
  348. fclose ($fp);
  349. }
  350. return $buffer;
  351. }
  352. /**
  353. * Adds file/folder to document table in database
  354. * improvement from set_default_settings (see below):
  355. * take all info from function parameters
  356. * no global variables needed
  357. *
  358. * NOTE $glued_table should already have backticks around it
  359. * (get it from the database library, and it is done automatically)
  360. *
  361. * @param path, filename, filetype,
  362. $glued_table, default_visibility
  363. * action: Adds an entry to the document table with the default settings.
  364. * @author Olivier Cauberghe <olivier.cauberghe@ugent.be>
  365. * @author Roan Embrechts
  366. * @version 1.2
  367. */
  368. function set_default_settings($upload_path, $filename, $filetype = 'file', $glued_table, $default_visibility = 'v')
  369. {
  370. if (!$default_visibility) $default_visibility = 'v';
  371. // Make sure path is not wrongly formed
  372. $upload_path = !empty($upload_path) ? "/$upload_path" : '';
  373. $endchar = substr($filename, strlen($filename) - 1, 1);
  374. if ($endchar == "\\" || $endchar == '/') {
  375. $filename = substr($filename, 0, strlen($filename) - 1);
  376. }
  377. $full_file_name = $upload_path.'/'.$filename;
  378. $full_file_name = str_replace("//", '/', $full_file_name);
  379. $sql_query = "SELECT count(*) as number_existing FROM $glued_table WHERE path='$full_file_name'";
  380. $sql_result = Database::query($sql_query);
  381. $result = Database::fetch_array($sql_result);
  382. // Determine which query to execute
  383. if ($result['number_existing'] > 0) {
  384. // Entry exists, update
  385. $query = "UPDATE $glued_table SET path='$full_file_name',visibility='$default_visibility', filetype='$filetype'
  386. WHERE path='$full_file_name'";
  387. } else {
  388. // No entry exists, create new one
  389. $query = "INSERT INTO $glued_table (path,visibility,filetype)
  390. VALUES ('$full_file_name','$default_visibility','$filetype')";
  391. }
  392. Database::query($query);
  393. }
  394. }
  395. /**
  396. * Define the image to display for each file extension.
  397. * This needs an existing image repository to work.
  398. *
  399. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  400. * @param - $file_name (string) - Name of a file
  401. * @return - The gif image to chose
  402. */
  403. function choose_image($file_name)
  404. {
  405. static $type, $image;
  406. /* TABLES INITIALISATION */
  407. if (!$type || !$image) {
  408. $type['word'] = array(
  409. 'doc',
  410. 'dot',
  411. 'rtf',
  412. 'mcw',
  413. 'wps',
  414. 'psw',
  415. 'docm',
  416. 'docx',
  417. 'dotm',
  418. 'dotx',
  419. );
  420. $type['web'] = array(
  421. 'htm',
  422. 'html',
  423. 'htx',
  424. 'xml',
  425. 'xsl',
  426. 'php',
  427. 'xhtml',
  428. );
  429. $type['image'] = array(
  430. 'gif',
  431. 'jpg',
  432. 'png',
  433. 'bmp',
  434. 'jpeg',
  435. 'tif',
  436. 'tiff',
  437. );
  438. $type['image_vect'] = array('svg', 'svgz');
  439. $type['audio'] = array(
  440. 'wav',
  441. 'mid',
  442. 'mp2',
  443. 'mp3',
  444. 'midi',
  445. 'sib',
  446. 'amr',
  447. 'kar',
  448. 'oga',
  449. 'au',
  450. 'wma',
  451. );
  452. $type['video'] = array(
  453. 'mp4',
  454. 'mov',
  455. 'rm',
  456. 'pls',
  457. 'mpg',
  458. 'mpeg',
  459. 'm2v',
  460. 'm4v',
  461. 'flv',
  462. 'f4v',
  463. 'avi',
  464. 'wmv',
  465. 'asf',
  466. '3gp',
  467. 'ogv',
  468. 'ogg',
  469. 'ogx',
  470. 'webm',
  471. );
  472. $type['excel'] = array(
  473. 'xls',
  474. 'xlt',
  475. 'xls',
  476. 'xlt',
  477. 'pxl',
  478. 'xlsx',
  479. 'xlsm',
  480. 'xlam',
  481. 'xlsb',
  482. 'xltm',
  483. 'xltx',
  484. );
  485. $type['compressed'] = array('zip', 'tar', 'rar', 'gz');
  486. $type['code'] = array(
  487. 'js',
  488. 'cpp',
  489. 'c',
  490. 'java',
  491. 'phps',
  492. 'jsp',
  493. 'asp',
  494. 'aspx',
  495. 'cfm',
  496. );
  497. $type['acrobat'] = array('pdf');
  498. $type['powerpoint'] = array(
  499. 'ppt',
  500. 'pps',
  501. 'pptm',
  502. 'pptx',
  503. 'potm',
  504. 'potx',
  505. 'ppam',
  506. 'ppsm',
  507. 'ppsx',
  508. );
  509. $type['flash'] = array('fla', 'swf');
  510. $type['text'] = array('txt', 'log');
  511. $type['oo_writer'] = array('odt', 'ott', 'sxw', 'stw');
  512. $type['oo_calc'] = array('ods', 'ots', 'sxc', 'stc');
  513. $type['oo_impress'] = array('odp', 'otp', 'sxi', 'sti');
  514. $type['oo_draw'] = array('odg', 'otg', 'sxd', 'std');
  515. $type['epub'] = array('epub');
  516. $type['java'] = array('class', 'jar');
  517. $type['freemind'] = array('mm');
  518. $image['word'] = 'word.gif';
  519. $image['web'] = 'file_html.gif';
  520. $image['image'] = 'file_image.gif';
  521. $image['image_vect'] = 'file_svg.png';
  522. $image['audio'] = 'file_sound.gif';
  523. $image['video'] = 'film.gif';
  524. $image['excel'] = 'excel.gif';
  525. $image['compressed'] = 'file_zip.gif';
  526. $image['code'] = 'icons/22/mime_code.png';
  527. $image['acrobat'] = 'file_pdf.gif';
  528. $image['powerpoint'] = 'powerpoint.gif';
  529. $image['flash'] = 'file_flash.gif';
  530. $image['text'] = 'icons/22/mime_text.png';
  531. $image['oo_writer'] = 'file_oo_writer.gif';
  532. $image['oo_calc'] = 'file_oo_calc.gif';
  533. $image['oo_impress'] = 'file_oo_impress.gif';
  534. $image['oo_draw'] = 'file_oo_draw.gif';
  535. $image['epub'] = 'file_epub.gif';
  536. $image['java'] = 'file_java.png';
  537. $image['freemind'] = 'file_freemind.png';
  538. }
  539. $extension = array();
  540. if (!is_array($file_name)) {
  541. if (preg_match('/\.([[:alnum:]]+)(\?|$)/', $file_name, $extension)) {
  542. $extension[1] = strtolower($extension[1]);
  543. foreach ($type as $generic_type => $extension_list) {
  544. if (in_array($extension[1], $extension_list)) {
  545. return $image[$generic_type];
  546. }
  547. }
  548. }
  549. }
  550. return 'defaut.gif';
  551. }
  552. /**
  553. * Transform a UNIX time stamp in human readable format date.
  554. *
  555. * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
  556. * @param - $date - UNIX time stamp
  557. * @return - A human readable representation of the UNIX date
  558. */
  559. function format_date($date)
  560. {
  561. return date('d.m.Y', $date);
  562. }
  563. /**
  564. * Transform the file path to a URL.
  565. *
  566. * @param - $file_path (string) - Relative local path of the file on the hard disk
  567. * @return - Relative url
  568. */
  569. function format_url($file_path)
  570. {
  571. $path_component = explode('/', $file_path);
  572. $path_component = array_map('rawurlencode', $path_component);
  573. return implode('/', $path_component);
  574. }
  575. /**
  576. * Get the most recent time the content of a folder was changed.
  577. *
  578. * @param - $dir_name (string) - Path of the dir on the hard disk
  579. * @param - $do_recursive (bool) - Traverse all folders in the folder?
  580. * @return - Time the content of the folder was changed
  581. */
  582. function recent_modified_file_time($dir_name, $do_recursive = true)
  583. {
  584. $dir = dir($dir_name);
  585. $last_modified = 0;
  586. $return = 0;
  587. if (is_dir($dir)) {
  588. while(($entry = $dir->read()) !== false)
  589. {
  590. if ($entry != '.' && $entry != '..')
  591. continue;
  592. if (!is_dir($dir_name.'/'.$entry))
  593. $current_modified = filemtime($dir_name.'/'.$entry);
  594. elseif ($do_recursive)
  595. $current_modified = recent_modified_file_time($dir_name.'/'.$entry, true);
  596. if ($current_modified > $last_modified)
  597. $last_modified = $current_modified;
  598. }
  599. $dir->close();
  600. //prevents returning 0 (for empty directories)
  601. $return = ($last_modified == 0) ? filemtime($dir_name) : $last_modified;
  602. }
  603. return $return;
  604. }
  605. /**
  606. * Get the total size of a directory.
  607. *
  608. * @param - $dir_name (string) - Path of the dir on the hard disk
  609. * @return - Total size in bytes
  610. */
  611. function folder_size($dir_name)
  612. {
  613. $size = 0;
  614. if ($dir_handle = opendir($dir_name)) {
  615. while (($entry = readdir($dir_handle)) !== false) {
  616. if ($entry == '.' || $entry == '..') {
  617. continue;
  618. }
  619. if (is_dir($dir_name.'/'.$entry)) {
  620. $size += folder_size($dir_name.'/'.$entry);
  621. } else {
  622. $size += filesize($dir_name.'/'.$entry);
  623. }
  624. }
  625. closedir($dir_handle);
  626. }
  627. return $size;
  628. }
  629. /**
  630. * Calculates the total size of a directory by adding the sizes (that
  631. * are stored in the database) of all files & folders in this directory.
  632. *
  633. * @param string $path
  634. * @param boolean $can_see_invisible
  635. * @return int Total size
  636. */
  637. function get_total_folder_size($path, $can_see_invisible = false)
  638. {
  639. $table_itemproperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
  640. $table_document = Database::get_course_table(TABLE_DOCUMENT);
  641. $tool_document = TOOL_DOCUMENT;
  642. $course_id = api_get_course_int_id();
  643. $session_id = api_get_session_id();
  644. $session_condition = api_get_session_condition(
  645. $session_id,
  646. true,
  647. true,
  648. 'props.session_id'
  649. );
  650. $visibility_rule = ' props.visibility ' . ($can_see_invisible ? '<> 2' : '= 1');
  651. $sql = "SELECT SUM(table1.size) FROM (
  652. SELECT size
  653. FROM $table_itemproperty AS props, $table_document AS docs
  654. WHERE
  655. docs.c_id = $course_id AND
  656. docs.id = props.ref AND
  657. docs.path LIKE '$path/%' AND
  658. props.c_id = $course_id AND
  659. props.tool = '$tool_document' AND
  660. $visibility_rule
  661. $session_condition
  662. GROUP BY ref
  663. ) as table1";
  664. $result = Database::query($sql);
  665. if ($result && Database::num_rows($result) != 0) {
  666. $row = Database::fetch_row($result);
  667. return $row[0] == null ? 0 : $row[0];
  668. } else {
  669. return 0;
  670. }
  671. }