diff --git a/main/newscorm/download.php b/main/newscorm/download.php new file mode 100644 index 0000000000..4bb035d029 --- /dev/null +++ b/main/newscorm/download.php @@ -0,0 +1,59 @@ +get_id(); + $lp_item_id = $_SESSION['oLP']->current; + $lp_item_info = new learnpathItem($lp_item_id); + if (!empty($lp_item_info)) { + //if (basename($lp_item_info->path) == basename($doc_url)) { + $visible = $_SESSION['oLP']->is_lp_visible_for_student($lp_id, $user_id); + + if ($visible) { + event_download($doc_url); + if (Security::check_abs_path($sys_course_path.$doc_url, $sys_course_path.'/')) { + $full_file_name = $sys_course_path.$doc_url; + DocumentManager::file_send_for_download($full_file_name); + exit; + } + } + //} + } +} + +Display::display_error_message(get_lang('ProtectedDocument'));//api_not_allowed backbutton won't work. +exit; \ No newline at end of file diff --git a/main/newscorm/learnpath.class.php b/main/newscorm/learnpath.class.php index f2d55fa992..5c7d12a5d3 100644 --- a/main/newscorm/learnpath.class.php +++ b/main/newscorm/learnpath.class.php @@ -6676,7 +6676,12 @@ class learnpath { if (!empty($item_path)) { $extension = pathinfo($item_path, PATHINFO_EXTENSION); } - if (($item_type == 'asset' || $item_type == 'sco') && ($extension == 'html' || $extension == 'htm')) { + + //assets can't be modified + + //$item_type == 'asset' || + if (( $item_type == 'sco') && ($extension == 'html' || $extension == 'htm')) { + if ($item_type == 'sco') { $form->addElement('html', ''); } @@ -8128,12 +8133,12 @@ class learnpath { $link_updates = array(); foreach ($this->items as $index => $item) { if (!in_array($item->type, array(TOOL_QUIZ, TOOL_FORUM, TOOL_THREAD, TOOL_LINK, TOOL_STUDENTPUBLICATION))) { - // Get included documents from this item. + // Get included documents from this item if ($item->type == 'sco') $inc_docs = $item->get_resources_from_source(null, api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'.'scorm/'.$this->path.'/'.$item->get_path()); else $inc_docs = $item->get_resources_from_source(); - + // Give a child element to the element. $my_item_id = $item->get_id(); $my_item = $xmldoc->createElement('item'); @@ -8179,7 +8184,6 @@ class learnpath { $my_xml_file_path = str_replace($path_to_remove, $path_to_replace, $my_file_path); } - $my_sub_dir = dirname($my_file_path); $my_sub_dir = str_replace('\\', '/', $my_sub_dir); //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8'); @@ -8206,23 +8210,27 @@ class learnpath { // Dependency to other files - not yet supported. $i = 1; - + foreach ($inc_docs as $doc_info) { + if (count($doc_info) < 1 || empty($doc_info[0])) { continue; } + $my_dep = $xmldoc->createElement('resource'); $res_id = 'RESOURCE_'.$item->get_id().'_'.$i; $my_dep->setAttribute('identifier', $res_id); $my_dep->setAttribute('type', 'webcontent'); $my_dep->setAttribute('adlcp:scormtype', 'asset'); $my_dep_file = $xmldoc->createElement('file'); + // Check type of URL. //error_log(__LINE__.'Now dealing with '.$doc_info[0].' of type '.$doc_info[1].'-'.$doc_info[2], 0); if ($doc_info[1] == 'remote') { // Remote file. Save url as is. $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', ''); - } elseif ($doc_info[1] == 'local') { + } elseif ($doc_info[1] == 'local') { switch ($doc_info[2]) { + case 'url': // Local URL - save path as url for now, don't zip file. $abs_path = api_get_path(SYS_PATH).str_replace(api_get_path(WEB_PATH), '', $doc_info[0]); $current_dir = dirname($abs_path); @@ -8278,6 +8286,7 @@ class learnpath { // Prepare the current directory path (until just under 'document') with a trailing slash. $cur_path = substr($current_course_path, -1) == '/' ? $current_course_path : $current_course_path.'/'; // Check if the current document is in that path. + if (strstr($file_path, $cur_path) !== false) { // The document is in that path, now get the relative path // to the containing document. @@ -8285,14 +8294,21 @@ class learnpath { $orig_file_path = str_replace('\\', '/', $orig_file_path); $relative_path = ''; if (strstr($file_path, $cur_path) !== false) { - $relative_path = substr($file_path, strlen($orig_file_path)); - $file_path = substr($file_path, strlen($cur_path)); + + if (strpos($orig_file_path, $file_path) == false) { + //no need to do something + $file_path = $relative_path = substr($file_path, strlen($cur_path)); + } else { + $relative_path = substr($file_path, strlen($orig_file_path)); + $file_path = substr($file_path, strlen($cur_path)); + } } else { // This case is still a problem as it's difficult to calculate a relative path easily // might still generate wrong links. //$file_path = substr($file_path,strlen($cur_path)); // Calculate the directory path to the current file (without trailing slash). $my_relative_path = dirname($file_path); + $my_relative_path = str_replace('\\', '/', $my_relative_path); $my_relative_file = basename($file_path); // Calculate the directory path to the containing file (without trailing slash). @@ -8310,11 +8326,13 @@ class learnpath { } $relative_path = $dotdot.$subdir.$my_relative_file; } + // Put the current document in the zip (this array is the array // that will manage documents already in the course folder - relative). $zip_files[] = $file_path; // Update the links to the current document in the containing document (make them relative). $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $relative_path); + $my_dep_file->setAttribute('href', $file_path); $my_dep->setAttribute('xml:base', ''); } elseif (strstr($file_path,$main_path) !== false) { @@ -8343,13 +8361,16 @@ class learnpath { } } break; - case 'rel': // Path relative to the current document. Save xml:base as current document's directory and save file in zip as subdir.file_path + case 'rel': // Path relative to the current document. Save xml:base as current document's directory and save file in zip as subdir.file_path if (substr($doc_info[0], 0, 2) == '..') { // Relative path going up. $current_dir = dirname($current_course_path.'/'.$item->get_file_path()).'/'; + + $current_dir = str_replace('\\', '/', $current_dir); $file_path = realpath($current_dir.$doc_info[0]); $file_path = str_replace('\\', '/', $file_path); + //error_log($file_path.' <-> '.$main_path,0); if (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside Chamilo's root path. @@ -8361,7 +8382,7 @@ class learnpath { $my_dep_file->setAttribute('href', 'document/'.$file_path); $my_dep->setAttribute('xml:base', ''); } - } else { + } else { $zip_files[] = $my_sub_dir.'/'.$doc_info[0]; $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', $my_xml_sub_dir); @@ -8575,7 +8596,7 @@ class learnpath { $zip_files[] = $my_sub_dir.'/'.$file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => 'document/'.$file_path); $my_dep_file->setAttribute('href', 'document/'.$file_path); - $my_dep->setAttribute('xml:base', ''); + $my_dep->setAttribute('xml:base', ''); } } break; @@ -8609,7 +8630,7 @@ class learnpath { $zip_files[] = $my_sub_dir.'/'.$file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', 'document/'.$file_path); - $my_dep->setAttribute('xml:base', ''); + $my_dep->setAttribute('xml:base', ''); } } break; @@ -8704,7 +8725,8 @@ class learnpath { // http://www.reload.ac.uk/scormplayer.html - once done, don't forget to close FS#138 //error_log(print_r($zip_files,true), 0); - + + $root = api_get_path(SYS_PATH); foreach ($zip_files as $file_path) { if (empty($file_path)) { continue; } @@ -8718,12 +8740,13 @@ class learnpath { $this->create_path($dest_file); //error_log('copy '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/'.$file_path.' to '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/'.$file_path,0); //echo $main_path.$file_path.'
'; + @copy($sys_course_path.$_course['path'].'/'.$file_path, $dest_file); // Check if the file needs a link update if (in_array($file_path, array_keys($link_updates))) { $string = file_get_contents($dest_file); - unlink($dest_file); + unlink($dest_file); foreach ($link_updates[$file_path] as $old_new) { //error_log('Replacing '.$old_new['orig'].' by '.$old_new['dest'].' in '.$file_path, 0); // This is an ugly hack that allows .flv files to be found by the flv player that @@ -8732,11 +8755,18 @@ class learnpath { // ../../.. to return from inc/lib/flv_player to the document/main path. if (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 5) == 'main/') { $old_new['dest'] = str_replace('main/', '../../../', $old_new['dest']); - } - elseif (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 6) == 'video/') { + } elseif (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 6) == 'video/') { $old_new['dest'] = str_replace('video/', '../../../../video/', $old_new['dest']); } $string = str_replace($old_new['orig'], $old_new['dest'], $string); + + //Add files inside the HTMLs + $new_path = str_replace('/courses/', '', $old_new['orig']); + /*var_dump($sys_course_path.$new_path); + var_dump($archive_path.$temp_dir_short.'/document/'.$old_new['dest']); + echo '---';*/ + copy($sys_course_path.$new_path, $archive_path.$temp_dir_short.'/document/'.$old_new['dest']); + } file_put_contents($dest_file, $string); } @@ -9073,9 +9103,6 @@ EOD; $course_restorer->set_tool_copy_settings(array('learnpaths' => array('reset_dates' => true))); $course_restorer->restore(api_get_course_id(), api_get_session_id(), false, false); } - - - } if (!function_exists('trim_value')) { diff --git a/main/newscorm/learnpathItem.class.php b/main/newscorm/learnpathItem.class.php index 512c092394..aec19fea99 100644 --- a/main/newscorm/learnpathItem.class.php +++ b/main/newscorm/learnpathItem.class.php @@ -725,6 +725,7 @@ class learnpathItem { //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: @@ -734,8 +735,10 @@ class learnpathItem { 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)) { + + switch (strtolower($ext)) { case 'html': case 'htm': case 'shtml': @@ -745,12 +748,13 @@ class learnpathItem { $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. + + // 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. @@ -759,15 +763,15 @@ class learnpathItem { if (strpos($source, ';') && !strpos($source, '&')) continue; // Avoid code - that should help. if ($attr == 'value') { - if (strpos($source , 'mp3file')) { + 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) { + } elseif (strpos($source, 'flv=') === 0) { + $source = substr($source, 4); if (strpos($source, '&') > 0) { $source = substr($source, 0, strpos($source, '&')); @@ -786,6 +790,7 @@ class learnpathItem { 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. @@ -808,8 +813,7 @@ class learnpathItem { // We didn't find any trace of current portal. $files_list[] = array($second_part, 'remote', 'url'); } - } - elseif(strpos($second_part, '=') > 0) { + } 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'); @@ -817,8 +821,7 @@ class learnpathItem { if (count($in_files_list) > 0) { $files_list = array_merge($files_list, $in_files_list); } - } - elseif(strstr($second_part, '..') === 0) { + } 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); @@ -889,6 +892,7 @@ class learnpathItem { } } } + // Found some protocol there. if (strpos($source, api_get_path(WEB_PATH)) !== false) { // We found the current portal url. @@ -903,15 +907,14 @@ class learnpathItem { } } else { // No protocol found, make link local. - if (substr($source, 0, 1) === '/') { + 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) { + } elseif (strstr($source, '..') === 0) { // Link is relative but going back in the hierarchy. $files_list[] = array($source, 'local', 'rel'); $dir = dirname($abs_path); @@ -921,10 +924,15 @@ class learnpathItem { $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); @@ -961,7 +969,7 @@ class learnpathItem { $checked_array_list[] = $files_list[$idx]; } } - } + } return $checked_array_list; } diff --git a/main/newscorm/lp_list.php b/main/newscorm/lp_list.php index b576c3abbc..6746f4af04 100644 --- a/main/newscorm/lp_list.php +++ b/main/newscorm/lp_list.php @@ -412,16 +412,16 @@ if (!empty($flat_list)) { /* Export */ if ($details['lp_type'] == 1) { - $dsp_disk = Display::url(Display::return_icon('export_scorm.png', get_lang('Export'), array(), ICON_SIZE_SMALL), api_get_self()."?".api_get_cidreq()."&action=export&lp_id=$id"); + $dsp_disk = Display::url(Display::return_icon('cd.gif', get_lang('Export'), array(), ICON_SIZE_SMALL), api_get_self()."?".api_get_cidreq()."&action=export&lp_id=$id"); } elseif ($details['lp_type'] == 2) { - $dsp_disk = Display::url(Display::return_icon('export_scorm.png', get_lang('Export'), array(), ICON_SIZE_SMALL), api_get_self()."?".api_get_cidreq()."&action=export&lp_id=$id&export_name=".replace_dangerous_char($name, 'strict').".zip"); + $dsp_disk = Display::url(Display::return_icon('cd.gif', get_lang('Export'), array(), ICON_SIZE_SMALL), api_get_self()."?".api_get_cidreq()."&action=export&lp_id=$id&export_name=".replace_dangerous_char($name, 'strict').".zip"); } else { - $dsp_disk = Display::return_icon('export_scorm_na.png', get_lang('Export'), array(), ICON_SIZE_SMALL); + $dsp_disk = Display::return_icon('cd_gray.gif', get_lang('Export'), array(), ICON_SIZE_SMALL); } //Copy - $copy = Display::url(Display::return_icon('cd.gif', get_lang('Copy'), array(), ICON_SIZE_SMALL), api_get_self()."?".api_get_cidreq()."&action=copy&lp_id=$id"); + $copy = Display::url(Display::return_icon('cd_copy.png', get_lang('Copy'), array(), ICON_SIZE_SMALL), api_get_self()."?".api_get_cidreq()."&action=copy&lp_id=$id"); /* Auto Lunch LP code*/ $lp_auto_lunch_icon = ''; diff --git a/main/newscorm/scorm.class.php b/main/newscorm/scorm.class.php index 5a73e1e455..a116851bfe 100644 --- a/main/newscorm/scorm.class.php +++ b/main/newscorm/scorm.class.php @@ -271,6 +271,7 @@ class scorm extends learnpath { $new_lp = Database::get_course_table(TABLE_LP_MAIN); $new_lp_item = Database::get_course_table(TABLE_LP_ITEM); $use_max_score = intval($use_max_score); + foreach ($this->organizations as $id => $dummy) { $is_session = api_get_session_id(); $is_session != 0 ? $session_id = $is_session : $session_id = 0; @@ -297,6 +298,7 @@ class scorm extends learnpath { $res = Database::query($sql); $lp_id = Database::insert_id(); $this->lp_id = $lp_id; + // Insert into item_property. api_item_property_update(api_get_course_info($course_code), TOOL_LEARNPATH, $this->lp_id, 'LearnpathAdded', api_get_user_id()); api_item_property_update(api_get_course_info($course_code), TOOL_LEARNPATH, $this->lp_id, 'visible', api_get_user_id()); @@ -308,6 +310,7 @@ class scorm extends learnpath { $parent = 0; $previous = 0; $level = 0; + foreach ($list as $item) { if ($item['level'] > $level) { // Push something into the parents array. @@ -363,6 +366,7 @@ class scorm extends learnpath { $identifier = Database::escape_string($item['identifier']); $prereq = Database::escape_string($item['prerequisites']); + $sql_item = "INSERT INTO $new_lp_item (c_id, lp_id,item_type,ref,title, path,min_score,max_score, $field_add parent_item_id,previous_item_id,next_item_id, prerequisite,display_order,launch_data, parameters) VALUES " . "($course_id, $lp_id, '$type','".$identifier."','".$title."'," . "'$path',0,$max_score, $value_add" . @@ -461,6 +465,7 @@ class scorm extends learnpath { $zip_file_path = $zip_file_info['tmp_name']; $zip_file_name = $zip_file_info['name']; + if ($this->debug > 1) { error_log('New LP - import_package() - zip file path = '.$zip_file_path.', zip file name = '.$zip_file_name, 0); } $course_rel_dir = api_get_course_path().'/scorm'; // scorm dir web path starting from /courses $course_sys_dir = api_get_path(SYS_COURSE_PATH).$course_rel_dir; // Absolute system path for this course. @@ -493,7 +498,8 @@ class scorm extends learnpath { $manifest_list = array(); // The following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?). - foreach ($zipContentArray as $thisContent) { + foreach ($zipContentArray as $thisContent) { + $thisContent['filename']; //error_log('Looking at '.$thisContent['filename'], 0); if (preg_match('~.(php.*|phtml)$~i', $thisContent['filename'])) { $this->set_error_msg("File $file contains a PHP script"); @@ -514,6 +520,7 @@ class scorm extends learnpath { } $realFileSize += $thisContent['size']; } + // Now get the shortest path (basically, the imsmanifest that is the closest to the root). $shortest_path = $manifest_list[0]; $slash_count = substr_count($shortest_path, '/'); @@ -565,6 +572,7 @@ class scorm extends learnpath { $saved_dir = getcwd(); chdir($course_sys_dir.$new_dir); $unzippingState = $zipFile->extract(); + for ($j = 0; $j < count($unzippingState); $j++) { $state = $unzippingState[$j]; @@ -596,10 +604,11 @@ class scorm extends learnpath { if ($this->debug >= 1) { error_log('Comparing: '.$safe_file, 0); } if ($this->debug >= 1) { error_log('and: '.$file, 0); } - + if ($safe_file != $file) { //@rename($course_sys_dir.$new_dir, $course_sys_dir.'/'.$safe_file); $mydir = dirname($course_sys_dir.$new_dir.$safe_file); + if (!is_dir($mydir)) { $mysubdirs = split('/', $mydir); $mybasedir = '/'; @@ -746,7 +755,7 @@ class scorm extends learnpath { require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php'; require_once api_get_path(LIBRARY_PATH).'fileManage.lib.php'; require_once api_get_path(LIBRARY_PATH).'document.lib.php'; - require_once api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php'; + require_once 'learnpath_functions.inc.php'; $course_id = api_get_course_int_id(); $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);