@ -3322,10 +3322,7 @@ class learnpath
}
}
}
//}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;
@ -8288,8 +8285,7 @@ class learnpath
*/
public function scorm_export()
{
global $_course;
$_course = api_get_course_info();
$course_id = api_get_course_int_id();
// Remove memory and time limits as much as possible as this might be a long process...
@ -8309,9 +8305,9 @@ class learnpath
$root_path = $main_path = api_get_path(SYS_PATH);
$files_cleanup = array();
// Place to temporarily stash the zipfiles .
// Place to temporarily stash the zip file.
// create the temp dir if it doesn't exist
// or do a cleanup befor creating the zipfile.
// or do a cleanup before creating the zip file.
if (!is_dir($temp_zip_dir)) {
mkdir($temp_zip_dir, api_get_permissions_for_new_directories());
} else {
@ -8332,10 +8328,13 @@ class learnpath
mkdir($dest_path_to_scorm_folder, api_get_permissions_for_new_directories(), true);
$zip_files_dist = copyr($current_course_path.'/scorm/'.$this->path, $dest_path_to_scorm_folder, array('imsmanifest'), $zip_files);
}
// Build a dummy imsmanifest structure. Do not add to the zip yet (we still need it).
// Build a dummy imsmanifest structure.
// Do not add to the zip yet (we still need it).
// This structure is developed following regulations for SCORM 1.2 packaging in the SCORM 1.2 Content
// Aggregation Model official document, secion "2.3 Content Packaging".
$xmldoc = new DOMDocument('1.0'); // We are going to build a UTF-8 encoded manifest. Later we will recode it to the desired (and supported) encoding.
// Aggregation Model official document, section "2.3 Content Packaging".
// We are going to build a UTF-8 encoded manifest. Later we will recode it to the desired (and supported) encoding.
$xmldoc = new DOMDocument('1.0');
$root = $xmldoc->createElement('manifest');
$root->setAttribute('identifier', 'SingleCourseManifest');
$root->setAttribute('version', '1.1');
@ -8352,7 +8351,6 @@ class learnpath
$root->appendChild($metadata);
$organizations = $xmldoc->createElement('organizations');
$resources = $xmldoc->createElement('resources');
// Build the only organization we will use in building our learnpaths.
@ -8387,14 +8385,18 @@ class learnpath
// For each element, add it to the imsmanifest structure, then add it to the zip.
// Always call the learnpathItem->scorm_export() method to change it to the SCORM format.
$link_updates = array();
$links_to_create = 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.
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
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 < item > to the < organization > element.
$my_item_id = $item->get_id();
$my_item = $xmldoc->createElement('item');
@ -8445,12 +8447,11 @@ class learnpath
$my_xml_file_path = str_replace($path_to_remove, '', $my_file_path);
}
} else {
$my_xml_file_path = $my_file_path;
$my_xml_file_path = $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');
$my_xml_sub_dir = $my_sub_dir;
// Give a < resource > child to the < resources > element
$my_resource = $xmldoc->createElement('resource');
@ -8608,8 +8609,10 @@ 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
if (substr($doc_info[0], 0, 2) == '..') {
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);
@ -8627,16 +8630,16 @@ 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);
}
break;
default:
$my_dep_file->setAttribute('href', $doc_info[0]);
$my_dep->setAttribute('xml:base', '');
break;
}
break;
default:
$my_dep_file->setAttribute('href', $doc_info[0]);
$my_dep->setAttribute('xml:base', '');
break;
}
}
$my_dep->appendChild($my_dep_file);
@ -8646,59 +8649,130 @@ class learnpath
$my_resource->appendChild($dependency);
$i++;
}
//$my_dependency = $xmldoc->createElement('dependency');
//$my_dependency->setAttribute('identifierref', '');
$resources->appendChild($my_resource);
$zip_files[] = $my_file_path;
//error_log('File '.$my_file_path. ' added to $zip_files', 0);
} else {
// If the item is a quiz or a link or whatever non-exportable, we include a step indicating it.
switch ($item->type) {
case TOOL_LINK:
$my_item = $xmldoc->createElement('item');
$my_item->setAttribute('identifier', 'ITEM_'.$item->get_id());
$my_item->setAttribute('identifierref', 'RESOURCE_'.$item->get_id());
$my_item->setAttribute('isvisible', 'true');
// Give a child element < title > to the < item > element.
$my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
$my_item->appendChild($my_title);
// Give a child element < adlcp:prerequisites > to the < item > element.
$my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string());
$my_prereqs->setAttribute('type', 'aicc_script');
$my_item->appendChild($my_prereqs);
// Give a child element < adlcp:maxtimeallowed > to the < item > element - not yet supported.
//$xmldoc->createElement('adlcp:maxtimeallowed', '');
// Give a child element < adlcp:timelimitaction > to the < item > element - not yet supported.
//$xmldoc->createElement('adlcp:timelimitaction', '');
// Give a child element < adlcp:datafromlms > to the < item > element - not yet supported.
//$xmldoc->createElement('adlcp:datafromlms', '');
// Give a child element < adlcp:masteryscore > to the < item > element.
$my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
$my_item->appendChild($my_masteryscore);
// Attach this item to the organization element or its parent if there is one.
if (!empty($item->parent) & & $item->parent != 0) {
$children = $organization->childNodes;
for ($i = 0; $i < $children->length; $i++) {
$item_temp = $children->item($i);
if ($item_temp -> nodeName == 'item') {
if ($item_temp->getAttribute('identifier') == 'ITEM_'.$item->parent) {
$item_temp -> appendChild($my_item);
$my_item = $xmldoc->createElement('item');
$my_item->setAttribute('identifier', 'ITEM_'.$item->get_id());
$my_item->setAttribute('identifierref', 'RESOURCE_'.$item->get_id());
$my_item->setAttribute('isvisible', 'true');
// Give a child element < title > to the < item > element.
$my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
$my_item->appendChild($my_title);
// Give a child element < adlcp:prerequisites > to the < item > element.
$my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string());
$my_prereqs->setAttribute('type', 'aicc_script');
$my_item->appendChild($my_prereqs);
// Give a child element < adlcp:maxtimeallowed > to the < item > element - not yet supported.
//$xmldoc->createElement('adlcp:maxtimeallowed', '');
// Give a child element < adlcp:timelimitaction > to the < item > element - not yet supported.
//$xmldoc->createElement('adlcp:timelimitaction', '');
// Give a child element < adlcp:datafromlms > to the < item > element - not yet supported.
//$xmldoc->createElement('adlcp:datafromlms', '');
// Give a child element < adlcp:masteryscore > to the < item > element.
$my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
$my_item->appendChild($my_masteryscore);
// Attach this item to the organization element or its parent if there is one.
if (!empty($item->parent) & & $item->parent != 0) {
$children = $organization->childNodes;
for ($i = 0; $i < $children->length; $i++) {
$item_temp = $children->item($i);
if ($item_temp -> nodeName == 'item') {
if ($item_temp->getAttribute('identifier') == 'ITEM_'.$item->parent) {
$item_temp -> appendChild($my_item);
}
}
}
} else {
$organization->appendChild($my_item);
}
$my_file_path = 'link_'.$item->get_id().'.html';
$sql = 'SELECT url, title FROM '.Database :: get_course_table(TABLE_LINK).'
WHERE c_id = '.$course_id.' AND id='.$item->path;
$rs = Database::query($sql);
if ($link = Database :: fetch_array($rs)) {
$url = $link['url'];
$title = stripslashes($link['title']);
$links_to_create[$my_file_path] = array('title' => $title, 'url' => $url);
//$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8');
$my_xml_file_path = $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');
$my_xml_sub_dir = $my_sub_dir;
// Give a < resource > child to the < resources > element.
$my_resource = $xmldoc->createElement('resource');
$my_resource->setAttribute('identifier', 'RESOURCE_'.$item->get_id());
$my_resource->setAttribute('type', 'webcontent');
$my_resource->setAttribute('href', $my_xml_file_path);
// adlcp:scormtype can be either 'sco' or 'asset'.
$my_resource->setAttribute('adlcp:scormtype', 'asset');
// xml:base is the base directory to find the files declared in this resource.
$my_resource->setAttribute('xml:base', '');
// give a < file > child to the < resource > element.
$my_file = $xmldoc->createElement('file');
$my_file->setAttribute('href', $my_xml_file_path);
$my_resource->appendChild($my_file);
$resources->appendChild($my_resource);
}
break;
case TOOL_QUIZ:
require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.class.php';
$exe_id = $item->path; // Should be using ref when everything will be cleaned up in this regard.
$exe = new Exercise();
$exe->read($exe_id);
$my_item = $xmldoc->createElement('item');
$my_item->setAttribute('identifier', 'ITEM_'.$item->get_id());
$my_item->setAttribute('identifierref', 'RESOURCE_'.$item->get_id());
$my_item->setAttribute('isvisible', 'true');
// Give a child element < title > to the < item > element.
$my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
$my_item->appendChild($my_title);
$my_max_score = $xmldoc->createElement('max_score', $item->get_max());
//$my_item->appendChild($my_max_score);
// Give a child element < adlcp:prerequisites > to the < item > element.
$my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string());
$my_prereqs->setAttribute('type','aicc_script');
$my_item->appendChild($my_prereqs);
// Give a child element < adlcp:masteryscore > to the < item > element.
$my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
$my_item->appendChild($my_masteryscore);
// Attach this item to the organization element or hits parent if there is one.
if (!empty($item->parent) & & $item->parent != 0) {
$children = $organization->childNodes;
for ($i = 0; $i < $children->length; $i++) {
$item_temp = $children->item($i);
if ($item_temp -> nodeName == 'item') {
if ($item_temp->getAttribute('identifier') == 'ITEM_'.$item->parent) {
$item_temp -> appendChild($my_item);
}
}
}
} else {
$organization->appendChild($my_item);
}
} else {
$organization->appendChild($my_item);
}
$my_file_path = 'link_'.$item->get_id().'.html';
$sql = 'SELECT url, title FROM '.Database :: get_course_table(TABLE_LINK).' WHERE c_id = '.$course_id.' AND id='.$item->path;
$rs = Database::query($sql);
if ($link = Database :: fetch_array($rs)) {
$url = $link['url'];
$title = stripslashes($link['title']);
$links_to_create[$my_file_path] = array('title' => $title, 'url' => $url);
// Include export scripts.
require_once api_get_path(SYS_CODE_PATH).'exercice/export/scorm/scorm_export.php';
// Get the path of the file(s) from the course directory root
//$my_file_path = $item->get_file_path('scorm/'.$this->path.'/');
$my_file_path = 'quiz_'.$item->get_id().'.html';
// Write the contents of the exported exercise into a (big) html file
// to later pack it into the exported SCORM. The file will be removed afterwards.
$contents = export_exercise($exe_id, true);
$tmp_file_path = $archive_path.$temp_dir_short.'/'.$my_file_path;
$res = file_put_contents($tmp_file_path, $contents);
if ($res === false) { error_log('Could not write into file '.$tmp_file_path.' '.__FILE__.' '.__LINE__, 0); }
$files_cleanup[] = $tmp_file_path;
//error_log($tmp_path); die();
//$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8');
$my_xml_file_path = $my_file_path;
$my_sub_dir = dirname($my_file_path);
@ -8711,250 +8785,176 @@ class learnpath
$my_resource->setAttribute('type', 'webcontent');
$my_resource->setAttribute('href', $my_xml_file_path);
// adlcp:scormtype can be either 'sco' or 'asset'.
$my_resource->setAttribute('adlcp:scormtype', 'asset ');
$my_resource->setAttribute('adlcp:scormtype', 'sco ');
// xml:base is the base directory to find the files declared in this resource.
$my_resource->setAttribute('xml:base', '');
// g ive a < file > child to the < resource > element.
// G ive a < file > child to the < resource > element.
$my_file = $xmldoc->createElement('file');
$my_file->setAttribute('href', $my_xml_file_path);
$my_resource->appendChild($my_file);
$resources->appendChild($my_resource);
}
break;
case TOOL_QUIZ:
require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.class.php';
$exe_id = $item->path; // Should be using ref when everything will be cleaned up in this regard.
$exe = new Exercise();
$exe->read($exe_id);
$my_item = $xmldoc->createElement('item');
$my_item->setAttribute('identifier', 'ITEM_'.$item->get_id());
$my_item->setAttribute('identifierref', 'RESOURCE_'.$item->get_id());
$my_item->setAttribute('isvisible', 'true');
// Give a child element < title > to the < item > element.
$my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
$my_item->appendChild($my_title);
$my_max_score = $xmldoc->createElement('max_score', $item->get_max());
//$my_item->appendChild($my_max_score);
// Give a child element < adlcp:prerequisites > to the < item > element.
$my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string());
$my_prereqs->setAttribute('type','aicc_script');
$my_item->appendChild($my_prereqs);
// Give a child element < adlcp:masteryscore > to the < item > element.
$my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
$my_item->appendChild($my_masteryscore);
// Attach this item to the organization element or hits parent if there is one.
if (!empty($item->parent) & & $item->parent != 0) {
$children = $organization->childNodes;
for ($i = 0; $i < $children->length; $i++) {
$item_temp = $children->item($i);
if ($item_temp -> nodeName == 'item') {
if ($item_temp->getAttribute('identifier') == 'ITEM_'.$item->parent) {
$item_temp -> appendChild($my_item);
}
}
}
} else {
$organization->appendChild($my_item);
}
// Include export scripts.
require_once api_get_path(SYS_CODE_PATH).'exercice/export/scorm/scorm_export.php';
// Get the path of the file(s) from the course directory root
//$my_file_path = $item->get_file_path('scorm/'.$this->path.'/');
$my_file_path = 'quiz_'.$item->get_id().'.html';
// Write the contents of the exported exercise into a (big) html file
// to later pack it into the exported SCORM. The file will be removed afterwards.
$contents = export_exercise($exe_id, true);
$tmp_file_path = $archive_path.$temp_dir_short.'/'.$my_file_path;
$res = file_put_contents($tmp_file_path, $contents);
if ($res === false) { error_log('Could not write into file '.$tmp_file_path.' '.__FILE__.' '.__LINE__, 0); }
$files_cleanup[] = $tmp_file_path;
//error_log($tmp_path); die();
//$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8');
$my_xml_file_path = $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');
$my_xml_sub_dir = $my_sub_dir;
// Give a < resource > child to the < resources > element.
$my_resource = $xmldoc->createElement('resource');
$my_resource->setAttribute('identifier', 'RESOURCE_'.$item->get_id());
$my_resource->setAttribute('type', 'webcontent');
$my_resource->setAttribute('href', $my_xml_file_path);
// adlcp:scormtype can be either 'sco' or 'asset'.
$my_resource->setAttribute('adlcp:scormtype', 'sco');
// xml:base is the base directory to find the files declared in this resource.
$my_resource->setAttribute('xml:base', '');
// Give a < file > child to the < resource > element.
$my_file = $xmldoc->createElement('file');
$my_file->setAttribute('href', $my_xml_file_path);
$my_resource->appendChild($my_file);
// Get included docs.
$inc_docs = $item->get_resources_from_source(null,$tmp_file_path);
// 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') {
switch ($doc_info[2]) {
case 'url': // Local URL - save path as url for now, don't zip file.
// Save file but as local file (retrieve from URL).
$abs_path = api_get_path(SYS_PATH).str_replace(api_get_path(WEB_PATH), '', $doc_info[0]);
$current_dir = dirname($abs_path);
$current_dir = str_replace('\\', '/', $current_dir);
$file_path = realpath($abs_path);
$file_path = str_replace('\\', '/', $file_path);
$my_dep_file->setAttribute('href', 'document/'.$file_path);
$my_dep->setAttribute('xml:base', '');
if (strstr($file_path, $main_path) !== false) {
// The calculated real path is really inside the chamilo root path.
// Reduce file path to what's under the DocumentRoot.
$file_path = substr($file_path, strlen($root_path));
//echo $file_path;echo '< br / > < br / > ';
//error_log('Reduced path: '.$file_path, 0);
$zip_files_abs[] = $file_path;
$link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => 'document/'.$file_path);
// Get included docs.
$inc_docs = $item->get_resources_from_source(null,$tmp_file_path);
// 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') {
switch ($doc_info[2]) {
case 'url': // Local URL - save path as url for now, don't zip file.
// Save file but as local file (retrieve from URL).
$abs_path = api_get_path(SYS_PATH).str_replace(api_get_path(WEB_PATH), '', $doc_info[0]);
$current_dir = dirname($abs_path);
$current_dir = str_replace('\\', '/', $current_dir);
$file_path = realpath($abs_path);
$file_path = str_replace('\\', '/', $file_path);
$my_dep_file->setAttribute('href', 'document/'.$file_path);
$my_dep->setAttribute('xml:base', '');
} elseif (empty($file_path)) {
/*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH),api_get_path(REL_PATH)));
if (strpos($document_root,-1) == '/') {
$document_root = substr(0, -1, $document_root);
}*/
$file_path = $_SERVER['DOCUMENT_ROOT'].$abs_path;
$file_path = str_replace('//', '/', $file_path);
if (file_exists($file_path)) {
$file_path = substr($file_path, strlen($current_dir)); // We get the relative path.
$zip_files[] = $my_sub_dir.'/'.$file_path;
if (strstr($file_path, $main_path) !== false) {
// The calculated real path is really inside the chamilo root path.
// Reduce file path to what's under the DocumentRoot.
$file_path = substr($file_path, strlen($root_path));
//echo $file_path;echo '< br / > < br / > ';
//error_log('Reduced path: '.$file_path, 0);
$zip_files_abs[] = $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', '');
} elseif (empty($file_path)) {
/*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH),api_get_path(REL_PATH)));
if (strpos($document_root,-1) == '/') {
$document_root = substr(0, -1, $document_root);
}*/
$file_path = $_SERVER['DOCUMENT_ROOT'].$abs_path;
$file_path = str_replace('//', '/', $file_path);
if (file_exists($file_path)) {
$file_path = substr($file_path, strlen($current_dir)); // We get the relative path.
$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', '');
}
}
}
break;
case 'abs': // Absolute path from DocumentRoot. Save file and leave path as is in the zip.
$current_dir = dirname($current_course_path.'/'.$item->get_file_path()).'/';
$current_dir = str_replace('\\', '/', $current_dir);
$file_path = realpath($doc_info[0]);
$file_path = str_replace('\\', '/', $file_path);
$my_dep_file->setAttribute('href', $file_path);
$my_dep->setAttribute('xml:base', '');
if (strstr($file_path,$main_path) !== false) {
// The calculated real path is really inside the chamilo root path.
// Reduce file path to what's under the DocumentRoot.
$file_path = substr($file_path, strlen($root_path));
//echo $file_path;echo '< br / > < br / > ';
//error_log('Reduced path: '.$file_path, 0);
$zip_files_abs[] = $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', '');
} elseif (empty($file_path)) {
/*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH)));
if (strpos($document_root,-1) == '/') {
$document_root = substr(0, -1, $document_root);
}*/
$file_path = $_SERVER['DOCUMENT_ROOT'].$doc_info[0];
$file_path = str_replace('//', '/', $file_path);
if (file_exists($file_path)) {
$file_path = substr($file_path,strlen($current_dir)); // We get the relative path.
$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', '');
}
}
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
if (substr($doc_info[0], 0, 2) == '..') {
// Relative path going up.
break;
case 'abs': // Absolute path from DocumentRoot. Save file and leave path as is in the zip.
$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 = realpath($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.
// Reduce file path to what's under the DocumentRoot.
$my_dep_file->setAttribute('href', $file_path);
$my_dep->setAttribute('xml:base', '');
if (strstr($file_path,$main_path) !== false) {
// The calculated real path is really inside the chamilo root path.
// Reduce file path to what's under the DocumentRoot.
$file_path = substr($file_path, strlen($root_path));
$file_path_dest = $file_path;
// File path is courses/CHAMILO/document/....
$info_file_path = explode('/', $file_path);
if ($info_file_path[0] == 'courses') { // Add character "/" in file path.
$file_path_dest = 'document/'.$file_path;
}
//echo $file_path;echo '< br / > < br / > ';
//error_log('Reduced path: '.$file_path, 0);
$zip_files_abs[] = $file_path;
$link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path_dest);
$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', '');
} elseif (empty($file_path)) {
/*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH)));
if (strpos($document_root,-1) == '/') {
$document_root = substr(0, -1, $document_root);
}*/
$file_path = $_SERVER['DOCUMENT_ROOT'].$doc_info[0];
$file_path = str_replace('//', '/', $file_path);
if (file_exists($file_path)) {
$file_path = substr($file_path,strlen($current_dir)); // We get the relative path.
$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', '');
}
}
} 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);
}
break;
default:
$my_dep_file->setAttribute('href', $doc_info[0]); // ../../courses/
$my_dep->setAttribute('xml:base', '');
break;
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
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.
// Reduce file path to what's under the DocumentRoot.
$file_path = substr($file_path, strlen($root_path));
$file_path_dest = $file_path;
// File path is courses/CHAMILO/document/....
$info_file_path = explode('/', $file_path);
if ($info_file_path[0] == 'courses') { // Add character "/" in file path.
$file_path_dest = 'document/'.$file_path;
}
//error_log('Reduced path: '.$file_path, 0);
$zip_files_abs[] = $file_path;
$link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path_dest);
$my_dep_file->setAttribute('href', 'document/'.$file_path);
$my_dep->setAttribute('xml:base', '');
}
} 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);
}
break;
default:
$my_dep_file->setAttribute('href', $doc_info[0]); // ../../courses/
$my_dep->setAttribute('xml:base', '');
break;
}
}
$my_dep->appendChild($my_dep_file);
$resources->appendChild($my_dep);
$dependency = $xmldoc->createElement('dependency');
$dependency->setAttribute('identifierref', $res_id);
$my_resource->appendChild($dependency);
$i++;
}
$my_dep->appendChild($my_dep_file);
$resources->appendChild($my_dep);
$dependency = $xmldoc->createElement('dependency');
$dependency->setAttribute('identifierref', $res_id);
$my_resource->appendChild($dependency);
$i++;
}
$resources->appendChild($my_resource);
$zip_files[] = $my_file_path;
$resources->appendChild($my_resource);
$zip_files[] = $my_file_path;
break;
default:
// Get the path of the file(s) from the course directory root
$my_file_path = 'non_exportable.html';
//$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_COMPAT, 'UTF-8');
$my_xml_file_path = $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_COMPAT, 'UTF-8');
$my_xml_sub_dir = $my_sub_dir;
// Give a < resource > child to the < resources > element.
$my_resource = $xmldoc->createElement('resource');
$my_resource->setAttribute('identifier', 'RESOURCE_'.$item->get_id());
$my_resource->setAttribute('type', 'webcontent');
// Get the path of the file(s) from the course directory root
$my_file_path = 'non_exportable.html';
//$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_COMPAT, 'UTF-8');
$my_xml_file_path = $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_COMPAT, 'UTF-8');
$my_xml_sub_dir = $my_sub_dir;
// Give a < resource > child to the < resources > element.
$my_resource = $xmldoc->createElement('resource');
$my_resource->setAttribute('identifier', 'RESOURCE_'.$item->get_id());
$my_resource->setAttribute('type', 'webcontent');
$my_resource->setAttribute('href', $folder_name.'/'.$my_xml_file_path);
// adlcp:scormtype can be either 'sco' or 'asset'.
$my_resource->setAttribute('adlcp:scormtype', 'asset');
// xml:base is the base directory to find the files declared in this resource.
$my_resource->setAttribute('xml:base', '');
// Give a < file > child to the < resource > element.
$my_file = $xmldoc->createElement('file');
$my_file->setAttribute('href', 'document/'.$my_xml_file_path);
$my_resource->appendChild($my_file);
$resources->appendChild($my_resource);
// adlcp:scormtype can be either 'sco' or 'asset'.
$my_resource->setAttribute('adlcp:scormtype', 'asset');
// xml:base is the base directory to find the files declared in this resource.
$my_resource->setAttribute('xml:base', '');
// Give a < file > child to the < resource > element.
$my_file = $xmldoc->createElement('file');
$my_file->setAttribute('href', 'document/'.$my_xml_file_path);
$my_resource->appendChild($my_file);
$resources->appendChild($my_resource);
break;
}
}
@ -8969,21 +8969,19 @@ class learnpath
// then add the file to the zip, then destroy the file (this is done automatically).
// http://www.reload.ac.uk/scormplayer.html - once done, don't forget to close FS#138
//error_log(print_r($zip_files,true), 0);
foreach ($zip_files as $file_path) {
if (empty($file_path)) { continue; }
//error_log(__LINE__.'getting document from '.$sys_course_path.$_course['path'].'/'.$file_path.' removing '.$sys_course_path.$_course['path'].'/',0);
if (empty($file_path)) {
continue;
}
$dest_file = $archive_path.$temp_dir_short.'/'.$file_path;
$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.'< br / > ';
@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);
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
// will be added in document/main/inc/lib/flv_player/flv_player.swf and that needs
// to find the flv to play in document/main/, so we replace main/ in the flv path by
@ -8997,11 +8995,8 @@ class learnpath
if (strpos("main/default_course_document", $old_new['dest'] === false)) {
$new_dest = str_replace('document/', $mult.'document/', $old_new['dest']);
} else {
//$new_dest = str_replace('main/default_course_document', $mult.'document/main/default_course_document', $old_new['dest']);
$new_dest = $old_new['dest'];
}
//$string = str_replace($old_new['orig'], $old_new['dest'], $string);
$string = str_replace($old_new['orig'], $new_dest, $string);
//Add files inside the HTMLs
@ -9014,23 +9009,21 @@ class learnpath
}
}
foreach ($zip_files_abs as $file_path) {
if (empty($file_path)) { continue; }
//error_log(__LINE__.'checking existence of '.$main_path.$file_path.'', 0);
if (!is_file($main_path.$file_path) || !is_readable($main_path.$file_path)) { continue; }
//error_log(__LINE__.'getting document from '.$main_path.$file_path.' removing '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/', 0);
if (empty($file_path)) {
continue;
}
if (!is_file($main_path.$file_path) || !is_readable($main_path.$file_path)) {
continue;
}
$dest_file = $archive_path.$temp_dir_short.'/document/'.$file_path;
$this->create_path($dest_file);
//error_log('Created path '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/document/'.$file_path, 0);
//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.' - '.$dest_file.'< br / > ';
copy($main_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);
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
// will be added in document/main/inc/lib/flv_player/flv_player.swf and that needs
// to find the flv to play in document/main/, so we replace main/ in the flv path by
@ -9044,7 +9037,6 @@ class learnpath
}
}
if (is_array($links_to_create)) {
foreach ($links_to_create as $file => $link) {
$file_content = '<!DOCTYPE html> < head >
@ -9124,15 +9116,18 @@ EOD;
if ($res === false) { error_log('Could not delete temp file '.$file.' '.__FILE__.' '.__LINE__, 0); }
}
// Send file to client.
//$name = 'scorm_export_'.$this->lp_id.'.zip';
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
$name = replace_dangerous_char($this->get_name()).'.zip';
DocumentManager::file_send_for_download($temp_zip_file, true, $name);
}
public function scorm_export_to_pdf($lp_id) {
/**
* @param int $lp_id
* @return bool
*/
public function scorm_export_to_pdf($lp_id)
{
$lp_id = intval($lp_id);
$files_to_export = array();
$course_data = api_get_course_info($this->cc);
@ -9175,11 +9170,13 @@ EOD;
}
/**
* Temp function to be moved in main_api or the best place around for this. Creates a file path
* if it doesn't exist
* Temp function to be moved in main_api or the best place around for this.
* Creates a file path if it doesn't exist
* @param string $path
*/
public function create_path($path) {
$path_bits = split('/', dirname($path));
public function create_path($path)
{
$path_bits = explode('/', dirname($path));
// IS_WINDOWS_OS has been defined in main_api.lib.php
$path_built = IS_WINDOWS_OS ? '' : '/';
@ -9201,7 +9198,8 @@ EOD;
* Delete the image relative to this learning path. No parameter. Only works on instanciated object.
* @return boolean The results of the unlink function, or false if there was no image to start with
*/
public function delete_lp_image() {
public function delete_lp_image()
{
$img = $this->get_preview_image();
if ($img != '') {
$del_file = $this->get_preview_image_path(null, 'sys');
@ -9222,7 +9220,8 @@ EOD;
* @param array The image array, coming from the $_FILES superglobal
* @return boolean True on success, false on error
*/
public function upload_image($image_array) {
public function upload_image($image_array)
{
$image_moved = false;
if (!empty ($image_array['name'])) {
$upload_ok = process_uploaded_file($image_array);
@ -9282,6 +9281,10 @@ EOD;
return false;
}
/**
* @param int $lp_id
* @param string $status
*/
public function set_autolunch($lp_id, $status)
{
$course_id = api_get_course_int_id();
@ -9328,6 +9331,9 @@ EOD;
return $row_max->previous;
}
/**
* Copies an LP
*/
public function copy()
{
$main_path = api_get_path(SYS_CODE_PATH);
@ -9354,7 +9360,8 @@ EOD;
$course_restorer->restore(api_get_course_id(), api_get_session_id(), false, false);
}
function verify_document_size($s) {
function verify_document_size($s)
{
$post_max = ini_get('post_max_size');
$upl_max = ini_get('upload_max_filesize');
$documents_total_space = DocumentManager::documents_total_space();