<?php /* For licensing terms, see /license.txt */ /** * Code library for HotPotatoes integration. * @package chamilo.exercise * @author Istvan Mandak (original author) */ $dbTable = Database::get_course_table(TABLE_DOCUMENT); // TODO: This is a global variable with too simple name, conflicts are possible. Better eliminate it. Correct the test unit too. /** * Creates a hotpotato directory. * * If a directory of that name already exists, don't create any. If a file of that name exists, remove it and create a directory. * @param string Wanted path * @return boolean Always true so far */ function hotpotatoes_init($base_work_dir) { //global $_course, $_user; $document_path = $base_work_dir.'/'; if (!is_dir($document_path)) { if (is_file($document_path)) { @unlink($document_path); } @mkdir($document_path, api_get_permissions_for_new_directories()); return true; } else { return false; } //why create a .htaccess here? //if (!is_file($document_path.".htacces")) //{ // if (!($fp = fopen($document_path.".htaccess", "w"))) { // } // $str = "order deny,allow\nallow from all"; // if (!fwrite($fp,$str)) { } //} } /** * Gets the title of the quizz file given as parameter. * @param string File name * @param string File path * @return string The exercise title */ function GetQuizName($fname, $fpath) { $title = GetComment($fname); if (trim($title) == '') { if (file_exists($fpath.$fname)) { if (!($fp = @fopen($fpath.$fname, 'r'))) { //die('Could not open Quiz input.'); return basename($fname); } $contents = @fread($fp, filesize($fpath.$fname)); @fclose($fp); $title = api_get_title_html($contents); } } if ($title == '') { $title = basename($fname); } return (string)$title; } /** * Gets the comment about a file from the corresponding database record. * @param string File path * @return string Comment from the database record * Added conditional to the table if is empty. */ function GetComment($path, $course_code = '') { global $dbTable; if (!empty($course_code)) { $course_info = api_get_course_info($course_code); $dbTable = Database::get_course_table(TABLE_DOCUMENT, $course_info['dbName']); } $path = Database::escape_string($path); $query = "SELECT comment FROM $dbTable WHERE path='$path'"; $result = Database::query($query); while ($row = Database::fetch_array($result)) { return $row[0]; } return ''; } /** * Sets the comment in the database for a particular path. * @param string File path * @param string Comment to set * @return string Result of the database operation (Database::query will output some message directly on error anyway) */ function SetComment($path, $comment) { global $dbTable; $path = Database::escape_string($path); $comment = Database::escape_string($comment); $query = "UPDATE $dbTable SET comment='$comment' WHERE path='$path'"; $result = Database::query($query); return "$result"; } /** * Reads the file contents into a string. * @param string Urlencoded path * @return string The file contents or false on security error */ function ReadFileCont($full_file_path) { if (Security::check_abs_path(dirname($full_file_path).'/', api_get_path(SYS_COURSE_PATH))) { if (is_file($full_file_path)) { if (!($fp = fopen(urldecode($full_file_path), 'r'))) { return ''; } $contents = fread($fp, filesize($full_file_path)); fclose($fp); return $contents; } } return false; } /** * Writes the file contents into the given filepath. * @param string Urlencoded path * @param string The file contents * @return boolean True on success, false on security error */ function WriteFileCont($full_file_path, $content) { // Check if this is not an attack, trying to get into other directories or something like that. global $_course; if (Security::check_abs_path(dirname($full_file_path).'/', api_get_path(SYS_COURSE_PATH).$_course['path'].'/')) { // Check if this is not an attack, trying to upload a php file or something like that. if (basename($full_file_path) != Security::filter_filename(basename($full_file_path))) { return false; } if (!($fp = fopen(urldecode($full_file_path), 'w'))) { //die('Could not open Quiz input.'); } fwrite($fp, $content); fclose($fp); return true; } return false; } /** * Gets the name of an img whose path is given (without directories or extensions). * @param string An image tag (<img src="...." ...>) * @return string The image file name or an empty string */ function GetImgName($imgtag) { // Select src tag from img tag. $match = array(); //preg_match('/(src=(["\'])1.*(["\'])1)/i', $imgtag, $match); //src preg_match('/src(\s)*=(\s)*[\'"]([^\'"]*)[\'"]/i', $imgtag, $match); //get the img src as contained between " or ' //list($key, $srctag) = each($match); $src = $match[3]; //$src = substr($srctag, 5, (strlen($srctag) - 7)); if (stristr($src, 'http') === false) { // Valid or invalid image name. if ($src == '') { return ''; } else { $tmp_src = basename($src) ; if ($tmp_src == '') { return $src; } else { return $tmp_src; } } } else { // The img tag contained "http", which means it is probably external. Ignore it. return ''; } } /** * Gets the source path of an image tag. * @param string An image tag * @return string The image source or "" */ function GetSrcName($imgtag) { // Select src tag from img tag. $match = array(); preg_match("|(src=\".*\" )|U", $imgtag, $match); //src list($key, $srctag) = each($match); $src = substr($srctag, 5, (strlen($srctag) - 7)); if (stristr($src, 'http') === false) { // valid or invalid image name return $src; } else { return ''; } } /** * Gets the image parameters from an image path. * @param string File name * @param string File path * @param reference Reference to a list of image parameters (emptied, then used to return results) * @param reference Reference to a counter of images (emptied, then used to return results) */ function GetImgParams($fname, $fpath, &$imgparams, &$imgcount) { // Select img tags from context. $imgparams = array(); //phpinfo(); $contents = ReadFileCont("$fpath"."$fname"); $matches = array(); preg_match_all('(<img .*>)', $contents, $matches); $imgcount = 0; while (list($int, $match) = each($matches)) { // Each match consists of a key and a value. while (list($key, $imgtag) = each($match)) { $imgname = GetImgName($imgtag); if ($imgname != '' && !in_array($imgname, $imgparams)) { array_push($imgparams, $imgname); // name (+ type) of the images in the html test $imgcount = $imgcount + 1; // number of images in the html test } } } } /** * Generates a list of hidden fields with the image params given as parameter to this function. * @param array List of image parameters * @return string String containing the hidden parameters built from the list given */ function GenerateHiddenList($imgparams) { $list = ''; if (is_array($imgparams)) { while (list($int, $string) = each($imgparams)) { $list .= "<input type=\"hidden\" name=\"imgparams[]\" value=\"$string\" />\n"; } } return $list; } /** * Searches for a node in the given array. * @param reference Reference to the array to search * @param string Node we are looking for in the array * @return mixed Node name or false if not found */ function myarraysearch(&$array, $node) { $match = false; $tmp_array = array(); for ($i = 0; $i < count($array); $i++) { if (!strcmp($array[$i], $node)) { $match = $node; } else { array_push($tmp_array, $array[$i]); } } $array = $tmp_array; return $match; } /** * Searches an image name into an array. * @param reference Reference to an array to search * @param string String to look for * @return mixed String given if found, false otherwise * @uses myarraysearch This function is just an additional layer on the myarraysearch() function */ function CheckImageName(&$imgparams, $string) { $checked = myarraysearch($imgparams, $string); return $checked; } /** * Replaces an image tag by ??? * @param string The content to replace * @return string The modified content */ function ReplaceImgTag($content) { $newcontent = $content; $matches = array(); preg_match_all('(<img .*>)', $content, $matches); $imgcount = 0; while (list($int, $match) = each($matches)) { while (list($key, $imgtag) = each($match)) { $imgname = GetSrcName($imgtag); if ($imgname == '') {} // Valid or invalid image name. else { $prehref = $imgname; $posthref = basename($imgname); $newcontent = str_replace($prehref, $posthref, $newcontent); } } } return $newcontent; } /** * Fills the folder name up to a certain length with "0". * @param string Original folder name * @param integer Length to reach * @return string Modified folder name */ function FillFolderName($name, $nsize) { $str = ''; for ($i = 0; $i < $nsize - strlen($name); $i++) { $str .= '0'; } $str .= $name; return $str; } /** * Generates the HotPotato folder tree. * @param string Folder path * @return string Folder name (modified) */ function GenerateHpFolder($folder) { $filelist = array(); if ($dir = @opendir($folder)) { while (($file = readdir($dir)) !== false) { if ($file != '.') { if ($file != '..') { $full_name = $folder.'/'.$file; if (is_dir($full_name)) { $filelist[] = $file; } } } } } $w = 0; do { $name = FillFolderName(mt_rand(1, 99999), 6); $checked = myarraysearch($filelist, $name); // As long as we find the name in the array, continue looping. As soon as we have a new element, quit. if ($checked) { $w = 1; } else { $w = 0; } } while ($w == 1); return $name; } /** * Gets the folder name (strips down path). * @param string Path * @return string Folder name stripped down */ function GetFolderName($fname) { $name = explode('/', $fname); $name = $name[sizeof($name) - 2]; return $name; } /** * Gets the folder path (withouth the name of the folder itself) ? * @param string Path * @return string Path stripped down */ function GetFolderPath($fname) { $str = ''; $name = explode('/', $fname); for ($i = 0; $i < sizeof($name) - 1; $i++) { $str = $str.$name[$i].'/'; } return $str; } /** * Checks if there are subfolders. * @param string Path * @return integer 1 if a subfolder was found, 0 otherwise */ function CheckSubFolder($path) { $folder = GetFolderPath($path); $dflag = 0; if ($dir = @opendir($folder)) { while (($file = readdir($dir)) !== false) { if ($file != '.') { if ($file != '..') { $full_name = $folder.'/'.$file; if (is_dir($full_name)) { $dflag = 1; // first directory } } } } } return $dflag; } /** * Hotpotato Garbage Collector * @param string Path * @param integer Flag * @param integer User id * @return void No return value, but echoes results */ function HotPotGCt($folder, $flag, $user_id) { // Garbage Collector $filelist = array(); if ($dir = @opendir($folder)) { while (($file = readdir($dir)) !== false) { if ($file != '.') { if ($file != '..') { $full_name = $folder.'/'.$file; if (is_dir($full_name)) { HotPotGCt($folder.'/'.$file, $flag, $user_id); } else { $filelist[] = $file; } } } } closedir($dir); } while (list($key, $val) = each($filelist)) { if (stristr($val, $user_id.'.t.html')) { if ($flag == 1) { my_delete($folder.'/'.$val); } else { echo $folder.'/'.$val.'<br />'; } } } }