Maintenance: CommonCartridge: Fix issue uploading referenced 'webcontent' files to the documents tool ('commoncartridge' folder) - refs BT#21709

pull/3943/head^2
Yannick Warnier 1 year ago
parent 7c911e26de
commit 13ec1f9b06
  1. 10
      main/common_cartridge/import/Cc1p3Convert.php
  2. 68
      main/common_cartridge/import/src/base/CcBase.php
  3. 6
      main/common_cartridge/import/src/converter/Cc13Quiz.php
  4. 50
      main/common_cartridge/import/src/converter/Cc13Resource.php

@ -39,9 +39,15 @@ class Cc1p3Convert extends CcBase
*/
public function generateImportData(): void
{
$countInstances = 0;
$xpath = static::newxPath(static::$manifest, static::$namespaces);
// Scan for detached resources of type 'webcontent'
$resources = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@type="'.static::CC_TYPE_WEBCONTENT.'"]');
$this->createInstances($resources, 0, $countInstances);
// Scan for organization items or resources that are tests (question banks)
$items = $xpath->query('/imscc:manifest/imscc:organizations/imscc:organization/imscc:item | /imscc:manifest/imscc:resources/imscc:resource[@type="'.static::CC_TYPE_QUESTION_BANK.'"]');
$this->createInstances($items);
$this->createInstances($items, 0,$countInstances);
$resources = new Cc13Resource();
$forums = new Cc13Forum();
@ -66,7 +72,7 @@ class Cc1p3Convert extends CcBase
$groupId,
null,
$documentPath,
'/cc1p3',
'/commoncartridge',
'Common Cartridge folder',
0
);

