Course maintenance: Add support for IMS Common Cartridge 1.3 import and export - refs #2747
Authored-by: Christian <christianbeeznest@users.noreply.github.com>pull/3952/head
parent
3ebaffa9e0
commit
47915cfb17
@ -0,0 +1,92 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
require_once __DIR__.'/../inc/global.inc.php'; |
||||||
|
require_once api_get_path(SYS_CODE_PATH).'common_cartridge/export/src/lib/ccdependencyparser.php'; |
||||||
|
use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver; |
||||||
|
use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder; |
||||||
|
use Chamilo\CourseBundle\Component\CourseCopy\CourseSelectForm; |
||||||
|
|
||||||
|
$current_course_tool = TOOL_COURSE_MAINTENANCE; |
||||||
|
|
||||||
|
api_protect_course_script(true); |
||||||
|
|
||||||
|
// Check access rights (only teachers are allowed here) |
||||||
|
if (!api_is_allowed_to_edit()) { |
||||||
|
api_not_allowed(true); |
||||||
|
} |
||||||
|
|
||||||
|
api_check_archive_dir(); |
||||||
|
api_set_more_memory_and_time_limits(); |
||||||
|
|
||||||
|
// Section for the tabs |
||||||
|
$this_section = SECTION_COURSES; |
||||||
|
|
||||||
|
// Breadcrumbs |
||||||
|
$interbreadcrumb[] = [ |
||||||
|
'url' => api_get_path(WEB_CODE_PATH).'course_info/maintenance.php', |
||||||
|
'name' => get_lang('Maintenance'), |
||||||
|
]; |
||||||
|
|
||||||
|
// Displaying the header |
||||||
|
$nameTools = get_lang('ExportCcVersion13'); |
||||||
|
Display::display_header($nameTools); |
||||||
|
|
||||||
|
// Display the tool title |
||||||
|
echo Display::page_header($nameTools); |
||||||
|
|
||||||
|
$action = isset($_POST['action']) ? $_POST['action'] : ''; |
||||||
|
$backupOption = 'select_items'; |
||||||
|
|
||||||
|
if (Security::check_token('post') && ($action === 'course_select_form')) { |
||||||
|
// Clear token |
||||||
|
Security::clear_token(); |
||||||
|
$resources = Security::remove_XSS($_POST['resource']); |
||||||
|
if (!empty($resources)) { |
||||||
|
$cb = new CourseBuilder('partial'); |
||||||
|
$course = $cb->build(0, null, false, array_keys($resources), $resources); |
||||||
|
$course = CourseSelectForm::get_posted_course(null, 0, '', $course); |
||||||
|
$imsccFile = Cc13ExportConvert::export($course); |
||||||
|
if ($imsccFile !== false) { |
||||||
|
echo Display::return_message(get_lang('ImsccCreated'), 'confirm'); |
||||||
|
echo '<br />'; |
||||||
|
echo Display::toolbarButton( |
||||||
|
get_lang('Download'), |
||||||
|
api_get_path(WEB_CODE_PATH).'course_info/download.php?archive='.$imsccFile.'&'.api_get_cidreq(), |
||||||
|
'file-zip-o', |
||||||
|
'primary' |
||||||
|
); |
||||||
|
/*echo Display::url( |
||||||
|
get_lang('Download'), |
||||||
|
api_get_path(WEB_CODE_PATH).'course_info/download.php?archive='.$imsccFile.'&'.api_get_cidreq(), |
||||||
|
['class' => 'btn btn-primary btn-large'] |
||||||
|
);*/ |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
// Clear token |
||||||
|
Security::clear_token(); |
||||||
|
$cb = new CourseBuilder('partial'); |
||||||
|
$toolsToBuild = [ |
||||||
|
RESOURCE_DOCUMENT, |
||||||
|
RESOURCE_FORUMCATEGORY, |
||||||
|
RESOURCE_FORUM, |
||||||
|
RESOURCE_FORUMTOPIC, |
||||||
|
RESOURCE_QUIZ, |
||||||
|
RESOURCE_TEST_CATEGORY, |
||||||
|
RESOURCE_LINK, |
||||||
|
RESOURCE_WIKI, |
||||||
|
]; |
||||||
|
$course = $cb->build(0, null, false, $toolsToBuild); |
||||||
|
if ($course->has_resources()) { |
||||||
|
// Add token to Course select form |
||||||
|
$hiddenFields['sec_token'] = Security::get_token(); |
||||||
|
CourseSelectForm::display_form($course, $hiddenFields, false, true, true); |
||||||
|
} else { |
||||||
|
echo Display::return_message(get_lang('NoResourcesToBackup'), 'warning'); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
Display::display_footer(); |
||||||
@ -0,0 +1,75 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
require_once __DIR__.'/../inc/global.inc.php'; |
||||||
|
require_once api_get_path(SYS_CODE_PATH).'common_cartridge/import/src/lib/validateurlsyntax.php'; |
||||||
|
require_once api_get_path(SYS_CODE_PATH).'common_cartridge/import/src/inc/constants.php'; |
||||||
|
|
||||||
|
$current_course_tool = TOOL_COURSE_MAINTENANCE; |
||||||
|
api_protect_course_script(true); |
||||||
|
|
||||||
|
// Check access rights (only teachers are allowed here) |
||||||
|
if (!api_is_allowed_to_edit()) { |
||||||
|
api_not_allowed(true); |
||||||
|
} |
||||||
|
|
||||||
|
api_set_more_memory_and_time_limits(); |
||||||
|
|
||||||
|
// Section for the tabs |
||||||
|
$this_section = SECTION_COURSES; |
||||||
|
|
||||||
|
// Breadcrumbs |
||||||
|
$interbreadcrumb[] = [ |
||||||
|
'url' => api_get_path(WEB_CODE_PATH).'course_info/maintenance.php?'.api_get_cidreq(), |
||||||
|
'name' => get_lang('Maintenance'), |
||||||
|
]; |
||||||
|
|
||||||
|
$form = new FormValidator('cc_import', 'post', api_get_self().'?'.api_get_cidreq()); |
||||||
|
$form->addFile('cc_file', get_lang('ImsccFile')); |
||||||
|
$form->addButtonImport(get_lang('Import')); |
||||||
|
|
||||||
|
if ($form->validate()) { |
||||||
|
$file = $_FILES['cc_file']; |
||||||
|
|
||||||
|
if (empty($file['tmp_name'])) { |
||||||
|
$errorMessage = get_lang('UplUploadFailed'); |
||||||
|
echo Display::return_message($errorMessage, 'error', false); |
||||||
|
} else { |
||||||
|
$allowedFileMimetype = ['imscc']; |
||||||
|
|
||||||
|
$extImportFile = substr($file['name'], (strrpos($file['name'], '.') + 1)); |
||||||
|
|
||||||
|
if (!in_array($extImportFile, $allowedFileMimetype)) { |
||||||
|
echo Display::return_message(get_lang('YouMustImportAFileAccordingToSelectedOption'), 'error'); |
||||||
|
} else { |
||||||
|
$baseDir = api_get_path(SYS_ARCHIVE_PATH); |
||||||
|
$uploadPath = 'imsccImport/'; |
||||||
|
$errors = []; |
||||||
|
if (!is_dir($baseDir.$uploadPath)) { |
||||||
|
@mkdir($baseDir.$uploadPath); |
||||||
|
} |
||||||
|
|
||||||
|
$filepath = $baseDir.$uploadPath; |
||||||
|
|
||||||
|
if (!Imscc13Import::unzip($file['tmp_name'], $filepath)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// We detect if it is cc v1.3 |
||||||
|
$detected = Imscc13Import::detectFormat($filepath); |
||||||
|
if ($detected) { |
||||||
|
Imscc13Import::execute($filepath); |
||||||
|
Display::addFlash(Display::return_message(get_lang('CcFileImported'), 'normal', false)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$template = new Template(get_lang('ImportCcVersion13')); |
||||||
|
Display::addFlash(Display::return_message(get_lang('ImportCcInstructions'), 'normal', false)); |
||||||
|
$template->assign('form', $form->returnForm()); |
||||||
|
$templateName = $template->get_template('common_cartridge/import_cc.tpl'); |
||||||
|
$content = $template->fetch($templateName); |
||||||
|
$template->assign('header', get_lang('ImportCcVersion13')); |
||||||
|
$template->assign('content', $content); |
||||||
|
$template->display_one_col_template(); |
||||||
@ -0,0 +1,291 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
class Cc13Convert |
||||||
|
{ |
||||||
|
public static function convert($packagedir, $outdir, $objCourse) |
||||||
|
{ |
||||||
|
$dir = realpath($packagedir); |
||||||
|
if (empty($dir)) { |
||||||
|
throw new InvalidArgumentException('Directory does not exist!'); |
||||||
|
} |
||||||
|
$odir = realpath($outdir); |
||||||
|
if (empty($odir)) { |
||||||
|
throw new InvalidArgumentException('Directory does not exist!'); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($objCourse)) { |
||||||
|
//Initialize the manifest metadata class |
||||||
|
$meta = new CcMetadataManifest(); |
||||||
|
|
||||||
|
//Package metadata |
||||||
|
$metageneral = new CcMetadataGeneral(); |
||||||
|
$metageneral->setLanguage($objCourse->info['language']); |
||||||
|
$metageneral->setTitle($objCourse->info['title'], $objCourse->info['language']); |
||||||
|
$metageneral->setDescription('', $objCourse->info['language']); |
||||||
|
$metageneral->setCatalog('category'); |
||||||
|
$metageneral->setEntry($objCourse->info['categoryName']); |
||||||
|
$meta->addMetadataGeneral($metageneral); |
||||||
|
|
||||||
|
// Create the manifest |
||||||
|
$manifest = new CcManifest(); |
||||||
|
|
||||||
|
$manifest->addMetadataManifest($meta); |
||||||
|
|
||||||
|
$organization = null; |
||||||
|
|
||||||
|
//Get the course structure - this will be transformed into organization |
||||||
|
//Step 1 - Get the list and order of sections/topics |
||||||
|
|
||||||
|
$count = 1; |
||||||
|
$sections = []; |
||||||
|
$resources = $objCourse->resources; |
||||||
|
|
||||||
|
// We check the quiz sections |
||||||
|
if (isset($resources['quiz'])) { |
||||||
|
$quizSections = self::getItemSections($resources['quiz'], 'quiz', $count, $objCourse->info['code'], $resources['Exercise_Question']); |
||||||
|
$sections = array_merge($sections, $quizSections); |
||||||
|
} |
||||||
|
|
||||||
|
// We check the document sections |
||||||
|
if (isset($resources['document'])) { |
||||||
|
$documentSections = self::getItemSections($resources['document'], 'document', $count, $objCourse->info['code']); |
||||||
|
$sections = array_merge($sections, $documentSections); |
||||||
|
} |
||||||
|
|
||||||
|
// We check the wiki sections |
||||||
|
if (isset($resources['wiki'])) { |
||||||
|
$wikiSections = self::getItemSections($resources['wiki'], 'wiki', $count, $objCourse->info['code']); |
||||||
|
$sections = array_merge($sections, $wikiSections); |
||||||
|
} |
||||||
|
|
||||||
|
// We check the forum sections |
||||||
|
if (isset($resources['forum'])) { |
||||||
|
$forumSections = self::getItemSections($resources['forum'], 'forum', $count, $objCourse->info['code'], $resources['Forum_Category']); |
||||||
|
$sections = array_merge($sections, $forumSections); |
||||||
|
} |
||||||
|
|
||||||
|
// We check the link sections |
||||||
|
if (isset($resources['link'])) { |
||||||
|
$linkSections = self::getItemSections($resources['link'], 'link', $count, $objCourse->info['code'], $resources['Link_Category']); |
||||||
|
$sections = array_merge($sections, $linkSections); |
||||||
|
} |
||||||
|
|
||||||
|
//organization title |
||||||
|
$organization = new CcOrganization(); |
||||||
|
foreach ($sections as $sectionid => $values) { |
||||||
|
$item = new CcItem(); |
||||||
|
$item->title = $values[0]; |
||||||
|
self::processSequence($item, $manifest, $values[1], $dir, $odir); |
||||||
|
$organization->addItem($item); |
||||||
|
} |
||||||
|
$manifest->putNodes(); |
||||||
|
|
||||||
|
if (!empty($organization)) { |
||||||
|
$manifest->addNewOrganization($organization); |
||||||
|
} |
||||||
|
|
||||||
|
$manifestpath = $outdir.DIRECTORY_SEPARATOR.'imsmanifest.xml'; |
||||||
|
$saved = $manifest->saveTo($manifestpath); |
||||||
|
|
||||||
|
return $saved; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function getItemSections($itemData, $itemType, &$count, $courseCode, $itmesExtraData = null) |
||||||
|
{ |
||||||
|
$sections = []; |
||||||
|
switch ($itemType) { |
||||||
|
case 'quiz': |
||||||
|
case 'document': |
||||||
|
case 'wiki': |
||||||
|
$convertType = $itemType; |
||||||
|
if ($itemType == 'wiki') { |
||||||
|
$convertType = 'Page'; |
||||||
|
} |
||||||
|
$sectionid = $count; |
||||||
|
$sectiontitle = ucfirst($itemType); |
||||||
|
$sequence = self::getSequence($itemData, 0, $convertType, $courseCode, $itmesExtraData); |
||||||
|
$sections[$sectionid] = [$sectiontitle, $sequence]; |
||||||
|
$count++; |
||||||
|
break; |
||||||
|
case 'link': |
||||||
|
$links = self::getSequence($itemData, null, $itemType); |
||||||
|
foreach ($links as $categoryId => $sequence) { |
||||||
|
$sectionid = $count; |
||||||
|
if (isset($itmesExtraData[$categoryId])) { |
||||||
|
$sectiontitle = $itmesExtraData[$categoryId]->title; |
||||||
|
} else { |
||||||
|
$sectiontitle = 'General'; |
||||||
|
} |
||||||
|
$sections[$sectionid] = [$sectiontitle, $sequence]; |
||||||
|
$count++; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 'forum': |
||||||
|
if (isset($itmesExtraData)) { |
||||||
|
foreach ($itmesExtraData as $fcategory) { |
||||||
|
if (isset($fcategory->obj)) { |
||||||
|
$objCategory = $fcategory->obj; |
||||||
|
$sectionid = $count; |
||||||
|
$sectiontitle = $objCategory->cat_title; |
||||||
|
$sequence = self::getSequence($itemData, $objCategory->iid, $itemType); |
||||||
|
$sections[$sectionid] = [$sectiontitle, $sequence]; |
||||||
|
$count++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
return $sections; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function getSequence($objItems, $categoryId = null, $itemType = null, $coursecode = null, $itemQuestions = null) |
||||||
|
{ |
||||||
|
$sequences = []; |
||||||
|
switch ($itemType) { |
||||||
|
case 'quiz': |
||||||
|
$sequence = []; |
||||||
|
foreach ($objItems as $objItem) { |
||||||
|
if ($categoryId === 0) { |
||||||
|
$questions = []; |
||||||
|
foreach ($objItem->obj->question_ids as $questionId) { |
||||||
|
if (isset($itemQuestions[$questionId])) { |
||||||
|
$questions[$questionId] = $itemQuestions[$questionId]; |
||||||
|
} |
||||||
|
} |
||||||
|
$sequence[$categoryId][$objItem->obj->iid] = [ |
||||||
|
'title' => $objItem->obj->title, |
||||||
|
'comment' => $objItem->obj->description, |
||||||
|
'cc_type' => 'quiz', |
||||||
|
'source_id' => $objItem->obj->iid, |
||||||
|
'questions' => $questions, |
||||||
|
'max_attempt' => $objItem->obj->max_attempt, |
||||||
|
'expired_time' => $objItem->obj->expired_time, |
||||||
|
'pass_percentage' => $objItem->obj->pass_percentage, |
||||||
|
'random_answers' => $objItem->obj->random_answers, |
||||||
|
'course_code' => $coursecode, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
$sequences = $sequence[$categoryId]; |
||||||
|
break; |
||||||
|
case 'document': |
||||||
|
$sequence = []; |
||||||
|
foreach ($objItems as $objItem) { |
||||||
|
if ($categoryId === 0) { |
||||||
|
$sequence[$categoryId][$objItem->source_id] = [ |
||||||
|
'title' => $objItem->title, |
||||||
|
'comment' => $objItem->comment, |
||||||
|
'cc_type' => ($objItem->file_type == 'folder' ? 'folder' : 'resource'), |
||||||
|
'source_id' => $objItem->source_id, |
||||||
|
'path' => $objItem->path, |
||||||
|
'file_type' => $objItem->file_type, |
||||||
|
'course_code' => $coursecode, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
$sequences = $sequence[$categoryId]; |
||||||
|
break; |
||||||
|
case 'forum': |
||||||
|
foreach ($objItems as $objItem) { |
||||||
|
if ($categoryId == $objItem->obj->forum_category) { |
||||||
|
$sequence[$categoryId][$objItem->obj->forum_id] = [ |
||||||
|
'title' => $objItem->obj->forum_title, |
||||||
|
'comment' => $objItem->obj->forum_comment, |
||||||
|
'cc_type' => 'forum', |
||||||
|
'source_id' => $objItem->obj->iid, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
$sequences = $sequence[$categoryId]; |
||||||
|
break; |
||||||
|
case 'page': |
||||||
|
foreach ($objItems as $objItem) { |
||||||
|
if ($categoryId === 0) { |
||||||
|
$sequence[$categoryId][$objItem->page_id] = [ |
||||||
|
'title' => $objItem->title, |
||||||
|
'comment' => $objItem->content, |
||||||
|
'cc_type' => 'page', |
||||||
|
'source_id' => $objItem->page_id, |
||||||
|
'reflink' => $objItem->reflink, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
$sequences = $sequence[$categoryId]; |
||||||
|
break; |
||||||
|
case 'link': |
||||||
|
if (!isset($categoryId)) { |
||||||
|
$categories = []; |
||||||
|
foreach ($objItems as $objItem) { |
||||||
|
$categories[$objItem->category_id] = self::getSequence($objItems, $objItem->category_id, $itemType); |
||||||
|
} |
||||||
|
$sequences = $categories; |
||||||
|
} else { |
||||||
|
foreach ($objItems as $objItem) { |
||||||
|
if ($categoryId == $objItem->category_id) { |
||||||
|
$sequence[$categoryId][$objItem->source_id] = [ |
||||||
|
'title' => $objItem->title, |
||||||
|
'comment' => $objItem->description, |
||||||
|
'cc_type' => 'url', |
||||||
|
'source_id' => $objItem->source_id, |
||||||
|
'url' => $objItem->url, |
||||||
|
'target' => $objItem->target, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
$sequences = $sequence[$categoryId]; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
return $sequences; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function processSequence(CcIItem &$item, CcIManifest &$manifest, array $sequence, $packageroot, $outdir) |
||||||
|
{ |
||||||
|
if (!empty($sequence)) { |
||||||
|
foreach ($sequence as $seq) { |
||||||
|
$activity_type = ucfirst($seq['cc_type']); |
||||||
|
$activity_indentation = 0; |
||||||
|
$aitem = self::itemIndenter($item, $activity_indentation); |
||||||
|
$caller = "CcConverter{$activity_type}"; |
||||||
|
if (class_exists($caller)) { |
||||||
|
$obj = new $caller($aitem, $manifest, $packageroot, $path); |
||||||
|
if (!$obj->convert($outdir, $seq)) { |
||||||
|
throw new RuntimeException("failed to convert {$activity_type}"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static function itemIndenter(CcIItem &$item, $level = 0) |
||||||
|
{ |
||||||
|
$indent = (int) $level; |
||||||
|
$indent = ($indent) <= 0 ? 0 : $indent; |
||||||
|
$nprev = null; |
||||||
|
$nfirst = null; |
||||||
|
for ($pos = 0, $size = $indent; $pos < $size; $pos++) { |
||||||
|
$nitem = new CcItem(); |
||||||
|
$nitem->title = ''; |
||||||
|
if (empty($nfirst)) { |
||||||
|
$nfirst = $nitem; |
||||||
|
} |
||||||
|
if (!empty($nprev)) { |
||||||
|
$nprev->addChildItem($nitem); |
||||||
|
} |
||||||
|
$nprev = $nitem; |
||||||
|
} |
||||||
|
$result = $item; |
||||||
|
if (!empty($nfirst)) { |
||||||
|
$item->addChildItem($nfirst); |
||||||
|
$result = $nprev; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver; |
||||||
|
|
||||||
|
class Cc13ExportConvert |
||||||
|
{ |
||||||
|
public static function export($objCourse) |
||||||
|
{ |
||||||
|
$permDirs = api_get_permissions_for_new_directories(); |
||||||
|
$backupDirectory = CourseArchiver::getBackupDir(); |
||||||
|
|
||||||
|
// Create a temp directory |
||||||
|
$backupDir = $backupDirectory.'CourseCC13Archiver_'.api_get_unique_id(); |
||||||
|
|
||||||
|
if (mkdir($backupDir, $permDirs, true)) { |
||||||
|
$converted = Cc13Convert::convert($backupDirectory, $backupDir, $objCourse); |
||||||
|
if ($converted) { |
||||||
|
$imsccFileName = self::createImscc($backupDir, $objCourse); |
||||||
|
|
||||||
|
return $imsccFileName; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public static function createImscc($backupDir, $objCourse) |
||||||
|
{ |
||||||
|
$backupDirectory = CourseArchiver::getBackupDir(); |
||||||
|
|
||||||
|
$date = new \DateTime(api_get_local_time()); |
||||||
|
|
||||||
|
$imsccFileName = $objCourse->info['code'].'_'.$date->format('Ymd-His').'.imscc'; |
||||||
|
$imsccFilePath = $backupDirectory.$imsccFileName; |
||||||
|
|
||||||
|
// Zip the course-contents |
||||||
|
$zip = new \PclZip($imsccFilePath); |
||||||
|
$zip->create($backupDir, PCLZIP_OPT_REMOVE_PATH, $backupDir); |
||||||
|
|
||||||
|
// Remove the temp-dir. |
||||||
|
rmdirr($backupDir); |
||||||
|
|
||||||
|
return $imsccFileName; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,49 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_forum.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcForum extends CcGeneralFile |
||||||
|
{ |
||||||
|
const DEAFULTNAME = 'discussion.xml'; |
||||||
|
protected $rootns = 'dt'; |
||||||
|
protected $rootname = 'topic'; |
||||||
|
protected $ccnamespaces = ['dt' => 'http://www.imsglobal.org/xsd/imsccv1p3/imsdt_v1p3', |
||||||
|
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', ]; |
||||||
|
protected $ccnsnames = ['dt' => 'http://www.imsglobal.org/profile/cc/ccv1p3/ccv1p3_imsdt_v1p3.xsd']; |
||||||
|
protected $title = null; |
||||||
|
protected $textType = 'text/plain'; |
||||||
|
protected $text = null; |
||||||
|
protected $attachments = []; |
||||||
|
|
||||||
|
public function setTitle($title) |
||||||
|
{ |
||||||
|
$this->title = self::safexml($title); |
||||||
|
} |
||||||
|
|
||||||
|
public function setText($text, $type = 'text/plain') |
||||||
|
{ |
||||||
|
$this->text = self::safexml($text); |
||||||
|
$this->textType = $type; |
||||||
|
} |
||||||
|
|
||||||
|
public function setAttachments(array $attachments) |
||||||
|
{ |
||||||
|
$this->attachments = $attachments; |
||||||
|
} |
||||||
|
|
||||||
|
protected function onSave() |
||||||
|
{ |
||||||
|
$rns = $this->ccnamespaces[$this->rootns]; |
||||||
|
$this->appendNewElementNs($this->root, $rns, 'title', $this->title); |
||||||
|
$text = $this->appendNewElementNs($this->root, $rns, 'text', $this->text); |
||||||
|
$this->appendNewAttributeNs($text, $rns, 'texttype', $this->textType); |
||||||
|
if (!empty($this->attachments)) { |
||||||
|
$attachments = $this->appendNewElementNs($this->root, $rns, 'attachments'); |
||||||
|
foreach ($this->attachments as $value) { |
||||||
|
$att = $this->appendNewElementNs($attachments, $rns, 'attachment'); |
||||||
|
$this->appendNewAttributeNs($att, $rns, 'href', $value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,151 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Item Class. |
||||||
|
*/ |
||||||
|
class CcItem implements CcIItem |
||||||
|
{ |
||||||
|
public $identifier = null; |
||||||
|
public $identifierref = null; |
||||||
|
public $isvisible = null; |
||||||
|
public $title = null; |
||||||
|
public $parameters = null; |
||||||
|
public $childitems = null; |
||||||
|
private $parentItem = null; |
||||||
|
private $isempty = true; |
||||||
|
|
||||||
|
public function __construct($node = null, $doc = null) |
||||||
|
{ |
||||||
|
if (is_object($node)) { |
||||||
|
$clname = get_class($node); |
||||||
|
if ($clname == 'CcResource') { |
||||||
|
$this->initNewItem(); |
||||||
|
$this->identifierref = $node->identifier; |
||||||
|
$this->title = is_string($doc) && (!empty($doc)) ? $doc : 'item'; |
||||||
|
} elseif ($clname == 'CcManifest') { |
||||||
|
$this->initNewItem(); |
||||||
|
$this->identifierref = $node->manifestID(); |
||||||
|
$this->title = is_string($doc) && (!empty($doc)) ? $doc : 'item'; |
||||||
|
} elseif (is_object($doc)) { |
||||||
|
$this->processItem($node, $doc); |
||||||
|
} else { |
||||||
|
$this->initNewItem(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
$this->initNewItem(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function attrValue(&$nod, $name, $ns = null) |
||||||
|
{ |
||||||
|
return is_null($ns) ? |
||||||
|
($nod->hasAttribute($name) ? $nod->getAttribute($name) : null) : |
||||||
|
($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null); |
||||||
|
} |
||||||
|
|
||||||
|
public function processItem(&$node, &$doc) |
||||||
|
{ |
||||||
|
$this->identifier = $this->attrValue($node, "identifier"); |
||||||
|
$this->structure = $this->attrValue($node, "structure"); |
||||||
|
$this->identifierref = $this->attrValue($node, "identifierref"); |
||||||
|
$atr = $this->attrValue($node, "isvisible"); |
||||||
|
$this->isvisible = is_null($atr) ? true : $atr; |
||||||
|
$nlist = $node->getElementsByTagName('title'); |
||||||
|
if (is_object($nlist) && ($nlist->length > 0)) { |
||||||
|
$this->title = $nlist->item(0)->nodeValue; |
||||||
|
} |
||||||
|
$nlist = $doc->nodeList("//imscc:item[@identifier='".$this->identifier."']/imscc:item"); |
||||||
|
if ($nlist->length > 0) { |
||||||
|
$this->childitems = []; |
||||||
|
foreach ($nlist as $item) { |
||||||
|
$key = $this->attrValue($item, "identifier"); |
||||||
|
$this->childitems[$key] = new CcItem($item, $doc); |
||||||
|
} |
||||||
|
} |
||||||
|
$this->isempty = false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add one Child Item. |
||||||
|
*/ |
||||||
|
public function addChildItem(CcIItem &$item) |
||||||
|
{ |
||||||
|
if (is_null($this->childitems)) { |
||||||
|
$this->childitems = []; |
||||||
|
} |
||||||
|
$this->childitems[$item->identifier] = $item; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add new child Item. |
||||||
|
* |
||||||
|
* @param string $title |
||||||
|
* |
||||||
|
* @return CcIItem |
||||||
|
*/ |
||||||
|
public function add_new_child_item($title = '') |
||||||
|
{ |
||||||
|
$sc = new CcItem(); |
||||||
|
$sc->title = $title; |
||||||
|
$this->addChildItem($sc); |
||||||
|
|
||||||
|
return $sc; |
||||||
|
} |
||||||
|
|
||||||
|
public function attachResource($resource) |
||||||
|
{ |
||||||
|
if ($this->hasChildItems()) { |
||||||
|
throw new Exception("Can not attach resource to item that contains other items!"); |
||||||
|
} |
||||||
|
$resident = null; |
||||||
|
if (is_string($resource)) { |
||||||
|
$resident = $resource; |
||||||
|
} elseif (is_object($resource)) { |
||||||
|
$clname = get_class($resource); |
||||||
|
if ($clname == 'CcResource') { |
||||||
|
$resident = $resource->identifier; |
||||||
|
} elseif ($clname == 'CcManifest') { |
||||||
|
$resident = $resource->manifestID(); |
||||||
|
} else { |
||||||
|
throw new Exception("Unable to attach resource. Invalid object."); |
||||||
|
} |
||||||
|
} |
||||||
|
if (is_null($resident) || (empty($resident))) { |
||||||
|
throw new Exception("Resource must have valid identifier!"); |
||||||
|
} |
||||||
|
$this->identifierref = $resident; |
||||||
|
} |
||||||
|
|
||||||
|
public function hasChildItems() |
||||||
|
{ |
||||||
|
return is_array($this->childitems) && (count($this->childitems) > 0); |
||||||
|
} |
||||||
|
|
||||||
|
public function child_item($identifier) |
||||||
|
{ |
||||||
|
return $this->hasChildItems() ? $this->childitems[$identifier] : null; |
||||||
|
} |
||||||
|
|
||||||
|
public function initClean() |
||||||
|
{ |
||||||
|
$this->identifier = null; |
||||||
|
$this->isvisible = null; |
||||||
|
$this->title = null; |
||||||
|
$this->parameters = null; |
||||||
|
$this->childitems = null; |
||||||
|
$this->parentItem = null; |
||||||
|
$this->isempty = true; |
||||||
|
} |
||||||
|
|
||||||
|
public function initNewItem() |
||||||
|
{ |
||||||
|
$this->identifier = CcHelpers::uuidgen('I_'); |
||||||
|
$this->isvisible = true; //default is true |
||||||
|
$this->title = null; |
||||||
|
$this->parameters = null; |
||||||
|
$this->childitems = null; |
||||||
|
$this->parentItem = null; |
||||||
|
$this->isempty = false; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,329 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_manifest.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcManifest extends XMLGenericDocument implements CcIManifest |
||||||
|
{ |
||||||
|
private $ccversion = null; |
||||||
|
private $ccobj = null; |
||||||
|
private $rootmanifest = null; |
||||||
|
private $activemanifest = null; |
||||||
|
private $parentmanifest = null; |
||||||
|
private $parentparentmanifest = null; |
||||||
|
private $ares = []; |
||||||
|
private $mainidentifier = null; |
||||||
|
|
||||||
|
public function __construct($ccver = 13, $activemanifest = null, |
||||||
|
$parentmanifest = null, $parentparentmanifest = null) |
||||||
|
{ |
||||||
|
$this->ccversion = $ccver; |
||||||
|
$this->ccobj = new CcVersion13(); |
||||||
|
parent::__construct('UTF-8', true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Register Namespace for use XPATH. |
||||||
|
*/ |
||||||
|
public function registerNamespacesForXpath() |
||||||
|
{ |
||||||
|
$scnam = $this->activemanifest->getCcNamespaces(); |
||||||
|
foreach ($scnam as $key => $value) { |
||||||
|
$this->registerNS($key, $value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add Metadata For Manifest. |
||||||
|
*/ |
||||||
|
public function addMetadataManifest(CcIMetadataManifest $met) |
||||||
|
{ |
||||||
|
$metanode = $this->node("//imscc:manifest[@identifier='". |
||||||
|
$this->activemanifest->manifestID(). |
||||||
|
"']/imscc:metadata"); |
||||||
|
$nmeta = $this->activemanifest->createMetadataNode($met, $this->doc, $metanode); |
||||||
|
$metanode->appendChild($nmeta); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add Metadata For Resource. |
||||||
|
* |
||||||
|
* @param string $identifier |
||||||
|
*/ |
||||||
|
public function addMetadataResource(CcIMetadataResource $met, $identifier) |
||||||
|
{ |
||||||
|
$metanode = $this->node("//imscc:resource". |
||||||
|
"[@identifier='". |
||||||
|
$identifier. |
||||||
|
"']"); |
||||||
|
$metanode2 = $this->node("//imscc:resource". |
||||||
|
"[@identifier='". |
||||||
|
$identifier. |
||||||
|
"']/imscc:file"); |
||||||
|
$nspaces = $this->activemanifest->getCcNamespaces(); |
||||||
|
$dnode = $this->appendNewElementNs($metanode2, $nspaces['imscc'], 'metadata'); |
||||||
|
$this->activemanifest->createMetadataResourceNode($met, $this->doc, $dnode); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add Metadata For File. |
||||||
|
* |
||||||
|
* @param string $identifier |
||||||
|
* @param string $filename |
||||||
|
*/ |
||||||
|
public function addMetadataFile(CcIMetadataFile $met, $identifier, $filename) |
||||||
|
{ |
||||||
|
if (empty($met) || empty($identifier) || empty($filename)) { |
||||||
|
throw new Exception('Try to add a metadata file with nulls values given!'); |
||||||
|
} |
||||||
|
|
||||||
|
$metanode = $this->node("//imscc:resource". |
||||||
|
"[@identifier='". |
||||||
|
$identifier. |
||||||
|
"']/imscc:file". |
||||||
|
"[@href='". |
||||||
|
$filename. |
||||||
|
"']"); |
||||||
|
|
||||||
|
$nspaces = $this->activemanifest->getCcNamespaces(); |
||||||
|
$dnode = $this->doc->createElementNS($nspaces['imscc'], "metadata"); |
||||||
|
|
||||||
|
$metanode->appendChild($dnode); |
||||||
|
|
||||||
|
$this->activemanifest->createMetadataFileNode($met, $this->doc, $dnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function onCreate() |
||||||
|
{ |
||||||
|
$this->activemanifest = new CcVersion13(); |
||||||
|
$this->rootmanifest = $this->activemanifest; |
||||||
|
$result = $this->activemanifest->createManifest($this->doc); |
||||||
|
$this->registerNamespacesForXpath(); |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function getRelativeBasePath() |
||||||
|
{ |
||||||
|
return $this->activemanifest->base(); |
||||||
|
} |
||||||
|
|
||||||
|
public function parentManifest() |
||||||
|
{ |
||||||
|
return new CcManifest($this, $this->parentmanifest, $this->parentparentmanifest); |
||||||
|
} |
||||||
|
|
||||||
|
public function rootManifest() |
||||||
|
{ |
||||||
|
return new CcManifest($this, $this->rootmanifest); |
||||||
|
} |
||||||
|
|
||||||
|
public function manifestID() |
||||||
|
{ |
||||||
|
return $this->activemanifest->manifestID(); |
||||||
|
} |
||||||
|
|
||||||
|
public function getManifestNamespaces() |
||||||
|
{ |
||||||
|
return $this->rootmanifest->getCcNamespaces(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a new organization. |
||||||
|
*/ |
||||||
|
public function addNewOrganization(CcIOrganization &$org) |
||||||
|
{ |
||||||
|
$norg = $this->activemanifest->createOrganizationNode($org, $this->doc); |
||||||
|
$orgnode = $this->node("//imscc:manifest[@identifier='". |
||||||
|
$this->activemanifest->manifestID(). |
||||||
|
"']/imscc:organizations"); |
||||||
|
$orgnode->appendChild($norg); |
||||||
|
} |
||||||
|
|
||||||
|
public function getResources($searchspecific = '') |
||||||
|
{ |
||||||
|
$reslist = $this->getResourceList($searchspecific); |
||||||
|
$resourcelist = []; |
||||||
|
foreach ($reslist as $resourceitem) { |
||||||
|
$resourcelist[] = new CcResources($this, $resourceitem); |
||||||
|
} |
||||||
|
|
||||||
|
return $resourcelist; |
||||||
|
} |
||||||
|
|
||||||
|
public function getCcNamespacePath($nsname) |
||||||
|
{ |
||||||
|
if (is_string($nsname) && (!empty($nsname))) { |
||||||
|
$scnam = $this->activemanifest->getCcNamespaces(); |
||||||
|
|
||||||
|
return $scnam[$nsname]; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public function getResourceList($searchspecific = '') |
||||||
|
{ |
||||||
|
return $this->nodeList("//imscc:manifest[@identifier='". |
||||||
|
$this->activemanifest->manifestID(). |
||||||
|
"']/imscc:resources/imscc:resource".$searchspecific); |
||||||
|
} |
||||||
|
|
||||||
|
public function onLoad() |
||||||
|
{ |
||||||
|
$this->registerNamespacesForXpath(); |
||||||
|
$this->fillManifest(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public function onSave() |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a resource to the manifest. |
||||||
|
* |
||||||
|
* @param string $identifier |
||||||
|
* @param string $type |
||||||
|
* |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function addResource(CcIResource $res, $identifier = null, $type = 'webcontent') |
||||||
|
{ |
||||||
|
if (!$this->ccobj->valid($type)) { |
||||||
|
throw new Exception("Type invalid..."); |
||||||
|
} |
||||||
|
|
||||||
|
if ($res == null) { |
||||||
|
throw new Exception('Invalid Resource or dont give it'); |
||||||
|
} |
||||||
|
$rst = $res; |
||||||
|
|
||||||
|
// TODO: This has to be reviewed since it does not handle multiple files properly. |
||||||
|
// Dependencies. |
||||||
|
if (is_object($identifier)) { |
||||||
|
$this->activemanifest->createResourceNode($rst, $this->doc, $identifier); |
||||||
|
} else { |
||||||
|
$nresnode = null; |
||||||
|
|
||||||
|
$rst->type = $type; |
||||||
|
if (!CcHelpers::isHtml($rst->filename)) { |
||||||
|
$rst->href = null; |
||||||
|
} |
||||||
|
|
||||||
|
$this->activemanifest->createResourceNode($rst, $this->doc, $nresnode); |
||||||
|
foreach ($rst->files as $file) { |
||||||
|
$ident = $this->getIdentifierByFilename($file); |
||||||
|
if ($ident == null) { |
||||||
|
$newres = new CcResources($rst->manifestroot, $file); |
||||||
|
if (!CcHelpers::isHtml($file)) { |
||||||
|
$newres->href = null; |
||||||
|
} |
||||||
|
$newres->type = 'webcontent'; |
||||||
|
$this->activemanifest->createResourceNode($newres, $this->doc, $nresnode); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$tmparray = [$rst->identifier, $rst->files[0]]; |
||||||
|
|
||||||
|
return $tmparray; |
||||||
|
} |
||||||
|
|
||||||
|
public function updateInstructoronly($identifier, $value = false) |
||||||
|
{ |
||||||
|
if (isset($this->activemanifest->resources[$identifier])) { |
||||||
|
$resource = $this->activemanifest->resources[$identifier]; |
||||||
|
$resource->instructoronly = $value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Append the resources nodes in the Manifest. |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function putNodes() |
||||||
|
{ |
||||||
|
$resnodestr = "//imscc:manifest[@identifier='".$this->activemanifest->manifestID(). |
||||||
|
"']/imscc:resources"; |
||||||
|
$resnode = $this->node($resnodestr); |
||||||
|
|
||||||
|
foreach ($this->activemanifest->resources as $k => $v) { |
||||||
|
($k); |
||||||
|
$depen = $this->checkIfExistInOther($v->files[0], $v->identifier); |
||||||
|
if (!empty($depen)) { |
||||||
|
$this->replaceFileXDependency($depen, $v->files[0]); |
||||||
|
$v->type = 'webcontent'; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
foreach ($this->activemanifest->resources as $node) { |
||||||
|
$rnode = $this->activemanifest->createResourceNode($node, $this->doc, null); |
||||||
|
$resnode->appendChild($rnode); |
||||||
|
if ($node->instructoronly) { |
||||||
|
$metafileceduc = new CcMetadataResourceEducational(); |
||||||
|
$metafileceduc->setValue(intended_user_role::INSTRUCTOR); |
||||||
|
$metafile = new CcMetadataResource(); |
||||||
|
$metafile->addMetadataResourceEducational($metafileceduc); |
||||||
|
$this->activemanifest->createMetadataEducational($metafile, $this->doc, $rnode); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $resnode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO - implement this method - critical |
||||||
|
*/ |
||||||
|
private function fillManifest() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
private function checkIfExistInOther($name, $identifier) |
||||||
|
{ |
||||||
|
$status = []; |
||||||
|
foreach ($this->activemanifest->resources as $value) { |
||||||
|
if (($value->identifier != $identifier) && isset($value->files[$name])) { |
||||||
|
$status[] = $value->identifier; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $status; |
||||||
|
} |
||||||
|
|
||||||
|
private function replaceFileXDependency($depen, $name) |
||||||
|
{ |
||||||
|
foreach ($depen as $key => $value) { |
||||||
|
($key); |
||||||
|
$ident = $this->getIdentifierByFilename($name); |
||||||
|
$this->activemanifest->resources[$value]->files = |
||||||
|
$this->arrayRemoveByValue($this->activemanifest->resources[$value]->files, $name); |
||||||
|
if (!in_array($ident, $this->activemanifest->resources[$value]->dependency)) { |
||||||
|
array_push($this->activemanifest->resources[$value]->dependency, $ident); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private function getIdentifierByFilename($name) |
||||||
|
{ |
||||||
|
$result = null; |
||||||
|
if (isset($this->activemanifest->resourcesInd[$name])) { |
||||||
|
$result = $this->activemanifest->resourcesInd[$name]; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
private function arrayRemoveByValue($arr, $value) |
||||||
|
{ |
||||||
|
return array_values(array_diff($arr, [$value])); |
||||||
|
} |
||||||
|
|
||||||
|
private function arrayRemoveByKey($arr, $key) |
||||||
|
{ |
||||||
|
return array_values(array_diff_key($arr, [$key])); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_manifest.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Metadata General Type. |
||||||
|
*/ |
||||||
|
class CcMetadataGeneral |
||||||
|
{ |
||||||
|
public $title = []; |
||||||
|
public $language = []; |
||||||
|
public $description = []; |
||||||
|
public $keyword = []; |
||||||
|
public $coverage = []; |
||||||
|
public $catalog = []; |
||||||
|
public $entry = []; |
||||||
|
|
||||||
|
public function setCoverage($coverage, $language) |
||||||
|
{ |
||||||
|
$this->coverage[] = [$language, $coverage]; |
||||||
|
} |
||||||
|
|
||||||
|
public function setDescription($description, $language) |
||||||
|
{ |
||||||
|
$this->description[] = [$language, $description]; |
||||||
|
} |
||||||
|
|
||||||
|
public function setKeyword($keyword, $language) |
||||||
|
{ |
||||||
|
$this->keyword[] = [$language, $keyword]; |
||||||
|
} |
||||||
|
|
||||||
|
public function setLanguage($language) |
||||||
|
{ |
||||||
|
$this->language[] = [$language]; |
||||||
|
} |
||||||
|
|
||||||
|
public function setTitle($title, $language) |
||||||
|
{ |
||||||
|
$this->title[] = [$language, $title]; |
||||||
|
} |
||||||
|
|
||||||
|
public function setCatalog($cat) |
||||||
|
{ |
||||||
|
$this->catalog[] = [$cat]; |
||||||
|
} |
||||||
|
|
||||||
|
public function setEntry($entry) |
||||||
|
{ |
||||||
|
$this->entry[] = [$entry]; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,52 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_manifest.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcMetadataManifest implements CcIMetadataManifest |
||||||
|
{ |
||||||
|
public $arraygeneral = []; |
||||||
|
public $arraytech = []; |
||||||
|
public $arrayrights = []; |
||||||
|
public $arraylifecycle = []; |
||||||
|
|
||||||
|
public function addMetadataGeneral($obj) |
||||||
|
{ |
||||||
|
if (empty($obj)) { |
||||||
|
throw new Exception('Medatada Object given is invalid or null!'); |
||||||
|
} |
||||||
|
!is_null($obj->title) ? $this->arraygeneral['title'] = $obj->title : null; |
||||||
|
!is_null($obj->language) ? $this->arraygeneral['language'] = $obj->language : null; |
||||||
|
!is_null($obj->description) ? $this->arraygeneral['description'] = $obj->description : null; |
||||||
|
!is_null($obj->keyword) ? $this->arraygeneral['keyword'] = $obj->keyword : null; |
||||||
|
!is_null($obj->coverage) ? $this->arraygeneral['coverage'] = $obj->coverage : null; |
||||||
|
!is_null($obj->catalog) ? $this->arraygeneral['catalog'] = $obj->catalog : null; |
||||||
|
!is_null($obj->entry) ? $this->arraygeneral['entry'] = $obj->entry : null; |
||||||
|
} |
||||||
|
|
||||||
|
public function addMetadataTechnical($obj) |
||||||
|
{ |
||||||
|
if (empty($obj)) { |
||||||
|
throw new Exception('Medatada Object given is invalid or null!'); |
||||||
|
} |
||||||
|
!is_null($obj->format) ? $this->arraytech['format'] = $obj->format : null; |
||||||
|
} |
||||||
|
|
||||||
|
public function addMetadataRights($obj) |
||||||
|
{ |
||||||
|
if (empty($obj)) { |
||||||
|
throw new Exception('Medatada Object given is invalid or null!'); |
||||||
|
} |
||||||
|
!is_null($obj->copyright) ? $this->arrayrights['copyrightAndOtherRestrictions'] = $obj->copyright : null; |
||||||
|
!is_null($obj->description) ? $this->arrayrights['description'] = $obj->description : null; |
||||||
|
!is_null($obj->cost) ? $this->arrayrights['cost'] = $obj->cost : null; |
||||||
|
} |
||||||
|
|
||||||
|
public function addMetadataLifecycle($obj) |
||||||
|
{ |
||||||
|
if (empty($obj)) { |
||||||
|
throw new Exception('Medatada Object given is invalid or null!'); |
||||||
|
} |
||||||
|
!is_null($obj->role) ? $this->arraylifecycle['role'] = $obj->role : null; |
||||||
|
!is_null($obj->entity) ? $this->arraylifecycle['entity'] = $obj->entity : null; |
||||||
|
!is_null($obj->date) ? $this->arraylifecycle['date'] = $obj->date : null; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_metadata_resource.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Metadata Resource. |
||||||
|
*/ |
||||||
|
class CcMetadataResource implements CcIMetadataResource |
||||||
|
{ |
||||||
|
public $arrayeducational = []; |
||||||
|
|
||||||
|
public function addMetadataResourceEducational($obj) |
||||||
|
{ |
||||||
|
if (empty($obj)) { |
||||||
|
throw new Exception('Medatada Object given is invalid or null!'); |
||||||
|
} |
||||||
|
$this->arrayeducational['value'] = (!is_null($obj->value) ? $obj->value : null); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_metadata_resource.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Metadata Resource Educational Type. |
||||||
|
*/ |
||||||
|
class CcMetadataResourceEducational |
||||||
|
{ |
||||||
|
public $value = []; |
||||||
|
|
||||||
|
public function setValue($value) |
||||||
|
{ |
||||||
|
$arr = [$value]; |
||||||
|
$this->value[] = $arr; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,97 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_organization.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Organization Class. |
||||||
|
*/ |
||||||
|
class CcOrganization implements CcIOrganization |
||||||
|
{ |
||||||
|
public $title = null; |
||||||
|
public $identifier = null; |
||||||
|
public $structure = null; |
||||||
|
public $itemlist = null; |
||||||
|
private $metadata = null; |
||||||
|
private $sequencing = null; |
||||||
|
|
||||||
|
public function __construct($node = null, $doc = null) |
||||||
|
{ |
||||||
|
if (is_object($node) && is_object($doc)) { |
||||||
|
$this->processOrganization($node, $doc); |
||||||
|
} else { |
||||||
|
$this->initNew(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add one Item into the Organization. |
||||||
|
*/ |
||||||
|
public function addItem(CcIItem &$item) |
||||||
|
{ |
||||||
|
if (is_null($this->itemlist)) { |
||||||
|
$this->itemlist = []; |
||||||
|
} |
||||||
|
$this->itemlist[$item->identifier] = $item; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add new Item into the Organization. |
||||||
|
* |
||||||
|
* @param string $title |
||||||
|
* |
||||||
|
* @return CcIItem |
||||||
|
*/ |
||||||
|
public function addNewItem($title = '') |
||||||
|
{ |
||||||
|
$nitem = new CcItem(); |
||||||
|
$nitem->title = $title; |
||||||
|
$this->addItem($nitem); |
||||||
|
|
||||||
|
return $nitem; |
||||||
|
} |
||||||
|
|
||||||
|
public function hasItems() |
||||||
|
{ |
||||||
|
return is_array($this->itemlist) && (count($this->itemlist) > 0); |
||||||
|
} |
||||||
|
|
||||||
|
public function attrValue(&$nod, $name, $ns = null) |
||||||
|
{ |
||||||
|
return is_null($ns) ? |
||||||
|
($nod->hasAttribute($name) ? $nod->getAttribute($name) : null) : |
||||||
|
($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null); |
||||||
|
} |
||||||
|
|
||||||
|
public function processOrganization(&$node, &$doc) |
||||||
|
{ |
||||||
|
$this->identifier = $this->attrValue($node, "identifier"); |
||||||
|
$this->structure = $this->attrValue($node, "structure"); |
||||||
|
$this->title = ''; |
||||||
|
$nlist = $node->getElementsByTagName('title'); |
||||||
|
if (is_object($nlist) && ($nlist->length > 0)) { |
||||||
|
$this->title = $nlist->item(0)->nodeValue; |
||||||
|
} |
||||||
|
$nlist = $doc->nodeList("//imscc:organization[@identifier='".$this->identifier."']/imscc:item"); |
||||||
|
$this->itemlist = []; |
||||||
|
foreach ($nlist as $item) { |
||||||
|
$this->itemlist[$item->getAttribute("identifier")] = new CcItem($item, $doc); |
||||||
|
} |
||||||
|
$this->isempty = false; |
||||||
|
} |
||||||
|
|
||||||
|
public function initNew() |
||||||
|
{ |
||||||
|
$this->title = null; |
||||||
|
$this->identifier = CcHelpers::uuidgen('O_'); |
||||||
|
$this->structure = 'rooted-hierarchy'; |
||||||
|
$this->itemlist = null; |
||||||
|
$this->metadata = null; |
||||||
|
$this->sequencing = null; |
||||||
|
} |
||||||
|
|
||||||
|
public function uuidgen() |
||||||
|
{ |
||||||
|
$uuid = sprintf('%04x%04x', mt_rand(0, 65535), mt_rand(0, 65535)); |
||||||
|
|
||||||
|
return strtoupper(trim($uuid)); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,98 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_page.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcPage extends CcGeneralFile |
||||||
|
{ |
||||||
|
protected $rootns = 'xmlns'; |
||||||
|
protected $rootname = 'html'; |
||||||
|
protected $ccnamespaces = ['xmlns' => 'http://www.w3.org/1999/xhtml']; |
||||||
|
|
||||||
|
protected $content = null; |
||||||
|
protected $title = null; |
||||||
|
protected $intro = null; |
||||||
|
|
||||||
|
public function setContent($value) |
||||||
|
{ |
||||||
|
// We are not cleaning up this one on purpose. |
||||||
|
$this->content = $value; |
||||||
|
} |
||||||
|
|
||||||
|
public function setTitle($value) |
||||||
|
{ |
||||||
|
$this->title = self::safexml($value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setIntro($value) |
||||||
|
{ |
||||||
|
$this->intro = self::safexml(strip_tags($value)); |
||||||
|
} |
||||||
|
|
||||||
|
public function onSave() |
||||||
|
{ |
||||||
|
$rns = $this->ccnamespaces[$this->rootns]; |
||||||
|
// Add the basic tags. |
||||||
|
$head = $this->appendNewElementNs($this->root, $rns, 'head'); |
||||||
|
$this->appendNewAttributeNs($head, $rns, 'profile', 'http://dublincore.org/documents/dc-html/'); |
||||||
|
|
||||||
|
// Linking Dublin Core Metadata 1.1. |
||||||
|
$link_dc = $this->appendNewElementNs($head, $rns, 'link'); |
||||||
|
$this->appendNewAttributeNs($link_dc, $rns, 'rel', 'schema.DC'); |
||||||
|
$this->appendNewAttributeNs($link_dc, $rns, 'href', 'http://purl.org/dc/elements/1.1/'); |
||||||
|
$link_dcterms = $this->appendNewElementNs($head, $rns, 'link'); |
||||||
|
$this->appendNewAttributeNs($link_dcterms, $rns, 'rel', 'schema.DCTERMS'); |
||||||
|
$this->appendNewAttributeNs($link_dcterms, $rns, 'href', 'http://purl.org/dc/terms/'); |
||||||
|
// Content type. |
||||||
|
$meta_type = $this->appendNewElementNs($head, $rns, 'meta'); |
||||||
|
$this->appendNewAttributeNs($meta_type, $rns, 'name', 'DC.type'); |
||||||
|
$this->appendNewAttributeNs($meta_type, $rns, 'scheme', 'DCTERMS.DCMIType'); |
||||||
|
$this->appendNewAttributeNs($meta_type, $rns, 'content', 'Text'); |
||||||
|
|
||||||
|
// Content description. |
||||||
|
if (!empty($this->intro)) { |
||||||
|
$meta_description = $this->appendNewElementNs($head, $rns, 'meta'); |
||||||
|
$this->appendNewAttributeNs($meta_description, $rns, 'name', 'DC.description'); |
||||||
|
$this->appendNewAttributeNs($meta_description, $rns, 'content', $this->intro); |
||||||
|
} |
||||||
|
|
||||||
|
$meta = $this->appendNewElementNs($head, $rns, 'meta'); |
||||||
|
$this->appendNewAttributeNs($meta, $rns, 'http-equiv', 'Content-type'); |
||||||
|
$this->appendNewAttributeNs($meta, $rns, 'content', 'text/html; charset=UTF-8'); |
||||||
|
// Set the title. |
||||||
|
$title = $this->appendNewElementNs($head, $rns, 'title', $this->title); |
||||||
|
$body = $this->appendNewElementNs($this->root, $rns, 'body'); |
||||||
|
// We are unable to use DOM for embedding HTML due to numerous content errors. |
||||||
|
// Therefore we place a dummy tag that will be later replaced with the real content. |
||||||
|
$this->appendNewElementNs($body, $rns, 'div', '##REPLACE##'); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public function saveTo($fname) |
||||||
|
{ |
||||||
|
$result = $this->onSave(); |
||||||
|
if ($result) { |
||||||
|
$dret = str_replace('<?xml version="1.0"?>'."\n", '', $this->viewXML());
|
||||||
|
$dret = str_replace('<div>##REPLACE##</div>', $this->content, $dret); |
||||||
|
$result = (file_put_contents($fname, $dret) !== false); |
||||||
|
if ($result) { |
||||||
|
$this->filename = $fname; |
||||||
|
$this->processPath(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
protected function onCreate() |
||||||
|
{ |
||||||
|
$impl = new DOMImplementation(); |
||||||
|
$dtd = $impl->createDocumentType('html', |
||||||
|
'-//W3C//DTD XHTML 1.0 Strict//EN', |
||||||
|
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); |
||||||
|
$doc = $impl->createDocument($this->ccnamespaces[$this->rootns], null, $dtd); |
||||||
|
$doc->formatOutput = true; |
||||||
|
$doc->preserveWhiteSpace = true; |
||||||
|
$this->doc = $doc; |
||||||
|
parent::onCreate(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,164 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_resources.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcResources implements CcIResource |
||||||
|
{ |
||||||
|
public $identifier = null; |
||||||
|
public $type = null; |
||||||
|
public $dependency = []; |
||||||
|
public $identifierref = null; |
||||||
|
public $href = null; |
||||||
|
public $base = null; |
||||||
|
public $persiststate = null; |
||||||
|
public $metadata = []; |
||||||
|
public $filename = null; |
||||||
|
public $files = []; |
||||||
|
public $isempty = null; |
||||||
|
public $manifestroot = null; |
||||||
|
public $folder = null; |
||||||
|
public $instructoronly = false; |
||||||
|
|
||||||
|
private $throwonerror = true; |
||||||
|
|
||||||
|
public function __construct($manifest, $file, $folder = '', $throwonerror = true) |
||||||
|
{ |
||||||
|
$this->throwonerror = $throwonerror; |
||||||
|
if (is_string($manifest)) { |
||||||
|
$this->folder = $folder; |
||||||
|
$this->processResource($manifest, $file, $folder); |
||||||
|
$this->manifestroot = $manifest; |
||||||
|
} elseif (is_object($manifest)) { |
||||||
|
$this->importResource($file, $manifest); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add resource. |
||||||
|
* |
||||||
|
* @param string $fname |
||||||
|
* @param string $location |
||||||
|
*/ |
||||||
|
public function addResource($fname, $location = '') |
||||||
|
{ |
||||||
|
$this->processResource($fname, $location, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Import a resource. |
||||||
|
*/ |
||||||
|
public function importResource(DOMElement &$node, CcIManifest &$doc) |
||||||
|
{ |
||||||
|
$searchstr = "//imscc:manifest[@identifier='".$doc->manifestID(). |
||||||
|
"']/imscc:resources/imscc:resource"; |
||||||
|
$this->identifier = $this->getAttrValue($node, "identifier"); |
||||||
|
$this->type = $this->getAttrValue($node, "type"); |
||||||
|
$this->href = $this->getAttrValue($node, "href"); |
||||||
|
$this->base = $this->getAttrValue($node, "base"); |
||||||
|
$this->persiststate = null; |
||||||
|
$nodo = $doc->nodeList($searchstr."[@identifier='". |
||||||
|
$this->identifier."']/metadata/@href"); |
||||||
|
$this->metadata = $nodo->nodeValue; |
||||||
|
$this->filename = $this->href; |
||||||
|
$nlist = $doc->nodeList($searchstr."[@identifier='". |
||||||
|
$this->identifier."']/imscc:file/@href"); |
||||||
|
$this->files = []; |
||||||
|
foreach ($nlist as $file) { |
||||||
|
$this->files[] = $file->nodeValue; |
||||||
|
} |
||||||
|
$nlist = $doc->nodeList($searchstr."[@identifier='". |
||||||
|
$this->identifier."']/imscc:dependency/@identifierref"); |
||||||
|
$this->dependency = []; |
||||||
|
foreach ($nlist as $dependency) { |
||||||
|
$this->dependency[] = $dependency->nodeValue; |
||||||
|
} |
||||||
|
$this->isempty = false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get a attribute value. |
||||||
|
* |
||||||
|
* @param DOMElement $nod |
||||||
|
* @param string $name |
||||||
|
* @param string $ns |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function getAttrValue(&$nod, $name, $ns = null) |
||||||
|
{ |
||||||
|
if (is_null($ns)) { |
||||||
|
return $nod->hasAttribute($name) ? $nod->getAttribute($name) : null; |
||||||
|
} |
||||||
|
|
||||||
|
return $nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Process a resource. |
||||||
|
* |
||||||
|
* @param string $manifestroot |
||||||
|
* @param string $fname |
||||||
|
* @param string $folder |
||||||
|
*/ |
||||||
|
public function processResource($manifestroot, &$fname, $folder) |
||||||
|
{ |
||||||
|
$file = empty($folder) ? $manifestroot.'/'.$fname : $manifestroot.'/'.$folder.'/'.$fname; |
||||||
|
|
||||||
|
if (!file_exists($file) && $this->throwonerror) { |
||||||
|
throw new Exception('The file doesnt exist!'); |
||||||
|
} |
||||||
|
|
||||||
|
getDepFiles($manifestroot, $fname, $this->folder, $this->files); |
||||||
|
array_unshift($this->files, $folder.$fname); |
||||||
|
$this->initEmptyNew(); |
||||||
|
$this->href = $folder.$fname; |
||||||
|
$this->identifierref = $folder.$fname; |
||||||
|
$this->filename = $fname; |
||||||
|
$this->isempty = false; |
||||||
|
$this->folder = $folder; |
||||||
|
} |
||||||
|
|
||||||
|
public function adjustPath($mroot, $fname) |
||||||
|
{ |
||||||
|
$result = null; |
||||||
|
if (file_exists($fname->filename)) { |
||||||
|
$result = pathDiff($fname->filename, $mroot); |
||||||
|
} elseif (file_exists($mroot.$fname->filename) || file_exists($mroot.DIRECTORY_SEPARATOR.$fname->filename)) { |
||||||
|
$result = $fname->filename; |
||||||
|
toUrlPath($result); |
||||||
|
$result = trim($result, "/"); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function initClean() |
||||||
|
{ |
||||||
|
$this->identifier = null; |
||||||
|
$this->type = null; |
||||||
|
$this->href = null; |
||||||
|
$this->base = null; |
||||||
|
$this->metadata = []; |
||||||
|
$this->dependency = []; |
||||||
|
$this->identifierref = null; |
||||||
|
$this->persiststate = null; |
||||||
|
$this->filename = ''; |
||||||
|
$this->files = []; |
||||||
|
$this->isempty = true; |
||||||
|
} |
||||||
|
|
||||||
|
public function initEmptyNew() |
||||||
|
{ |
||||||
|
$this->identifier = CcHelpers::uuidgen('I_', '_R'); |
||||||
|
$this->type = null; |
||||||
|
$this->href = null; |
||||||
|
$this->persiststate = null; |
||||||
|
$this->filename = null; |
||||||
|
$this->isempty = false; |
||||||
|
$this->identifierref = null; |
||||||
|
} |
||||||
|
|
||||||
|
public function getManifestroot() |
||||||
|
{ |
||||||
|
return $this->manifestroot; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,102 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
class CcVersion13 extends CcVersion1 |
||||||
|
{ |
||||||
|
const WEBCONTENT = 'webcontent'; |
||||||
|
const QUESTIONBANK = 'imsqti_xmlv1p3/imscc_xmlv1p3/question-bank'; |
||||||
|
const ASSESSMENT = 'imsqti_xmlv1p3/imscc_xmlv1p3/assessment'; |
||||||
|
const ASSOCIATEDCONTENT = 'associatedcontent/imscc_xmlv1p3/learning-application-resource'; |
||||||
|
const DISCUSSIONTOPIC = 'imsdt_xmlv1p3'; |
||||||
|
const WEBLINK = 'imswl_xmlv1p3'; |
||||||
|
const BASICLTI = 'imsbasiclti_xmlv1p3'; |
||||||
|
|
||||||
|
public static $checker = [self::WEBCONTENT, |
||||||
|
self::ASSESSMENT, |
||||||
|
self::ASSOCIATEDCONTENT, |
||||||
|
self::DISCUSSIONTOPIC, |
||||||
|
self::QUESTIONBANK, |
||||||
|
self::WEBLINK, |
||||||
|
self::BASICLTI, ]; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->ccnamespaces = ['imscc' => 'http://www.imsglobal.org/xsd/imsccv1p3/imscp_v1p1', |
||||||
|
'lomimscc' => 'http://ltsc.ieee.org/xsd/imsccv1p3/LOM/manifest', |
||||||
|
'lom' => 'http://ltsc.ieee.org/xsd/imsccv1p3/LOM/resource', |
||||||
|
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
||||||
|
'cc' => 'http://www.imsglobal.org/xsd/imsccv1p3/imsccauth_v1p1', |
||||||
|
]; |
||||||
|
|
||||||
|
$this->ccnsnames = ['imscc' => 'http://www.imsglobal.org/profile/cc/ccv1p3/ccv1p3_imscp_v1p2_v1p0.xsd', |
||||||
|
'lomimscc' => 'http://www.imsglobal.org/profile/cc/ccv1p3/LOM/ccv1p3_lommanifest_v1p0.xsd', |
||||||
|
'lom' => 'http://www.imsglobal.org/profile/cc/ccv1p3/LOM/ccv1p3_lomresource_v1p0.xsd', |
||||||
|
]; |
||||||
|
|
||||||
|
$this->ccversion = '1.3.0'; |
||||||
|
$this->camversion = '1.3.0'; |
||||||
|
$this->_generator = 'Chamilo Common Cartridge generator'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validate if the type are valid or not. |
||||||
|
* |
||||||
|
* @param string $type |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
public function valid($type) |
||||||
|
{ |
||||||
|
return in_array($type, self::$checker); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Education Metadata (How To). |
||||||
|
* |
||||||
|
* @param object $met |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function createMetadataEducational($met, DOMDocument &$doc, $xmlnode) |
||||||
|
{ |
||||||
|
$metadata = $doc->createElementNS($this->ccnamespaces['imscc'], 'metadata'); |
||||||
|
$xmlnode->insertBefore($metadata, $xmlnode->firstChild); |
||||||
|
$lom = $doc->createElementNS($this->ccnamespaces['lom'], 'lom'); |
||||||
|
$metadata->appendChild($lom); |
||||||
|
$educational = $doc->createElementNS($this->ccnamespaces['lom'], 'educational'); |
||||||
|
$lom->appendChild($educational); |
||||||
|
|
||||||
|
foreach ($met->arrayeducational as $value) { |
||||||
|
!is_array($value) ? $value = [$value] : null; |
||||||
|
foreach ($value as $v) { |
||||||
|
$userrole = $doc->createElementNS($this->ccnamespaces['lom'], 'intendedEndUserRole'); |
||||||
|
$educational->appendChild($userrole); |
||||||
|
$nd4 = $doc->createElementNS($this->ccnamespaces['lom'], 'source', 'IMSGLC_CC_Rolesv1p2'); |
||||||
|
$nd5 = $doc->createElementNS($this->ccnamespaces['lom'], 'value', $v[0]); |
||||||
|
$userrole->appendChild($nd4); |
||||||
|
$userrole->appendChild($nd5); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $metadata; |
||||||
|
} |
||||||
|
|
||||||
|
protected function updateItems($items, DOMDocument &$doc, DOMElement &$xmlnode) |
||||||
|
{ |
||||||
|
foreach ($items as $key => $item) { |
||||||
|
$itemnode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item'); |
||||||
|
$this->updateAttribute($doc, 'identifier', $key, $itemnode); |
||||||
|
$this->updateAttribute($doc, 'identifierref', $item->identifierref, $itemnode); |
||||||
|
if (!is_null($item->title)) { |
||||||
|
$titlenode = $doc->createElementNS($this->ccnamespaces['imscc'], 'title'); |
||||||
|
$titlenode->appendChild(new DOMText($item->title)); |
||||||
|
$itemnode->appendChild($titlenode); |
||||||
|
} |
||||||
|
if ($item->hasChildItems()) { |
||||||
|
$this->updateItems($item->childitems, $doc, $itemnode); |
||||||
|
} |
||||||
|
$xmlnode->appendChild($itemnode); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_weblink.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcWebLink extends CcGeneralFile |
||||||
|
{ |
||||||
|
const DEAFULTNAME = 'weblink.xml'; |
||||||
|
|
||||||
|
protected $rootns = 'wl'; |
||||||
|
protected $rootname = 'webLink'; |
||||||
|
protected $ccnamespaces = ['wl' => 'http://www.imsglobal.org/xsd/imsccv1p3/imswl_v1p3', |
||||||
|
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', ]; |
||||||
|
protected $ccnsnames = ['wl' => 'http://www.imsglobal.org/profile/cc/ccv1p3/ccv1p3_imswl_v1p3.xsd']; |
||||||
|
|
||||||
|
protected $url = null; |
||||||
|
protected $title = null; |
||||||
|
protected $href = null; |
||||||
|
protected $target = '_self'; |
||||||
|
protected $windowFeatures = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the url title. |
||||||
|
* |
||||||
|
* @param string $title |
||||||
|
*/ |
||||||
|
public function setTitle($title) |
||||||
|
{ |
||||||
|
$this->title = self::safexml($title); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the url specifics. |
||||||
|
* |
||||||
|
* @param string $url |
||||||
|
* @param string $target |
||||||
|
* @param string $windowFeatures |
||||||
|
*/ |
||||||
|
public function setUrl($url, $target = '_self', $windowFeatures = null) |
||||||
|
{ |
||||||
|
$this->url = $url; |
||||||
|
$this->target = $target; |
||||||
|
$this->windowFeatures = $windowFeatures; |
||||||
|
} |
||||||
|
|
||||||
|
protected function onSave() |
||||||
|
{ |
||||||
|
$rns = $this->ccnamespaces[$this->rootns]; |
||||||
|
$this->appendNewElementNs($this->root, $rns, 'title', $this->title); |
||||||
|
$url = $this->appendNewElementNs($this->root, $rns, 'url'); |
||||||
|
$this->appendNewAttributeNs($url, $rns, 'href', $this->url); |
||||||
|
if (!empty($this->target)) { |
||||||
|
$this->appendNewAttributeNs($url, $rns, 'target', $this->target); |
||||||
|
} |
||||||
|
if (!empty($this->windowFeatures)) { |
||||||
|
$this->appendNewAttributeNs($url, $rns, 'windowFeatures', $this->windowFeatures); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,88 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converters.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcConverters |
||||||
|
{ |
||||||
|
protected $item = null; |
||||||
|
protected $manifest = null; |
||||||
|
protected $rootpath = null; |
||||||
|
protected $path = null; |
||||||
|
protected $defaultfile = null; |
||||||
|
protected $defaultname = null; |
||||||
|
protected $ccType = null; |
||||||
|
protected $doc = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* ctor. |
||||||
|
* |
||||||
|
* @param CcIItem $item |
||||||
|
* @param CcIManifest $manifest |
||||||
|
* @param string $rootpath |
||||||
|
* @param string $path |
||||||
|
* |
||||||
|
* @throws InvalidArgumentException |
||||||
|
*/ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$rpath = realpath($rootpath); |
||||||
|
if (empty($rpath)) { |
||||||
|
throw new InvalidArgumentException('Invalid path!'); |
||||||
|
} |
||||||
|
$rpath2 = realpath($path); |
||||||
|
if (empty($rpath)) { |
||||||
|
throw new InvalidArgumentException('Invalid path!'); |
||||||
|
} |
||||||
|
$doc = new XMLGenericDocument(); |
||||||
|
|
||||||
|
$this->doc = $doc; |
||||||
|
$this->item = $item; |
||||||
|
$this->manifest = $manifest; |
||||||
|
$this->rootpath = $rpath; |
||||||
|
$this->path = $rpath2; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* performs conversion. |
||||||
|
* |
||||||
|
* @param string $outdir - root directory of common cartridge |
||||||
|
* @param object $objCourse |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
abstract public function convert($outdir, $objCourse); |
||||||
|
|
||||||
|
/** |
||||||
|
* Is the element visible in the course? |
||||||
|
* |
||||||
|
* @throws RuntimeException |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
protected function isVisible() |
||||||
|
{ |
||||||
|
$tdoc = new XMLGenericDocument(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores any files that need to be stored. |
||||||
|
*/ |
||||||
|
protected function store(CcGeneralFile $doc, $outdir, $title, $deps = null) |
||||||
|
{ |
||||||
|
$rdir = new CcResourceLocation($outdir); |
||||||
|
$rtp = $rdir->fullpath(true).$this->defaultname; |
||||||
|
if ($doc->saveTo($rtp)) { |
||||||
|
$resource = new CcResources($rdir->rootdir(), $this->defaultname, $rdir->dirname(true)); |
||||||
|
$resource->dependency = empty($deps) ? [] : $deps; |
||||||
|
$resource->instructoronly = !$this->isVisible(); |
||||||
|
$res = $this->manifest->addResource($resource, null, $this->ccType); |
||||||
|
$resitem = new CcItem(); |
||||||
|
$resitem->attachResource($res[0]); |
||||||
|
$resitem->title = $title; |
||||||
|
$this->item->addChildItem($resitem); |
||||||
|
} else { |
||||||
|
throw new RuntimeException("Unable to save file {$rtp}!"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,53 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_general.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcGeneralFile extends XMLGenericDocument |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Root element. |
||||||
|
* |
||||||
|
* @var DOMElement |
||||||
|
*/ |
||||||
|
protected $root = null; |
||||||
|
protected $rootns = null; |
||||||
|
protected $rootname = null; |
||||||
|
protected $ccnamespaces = []; |
||||||
|
protected $ccnsnames = []; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
parent::__construct(); |
||||||
|
|
||||||
|
foreach ($this->ccnamespaces as $key => $value) { |
||||||
|
$this->registerNS($key, $value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected function onCreate() |
||||||
|
{ |
||||||
|
$rootel = $this->appendNewElementNs($this->doc, |
||||||
|
$this->ccnamespaces[$this->rootns], |
||||||
|
$this->rootname); |
||||||
|
//add all namespaces |
||||||
|
foreach ($this->ccnamespaces as $key => $value) { |
||||||
|
$dummy_attr = "{$key}:dummy"; |
||||||
|
$this->doc->createAttributeNS($value, $dummy_attr); |
||||||
|
} |
||||||
|
|
||||||
|
// add location of schemas |
||||||
|
$schemaLocation = ''; |
||||||
|
foreach ($this->ccnsnames as $key => $value) { |
||||||
|
$vt = empty($schemaLocation) ? '' : ' '; |
||||||
|
$schemaLocation .= $vt.$this->ccnamespaces[$key].' '.$value; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($schemaLocation) && isset($this->ccnamespaces['xsi'])) { |
||||||
|
$this->appendNewAttributeNs($rootel, |
||||||
|
$this->ccnamespaces['xsi'], |
||||||
|
'xsi:schemaLocation', |
||||||
|
$schemaLocation); |
||||||
|
} |
||||||
|
|
||||||
|
$this->root = $rootel; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,520 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_version1.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Version 1 class of Common Cartridge. |
||||||
|
*/ |
||||||
|
class CcVersion1 extends CcVersionBase |
||||||
|
{ |
||||||
|
const WEBCONTENT = 'webcontent'; |
||||||
|
const QUESTIONBANK = 'imsqti_xmlv1p2/imscc_xmlv1p0/question-bank'; |
||||||
|
const ASSESSMENT = 'imsqti_xmlv1p2/imscc_xmlv1p0/assessment'; |
||||||
|
const ASSOCIATEDCONTENT = 'associatedcontent/imscc_xmlv1p0/learning-application-resource'; |
||||||
|
const DISCUSSIONTOPIC = 'imsdt_xmlv1p0'; |
||||||
|
const WEBLINK = 'imswl_xmlv1p0'; |
||||||
|
|
||||||
|
public static $checker = [self::WEBCONTENT, |
||||||
|
self::ASSESSMENT, |
||||||
|
self::ASSOCIATEDCONTENT, |
||||||
|
self::DISCUSSIONTOPIC, |
||||||
|
self::QUESTIONBANK, |
||||||
|
self::WEBLINK, ]; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->ccnamespaces = ['imscc' => 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1', |
||||||
|
'lomimscc' => 'http://ltsc.ieee.org/xsd/imscc/LOM', |
||||||
|
'lom' => 'http://ltsc.ieee.org/xsd/LOM', |
||||||
|
'voc' => 'http://ltsc.ieee.org/xsd/LOM/vocab', |
||||||
|
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
||||||
|
]; |
||||||
|
|
||||||
|
$this->ccnsnames = [ |
||||||
|
'imscc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/imscp_v1p2_localised.xsd', |
||||||
|
'lom' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/lomLoose_localised.xsd', |
||||||
|
'lomimscc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_1/lomLoose_localised.xsd', |
||||||
|
'voc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/vocab/loose.xsd', |
||||||
|
]; |
||||||
|
|
||||||
|
$this->ccversion = '1.0.0'; |
||||||
|
$this->camversion = '1.0.0'; |
||||||
|
$this->_generator = 'Common Cartridge generator'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validate if the type are valid or not. |
||||||
|
* |
||||||
|
* @param string $type |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
public function valid($type) |
||||||
|
{ |
||||||
|
return in_array($type, self::$checker); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Education Metadata (How To). |
||||||
|
* |
||||||
|
* @param object $met |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function createMetadataEducational($met, DOMDocument &$doc, $xmlnode) |
||||||
|
{ |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['lom'], 'educational'); |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lom'], 'intendedEndUserRole'); |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['voc'], 'vocabulary'); |
||||||
|
|
||||||
|
$xmlnode->appendChild($nd); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
|
||||||
|
foreach ($met->arrayeducational as $name => $value) { |
||||||
|
!is_array($value) ? $value = [$value] : null; |
||||||
|
foreach ($value as $v) { |
||||||
|
$nd4 = $doc->createElementNS($this->ccnamespaces['voc'], $name, $v[0]); |
||||||
|
$nd3->appendChild($nd4); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nd; |
||||||
|
} |
||||||
|
|
||||||
|
protected function onCreate(DOMDocument &$doc, $rootmanifestnode = null, $nmanifestID = null) |
||||||
|
{ |
||||||
|
$doc->formatOutput = true; |
||||||
|
$doc->preserveWhiteSpace = true; |
||||||
|
|
||||||
|
$this->manifestID = is_null($nmanifestID) ? CcHelpers::uuidgen('M_') : $nmanifestID; |
||||||
|
$mUUID = $doc->createAttribute('identifier'); |
||||||
|
$mUUID->nodeValue = $this->manifestID; |
||||||
|
|
||||||
|
if (is_null($rootmanifestnode)) { |
||||||
|
if (!empty($this->_generator)) { |
||||||
|
$comment = $doc->createComment($this->_generator); |
||||||
|
$doc->appendChild($comment); |
||||||
|
} |
||||||
|
|
||||||
|
$rootel = $doc->createElementNS($this->ccnamespaces['imscc'], 'manifest'); |
||||||
|
$rootel->appendChild($mUUID); |
||||||
|
$doc->appendChild($rootel); |
||||||
|
|
||||||
|
// Add all namespaces. |
||||||
|
foreach ($this->ccnamespaces as $key => $value) { |
||||||
|
$dummy_attr = $key.":dummy"; |
||||||
|
$doc->createAttributeNS($value, $dummy_attr); |
||||||
|
} |
||||||
|
|
||||||
|
// Add location of schemas. |
||||||
|
$schemaLocation = ''; |
||||||
|
foreach ($this->ccnsnames as $key => $value) { |
||||||
|
$vt = empty($schemaLocation) ? '' : ' '; |
||||||
|
$schemaLocation .= $vt.$this->ccnamespaces[$key].' '.$value; |
||||||
|
} |
||||||
|
$aSchemaLoc = $doc->createAttributeNS($this->ccnamespaces['xsi'], 'xsi:schemaLocation'); |
||||||
|
$aSchemaLoc->nodeValue = $schemaLocation; |
||||||
|
$rootel->appendChild($aSchemaLoc); |
||||||
|
} else { |
||||||
|
$rootel = $doc->createElementNS($this->ccnamespaces['imscc'], 'imscc:manifest'); |
||||||
|
$rootel->appendChild($mUUID); |
||||||
|
} |
||||||
|
|
||||||
|
$metadata = $doc->createElementNS($this->ccnamespaces['imscc'], 'metadata'); |
||||||
|
$schema = $doc->createElementNS($this->ccnamespaces['imscc'], 'schema', 'IMS Common Cartridge'); |
||||||
|
$schemaversion = $doc->createElementNS($this->ccnamespaces['imscc'], 'schemaversion', $this->ccversion); |
||||||
|
|
||||||
|
$metadata->appendChild($schema); |
||||||
|
$metadata->appendChild($schemaversion); |
||||||
|
$rootel->appendChild($metadata); |
||||||
|
|
||||||
|
if (!is_null($rootmanifestnode)) { |
||||||
|
$rootmanifestnode->appendChild($rootel); |
||||||
|
} |
||||||
|
|
||||||
|
$organizations = $doc->createElementNS($this->ccnamespaces['imscc'], 'organizations'); |
||||||
|
$rootel->appendChild($organizations); |
||||||
|
$resources = $doc->createElementNS($this->ccnamespaces['imscc'], 'resources'); |
||||||
|
$rootel->appendChild($resources); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected function updateAttribute(DOMDocument &$doc, $attrname, $attrvalue, DOMElement &$node) |
||||||
|
{ |
||||||
|
$busenew = (is_object($node) && $node->hasAttribute($attrname)); |
||||||
|
$nResult = null; |
||||||
|
if (!$busenew && is_null($attrvalue)) { |
||||||
|
$node->removeAttribute($attrname); |
||||||
|
} else { |
||||||
|
$nResult = $busenew ? $node->getAttributeNode($attrname) : $doc->createAttribute($attrname); |
||||||
|
$nResult->nodeValue = $attrvalue; |
||||||
|
if (!$busenew) { |
||||||
|
$node->appendChild($nResult); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nResult; |
||||||
|
} |
||||||
|
|
||||||
|
protected function updateAttributeNs(DOMDocument &$doc, $attrname, $attrnamespace, $attrvalue, DOMElement &$node) |
||||||
|
{ |
||||||
|
$busenew = (is_object($node) && $node->hasAttributeNS($attrnamespace, $attrname)); |
||||||
|
$nResult = null; |
||||||
|
if (!$busenew && is_null($attrvalue)) { |
||||||
|
$node->removeAttributeNS($attrnamespace, $attrname); |
||||||
|
} else { |
||||||
|
$nResult = $busenew ? $node->getAttributeNodeNS($attrnamespace, $attrname) : |
||||||
|
$doc->createAttributeNS($attrnamespace, $attrname); |
||||||
|
$nResult->nodeValue = $attrvalue; |
||||||
|
if (!$busenew) { |
||||||
|
$node->appendChild($nResult); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nResult; |
||||||
|
} |
||||||
|
|
||||||
|
protected function getChildNode(DOMDocument &$doc, $itemname, DOMElement &$node) |
||||||
|
{ |
||||||
|
$nlist = $node->getElementsByTagName($itemname); |
||||||
|
$item = is_object($nlist) && ($nlist->length > 0) ? $nlist->item(0) : null; |
||||||
|
|
||||||
|
return $item; |
||||||
|
} |
||||||
|
|
||||||
|
protected function updateChildItem(DOMDocument &$doc, $itemname, $itemvalue, DOMElement &$node, $attrtostore = null) |
||||||
|
{ |
||||||
|
$tnode = $this->getChildNode($doc, 'title', $node); |
||||||
|
$usenew = is_null($tnode); |
||||||
|
$tnode = $usenew ? $doc->createElementNS($this->ccnamespaces['imscc'], $itemname) : $tnode; |
||||||
|
if (!is_null($attrtostore)) { |
||||||
|
foreach ($attrtostore as $key => $value) { |
||||||
|
$this->updateAttribute($doc, $key, $value, $tnode); |
||||||
|
} |
||||||
|
} |
||||||
|
$tnode->nodeValue = $itemvalue; |
||||||
|
if ($usenew) { |
||||||
|
$node->appendChild($tnode); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected function updateItems($items, DOMDocument &$doc, DOMElement &$xmlnode) |
||||||
|
{ |
||||||
|
foreach ($items as $key => $item) { |
||||||
|
$itemnode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item'); |
||||||
|
$this->updateAttribute($doc, 'identifier', $key, $itemnode); |
||||||
|
$this->updateAttribute($doc, 'identifierref', $item->identifierref, $itemnode); |
||||||
|
$this->updateAttribute($doc, 'parameters', $item->parameters, $itemnode); |
||||||
|
if (!empty($item->title)) { |
||||||
|
$titlenode = $doc->createElementNS($this->ccnamespaces['imscc'], |
||||||
|
'title', |
||||||
|
$item->title); |
||||||
|
$itemnode->appendChild($titlenode); |
||||||
|
} |
||||||
|
if ($item->hasChildItems()) { |
||||||
|
$this->updateItems($item->childitems, $doc, $itemnode); |
||||||
|
} |
||||||
|
$xmlnode->appendChild($itemnode); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a Resource (How to). |
||||||
|
* |
||||||
|
* @param CcIResource $res |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createResource(CcIResource &$res, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
$usenew = is_object($xmlnode); |
||||||
|
$dnode = $usenew ? $xmlnode : $doc->createElementNS($this->ccnamespaces['imscc'], "resource"); |
||||||
|
$this->updateAttribute($doc, 'identifier', $res->identifier, $dnode); |
||||||
|
$this->updateAttribute($doc, 'type', $res->type, $dnode); |
||||||
|
!is_null($res->href) ? $this->updateAttribute($doc, 'href', $res->href, $dnode) : null; |
||||||
|
$this->updateAttribute($doc, 'base', $res->base, $dnode); |
||||||
|
|
||||||
|
foreach ($res->files as $file) { |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['imscc'], 'file'); |
||||||
|
$ndatt = $doc->createAttribute('href'); |
||||||
|
$ndatt->nodeValue = $file; |
||||||
|
$nd->appendChild($ndatt); |
||||||
|
$dnode->appendChild($nd); |
||||||
|
} |
||||||
|
$this->resources[$res->identifier] = $res; |
||||||
|
$this->resourcesInd[$res->files[0]] = $res->identifier; |
||||||
|
|
||||||
|
foreach ($res->dependency as $dependency) { |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['imscc'], 'dependency'); |
||||||
|
$ndatt = $doc->createAttribute('identifierref'); |
||||||
|
$ndatt->nodeValue = $dependency; |
||||||
|
$nd->appendChild($ndatt); |
||||||
|
$dnode->appendChild($nd); |
||||||
|
} |
||||||
|
|
||||||
|
return $dnode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create an Item Folder (How To). |
||||||
|
* |
||||||
|
* @param CcIOrganization $org |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param DOMElement $xmlnode |
||||||
|
*/ |
||||||
|
protected function createItemFolder(CcIOrganization &$org, DOMDocument &$doc, DOMElement &$xmlnode = null) |
||||||
|
{ |
||||||
|
$itemfoldernode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item'); |
||||||
|
$this->updateAttribute($doc, 'identifier', "root", $itemfoldernode); |
||||||
|
|
||||||
|
if ($org->hasItems()) { |
||||||
|
$this->updateItems($org->itemlist, $doc, $itemfoldernode); |
||||||
|
} |
||||||
|
if (is_null($this->organizations)) { |
||||||
|
$this->organizations = []; |
||||||
|
} |
||||||
|
$this->organizations[$org->identifier] = $org; |
||||||
|
|
||||||
|
$xmlnode->appendChild($itemfoldernode); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create an Organization (How To). |
||||||
|
* |
||||||
|
* @param CcIOrganization $org |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createOrganization(CcIOrganization &$org, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
$usenew = is_object($xmlnode); |
||||||
|
$dnode = $usenew ? $xmlnode : $doc->createElementNS($this->ccnamespaces['imscc'], "organization"); |
||||||
|
$this->updateAttribute($doc, 'identifier', $org->identifier, $dnode); |
||||||
|
$this->updateAttribute($doc, 'structure', $org->structure, $dnode); |
||||||
|
|
||||||
|
$this->createItemFolder($org, $doc, $dnode); |
||||||
|
|
||||||
|
return $dnode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Metadata For Manifest (How To). |
||||||
|
* |
||||||
|
* @param CcIMetadataManifest $met |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataManifest(CcIMetadataManifest $met, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
$dnode = $doc->createElementNS($this->ccnamespaces['lomimscc'], "lom"); |
||||||
|
if (!empty($xmlnode)) { |
||||||
|
$xmlnode->appendChild($dnode); |
||||||
|
} |
||||||
|
$dnodegeneral = empty($met->arraygeneral) ? null : $this->createMetadataGeneral($met, $doc, $xmlnode); |
||||||
|
$dnodetechnical = empty($met->arraytech) ? null : $this->createMetadataTechnical($met, $doc, $xmlnode); |
||||||
|
$dnoderights = empty($met->arrayrights) ? null : $this->createMetadataRights($met, $doc, $xmlnode); |
||||||
|
$dnodelifecycle = empty($met->arraylifecycle) ? null : $this->createMetadataLifecycle($met, $doc, $xmlnode); |
||||||
|
|
||||||
|
!is_null($dnodegeneral) ? $dnode->appendChild($dnodegeneral) : null; |
||||||
|
!is_null($dnodetechnical) ? $dnode->appendChild($dnodetechnical) : null; |
||||||
|
!is_null($dnoderights) ? $dnode->appendChild($dnoderights) : null; |
||||||
|
!is_null($dnodelifecycle) ? $dnode->appendChild($dnodelifecycle) : null; |
||||||
|
|
||||||
|
return $dnode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Metadata For Resource (How To). |
||||||
|
* |
||||||
|
* @param CcIMetadataResource $met |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataResource(CcIMetadataResource $met, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
$dnode = $doc->createElementNS($this->ccnamespaces['lom'], "lom"); |
||||||
|
|
||||||
|
!empty($xmlnode) ? $xmlnode->appendChild($dnode) : null; |
||||||
|
!empty($met->arrayeducational) ? $this->createMetadataEducational($met, $doc, $dnode) : null; |
||||||
|
|
||||||
|
return $dnode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Metadata For File (How To). |
||||||
|
* |
||||||
|
* @param CcIMetadataFile $met |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataFile(CcIMetadataFile $met, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
$dnode = $doc->createElementNS($this->ccnamespaces['lom'], "lom"); |
||||||
|
|
||||||
|
!empty($xmlnode) ? $xmlnode->appendChild($dnode) : null; |
||||||
|
!empty($met->arrayeducational) ? $this->createMetadataEducational($met, $doc, $dnode) : null; |
||||||
|
|
||||||
|
return $dnode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create General Metadata (How To). |
||||||
|
* |
||||||
|
* @param object $met |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataGeneral($met, DOMDocument &$doc, $xmlnode) |
||||||
|
{ |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'general'); |
||||||
|
|
||||||
|
foreach ($met->arraygeneral as $name => $value) { |
||||||
|
!is_array($value) ? $value = [$value] : null; |
||||||
|
foreach ($value as $v) { |
||||||
|
if ($name != 'language' && $name != 'catalog' && $name != 'entry') { |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name); |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'string', $v[1]); |
||||||
|
$ndatt = $doc->createAttribute('language'); |
||||||
|
$ndatt->nodeValue = $v[0]; |
||||||
|
$nd3->appendChild($ndatt); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
} else { |
||||||
|
if ($name == 'language') { |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name, $v[0]); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (!empty($met->arraygeneral['catalog']) || !empty($met->arraygeneral['entry'])) { |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'identifier'); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
if (!empty($met->arraygeneral['catalog'])) { |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'catalog', $met->arraygeneral['catalog'][0][0]); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
} |
||||||
|
if (!empty($met->arraygeneral['entry'])) { |
||||||
|
$nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'entry', $met->arraygeneral['entry'][0][0]); |
||||||
|
$nd2->appendChild($nd4); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nd; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Technical Metadata (How To). |
||||||
|
* |
||||||
|
* @param object $met |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataTechnical($met, DOMDocument &$doc, $xmlnode) |
||||||
|
{ |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'technical'); |
||||||
|
$xmlnode->appendChild($nd); |
||||||
|
|
||||||
|
foreach ($met->arraytech as $name => $value) { |
||||||
|
!is_array($value) ? $value = [$value] : null; |
||||||
|
foreach ($value as $v) { |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name, $v[0]); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nd; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Rights Metadata (How To). |
||||||
|
* |
||||||
|
* @param object $met |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataRights($met, DOMDocument &$doc, $xmlnode) |
||||||
|
{ |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'rights'); |
||||||
|
|
||||||
|
foreach ($met->arrayrights as $name => $value) { |
||||||
|
!is_array($value) ? $value = [$value] : null; |
||||||
|
foreach ($value as $v) { |
||||||
|
if ($name == 'description') { |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name); |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'string', $v[1]); |
||||||
|
$ndatt = $doc->createAttribute('language'); |
||||||
|
$ndatt->nodeValue = $v[0]; |
||||||
|
$nd3->appendChild($ndatt); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
} elseif ($name == 'copyrightAndOtherRestrictions' || $name == 'cost') { |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name); |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'value', $v[0]); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
$nd->appendChild($nd2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nd; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Lifecycle Metadata (How To). |
||||||
|
* |
||||||
|
* @param object $met |
||||||
|
* @param DOMDocument $doc |
||||||
|
* @param object $met |
||||||
|
* @param object $xmlnode |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
protected function createMetadataLifecycle($met, DOMDocument &$doc, $xmlnode) |
||||||
|
{ |
||||||
|
$nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'lifeCycle'); |
||||||
|
$nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'contribute'); |
||||||
|
|
||||||
|
$nd->appendChild($nd2); |
||||||
|
$xmlnode->appendChild($nd); |
||||||
|
|
||||||
|
foreach ($met->arraylifecycle as $name => $value) { |
||||||
|
!is_array($value) ? $value = [$value] : null; |
||||||
|
foreach ($value as $v) { |
||||||
|
if ($name == 'role') { |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
$nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'value', $v[0]); |
||||||
|
$nd3->appendChild($nd4); |
||||||
|
} else { |
||||||
|
if ($name == 'date') { |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
$nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'dateTime', $v[0]); |
||||||
|
$nd3->appendChild($nd4); |
||||||
|
} else { |
||||||
|
$nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name, $v[0]); |
||||||
|
$nd2->appendChild($nd3); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $nd; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,122 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_version_base.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Abstract Version Base class. |
||||||
|
*/ |
||||||
|
abstract class CcVersionBase |
||||||
|
{ |
||||||
|
public $resources = null; |
||||||
|
public $resourcesInd = null; |
||||||
|
public $organizations = null; |
||||||
|
public $ccversion = null; |
||||||
|
public $camversion = null; |
||||||
|
|
||||||
|
protected $_generator = null; |
||||||
|
protected $ccnamespaces = []; |
||||||
|
protected $isrootmanifest = false; |
||||||
|
protected $manifestID = null; |
||||||
|
protected $organizationid = null; |
||||||
|
protected $metadata = null; |
||||||
|
protected $base = null; |
||||||
|
|
||||||
|
public function getCcNamespaces() |
||||||
|
{ |
||||||
|
return $this->ccnamespaces; |
||||||
|
} |
||||||
|
|
||||||
|
public function createManifest(DOMDocument &$doc, $rootmanifestnode = null) |
||||||
|
{ |
||||||
|
return $this->onCreate($doc, $rootmanifestnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function createResourceNode(CcIResource &$res, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
return $this->createResource($res, $doc, $xmlnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function createMetadataNode(&$met, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
return $this->createMetadataManifest($met, $doc, $xmlnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function createMetadataResourceNode(&$met, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
return $this->createMetadataResource($met, $doc, $xmlnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function createMetadataFileNode(&$met, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
return $this->createMetadataFile($met, $doc, $xmlnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function createOrganizationNode(CcIOrganization &$org, DOMDocument &$doc, $xmlnode = null) |
||||||
|
{ |
||||||
|
return $this->createOrganization($org, $doc, $xmlnode); |
||||||
|
} |
||||||
|
|
||||||
|
public function manifestID() |
||||||
|
{ |
||||||
|
return $this->manifestID; |
||||||
|
} |
||||||
|
|
||||||
|
public function setManifestID($id) |
||||||
|
{ |
||||||
|
$this->manifestID = $id; |
||||||
|
} |
||||||
|
|
||||||
|
public function getBase() |
||||||
|
{ |
||||||
|
return $this->base; |
||||||
|
} |
||||||
|
|
||||||
|
public function setBase($baseval) |
||||||
|
{ |
||||||
|
$this->base = $baseval; |
||||||
|
} |
||||||
|
|
||||||
|
public function importResources(DOMElement &$node, CcIManifest &$doc) |
||||||
|
{ |
||||||
|
if (is_null($this->resources)) { |
||||||
|
$this->resources = []; |
||||||
|
} |
||||||
|
$nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'], 'resource'); |
||||||
|
if (is_object($nlist)) { |
||||||
|
foreach ($nlist as $nd) { |
||||||
|
$sc = new CcResource($doc, $nd); |
||||||
|
$this->resources[$sc->identifier] = $sc; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function importOrganizationItems(DOMElement &$node, CcIManifest &$doc) |
||||||
|
{ |
||||||
|
if (is_null($this->organizations)) { |
||||||
|
$this->organizations = []; |
||||||
|
} |
||||||
|
$nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'], 'organization'); |
||||||
|
if (is_object($nlist)) { |
||||||
|
foreach ($nlist as $nd) { |
||||||
|
$sc = new CcOrganization($nd, $doc); |
||||||
|
$this->organizations[$sc->identifier] = $sc; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function setGenerator($value) |
||||||
|
{ |
||||||
|
$this->_generator = $value; |
||||||
|
} |
||||||
|
|
||||||
|
abstract protected function onCreate(DOMDocument &$doc, $rootmanifestnode = null, $nmanifestID = null); |
||||||
|
|
||||||
|
abstract protected function createMetadataManifest(CcIMetadataManifest $met, DOMDocument &$doc, $xmlnode = null); |
||||||
|
|
||||||
|
abstract protected function createMetadataResource(CcIMetadataResource $met, DOMDocument &$doc, $xmlnode = null); |
||||||
|
|
||||||
|
abstract protected function createMetadataFile(CcIMetadataFile $met, DOMDocument &$doc, $xmlnode = null); |
||||||
|
|
||||||
|
abstract protected function createResource(CcIResource &$res, DOMDocument &$doc, $xmlnode = null); |
||||||
|
|
||||||
|
abstract protected function createOrganization(CcIOrganization &$org, DOMDocument &$doc, $xmlnode = null); |
||||||
|
} |
||||||
@ -0,0 +1,269 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/gral_lib/cssparser.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CssParser |
||||||
|
{ |
||||||
|
private $css; |
||||||
|
private $html; |
||||||
|
|
||||||
|
public function __construct($html = true) |
||||||
|
{ |
||||||
|
$this->html = ($html != false); |
||||||
|
$this->clear(); |
||||||
|
} |
||||||
|
|
||||||
|
public function clear() |
||||||
|
{ |
||||||
|
unset($this->css); |
||||||
|
$this->css = []; |
||||||
|
if ($this->html) { |
||||||
|
$this->add("ADDRESS", ""); |
||||||
|
$this->add("APPLET", ""); |
||||||
|
$this->add("AREA", ""); |
||||||
|
$this->add("A", "text-decoration : underline; color : Blue;"); |
||||||
|
$this->add("A:visited", "color : Purple;"); |
||||||
|
$this->add("BASE", ""); |
||||||
|
$this->add("BASEFONT", ""); |
||||||
|
$this->add("BIG", ""); |
||||||
|
$this->add("BLOCKQUOTE", ""); |
||||||
|
$this->add("BODY", ""); |
||||||
|
$this->add("BR", ""); |
||||||
|
$this->add("B", "font-weight: bold;"); |
||||||
|
$this->add("CAPTION", ""); |
||||||
|
$this->add("CENTER", ""); |
||||||
|
$this->add("CITE", ""); |
||||||
|
$this->add("CODE", ""); |
||||||
|
$this->add("DD", ""); |
||||||
|
$this->add("DFN", ""); |
||||||
|
$this->add("DIR", ""); |
||||||
|
$this->add("DIV", ""); |
||||||
|
$this->add("DL", ""); |
||||||
|
$this->add("DT", ""); |
||||||
|
$this->add("EM", ""); |
||||||
|
$this->add("FONT", ""); |
||||||
|
$this->add("FORM", ""); |
||||||
|
$this->add("H1", ""); |
||||||
|
$this->add("H2", ""); |
||||||
|
$this->add("H3", ""); |
||||||
|
$this->add("H4", ""); |
||||||
|
$this->add("H5", ""); |
||||||
|
$this->add("H6", ""); |
||||||
|
$this->add("HEAD", ""); |
||||||
|
$this->add("HR", ""); |
||||||
|
$this->add("HTML", ""); |
||||||
|
$this->add("IMG", ""); |
||||||
|
$this->add("INPUT", ""); |
||||||
|
$this->add("ISINDEX", ""); |
||||||
|
$this->add("I", "font-style: italic;"); |
||||||
|
$this->add("KBD", ""); |
||||||
|
$this->add("LINK", ""); |
||||||
|
$this->add("LI", ""); |
||||||
|
$this->add("MAP", ""); |
||||||
|
$this->add("MENU", ""); |
||||||
|
$this->add("META", ""); |
||||||
|
$this->add("OL", ""); |
||||||
|
$this->add("OPTION", ""); |
||||||
|
$this->add("PARAM", ""); |
||||||
|
$this->add("PRE", ""); |
||||||
|
$this->add("P", ""); |
||||||
|
$this->add("SAMP", ""); |
||||||
|
$this->add("SCRIPT", ""); |
||||||
|
$this->add("SELECT", ""); |
||||||
|
$this->add("SMALL", ""); |
||||||
|
$this->add("STRIKE", ""); |
||||||
|
$this->add("STRONG", ""); |
||||||
|
$this->add("STYLE", ""); |
||||||
|
$this->add("SUB", ""); |
||||||
|
$this->add("SUP", ""); |
||||||
|
$this->add("TABLE", ""); |
||||||
|
$this->add("TD", ""); |
||||||
|
$this->add("TEXTAREA", ""); |
||||||
|
$this->add("TH", ""); |
||||||
|
$this->add("TITLE", ""); |
||||||
|
$this->add("TR", ""); |
||||||
|
$this->add("TT", ""); |
||||||
|
$this->add("UL", ""); |
||||||
|
$this->add("U", "text-decoration : underline;"); |
||||||
|
$this->add("VAR", ""); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function setHTML($html) |
||||||
|
{ |
||||||
|
$this->html = ($html != false); |
||||||
|
} |
||||||
|
|
||||||
|
public function add($key, $codestr) |
||||||
|
{ |
||||||
|
$key = strtolower($key); |
||||||
|
$codestr = strtolower($codestr); |
||||||
|
if (!isset($this->css[$key])) { |
||||||
|
$this->css[$key] = []; |
||||||
|
} |
||||||
|
$codes = explode(";", $codestr); |
||||||
|
if (count($codes) > 0) { |
||||||
|
$codekey = ''; |
||||||
|
$codevalue = ''; |
||||||
|
foreach ($codes as $code) { |
||||||
|
$code = trim($code); |
||||||
|
$this->assignValues(explode(":", $code), $codekey, $codevalue); |
||||||
|
if (strlen($codekey) > 0) { |
||||||
|
$this->css[$key][trim($codekey)] = trim($codevalue); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function get($key, $property) |
||||||
|
{ |
||||||
|
$key = strtolower($key); |
||||||
|
$property = strtolower($property); |
||||||
|
$tag = ''; |
||||||
|
$subtag = ''; |
||||||
|
$class = ''; |
||||||
|
$id = ''; |
||||||
|
$this->assignValues(explode(":", $key), $tag, $subtag); |
||||||
|
$this->assignValues(explode(".", $tag), $tag, $class); |
||||||
|
$this->assignValues(explode("#", $tag), $tag, $id); |
||||||
|
$result = ""; |
||||||
|
$_subtag = ''; |
||||||
|
$_class = ''; |
||||||
|
$_id = ''; |
||||||
|
foreach ($this->css as $_tag => $value) { |
||||||
|
$this->assignValues(explode(":", $_tag), $_tag, $_subtag); |
||||||
|
$this->assignValues(explode(".", $_tag), $_tag, $_class); |
||||||
|
$this->assignValues(explode("#", $_tag), $_tag, $_id); |
||||||
|
|
||||||
|
$tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0); |
||||||
|
$subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0); |
||||||
|
$classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0); |
||||||
|
$idmatch = (strcmp($id, $_id) == 0); |
||||||
|
|
||||||
|
if ($tagmatch & $subtagmatch & $classmatch & $idmatch) { |
||||||
|
$temp = $_tag; |
||||||
|
if ((strlen($temp) > 0) & (strlen($_class) > 0)) { |
||||||
|
$temp .= ".".$_class; |
||||||
|
} elseif (strlen($temp) == 0) { |
||||||
|
$temp = ".".$_class; |
||||||
|
} |
||||||
|
if ((strlen($temp) > 0) & (strlen($_subtag) > 0)) { |
||||||
|
$temp .= ":".$_subtag; |
||||||
|
} elseif (strlen($temp) == 0) { |
||||||
|
$temp = ":".$_subtag; |
||||||
|
} |
||||||
|
if (isset($this->css[$temp][$property])) { |
||||||
|
$result = $this->css[$temp][$property]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function getSection($key) |
||||||
|
{ |
||||||
|
$key = strtolower($key); |
||||||
|
$tag = ''; |
||||||
|
$subtag = ''; |
||||||
|
$class = ''; |
||||||
|
$id = ''; |
||||||
|
$_subtag = ''; |
||||||
|
$_class = ''; |
||||||
|
$_id = ''; |
||||||
|
|
||||||
|
$this->assignValues(explode(":", $key), $tag, $subtag); |
||||||
|
$this->assignValues(explode(".", $tag), $tag, $class); |
||||||
|
$this->assignValues(explode("#", $tag), $tag, $id); |
||||||
|
$result = []; |
||||||
|
foreach ($this->css as $_tag => $value) { |
||||||
|
$this->assignValues(explode(":", $_tag), $_tag, $_subtag); |
||||||
|
$this->assignValues(explode(".", $_tag), $_tag, $_class); |
||||||
|
$this->assignValues(explode("#", $_tag), $_tag, $_id); |
||||||
|
|
||||||
|
$tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0); |
||||||
|
$subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0); |
||||||
|
$classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0); |
||||||
|
$idmatch = (strcmp($id, $_id) == 0); |
||||||
|
|
||||||
|
if ($tagmatch & $subtagmatch & $classmatch & $idmatch) { |
||||||
|
$temp = $_tag; |
||||||
|
if ((strlen($temp) > 0) & (strlen($_class) > 0)) { |
||||||
|
$temp .= ".".$_class; |
||||||
|
} elseif (strlen($temp) == 0) { |
||||||
|
$temp = ".".$_class; |
||||||
|
} |
||||||
|
if ((strlen($temp) > 0) & (strlen($_subtag) > 0)) { |
||||||
|
$temp .= ":".$_subtag; |
||||||
|
} elseif (strlen($temp) == 0) { |
||||||
|
$temp = ":".$_subtag; |
||||||
|
} |
||||||
|
foreach ($this->css[$temp] as $property => $value) { |
||||||
|
$result[$property] = $value; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function parseStr($str) |
||||||
|
{ |
||||||
|
$this->clear(); |
||||||
|
// Remove comments |
||||||
|
$str = preg_replace("/\/\*(.*)?\*\//Usi", "", $str); |
||||||
|
// Parse this damn csscode |
||||||
|
$parts = explode("}", $str); |
||||||
|
if (count($parts) > 0) { |
||||||
|
foreach ($parts as $part) { |
||||||
|
$keystr = ''; |
||||||
|
$codestr = ''; |
||||||
|
$this->assignValues(explode("{", $part), $keystr, $codestr); |
||||||
|
$keys = explode(",", trim($keystr)); |
||||||
|
if (count($keys) > 0) { |
||||||
|
foreach ($keys as $key) { |
||||||
|
if (strlen($key) > 0) { |
||||||
|
$key = str_replace("\n", "", $key); |
||||||
|
$key = str_replace("\\", "", $key); |
||||||
|
$this->Add($key, trim($codestr)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return count($this->css) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
public function parse($filename) |
||||||
|
{ |
||||||
|
$this->clear(); |
||||||
|
if (file_exists($filename)) { |
||||||
|
return $this->parseStr(file_get_contents($filename)); |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function getCSS() |
||||||
|
{ |
||||||
|
$result = ""; |
||||||
|
foreach ($this->css as $key => $values) { |
||||||
|
$result .= $key." {\n"; |
||||||
|
foreach ($values as $key => $value) { |
||||||
|
$result .= " $key: $value;\n"; |
||||||
|
} |
||||||
|
$result .= "}\n\n"; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
private function assignValues($arr, &$val1, &$val2) |
||||||
|
{ |
||||||
|
$n = count($arr); |
||||||
|
if ($n > 0) { |
||||||
|
$val1 = $arr[0]; |
||||||
|
$val2 = ($n > 1) ? $arr[1] : ''; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,470 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/xmlbase.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Base XML class. |
||||||
|
*/ |
||||||
|
class XMLGenericDocument |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Document. |
||||||
|
* |
||||||
|
* @var DOMDocument |
||||||
|
*/ |
||||||
|
public $doc = null; |
||||||
|
/** |
||||||
|
* Xpath. |
||||||
|
* |
||||||
|
* @var DOMXPath |
||||||
|
*/ |
||||||
|
protected $dxpath = null; |
||||||
|
protected $filename; |
||||||
|
private $charset; |
||||||
|
private $filepath; |
||||||
|
private $isloaded = false; |
||||||
|
private $arrayPrefixNS = []; |
||||||
|
private $isHtml = false; |
||||||
|
|
||||||
|
public function __construct($ch = 'UTF-8', $validatenow = true) |
||||||
|
{ |
||||||
|
$this->charset = $ch; |
||||||
|
$this->documentInit(); |
||||||
|
$this->doc->validateOnParse = $validatenow; |
||||||
|
} |
||||||
|
|
||||||
|
public function __destruct() |
||||||
|
{ |
||||||
|
$this->dxpath = null; |
||||||
|
$this->doc = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public static function safexml($value) |
||||||
|
{ |
||||||
|
$result = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), |
||||||
|
ENT_NOQUOTES, |
||||||
|
'UTF-8', |
||||||
|
false); |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function viewXML() |
||||||
|
{ |
||||||
|
return $this->doc->saveXML(); |
||||||
|
} |
||||||
|
|
||||||
|
public function registerNS($prefix, $nsuri) |
||||||
|
{ |
||||||
|
$this->arrayPrefixNS[$prefix] = $nsuri; |
||||||
|
} |
||||||
|
|
||||||
|
public function load($fname) |
||||||
|
{ |
||||||
|
// Sine xml will remain loaded should the repeated load fail we should recreate document to be empty. |
||||||
|
$this->documentInit(false); |
||||||
|
$this->isloaded = $this->doc->load($fname); |
||||||
|
if ($this->isloaded) { |
||||||
|
$this->filename = $fname; |
||||||
|
$this->processPath(); |
||||||
|
$this->isHtml = false; |
||||||
|
} |
||||||
|
|
||||||
|
return $this->onLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
public function loadUrl($url) |
||||||
|
{ |
||||||
|
$this->documentInit(); |
||||||
|
$this->isloaded = true; |
||||||
|
$this->doc->loadXML(file_get_contents($url)); |
||||||
|
$this->isHtml = false; |
||||||
|
|
||||||
|
return $this->onLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
public function loadHTML($content) |
||||||
|
{ |
||||||
|
$this->documentInit(); |
||||||
|
$this->doc->validateOnParse = false; |
||||||
|
$this->isloaded = true; |
||||||
|
$this->doc->loadHTML($content); |
||||||
|
$this->isHtml = true; |
||||||
|
|
||||||
|
return $this->onLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
public function loadXML($content) |
||||||
|
{ |
||||||
|
$this->documentInit(); |
||||||
|
$this->doc->validateOnParse = false; |
||||||
|
$this->isloaded = true; |
||||||
|
$this->doc->load($content); |
||||||
|
$this->isHtml = true; |
||||||
|
|
||||||
|
return $this->onLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
public function loadHTMLFile($fname) |
||||||
|
{ |
||||||
|
// Sine xml will remain loaded should the repeated load fail |
||||||
|
// we should recreate document to be empty. |
||||||
|
$this->documentInit(); |
||||||
|
$this->doc->validateOnParse = false; |
||||||
|
$this->isloaded = $this->doc->loadHTMLFile($fname); |
||||||
|
if ($this->isloaded) { |
||||||
|
$this->filename = $fname; |
||||||
|
$this->processPath(); |
||||||
|
$this->isHtml = true; |
||||||
|
} |
||||||
|
|
||||||
|
return $this->onLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
public function loadXMLFile($fname) |
||||||
|
{ |
||||||
|
// Sine xml will remain loaded should the repeated load fail |
||||||
|
// we should recreate document to be empty. |
||||||
|
$this->documentInit(); |
||||||
|
$this->doc->validateOnParse = false; |
||||||
|
$this->isloaded = $this->doc->load($fname); |
||||||
|
if ($this->isloaded) { |
||||||
|
$this->filename = $fname; |
||||||
|
$this->processPath(); |
||||||
|
$this->isHtml = true; |
||||||
|
} |
||||||
|
|
||||||
|
return $this->onLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
public function loadString($content) |
||||||
|
{ |
||||||
|
$this->doc = new DOMDocument("1.0", $this->charset); |
||||||
|
$content = '<virtualtag>'.$content.'</virtualtag>'; |
||||||
|
$this->doc->loadXML($content); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public function save() |
||||||
|
{ |
||||||
|
$this->saveTo($this->filename); |
||||||
|
} |
||||||
|
|
||||||
|
public function saveTo($fname) |
||||||
|
{ |
||||||
|
$status = false; |
||||||
|
if ($this->onSave()) { |
||||||
|
if ($this->isHtml) { |
||||||
|
$this->doc->saveHTMLFile($fname); |
||||||
|
} else { |
||||||
|
$this->doc->save($fname); |
||||||
|
} |
||||||
|
$this->filename = $fname; |
||||||
|
$this->processPath(); |
||||||
|
$status = true; |
||||||
|
} |
||||||
|
|
||||||
|
return $status; |
||||||
|
} |
||||||
|
|
||||||
|
public function validate() |
||||||
|
{ |
||||||
|
return $this->doc->validate(); |
||||||
|
} |
||||||
|
|
||||||
|
public function attributeValue($path, $attrname, $node = null) |
||||||
|
{ |
||||||
|
$this->chkxpath(); |
||||||
|
$result = null; |
||||||
|
$resultlist = null; |
||||||
|
if (is_null($node)) { |
||||||
|
$resultlist = $this->dxpath->query($path); |
||||||
|
} else { |
||||||
|
$resultlist = $this->dxpath->query($path, $node); |
||||||
|
} |
||||||
|
if (is_object($resultlist) && ($resultlist->length > 0) && $resultlist->item(0)->hasAttribute($attrname)) { |
||||||
|
$result = $resultlist->item(0)->getAttribute($attrname); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get's text value of the node based on xpath query. |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
* @param DOMNode $node |
||||||
|
* @param int $count |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function nodeValue($path, $node = null, $count = 1) |
||||||
|
{ |
||||||
|
$nd = $this->node($path, $node, $count); |
||||||
|
|
||||||
|
return $this->nodeTextValue($nd); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get's text value of the node. |
||||||
|
* |
||||||
|
* @param DOMNode $node |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function nodeTextValue($node) |
||||||
|
{ |
||||||
|
$result = ''; |
||||||
|
if (is_object($node)) { |
||||||
|
if ($node->hasChildNodes()) { |
||||||
|
$chnodesList = $node->childNodes; |
||||||
|
$types = [XML_TEXT_NODE, XML_CDATA_SECTION_NODE]; |
||||||
|
foreach ($chnodesList as $chnode) { |
||||||
|
if (in_array($chnode->nodeType, $types)) { |
||||||
|
$result .= $chnode->wholeText; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the nodes from a path |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
* @param DOMNode $nd |
||||||
|
* @param int $count |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function node($path, $nd = null, $count = 1) |
||||||
|
{ |
||||||
|
$result = null; |
||||||
|
$resultlist = $this->nodeList($path, $nd); |
||||||
|
if (is_object($resultlist) && ($resultlist->length > 0)) { |
||||||
|
$result = $resultlist->item($count - 1); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get a list of nodes from a path |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
* @param DOMNode $node |
||||||
|
* |
||||||
|
* @return DOMNodeList |
||||||
|
*/ |
||||||
|
public function nodeList($path, $node = null) |
||||||
|
{ |
||||||
|
$this->chkxpath(); |
||||||
|
$resultlist = null; |
||||||
|
if (is_null($node)) { |
||||||
|
$resultlist = $this->dxpath->query($path); |
||||||
|
} else { |
||||||
|
$resultlist = $this->dxpath->query($path, $node); |
||||||
|
} |
||||||
|
|
||||||
|
return $resultlist; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create new attribute. |
||||||
|
* |
||||||
|
* @param string $namespace |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return DOMAttr |
||||||
|
*/ |
||||||
|
public function createAttributeNs($namespace, $name, $value = null) |
||||||
|
{ |
||||||
|
$result = $this->doc->createAttributeNS($namespace, $name); |
||||||
|
if (!is_null($value)) { |
||||||
|
$result->nodeValue = $value; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create new attribute. |
||||||
|
* |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return DOMAttr |
||||||
|
*/ |
||||||
|
public function createAttribute($name, $value = null) |
||||||
|
{ |
||||||
|
$result = $this->doc->createAttribute($name); |
||||||
|
if (!is_null($value)) { |
||||||
|
$result->nodeValue = $value; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds new node. |
||||||
|
* |
||||||
|
* @param string $namespace |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function appendNewElementNs(DOMNode &$parentnode, $namespace, $name, $value = null) |
||||||
|
{ |
||||||
|
$newnode = null; |
||||||
|
if (is_null($value)) { |
||||||
|
$newnode = $this->doc->createElementNS($namespace, $name); |
||||||
|
} else { |
||||||
|
$newnode = $this->doc->createElementNS($namespace, $name, $value); |
||||||
|
} |
||||||
|
|
||||||
|
return $parentnode->appendChild($newnode); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* New node with CDATA content. |
||||||
|
* |
||||||
|
* @param string $namespace |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
*/ |
||||||
|
public function appendNewElementNsCdata(DOMNode &$parentnode, $namespace, $name, $value = null) |
||||||
|
{ |
||||||
|
$newnode = $this->doc->createElementNS($namespace, $name); |
||||||
|
if (!is_null($value)) { |
||||||
|
$cdata = $this->doc->createCDATASection($value); |
||||||
|
$newnode->appendChild($cdata); |
||||||
|
} |
||||||
|
|
||||||
|
return $parentnode->appendChild($newnode); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds new node. |
||||||
|
* |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function appendNewElement(DOMNode &$parentnode, $name, $value = null) |
||||||
|
{ |
||||||
|
$newnode = null; |
||||||
|
if (is_null($value)) { |
||||||
|
$newnode = $this->doc->createElement($name); |
||||||
|
} else { |
||||||
|
$newnode = $this->doc->createElement($name, $value); |
||||||
|
} |
||||||
|
|
||||||
|
return $parentnode->appendChild($newnode); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds new attribute. |
||||||
|
* |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function appendNewAttribute(DOMNode &$node, $name, $value = null) |
||||||
|
{ |
||||||
|
return $node->appendChild($this->createAttribute($name, $value)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds new attribute. |
||||||
|
* |
||||||
|
* @param string $namespace |
||||||
|
* @param string $name |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return DOMNode |
||||||
|
*/ |
||||||
|
public function appendNewAttributeNs(DOMNode &$node, $namespace, $name, $value = null) |
||||||
|
{ |
||||||
|
return $node->appendChild($this->createAttributeNs($namespace, $name, $value)); |
||||||
|
} |
||||||
|
|
||||||
|
public function fileName() |
||||||
|
{ |
||||||
|
return $this->filename; |
||||||
|
} |
||||||
|
|
||||||
|
public function filePath() |
||||||
|
{ |
||||||
|
return $this->filepath; |
||||||
|
} |
||||||
|
|
||||||
|
public function resetXpath() |
||||||
|
{ |
||||||
|
$this->dxpath = null; |
||||||
|
$this->chkxpath(); |
||||||
|
} |
||||||
|
|
||||||
|
protected function onLoad() |
||||||
|
{ |
||||||
|
return $this->isloaded; |
||||||
|
} |
||||||
|
|
||||||
|
protected function onSave() |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected function onCreate() |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected function processPath() |
||||||
|
{ |
||||||
|
$path_parts = pathinfo($this->filename); |
||||||
|
$this->filepath = array_key_exists('dirname', $path_parts) ? $path_parts['dirname']."/" : ''; |
||||||
|
} |
||||||
|
|
||||||
|
private function documentInit($withonCreate = true) |
||||||
|
{ |
||||||
|
$hg = false; |
||||||
|
if ($this->isloaded) { |
||||||
|
$guardstate = $this->doc->validateOnParse; |
||||||
|
$hg = true; |
||||||
|
unset($this->dxpath); |
||||||
|
unset($this->doc); |
||||||
|
$this->isloaded = false; |
||||||
|
} |
||||||
|
$this->doc = new DOMDocument("1.0", $this->charset); |
||||||
|
$this->doc->strictErrorChecking = true; |
||||||
|
if ($hg) { |
||||||
|
$this->doc->validateOnParse = $guardstate; |
||||||
|
} |
||||||
|
$this->doc->formatOutput = true; |
||||||
|
$this->doc->preserveWhiteSpace = true; |
||||||
|
if ($withonCreate) { |
||||||
|
$this->onCreate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function chkxpath() |
||||||
|
{ |
||||||
|
if (!isset($this->dxpath) || is_null($this->dxpath)) { |
||||||
|
$this->dxpath = new DOMXPath($this->doc); |
||||||
|
foreach ($this->arrayPrefixNS as $nskey => $nsuri) { |
||||||
|
$this->dxpath->registerNamespace($nskey, $nsuri); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,37 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converter_folder.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcConverterFolder extends CcConverters |
||||||
|
{ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$this->defaultfile = 'folder.xml'; |
||||||
|
parent::__construct($item, $manifest, $rootpath, $path); |
||||||
|
} |
||||||
|
|
||||||
|
public function convert($outdir, $objDocument) |
||||||
|
{ |
||||||
|
$contextid = $objDocument['source_id']; |
||||||
|
$folder = api_get_path(SYS_COURSE_PATH).api_get_course_path($objDocument['course_code']).'/'.$objDocument['path']; |
||||||
|
$files = CcHelpers::handleStaticContent($this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$contextid, |
||||||
|
$outdir, |
||||||
|
true, |
||||||
|
$folder |
||||||
|
); |
||||||
|
$resvalue = null; |
||||||
|
foreach ($files as $values) { |
||||||
|
if ($values[2]) { |
||||||
|
$resvalue = $values[0]; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
$resitem = new CcItem(); |
||||||
|
$resitem->identifierref = $resvalue; |
||||||
|
$resitem->title = $objDocument['title']; |
||||||
|
$this->item->addChildItem($resitem); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converter_forum.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcConverterForum extends CcConverters |
||||||
|
{ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$this->ccType = CcVersion13::DISCUSSIONTOPIC; |
||||||
|
$this->defaultfile = 'forum.xml'; |
||||||
|
$this->defaultname = 'discussion.xml'; |
||||||
|
parent::__construct($item, $manifest, $rootpath, $path); |
||||||
|
} |
||||||
|
|
||||||
|
public function convert($outdir, $item) |
||||||
|
{ |
||||||
|
$rt = new CcForum(); |
||||||
|
$title = $item['title']; |
||||||
|
$rt->setTitle($title); |
||||||
|
$text = $item['comment']; |
||||||
|
$deps = null; |
||||||
|
if (!empty($text)) { |
||||||
|
$contextid = $item['source_id']; |
||||||
|
$result = CcHelpers::processLinkedFiles($text, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$contextid, |
||||||
|
$outdir); |
||||||
|
$textformat = 'text/html'; |
||||||
|
$rt->setText($result[0], $textformat); |
||||||
|
$deps = $result[1]; |
||||||
|
} |
||||||
|
$this->store($rt, $outdir, $title, $deps); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converter_page.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcConverterPage extends CcConverters |
||||||
|
{ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$this->ccType = CcVersion13::WEBCONTENT; |
||||||
|
$this->defaultfile = 'page.xml'; |
||||||
|
$this->defaultname = uniqid().'.html'; |
||||||
|
parent::__construct($item, $manifest, $rootpath, $path); |
||||||
|
} |
||||||
|
|
||||||
|
public function convert($outdir, $objPage) |
||||||
|
{ |
||||||
|
$rt = new CcPage(); |
||||||
|
$title = $objPage['title']; |
||||||
|
$intro = ''; |
||||||
|
$contextid = $objPage['source_id']; |
||||||
|
$pagecontent = $objPage['comment']; |
||||||
|
$rt->setTitle($title); |
||||||
|
$rawname = str_replace(' ', '_', strtolower(trim(Security::filter_filename($title)))); |
||||||
|
|
||||||
|
if (!empty($rawname)) { |
||||||
|
$this->defaultname = $rawname.".html"; |
||||||
|
} |
||||||
|
|
||||||
|
$result = CcHelpers::processLinkedFiles($pagecontent, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$contextid, |
||||||
|
$outdir, |
||||||
|
true); |
||||||
|
$rt->setContent($result[0]); |
||||||
|
$rt->setIntro($intro); |
||||||
|
//store everything |
||||||
|
$this->store($rt, $outdir, $title, $result[1]); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,80 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converter_quiz.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcConverterQuiz extends CcConverters |
||||||
|
{ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$this->ccType = CcVersion13::ASSESSMENT; |
||||||
|
$this->defaultfile = 'quiz.xml'; |
||||||
|
$this->defaultname = Assesment13ResourceFile::DEAFULTNAME; |
||||||
|
parent::__construct($item, $manifest, $rootpath, $path); |
||||||
|
} |
||||||
|
|
||||||
|
public function convert($outdir, $objQuizz) |
||||||
|
{ |
||||||
|
$rt = new Assesment13ResourceFile(); |
||||||
|
$title = $objQuizz['title']; |
||||||
|
$rt->setTitle($title); |
||||||
|
|
||||||
|
// Metadata. |
||||||
|
$metadata = new CcAssesmentMetadata(); |
||||||
|
$rt->setMetadata($metadata); |
||||||
|
$metadata->enableFeedback(); |
||||||
|
$metadata->enableHints(); |
||||||
|
$metadata->enableSolutions(); |
||||||
|
// Attempts. |
||||||
|
$maxAttempts = $objQuizz['max_attempt']; |
||||||
|
|
||||||
|
if ($maxAttempts > 0) { |
||||||
|
// Qti does not support number of specific attempts bigger than 5 (??) |
||||||
|
if ($maxAttempts > 5) { |
||||||
|
$maxAttempts = CcQtiValues::unlimited; |
||||||
|
} |
||||||
|
$metadata->setMaxattempts($maxAttempts); |
||||||
|
} |
||||||
|
|
||||||
|
// Time limit must be converted into minutes. |
||||||
|
$timelimit = $objQuizz['expired_time']; |
||||||
|
|
||||||
|
if ($timelimit > 0) { |
||||||
|
$metadata->setTimelimit($timelimit); |
||||||
|
$metadata->enableLatesubmissions(false); |
||||||
|
} |
||||||
|
|
||||||
|
$contextid = $objQuizz['source_id']; |
||||||
|
|
||||||
|
$result = CcHelpers::processLinkedFiles($objQuizz['comment'], |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$contextid, |
||||||
|
$outdir); |
||||||
|
|
||||||
|
CcAssesmentHelper::addAssesmentDescription($rt, $result[0], CcQtiValues::HTMLTYPE); |
||||||
|
|
||||||
|
// Section. |
||||||
|
$section = new CcAssesmentSection(); |
||||||
|
$rt->setSection($section); |
||||||
|
// Process the actual questions. |
||||||
|
$ndeps = CcAssesmentHelper::processQuestions($objQuizz, |
||||||
|
$this->manifest, |
||||||
|
$section, |
||||||
|
$this->rootpath, |
||||||
|
$contextid, |
||||||
|
$outdir |
||||||
|
); |
||||||
|
|
||||||
|
if ($ndeps === false) { |
||||||
|
// No exportable questions in quiz or quiz has no questions |
||||||
|
// so just skip it. |
||||||
|
return true; |
||||||
|
} |
||||||
|
// Store any additional dependencies. |
||||||
|
$deps = array_merge($result[1], $ndeps); |
||||||
|
|
||||||
|
// Store everything. |
||||||
|
$this->store($rt, $outdir, $title, $deps); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,48 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converter_resource.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcConverterResource extends CcConverters |
||||||
|
{ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$this->ccType = CcVersion13::WEBCONTENT; |
||||||
|
$this->defaultfile = 'resource.xml'; |
||||||
|
parent::__construct($item, $manifest, $rootpath, $path); |
||||||
|
} |
||||||
|
|
||||||
|
public function convert($outdir, $objResource) |
||||||
|
{ |
||||||
|
$title = $objResource['title']; |
||||||
|
$contextid = $objResource['source_id']; |
||||||
|
$docfilepath = null; |
||||||
|
if (isset($objResource['path'])) { |
||||||
|
$docfilepath = api_get_path(SYS_COURSE_PATH).api_get_course_path($objResource['course_code']).DIRECTORY_SEPARATOR.$objResource['path']; |
||||||
|
} |
||||||
|
|
||||||
|
$files = CcHelpers::handleResourceContent($this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$contextid, |
||||||
|
$outdir, |
||||||
|
true, |
||||||
|
$docfilepath); |
||||||
|
|
||||||
|
$deps = null; |
||||||
|
$resvalue = null; |
||||||
|
foreach ($files as $values) { |
||||||
|
if ($values[2]) { |
||||||
|
$resvalue = $values[0]; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$resitem = new CcItem(); |
||||||
|
$resitem->identifierref = $resvalue; |
||||||
|
$resitem->title = $title; |
||||||
|
$this->item->addChildItem($resitem); |
||||||
|
|
||||||
|
// Checking the visibility. |
||||||
|
$this->manifest->updateInstructoronly($resvalue, !$this->isVisible()); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_converter_url.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcConverterUrl extends CcConverters |
||||||
|
{ |
||||||
|
public function __construct(CcIItem &$item, CcIManifest &$manifest, $rootpath, $path) |
||||||
|
{ |
||||||
|
$this->ccType = CcVersion13::WEBLINK; |
||||||
|
$this->defaultfile = 'url.xml'; |
||||||
|
$this->defaultname = 'weblink.xml'; |
||||||
|
parent::__construct($item, $manifest, $rootpath, $path); |
||||||
|
} |
||||||
|
|
||||||
|
public function convert($outdir, $objLink) |
||||||
|
{ |
||||||
|
$rt = new CcWebLink(); |
||||||
|
$title = $objLink['title']; |
||||||
|
$rt->setTitle($title); |
||||||
|
$url = $objLink['url']; |
||||||
|
if (!empty($url)) { |
||||||
|
$rt->setUrl($url, $objLink['target']); |
||||||
|
} |
||||||
|
$this->store($rt, $outdir, $title); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Item Interface. |
||||||
|
*/ |
||||||
|
interface CcIItem |
||||||
|
{ |
||||||
|
public function addChildItem(CcIItem &$item); |
||||||
|
|
||||||
|
public function attachResource($res); // can be object or value |
||||||
|
|
||||||
|
public function hasChildItems(); |
||||||
|
|
||||||
|
public function attrValue(&$nod, $name, $ns = null); |
||||||
|
|
||||||
|
public function processItem(&$node, &$doc); |
||||||
|
} |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Manifest Interface. |
||||||
|
*/ |
||||||
|
interface CcIManifest |
||||||
|
{ |
||||||
|
public function onCreate(); |
||||||
|
|
||||||
|
public function onLoad(); |
||||||
|
|
||||||
|
public function onSave(); |
||||||
|
|
||||||
|
public function addNewOrganization(CcIOrganization &$org); |
||||||
|
|
||||||
|
public function getResources(); |
||||||
|
|
||||||
|
public function getResourceList(); |
||||||
|
|
||||||
|
public function addResource(CcIResource $res, $identifier = null, $type = 'webcontent'); |
||||||
|
|
||||||
|
public function addMetadataManifest(CcIMetadataManifest $met); |
||||||
|
|
||||||
|
public function addMetadataResource(CcIMetadataResource $met, $identifier); |
||||||
|
|
||||||
|
public function addMetadataFile(CcIMetadataFile $met, $identifier, $filename); |
||||||
|
|
||||||
|
public function putNodes(); |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Metadata File Interface. |
||||||
|
*/ |
||||||
|
interface CcIMetadataFile |
||||||
|
{ |
||||||
|
public function addMetadataFileEducational($obj); |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Metadata Manifest Interface. |
||||||
|
*/ |
||||||
|
interface CcIMetadataManifest |
||||||
|
{ |
||||||
|
public function addMetadataGeneral($obj); |
||||||
|
|
||||||
|
public function addMetadataTechnical($obj); |
||||||
|
|
||||||
|
public function addMetadataRights($obj); |
||||||
|
|
||||||
|
public function addMetadataLifecycle($obj); |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Metadata Resource Interface. |
||||||
|
*/ |
||||||
|
interface CcIMetadataResource |
||||||
|
{ |
||||||
|
public function addMetadataResourceEducational($obj); |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Organization Interface. |
||||||
|
*/ |
||||||
|
interface CcIOrganization |
||||||
|
{ |
||||||
|
public function addItem(CcIItem &$item); |
||||||
|
|
||||||
|
public function hasItems(); |
||||||
|
|
||||||
|
public function attrValue(&$nod, $name, $ns = null); |
||||||
|
|
||||||
|
public function processOrganization(&$node, &$doc); |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
/** |
||||||
|
* CC Resource Interface. |
||||||
|
*/ |
||||||
|
interface CcIResource |
||||||
|
{ |
||||||
|
public function getAttrValue(&$nod, $name, $ns = null); |
||||||
|
|
||||||
|
public function addResource($fname, $location = ''); |
||||||
|
|
||||||
|
public function importResource(DOMElement &$node, CcIManifest &$doc); |
||||||
|
|
||||||
|
public function processResource($manifestroot, &$fname, $folder); |
||||||
|
} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class Assesment13ResourceFile extends Assesment1ResourceFile |
||||||
|
{ |
||||||
|
protected $ccnsnames = ['xmlns' => 'http://www.imsglobal.org/profile/cc/ccv1p3/ccv1p3_qtiasiv1p2p1_v1p0.xsd']; |
||||||
|
} |
||||||
@ -0,0 +1,74 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class Assesment1ResourceFile extends CcGeneralFile |
||||||
|
{ |
||||||
|
const DEAFULTNAME = 'assesment.xml'; |
||||||
|
|
||||||
|
protected $rootns = 'xmlns'; |
||||||
|
protected $rootname = CcQtiTags::QUESTESTINTEROP; |
||||||
|
protected $ccnamespaces = ['xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2', |
||||||
|
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', ]; |
||||||
|
protected $ccnsnames = ['xmlns' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_4/ims_qtiasiv1p2_localised.xsd']; |
||||||
|
protected $assessmentTitle = 'Untitled'; |
||||||
|
protected $metadata = null; |
||||||
|
protected $rubric = null; |
||||||
|
protected $presentationMaterial = null; |
||||||
|
protected $section = null; |
||||||
|
|
||||||
|
public function setMetadata(CcAssesmentMetadata $object) |
||||||
|
{ |
||||||
|
$this->metadata = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setRubric(CcAssesmentRubricBase $object) |
||||||
|
{ |
||||||
|
$this->rubric = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setPresentationMaterial(CcAssesmentPresentationMaterialBase $object) |
||||||
|
{ |
||||||
|
$this->presentationMaterial = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setSection(CcAssesmentSection $object) |
||||||
|
{ |
||||||
|
$this->section = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setTitle($value) |
||||||
|
{ |
||||||
|
$this->assessmentTitle = self::safexml($value); |
||||||
|
} |
||||||
|
|
||||||
|
protected function onSave() |
||||||
|
{ |
||||||
|
$rns = $this->ccnamespaces[$this->rootns]; |
||||||
|
//root assesment element - required |
||||||
|
$assessment = $this->appendNewElementNs($this->root, $rns, CcQtiTags::ASSESSMENT); |
||||||
|
$this->appendNewAttributeNs($assessment, $rns, CcQtiTags::IDENT, CcHelpers::uuidgen('QDB_')); |
||||||
|
$this->appendNewAttributeNs($assessment, $rns, CcQtiTags::TITLE, $this->assessmentTitle); |
||||||
|
|
||||||
|
//metadata - optional |
||||||
|
if (!empty($this->metadata)) { |
||||||
|
$this->metadata->generate($this, $assessment, $rns); |
||||||
|
} |
||||||
|
|
||||||
|
//rubric - optional |
||||||
|
if (!empty($this->rubric)) { |
||||||
|
$this->rubric->generate($this, $assessment, $rns); |
||||||
|
} |
||||||
|
|
||||||
|
//presentation_material - optional |
||||||
|
if (!empty($this->presentationMaterial)) { |
||||||
|
$this->presentationMaterial->generate($this, $assessment, $rns); |
||||||
|
} |
||||||
|
|
||||||
|
//section - required |
||||||
|
if (!empty($this->section)) { |
||||||
|
$this->section->generate($this, $assessment, $rns); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentAltmaterial extends CcAssesmentMaterialBase |
||||||
|
{ |
||||||
|
public function __construct($value = null) |
||||||
|
{ |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML); |
||||||
|
$this->tagname = CcQtiTags::ALTMATERIAL; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentDecvartype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::VARNAME, CcQtiValues::SCORE); |
||||||
|
$this->setSetting(CcQtiTags::VARTYPE, CcQtiValues::INTEGER); |
||||||
|
$this->setSetting(CcQtiTags::MINVALUE); |
||||||
|
$this->setSetting(CcQtiTags::MAXVALUE); |
||||||
|
} |
||||||
|
|
||||||
|
public function setVartype($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::VARTYPE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLimits($min = null, $max = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::MINVALUE, $min); |
||||||
|
$this->setSetting(CcQtiTags::MAXVALUE, $max); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::DECVAR); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentFlowLabeltype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $flowLabel = null; |
||||||
|
protected $responseLabel = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS); |
||||||
|
} |
||||||
|
|
||||||
|
public function setClass($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlowLabel(CcAssesmentFlowLabeltype $object) |
||||||
|
{ |
||||||
|
$this->flowLabel = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setResponseLabel(CcAssesmentResponseLabeltype $object) |
||||||
|
{ |
||||||
|
$this->responseLabel = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::FLOW_LABEL); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->material)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->materialRef)) { |
||||||
|
$this->materialRef->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseLabel)) { |
||||||
|
$this->responseLabel->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->flowLabel)) { |
||||||
|
$this->flowLabel->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentFlowMatBase extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $mattag = null; |
||||||
|
|
||||||
|
public function __construct($value = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlowMat(CcAssesmentFlowMatBase $object) |
||||||
|
{ |
||||||
|
$this->setTagValue($object); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->setTagValue($object); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterialRef(CcAssesmentMatref $object) |
||||||
|
{ |
||||||
|
$this->setTagValue($object); |
||||||
|
} |
||||||
|
|
||||||
|
public function setClass($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::FLOW_MAT); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
if (!empty($this->mattag)) { |
||||||
|
$this->mattag->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected function setTagValue($object) |
||||||
|
{ |
||||||
|
$this->mattag = $object; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,52 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentFlowMattype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $material = null; |
||||||
|
protected $materialRef = null; |
||||||
|
protected $flowMat = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS); |
||||||
|
} |
||||||
|
|
||||||
|
public function setClass($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterialRef(CcAssesmentResponseMatref $object) |
||||||
|
{ |
||||||
|
$this->materialRef = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlowMat(CcAssesmentFlowMattype $object) |
||||||
|
{ |
||||||
|
$this->flowMat = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::FLOW_MAT); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->flowMat)) { |
||||||
|
$this->flowMat->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->material)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->materialRef)) { |
||||||
|
$this->materialRef->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,68 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentFlowtype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $flow = null; |
||||||
|
protected $material = null; |
||||||
|
protected $materialRef = null; |
||||||
|
protected $responseLid = null; |
||||||
|
protected $responseStr = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS); |
||||||
|
} |
||||||
|
|
||||||
|
public function setClass($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::T_CLASS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlow(CcAssesmentFlowtype $object) |
||||||
|
{ |
||||||
|
$this->flow = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterialRef(CcAssesmentResponseMatref $object) |
||||||
|
{ |
||||||
|
$this->materialRef = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setResponseLid(CcResponseLidtype $object) |
||||||
|
{ |
||||||
|
$this->responseLid = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setResponseStr(CcAssesmentResponseStrtype $object) |
||||||
|
{ |
||||||
|
$this->responseStr = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::FLOW); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->flow)) { |
||||||
|
$this->flow->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->material)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseLid)) { |
||||||
|
$this->responseLid->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseStr)) { |
||||||
|
$this->responseStr->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,135 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcAssesmentHelper |
||||||
|
{ |
||||||
|
public static $correctFb = null; |
||||||
|
public static $incorrectFb = null; |
||||||
|
|
||||||
|
public static function addFeedback($qitem, $content, $contentType, $ident) |
||||||
|
{ |
||||||
|
if (empty($content)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
$qitemfeedback = new CcAssesmentItemfeedbacktype(); |
||||||
|
$qitem->addItemfeedback($qitemfeedback); |
||||||
|
if (!empty($ident)) { |
||||||
|
$qitemfeedback->setIdent($ident); |
||||||
|
} |
||||||
|
$qflowmat = new CcAssesmentFlowMattype(); |
||||||
|
$qitemfeedback->setFlowMat($qflowmat); |
||||||
|
$qmaterialfb = new CcAssesmentMaterial(); |
||||||
|
$qflowmat->setMaterial($qmaterialfb); |
||||||
|
$qmattext = new CcAssesmentMattext(); |
||||||
|
$qmaterialfb->setMattext($qmattext); |
||||||
|
$qmattext->setContent($content, $contentType); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public static function addAnswer($qresponseChoice, $content, $contentType) |
||||||
|
{ |
||||||
|
$qresponseLabel = new CcAssesmentResponseLabeltype(); |
||||||
|
$qresponseChoice->addResponseLabel($qresponseLabel); |
||||||
|
$qrespmaterial = new CcAssesmentMaterial(); |
||||||
|
$qresponseLabel->setMaterial($qrespmaterial); |
||||||
|
$qrespmattext = new CcAssesmentMattext(); |
||||||
|
$qrespmaterial->setMattext($qrespmattext); |
||||||
|
$qrespmattext->setContent($content, $contentType); |
||||||
|
|
||||||
|
return $qresponseLabel; |
||||||
|
} |
||||||
|
|
||||||
|
public static function addResponseCondition($node, $title, $ident, $feedbackRefid, $respident) |
||||||
|
{ |
||||||
|
$qrespcondition = new CcAssesmentRespconditiontype(); |
||||||
|
$node->addRespcondition($qrespcondition); |
||||||
|
//define rest of the conditions |
||||||
|
$qconditionvar = new CcAssignmentConditionvar(); |
||||||
|
$qrespcondition->setConditionvar($qconditionvar); |
||||||
|
$qvarequal = new CcAssignmentConditionvarVarequaltype($ident); |
||||||
|
$qvarequal->enableCase(); |
||||||
|
$qconditionvar->setVarequal($qvarequal); |
||||||
|
$qvarequal->setRespident($respident); |
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid($feedbackRefid); |
||||||
|
} |
||||||
|
|
||||||
|
public static function addAssesmentDescription($rt, $content, $contenttype) |
||||||
|
{ |
||||||
|
if (empty($rt) || empty($content)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
$activity_rubric = new CcAssesmentRubricBase(); |
||||||
|
$rubric_material = new CcAssesmentMaterial(); |
||||||
|
$activity_rubric->setMaterial($rubric_material); |
||||||
|
$rubric_mattext = new CcAssesmentMattext(); |
||||||
|
$rubric_material->setLabel('Summary'); |
||||||
|
$rubric_material->setMattext($rubric_mattext); |
||||||
|
$rubric_mattext->setContent($content, $contenttype); |
||||||
|
$rt->setRubric($activity_rubric); |
||||||
|
} |
||||||
|
|
||||||
|
public static function addRespcondition($node, $title, $feedbackRefid, $gradeValue = null, $continue = false) |
||||||
|
{ |
||||||
|
$qrespcondition = new CcAssesmentRespconditiontype(); |
||||||
|
$qrespcondition->setTitle($title); |
||||||
|
$node->addRespcondition($qrespcondition); |
||||||
|
$qrespcondition->enableContinue($continue); |
||||||
|
//Add setvar if grade present |
||||||
|
if ($gradeValue !== null) { |
||||||
|
$qsetvar = new CcAssignmentSetvartype($gradeValue); |
||||||
|
$qrespcondition->addSetvar($qsetvar); |
||||||
|
} |
||||||
|
//define the condition for success |
||||||
|
$qconditionvar = new CcAssignmentConditionvar(); |
||||||
|
$qrespcondition->setConditionvar($qconditionvar); |
||||||
|
$qother = new CcAssignmentConditionvarOthertype(); |
||||||
|
$qconditionvar->setOther($qother); |
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid($feedbackRefid); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Enter description here ... |
||||||
|
* |
||||||
|
* @param XMLGenericDocument $qdoc |
||||||
|
* @param unknown_type $manifest |
||||||
|
* @param cc_assesment_section $section |
||||||
|
* @param unknown_type $rootpath |
||||||
|
* @param unknown_type $contextid |
||||||
|
* @param unknown_type $outdir |
||||||
|
*/ |
||||||
|
public static function processQuestions(&$objQuizz, &$manifest, CcAssesmentSection &$section, $rootpath, $contextid, $outdir) |
||||||
|
{ |
||||||
|
PkgResourceDependencies::instance()->reset(); |
||||||
|
$questioncount = 0; |
||||||
|
foreach ($objQuizz['questions'] as $question) { |
||||||
|
$qtype = $question->quiz_type; |
||||||
|
/* Question type : |
||||||
|
* 1 : Unique Answer (Multiple choice, single response) |
||||||
|
* 2 : Multiple Answers (Multiple choice, multiple response) |
||||||
|
* |
||||||
|
*/ |
||||||
|
$questionProcessor = null; |
||||||
|
switch ($qtype) { |
||||||
|
case 1: |
||||||
|
$questionProcessor = new CcAssesmentQuestionMultichoice($objQuizz, $objQuizz['questions'], $manifest, $section, $question, $rootpath, $contextid, $outdir); |
||||||
|
$questionProcessor->generate(); |
||||||
|
$questioncount++; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
$questionProcessor = new CcAssesmentQuestionMultichoiceMultiresponse($objQuizz, $objQuizz['questions'], $manifest, $section, $question, $rootpath, $contextid, $outdir); |
||||||
|
$questionProcessor->generate(); |
||||||
|
$questioncount++; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
//return dependencies |
||||||
|
return ($questioncount == 0) ? false : PkgResourceDependencies::instance()->getDeps(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbacHinttype extends CcAssesmentItemfeedbackShintypeBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
parent::__construct(); |
||||||
|
$this->tagname = CcQtiTags::HINT; |
||||||
|
} |
||||||
|
|
||||||
|
public function addHintmaterial(CcAssesmentItemfeedbackHintmaterial $object) |
||||||
|
{ |
||||||
|
$this->items[] = $object; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbackHintmaterial extends CcAssesmentItemfeedbackShintmaterialBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->tagname = CcQtiTags::HINT; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbackShintmaterialBase extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $tagname = null; |
||||||
|
protected $flowMats = []; |
||||||
|
protected $materials = []; |
||||||
|
|
||||||
|
public function addFlowMat(CcAssesmentFlowMattype $object) |
||||||
|
{ |
||||||
|
$this->flowMats[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function add_material(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->materials[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, $this->tagname); |
||||||
|
|
||||||
|
if (!empty($this->flowMats)) { |
||||||
|
foreach ($this->flowMats as $flowMat) { |
||||||
|
$flowMat->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->materials)) { |
||||||
|
foreach ($this->materials as $material) { |
||||||
|
$material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbackShintypeBase extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $tagname = null; |
||||||
|
protected $items = []; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::FEEDBACKSTYLE, CcQtiValues::COMPLETE); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, $this->tagname); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->items)) { |
||||||
|
foreach ($this->items as $telement) { |
||||||
|
$telement->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbackSolutionmaterial extends CcAssesmentItemfeedbackShintmaterialBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->tagname = CcQtiTags::SOLUTIONMATERIAL; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbackSolutiontype extends CcAssesmentItemfeedbackShintypeBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
parent::__construct(); |
||||||
|
$this->tagname = CcQtiTags::SOLUTION; |
||||||
|
} |
||||||
|
|
||||||
|
public function add_solutionmaterial(CcAssesmentItemfeedbackSolutionmaterial $object) |
||||||
|
{ |
||||||
|
$this->items[] = $object; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,74 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemfeedbacktype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $flowMat = null; |
||||||
|
protected $material = null; |
||||||
|
protected $solution = null; |
||||||
|
protected $hint = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, CcHelpers::uuidgen('I_')); |
||||||
|
$this->setSetting(CcQtiTags::TITLE); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $value |
||||||
|
*/ |
||||||
|
public function setIdent($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $value |
||||||
|
*/ |
||||||
|
public function setTitle($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::TITLE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlowMat(CcAssesmentFlowMattype $object) |
||||||
|
{ |
||||||
|
$this->flowMat = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function set_solution(CcAssesmentItemfeedbackSolutiontype $object) |
||||||
|
{ |
||||||
|
$this->solution = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function set_hint($object) |
||||||
|
{ |
||||||
|
$this->hint = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::ITEMFEEDBACK); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->flowMat) && empty($this->material)) { |
||||||
|
$this->flowMat->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->material) && empty($this->flowMat)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->solution)) { |
||||||
|
$this->solution->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->itemfeedback)) { |
||||||
|
$this->itemfeedback->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentItemmetadata extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
public function addMetadata($object) |
||||||
|
{ |
||||||
|
$this->metadata[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::ITEMMETADATA); |
||||||
|
if (!empty($this->metadata)) { |
||||||
|
foreach ($this->metadata as $metaitem) { |
||||||
|
$metaitem->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentMatbreak |
||||||
|
{ |
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$doc->appendNewElementNs($item, $namespace, CcQtiTags::MATBREAK); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentMaterial extends CcAssesmentMaterialBase |
||||||
|
{ |
||||||
|
protected $altmaterial = null; |
||||||
|
|
||||||
|
public function __construct($value = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LABEL); |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML); |
||||||
|
$this->tagname = CcQtiTags::MATERIAL; |
||||||
|
} |
||||||
|
|
||||||
|
public function setLabel($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LABEL, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setAltmaterial(CcAssesmentAltmaterial $object) |
||||||
|
{ |
||||||
|
$this->altmaterial = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$material = parent::generate($doc, $item, $namespace); |
||||||
|
if (!empty($this->altmaterial)) { |
||||||
|
$this->altmaterial->generate($doc, $material, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcAssesmentMaterialBase extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var mixed |
||||||
|
*/ |
||||||
|
protected $mattag = null; |
||||||
|
protected $tagname = null; |
||||||
|
|
||||||
|
public function setMattext(CcAssesmentMattext $object) |
||||||
|
{ |
||||||
|
$this->setTagValue($object); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMatref(CcAssesmentMatref $object) |
||||||
|
{ |
||||||
|
$this->setTagValue($object); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMatbreak(CcAssesmentMatbreak $object) |
||||||
|
{ |
||||||
|
$this->setTagValue($object); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLang($value) |
||||||
|
{ |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$material = $doc->appendNewElementNs($item, $namespace, $this->tagname); |
||||||
|
$this->generateAttributes($doc, $material, $namespace); |
||||||
|
if (!empty($this->mattag)) { |
||||||
|
$this->mattag->generate($doc, $material, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
return $material; |
||||||
|
} |
||||||
|
|
||||||
|
protected function setTagValue($object) |
||||||
|
{ |
||||||
|
$this->mattag = $object; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentMatref |
||||||
|
{ |
||||||
|
protected $linkref = null; |
||||||
|
|
||||||
|
public function __construct($linkref) |
||||||
|
{ |
||||||
|
$this->linkref = $linkref; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::MATREF, $this->linkref); |
||||||
|
$doc->appendNewAttributeNs($node, $namespace, CcQtiTags::LINKREFID, $this->linkref); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,62 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentMattext extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $value = null; |
||||||
|
|
||||||
|
public function __construct($value = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::TEXTTYPE, CcQtiValues::TEXTTYPE); |
||||||
|
$this->setSetting(CcQtiTags::CHARSET); //, 'ascii-us'); |
||||||
|
$this->setSetting(CcQtiTags::LABEL); |
||||||
|
$this->setSetting(CcQtiTags::URI); |
||||||
|
$this->setSetting(CcQtiTags::WIDTH); |
||||||
|
$this->setSetting(CcQtiTags::HEIGHT); |
||||||
|
$this->setSetting(CcQtiTags::X0); |
||||||
|
$this->setSetting(CcQtiTags::Y0); |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML); |
||||||
|
$this->setSettingWns(CcQtiTags::XML_SPACE, CcXmlNamespace::XML); //, 'default'); |
||||||
|
$this->value = $value; |
||||||
|
} |
||||||
|
|
||||||
|
public function setLabel($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LABEL, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setUri($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::URI, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setWidthHeight($width = null, $height = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::WIDTH, $width); |
||||||
|
$this->setSetting(CcQtiTags::HEIGHT, $height); |
||||||
|
} |
||||||
|
|
||||||
|
public function setCoor($x = null, $y = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::X0, $x); |
||||||
|
$this->setSetting(CcQtiTags::Y0, $y); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLang($lang = null) |
||||||
|
{ |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML, $lang); |
||||||
|
} |
||||||
|
|
||||||
|
public function setContent($content, $type = CcQtiValues::TEXTTYPE, $charset = null) |
||||||
|
{ |
||||||
|
$this->value = $content; |
||||||
|
$this->setSetting(CcQtiTags::TEXTTYPE, $type); |
||||||
|
$this->setSetting(CcQtiTags::CHARSET, $charset); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$mattext = $doc->appendNewElementNsCdata($item, $namespace, CcQtiTags::MATTEXT, $this->value); |
||||||
|
$this->generateAttributes($doc, $mattext, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,60 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentMetadata extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
//prepared default values |
||||||
|
$this->setSetting(CcQtiMetadata::CC_PROFILE, CcQtiValues::EXAM_PROFILE); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_ASSESSMENTTYPE, CcQtiValues::EXAMINATION); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_SCORETYPE, CcQtiValues::PERCENTAGE); |
||||||
|
//optional empty values |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_FEEDBACKPERMITTED); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_HINTSPERMITTED); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_SOLUTIONSPERMITTED); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_TIMELIMIT); |
||||||
|
$this->setSetting(CcQtiMetadata::CC_ALLOW_LATE_SUBMISSION); |
||||||
|
$this->setSetting(CcQtiMetadata::CC_MAXATTEMPTS); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableHints($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiMetadata::QMD_HINTSPERMITTED, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableSolutions($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiMetadata::QMD_SOLUTIONSPERMITTED, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableLatesubmissions($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiMetadata::CC_ALLOW_LATE_SUBMISSION, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableFeedback($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiMetadata::QMD_FEEDBACKPERMITTED, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setTimelimit($value) |
||||||
|
{ |
||||||
|
$ivalue = (int) $value; |
||||||
|
if (($ivalue < 0) || ($ivalue > 527401)) { |
||||||
|
throw new OutOfRangeException('Time limit value out of permitted range!'); |
||||||
|
} |
||||||
|
|
||||||
|
$this->setSetting(CcQtiMetadata::QMD_TIMELIMIT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaxattempts($value) |
||||||
|
{ |
||||||
|
$valid_values = [CcQtiValues::EXAMINATION, CcQtiValues::UNLIMITED, 1, 2, 3, 4, 5]; |
||||||
|
if (!in_array($value, $valid_values)) { |
||||||
|
throw new OutOfRangeException('Max attempts has invalid value'); |
||||||
|
} |
||||||
|
|
||||||
|
$this->setSetting(CcQtiMetadata::CC_MAXATTEMPTS, $value); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,84 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentPresentation extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $flow = null; |
||||||
|
protected $material = null; |
||||||
|
protected $responseLid = null; |
||||||
|
protected $responseStr = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LABEL); |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML); |
||||||
|
$this->setSetting(CcQtiTags::X0); |
||||||
|
$this->setSetting(CcQtiTags::Y0); |
||||||
|
$this->setSetting(CcQtiTags::WIDTH); |
||||||
|
$this->setSetting(CcQtiTags::HEIGHT); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLabel($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LABEL, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLang($value) |
||||||
|
{ |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setCoor($x = null, $y = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::X0, $x); |
||||||
|
$this->setSetting(CcQtiTags::Y0, $y); |
||||||
|
} |
||||||
|
|
||||||
|
public function setSize($width = null, $height = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::WIDTH, $width); |
||||||
|
$this->setSetting(CcQtiTags::HEIGHT, $height); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlow(CcAssesmentFlowtype $object) |
||||||
|
{ |
||||||
|
$this->flow = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setResponseLid(CcResponseLidtype $object) |
||||||
|
{ |
||||||
|
$this->responseLid = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setResponseStr(CcAssesmentResponseStrtype $object) |
||||||
|
{ |
||||||
|
$this->responseStr = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::PRESENTATION); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->flow)) { |
||||||
|
$this->flow->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->material) && empty($this->flow)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseLid) && empty($this->flow)) { |
||||||
|
$this->responseLid->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseStr) && empty($this->flow)) { |
||||||
|
$this->responseStr->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentPresentationMaterialBase extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $flowmats = []; |
||||||
|
|
||||||
|
public function addFlowMat($object) |
||||||
|
{ |
||||||
|
$this->flowmats[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::PRESENTATION_MATERIAL); |
||||||
|
if (!empty($this->flowmats)) { |
||||||
|
foreach ($this->flowmats as $flowMat) { |
||||||
|
$flowMat->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,216 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentQuestionMultichoice extends CcAssesmentQuestionProcBase |
||||||
|
{ |
||||||
|
public function __construct($quiz, $questions, $manifest, $section, $question, $rootpath, $contextid, $outdir) |
||||||
|
{ |
||||||
|
parent::__construct($quiz, $questions, $manifest, $section, $question, $rootpath, $contextid, $outdir); |
||||||
|
$this->qtype = CcQtiProfiletype::MULTIPLE_CHOICE; |
||||||
|
|
||||||
|
$correctAnswerNode = 0; |
||||||
|
$questionScore = 0; |
||||||
|
foreach ($question->answers as $answer) { |
||||||
|
if ($answer['correct'] > 0) { |
||||||
|
$correctAnswerNode = 1; |
||||||
|
$this->correctAnswerNodeId = $answer['id']; |
||||||
|
$questionScore = $answer['ponderation']; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (empty($correctAnswerNode)) { |
||||||
|
throw new RuntimeException('No correct answer!'); |
||||||
|
} |
||||||
|
//$this->total_grade_value = ($question_score).'.0000000'; |
||||||
|
$this->totalGradeValue = $questionScore; |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateAnswers() |
||||||
|
{ |
||||||
|
//add responses holder |
||||||
|
$qresponseLid = new CcResponseLidtype(); |
||||||
|
$this->qresponseLid = $qresponseLid; |
||||||
|
$this->qpresentation->setResponseLid($qresponseLid); |
||||||
|
$qresponseChoice = new CcAssesmentRenderChoicetype(); |
||||||
|
$qresponseLid->setRenderChoice($qresponseChoice); |
||||||
|
|
||||||
|
//Mark that question has only one correct answer - |
||||||
|
//which applies for multiple choice and yes/no questions |
||||||
|
$qresponseLid->setRcardinality(CcQtiValues::SINGLE); |
||||||
|
|
||||||
|
//are we to shuffle the responses? |
||||||
|
$shuffleAnswers = $this->quiz['random_answers'] > 0; |
||||||
|
|
||||||
|
$qresponseChoice->enableShuffle($shuffleAnswers); |
||||||
|
$answerlist = []; |
||||||
|
|
||||||
|
$qaResponses = $this->questionNode->answers; |
||||||
|
|
||||||
|
foreach ($qaResponses as $node) { |
||||||
|
$answerContent = $node['answer']; |
||||||
|
$id = $node['id']; |
||||||
|
|
||||||
|
$result = CcHelpers::processLinkedFiles($answerContent, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
$qresponseLabel = CcAssesmentHelper::addAnswer($qresponseChoice, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE); |
||||||
|
|
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
|
||||||
|
$answerIdent = $qresponseLabel->getIdent(); |
||||||
|
$feedbackIdent = $answerIdent.'_fb'; |
||||||
|
if (empty($this->correctAnswerIdent) && $id) { |
||||||
|
$this->correctAnswerIdent = $answerIdent; |
||||||
|
} |
||||||
|
|
||||||
|
//add answer specific feedbacks if not empty |
||||||
|
$content = $node['comment']; |
||||||
|
|
||||||
|
if (!empty($content)) { |
||||||
|
$result = CcHelpers::processLinkedFiles($content, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
CcAssesmentHelper::addFeedback($this->qitem, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE, |
||||||
|
$feedbackIdent); |
||||||
|
|
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
$answerlist[$answerIdent] = $feedbackIdent; |
||||||
|
} |
||||||
|
} |
||||||
|
$this->answerlist = $answerlist; |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateFeedbacks() |
||||||
|
{ |
||||||
|
parent::onGenerateFeedbacks(); |
||||||
|
|
||||||
|
//Question combined feedbacks |
||||||
|
$correctQuestionFb = ''; |
||||||
|
$incorrectQuestionFb = ''; |
||||||
|
|
||||||
|
if (empty($correctQuestionFb)) { |
||||||
|
//Hardcode some text for now |
||||||
|
$correctQuestionFb = 'Well done!'; |
||||||
|
} |
||||||
|
if (empty($incorrectQuestionFb)) { |
||||||
|
//Hardcode some text for now |
||||||
|
$incorrectQuestionFb = 'Better luck next time!'; |
||||||
|
} |
||||||
|
|
||||||
|
$proc = ['correct_fb' => $correctQuestionFb, 'general_incorrect_fb' => $incorrectQuestionFb]; |
||||||
|
foreach ($proc as $ident => $content) { |
||||||
|
if (empty($content)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
$result = CcHelpers::processLinkedFiles($content, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
CcAssesmentHelper::addFeedback($this->qitem, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE, |
||||||
|
$ident); |
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
if ($ident == 'correct_fb') { |
||||||
|
$this->correctFeedbacks[] = $ident; |
||||||
|
} else { |
||||||
|
$this->incorrectFeedbacks[] = $ident; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateResponseProcessing() |
||||||
|
{ |
||||||
|
parent::onGenerateResponseProcessing(); |
||||||
|
|
||||||
|
//respconditions |
||||||
|
/** |
||||||
|
* General unconditional feedback must be added as a first respcondition |
||||||
|
* without any condition and just displayfeedback (if exists). |
||||||
|
*/ |
||||||
|
if (!empty($this->generalFeedback)) { |
||||||
|
$qrespcondition = new CcAssesmentRespconditiontype(); |
||||||
|
$qrespcondition->setTitle('General feedback'); |
||||||
|
$this->qresprocessing->addRespcondition($qrespcondition); |
||||||
|
$qrespcondition->enableContinue(); |
||||||
|
//define the condition for success |
||||||
|
$qconditionvar = new CcAssignmentConditionvar(); |
||||||
|
$qrespcondition->setConditionvar($qconditionvar); |
||||||
|
$qother = new CcAssignmentConditionvarOthertype(); |
||||||
|
$qconditionvar->setOther($qother); |
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid('general_fb'); |
||||||
|
} |
||||||
|
|
||||||
|
//success condition |
||||||
|
$qrespcondition = new CcAssesmentRespconditiontype(); |
||||||
|
$qrespcondition->setTitle('Correct'); |
||||||
|
$this->qresprocessing->addRespcondition($qrespcondition); |
||||||
|
$qrespcondition->enableContinue(false); |
||||||
|
$qsetvar = new CcAssignmentSetvartype(100); |
||||||
|
$qrespcondition->addSetvar($qsetvar); |
||||||
|
//define the condition for success |
||||||
|
$qconditionvar = new CcAssignmentConditionvar(); |
||||||
|
$qrespcondition->setConditionvar($qconditionvar); |
||||||
|
$qvarequal = new CcAssignmentConditionvarVarequaltype($this->correctAnswerIdent); |
||||||
|
$qconditionvar->setVarequal($qvarequal); |
||||||
|
$qvarequal->setRespident($this->qresponseLid->getIdent()); |
||||||
|
|
||||||
|
if (array_key_exists($this->correctAnswerIdent, $this->answerlist)) { |
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid($this->answerlist[$this->correctAnswerIdent]); |
||||||
|
} |
||||||
|
|
||||||
|
foreach ($this->correctFeedbacks as $ident) { |
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid($ident); |
||||||
|
} |
||||||
|
|
||||||
|
//rest of the conditions |
||||||
|
foreach ($this->answerlist as $ident => $refid) { |
||||||
|
if ($ident == $this->correctAnswerIdent) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
$qrespcondition = new CcAssesmentRespconditiontype(); |
||||||
|
$this->qresprocessing->addRespcondition($qrespcondition); |
||||||
|
$qsetvar = new CcAssignmentSetvartype(0); |
||||||
|
$qrespcondition->addSetvar($qsetvar); |
||||||
|
//define the condition for fail |
||||||
|
$qconditionvar = new CcAssignmentConditionvar(); |
||||||
|
$qrespcondition->setConditionvar($qconditionvar); |
||||||
|
$qvarequal = new CcAssignmentConditionvarVarequaltype($ident); |
||||||
|
$qconditionvar->setVarequal($qvarequal); |
||||||
|
$qvarequal->setRespident($this->qresponseLid->getIdent()); |
||||||
|
|
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid($refid); |
||||||
|
|
||||||
|
foreach ($this->incorrectFeedbacks as $ident) { |
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
$qdisplayfeedback->setLinkrefid($ident); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,190 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentQuestionMultichoiceMultiresponse extends CcAssesmentQuestionProcBase |
||||||
|
{ |
||||||
|
protected $correctAnswers = null; |
||||||
|
|
||||||
|
public function __construct($quiz, $questions, $manifest, $section, $questionNode, $rootpath, $contextid, $outdir) |
||||||
|
{ |
||||||
|
parent::__construct($quiz, $questions, $manifest, $section, $questionNode, $rootpath, $contextid, $outdir); |
||||||
|
$this->qtype = CcQtiProfiletype::MULTIPLE_RESPONSE; |
||||||
|
|
||||||
|
$correctAnswerNodes = []; |
||||||
|
$questionScore = 0; |
||||||
|
foreach ($questionNode->answers as $answer) { |
||||||
|
if ($answer['correct'] > 0) { |
||||||
|
$correctAnswerNodes[] = $answer; |
||||||
|
$questionScore += $answer['ponderation']; |
||||||
|
} |
||||||
|
} |
||||||
|
if (count($correctAnswerNodes) == 0) { |
||||||
|
throw new RuntimeException('No correct answer!'); |
||||||
|
} |
||||||
|
$this->correctAnswers = $correctAnswerNodes; |
||||||
|
$this->totalGradeValue = $questionScore; |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateAnswers() |
||||||
|
{ |
||||||
|
//add responses holder |
||||||
|
$qresponseLid = new CcResponseLidtype(); |
||||||
|
$this->qresponseLid = $qresponseLid; |
||||||
|
$this->qpresentation->setResponseLid($qresponseLid); |
||||||
|
$qresponseChoice = new CcAssesmentRenderChoicetype(); |
||||||
|
$qresponseLid->setRenderChoice($qresponseChoice); |
||||||
|
//Mark that question has more than one correct answer |
||||||
|
$qresponseLid->setRcardinality(CcQtiValues::MULTIPLE); |
||||||
|
//are we to shuffle the responses? |
||||||
|
|
||||||
|
$shuffleAnswers = $this->quiz['random_answers'] > 0; |
||||||
|
$qresponseChoice->enableShuffle($shuffleAnswers); |
||||||
|
$answerlist = []; |
||||||
|
|
||||||
|
$qaResponses = $this->questionNode->answers; |
||||||
|
foreach ($qaResponses as $node) { |
||||||
|
$answerContent = $node['answer']; |
||||||
|
$answerGradeFraction = $node['ponderation']; |
||||||
|
|
||||||
|
$result = CcHelpers::processLinkedFiles($answerContent, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
$qresponseLabel = CcAssesmentHelper::addAnswer($qresponseChoice, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE); |
||||||
|
|
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
|
||||||
|
$answerIdent = $qresponseLabel->getIdent(); |
||||||
|
$feedbackIdent = $answerIdent.'_fb'; |
||||||
|
//add answer specific feedbacks if not empty |
||||||
|
$content = $node['comment']; |
||||||
|
if (!empty($content)) { |
||||||
|
$result = CcHelpers::processLinkedFiles($content, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
CcAssesmentHelper::addFeedback($this->qitem, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE, |
||||||
|
$feedbackIdent); |
||||||
|
|
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
} |
||||||
|
$answerlist[$answerIdent] = [$feedbackIdent, ($answerGradeFraction > 0)]; |
||||||
|
} |
||||||
|
$this->answerlist = $answerlist; |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateFeedbacks() |
||||||
|
{ |
||||||
|
parent::onGenerateFeedbacks(); |
||||||
|
//Question combined feedbacks |
||||||
|
$correctQuestionFb = ''; |
||||||
|
$incorrectQuestionFb = ''; |
||||||
|
if (empty($correctQuestionFb)) { |
||||||
|
//Hardcode some text for now |
||||||
|
$correctQuestionFb = 'Well done!'; |
||||||
|
} |
||||||
|
if (empty($incorrectQuestionFb)) { |
||||||
|
//Hardcode some text for now |
||||||
|
$incorrectQuestionFb = 'Better luck next time!'; |
||||||
|
} |
||||||
|
|
||||||
|
$proc = ['correct_fb' => $correctQuestionFb, 'incorrect_fb' => $incorrectQuestionFb]; |
||||||
|
foreach ($proc as $ident => $content) { |
||||||
|
if (empty($content)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
$result = CcHelpers::processLinkedFiles($content, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
CcAssesmentHelper::addFeedback($this->qitem, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE, |
||||||
|
$ident); |
||||||
|
|
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
if ($ident == 'correct_fb') { |
||||||
|
$this->correctFeedbacks[$ident] = $ident; |
||||||
|
} else { |
||||||
|
$this->incorrectFeedbacks[$ident] = $ident; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateResponseProcessing() |
||||||
|
{ |
||||||
|
parent::onGenerateResponseProcessing(); |
||||||
|
|
||||||
|
//respconditions |
||||||
|
/** |
||||||
|
* General unconditional feedback must be added as a first respcondition |
||||||
|
* without any condition and just displayfeedback (if exists). |
||||||
|
*/ |
||||||
|
CcAssesmentHelper::addRespcondition($this->qresprocessing, |
||||||
|
'General feedback', |
||||||
|
$this->generalFeedback, |
||||||
|
null, |
||||||
|
true |
||||||
|
); |
||||||
|
|
||||||
|
$qrespcondition = new CcAssesmentRespconditiontype(); |
||||||
|
$qrespcondition->setTitle('Correct'); |
||||||
|
$this->qresprocessing->addRespcondition($qrespcondition); |
||||||
|
$qrespcondition->enableContinue(false); |
||||||
|
$qsetvar = new CcAssignmentSetvartype(100); |
||||||
|
$qrespcondition->addSetvar($qsetvar); |
||||||
|
//define the condition for success |
||||||
|
$qconditionvar = new CcAssignmentConditionvar(); |
||||||
|
$qrespcondition->setConditionvar($qconditionvar); |
||||||
|
//create root and condition |
||||||
|
$qandcondition = new CcAssignmentConditionvarAndtype(); |
||||||
|
$qconditionvar->setAnd($qandcondition); |
||||||
|
foreach ($this->answerlist as $ident => $refid) { |
||||||
|
$qvarequal = new CcAssignmentConditionvarVarequaltype($ident); |
||||||
|
$qvarequal->enableCase(); |
||||||
|
if ($refid[1]) { |
||||||
|
$qandcondition->setVarequal($qvarequal); |
||||||
|
} else { |
||||||
|
$qandcondition->setNot($qvarequal); |
||||||
|
} |
||||||
|
$qvarequal->setRespident($this->qresponseLid->getIdent()); |
||||||
|
} |
||||||
|
|
||||||
|
$qdisplayfeedback = new CcAssignmentDisplayfeedbacktype(); |
||||||
|
$qrespcondition->addDisplayfeedback($qdisplayfeedback); |
||||||
|
$qdisplayfeedback->setFeedbacktype(CcQtiValues::RESPONSE); |
||||||
|
//TODO: this needs to be fixed |
||||||
|
reset($this->correctFeedbacks); |
||||||
|
$ident = key($this->correctFeedbacks); |
||||||
|
$qdisplayfeedback->setLinkrefid($ident); |
||||||
|
|
||||||
|
//rest of the conditions |
||||||
|
foreach ($this->answerlist as $ident => $refid) { |
||||||
|
CcAssesmentHelper::addResponseCondition($this->qresprocessing, |
||||||
|
'Incorrect feedback', |
||||||
|
$refid[0], |
||||||
|
$this->generalFeedback, |
||||||
|
$this->qresponseLid->getIdent() |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
//Final element for incorrect feedback |
||||||
|
reset($this->incorrectFeedbacks); |
||||||
|
$ident = key($this->incorrectFeedbacks); |
||||||
|
CcAssesmentHelper::addRespcondition($this->qresprocessing, |
||||||
|
'Incorrect feedback', |
||||||
|
$ident, |
||||||
|
0 |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,155 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentQuestionProcBase |
||||||
|
{ |
||||||
|
protected $quiz = null; |
||||||
|
protected $questions = null; |
||||||
|
protected $manifest = null; |
||||||
|
protected $section = null; |
||||||
|
protected $questionNode = null; |
||||||
|
protected $rootpath = null; |
||||||
|
protected $contextid = null; |
||||||
|
protected $outdir = null; |
||||||
|
protected $qtype = null; |
||||||
|
protected $qmetadata = null; |
||||||
|
protected $qitem = null; |
||||||
|
protected $qpresentation = null; |
||||||
|
protected $qresponseLid = null; |
||||||
|
protected $qresprocessing = null; |
||||||
|
protected $correct_grade_value = null; |
||||||
|
protected $correctAnswerNodeId = null; |
||||||
|
protected $correctAnswerIdent = null; |
||||||
|
protected $totalGradeValue = null; |
||||||
|
protected $answerlist = null; |
||||||
|
protected $generalFeedback = null; |
||||||
|
protected $correctFeedbacks = []; |
||||||
|
protected $incorrectFeedbacks = []; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param XMLGenericDocument $questions |
||||||
|
* @param cc_assesment_section $section |
||||||
|
* @param object $question_node |
||||||
|
* @param string $rootpath |
||||||
|
* @param string $contextid |
||||||
|
* @param string $outdir |
||||||
|
*/ |
||||||
|
public function __construct(&$quiz, &$questions, CcManifest &$manifest, CcAssesmentSection &$section, &$questionNode, $rootpath, $contextid, $outdir) |
||||||
|
{ |
||||||
|
$this->quiz = $quiz; |
||||||
|
$this->questions = $questions; |
||||||
|
$this->manifest = $manifest; |
||||||
|
$this->section = $section; |
||||||
|
$this->questionNode = $questionNode; |
||||||
|
$this->rootpath = $rootpath; |
||||||
|
$this->contextid = $contextid; |
||||||
|
$this->outdir = $outdir; |
||||||
|
$qitem = new CcAssesmentSectionItem(); |
||||||
|
$this->section->addItem($qitem); |
||||||
|
$qitem->setTitle($questionNode->question); |
||||||
|
$this->qitem = $qitem; |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateMetadata() |
||||||
|
{ |
||||||
|
if (empty($this->qmetadata)) { |
||||||
|
$this->qmetadata = new CcQuestionMetadata($this->qtype); |
||||||
|
//Get weighting value |
||||||
|
$weightingValue = $this->questionNode->ponderation; |
||||||
|
|
||||||
|
if ($weightingValue > 1) { |
||||||
|
$this->qmetadata->setWeighting($weightingValue); |
||||||
|
} |
||||||
|
|
||||||
|
//Get category |
||||||
|
$questionCategory = $this->questionNode->questionCategory; |
||||||
|
|
||||||
|
if (!empty($questionCategory)) { |
||||||
|
$this->qmetadata->setCategory($questionCategory); |
||||||
|
} |
||||||
|
$rts = new CcAssesmentItemmetadata(); |
||||||
|
$rts->addMetadata($this->qmetadata); |
||||||
|
$this->qitem->setItemmetadata($rts); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function onGeneratePresentation() |
||||||
|
{ |
||||||
|
if (empty($this->qpresentation)) { |
||||||
|
$qpresentation = new CcAssesmentPresentation(); |
||||||
|
$this->qitem->setPresentation($qpresentation); |
||||||
|
//add question text |
||||||
|
$qmaterial = new CcAssesmentMaterial(); |
||||||
|
$qmattext = new CcAssesmentMattext(); |
||||||
|
|
||||||
|
$questionText = $this->questionNode->question; |
||||||
|
$result = CcHelpers::processLinkedFiles($questionText, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
$qmattext->setContent($result[0], CcQtiValues::HTMLTYPE); |
||||||
|
$qmaterial->setMattext($qmattext); |
||||||
|
$qpresentation->setMaterial($qmaterial); |
||||||
|
$this->qpresentation = $qpresentation; |
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateAnswers() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateFeedbacks() |
||||||
|
{ |
||||||
|
$generalQuestionFeedback = ''; |
||||||
|
|
||||||
|
if (empty($generalQuestionFeedback)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$name = 'general_fb'; |
||||||
|
//Add question general feedback - the one that should be always displayed |
||||||
|
$result = CcHelpers::processLinkedFiles($generalQuestionFeedback, |
||||||
|
$this->manifest, |
||||||
|
$this->rootpath, |
||||||
|
$this->contextid, |
||||||
|
$this->outdir); |
||||||
|
|
||||||
|
CcAssesmentHelper::addFeedback($this->qitem, |
||||||
|
$result[0], |
||||||
|
CcQtiValues::HTMLTYPE, |
||||||
|
$name); |
||||||
|
|
||||||
|
PkgResourceDependencies::instance()->add($result[1]); |
||||||
|
$this->generalFeedback = $name; |
||||||
|
} |
||||||
|
|
||||||
|
public function onGenerateResponseProcessing() |
||||||
|
{ |
||||||
|
$qresprocessing = new CcAssesmentResprocessingtype(); |
||||||
|
$this->qitem->addResprocessing($qresprocessing); |
||||||
|
$qdecvar = new CcAssesmentDecvartype(); |
||||||
|
$qresprocessing->setDecvar($qdecvar); |
||||||
|
//according to the Common Cartridge 1.1 Profile: Implementation document |
||||||
|
//this should always be set to 0, 100 in case of question type that is not essay |
||||||
|
$qdecvar->setLimits(0, 100); |
||||||
|
$qdecvar->setVartype(CcQtiValues::DECIMAL); |
||||||
|
|
||||||
|
$this->qresprocessing = $qresprocessing; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate() |
||||||
|
{ |
||||||
|
$this->onGenerateMetadata(); |
||||||
|
|
||||||
|
$this->onGeneratePresentation(); |
||||||
|
|
||||||
|
$this->onGenerateAnswers(); |
||||||
|
|
||||||
|
$this->onGenerateFeedbacks(); |
||||||
|
|
||||||
|
$this->onGenerateResponseProcessing(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentRenderChoicetype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $materials = []; |
||||||
|
protected $material_refs = []; |
||||||
|
protected $responseLabels = []; |
||||||
|
protected $flow_labels = []; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::SHUFFLE, CcQtiValues::NO); |
||||||
|
$this->setSetting(CcQtiTags::MINNUMBER); |
||||||
|
$this->setSetting(CcQtiTags::MAXNUMBER); |
||||||
|
} |
||||||
|
|
||||||
|
public function add_material(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->materials[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function add_material_ref(CcAssesmentResponseMatref $object) |
||||||
|
{ |
||||||
|
$this->material_refs[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function addResponseLabel(CcAssesmentResponseLabeltype $object) |
||||||
|
{ |
||||||
|
$this->responseLabels[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function add_flow_label($object) |
||||||
|
{ |
||||||
|
$this->flow_labels[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function enableShuffle($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiTags::SHUFFLE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLimits($min = null, $max = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::MINNUMBER, $min); |
||||||
|
$this->setSetting(CcQtiTags::MAXNUMBER, $max); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::RENDER_CHOICE); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->materials)) { |
||||||
|
foreach ($this->materials as $mattag) { |
||||||
|
$mattag->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->material_refs)) { |
||||||
|
foreach ($this->material_refs as $matreftag) { |
||||||
|
$matreftag->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseLabels)) { |
||||||
|
foreach ($this->responseLabels as $resplabtag) { |
||||||
|
$resplabtag->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->flow_labels)) { |
||||||
|
foreach ($this->flow_labels as $flowlabtag) { |
||||||
|
$flowlabtag->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,106 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentRenderFibtype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $material = null; |
||||||
|
protected $materialRef = null; |
||||||
|
protected $responseLabel = null; |
||||||
|
protected $flowLabel = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::ENCODING); |
||||||
|
$this->setSetting(CcQtiTags::CHARSET); |
||||||
|
$this->setSetting(CcQtiTags::ROWS); |
||||||
|
$this->setSetting(CcQtiTags::COLUMNS); |
||||||
|
$this->setSetting(CcQtiTags::MAXCHARS); |
||||||
|
$this->setSetting(CcQtiTags::MINNUMBER); |
||||||
|
$this->setSetting(CcQtiTags::MAXNUMBER); |
||||||
|
$this->setSetting(CcQtiTags::PROMPT, CcQtiValues::BOX); |
||||||
|
$this->setSetting(CcQtiTags::FIBTYPE, CcQtiValues::STRING); |
||||||
|
} |
||||||
|
|
||||||
|
public function setEncoding($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::ENCODING, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setCharset($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::CHARSET, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setRows($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::ROWS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setColumns($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::COLUMNS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaxchars($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::COLUMNS, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLimits($min = null, $max = null) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::MINNUMBER, $min); |
||||||
|
$this->setSetting(CcQtiTags::MAXNUMBER, $max); |
||||||
|
} |
||||||
|
|
||||||
|
public function setPrompt($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::PROMPT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFibtype($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::FIBTYPE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterialRef(CcAssesmentResponseMatref $object) |
||||||
|
{ |
||||||
|
$this->materialRef = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setResponseLabel(CcAssesmentResponseLabeltype $object) |
||||||
|
{ |
||||||
|
$this->responseLabel = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlowLabel($object) |
||||||
|
{ |
||||||
|
$this->flowLabel = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::RENDER_FIB); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->material) && empty($this->materialRef)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->materialRef) && empty($this->material)) { |
||||||
|
$this->materialRef->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->responseLabel)) { |
||||||
|
$this->responseLabel->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->flowLabel)) { |
||||||
|
$this->flowLabel->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,62 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentRespconditiontype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $conditionvar = null; |
||||||
|
protected $setvar = []; |
||||||
|
protected $displayfeedback = []; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::TITLE); |
||||||
|
$this->setSetting(CcQtiTags::CONTINUE_, CcQtiValues::NO); |
||||||
|
} |
||||||
|
|
||||||
|
public function setTitle($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::TITLE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableContinue($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiTags::CONTINUE_, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setConditionvar(CcAssignmentConditionvar $object) |
||||||
|
{ |
||||||
|
$this->conditionvar = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function addSetvar(CcAssignmentSetvartype $object) |
||||||
|
{ |
||||||
|
$this->setvar[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function addDisplayfeedback(CcAssignmentDisplayfeedbacktype $object) |
||||||
|
{ |
||||||
|
$this->displayfeedback[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::RESPCONDITION); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->conditionvar)) { |
||||||
|
$this->conditionvar->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->setvar)) { |
||||||
|
foreach ($this->setvar as $setvar) { |
||||||
|
$setvar->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->displayfeedback)) { |
||||||
|
foreach ($this->displayfeedback as $displayfeedback) { |
||||||
|
$displayfeedback->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,81 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentResponseLabeltype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $material = null; |
||||||
|
protected $materialRef = null; |
||||||
|
protected $flowMat = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, CcHelpers::uuidgen('I_')); |
||||||
|
$this->setSetting(CcQtiTags::LABELREFID); |
||||||
|
$this->setSetting(CcQtiTags::RSHUFFLE); |
||||||
|
$this->setSetting(CcQtiTags::MATCH_GROUP); |
||||||
|
$this->setSetting(CcQtiTags::MATCH_MAX); |
||||||
|
} |
||||||
|
|
||||||
|
public function setIdent($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function getIdent() |
||||||
|
{ |
||||||
|
return $this->getSetting(CcQtiTags::IDENT); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLabelrefid($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LABELREFID, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableRshuffle($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiTags::RSHUFFLE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMatchGroup($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::MATCH_GROUP, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMatchMax($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::MATCH_MAX, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterialRef(CcAssesmentResponseMatref $object) |
||||||
|
{ |
||||||
|
$this->materialRef = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setFlowMat(CcAssesmentFlowMattype $object) |
||||||
|
{ |
||||||
|
$this->flowMat = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::RESPONSE_LABEL); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->material)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->materialRef)) { |
||||||
|
$this->materialRef->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->flowMat)) { |
||||||
|
$this->flowMat->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentResponseMatref extends CcAssesmentMatref |
||||||
|
{ |
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::MATERIAL_REF); |
||||||
|
$doc->appendNewAttributeNs($node, $namespace, CcQtiTags::LINKREFID, $this->linkref); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentResponseStrtype extends CcResponseLidtype |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$rtt = parent::__construct(); |
||||||
|
$this->tagname = CcQtiTags::RESPONSE_STR; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentResprocessingtype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $decvar = null; |
||||||
|
protected $respconditions = []; |
||||||
|
|
||||||
|
public function setDecvar(CcAssesmentDecvartype $object) |
||||||
|
{ |
||||||
|
$this->decvar = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function addRespcondition(CcAssesmentRespconditiontype $object) |
||||||
|
{ |
||||||
|
$this->respconditions[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::RESPROCESSING); |
||||||
|
$outcomes = $doc->appendNewElementNs($node, $namespace, CcQtiTags::OUTCOMES); |
||||||
|
if (!empty($this->decvar)) { |
||||||
|
$this->decvar->generate($doc, $outcomes, $namespace); |
||||||
|
} |
||||||
|
if (!empty($this->respconditions)) { |
||||||
|
foreach ($this->respconditions as $rcond) { |
||||||
|
$rcond->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentRubricBase extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $material = null; |
||||||
|
|
||||||
|
public function setMaterial($object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$rubric = $doc->appendNewElementNs($item, $namespace, CcQtiTags::RUBRIC); |
||||||
|
if (!empty($this->material)) { |
||||||
|
$this->material->generate($doc, $rubric, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,48 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentSection extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
protected $items = []; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, CcHelpers::uuidgen('I_')); |
||||||
|
$this->setSetting(CcQtiTags::TITLE); |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML); |
||||||
|
} |
||||||
|
|
||||||
|
public function setIdent($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setTitle($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::TITLE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLang($value) |
||||||
|
{ |
||||||
|
$this->setSettingWns(CcQtiTags::XML_LANG, CcXmlNamespace::XML, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function addItem(CcAssesmentSectionItem $object) |
||||||
|
{ |
||||||
|
$this->items[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::SECTION); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
if (!empty($this->items)) { |
||||||
|
foreach ($this->items as $item) { |
||||||
|
$item->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,56 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssesmentSectionItem extends CcAssesmentSection |
||||||
|
{ |
||||||
|
protected $itemmetadata = null; |
||||||
|
protected $presentation = null; |
||||||
|
protected $resprocessing = []; |
||||||
|
protected $itemfeedback = []; |
||||||
|
|
||||||
|
public function setItemmetadata(CcAssesmentItemmetadata $object) |
||||||
|
{ |
||||||
|
$this->itemmetadata = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setPresentation(CcAssesmentPresentation $object) |
||||||
|
{ |
||||||
|
$this->presentation = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function addResprocessing(CcAssesmentResprocessingtype $object) |
||||||
|
{ |
||||||
|
$this->resprocessing[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function addItemfeedback(CcAssesmentItemfeedbacktype $object) |
||||||
|
{ |
||||||
|
$this->itemfeedback[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::ITEM); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->itemmetadata)) { |
||||||
|
$this->itemmetadata->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->presentation)) { |
||||||
|
$this->presentation->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->resprocessing)) { |
||||||
|
foreach ($this->resprocessing as $resprocessing) { |
||||||
|
$resprocessing->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->itemfeedback)) { |
||||||
|
foreach ($this->itemfeedback as $itemfeedback) { |
||||||
|
$itemfeedback->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,53 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentConditionvar extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $and = null; |
||||||
|
protected $other = null; |
||||||
|
protected $varequal = []; |
||||||
|
protected $varsubstring = null; |
||||||
|
|
||||||
|
public function setAnd(CcAssignmentConditionvarAndtype $object) |
||||||
|
{ |
||||||
|
$this->and = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setOther(CcAssignmentConditionvarOthertype $object) |
||||||
|
{ |
||||||
|
$this->other = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setVarequal(CcAssignmentConditionvarVarequaltype $object) |
||||||
|
{ |
||||||
|
$this->varequal[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setVarsubstring(CcAssignmentConditionvarVarsubstringtype $object) |
||||||
|
{ |
||||||
|
$this->varsubstring = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::CONDITIONVAR); |
||||||
|
|
||||||
|
if (!empty($this->and)) { |
||||||
|
$this->and->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->other)) { |
||||||
|
$this->other->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->varequal)) { |
||||||
|
foreach ($this->varequal as $varequal) { |
||||||
|
$varequal->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->varsubstring)) { |
||||||
|
$this->varsubstring->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentConditionvarAndtype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $nots = []; |
||||||
|
protected $varequals = []; |
||||||
|
|
||||||
|
public function setNot(CcAssignmentConditionvarVarequaltype $object) |
||||||
|
{ |
||||||
|
$this->nots[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setVarequal(CcAssignmentConditionvarVarequaltype $object) |
||||||
|
{ |
||||||
|
$this->varequals[] = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::AND_); |
||||||
|
if (!empty($this->nots)) { |
||||||
|
foreach ($this->nots as $notv) { |
||||||
|
$not = $doc->appendNewElementNs($node, $namespace, CcQtiTags::NOT_); |
||||||
|
$notv->generate($doc, $not, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->varequals)) { |
||||||
|
foreach ($this->varequals as $varequal) { |
||||||
|
$varequal->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentConditionvarOthertype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$doc->appendNewElementNs($item, $namespace, CcQtiTags::OTHER); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentConditionvarVarequaltype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $tagname = null; |
||||||
|
protected $answerid = null; |
||||||
|
|
||||||
|
public function __construct($value = null) |
||||||
|
{ |
||||||
|
if (is_null($value)) { |
||||||
|
throw new InvalidArgumentException('Must not pass null!'); |
||||||
|
} |
||||||
|
$this->answerid = $value; |
||||||
|
$this->setSetting(CcQtiTags::RESPIDENT); |
||||||
|
$this->setSetting(CcQtiTags::CASE_); |
||||||
|
$this->tagname = CcQtiTags::VAREQUAL; |
||||||
|
} |
||||||
|
|
||||||
|
public function setRespident($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::RESPIDENT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableCase($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiTags::CASE_, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, $this->tagname, $this->answerid); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentConditionvarVarsubstringtype extends CcAssignmentConditionvarVarequaltype |
||||||
|
{ |
||||||
|
public function __construct($value) |
||||||
|
{ |
||||||
|
parent::__construct($value); |
||||||
|
$this->tagname = CcQtiTags::VARSUBSTRING; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentDisplayfeedbacktype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::FEEDBACKTYPE); |
||||||
|
$this->setSetting(CcQtiTags::LINKREFID); |
||||||
|
} |
||||||
|
|
||||||
|
public function setFeedbacktype($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::FEEDBACKTYPE, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLinkrefid($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::LINKREFID, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::DISPLAYFEEDBACK); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcAssignmentSetvartype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $tagvalue = null; |
||||||
|
|
||||||
|
public function __construct($tagvalue = 100) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::VARNAME, CcQtiValues::SCORE); |
||||||
|
$this->setSetting(CcQtiTags::ACTION, CcQtiValues::SET); |
||||||
|
$this->tagvalue = $tagvalue; |
||||||
|
} |
||||||
|
|
||||||
|
public function setVarname($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::VARNAME, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, CcQtiTags::SETVAR, $this->tagvalue); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcQtiMetadata |
||||||
|
{ |
||||||
|
// Assessment. |
||||||
|
const QMD_ASSESSMENTTYPE = 'qmd_assessmenttype'; |
||||||
|
const QMD_SCORETYPE = 'qmd_scoretype'; |
||||||
|
const QMD_FEEDBACKPERMITTED = 'qmd_feedbackpermitted'; |
||||||
|
const QMD_HINTSPERMITTED = 'qmd_hintspermitted'; |
||||||
|
const QMD_SOLUTIONSPERMITTED = 'qmd_solutionspermitted'; |
||||||
|
const QMD_TIMELIMIT = 'qmd_timelimit'; |
||||||
|
const CC_ALLOW_LATE_SUBMISSION = 'cc_allow_late_submission'; |
||||||
|
const CC_MAXATTEMPTS = 'cc_maxattempts'; |
||||||
|
const CC_PROFILE = 'cc_profile'; |
||||||
|
|
||||||
|
// Items. |
||||||
|
const CC_WEIGHTING = 'cc_weighting'; |
||||||
|
const QMD_SCORINGPERMITTED = 'qmd_scoringpermitted'; |
||||||
|
const QMD_COMPUTERSCORED = 'qmd_computerscored'; |
||||||
|
const CC_QUESTION_CATEGORY = 'cc_question_category'; |
||||||
|
} |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcQtiProfiletype |
||||||
|
{ |
||||||
|
const MULTIPLE_CHOICE = 'cc.multiple_choice.v0p1'; |
||||||
|
const MULTIPLE_RESPONSE = 'cc.multiple_response.v0p1'; |
||||||
|
const TRUE_FALSE = 'cc.true_false.v0p1'; |
||||||
|
const FIELD_ENTRY = 'cc.fib.v0p1'; |
||||||
|
const PATTERN_MATCH = 'cc.pattern_match.v0p1'; |
||||||
|
const ESSAY = 'cc.essay.v0p1'; |
||||||
|
|
||||||
|
/** |
||||||
|
* validates a profile value. |
||||||
|
* |
||||||
|
* @param string $value |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
public static function valid($value) |
||||||
|
{ |
||||||
|
static $verificationValues = [self::ESSAY, |
||||||
|
self::FIELD_ENTRY, |
||||||
|
self::MULTIPLE_CHOICE, |
||||||
|
self::MULTIPLE_RESPONSE, |
||||||
|
self::PATTERN_MATCH, |
||||||
|
self::TRUE_FALSE, |
||||||
|
]; |
||||||
|
|
||||||
|
return in_array($value, $verificationValues); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,88 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcQtiTags |
||||||
|
{ |
||||||
|
const QUESTESTINTEROP = 'questestinterop'; |
||||||
|
const ASSESSMENT = 'assessment'; |
||||||
|
const QTIMETADATA = 'qtimetadata'; |
||||||
|
const QTIMETADATAFIELD = 'qtimetadatafield'; |
||||||
|
const FIELDLABEL = 'fieldlabel'; |
||||||
|
const FIELDENTRY = 'fieldentry'; |
||||||
|
const SECTION = 'section'; |
||||||
|
const IDENT = 'ident'; |
||||||
|
const ITEM = 'item'; |
||||||
|
const TITLE = 'title'; |
||||||
|
const ITEMMETADATA = 'itemmetadata'; |
||||||
|
const PRESENTATION = 'presentation'; |
||||||
|
const MATERIAL = 'material'; |
||||||
|
const MATTEXT = 'mattext'; |
||||||
|
const MATREF = 'matref'; |
||||||
|
const MATBREAK = 'matbreak'; |
||||||
|
const TEXTTYPE = 'texttype'; |
||||||
|
const RESPONSE_LID = 'response_lid'; |
||||||
|
const RENDER_CHOICE = 'render_choice'; |
||||||
|
const RESPONSE_LABEL = 'response_label'; |
||||||
|
const RESPROCESSING = 'resprocessing'; |
||||||
|
const OUTCOMES = 'outcomes'; |
||||||
|
const DECVAR = 'decvar'; |
||||||
|
const RESPCONDITION = 'respcondition'; |
||||||
|
const CONDITIONVAR = 'conditionvar'; |
||||||
|
const OTHER = 'other'; |
||||||
|
const DISPLAYFEEDBACK = 'displayfeedback'; |
||||||
|
const MAXVALUE = 'maxvalue'; |
||||||
|
const MINVALUE = 'minvalue'; |
||||||
|
const VARNAME = 'varname'; |
||||||
|
const VARTYPE = 'vartype'; |
||||||
|
const CONTINUE_ = 'continue'; |
||||||
|
const FEEDBACKTYPE = 'feedbacktype'; |
||||||
|
const LINKREFID = 'linkrefid'; |
||||||
|
const VAREQUAL = 'varequal'; |
||||||
|
const RESPIDENT = 'respident'; |
||||||
|
const ITEMFEEDBACK = 'itemfeedback'; |
||||||
|
const FLOW_MAT = 'flow_mat'; |
||||||
|
const RCARDINALITY = 'rcardinality'; |
||||||
|
const CHARSET = 'charset'; |
||||||
|
const LABEL = 'label'; |
||||||
|
const URI = 'uri'; |
||||||
|
const WIDTH = 'width'; |
||||||
|
const HEIGHT = 'height'; |
||||||
|
const X0 = 'x0'; |
||||||
|
const Y0 = 'y0'; |
||||||
|
const XML_LANG = 'lang'; |
||||||
|
const XML_SPACE = 'space'; |
||||||
|
const RUBRIC = 'rubric'; |
||||||
|
const ALTMATERIAL = 'altmaterial'; |
||||||
|
const PRESENTATION_MATERIAL = 'presentation_material'; |
||||||
|
const T_CLASS = 'class'; |
||||||
|
const MATERIAL_REF = 'material_ref'; |
||||||
|
const RTIMING = 'rtiming'; |
||||||
|
const RENDER_FIB = 'render_fib'; |
||||||
|
const SHUFFLE = 'shuffle'; |
||||||
|
const MINNUMBER = 'minnumber'; |
||||||
|
const MAXNUMBER = 'maxnumber'; |
||||||
|
const ENCODING = 'encoding'; |
||||||
|
const MAXCHARS = 'maxchars'; |
||||||
|
const PROMPT = 'prompt'; |
||||||
|
const FIBTYPE = 'fibtype'; |
||||||
|
const ROWS = 'rows'; |
||||||
|
const COLUMNS = 'columns'; |
||||||
|
const LABELREFID = 'labelrefid'; |
||||||
|
const RSHUFFLE = 'rshuffle'; |
||||||
|
const MATCH_GROUP = 'match_group'; |
||||||
|
const MATCH_MAX = 'match_max'; |
||||||
|
const FLOW = 'flow'; |
||||||
|
const RESPONSE_STR = 'response_str'; |
||||||
|
const FLOW_LABEL = 'flow_label'; |
||||||
|
const SETVAR = 'setvar'; |
||||||
|
const ACTION = 'action'; |
||||||
|
const AND_ = 'and'; |
||||||
|
const NOT_ = 'not'; |
||||||
|
const CASE_ = 'case'; |
||||||
|
const VARSUBSTRING = 'varsubstring'; |
||||||
|
const HINT = 'hint'; |
||||||
|
const SOLUTION = 'solution'; |
||||||
|
const FEEDBACKSTYLE = 'feedbackstyle'; |
||||||
|
const SOLUTIONMATERIAL = 'solutionmaterial'; |
||||||
|
const HINTMATERIAL = 'hintmaterial'; |
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcQtiValues |
||||||
|
{ |
||||||
|
const EXAM_PROFILE = 'cc.exam.v0p1'; |
||||||
|
const YES = 'Yes'; |
||||||
|
const NO = 'No'; |
||||||
|
const RESPONSE = 'Response'; |
||||||
|
const SOLUTION = 'Solution'; |
||||||
|
const HINT = 'Hint'; |
||||||
|
const EXAMINATION = 'Examination'; |
||||||
|
const PERCENTAGE = 'Percentage'; |
||||||
|
const UNLIMITED = 'unlimited'; |
||||||
|
const SINGLE = 'Single'; |
||||||
|
const MULTIPLE = 'Multiple'; |
||||||
|
const ORDERER = 'Ordered'; |
||||||
|
const ASTERISK = 'Asterisk'; |
||||||
|
const BOX = 'Box'; |
||||||
|
const DASHLINE = 'Dashline'; |
||||||
|
const UNDERLINE = 'Underline'; |
||||||
|
const DECIMAL = 'Decimal'; |
||||||
|
const INTEGER = 'Integer'; |
||||||
|
const SCIENTIFIC = 'Scientific'; |
||||||
|
const STRING = 'String'; |
||||||
|
const SCORE = 'SCORE'; |
||||||
|
const SET = 'Set'; |
||||||
|
const COMPLETE = 'Complete'; |
||||||
|
const TEXTTYPE = 'text/plain'; |
||||||
|
const HTMLTYPE = 'text/html'; |
||||||
|
} |
||||||
@ -0,0 +1,44 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcQuestionMetadata extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Constructs metadata. |
||||||
|
* |
||||||
|
* @param string $profile |
||||||
|
* |
||||||
|
* @throws InvalidArgumentException |
||||||
|
*/ |
||||||
|
public function __construct($profile) |
||||||
|
{ |
||||||
|
if (!CcQtiProfiletype::valid($profile)) { |
||||||
|
throw new InvalidArgumentException('Invalid profile type!'); |
||||||
|
} |
||||||
|
$this->setSetting(CcQtiMetadata::CC_PROFILE, $profile); |
||||||
|
$this->setSetting(CcQtiMetadata::CC_QUESTION_CATEGORY); |
||||||
|
$this->setSetting(CcQtiMetadata::CC_WEIGHTING); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_SCORINGPERMITTED); |
||||||
|
$this->setSetting(CcQtiMetadata::QMD_COMPUTERSCORED); |
||||||
|
} |
||||||
|
|
||||||
|
public function setCategory($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiMetadata::CC_QUESTION_CATEGORY, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setWeighting($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiMetadata::CC_WEIGHTING, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableScoringpermitted($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiMetadata::QMD_SCORINGPERMITTED, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableComputerscored($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiMetadata::QMD_COMPUTERSCORED, $value); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,86 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $metadata = []; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $namespace |
||||||
|
*/ |
||||||
|
public function generateAttributes(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
foreach ($this->metadata as $attribute => $value) { |
||||||
|
if (!is_null($value)) { |
||||||
|
if (!is_array($value)) { |
||||||
|
$doc->appendNewAttributeNs($item, $namespace, $attribute, $value); |
||||||
|
} else { |
||||||
|
$ns = key($value); |
||||||
|
$nval = current($value); |
||||||
|
if (!is_null($nval)) { |
||||||
|
$doc->appendNewAttributeNs($item, $ns, $attribute, $nval); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $namespace |
||||||
|
*/ |
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$qtimetadata = $doc->appendNewElementNs($item, $namespace, CcQtiTags::QTIMETADATA); |
||||||
|
foreach ($this->metadata as $label => $entry) { |
||||||
|
if (!is_null($entry)) { |
||||||
|
$qtimetadatafield = $doc->appendNewElementNs($qtimetadata, $namespace, CcQtiTags::QTIMETADATAFIELD); |
||||||
|
$doc->appendNewElementNs($qtimetadatafield, $namespace, CcQtiTags::FIELDLABEL, $label); |
||||||
|
$doc->appendNewElementNs($qtimetadatafield, $namespace, CcQtiTags::FIELDENTRY, $entry); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $setting |
||||||
|
* @param mixed $value |
||||||
|
*/ |
||||||
|
protected function setSetting($setting, $value = null) |
||||||
|
{ |
||||||
|
$this->metadata[$setting] = $value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $setting |
||||||
|
* |
||||||
|
* @return mixed |
||||||
|
*/ |
||||||
|
protected function getSetting($setting) |
||||||
|
{ |
||||||
|
$result = null; |
||||||
|
if (array_key_exists($setting, $this->metadata)) { |
||||||
|
$result = $this->metadata[$setting]; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $setting |
||||||
|
* @param string $namespace |
||||||
|
* @param string $value |
||||||
|
*/ |
||||||
|
protected function setSettingWns($setting, $namespace, $value = null) |
||||||
|
{ |
||||||
|
$this->metadata[$setting] = [$namespace => $value]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $setting |
||||||
|
* @param bool $value |
||||||
|
*/ |
||||||
|
protected function enableSettingYesno($setting, $value = true) |
||||||
|
{ |
||||||
|
$svalue = $value ? CcQtiValues::YES : CcQtiValues::NO; |
||||||
|
$this->setSetting($setting, $svalue); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,81 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
class CcResponseLidtype extends CcQuestionMetadataBase |
||||||
|
{ |
||||||
|
protected $tagname = null; |
||||||
|
protected $material = null; |
||||||
|
protected $materialRef = null; |
||||||
|
protected $renderChoice = null; |
||||||
|
protected $renderFib = null; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::RCARDINALITY, CcQtiValues::SINGLE); |
||||||
|
$this->setSetting(CcQtiTags::RTIMING); |
||||||
|
$this->setSetting(CcQtiTags::IDENT, CcHelpers::uuidgen('I_')); |
||||||
|
$this->tagname = CcQtiTags::RESPONSE_LID; |
||||||
|
} |
||||||
|
|
||||||
|
public function setRcardinality($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::RCARDINALITY, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function enableRtiming($value = true) |
||||||
|
{ |
||||||
|
$this->enableSettingYesno(CcQtiTags::RTIMING, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function setIdent($value) |
||||||
|
{ |
||||||
|
$this->setSetting(CcQtiTags::IDENT, $value); |
||||||
|
} |
||||||
|
|
||||||
|
public function getIdent() |
||||||
|
{ |
||||||
|
return $this->getSetting(CcQtiTags::IDENT); |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterialRef(CcAssesmentResponseMatref $object) |
||||||
|
{ |
||||||
|
$this->materialRef = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setMaterial(CcAssesmentMaterial $object) |
||||||
|
{ |
||||||
|
$this->material = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setRenderChoice(CcAssesmentRenderChoicetype $object) |
||||||
|
{ |
||||||
|
$this->renderChoice = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function setRenderFib(CcAssesmentRenderFibtype $object) |
||||||
|
{ |
||||||
|
$this->renderFib = $object; |
||||||
|
} |
||||||
|
|
||||||
|
public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) |
||||||
|
{ |
||||||
|
$node = $doc->appendNewElementNs($item, $namespace, $this->tagname); |
||||||
|
$this->generateAttributes($doc, $node, $namespace); |
||||||
|
|
||||||
|
if (!empty($this->material) && empty($this->materialRef)) { |
||||||
|
$this->material->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->materialRef) && empty($this->material)) { |
||||||
|
$this->materialRef->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->renderChoice) && empty($this->renderFib)) { |
||||||
|
$this->renderChoice->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($this->renderFib) && empty($this->renderChoice)) { |
||||||
|
$this->renderFib->generate($doc, $node, $namespace); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/cc_asssesment.php under GNU/GPL license */ |
||||||
|
|
||||||
|
abstract class CcXmlNamespace |
||||||
|
{ |
||||||
|
const XML = 'http://www.w3.org/XML/1998/namespace'; |
||||||
|
} |
||||||
@ -0,0 +1,236 @@ |
|||||||
|
<?php |
||||||
|
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/gral_lib/ccdependencyparser.php under GNU/GPL license */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts \ Directory separator to the / more suitable for URL. |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
*/ |
||||||
|
function toUrlPath(&$path) |
||||||
|
{ |
||||||
|
for ($count = 0; $count < strlen($path); $count++) { |
||||||
|
$chr = $path[$count]; |
||||||
|
if (($chr == '\\')) { |
||||||
|
$path[$count] = '/'; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns relative path from two directories with full path. |
||||||
|
* |
||||||
|
* @param string $path1 |
||||||
|
* @param string $path2 |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
function pathDiff($path1, $path2) |
||||||
|
{ |
||||||
|
toUrlPath($path1); |
||||||
|
toUrlPath($path2); |
||||||
|
$result = ""; |
||||||
|
$bl2 = strlen($path2); |
||||||
|
$a = strpos($path1, $path2); |
||||||
|
if ($a !== false) { |
||||||
|
$result = trim(substr($path1, $bl2 + $a), '/'); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts direcotry separator in given path to / to validate in CC |
||||||
|
* Value is passed byref hence variable itself is changed. |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
*/ |
||||||
|
function toNativePath(&$path) |
||||||
|
{ |
||||||
|
for ($count = 0; $count < strlen($path); $count++) { |
||||||
|
$chr = $path[$count]; |
||||||
|
if (($chr == '\\') || ($chr == '/')) { |
||||||
|
$path[$count] = '/'; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Function strips url part from css link. |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
* @param string $rootDir |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
function stripUrl($path, $rootDir = '') |
||||||
|
{ |
||||||
|
$result = $path; |
||||||
|
if (is_string($path) && ($path != '')) { |
||||||
|
$start = strpos($path, '(') + 1; |
||||||
|
$length = strpos($path, ')') - $start; |
||||||
|
$rut = $rootDir.substr($path, $start, $length); |
||||||
|
$result = fullPath($rut, '/'); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get full path |
||||||
|
* |
||||||
|
* @param string $path |
||||||
|
* @param string $dirsep |
||||||
|
* @return false|string |
||||||
|
*/ |
||||||
|
function fullPath($path, $dirsep = DIRECTORY_SEPARATOR) |
||||||
|
{ |
||||||
|
$token = '$IMS-CC-FILEBASE$'; |
||||||
|
$path = str_replace($token, '', $path); |
||||||
|
if (is_string($path) && ($path != '')) { |
||||||
|
$sep = $dirsep; |
||||||
|
$dotDir = '.'; |
||||||
|
$upDir = '..'; |
||||||
|
$length = strlen($path); |
||||||
|
$rtemp = trim($path); |
||||||
|
$start = strrpos($path, $sep); |
||||||
|
$canContinue = ($start !== false); |
||||||
|
$result = $canContinue ? '' : $path; |
||||||
|
$rcount = 0; |
||||||
|
while ($canContinue) { |
||||||
|
$dirPart = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp; |
||||||
|
$canContinue = ($dirPart !== false); |
||||||
|
if ($canContinue) { |
||||||
|
if ($dirPart != $dotDir) { |
||||||
|
if ($dirPart == $upDir) { |
||||||
|
$rcount++; |
||||||
|
} else { |
||||||
|
if ($rcount > 0) { |
||||||
|
$rcount--; |
||||||
|
} else { |
||||||
|
$result = ($result == '') ? $dirPart : $dirPart.$sep.$result; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
$rtemp = substr($path, 0, $start); |
||||||
|
$start = strrpos($rtemp, $sep); |
||||||
|
$canContinue = (($start !== false) || (strlen($rtemp) > 0)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* validates URL. |
||||||
|
* |
||||||
|
* @param string $url |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
function isUrl($url) |
||||||
|
{ |
||||||
|
$result = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) !== false; |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the dependency files of the $fname file |
||||||
|
* |
||||||
|
* @param string $manifestroot |
||||||
|
* @param string $fname |
||||||
|
* @param string $folder |
||||||
|
* @param array $filenames |
||||||
|
*/ |
||||||
|
function getDepFiles($manifestroot, $fname, $folder, &$filenames) |
||||||
|
{ |
||||||
|
static $types = ['xhtml' => true, 'html' => true, 'htm' => true]; |
||||||
|
$extension = strtolower(trim(pathinfo($fname, PATHINFO_EXTENSION))); |
||||||
|
$filenames = []; |
||||||
|
if (isset($types[$extension])) { |
||||||
|
$dcx = new XMLGenericDocument(); |
||||||
|
$filename = $manifestroot.$folder.$fname; |
||||||
|
if (!file_exists($filename)) { |
||||||
|
$filename = $manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname; |
||||||
|
} |
||||||
|
if (file_exists($filename)) { |
||||||
|
$res = $dcx->loadHTMLFile($filename); |
||||||
|
if ($res) { |
||||||
|
getDepFilesHTML($manifestroot, $fname, $filenames, $dcx, $folder); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the dependency of .html of the $fname file |
||||||
|
* |
||||||
|
* @param string $manifestroot |
||||||
|
* @param string $fname |
||||||
|
* @param string $filenames |
||||||
|
* @param string $dcx |
||||||
|
* @param string $folder |
||||||
|
*/ |
||||||
|
function getDepFilesHTML($manifestroot, $fname, &$filenames, &$dcx, $folder) |
||||||
|
{ |
||||||
|
$dcx->resetXpath(); |
||||||
|
$nlist = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href"); |
||||||
|
$cssObjArray = []; |
||||||
|
foreach ($nlist as $nl) { |
||||||
|
$item = $folder.$nl->nodeValue; |
||||||
|
$path_parts = pathinfo($item); |
||||||
|
$fname = $path_parts['basename']; |
||||||
|
$ext = array_key_exists('extension', $path_parts) ? $path_parts['extension'] : ''; |
||||||
|
if (!isUrl($folder.$nl->nodeValue) && !isUrl($nl->nodeValue)) { |
||||||
|
$path = $folder.$nl->nodeValue; |
||||||
|
$file = fullPath($path, "/"); |
||||||
|
toNativePath($file); |
||||||
|
if (file_exists($manifestroot.DIRECTORY_SEPARATOR.$file)) { |
||||||
|
$filenames[$file] = $file; |
||||||
|
} |
||||||
|
} |
||||||
|
if ($ext == 'css') { |
||||||
|
$css = new CssParser(); |
||||||
|
$css->parse($dcx->filePath().$nl->nodeValue); |
||||||
|
$cssObjArray[$item] = $css; |
||||||
|
} |
||||||
|
} |
||||||
|
$nlist = $dcx->nodeList("//*/@class"); |
||||||
|
foreach ($nlist as $nl) { |
||||||
|
$item = $folder.$nl->nodeValue; |
||||||
|
foreach ($cssObjArray as $csskey => $cssobj) { |
||||||
|
$bimg = $cssobj->get($item, "background-image"); |
||||||
|
$limg = $cssobj->get($item, "list-style-image"); |
||||||
|
$npath = pathinfo($csskey); |
||||||
|
if ((!empty($bimg)) && ($bimg != 'none')) { |
||||||
|
$value = stripUrl($bimg, $npath['dirname'].'/'); |
||||||
|
$filenames[$value] = $value; |
||||||
|
} elseif ((!empty($limg)) && ($limg != 'none')) { |
||||||
|
$value = stripUrl($limg, $npath['dirname'].'/'); |
||||||
|
$filenames[$value] = $value; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
$elemsToCheck = ["body", "p", "ul", "h4", "a", "th"]; |
||||||
|
$doWeHaveIt = []; |
||||||
|
foreach ($elemsToCheck as $elem) { |
||||||
|
$doWeHaveIt[$elem] = ($dcx->nodeList("//".$elem)->length > 0); |
||||||
|
} |
||||||
|
foreach ($elemsToCheck as $elem) { |
||||||
|
if ($doWeHaveIt[$elem]) { |
||||||
|
foreach ($cssObjArray as $csskey => $cssobj) { |
||||||
|
$sb = $cssobj->get($elem, "background-image"); |
||||||
|
$sbl = $cssobj->get($elem, "list-style-image"); |
||||||
|
$npath = pathinfo($csskey); |
||||||
|
if ((!empty($sb)) && ($sb != 'none')) { |
||||||
|
$value = stripUrl($sb, $npath['dirname'].'/'); |
||||||
|
$filenames[$value] = $value; |
||||||
|
} elseif ((!empty($sbl)) && ($sbl != 'none')) { |
||||||
|
$value = stripUrl($sbl, $npath['dirname'].'/'); |
||||||
|
$filenames[$value] = $value; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,283 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
abstract class CcHelpers |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Checks extension of the supplied filename. |
||||||
|
* |
||||||
|
* @param string $filename |
||||||
|
*/ |
||||||
|
public static function isHtml($filename) |
||||||
|
{ |
||||||
|
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); |
||||||
|
|
||||||
|
return in_array($extension, ['htm', 'html']); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates unique identifier. |
||||||
|
* |
||||||
|
* @param string $prefix |
||||||
|
* @param string $suffix |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public static function uuidgen($prefix = '', $suffix = '', $uppercase = true) |
||||||
|
{ |
||||||
|
$uuid = trim(sprintf('%s%04x%04x%s', $prefix, mt_rand(0, 65535), mt_rand(0, 65535), $suffix)); |
||||||
|
$result = $uppercase ? strtoupper($uuid) : strtolower($uuid); |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new folder with random name. |
||||||
|
* |
||||||
|
* @param string $where |
||||||
|
* @param string $prefix |
||||||
|
* @param string $suffix |
||||||
|
* |
||||||
|
* @return mixed - directory short name or false in case of failure |
||||||
|
*/ |
||||||
|
public static function randomdir($where, $prefix = '', $suffix = '') |
||||||
|
{ |
||||||
|
$permDirs = api_get_permissions_for_new_directories(); |
||||||
|
|
||||||
|
$dirname = false; |
||||||
|
$randomname = self::uuidgen($prefix, $suffix, false); |
||||||
|
$newdirname = $where.DIRECTORY_SEPARATOR.$randomname; |
||||||
|
if (mkdir($newdirname)) { |
||||||
|
chmod($newdirname, $permDirs); |
||||||
|
$dirname = $randomname; |
||||||
|
} |
||||||
|
|
||||||
|
return $dirname; |
||||||
|
} |
||||||
|
|
||||||
|
public static function buildQuery($attributes, $search) |
||||||
|
{ |
||||||
|
$result = ''; |
||||||
|
foreach ($attributes as $attribute) { |
||||||
|
if ($result != '') { |
||||||
|
$result .= ' | '; |
||||||
|
} |
||||||
|
$result .= "//*[starts-with(@{$attribute},'{$search}')]/@{$attribute}"; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public static function processEmbeddedFiles(&$doc, $attributes, $search, $customslash = null) |
||||||
|
{ |
||||||
|
$result = []; |
||||||
|
$query = self::buildQuery($attributes, $search); |
||||||
|
$list = $doc->nodeList($query); |
||||||
|
foreach ($list as $filelink) { |
||||||
|
$rvalue = str_replace($search, '', $filelink->nodeValue); |
||||||
|
if (!empty($customslash)) { |
||||||
|
$rvalue = str_replace($customslash, '/', $rvalue); |
||||||
|
} |
||||||
|
$result[] = rawurldecode($rvalue); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get list of embedded files. |
||||||
|
* |
||||||
|
* @param string $html |
||||||
|
* |
||||||
|
* @return multitype:mixed |
||||||
|
*/ |
||||||
|
public static function embeddedFiles($html) |
||||||
|
{ |
||||||
|
$result = []; |
||||||
|
$doc = new XMLGenericDocument(); |
||||||
|
$doc->doc->validateOnParse = false; |
||||||
|
$doc->doc->strictErrorChecking = false; |
||||||
|
if (!empty($html) && $doc->loadHTML($html)) { |
||||||
|
$attributes = ['src', 'href']; |
||||||
|
$result1 = self::processEmbeddedFiles($doc, $attributes, '@@PLUGINFILE@@'); |
||||||
|
$result2 = self::processEmbeddedFiles($doc, $attributes, '$@FILEPHP@$', '$@SLASH@$'); |
||||||
|
$result = array_merge($result1, $result2); |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public static function embeddedMapping($packageroot, $contextid = null, $folder = null, $docfilepath = null) |
||||||
|
{ |
||||||
|
if (isset($folder)) { |
||||||
|
$files = array_diff(scandir($folder), ['.', '..']); |
||||||
|
} else { |
||||||
|
$folder = dirname($docfilepath); |
||||||
|
$files[] = basename($docfilepath); |
||||||
|
} |
||||||
|
|
||||||
|
$depfiles = []; |
||||||
|
foreach ($files as $file) { |
||||||
|
$mainfile = 1; |
||||||
|
$filename = $file; |
||||||
|
$filepath = DIRECTORY_SEPARATOR; |
||||||
|
$source = ''; |
||||||
|
$author = ''; |
||||||
|
$license = ''; |
||||||
|
$hashedname = ''; |
||||||
|
$hashpart = ''; |
||||||
|
|
||||||
|
$location = $folder.DIRECTORY_SEPARATOR.$file; |
||||||
|
$type = mime_content_type($file); |
||||||
|
|
||||||
|
$depfiles[$filepath.$filename] = [$location, |
||||||
|
($mainfile == 1), |
||||||
|
strtolower(str_replace(' ', '_', $filename)), |
||||||
|
$type, |
||||||
|
$source, |
||||||
|
$author, |
||||||
|
$license, |
||||||
|
strtolower(str_replace(' ', '_', $filepath)), ]; |
||||||
|
} |
||||||
|
|
||||||
|
return $depfiles; |
||||||
|
} |
||||||
|
|
||||||
|
public static function addFiles(CcIManifest &$manifest, $packageroot, $outdir, $allinone = true, $folder = null, $docfilepath = null) |
||||||
|
{ |
||||||
|
$permDirs = api_get_permissions_for_new_directories(); |
||||||
|
|
||||||
|
$files = CcHelpers::embeddedMapping($packageroot, null, $folder, $docfilepath); |
||||||
|
|
||||||
|
$rdir = $allinone ? new CcResourceLocation($outdir) : null; |
||||||
|
foreach ($files as $virtual => $values) { |
||||||
|
$clean_filename = $values[2]; |
||||||
|
if (!$allinone) { |
||||||
|
$rdir = new CcResourceLocation($outdir); |
||||||
|
} |
||||||
|
$rtp = $rdir->fullpath().$values[7].$clean_filename; |
||||||
|
//Are there any relative virtual directories? |
||||||
|
//let us try to recreate them |
||||||
|
$justdir = $rdir->fullpath(false).$values[7]; |
||||||
|
if (!file_exists($justdir)) { |
||||||
|
if (!mkdir($justdir, $permDirs, true)) { |
||||||
|
throw new RuntimeException('Unable to create directories!'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$source = $values[0]; |
||||||
|
if (is_dir($source)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (!copy($source, $rtp)) { |
||||||
|
throw new RuntimeException('Unable to copy files!'); |
||||||
|
} |
||||||
|
$resource = new CcResources($rdir->rootdir(), |
||||||
|
$values[7].$clean_filename, |
||||||
|
$rdir->dirname(false)); |
||||||
|
|
||||||
|
$res = $manifest->addResource($resource, null, CcVersion13::WEBCONTENT); |
||||||
|
|
||||||
|
PkgStaticResources::instance()->add($virtual, |
||||||
|
$res[0], |
||||||
|
$rdir->dirname(false).$values[7].$clean_filename, |
||||||
|
$values[1], |
||||||
|
$resource); |
||||||
|
} |
||||||
|
|
||||||
|
PkgStaticResources::instance()->finished = true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Excerpt from IMS CC 1.1 overview : |
||||||
|
* No spaces in filenames, directory and file references should |
||||||
|
* employ all lowercase or all uppercase - no mixed case. |
||||||
|
* |
||||||
|
* @param string $packageroot |
||||||
|
* @param int $contextid |
||||||
|
* @param string $outdir |
||||||
|
* @param bool $allinone |
||||||
|
* |
||||||
|
* @throws RuntimeException |
||||||
|
*/ |
||||||
|
public static function handleStaticContent(CcIManifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true, $folder = null) |
||||||
|
{ |
||||||
|
self::addFiles($manifest, $packageroot, $outdir, $allinone, $folder); |
||||||
|
|
||||||
|
return PkgStaticResources::instance()->getValues(); |
||||||
|
} |
||||||
|
|
||||||
|
public static function handleResourceContent(CcIManifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true, $docfilepath = null) |
||||||
|
{ |
||||||
|
$result = []; |
||||||
|
|
||||||
|
self::addFiles($manifest, $packageroot, $outdir, $allinone, null, $docfilepath); |
||||||
|
|
||||||
|
$files = self::embeddedMapping($packageroot, $contextid, null, $docfilepath); |
||||||
|
$rootnode = null; |
||||||
|
$rootvals = null; |
||||||
|
$depfiles = []; |
||||||
|
$depres = []; |
||||||
|
$flocation = null; |
||||||
|
foreach ($files as $virtual => $values) { |
||||||
|
$vals = PkgStaticResources::instance()->getIdentifier($virtual); |
||||||
|
$resource = $vals[3]; |
||||||
|
$identifier = $resource->identifier; |
||||||
|
$flocation = $vals[1]; |
||||||
|
if ($values[1]) { |
||||||
|
$rootnode = $resource; |
||||||
|
$rootvals = $flocation; |
||||||
|
continue; |
||||||
|
} |
||||||
|
$depres[] = $identifier; |
||||||
|
$depfiles[] = $vals[1]; |
||||||
|
$result[$virtual] = [$identifier, $flocation, false]; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($rootnode)) { |
||||||
|
$rootnode->files = array_merge($rootnode->files, $depfiles); |
||||||
|
$result[$virtual] = [$rootnode->identifier, $rootvals, true]; |
||||||
|
} |
||||||
|
|
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public static function processLinkedFiles($content, CcIManifest &$manifest, $packageroot, |
||||||
|
$contextid, $outdir, $webcontent = false) |
||||||
|
{ |
||||||
|
// Detect all embedded files |
||||||
|
// copy all files in the cc package stripping any spaces and using only lowercase letters |
||||||
|
// add those files as resources of the type webcontent to the manifest |
||||||
|
// replace the links to the resource using $IMS-CC-FILEBASE$ and their new locations |
||||||
|
// cc_resource has array of files and array of dependencies |
||||||
|
// most likely we would need to add all files as independent resources and than |
||||||
|
// attach them all as dependencies to the forum tag. |
||||||
|
$lfiles = self::embeddedFiles($content); |
||||||
|
$text = $content; |
||||||
|
$deps = []; |
||||||
|
if (!empty($lfiles)) { |
||||||
|
$files = self::handleStaticContent($manifest, |
||||||
|
$packageroot, |
||||||
|
$contextid, |
||||||
|
$outdir); |
||||||
|
$replaceprefix = $webcontent ? '' : '$IMS-CC-FILEBASE$'; |
||||||
|
foreach ($lfiles as $lfile) { |
||||||
|
if (isset($files[$lfile])) { |
||||||
|
$filename = str_replace('%2F', '/', rawurlencode($lfile)); |
||||||
|
$content = str_replace('@@PLUGINFILE@@'.$filename, |
||||||
|
$replaceprefix.'../'.$files[$lfile][1], |
||||||
|
$content); |
||||||
|
// For the legacy stuff. |
||||||
|
$content = str_replace('$@FILEPHP@$'.str_replace('/', '$@SLASH@$', $filename), |
||||||
|
$replaceprefix.'../'.$files[$lfile][1], |
||||||
|
$content); |
||||||
|
$deps[] = $files[$lfile][0]; |
||||||
|
} |
||||||
|
} |
||||||
|
$text = $content; |
||||||
|
} |
||||||
|
|
||||||
|
return [$text, $deps]; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,77 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
final class CcResourceLocation |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Root directory. |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
private $rootdir = null; |
||||||
|
/** |
||||||
|
* new directory. |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
private $dir = null; |
||||||
|
/** |
||||||
|
* Full precalculated path. |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
private $fullpath = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* ctor. |
||||||
|
* |
||||||
|
* @param string $rootdir - path to the containing directory |
||||||
|
* |
||||||
|
* @throws InvalidArgumentException |
||||||
|
* @throws RuntimeException |
||||||
|
*/ |
||||||
|
public function __construct($rootdir) |
||||||
|
{ |
||||||
|
$rdir = realpath($rootdir); |
||||||
|
if (empty($rdir)) { |
||||||
|
throw new InvalidArgumentException('Invalid path!'); |
||||||
|
} |
||||||
|
$dir = CcHelpers::randomdir($rdir, 'i_'); |
||||||
|
if ($dir === false) { |
||||||
|
throw new RuntimeException('Unable to create directory!'); |
||||||
|
} |
||||||
|
$this->rootdir = $rdir; |
||||||
|
$this->dir = $dir; |
||||||
|
$this->fullpath = $rdir.DIRECTORY_SEPARATOR.$dir; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Newly created directory. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function dirname($endseparator = false) |
||||||
|
{ |
||||||
|
return $this->dir.($endseparator ? '/' : ''); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Full path to the new directory. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function fullpath($endseparator = false) |
||||||
|
{ |
||||||
|
return $this->fullpath.($endseparator ? DIRECTORY_SEPARATOR : ''); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns containing dir. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function rootdir($endseparator = false) |
||||||
|
{ |
||||||
|
return $this->rootdir.($endseparator ? DIRECTORY_SEPARATOR : ''); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
class PkgResourceDependencies |
||||||
|
{ |
||||||
|
private $values = []; |
||||||
|
private static $instance = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* @return PkgResourceDependencies |
||||||
|
*/ |
||||||
|
public static function instance() |
||||||
|
{ |
||||||
|
if (empty(self::$instance)) { |
||||||
|
$c = __CLASS__; |
||||||
|
self::$instance = new $c(); |
||||||
|
} |
||||||
|
|
||||||
|
return self::$instance; |
||||||
|
} |
||||||
|
|
||||||
|
public function add(array $deps) |
||||||
|
{ |
||||||
|
$this->values = array_merge($this->values, $deps); |
||||||
|
} |
||||||
|
|
||||||
|
public function reset() |
||||||
|
{ |
||||||
|
$this->values = []; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function getDeps() |
||||||
|
{ |
||||||
|
return $this->values; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
class PkgStaticResources |
||||||
|
{ |
||||||
|
public $finished = false; |
||||||
|
|
||||||
|
private $values = []; |
||||||
|
private static $instance = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* @return PkgStaticResources |
||||||
|
*/ |
||||||
|
public static function instance() |
||||||
|
{ |
||||||
|
if (empty(self::$instance)) { |
||||||
|
$c = __CLASS__; |
||||||
|
self::$instance = new $c(); |
||||||
|
} |
||||||
|
|
||||||
|
return self::$instance; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* add new element. |
||||||
|
* |
||||||
|
* @param string $identifier |
||||||
|
* @param string $file |
||||||
|
* @param bool $main |
||||||
|
*/ |
||||||
|
public function add($key, $identifier, $file, $main, $node = null) |
||||||
|
{ |
||||||
|
$this->values[$key] = [$identifier, $file, $main, $node]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function getValues() |
||||||
|
{ |
||||||
|
return $this->values; |
||||||
|
} |
||||||
|
|
||||||
|
public function getIdentifier($location) |
||||||
|
{ |
||||||
|
return isset($this->values[$location]) ? $this->values[$location] : false; |
||||||
|
} |
||||||
|
|
||||||
|
public function reset() |
||||||
|
{ |
||||||
|
$this->values = []; |
||||||
|
$this->finished = false; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
class Cc1p3Convert extends CcBase |
||||||
|
{ |
||||||
|
const CC_TYPE_FORUM = 'imsdt_xmlv1p3'; |
||||||
|
const CC_TYPE_QUIZ = 'imsqti_xmlv1p3/imscc_xmlv1p3/assessment'; |
||||||
|
const CC_TYPE_QUESTION_BANK = 'imsqti_xmlv1p3/imscc_xmlv1p3/question-bank'; |
||||||
|
const CC_TYPE_WEBLINK = 'imswl_xmlv1p3'; |
||||||
|
const CC_TYPE_ASSOCIATED_CONTENT = 'associatedcontent/imscc_xmlv1p3/learning-application-resource'; |
||||||
|
const CC_TYPE_BASICLTI = 'imsbasiclti_xmlv1p3'; |
||||||
|
|
||||||
|
public static $namespaces = ['imscc' => 'http://www.imsglobal.org/xsd/imsccv1p3/imscp_v1p1', |
||||||
|
'lomimscc' => 'http://ltsc.ieee.org/xsd/imsccv1p3/LOM/manifest', |
||||||
|
'lom' => 'http://ltsc.ieee.org/xsd/imsccv1p3/LOM/resource', |
||||||
|
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
||||||
|
'cc' => 'http://www.imsglobal.org/xsd/imsccv1p3/imsccauth_v1p1', ]; |
||||||
|
|
||||||
|
public static $restypes = ['associatedcontent/imscc_xmlv1p3/learning-application-resource', 'webcontent']; |
||||||
|
public static $forumns = ['dt' => 'http://www.imsglobal.org/xsd/imsccv1p3/imsdt_v1p3']; |
||||||
|
public static $quizns = ['xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2']; |
||||||
|
public static $resourcens = ['wl' => 'http://www.imsglobal.org/xsd/imsccv1p3/imswl_v1p3']; |
||||||
|
public static $basicltins = [ |
||||||
|
'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p0', |
||||||
|
'blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0', |
||||||
|
'lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0', |
||||||
|
'lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0', |
||||||
|
]; |
||||||
|
|
||||||
|
public function __construct($path_to_manifest) |
||||||
|
{ |
||||||
|
parent::__construct($path_to_manifest); |
||||||
|
} |
||||||
|
|
||||||
|
public function generateImportData() |
||||||
|
{ |
||||||
|
$xpath = static::newxPath(static::$manifest, static::$namespaces); |
||||||
|
$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); |
||||||
|
|
||||||
|
$resources = new Cc13Resource(); |
||||||
|
$forums = new Cc13Forum(); |
||||||
|
$quiz = new Cc13Quiz(); |
||||||
|
|
||||||
|
$documentValues = $resources->generateData('document'); |
||||||
|
$linkValues = $resources->generateData('link'); |
||||||
|
$forumValues = $forums->generateData(); |
||||||
|
$quizValues = $quiz->generateData(); |
||||||
|
|
||||||
|
if (!empty($forums)) { |
||||||
|
$saved = $forums->storeForums($forumValues); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($quizValues)) { |
||||||
|
$saved = $quiz->storeQuizzes($quizValues); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($documentValues)) { |
||||||
|
$saved = $resources->storeDocuments($documentValues, static::$pathToManifestFolder); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($linkValues)) { |
||||||
|
$saved = $resources->storeLinks($linkValues); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,92 @@ |
|||||||
|
<?php |
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
class Imscc13Import |
||||||
|
{ |
||||||
|
const FORMAT_IMSCC13 = 'imscc13'; |
||||||
|
|
||||||
|
public function log($message, $level, $a = null, $depth = null, $display = false) |
||||||
|
{ |
||||||
|
error_log("(imscc1) $message , level : $level , extra info: $a, message depth : $depth"); |
||||||
|
} |
||||||
|
|
||||||
|
public static function detectFormat($filepath) |
||||||
|
{ |
||||||
|
$manifest = Cc1p3Convert::getManifest($filepath); |
||||||
|
|
||||||
|
if (file_exists($manifest)) { |
||||||
|
// Looks promising, lets load some information. |
||||||
|
$handle = fopen($manifest, 'r'); |
||||||
|
$xmlSnippet = fread($handle, 1024); |
||||||
|
fclose($handle); |
||||||
|
|
||||||
|
// Check if it has the required strings. |
||||||
|
$xmlSnippet = strtolower($xmlSnippet); |
||||||
|
$xmlSnippet = preg_replace('/\s*/m', '', $xmlSnippet); |
||||||
|
$xmlSnippet = str_replace("'", '', $xmlSnippet); |
||||||
|
$xmlSnippet = str_replace('"', '', $xmlSnippet); |
||||||
|
|
||||||
|
$search_string = "xmlns=http://www.imsglobal.org/xsd/imsccv1p3/imscp_v1p1"; |
||||||
|
if (strpos($xmlSnippet, $search_string) !== false) { |
||||||
|
return self::FORMAT_IMSCC13; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public function execute($filepath) |
||||||
|
{ |
||||||
|
$manifest = Cc1p3Convert::getManifest($filepath); |
||||||
|
|
||||||
|
if (empty($manifest)) { |
||||||
|
throw new RuntimeException('No Manifest detected!'); |
||||||
|
} |
||||||
|
|
||||||
|
$validator = new ManifestValidator('schemas13'); |
||||||
|
|
||||||
|
if (!$validator->validate($manifest)) { |
||||||
|
throw new RuntimeException('validation error(s): '.PHP_EOL.ErrorMessages::instance()); |
||||||
|
} |
||||||
|
|
||||||
|
$cc113Convert = new Cc1p3Convert($manifest); |
||||||
|
|
||||||
|
if ($cc113Convert->isAuth()) { |
||||||
|
throw new RuntimeException('protected_cc_not_supported'); |
||||||
|
} |
||||||
|
|
||||||
|
$cc113Convert->generateImportData(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Unzip a file into the specified directory. Throws a RuntimeException |
||||||
|
* if the extraction failed. |
||||||
|
*/ |
||||||
|
public static function unzip($file, $to = 'cache/zip') |
||||||
|
{ |
||||||
|
@ini_set('memory_limit', '256M'); |
||||||
|
if (!is_dir($to)) { |
||||||
|
mkdir($to); |
||||||
|
chmod($to, 0777); |
||||||
|
} |
||||||
|
if (class_exists('ZipArchive')) { |
||||||
|
// use ZipArchive |
||||||
|
$zip = new ZipArchive(); |
||||||
|
$res = $zip->open($file); |
||||||
|
if ($res === true) { |
||||||
|
$zip->extractTo($to); |
||||||
|
$zip->close(); |
||||||
|
} else { |
||||||
|
throw new RuntimeException('Could not open zip file [ZipArchive].'); |
||||||
|
} |
||||||
|
} else { |
||||||
|
// use PclZip |
||||||
|
$zip = new PclZip($file); |
||||||
|
if ($zip->extract(PCLZIP_OPT_PATH, $to) === 0) { |
||||||
|
throw new RuntimeException('Could not extract zip file [PclZip].'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@ |
|||||||
|
<?xml version = "1.0" encoding = "UTF-8"?> |
||||||
|
<xs:schema xmlns ="http://dummy.libxml2.validator" |
||||||
|
targetNamespace ="http://dummy.libxml2.validator" |
||||||
|
xmlns:xs ="http://www.w3.org/2001/XMLSchema" |
||||||
|
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns:imscp ="http://www.imsglobal.org/xsd/imsccv1p3/imscp_v1p1" |
||||||
|
xmlns:lomimscc ="http://ltsc.ieee.org/xsd/imsccv1p3/LOM/manifest" |
||||||
|
xmlns:lom ="http://ltsc.ieee.org/xsd/imsccv1p3/LOM/resource" |
||||||
|
xmlns:cc ="http://www.imsglobal.org/xsd/imsccv1p3/imsccauth_v1p3" |
||||||
|
version="IMS CC 1.3 CP 1.2" |
||||||
|
elementFormDefault ="qualified" |
||||||
|
attributeFormDefault="unqualified" |
||||||
|
> |
||||||
|
|
||||||
|
<xs:import namespace="http://www.imsglobal.org/xsd/imsccv1p3/imscp_v1p1" schemaLocation="ccv1p3_imscp_v1p2_v1p0.xsd" /> |
||||||
|
<!--xs:import namespace="http://ltsc.ieee.org/xsd/imsccv1p3/LOM/manifest" schemaLocation="LOM/ccv1p3_lommanifest_v1p0.xsd"/--> |
||||||
|
<!--xs:import namespace="http://ltsc.ieee.org/xsd/imsccv1p3/LOM/resource" schemaLocation="LOM/ccv1p3_lomresource_v1p0.xsd"/--> |
||||||
|
<!--xs:import namespace="http://www.imsglobal.org/xsd/imsccv1p3/imsccauth_v1p3" schemaLocation="ccv1p3_imsccauth_v1p3.xsd" /--> |
||||||
|
</xs:schema> |
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue