/** * 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 Chamilo 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 */ public 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 = DocumentManager::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, '&')) { 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) { // 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 (strpos($source, 'width=') || strpos($source, 'autostart=')) { continue; } 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; }