2 /****************************************************************/
4 /****************************************************************/
5 /* Copyright (c) 2002-2010 */
6 /* Inclusive Design Institute */
9 /* This program is free software. You can redistribute it and/or*/
10 /* modify it under the terms of the GNU General Public License */
11 /* as published by the Free Software Foundation. */
12 /****************************************************************/
13 if (!defined('AT_INCLUDE_PATH')) { exit; }
16 * Allows the copying of entire directories.
18 * @param string $source the source directory
19 * @param string $dest the destination directory
20 * @return boolean whether the copy was successful or not
21 * @link http://www.php.net/copy
22 * @author www at w8c dot com
25 function copys($source,$dest)
27 if (!is_dir($source)) {
35 while (@($entry=$h->read()) !== false) {
36 if (($entry == '.') || ($entry == '..')) {
40 if (is_dir("$source/$entry") && $dest!=="$source/$entry") {
41 copys("$source/$entry", "$dest/$entry");
43 @copy("$source/$entry", "$dest/$entry");
51 * Enables deletion of directory if not empty
53 * @param string $dir the directory to delete
54 * @return boolean whether the deletion was successful
55 * @author Joel Kronenberg
57 function clr_dir($dir) {
58 if(!$opendir = @opendir($dir)) {
62 while(($readdir=readdir($opendir)) !== false) {
63 if (($readdir !== '..') && ($readdir !== '.')) {
64 $readdir = trim($readdir);
66 clearstatcache(); /* especially needed for Windows machines: */
68 if (is_file($dir.'/'.$readdir)) {
69 if(!@unlink($dir.'/'.$readdir)) {
72 } else if (is_dir($dir.'/'.$readdir)) {
73 /* calls itself to clear subdirectories */
74 if(!clr_dir($dir.'/'.$readdir)) {
90 * Calculate the size in Bytes of a directory recursively.
92 * @param string $dir the directory to traverse
93 * @return int the total size in Bytes of the directory
94 * @author Joel Kronenberg
96 function dirsize($dir) {
104 while (($file = readdir($dh)) !== false) {
106 if ($file != '.' && $file != '..') {
109 $size += dirsize($path.'/');
110 } elseif (is_file($path)) {
111 $size += filesize($path);
124 * This function gets used by PclZip when extracting a zip archive.
126 * @return int whether or not to include the file
127 * @author Joel Kronenberg
129 function preExtractCallBack($p_event, &$p_header) {
130 global $translated_file_names;
132 if ($p_header['folder'] == 1) {
136 if ($translated_file_names[$p_header['index']] == '') {
140 if ($translated_file_names[$p_header['index']]) {
141 $p_header['filename'] = substr($p_header['filename'], 0, -strlen($p_header['stored_filename']));
142 $p_header['filename'] .= $translated_file_names[$p_header['index']];
148 * This function gets used by PclZip when creating a zip archive.
150 * @return int whether or not to include the file
151 * @author Joel Kronenberg
153 function preImportCallBack($p_event, &$p_header) {
154 global $IllegalExtentions;
156 if ($p_header['folder'] == 1) {
160 $path_parts = pathinfo($p_header['filename']);
161 $ext = $path_parts['extension'];
163 if (in_array($ext, $IllegalExtentions)) {
171 /* prints the <options> out of $cats which is an array of course categories where */
172 /* $cats[parent_cat_id][] = $row */
173 function print_course_cats($parent_cat_id, &$cats, $cat_row, $depth=0) {
174 $my_cats = $cats[$parent_cat_id];
175 if (!is_array($my_cats)) {
178 foreach ($my_cats as $cat) {
180 echo '<option value="'.$cat['cat_id'].'"';
181 if($cat['cat_id'] == $cat_row){
182 echo ' selected="selected"';
185 echo str_pad('', $depth, '-');
186 echo $cat['cat_name'].'</option>'."\n";
188 print_course_cats($cat['cat_id'], $cats, $cat_row, $depth+1);
192 // returns the most appropriate representation of Bytes in MB, KB, or B
193 function get_human_size($num_bytes) {
194 $abs_num_bytes = abs($num_bytes);
196 if ($abs_num_bytes >= AT_KBYTE_SIZE * AT_KBYTE_SIZE) {
197 return round(bytes_to_megabytes($num_bytes), 2) .' '. _AT('mb');
198 } else if ($abs_num_bytes >= AT_KBYTE_SIZE) {
199 return round(bytes_to_kilobytes($num_bytes), 2) .' '._AT('kb') ;
203 return $num_bytes . ' '._AT('bt');
207 * Returns the MB representation of inputed bytes
209 * @param int $num_bytes the input bytes to convert
210 * @return int MB representation of $num_bytes
211 * @author Heidi Hazelton
213 function bytes_to_megabytes($num_bytes) {
214 return $num_bytes/AT_KBYTE_SIZE/AT_KBYTE_SIZE;
218 * Returns the Byte representation of inputed MB
220 * @param int $num_bytes the input MB to convert
221 * @return int the Bytes representation of $num_bytes
222 * @author Heidi Hazelton
224 function megabytes_to_bytes($num_bytes) {
225 return $num_bytes*AT_KBYTE_SIZE*AT_KBYTE_SIZE;
229 * Returns the KB representation of inputed Bytes
231 * @param int $num_bytes the input Bytes to convert
232 * @return int the KB representation of $num_bytes
233 * @author Heidi Hazelton
235 function bytes_to_kilobytes($num_bytes) {
236 return $num_bytes/AT_KBYTE_SIZE;
240 * Returns the Bytes representation of inputed KBytes
242 * @param int $num_bytes the input KBytes to convert
243 * @return int the KBytes representation of $num_bytes
244 * @author Heidi Hazelton
246 function kilobytes_to_bytes($num_bytes) {
247 return $num_bytes*AT_KBYTE_SIZE;
251 * Outputs the directories associated with a course in the form of <option> elements.
253 * @param string $cur_dir the current directory to include in the options.
254 * @author Norma Thompson
256 function output_dirs($current_path,$cur_dir,$indent) {
258 if ($dir = opendir($current_path.$cur_dir)) {
260 // recursively call output_dirs() for all directories in this directory
261 while (false !== ($file = readdir($dir)) ) {
263 //if the name is not a directory
264 if( ($file == '.') || ($file == '..') ) {
268 // if it is a directory call function
269 if(is_dir($current_path.$cur_dir.$file)) {
270 $ldir = explode('/',$cur_dir.$file);
271 $count = count($ldir);
272 $label = $ldir[$count-1];
274 $dir_option .= '<option value="'.$cur_dir.$file.'/" >'.$indent.$label.'</option>';
276 $dir_option .= output_dirs($current_path,$cur_dir.$file.'/',$indent.'--');
286 function display_tree($current_path, $cur_dir, $pathext, $ignore_children = false) {
289 if (!isset($list_array)) {
290 $list_array = explode(',', $_GET['list']);
292 if ($dir = opendir($current_path . $cur_dir)) {
294 // recursively call output_dirs() for all directories in this directory
295 while (false !== ($file = readdir($dir)) ) {
297 //if the name is not a directory
298 if( ($file == '.') || ($file == '..') ) {
302 // if it is a directory call function
303 if (is_dir($current_path . $cur_dir . $file)) {
305 //$ldir = explode('/',$cur_dir.$file);
306 //$count = count($ldir);
307 //$label = $ldir[$count-1];
311 if ($cur_dir . $file == substr($pathext, 0, -1)) {
312 $check = 'checked="checked"';
313 $here = ' ' . _AT('current_location');
314 } else if (($cur_dir == $pathext) && in_array($file, $list_array)) {
315 $ignore_children = true;
318 if ($ignore_children) {
319 $check = 'disabled="disabled"';
320 $class = ' disabled';
323 $dir_option .= '<ul><li class="folders'.$class.'">';
324 $dir_option .= '<label><input type="radio" name="dir_name" value="'.$cur_dir.$file.'" '.$check. '/>'. $file . $here. '</label>';
325 $dir_option .= ''.display_tree($current_path,$cur_dir.$file.'/', $pathext, $ignore_children).'';
326 $dir_option .= '</li></ul>';
328 if (($cur_dir == $pathext) && in_array($file, $list_array)) {
329 $ignore_children = false;
342 function course_realpath($file) {
343 if (!$_SESSION['course_id']) {
347 $course_path = AT_CONTENT_DIR . $_SESSION['course_id'];
349 $path_parts = pathinfo($file);
351 $dir_name = $path_parts['dirname'];
352 $file_name = $path_parts['basename'];
353 $ext_name = $path_parts['extension'];
355 //1. determine the real path of the file/directory
356 if (is_dir($dir_name.DIRECTORY_SEPARATOR.$file_name) && $ext_name == '') {
357 //if directory ws passed through (moving file to diff directory)
358 $real = realpath($dir_name . DIRECTORY_SEPARATOR . $file_name);
360 //if file was passed through or no existant direcotry was passed through (rename/creating dir)
361 $real = realpath($dir_name);
364 //2. and whether its in the course content directory
365 if (substr($real, 0, strlen($course_path)) != $course_path) {
369 //3. check if extensions are legal
371 //4. Otherwise return the real path of the file
376 * Returns canonicalized absolute pathname to a file/directory in the content directory
378 * @param string $file the relative path to the file or directory
379 * @return string the full path to the file or directory, FALSE if it does not exist in our content directory.
381 function course_realpath_NEW_VERSION($file) {
382 if (!$_SESSION['course_id']) {
386 $course_path = AT_CONTENT_DIR . $_SESSION['course_id'];
388 // determine the real path of the file/directory
389 $real = realpath($course_path . DIRECTORY_SEPARATOR . $file);
391 if (!file_exists($real)) {
392 // the file or directory does not exist
395 } else if (substr($real, 0, strlen($course_path)) != $course_path) {
396 // the file or directory is not in the content path
400 // Otherwise return the real path of the file
406 * Returns the name of the readme file in the given directory
408 * @param string $dir_name the name of the directory
409 * @return string the name of the readme file
411 function get_readme($dir)
413 if (!is_dir($dir)) return '';
417 while (($file = readdir($dh)) !== false) {
418 if (stristr($file, 'readme') && substr($file, -4) <> '.php')
428 * This function is mainly used to download big zip files that are created by ATutor.
429 * For example, download common cartridge, content package, backup.
430 * Note that the file is only in binary, as fopen($filename, "rb").
431 * Don't use it to read open text/html files
433 * When downloading large files exceeding 1M, instead of use readfile() to read
434 * the whole file into memory once at a time, push down 1M at a time. This way can
435 * download whatever size of the file regardless of php memory limit.
437 function readfile_in_chunks($filename) {
438 $filesize = intval(sprintf("%u", filesize($filename)));
439 $chunk_size = 1024 * 1024;
441 if ($filesize > $chunk_size) {
442 $fp = fopen($filename, "rb");
445 echo fread($fp, $chunk_size);
456 * This function handles ajax request and return an array of errors encoded in JSON
457 * @param int HTTP Status code, so far, handle 200 and 500.
459 function handleAjaxUpload($statusCode) {
460 if ($_POST['type'] === 'ajax') {
461 if ($statusCode === 500) {
462 // $msg->printErrors();
463 header("HTTP/1.1 500 Internal Server Error", TRUE, 500);
464 } elseif ($statusCode === 200) {
465 // $msg->printFeedbacks();
466 header("HTTP/1.1 200 Ok", TRUE, 200);