@ -66,7 +66,12 @@ class CcBase
return static::$resourcens;
}
public static function getManifest($folder)
/**
* Find the imsmanifest.xml file inside the given folder and return its path
* @param string $folder Full path name of the folder in which we expect to find imsmanifest.xml
* @return false|string
*/
public static function getManifest(string $folder)
{
if (!is_dir($folder)) {
return false;
@ -156,6 +161,19 @@ class CcBase
}
}
public function getItemHref($identifier)
{
$xpath = static::newxPath(static::$manifest, static::$namespaces);
$nodes = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="'.$identifier.'"]/imscc:file/@href');
if ($nodes && !empty($nodes->item(0)->nodeValue)) {
return $nodes->item(0)->nodeValue;
} else {
return '';
}
}
public static function newxPath(DOMDocument $manifest, $namespaces = '')
{
$xpath = new DOMXPath($manifest);
@ -257,13 +275,12 @@ class CcBase
foreach ($items as $item) {
$array_index++;
if ($item->nodeName == "item") {
$identifierref = '';
$title = $path = $tool_type = $identifierref = '';
if ($item->nodeName == 'item') {
if ($item->hasAttribute('identifierref')) {
$identifierref = $item->getAttribute('identifierref');
}
$title = '';
$titles = $xpath->query('imscc:title', $item);
if ($titles->length > 0) {
$title = $titles->item(0)->nodeValue;
@ -275,34 +292,43 @@ class CcBase
if (empty($identifierref) && empty($title)) {
$tool_type = TYPE_UNKNOWN;
}
} elseif ($item->nodeName == "resource") {
} elseif ($item->nodeName == 'resource') {
$identifierref = $xpath->query('@identifier', $item);
$identifierref = !empty($identifierref->item(0)->nodeValue) ? $identifierref->item(0)->nodeValue : '';
$ccType = $this->getItemCcType($identifierref);
$tool_type = $this->convertToToolType($ccType);
$title = 'Quiz Bank '.($this->countInstances($tool_type) + 1);
if (self::CC_TYPE_WEBCONTENT == $ccType) {
$path = $this->getItemHref($identifierref);
$title = basename($path);
} else { // A resource but not a file... we assume it's a quiz bank and its assigned identifier is irrelevant to its name
$title = 'Quiz Bank '.($this->countInstances($tool_type) + 1);
}
}
if ($level == ROOT_DEEP) {
$index_root = $array_index;
}
static::$instances['index'][$array_index]['common_cartridge_type'] = $ccType;
static::$instances['index'][$array_index]['tool_type'] = $tool_type;
static::$instances['index'][$array_index]['title'] = $title ? $title : '';
static::$instances['index'][$array_index]['root_parent'] = $index_root;
static::$instances['index'][$array_index]['index'] = $array_index;
static::$instances['index'][$array_index]['deep'] = $level;
static::$instances['index'][$array_index]['instance'] = $this->countInstances($tool_type);
static::$instances['index'][$array_index]['resource_identifier'] = $identifierref;
static::$instances['instances'][$tool_type][] = ['title' => $title,
'instance' => static::$instances['index'][$array_index]['instance'],
'common_cartridge_type' => $ccType,
'resource_identifier' => $identifierref,
'deep' => $level, ];
static::$instances['index'][$array_index] = [
'common_cartridge_type' => $ccType,
'tool_type' => $tool_type,
'title' => $title ? $title : '',
'root_parent' => $index_root,
'index' => $array_index,
'deep' => $level,
'instance' => $this->countInstances($tool_type),
'resource_identifier' => $identifierref,
];
static::$instances['instances'][$tool_type][] = [
'title' => $title,
'instance' => static::$instances['index'][$array_index]['instance'],
'common_cartridge_type' => $ccType,
'resource_identifier' => $identifierref,
'deep' => $level,
'src' => $path,
];
$more_items = $xpath->query('imscc:item', $item);

@ -31,6 +31,8 @@ class Cc13Quiz extends Cc13Entities
{
$token = '/\$(?:IMS|1EdTech)[-_]CC[-_]FILEBASE\$/';
$courseInfo = api_get_course_info();
// Replace by the path in documents in which we place all relevant CC files
$replacementPath = '/courses/'.$courseInfo['directory'].'/document/commoncartridge/';
$exercise = new Exercise($courseInfo['real_id']);
$title = Exercise::format_title_variable($quiz['title']);
$exercise->updateTitle($title);
@ -66,9 +68,9 @@ class Cc13Quiz extends Cc13Entities
$questionInstance->updateTitle(substr(Security::remove_XSS(strip_tags_blacklist($question['title'], ['br', 'p'])), 0, 20));
$questionText = Security::remove_XSS(strip_tags_blacklist($question['title'], ['br', 'p']));
// Replace the path from $1EdTech-CC-FILEBASE$ to a correct chamilo path
$questionText = preg_replace($token, '/courses/'.$courseInfo['path'].'/document', $questionText);
$questionText = preg_replace($token, $replacementPath, $questionText);
$questionInstance->updateDescription($questionText);
$questionInstance->updateLevel(1);
$questionInstance->updateCategory(0);

@ -32,6 +32,9 @@ class Cc13Resource extends Cc13Entities
public function storeDocuments($documents, $path)
{
$courseInfo = api_get_course_info();
$sessionId = api_get_session_id();
$groupId = api_get_group_id();
$documentPath = api_get_path(SYS_COURSE_PATH).$courseInfo['directory'].'/document';
foreach ($documents as $document) {
if ($document[2] == 'file') {
@ -47,9 +50,22 @@ class Cc13Resource extends Cc13Entities
$_POST['language'] = $courseInfo['language'];
$_POST['cc_import'] = true;
$destDir = dirname($document[4]);
// Create the subdirectory if necessary
create_unexisting_directory(
$courseInfo,
api_get_user_id(),
$sessionId,
$groupId,
null,
$documentPath,
'/commoncartridge/'.$destDir,
$destDir,
1
);
DocumentManager::upload_document(
$files,
'/cc1p3',
'/commoncartridge/'.$destDir,
$document[1],
'',
null,
@ -80,12 +96,8 @@ class Cc13Resource extends Cc13Entities
if (empty($resource)) {
unset($resource);
$resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="'.$instance['resource_identifier'].'"]/imscc:file/@href');
if ($resource->length > 0) {
$resource = !empty($resource->item(0)->nodeValue) ? $resource->item(0)->nodeValue : '';
} else {
$resource = '';
}
// src has been set in CcBase::createInstances() based on the contents of <file href="...">
$resource = $instance['src'];
}
if (!empty($resource)) {
$link = $resource;
@ -93,7 +105,8 @@ class Cc13Resource extends Cc13Entities
}
if ($instance['common_cartridge_type'] == Cc1p3Convert::CC_TYPE_WEBLINK) {
$external_resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="'.$instance['resource_identifier'].'"]/imscc:file/@href')->item(0)->nodeValue;
// src has been set in CcBase::createInstances() based on the contents of <file href="...">
$external_resource = $instance['src'];
if ($external_resource) {
$resource = $this->loadXmlResource(Cc1p3Convert::$pathToManifestFolder.DIRECTORY_SEPARATOR.$external_resource);
@ -122,12 +135,12 @@ class Cc13Resource extends Cc13Entities
$mod_options = 'objectframe';
$mod_reference = $link;
$mod_alltext = '';
//detected if we are dealing with html file
// detect if we are dealing with html file
if (!empty($link) && ($instance['common_cartridge_type'] == Cc1p3Convert::CC_TYPE_WEBCONTENT)) {
$ext = strtolower(pathinfo($link, PATHINFO_EXTENSION));
if (in_array($ext, ['html', 'htm', 'xhtml'])) {
$mod_type = 'html';
//extract the content of the file
//extract the content of the file and treat it
$rootpath = realpath(Cc1p3Convert::$pathToManifestFolder);
$htmlpath = realpath($rootpath.DIRECTORY_SEPARATOR.$link);
$dirpath = dirname($htmlpath);
@ -163,7 +176,7 @@ class Cc13Resource extends Cc13Entities
$rtp = realpath($rpath);
if (($rtp !== false) && is_file($rtp)) {
//file is there - we are in business
$strip = str_replace("\\", "/", str_ireplace($rootpath, '', $rtp));
$strip = str_replace("\\", "/", str_ireplace($rootpath, '/', $rtp));
//$encoded_file = '$@FILEPHP@$'.str_replace('/', '$@SLASH@$', $strip);
$encoded_file = $strip;
$searches[] = $resrc->nodeValue;
@ -180,13 +193,14 @@ class Cc13Resource extends Cc13Entities
}
}
$values = [$instance['instance'],
self::safexml($instance['title']),
$mod_type,
$mod_alltext,
$mod_reference,
$mod_options,
];
$values = [
$instance['instance'],
self::safexml($instance['title']),
$mod_type,
$mod_alltext,
$mod_reference, // src or href
$mod_options,
];
return $values;
}

Loading…
Cancel
Save