/** * Gets a link to the resource from the present location, depending on item ID. * @param string Type of link expected * @param integer Learnpath item ID * @return string Link to the lp_item resource */ function get_link($type = 'http', $item_id = null) { if ($this->debug > 0) { error_log('New LP - In learnpath::get_link(' . $type . ',' . $item_id . ')', 0); } if (empty($item_id)) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - no item id given in learnpath::get_link(), using current: ' . $this->get_current_item_id(), 0); } $item_id = $this->get_current_item_id(); } if (empty($item_id)) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - no current item id found in learnpath object', 0); } //still empty, this means there was no item_id given and we are not in an object context or //the object property is empty, return empty link $item_id = $this->first(); return ''; } $file = ''; $lp_table = Database::get_course_table(TABLE_LP_MAIN); $lp_item_table = Database::get_course_table(TABLE_LP_ITEM); $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW); $item_id = Database::escape_string($item_id); $sel = "SELECT l.lp_type as ltype, l.path as lpath, li.item_type as litype, li.path as lipath, li.parameters as liparams " . "FROM {$lp_table} l, {$lp_item_table} li WHERE li.id = {$item_id} AND li.lp_id = l.id"; if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - selecting item ' . $sel, 0); } $res = Database::query($sel); if (Database::num_rows($res) > 0) { $row = Database::fetch_array($res); //var_dump($row); $lp_type = $row['ltype']; $lp_path = $row['lpath']; $lp_item_type = $row['litype']; $lp_item_path = $row['lipath']; $lp_item_params = $row['liparams']; if (empty($lp_item_params) && strpos($lp_item_path, '?') !== false) { list($lp_item_path, $lp_item_params) = explode('?', $lp_item_path); } //$lp_item_params = '?'.$lp_item_params; //add ? if none - left commented to give freedom to scorm implementation //if(substr($lp_item_params,0,1)!='?'){ // $lp_item_params = '?'.$lp_item_params; //} $sys_course_path = ""; if ($type == 'http') { $course_path = ""; //web path } else { $course_path = $sys_course_path; //system path } $course_path = "../../upload/scorm/" . $this->parent_dir; //now go through the specific cases to get the end of the path switch ($lp_type) { case 1: if ($lp_item_type == 'dokeos_chapter') { $file = 'lp_content.php?type=dir'; } else { require_once 'resourcelinker.inc.php'; $file = rl_get_resource_link_for_learnpath(api_get_course_id(), $this->get_id(), $item_id); // check how much attempts of a exercise exits in lp $lp_item_id = $this->get_current_item_id(); $lp_view_id = $this->get_view_id(); $prevent_reinit = $this->items[$this->current]->get_prevent_reinit(); $list = $this->get_toc(); $type_quiz = false; foreach ($list as $toc) { if ($toc['id'] == $lp_item_id && $toc['type'] == 'quiz') { $type_quiz = true; } } if ($type_quiz) { $lp_item_id = Database::escape_string($lp_item_id); $lp_view_id = Database::escape_string($lp_view_id); $sql = "SELECT count(*) FROM {$lp_item_view_table} WHERE lp_item_id='" . (int) $lp_item_id . "' AND lp_view_id ='" . (int) $lp_view_id . "' AND status='completed'"; $result = Database::query($sql, __FILE__, __LINE__); $row_count = Database::fetch_row($result); $count_item_view = (int) $row_count[0]; $not_multiple_attempt = 0; if ($prevent_reinit === 1 && $count_item_view > 0) { $not_multiple_attempt = 0; //See Bug #6751 } $file .= '¬_multiple_attempt=' . $not_multiple_attempt; } $tmp_array = explode("/", $file); $document_name = $tmp_array[count($tmp_array) - 1]; if (strpos($document_name, '_DELETED_')) { $file = 'blank.php?error=document_deleted'; } } break; case 2: if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Item type: ' . $lp_item_type, 0); } if ($lp_item_type != 'dir') { //Quite complex here: //we want to make sure 'http://' (and similar) links can //be loaded as is (withouth the Dokeos path in front) but //some contents use this form: resource.htm?resource=http://blablabla //which means we have to find a protocol at the path's start, otherwise //it should not be considered as an external URL //if($this->prerequisites_match($item_id)){ if (preg_match('#^[a-zA-Z]{2,5}://#', $lp_item_path) != 0) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Found match for protocol in ' . $lp_item_path, 0); } //distant url, return as is $file = $lp_item_path; } else { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - No starting protocol in ' . $lp_item_path, 0); } //prevent getting untranslatable urls $lp_item_path = preg_replace('/%2F/', '/', $lp_item_path); $lp_item_path = preg_replace('/%3A/', ':', $lp_item_path); //prepare the path $file = $course_path . $lp_path . '/' . $lp_item_path; //TODO fix this for urls with protocol header $file = str_replace('//', '/', $file); $file = str_replace(':/', '://', $file); if (substr($lp_path, -1) == '/') { $lp_path = substr($lp_path, 0, -1); } if (is_file(realpath($sys_course_path . '/scorm/' . $lp_path . '/' . $lp_item_path))) { //if file not found $decoded = html_entity_decode($lp_item_path); list($decoded) = explode('?', $decoded); if (!is_file(realpath($sys_course_path . '/scorm/' . $lp_path . '/' . $decoded))) { require_once 'resourcelinker.inc.php'; $file = rl_get_resource_link_for_learnpath(api_get_course_id(), $this->get_id(), $item_id); if (empty($file)) { $file = 'blank.php?error=document_not_found'; } else { $tmp_array = explode("/", $file); $document_name = $tmp_array[count($tmp_array) - 1]; if (strpos($document_name, '_DELETED_')) { $file = 'blank.php?error=document_deleted'; } } } else { $file = $course_path . '/scorm/' . $lp_path . '/' . $decoded; } } } //}else{ //prerequisites did not match //$file = 'blank.php'; //} //We want to use parameters if they were defined in the imsmanifest if ($file != 'blank.php') { $file .= (strstr($file, '?') === false ? '?' : '') . $lp_item_params; } } else { $file = 'lp_content.php?type=dir'; } break; case 3: if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Item type: ' . $lp_item_type, 0); } //formatting AICC HACP append URL $aicc_append = '?aicc_sid=' . urlencode(session_id()) . '&aicc_url=' . urlencode(api_get_path(WEB_CODE_PATH) . 'newscorm/aicc_hacp.php') . '&' . $lp_item_params; if ($lp_item_type != 'dir') { //Quite complex here: //we want to make sure 'http://' (and similar) links can //be loaded as is (withouth the Dokeos path in front) but //some contents use this form: resource.htm?resource=http://blablabla //which means we have to find a protocol at the path's start, otherwise //it should not be considered as an external URL if (preg_match('#^[a-zA-Z]{2,5}://#', $lp_item_path) != 0) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Found match for protocol in ' . $lp_item_path, 0); } //distant url, return as is $file = $lp_item_path; // Enabled and modified by Ivan Tcholakov, 16-OCT-2008. /* if(stristr($file,'<servername>')!==false){ $file = str_replace('<servername>',$course_path.'/scorm/'.$lp_path.'/',$lp_item_path); } */ if (stripos($file, '<servername>') !== false) { //$file = str_replace('<servername>',$course_path.'/scorm/'.$lp_path.'/',$lp_item_path); $web_course_path = str_replace('https://', '', str_replace('http://', '', $course_path)); $file = str_replace('<servername>', $web_course_path . '/scorm/' . $lp_path, $lp_item_path); } // $file .= $aicc_append; } else { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - No starting protocol in ' . $lp_item_path, 0); } //prevent getting untranslatable urls $lp_item_path = preg_replace('/%2F/', '/', $lp_item_path); $lp_item_path = preg_replace('/%3A/', ':', $lp_item_path); //prepare the path - lp_path might be unusable because it includes the "aicc" subdir name $file = $course_path . '/scorm/' . $lp_path . '/' . $lp_item_path; //TODO fix this for urls with protocol header $file = str_replace('//', '/', $file); $file = str_replace(':/', '://', $file); $file .= $aicc_append; } } else { $file = 'lp_content.php?type=dir'; } break; case 4: break; default: break; } } if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - returning "' . $file . '" from get_link', 0); } return $file; }
/** * Gets a link to the resource from the present location, depending on item ID. * @param string Type of link expected * @param integer Learnpath item ID * @return string Link to the lp_item resource */ public function get_link($type = 'http', $item_id = null, $provided_toc = false) { $course_id = $this->get_course_int_id(); if ($this->debug > 0) { error_log('New LP - In learnpath::get_link(' . $type . ',' . $item_id . ')', 0); } if (empty($item_id)) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - no item id given in learnpath::get_link(), using current: ' . $this->get_current_item_id(), 0); } $item_id = $this->get_current_item_id(); } if (empty($item_id)) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - no current item id found in learnpath object', 0); } //still empty, this means there was no item_id given and we are not in an object context or //the object property is empty, return empty link $item_id = $this->first(); return ''; } $file = ''; $lp_table = Database::get_course_table(TABLE_LP_MAIN); $lp_item_table = Database::get_course_table(TABLE_LP_ITEM); $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW); $item_id = Database::escape_string($item_id); $sql = "SELECT l.lp_type as ltype, l.path as lpath, li.item_type as litype, li.path as lipath, li.parameters as liparams\n \t\tFROM {$lp_table} l\n INNER JOIN {$lp_item_table} li\n ON (li.lp_id = l.id AND l.c_id = {$course_id} AND li.c_id = {$course_id} )\n \t\tWHERE li.id = {$item_id} "; if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - selecting item ' . $sql, 0); } $res = Database::query($sql); if (Database::num_rows($res) > 0) { $row = Database::fetch_array($res); $lp_type = $row['ltype']; $lp_path = $row['lpath']; $lp_item_type = $row['litype']; $lp_item_path = $row['lipath']; $lp_item_params = $row['liparams']; if (empty($lp_item_params) && strpos($lp_item_path, '?') !== false) { list($lp_item_path, $lp_item_params) = explode('?', $lp_item_path); } $sys_course_path = api_get_path(SYS_COURSE_PATH) . api_get_course_path(); if ($type == 'http') { $course_path = api_get_path(WEB_COURSE_PATH) . api_get_course_path(); //web path } else { $course_path = $sys_course_path; //system path } // Fixed issue BT#1272 - If the item type is a Chamilo Item (quiz, link, etc), then change the lp type to thread it as a normal Chamilo LP not a SCO. if (in_array($lp_item_type, array('quiz', 'document', 'link', 'forum', 'thread', 'student_publication'))) { $lp_type = 1; } if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - $lp_type ' . $lp_type, 0); error_log('New LP - In learnpath::get_link() - $lp_item_type ' . $lp_item_type, 0); } // Now go through the specific cases to get the end of the path // @todo Use constants instead of int values. switch ($lp_type) { case 1: if ($lp_item_type == 'dokeos_chapter') { $file = 'lp_content.php?type=dir'; } else { require_once 'resourcelinker.inc.php'; $file = rl_get_resource_link_for_learnpath($course_id, $this->get_id(), $item_id); if ($this->debug > 0) { error_log('rl_get_resource_link_for_learnpath - file: ' . $file, 0); } if ($lp_item_type == 'link') { require_once api_get_path(LIBRARY_PATH) . 'link.lib.php'; if (is_youtube_link($file)) { $src = get_youtube_video_id($file); $file = 'embed.php?type=youtube&src=' . $src; } if (isVimeoLink($file)) { $src = getVimeoLinkId($file); $file = 'embed.php?type=vimeo&src=' . $src; } } else { // check how much attempts of a exercise exits in lp $lp_item_id = $this->get_current_item_id(); $lp_view_id = $this->get_view_id(); $prevent_reinit = null; if (isset($this->items[$this->current])) { $prevent_reinit = $this->items[$this->current]->get_prevent_reinit(); } if (empty($provided_toc)) { if ($this->debug > 0) { error_log('In learnpath::get_link() Loading get_toc ', 0); } $list = $this->get_toc(); } else { if ($this->debug > 0) { error_log('In learnpath::get_link() Loading get_toc from "cache" ', 0); } $list = $provided_toc; } $type_quiz = false; foreach ($list as $toc) { if ($toc['id'] == $lp_item_id && $toc['type'] == 'quiz') { $type_quiz = true; } } if ($type_quiz) { $lp_item_id = Database::escape_string($lp_item_id); $lp_view_id = Database::escape_string($lp_view_id); $sql = "SELECT count(*) FROM {$lp_item_view_table}\n WHERE c_id = {$course_id} AND lp_item_id='" . (int) $lp_item_id . "' AND lp_view_id ='" . (int) $lp_view_id . "' AND status='completed'"; $result = Database::query($sql); $row_count = Database::fetch_row($result); $count_item_view = (int) $row_count[0]; $not_multiple_attempt = 0; if ($prevent_reinit === 1 && $count_item_view > 0) { $not_multiple_attempt = 1; } $file .= '¬_multiple_attempt=' . $not_multiple_attempt; } $tmp_array = explode('/', $file); $document_name = $tmp_array[count($tmp_array) - 1]; if (strpos($document_name, '_DELETED_')) { $file = 'blank.php?error=document_deleted'; } } } break; case 2: if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Item type: ' . $lp_item_type, 0); } if ($lp_item_type != 'dir') { // Quite complex here: // We want to make sure 'http://' (and similar) links can // be loaded as is (withouth the Chamilo path in front) but // some contents use this form: resource.htm?resource=http://blablabla // which means we have to find a protocol at the path's start, otherwise // it should not be considered as an external URL. //if ($this->prerequisites_match($item_id)) { if (preg_match('#^[a-zA-Z]{2,5}://#', $lp_item_path) != 0) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Found match for protocol in ' . $lp_item_path, 0); } // Distant url, return as is. $file = $lp_item_path; } else { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - No starting protocol in ' . $lp_item_path, 0); } // Prevent getting untranslatable urls. $lp_item_path = preg_replace('/%2F/', '/', $lp_item_path); $lp_item_path = preg_replace('/%3A/', ':', $lp_item_path); // Prepare the path. $file = $course_path . '/scorm/' . $lp_path . '/' . $lp_item_path; // TODO: Fix this for urls with protocol header. $file = str_replace('//', '/', $file); $file = str_replace(':/', '://', $file); if (substr($lp_path, -1) == '/') { $lp_path = substr($lp_path, 0, -1); } if (!is_file(realpath($sys_course_path . '/scorm/' . $lp_path . '/' . $lp_item_path))) { // if file not found. $decoded = html_entity_decode($lp_item_path); list($decoded) = explode('?', $decoded); if (!is_file(realpath($sys_course_path . '/scorm/' . $lp_path . '/' . $decoded))) { require_once 'resourcelinker.inc.php'; $file = rl_get_resource_link_for_learnpath($course_id, $this->get_id(), $item_id); if (empty($file)) { $file = 'blank.php?error=document_not_found'; } else { $tmp_array = explode('/', $file); $document_name = $tmp_array[count($tmp_array) - 1]; if (strpos($document_name, '_DELETED_')) { $file = 'blank.php?error=document_deleted'; } else { $file = 'blank.php?error=document_not_found'; } } } else { $file = $course_path . '/scorm/' . $lp_path . '/' . $decoded; } } } //}else{ //prerequisites did not match //$file = 'blank.php'; //} // We want to use parameters if they were defined in the imsmanifest if (strpos($file, 'blank.php') === false) { $file .= (strstr($file, '?') === false ? '?' : '') . $lp_item_params; } } else { $file = 'lp_content.php?type=dir'; } break; case 3: if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Item type: ' . $lp_item_type, 0); } // Formatting AICC HACP append URL. $aicc_append = '?aicc_sid=' . urlencode(session_id()) . '&aicc_url=' . urlencode(api_get_path(WEB_CODE_PATH) . 'newscorm/aicc_hacp.php') . '&'; if ($lp_item_type != 'dir') { // Quite complex here: // We want to make sure 'http://' (and similar) links can // be loaded as is (withouth the Chamilo path in front) but // some contents use this form: resource.htm?resource=http://blablabla // which means we have to find a protocol at the path's start, otherwise // it should not be considered as an external URL. if (preg_match('#^[a-zA-Z]{2,5}://#', $lp_item_path) != 0) { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - Found match for protocol in ' . $lp_item_path, 0); } // Distant url, return as is. $file = $lp_item_path; // Enabled and modified by Ivan Tcholakov, 16-OCT-2008. /* if (stristr($file,'<servername>') !== false) { $file = str_replace('<servername>', $course_path.'/scorm/'.$lp_path.'/', $lp_item_path); } */ if (stripos($file, '<servername>') !== false) { //$file = str_replace('<servername>',$course_path.'/scorm/'.$lp_path.'/',$lp_item_path); $web_course_path = str_replace('https://', '', str_replace('http://', '', $course_path)); $file = str_replace('<servername>', $web_course_path . '/scorm/' . $lp_path, $lp_item_path); } // $file .= $aicc_append; } else { if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() ' . __LINE__ . ' - No starting protocol in ' . $lp_item_path, 0); } // Prevent getting untranslatable urls. $lp_item_path = preg_replace('/%2F/', '/', $lp_item_path); $lp_item_path = preg_replace('/%3A/', ':', $lp_item_path); // Prepare the path - lp_path might be unusable because it includes the "aicc" subdir name. $file = $course_path . '/scorm/' . $lp_path . '/' . $lp_item_path; // TODO: Fix this for urls with protocol header. $file = str_replace('//', '/', $file); $file = str_replace(':/', '://', $file); $file .= $aicc_append; } } else { $file = 'lp_content.php?type=dir'; } break; case 4: break; default: break; } } if ($this->debug > 2) { error_log('New LP - In learnpath::get_link() - returning "' . $file . '" from get_link', 0); } return $file; }