Merge branch '1.11.x' of https://github.com/chamilo/chamilo-lms into 1.11.x
commit
8dd9439e33
@ -0,0 +1,39 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Application\Migrations\Schema\V111; |
||||
|
||||
use Application\Migrations\AbstractMigrationChamilo; |
||||
use Doctrine\DBAL\Schema\Schema; |
||||
use Doctrine\DBAL\Types\Type; |
||||
|
||||
/** |
||||
* Class Version20160713180000 |
||||
* Add option to use SVG icons instead of their PNG version |
||||
* @package Application\Migrations\Schema\V111 |
||||
*/ |
||||
class Version20160713180000 extends AbstractMigrationChamilo |
||||
{ |
||||
/** |
||||
* @param Schema $schema |
||||
* @throws \Doctrine\DBAL\DBALException |
||||
* @throws \Doctrine\DBAL\Schema\SchemaException |
||||
*/ |
||||
public function up(Schema $schema) |
||||
{ |
||||
$this->addSql("DELETE FROM settings_current WHERE variable = 'allow_browser_sniffer'"); |
||||
$this->addSql("DELETE FROM settings_options WHERE variable = 'allow_browser_sniffer'"); |
||||
} |
||||
|
||||
/** |
||||
* @param Schema $schema |
||||
* @throws \Doctrine\DBAL\DBALException |
||||
* @throws \Doctrine\DBAL\Schema\SchemaException |
||||
*/ |
||||
public function down(Schema $schema) |
||||
{ |
||||
$this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('allow_browser_sniffer', NULL, 'radio', 'Tuning', 'false', 'AllowBrowserSnifferTitle','AllowBrowserSnifferComment',NULL,NULL, 0)"); |
||||
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_browser_sniffer','true','Yes') "); |
||||
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_browser_sniffer','false','No') "); |
||||
} |
||||
} |
@ -0,0 +1,58 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
/** |
||||
* Import a backup from moodle system. |
||||
* |
||||
* @author José Loguercio <jose.loguercio@beeznest.com> |
||||
* @package chamilo.backup |
||||
*/ |
||||
|
||||
require_once '../inc/global.inc.php'; |
||||
require_once '../inc/lib/MoodleImport.class.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); |
||||
} |
||||
|
||||
// Remove memory and time limits as much as possible as this might be a long process... |
||||
if (function_exists('ini_set')) { |
||||
api_set_memory_limit('256M'); |
||||
ini_set('max_execution_time', 1800); |
||||
} |
||||
|
||||
// Section for the tabs |
||||
$this_section = SECTION_COURSES; |
||||
|
||||
// Breadcrumbs |
||||
$interbreadcrumb[] = array( |
||||
'url' => '../course_info/maintenance.php', |
||||
'name' => get_lang('Maintenance') |
||||
); |
||||
|
||||
$form = new FormValidator('import_moodle'); |
||||
$form->addFile('moodle_file', get_lang('MoodleFile')); |
||||
$form->addButtonImport(get_lang('Import')); |
||||
|
||||
if ($form->validate()) { |
||||
$file = $_FILES['moodle_file']; |
||||
$moodleImport = new MoodleImport(); |
||||
$moodleImport->readMoodleFile($file); |
||||
} |
||||
|
||||
$templateName = get_lang('ImportFromMoodle'); |
||||
|
||||
$template = new Template($templateName); |
||||
$infoMsg = Display::return_message(get_lang('ImportFromMoodleInstructions')); |
||||
$template->assign('info_msg', $infoMsg); |
||||
$template->assign('form', $form->returnForm()); |
||||
$content = $template->fetch('default/coursecopy/import_moodle.tpl'); |
||||
|
||||
$template->assign('header', $templateName); |
||||
$template->assign('content', $content); |
||||
|
||||
$template->display_one_col_template(); |
@ -0,0 +1,733 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
/** |
||||
* Class MoodleImport |
||||
* |
||||
* @author José Loguercio <jose.loguercio@beeznest.com> |
||||
* @package chamilo.library |
||||
*/ |
||||
|
||||
class MoodleImport |
||||
{ |
||||
/** |
||||
* Read and validate the moodleFile |
||||
* |
||||
* @param resource $uploadedFile *.* mbz file moodle course backup |
||||
* @return bool |
||||
*/ |
||||
public function readMoodleFile($uploadedFile) |
||||
{ |
||||
$file = $uploadedFile['tmp_name']; |
||||
|
||||
if (is_file($file) && is_readable($file)) { |
||||
$package = new PclZip($file); |
||||
$packageContent = $package->listContent(); |
||||
$mainFileKey = 0; |
||||
foreach ($packageContent as $index => $value) { |
||||
if ($value['filename'] == 'moodle_backup.xml') { |
||||
$mainFileKey = $index; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (!$mainFileKey) { |
||||
Display::addFlash(Display::return_message(get_lang('FailedToImportThisIsNotAMoodleFile'), 'error')); |
||||
} |
||||
|
||||
$folder = api_get_unique_id(); |
||||
$destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder; |
||||
$coursePath = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'; |
||||
$courseInfo = api_get_course_info(); |
||||
|
||||
mkdir($destinationDir, api_get_permissions_for_new_directories(), true); |
||||
|
||||
$package->extract( |
||||
PCLZIP_OPT_PATH, |
||||
$destinationDir |
||||
); |
||||
|
||||
$xml = @file_get_contents($destinationDir.'/moodle_backup.xml'); |
||||
|
||||
$doc = new DOMDocument(); |
||||
$res = @$doc->loadXML($xml); |
||||
if ($res) { |
||||
$activities = $doc->getElementsByTagName('activity'); |
||||
foreach ($activities as $activity) { |
||||
if ($activity->childNodes->length) { |
||||
$currentItem = []; |
||||
|
||||
foreach ($activity->childNodes as $item) { |
||||
$currentItem[$item->nodeName] = $item->nodeValue; |
||||
} |
||||
|
||||
$moduleName = isset($currentItem['modulename']) ? $currentItem['modulename'] : false; |
||||
switch ($moduleName) { |
||||
case 'forum': |
||||
require_once '../forum/forumfunction.inc.php'; |
||||
$catForumValues = []; |
||||
|
||||
// Read the current forum module xml. |
||||
$moduleDir = $currentItem['directory']; |
||||
$moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml'); |
||||
$moduleValues = $this->readForumModule($moduleXml); |
||||
|
||||
// Create a Forum category based on Moodle forum type. |
||||
$catForumValues['forum_category_title'] = $moduleValues['type']; |
||||
$catForumValues['forum_category_comment'] = ''; |
||||
$catId = store_forumcategory($catForumValues); |
||||
$forumValues = []; |
||||
$forumValues['forum_title'] = $moduleValues['name']; |
||||
$forumValues['forum_image'] = ''; |
||||
$forumValues['forum_comment'] = $moduleValues['intro']; |
||||
$forumValues['forum_category'] = $catId; |
||||
|
||||
store_forum($forumValues); |
||||
break; |
||||
case 'quiz': |
||||
|
||||
// Read the current quiz module xml. |
||||
// The quiz case is the very complicate process of all the import. |
||||
// Please if you want to review the script, try to see the readingXML functions. |
||||
// The readingXML functions in this clases do all the mayor work here. |
||||
|
||||
$moduleDir = $currentItem['directory']; |
||||
$moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml'); |
||||
$questionsXml = @file_get_contents($destinationDir.'/questions.xml'); |
||||
$moduleValues = $this->readQuizModule($moduleXml); |
||||
|
||||
// At this point we got all the prepared resources from Moodle file |
||||
// $moduleValues variable contains all the necesary info to the quiz import |
||||
// var_dump($moduleValues); // <-- uncomment this to see the final array |
||||
|
||||
// Lets do this ... |
||||
$exercise = new Exercise(); |
||||
$exercise->updateTitle(Exercise::format_title_variable($moduleValues['name'])); |
||||
$exercise->updateDescription($moduleValues['intro']); |
||||
$exercise->updateAttempts($moduleValues['attempts_number']); |
||||
$exercise->updateFeedbackType(0); |
||||
|
||||
// Match shuffle question with chamilo |
||||
switch ($moduleValues['shufflequestions']) { |
||||
case '0': |
||||
$exercise->setRandom(0); |
||||
break; |
||||
case '1': |
||||
$exercise->setRandom(-1); |
||||
break; |
||||
default: |
||||
$exercise->setRandom(0); |
||||
} |
||||
$exercise->updateRandomAnswers($moduleValues['shuffleanswers']); |
||||
// @todo divide to minutes |
||||
$exercise->updateExpiredTime($moduleValues['timelimit']); |
||||
|
||||
if ($moduleValues['questionsperpage'] == 1) { |
||||
$exercise->updateType(2); |
||||
} else { |
||||
$exercise->updateType(1); |
||||
} |
||||
|
||||
// Create the new Quiz |
||||
$exercise->save(); |
||||
|
||||
// Ok, we got the Quiz and create it, now its time to add the Questions |
||||
foreach ($moduleValues['question_instances'] as $index => $question) { |
||||
$questionsValues = $this->readMainQuestionsXml($questionsXml, $question['questionid']); |
||||
$moduleValues['question_instances'][$index] = $questionsValues; |
||||
// Set Question Type from Moodle XML element <qtype> |
||||
$qType = $moduleValues['question_instances'][$index]['qtype']; |
||||
// Add the matched chamilo question type to the array |
||||
$moduleValues['question_instances'][$index]['chamilo_qtype'] = $this->matchMoodleChamiloQuestionTypes($qType); |
||||
$questionInstance = Question::getInstance($moduleValues['question_instances'][$index]['chamilo_qtype']); |
||||
if ($questionInstance) { |
||||
$questionInstance->updateTitle($moduleValues['question_instances'][$index]['name']); |
||||
$questionInstance->updateDescription($moduleValues['question_instances'][$index]['questiontext']); |
||||
$questionInstance->updateLevel(1); |
||||
$questionInstance->updateCategory(0); |
||||
|
||||
//Save normal question if NOT media |
||||
if ($questionInstance->type != MEDIA_QUESTION) { |
||||
$questionInstance->save($exercise->id); |
||||
|
||||
// modify the exercise |
||||
$exercise->addToList($questionInstance->id); |
||||
$exercise->update_question_positions(); |
||||
} |
||||
|
||||
$questionList = $moduleValues['question_instances'][$index]['plugin_qtype_'.$qType.'_question']; |
||||
$currentQuestion = $moduleValues['question_instances'][$index]; |
||||
|
||||
$result = $this->processAnswers($questionList, $qType, $questionInstance, $currentQuestion); |
||||
} |
||||
} |
||||
|
||||
break; |
||||
case 'resource': |
||||
// Read the current resource module xml. |
||||
$moduleDir = $currentItem['directory']; |
||||
$moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml'); |
||||
$filesXml = @file_get_contents($destinationDir.'/files.xml'); |
||||
$moduleValues = $this->readResourceModule($moduleXml); |
||||
$mainFileModuleValues = $this->readMainFilesXml($filesXml, $moduleValues['contextid']); |
||||
$fileInfo = array_merge($moduleValues, $mainFileModuleValues, $currentItem); |
||||
$documentPath = $coursePath.'document/'; |
||||
$currentResourceFilePath = $destinationDir.'/files/'; |
||||
$dirs = new RecursiveDirectoryIterator($currentResourceFilePath); |
||||
foreach (new RecursiveIteratorIterator($dirs) as $file) { |
||||
if (is_file($file) && strpos($file, $fileInfo['contenthash']) !== false) { |
||||
$files = []; |
||||
$files['file']['name'] = $fileInfo['filename']; |
||||
$files['file']['tmp_name'] = $file->getPathname(); |
||||
$files['file']['type'] = $fileInfo['mimetype']; |
||||
$files['file']['error'] = 0; |
||||
$files['file']['size'] = $fileInfo['filesize']; |
||||
$files['file']['from_file'] = true; |
||||
$files['file']['move_file'] = true; |
||||
$_POST['language'] = $courseInfo['language']; |
||||
$_POST['moodle_import'] = true; |
||||
|
||||
DocumentManager::upload_document( |
||||
$files, |
||||
'/', |
||||
$fileInfo['title'], |
||||
'', |
||||
null, |
||||
null, |
||||
true, |
||||
true |
||||
); |
||||
} |
||||
} |
||||
|
||||
break; |
||||
case 'url': |
||||
// Read the current url module xml. |
||||
$moduleDir = $currentItem['directory']; |
||||
$moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml'); |
||||
$moduleValues = $this->readUrlModule($moduleXml); |
||||
$_POST['title'] = $moduleValues['name']; |
||||
$_POST['url'] = $moduleValues['externalurl']; |
||||
$_POST['description'] = $moduleValues['intro']; |
||||
$_POST['category_id'] = 0; |
||||
$_POST['target'] = '_blank'; |
||||
|
||||
Link::addlinkcategory("link"); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} else { |
||||
return false; |
||||
} |
||||
} else { |
||||
return false; |
||||
} |
||||
|
||||
removeDir($destinationDir); |
||||
return $packageContent[$mainFileKey]; |
||||
} |
||||
|
||||
/** |
||||
* Read and validate the forum module XML |
||||
* |
||||
* @param resource $moduleXml XML file |
||||
* @return mixed | array if is a valid xml file, false otherwise |
||||
*/ |
||||
public function readForumModule($moduleXml) |
||||
{ |
||||
$moduleDoc = new DOMDocument(); |
||||
$moduleRes = @$moduleDoc->loadXML($moduleXml); |
||||
if ($moduleRes) { |
||||
$activities = $moduleDoc->getElementsByTagName('forum'); |
||||
$currentItem = []; |
||||
foreach ($activities as $activity) { |
||||
if ($activity->childNodes->length) { |
||||
foreach ($activity->childNodes as $item) { |
||||
$currentItem[$item->nodeName] = $item->nodeValue; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $currentItem; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Read and validate the resource module XML |
||||
* |
||||
* @param resource $moduleXml XML file |
||||
* @return mixed | array if is a valid xml file, false otherwise |
||||
*/ |
||||
public function readResourceModule($moduleXml) |
||||
{ |
||||
$moduleDoc = new DOMDocument(); |
||||
$moduleRes = @$moduleDoc->loadXML($moduleXml); |
||||
if ($moduleRes) { |
||||
$activities = $moduleDoc->getElementsByTagName('resource'); |
||||
$mainActivity = $moduleDoc->getElementsByTagName('activity'); |
||||
$contextId = $mainActivity->item(0)->getAttribute('contextid'); |
||||
$currentItem = []; |
||||
foreach ($activities as $activity) { |
||||
if ($activity->childNodes->length) { |
||||
foreach ($activity->childNodes as $item) { |
||||
$currentItem[$item->nodeName] = $item->nodeValue; |
||||
} |
||||
} |
||||
} |
||||
|
||||
$currentItem['contextid'] = $contextId; |
||||
return $currentItem; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Read and validate the url module XML |
||||
* |
||||
* @param resource $moduleXml XML file |
||||
* @return mixed | array if is a valid xml file, false otherwise |
||||
*/ |
||||
public function readUrlModule($moduleXml) |
||||
{ |
||||
$moduleDoc = new DOMDocument(); |
||||
$moduleRes = @$moduleDoc->loadXML($moduleXml); |
||||
if ($moduleRes) { |
||||
$activities = $moduleDoc->getElementsByTagName('url'); |
||||
$currentItem = []; |
||||
foreach ($activities as $activity) { |
||||
if ($activity->childNodes->length) { |
||||
foreach ($activity->childNodes as $item) { |
||||
$currentItem[$item->nodeName] = $item->nodeValue; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $currentItem; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Read and validate the quiz module XML |
||||
* |
||||
* @param resource $moduleXml XML file |
||||
* @return mixed | array if is a valid xml file, false otherwise |
||||
*/ |
||||
public function readQuizModule($moduleXml) |
||||
{ |
||||
$moduleDoc = new DOMDocument(); |
||||
$moduleRes = @$moduleDoc->loadXML($moduleXml); |
||||
if ($moduleRes) { |
||||
$activities = $moduleDoc->getElementsByTagName('quiz'); |
||||
$currentItem = []; |
||||
foreach ($activities as $activity) { |
||||
if ($activity->childNodes->length) { |
||||
foreach ($activity->childNodes as $item) { |
||||
$currentItem[$item->nodeName] = $item->nodeValue; |
||||
} |
||||
} |
||||
} |
||||
|
||||
$questions = $moduleDoc->getElementsByTagName('question_instance'); |
||||
|
||||
$questionList = []; |
||||
$counter = 0; |
||||
foreach ($questions as $question) { |
||||
if ($question->childNodes->length) { |
||||
foreach ($question->childNodes as $item) { |
||||
$questionList[$counter][$item->nodeName] = $item->nodeValue; |
||||
} |
||||
$counter++; |
||||
} |
||||
|
||||
} |
||||
$currentItem['question_instances'] = $questionList; |
||||
return $currentItem; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Search the current file resource in main Files XML |
||||
* |
||||
* @param resource $filesXml XML file |
||||
* @param int $contextId |
||||
* @return mixed | array if is a valid xml file, false otherwise |
||||
*/ |
||||
public function readMainFilesXml($filesXml, $contextId) |
||||
{ |
||||
$moduleDoc = new DOMDocument(); |
||||
$moduleRes = @$moduleDoc->loadXML($filesXml); |
||||
if ($moduleRes) { |
||||
$activities = $moduleDoc->getElementsByTagName('file'); |
||||
$currentItem = []; |
||||
foreach ($activities as $activity) { |
||||
if ($activity->childNodes->length) { |
||||
$isThisItemThatIWant = false; |
||||
foreach ($activity->childNodes as $item) { |
||||
if (!$isThisItemThatIWant && $item->nodeName == 'contenthash') { |
||||
$currentItem['contenthash'] = $item->nodeValue; |
||||
} |
||||
if ($item->nodeName == 'contextid' && intval($item->nodeValue) == intval($contextId) && !$isThisItemThatIWant) { |
||||
$isThisItemThatIWant = true; |
||||
continue; |
||||
} |
||||
|
||||
if ($isThisItemThatIWant && $item->nodeName == 'filename') { |
||||
$currentItem['filename'] = $item->nodeValue; |
||||
} |
||||
|
||||
if ($isThisItemThatIWant && $item->nodeName == 'filesize') { |
||||
$currentItem['filesize'] = $item->nodeValue; |
||||
} |
||||
|
||||
if ($isThisItemThatIWant && $item->nodeName == 'mimetype' && $item->nodeValue == 'document/unknown') { |
||||
break; |
||||
} |
||||
|
||||
if ($isThisItemThatIWant && $item->nodeName == 'mimetype' && $item->nodeValue !== 'document/unknown') { |
||||
$currentItem['mimetype'] = $item->nodeValue; |
||||
break 2; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $currentItem; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Search the current quiestion resource in main Questions XML |
||||
* |
||||
* @param resource $questionsXml XML file |
||||
* @param int $questionId |
||||
* @return mixed | array if is a valid xml file, false otherwise |
||||
*/ |
||||
public function readMainQuestionsXml($questionsXml, $questionId) |
||||
{ |
||||
$moduleDoc = new DOMDocument(); |
||||
$moduleRes = @$moduleDoc->loadXML($questionsXml); |
||||
if ($moduleRes) { |
||||
$questions = $moduleDoc->getElementsByTagName('question'); |
||||
$currentItem = []; |
||||
foreach ($questions as $question) { |
||||
if (intval($question->getAttribute('id')) == $questionId) { |
||||
if ($question->childNodes->length) { |
||||
$currentItem['questionid'] = $questionId; |
||||
$questionType = ''; |
||||
foreach ($question->childNodes as $item) { |
||||
$currentItem[$item->nodeName] = $item->nodeValue; |
||||
if ($item->nodeName == 'qtype') { |
||||
$questionType = $item->nodeValue; |
||||
} |
||||
|
||||
if ($item->nodeName == 'plugin_qtype_'.$questionType.'_question') { |
||||
$answer = $item->getElementsByTagName($this->getQuestionTypeAnswersTag($questionType)); |
||||
$currentItem['plugin_qtype_'.$questionType.'_question'] = []; |
||||
for ($i = 0; $i <= $answer->length - 1; $i++) { |
||||
$currentItem['plugin_qtype_'.$questionType.'_question'][$i]['answerid'] = $answer->item($i)->getAttribute('id'); |
||||
foreach ($answer->item($i)->childNodes as $properties) { |
||||
$currentItem['plugin_qtype_'.$questionType.'_question'][$i][$properties->nodeName] = $properties->nodeValue; |
||||
} |
||||
} |
||||
|
||||
$typeValues = $item->getElementsByTagName($this->getQuestionTypeOptionsTag($questionType)); |
||||
for ($i = 0; $i <= $typeValues->length - 1; $i++) { |
||||
foreach ($typeValues->item($i)->childNodes as $properties) { |
||||
$currentItem[$questionType.'_values'][$properties->nodeName] = $properties->nodeValue; |
||||
if ($properties->nodeName == 'sequence') { |
||||
$sequence = $properties->nodeValue; |
||||
$sequenceIds = explode(',', $sequence); |
||||
foreach ($sequenceIds as $qId) { |
||||
$questionMatch = $this->readMainQuestionsXml($questionsXml, $qId); |
||||
$currentItem['plugin_qtype_'.$questionType.'_question'][] = $questionMatch; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
$this->traverseArray($currentItem, ['#text', 'question_hints', 'tags']); |
||||
return $currentItem; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* return the correct question type options tag |
||||
* |
||||
* @param string $questionType name |
||||
* @return string question type tag |
||||
*/ |
||||
public function getQuestionTypeOptionsTag($questionType) |
||||
{ |
||||
switch ($questionType) { |
||||
case 'match': |
||||
case 'ddmatch': |
||||
return 'matchoptions'; |
||||
break; |
||||
default: |
||||
return $questionType; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* return the correct question type answers tag |
||||
* |
||||
* @param string $questionType name |
||||
* @return string question type tag |
||||
*/ |
||||
public function getQuestionTypeAnswersTag($questionType) |
||||
{ |
||||
switch ($questionType) { |
||||
case 'match': |
||||
case 'ddmatch': |
||||
return 'match'; |
||||
break; |
||||
default: |
||||
return 'answer'; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param string $moodleQuestionType |
||||
* @return integer Chamilo question type |
||||
*/ |
||||
public function matchMoodleChamiloQuestionTypes($moodleQuestionType) |
||||
{ |
||||
switch ($moodleQuestionType) { |
||||
case 'multichoice': |
||||
return UNIQUE_ANSWER; |
||||
break; |
||||
case 'multianswer': |
||||
case 'shortanswer': |
||||
case 'match': |
||||
return FILL_IN_BLANKS; |
||||
break; |
||||
case 'essay': |
||||
return FREE_ANSWER; |
||||
break; |
||||
case 'truefalse': |
||||
return MULTIPLE_ANSWER_TRUE_FALSE; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Process Moodle Answers to Chamilo |
||||
* |
||||
* @param array $questionList |
||||
* @param string $questionType |
||||
* @param object $questionInstance Question/Answer instance |
||||
* @param array $currentQuestion |
||||
* @return integer db response |
||||
*/ |
||||
public function processAnswers($questionList, $questionType, $questionInstance, $currentQuestion) |
||||
{ |
||||
switch ($questionType) { |
||||
case 'multichoice': |
||||
$objAnswer = new Answer($questionInstance->id); |
||||
$questionWeighting = 0; |
||||
foreach ($questionList as $slot => $answer) { |
||||
$this->processUniqueAnswer($objAnswer, $answer, $slot + 1, $questionWeighting); |
||||
} |
||||
|
||||
// saves the answers into the data base |
||||
$objAnswer->save(); |
||||
// sets the total weighting of the question |
||||
$questionInstance->updateWeighting($questionWeighting); |
||||
$questionInstance->save(); |
||||
|
||||
return true; |
||||
break; |
||||
case 'multianswer': |
||||
$objAnswer = new Answer($questionInstance->id); |
||||
|
||||
$placeholder = $currentQuestion['questiontext']; |
||||
|
||||
$optionsValues = []; |
||||
|
||||
foreach ($questionList as $slot => $subQuestion) { |
||||
$qtype = $subQuestion['qtype']; |
||||
$optionsValues[] = $this->processFillBlanks($objAnswer, $subQuestion, $subQuestion['plugin_qtype_'.$qtype.'_question'], $placeholder, $slot + 1); |
||||
} |
||||
|
||||
$answerOptionsWeight = '::'; |
||||
$answerOptionsSize = ''; |
||||
$questionWeighting = 0; |
||||
foreach ($optionsValues as $index => $value) { |
||||
$questionWeighting += $value['weight']; |
||||
$answerOptionsWeight .= $value['weight'].','; |
||||
$answerOptionsSize .= $value['size'].','; |
||||
} |
||||
|
||||
$answerOptionsWeight = substr($answerOptionsWeight, 0, -1); |
||||
$answerOptionsSize = substr($answerOptionsSize, 0, -1); |
||||
|
||||
$suffleAnswers = isset($subQuestion[$qtype.'_values']['shuffleanswers']) ? $subQuestion[$qtype.'_values']['shuffleanswers'] : false; |
||||
|
||||
if ($suffleAnswers) { |
||||
$answerOptions = $answerOptionsWeight.':'.$answerOptionsSize.':0@'.$suffleAnswers; |
||||
} else { |
||||
$answerOptions = $answerOptionsWeight.':'.$answerOptionsSize.':0@'; |
||||
} |
||||
|
||||
$placeholder = $placeholder.$answerOptions; |
||||
|
||||
$questionInstance->updateWeighting($questionWeighting); |
||||
$questionInstance->updateDescription(''); |
||||
$questionInstance->save(); |
||||
$objAnswer->createAnswer($placeholder, 0, '', 0, 1); |
||||
$objAnswer->save(); |
||||
case 'shortanswer': |
||||
case 'match': |
||||
case 'ddmatch': |
||||
// Not Supported Yet |
||||
return false; |
||||
break; |
||||
case 'essay': |
||||
$questionWeighting = $currentQuestion['defaultmark']; |
||||
$questionInstance->updateWeighting($questionWeighting); |
||||
$questionInstance->save(); |
||||
break; |
||||
case 'truefalse': |
||||
// Not Supported Yet |
||||
return false; |
||||
break; |
||||
default: |
||||
return false; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Process Chamilo Unique Answer |
||||
* |
||||
* @param object $objAnswer |
||||
* @param array $answerValues |
||||
* @param integer $position |
||||
* @param integer $questionWeighting |
||||
* @return integer db response |
||||
*/ |
||||
public function processUniqueAnswer($objAnswer, $answerValues, $position, &$questionWeighting) |
||||
{ |
||||
$correct = intval($answerValues['fraction']) ? intval($answerValues['fraction']) : 0; |
||||
$answer = $answerValues['answertext']; |
||||
$comment = $answerValues['feedback']; |
||||
$weighting = $answerValues['fraction']; |
||||
$weighting = abs($weighting); |
||||
if ($weighting > 0) { |
||||
$questionWeighting += $weighting; |
||||
} |
||||
$goodAnswer = $correct ? true : false; |
||||
|
||||
$objAnswer->createAnswer( |
||||
$answer, |
||||
$goodAnswer, |
||||
$comment, |
||||
$weighting, |
||||
$position, |
||||
null, |
||||
null, |
||||
'' |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Process Chamilo FillBlanks |
||||
* |
||||
* @param object $objAnswer |
||||
* @param array $question |
||||
* @param array $answerValues |
||||
* @param string $placeholder |
||||
* @param integer $position |
||||
* @return integer db response |
||||
*/ |
||||
public function processFillBlanks($objAnswer, $question, $answerValues, &$placeholder, $position) |
||||
{ |
||||
switch ($question['qtype']) { |
||||
case 'multichoice': |
||||
$optionsValues = []; |
||||
|
||||
$correctAnswer = ''; |
||||
$othersAnswer = ''; |
||||
foreach ($answerValues as $answer) { |
||||
$correct = intval($answer['fraction']); |
||||
if ($correct) { |
||||
$correctAnswer .= $answer['answertext'].'|'; |
||||
$optionsValues['weight'] = $answer['fraction']; |
||||
$optionsValues['size'] = '200'; |
||||
} else { |
||||
$othersAnswer .= $answer['answertext'].'|'; |
||||
} |
||||
} |
||||
$currentAnswers = $correctAnswer.$othersAnswer; |
||||
$currentAnswers = '['.substr($currentAnswers, 0, -1).']'; |
||||
$placeholder = str_replace("{#$position}", $currentAnswers, $placeholder); |
||||
|
||||
return $optionsValues; |
||||
|
||||
break; |
||||
case 'shortanswer': |
||||
$optionsValues = []; |
||||
|
||||
$correctAnswer = ''; |
||||
|
||||
foreach ($answerValues as $answer) { |
||||
$correct = intval($answer['fraction']); |
||||
if ($correct) { |
||||
$correctAnswer .= $answer['answertext']; |
||||
$optionsValues['weight'] = $answer['fraction']; |
||||
$optionsValues['size'] = '200'; |
||||
} |
||||
} |
||||
|
||||
$currentAnswers = '['.$correctAnswer.']'; |
||||
$placeholder = str_replace("{#$position}", $currentAnswers, $placeholder); |
||||
|
||||
return $optionsValues; |
||||
|
||||
break; |
||||
default: |
||||
return false; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Litle utility to delete the unuseful tags |
||||
* |
||||
* @param $array |
||||
* @param $keys |
||||
*/ |
||||
public function traverseArray(&$array, $keys) { |
||||
foreach ($array as $key => &$value) { |
||||
if (is_array($value)) { |
||||
$this->traverseArray($value, $keys); |
||||
} else { |
||||
if (in_array($key, $keys)){ |
||||
unset($array[$key]); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,4 @@ |
||||
{{ info_msg }} |
||||
<br /> |
||||
<br /> |
||||
{{ form }} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue