예제 #1
0
 /**
  * Gets the list of included resources as a list of absolute or relative paths of
  * resources included in the current item. This allows for a better SCORM export.
  * The list will generally include pictures, flash objects, java applets, or any other
  * stuff included in the source of the current item. The current item is expected
  * to be an HTML file. If it is not, then the function will return and empty list.
  * @param	string	type (one of the Dokeos tools) - optional (otherwise takes the current item's type)
  * @param	string	path (absolute file path) - optional (otherwise takes the current item's path)
  * @param	int		level of recursivity we're in
  * @return	array	List of file paths. An additional field containing 'local' or 'remote' helps determine if the file should be copied into the zip or just linked
  */
 function get_resources_from_source($type = null, $abs_path = null, $recursivity = 1)
 {
     $max = 5;
     if ($recursivity > $max) {
         return array();
     }
     if (!isset($type)) {
         $type = $this->get_type();
     }
     if (!isset($abs_path)) {
         $path = $this->get_file_path();
         $abs_path = api_get_path(SYS_COURSE_PATH) . api_get_course_path() . '/' . $path;
         //echo "Abs path coming from item : ".$abs_path."<br/>\n";
     }
     /*
     else
     {
     	echo "Abs path coming from param: ".$abs_path."<br/>\n";
     }
     */
     //error_log(str_repeat(' ',$recursivity).'Analyse file '.$abs_path,0);
     $files_list = array();
     $type = $this->get_type();
     switch ($type) {
         case TOOL_DOCUMENT:
         case TOOL_QUIZ:
         case 'sco':
             //get the document and, if HTML, open it
             if (is_file($abs_path)) {
                 //for now, read the whole file in one go (that's gonna be a problem when the file is too big)
                 $info = pathinfo($abs_path);
                 $ext = $info['extension'];
                 switch (strtolower($ext)) {
                     case 'html':
                     case 'htm':
                     case 'shtml':
                     case 'css':
                         $wanted_attributes = array('src', 'url', '@import', 'href', 'value');
                         //parse it for included resources
                         $file_content = file_get_contents($abs_path);
                         //get an array of attributes from the HTML source
                         $attributes = learnpathItem::parse_HTML_attributes($file_content, $wanted_attributes);
                         //look at 'src' attributes in this file
                         foreach ($wanted_attributes as $attr) {
                             if (isset($attributes[$attr])) {
                                 //find which kind of path these are (local or remote)
                                 $sources = $attributes[$attr];
                                 foreach ($sources as $source) {
                                     //skip what is obviously not a resource
                                     if (strpos($source, "+this.")) {
                                         continue;
                                     }
                                     //javascript code - will still work unaltered
                                     if (strpos($source, '.') === false) {
                                         continue;
                                     }
                                     //no dot, should not be an external file anyway
                                     if (strpos($source, 'mailto:')) {
                                         continue;
                                     }
                                     //mailto link
                                     if (strpos($source, ';') && !strpos($source, '&amp;')) {
                                         continue;
                                     }
                                     //avoid code - that should help
                                     if ($attr == 'value') {
                                         if (strpos($source, 'mp3file')) {
                                             $files_list[] = array(substr($source, 0, strpos($source, '.swf') + 4), 'local', 'abs');
                                             $mp3file = substr($source, strpos($source, 'mp3file=') + 8);
                                             if (substr($mp3file, 0, 1) == '/') {
                                                 $files_list[] = array($mp3file, 'local', 'abs');
                                             } else {
                                                 $files_list[] = array($mp3file, 'local', 'rel');
                                             }
                                         } elseif (strpos($source, 'flv=') === 0) {
                                             $source = substr($source, 4);
                                             if (strpos($source, '&') > 0) {
                                                 $source = substr($source, 0, strpos($source, '&'));
                                             }
                                             if (strpos($source, '://') > 0) {
                                                 if (strpos($source, api_get_path(WEB_PATH)) !== false) {
                                                     //we found the current portal url
                                                     $files_list[] = array($source, 'local', 'url');
                                                 } else {
                                                     //we didn't find any trace of current portal
                                                     $files_list[] = array($source, 'remote', 'url');
                                                 }
                                             } else {
                                                 $files_list[] = array($source, 'local', 'abs');
                                             }
                                             continue;
                                             //skipping anything else to avoid two entries (while the others can have sub-files in their url, flv's can't)
                                         }
                                     }
                                     if (strpos($source, '://') > 0) {
                                         //cut at '?' in a URL with params
                                         if (strpos($source, '?') > 0) {
                                             $second_part = substr($source, strpos($source, '?'));
                                             if (strpos($second_part, '://') > 0) {
                                                 //if the second part of the url contains a url too, treat the second one before cutting
                                                 $pos1 = strpos($second_part, '=');
                                                 $pos2 = strpos($second_part, '&');
                                                 $second_part = substr($second_part, $pos1 + 1, $pos2 - ($pos1 + 1));
                                                 if (strpos($second_part, api_get_path(WEB_PATH)) !== false) {
                                                     //we found the current portal url
                                                     $files_list[] = array($second_part, 'local', 'url');
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $second_part, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 } else {
                                                     //we didn't find any trace of current portal
                                                     $files_list[] = array($second_part, 'remote', 'url');
                                                 }
                                             } elseif (strpos($second_part, '=') > 0) {
                                                 if (substr($second_part, 0, 1) === '/') {
                                                     //link starts with a /, making it absolute (relative to DocumentRoot)
                                                     $files_list[] = array($second_part, 'local', 'abs');
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $second_part, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 } elseif (strstr($second_part, '..') === 0) {
                                                     //link is relative but going back in the hierarchy
                                                     $files_list[] = array($second_part, 'local', 'rel');
                                                     $dir = dirname($abs_path);
                                                     $new_abs_path = realpath($dir . '/' . $second_part);
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $new_abs_path, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 } else {
                                                     //no starting '/', making it relative to current document's path
                                                     if (substr($second_part, 0, 2) == './') {
                                                         $second_part = substr($second_part, 2);
                                                     }
                                                     $files_list[] = array($second_part, 'local', 'rel');
                                                     $dir = dirname($abs_path);
                                                     $new_abs_path = realpath($dir . '/' . $second_part);
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $new_abs_path, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 }
                                             }
                                             //leave that second part behind now
                                             $source = substr($source, 0, strpos($source, '?'));
                                             if (strpos($source, '://') > 0) {
                                                 if (strpos($source, api_get_path(WEB_PATH)) !== false) {
                                                     //we found the current portal url
                                                     $files_list[] = array($source, 'local', 'url');
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $source, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 } else {
                                                     //we didn't find any trace of current portal
                                                     $files_list[] = array($source, 'remote', 'url');
                                                 }
                                             } else {
                                                 //no protocol found, make link local
                                                 if (substr($source, 0, 1) === '/') {
                                                     //link starts with a /, making it absolute (relative to DocumentRoot)
                                                     $files_list[] = array($source, 'local', 'abs');
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $source, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 } elseif (strstr($source, '..') === 0) {
                                                     //link is relative but going back in the hierarchy
                                                     $files_list[] = array($source, 'local', 'rel');
                                                     $dir = dirname($abs_path);
                                                     $new_abs_path = realpath($dir . '/' . $source);
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $new_abs_path, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 } else {
                                                     //no starting '/', making it relative to current document's path
                                                     if (substr($source, 0, 2) == './') {
                                                         $source = substr($source, 2);
                                                     }
                                                     $files_list[] = array($source, 'local', 'rel');
                                                     $dir = dirname($abs_path);
                                                     $new_abs_path = realpath($dir . '/' . $source);
                                                     $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $new_abs_path, $recursivity + 1);
                                                     if (count($in_files_list) > 0) {
                                                         $files_list = array_merge($files_list, $in_files_list);
                                                     }
                                                 }
                                             }
                                         }
                                         //found some protocol there
                                         if (strpos($source, api_get_path(WEB_PATH)) !== false || strpos(str_replace('http', 'https', $source), api_get_path(WEB_PATH)) !== false) {
                                             //we found the current portal url
                                             // if url of doc is with http:// and is the same as portal but with https, replace source url
                                             if (strpos(str_replace('http', 'https', $source), api_get_path(WEB_PATH)) !== false) {
                                                 $source = str_replace('http', 'https', $source);
                                             }
                                             $files_list[] = array($source, 'local', 'url');
                                             $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $source, $recursivity + 1);
                                             if (count($in_files_list) > 0) {
                                                 $files_list = array_merge($files_list, $in_files_list);
                                             }
                                         } else {
                                             //we didn't find any trace of current portal
                                             $files_list[] = array($source, 'remote', 'url');
                                         }
                                     } else {
                                         //no protocol found, make link local
                                         if (substr($source, 0, 1) === '/') {
                                             //link starts with a /, making it absolute (relative to DocumentRoot)
                                             $files_list[] = array($source, 'local', 'abs');
                                             $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $source, $recursivity + 1);
                                             if (count($in_files_list) > 0) {
                                                 $files_list = array_merge($files_list, $in_files_list);
                                             }
                                         } elseif (strstr($source, '..') === 0) {
                                             //link is relative but going back in the hierarchy
                                             $files_list[] = array($source, 'local', 'rel');
                                             $dir = dirname($abs_path);
                                             $new_abs_path = realpath($dir . '/' . $source);
                                             $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $new_abs_path, $recursivity + 1);
                                             if (count($in_files_list) > 0) {
                                                 $files_list = array_merge($files_list, $in_files_list);
                                             }
                                         } else {
                                             //no starting '/', making it relative to current document's path
                                             if (substr($source, 0, 2) == './') {
                                                 $source = substr($source, 2);
                                             }
                                             $files_list[] = array($source, 'local', 'rel');
                                             $dir = dirname($abs_path);
                                             $new_abs_path = realpath($dir . '/' . $source);
                                             $in_files_list[] = learnpathItem::get_resources_from_source(TOOL_DOCUMENT, $new_abs_path, $recursivity + 1);
                                             if (count($in_files_list) > 0) {
                                                 $files_list = array_merge($files_list, $in_files_list);
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                         break;
                     default:
                         break;
                 }
             } else {
                 //the file could not be found
                 return false;
             }
             break;
         default:
             //ignore
             break;
     }
     //error_log(str_repeat(' ',$recursivity),'found files '.print_r($files_list,true),0);
     //return $files_list;
     $checked_files_list = array();
     $checked_array_list = array();
     foreach ($files_list as $idx => $file) {
         if (!empty($file[0])) {
             if (!in_array($file[0], $checked_files_list)) {
                 $checked_files_list[] = $files_list[$idx][0];
                 $checked_array_list[] = $files_list[$idx];
             }
         }
     }
     return $checked_array_list;
 }