Actualización
This commit is contained in:
24
plugin/migrationmoodle/README.md
Normal file
24
plugin/migrationmoodle/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# MigrationMoodlePlugin
|
||||
|
||||
Allow migrate course contents and user progress from a Moodle platform.
|
||||
|
||||
> In development.
|
||||
|
||||
## Instructions
|
||||
|
||||
- Install the plugin
|
||||
- Set the configuration (params to moodle DB connection and moodledata directory)
|
||||
- Optionally, set the admin region
|
||||
|
||||
You can run the migration tasks from browser using the admin panel.
|
||||
You must ejecute the tasks in the order indicated in the task list.
|
||||
|
||||
Also you can run all the migrations running `php plugin/migrationmoodle/run_cli.php`.
|
||||
But if you want to run the migration with multiple url, then you will need edi `MigrationMoodlePlugin::getAccessUrlId`,
|
||||
`MigrationMoodlePlugin::getMoodledataPath` methods to set your plugin settings.
|
||||
|
||||
# Notes
|
||||
|
||||
- Check if exists an index on `c_lp_item_view.status` on Chamilo DB.
|
||||
It for optimize the performance when executing the SQL query used in UserScormProgressLoader.
|
||||
- It requires a Moodle DB with MySQL 8 or MariaDB 10.2.2 for some tasks (LessonPagesTask).
|
||||
241
plugin/migrationmoodle/admin.php
Normal file
241
plugin/migrationmoodle/admin.php
Normal file
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Script\BaseScript;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Task\BaseTask;
|
||||
|
||||
ini_set('memory_limit', -1);
|
||||
ini_set('max_execution_time', 0);
|
||||
|
||||
$cidReset = true;
|
||||
|
||||
$outputBuffering = false;
|
||||
|
||||
require_once __DIR__.'/../../main/inc/global.inc.php';
|
||||
|
||||
api_protect_admin_script(true);
|
||||
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : '';
|
||||
|
||||
$plugin = MigrationMoodlePlugin::create();
|
||||
|
||||
if ('true' != $plugin->get('active')) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$menuTasks = [
|
||||
'_' => [
|
||||
'course_categories',
|
||||
'courses',
|
||||
//'role_assignments',
|
||||
'users',
|
||||
],
|
||||
'courses' => [
|
||||
'course_introductions',
|
||||
'course_sections',
|
||||
'course_modules_scorm',
|
||||
],
|
||||
'course_sections' => [
|
||||
'files_for_course_sections',
|
||||
'course_modules_lesson',
|
||||
'course_modules_quiz',
|
||||
'course_modules_url',
|
||||
//'c_quiz',
|
||||
'sort_section_modules',
|
||||
],
|
||||
'course_modules_lesson' => [
|
||||
'lesson_pages',
|
||||
],
|
||||
'lesson_pages' => [
|
||||
'lesson_pages_document',
|
||||
'lesson_pages_quiz',
|
||||
],
|
||||
'lesson_pages_document' => [
|
||||
'files_for_lesson_pages',
|
||||
],
|
||||
'lesson_pages_quiz' => [
|
||||
'lesson_pages_quiz_question',
|
||||
'files_for_lesson_answers',
|
||||
],
|
||||
'lesson_pages_quiz_question' => [
|
||||
'lesson_answers_true_false',
|
||||
'lesson_answers_multiple_choice',
|
||||
'lesson_answers_multiple_answer',
|
||||
'lesson_answers_matching',
|
||||
'lesson_answers_essay',
|
||||
'lesson_answers_short_answer',
|
||||
],
|
||||
'course_modules_quiz' => [
|
||||
'quizzes',
|
||||
'quizzes_scores',
|
||||
],
|
||||
'quizzes' => [
|
||||
'files_for_quizzes',
|
||||
'question_categories',
|
||||
'questions',
|
||||
],
|
||||
'questions' => [
|
||||
'question_multi_choice_single',
|
||||
'question_multi_choice_multiple',
|
||||
'questions_true_false',
|
||||
'question_short_answer',
|
||||
'question_gapselect',
|
||||
],
|
||||
'course_modules_scorm' => [
|
||||
'scorm_scoes',
|
||||
],
|
||||
'scorm_scoes' => [
|
||||
'files_for_scorm_scoes',
|
||||
],
|
||||
'course_introductions' => [
|
||||
'files_for_course_introductions',
|
||||
],
|
||||
'course_modules_url' => [
|
||||
'urls',
|
||||
],
|
||||
'users' => [
|
||||
'users_last_login',
|
||||
'track_login',
|
||||
'user_sessions',
|
||||
],
|
||||
'user_sessions' => [
|
||||
'users_learn_paths',
|
||||
'users_scorms_view',
|
||||
'track_course_access',
|
||||
],
|
||||
'users_learn_paths' => [
|
||||
'users_learn_paths_lesson_timer',
|
||||
'users_learn_paths_lesson_branch',
|
||||
'users_learn_paths_lesson_attempts',
|
||||
'users_learn_paths_quizzes',
|
||||
],
|
||||
'users_learn_paths_quizzes' => [
|
||||
'users_quizzes_attempts',
|
||||
'user_question_attempts_shortanswer',
|
||||
'user_question_attempts_gapselect',
|
||||
'user_question_attempts_truefalse',
|
||||
],
|
||||
];
|
||||
|
||||
$menuScripts = [
|
||||
'_' => [
|
||||
'user_learn_paths_progress',
|
||||
'user_scorms_progress',
|
||||
],
|
||||
];
|
||||
|
||||
$htmlHeadXtra[] = '<style>.fa-ul {list-style-type: decimal; list-style-position: outside;}</style>';
|
||||
|
||||
Display::display_header($plugin->get_title());
|
||||
|
||||
echo '<div class="row">';
|
||||
echo '<div class="col-sm-6 col-sm-push-6">';
|
||||
echo '<pre style="max-height: 1190px; overflow: auto; height: 1190px;">';
|
||||
|
||||
if (!empty($action) && isAllowedAction($action, $menuTasks) && !$plugin->isTaskDone($action)) {
|
||||
$taskName = api_underscore_to_camel_case($action).'Task';
|
||||
|
||||
echo Display::page_subheader(
|
||||
$plugin->get_lang($taskName)
|
||||
);
|
||||
|
||||
$taskName = 'Chamilo\\PluginBundle\\MigrationMoodle\\Task\\'.$taskName;
|
||||
|
||||
/** @var BaseTask $task */
|
||||
$task = new $taskName();
|
||||
|
||||
$task->execute();
|
||||
}
|
||||
|
||||
if (!empty($action) && isAllowedAction($action, $menuScripts) && !$plugin->isTaskDone($action)) {
|
||||
$scriptName = api_underscore_to_camel_case($action).'Script';
|
||||
|
||||
echo Display::page_subheader(
|
||||
$plugin->get_lang($scriptName)
|
||||
);
|
||||
|
||||
$scriptClass = 'Chamilo\\PluginBundle\\MigrationMoodle\\Script\\'.$scriptName;
|
||||
|
||||
/** @var BaseScript $script */
|
||||
$script = new $scriptClass();
|
||||
|
||||
$script->run();
|
||||
}
|
||||
|
||||
echo '</pre>';
|
||||
echo '</div>';
|
||||
echo '<div class="col-sm-6 col-sm-pull-6">';
|
||||
echo Display::page_subheader('Tasks');
|
||||
echo displayMenu($menuTasks);
|
||||
echo Display::page_subheader('Scripts');
|
||||
echo displayMenu($menuScripts, 'Script');
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
Display::display_footer();
|
||||
|
||||
/**
|
||||
* @param string $parent
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function displayMenu(array $menu, $type = 'Task', $parent = '_')
|
||||
{
|
||||
$plugin = MigrationMoodlePlugin::create();
|
||||
|
||||
$items = $menu[$parent];
|
||||
|
||||
$isParentDone = $parent === '_' ? true : $plugin->isTaskDone($parent);
|
||||
|
||||
$baseUrl = api_get_self()."?action=";
|
||||
|
||||
$html = '<ol class="fa-ul">';
|
||||
|
||||
foreach ($items as $item) {
|
||||
$title = api_underscore_to_camel_case($item);
|
||||
|
||||
$html .= '<li>';
|
||||
|
||||
$htmlItem = Display::returnFontAwesomeIcon('check-square-o', '', true);
|
||||
$htmlItem .= $plugin->get_lang($title.$type);
|
||||
|
||||
if ($isParentDone) {
|
||||
if (!$plugin->isTaskDone($item)) {
|
||||
$htmlItem = Display::returnFontAwesomeIcon('square-o', '', true);
|
||||
$htmlItem .= Display::url(
|
||||
$plugin->get_lang($title.$type),
|
||||
$baseUrl.$item
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$html .= $htmlItem;
|
||||
|
||||
if (isset($menu[$item])) {
|
||||
$html .= displayMenu($menu, $type, $item);
|
||||
}
|
||||
|
||||
$html .= '</li>';
|
||||
}
|
||||
|
||||
$html .= '</ol>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function isAllowedAction($action, array $menu)
|
||||
{
|
||||
foreach ($menu as $items) {
|
||||
if (in_array($action, $items)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
59
plugin/migrationmoodle/install.php
Normal file
59
plugin/migrationmoodle/install.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$plugin = MigrationMoodlePlugin::create();
|
||||
|
||||
try {
|
||||
UserManager::create_extra_field(
|
||||
'moodle_password',
|
||||
ExtraField::FIELD_TYPE_TEXT,
|
||||
$plugin->get_lang('MoodlePassword'),
|
||||
''
|
||||
);
|
||||
|
||||
createPluginTables();
|
||||
} catch (Exception $exception) {
|
||||
$message = sprintf(
|
||||
$plugin->get_lang('InstallError'),
|
||||
$exception->getMessage()
|
||||
);
|
||||
|
||||
echo Display::return_message($message, 'error');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database tables for this plugin.
|
||||
*/
|
||||
function createPluginTables()
|
||||
{
|
||||
$installed = AppPlugin::getInstance()->isInstalled('migrationmoodle');
|
||||
|
||||
if ($installed) {
|
||||
return;
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = "CREATE TABLE IF NOT EXISTS plugin_migrationmoodle_task (
|
||||
id INT AUTO_INCREMENT NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY(id)
|
||||
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB";
|
||||
$queries[] = "CREATE TABLE IF NOT EXISTS plugin_migrationmoodle_item (
|
||||
id INT AUTO_INCREMENT NOT NULL,
|
||||
task_id INT NOT NULL,
|
||||
hash VARCHAR(255) NOT NULL,
|
||||
extracted_id INT NOT NULL,
|
||||
loaded_id INT NOT NULL,
|
||||
INDEX IDX_HASH (hash),
|
||||
INDEX IDX_EXTRACTED_LOADED (extracted_id, loaded_id),
|
||||
INDEX IDX_LOADED (loaded_id),
|
||||
INDEX IDX_TASK (task_id),
|
||||
PRIMARY KEY(id)
|
||||
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB";
|
||||
$queries[] = "ALTER TABLE plugin_migrationmoodle_item ADD CONSTRAINT FK_TASK FOREIGN KEY (task_id)
|
||||
REFERENCES plugin_migrationmoodle_task (id) ON DELETE CASCADE";
|
||||
|
||||
foreach ($queries as $query) {
|
||||
Database::query($query);
|
||||
}
|
||||
}
|
||||
79
plugin/migrationmoodle/lang/english.php
Normal file
79
plugin/migrationmoodle/lang/english.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$strings['plugin_title'] = 'Import from Moodle';
|
||||
$strings['plugin_comment'] = 'Execute an import process from a Moodle database and files to Chamilo.';
|
||||
|
||||
$strings['MoodlePassword'] = 'Moodle password';
|
||||
$strings['UninstallError'] = 'An error ocurred uninstalling the plugin.';
|
||||
|
||||
$strings['active'] = 'Active';
|
||||
$strings['db_host'] = 'Moodle DB host';
|
||||
$strings['db_user'] = 'Moodle DB user';
|
||||
$strings['db_password'] = 'Moodle DB password';
|
||||
$strings['db_name'] = 'Moodle DB name';
|
||||
$strings['user_filter'] = 'Filter for users';
|
||||
$strings['user_filter_help'] = 'Only import users who have a username prefixed with this string.<br>'
|
||||
.'The import of courses is also affected by this configuration, as it only imports courses in which users with this username prefix are enrolled.';
|
||||
$strings['url_id'] = 'URL ID';
|
||||
$strings['url_id_help'] = 'Access URL ID to save courses, users and sessions to (if using multi-url).';
|
||||
$strings['moodle_path'] = 'Moodledata path';
|
||||
$strings['moodle_path_help'] = 'The moodledata folder path. Usually something like <pre>/var/www/moodledata</pre>';
|
||||
|
||||
// Tasks
|
||||
$strings['UsersTask'] = 'Users';
|
||||
$strings['CourseCategoriesTask'] = 'Course categories';
|
||||
$strings['CoursesTask'] = 'Courses';
|
||||
$strings['CourseSectionsTask'] = 'Course sections';
|
||||
$strings['CourseModulesLessonTask'] = 'Course modules: Lessons';
|
||||
$strings['LessonPagesTask'] = 'Lesson pages';
|
||||
$strings['LessonPagesDocumentTask'] = 'Lesson pages: Documents';
|
||||
$strings['FilesForLessonPagesTask'] = 'Files for lesson pages';
|
||||
$strings['LessonPagesQuizTask'] = 'Lesson pages: Questions';
|
||||
$strings['LessonPagesQuizQuestionTask'] = 'Questions for question pages';
|
||||
$strings['LessonAnswersTrueFalseTask'] = 'Answers for True/False questions';
|
||||
$strings['LessonAnswersMultipleChoiceTask'] = 'Answers for Multiple Choice questions';
|
||||
$strings['LessonAnswersMultipleAnswerTask'] = 'Answers for Multiple Answer questions';
|
||||
$strings['LessonAnswersMatchingTask'] = 'Answers for Matching questions';
|
||||
$strings['LessonAnswersEssayTask'] = 'Answers for Essay questions';
|
||||
$strings['LessonAnswersShortAnswerTask'] = 'Answers for Short Answer questions';
|
||||
$strings['FilesForLessonAnswersTask'] = 'Files for lesson answers';
|
||||
$strings['CourseModulesQuizTask'] = 'Course modules: Quizzes';
|
||||
$strings['CQuizTask'] = 'C Quiz';
|
||||
$strings['RoleAssignmentsTask'] = 'Role assignments';
|
||||
$strings['QuizzesTask'] = 'Quizzes';
|
||||
$strings['FilesForQuizzesTask'] = 'Files for quizzes';
|
||||
$strings['QuestionCategoriesTask'] = 'Question categories';
|
||||
$strings['QuestionsTask'] = 'Questions';
|
||||
$strings['QuestionMultiChoiceSingleTask'] = 'Answers for multichoice questions (single)';
|
||||
$strings['QuestionMultiChoiceMultipleTask'] = 'Answers for multichoice questions (multiple)';
|
||||
$strings['QuestionsTrueFalseTask'] = 'Answers for truefalse questions';
|
||||
$strings['QuestionShortAnswerTask'] = 'Answers for shortanswers questions';
|
||||
$strings['CourseModulesScormTask'] = 'SCORM courses';
|
||||
$strings['ScormScoesTask'] = 'SCORM items';
|
||||
$strings['FilesForScormScoesTask'] = 'Files for SCORM items';
|
||||
$strings['UserSessionsTask'] = 'Course Sessions for users';
|
||||
$strings['CourseIntroductionsTask'] = 'Course introductions';
|
||||
$strings['FilesForCourseIntroductionsTask'] = 'Files for course introductions';
|
||||
$strings['FilesForCourseSectionsTask'] = 'Files for course sections';
|
||||
$strings['CourseModulesUrlTask'] = 'Course modules: URLs';
|
||||
$strings['UrlsTask'] = 'URLs';
|
||||
$strings['SortSectionModulesTask'] = 'Sort modules in section';
|
||||
$strings['UsersScormsViewTask'] = 'SCORM views for users';
|
||||
$strings['UsersScormsProgressTask'] = 'SCORM progress';
|
||||
$strings['UsersLearnPathsTask'] = 'Learn paths views of users';
|
||||
$strings['UsersLearnPathsLessonTimerTask'] = 'Lesson timer to start time of Learn paths section';
|
||||
$strings['QuizzesScoresTask'] = 'Update quiz scores in learn path';
|
||||
$strings['QuestionGapselectTask'] = 'Answers for gapselect questions';
|
||||
$strings['UsersLearnPathsLessonBranchTask'] = 'Lesson branch to total time in learn paths documents';
|
||||
$strings['UsersLearnPathsLessonAttemptsTask'] = 'Lesson attempts to total time in learn paths quizzes';
|
||||
$strings['UsersLearnPathsQuizzesTask'] = 'Quizzes attempts to learn paths quizzes attempts';
|
||||
$strings['UsersQuizzesAttemptsTask'] = 'Quiz attempts of users';
|
||||
$strings['UserQuestionAttemptsShortanswerTask'] = 'Question attempts of users for shortanswer';
|
||||
$strings['UserQuestionAttemptsGapselectTask'] = 'Question attempts of users for gapselect';
|
||||
$strings['UserQuestionAttemptsTruefalseTask'] = 'Question attempts of users for truefalse';
|
||||
$strings['UsersLastLoginTask'] = 'Last logins for users';
|
||||
$strings['TrackLoginTask'] = 'First login and last logout';
|
||||
$strings['TrackCourseAccessTask'] = 'User access to course';
|
||||
$strings['UserLearnPathsProgressScript'] = 'Update progress in learning paths for users.';
|
||||
$strings['UserScormsProgressScript'] = 'Update progress in SCORMs for users.';
|
||||
24
plugin/migrationmoodle/lang/french.php
Normal file
24
plugin/migrationmoodle/lang/french.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$strings['plugin_title'] = 'Importation depuis Moodle';
|
||||
$strings['plugin_comment'] = 'Exécuter un processus d\'import depuis une base de données et des fichiers Moodle dans Chamilo.';
|
||||
|
||||
$strings['MoodlePassword'] = 'Mot de passe Moodle';
|
||||
$strings['UninstallError'] = 'Une erreur s\'est produite durant la désinstallation du plugin d\'import Moodle.';
|
||||
|
||||
$strings['active'] = 'Activé';
|
||||
$strings['db_host'] = 'Hôte BdD Moodle';
|
||||
$strings['db_user'] = 'Utilisateur BdD Moodle';
|
||||
$strings['db_password'] = 'Mot de passe BdD Moodle';
|
||||
$strings['db_name'] = 'Nom BdD Moodle';
|
||||
$strings['user_filter'] = 'Filtre utilisateurs';
|
||||
$strings['user_filter_help'] = 'Seuls les utilisateurs dont le nom d\'utilisateur est préfixé de cette chaîne de caractères seront importés.<br>'
|
||||
.'L\'import des cours est aussi affecté par cette variable, car seuls les cours auxquels des utilisateurs commençant par ce préfixe sont inscrits seront migrés.';
|
||||
$strings['url_id'] = 'ID d\'URL';
|
||||
$strings['url_id_help'] = 'ID d\'URL (si multi-URL utilisés) dans lequel sauver les cours, utiilisateurs et sessions.';
|
||||
$strings['moodle_path'] = 'Chemin vers moodledata';
|
||||
$strings['moodle_path_help'] = 'Le chemin vers le répertoire moodledata. Habituellement quelque chose comme <pre>/var/www/moodledata</pre>';
|
||||
|
||||
// Tasks
|
||||
$strings['UsersTask'] = 'Utilisateurs';
|
||||
4
plugin/migrationmoodle/plugin.php
Normal file
4
plugin/migrationmoodle/plugin.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$plugin_info = MigrationMoodlePlugin::create()->get_info();
|
||||
120
plugin/migrationmoodle/run_cli.php
Normal file
120
plugin/migrationmoodle/run_cli.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Script\BaseScript;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Task\BaseTask;
|
||||
|
||||
$cidReset = true;
|
||||
|
||||
ini_set('memory_limit', -1);
|
||||
ini_set('max_execution_time', 0);
|
||||
|
||||
require_once __DIR__.'/../../main/inc/global.inc.php';
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
echo 'Run on CLI.'.PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
|
||||
$outputBuffering = false;
|
||||
|
||||
$plugin = MigrationMoodlePlugin::create();
|
||||
|
||||
$taskNames = [
|
||||
'course_categories',
|
||||
'courses',
|
||||
'course_introductions',
|
||||
'files_for_course_introductions',
|
||||
'course_sections',
|
||||
'files_for_course_sections',
|
||||
'course_modules_lesson',
|
||||
'lesson_pages',
|
||||
'lesson_pages_document',
|
||||
'files_for_lesson_pages',
|
||||
'lesson_pages_quiz',
|
||||
'lesson_pages_quiz_question',
|
||||
'lesson_answers_true_false',
|
||||
'lesson_answers_multiple_choice',
|
||||
'lesson_answers_multiple_answer',
|
||||
'lesson_answers_matching',
|
||||
'lesson_answers_essay',
|
||||
'lesson_answers_short_answer',
|
||||
'files_for_lesson_answers',
|
||||
'course_modules_quiz',
|
||||
'quizzes',
|
||||
'files_for_quizzes',
|
||||
'question_categories',
|
||||
'questions',
|
||||
'question_multi_choice_single',
|
||||
'question_multi_choice_multiple',
|
||||
'questions_true_false',
|
||||
'question_short_answer',
|
||||
'question_gapselect',
|
||||
'quizzes_scores',
|
||||
'course_modules_url',
|
||||
'urls',
|
||||
'sort_section_modules',
|
||||
'course_modules_scorm',
|
||||
'scorm_scoes',
|
||||
'files_for_scorm_scoes',
|
||||
'users',
|
||||
'users_last_login',
|
||||
'track_login',
|
||||
'user_sessions',
|
||||
'users_learn_paths',
|
||||
'users_learn_paths_lesson_timer',
|
||||
'users_learn_paths_lesson_branch',
|
||||
'users_learn_paths_lesson_attempts',
|
||||
'users_learn_paths_quizzes',
|
||||
'users_quizzes_attempts',
|
||||
'user_question_attempts_shortanswer',
|
||||
'user_question_attempts_gapselect',
|
||||
'user_question_attempts_truefalse',
|
||||
'users_scorms_view',
|
||||
'track_course_access',
|
||||
];
|
||||
|
||||
foreach ($taskNames as $i => $taskName) {
|
||||
$taskClass = api_underscore_to_camel_case($taskName).'Task';
|
||||
$taskClass = 'Chamilo\\PluginBundle\\MigrationMoodle\\Task\\'.$taskClass;
|
||||
|
||||
echo PHP_EOL.'['.date(DateTime::ATOM).'] '.($i + 1).': ';
|
||||
|
||||
if ($plugin->isTaskDone($taskName)) {
|
||||
echo "Already done \"$taskClass\"".PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "Executing \"$taskClass.\"".PHP_EOL;
|
||||
|
||||
/** @var BaseTask $task */
|
||||
$task = new $taskClass();
|
||||
$task->execute();
|
||||
|
||||
echo '['.date(DateTime::ATOM)."] End \"$taskClass\"".PHP_EOL;
|
||||
}
|
||||
|
||||
$scriptNames = [
|
||||
'user_learn_paths_progress',
|
||||
'user_scorms_progress',
|
||||
];
|
||||
|
||||
foreach ($scriptNames as $i => $scriptName) {
|
||||
$scriptClass = api_underscore_to_camel_case($scriptName).'Script';
|
||||
$scriptClass = 'Chamilo\\PluginBundle\\MigrationMoodle\\Script\\'.$scriptClass;
|
||||
|
||||
echo PHP_EOL.'['.date(DateTime::ATOM).'] '.($i + 1).': ';
|
||||
|
||||
if ($plugin->isTaskDone($scriptName)) {
|
||||
echo "Already done \"$scriptClass\"".PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "Executing \"$scriptClass.\"".PHP_EOL;
|
||||
|
||||
/** @var BaseScript $script */
|
||||
$script = new $scriptClass();
|
||||
$script->run();
|
||||
|
||||
echo '['.date(DateTime::ATOM)."] End \"$scriptClass\"".PHP_EOL;
|
||||
}
|
||||
63
plugin/migrationmoodle/src/Extractor/BaseExtractor.php
Normal file
63
plugin/migrationmoodle/src/Extractor/BaseExtractor.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Extractor;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\ExtractorInterface;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
|
||||
/**
|
||||
* Class Extractor.
|
||||
*/
|
||||
class BaseExtractor implements ExtractorInterface
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $query;
|
||||
|
||||
/**
|
||||
* Extractor constructor.
|
||||
*/
|
||||
public function __construct(array $configuration)
|
||||
{
|
||||
$this->query = $configuration['query'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function filter(array $sourceData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return \Generator|iterable
|
||||
*/
|
||||
public function extract()
|
||||
{
|
||||
$plugin = \MigrationMoodlePlugin::create();
|
||||
|
||||
try {
|
||||
$connection = $plugin->getConnection();
|
||||
} catch (DBALException $e) {
|
||||
throw new \Exception('Unable to start connection.', 0, $e);
|
||||
}
|
||||
|
||||
try {
|
||||
$statement = $connection->executeQuery($this->query);
|
||||
} catch (DBALException $e) {
|
||||
throw new \Exception("Unable to execute query \"{$this->query}\".", 0, $e);
|
||||
}
|
||||
|
||||
while ($sourceRow = $statement->fetch(FetchMode::ASSOCIATIVE)) {
|
||||
yield $sourceRow;
|
||||
}
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
}
|
||||
39
plugin/migrationmoodle/src/Extractor/FilterExtractor.php
Normal file
39
plugin/migrationmoodle/src/Extractor/FilterExtractor.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Extractor;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Traits\MapTrait\MapTrait;
|
||||
|
||||
/**
|
||||
* Class FilterExtractor.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Extractor
|
||||
*/
|
||||
abstract class FilterExtractor extends BaseExtractor
|
||||
{
|
||||
use MapTrait;
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function existsExtracted($id)
|
||||
{
|
||||
$taskName = $this->getTaskName();
|
||||
|
||||
$result = \Database::select(
|
||||
'COUNT(1) AS c',
|
||||
'plugin_migrationmoodle_item i INNER JOIN plugin_migrationmoodle_task t ON i.task_id = t.id',
|
||||
[
|
||||
'where' => [
|
||||
't.name = ? AND i.extracted_id = ?' => [$taskName, $id],
|
||||
],
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
return $result['c'] > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Extractor;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Task\CoursesTask;
|
||||
|
||||
/**
|
||||
* Class LoadedCoursesFilterExtractor.
|
||||
*
|
||||
* Extractor for course already extracted and loaded.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Extractor
|
||||
*/
|
||||
class LoadedCoursesFilterExtractor extends FilterExtractor
|
||||
{
|
||||
/**
|
||||
* LoadedCoursesFilterExtractor constructor.
|
||||
*/
|
||||
public function __construct(array $configuration)
|
||||
{
|
||||
parent::__construct($configuration);
|
||||
|
||||
$this->calledClass = CoursesTask::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function filter(array $sourceData)
|
||||
{
|
||||
$courseId = $sourceData['id'];
|
||||
|
||||
if (isset($sourceData['course'])) {
|
||||
$courseId = $sourceData['course'];
|
||||
}
|
||||
|
||||
return !$this->existsExtracted($courseId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Extractor;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Task\CourseModulesScormTask;
|
||||
|
||||
/**
|
||||
* Class LoadedScormsFilterExtractor.
|
||||
*
|
||||
* Extractor for scorms already extracted and loaded.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Extractor
|
||||
*/
|
||||
class LoadedScormsFilterExtractor extends FilterExtractor
|
||||
{
|
||||
/**
|
||||
* LoadedScormsFilterExtractor constructor.
|
||||
*/
|
||||
public function __construct(array $configuration)
|
||||
{
|
||||
parent::__construct($configuration);
|
||||
|
||||
$this->calledClass = CourseModulesScormTask::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to avoid scorms not yet migrated.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function filter(array $sourceData)
|
||||
{
|
||||
$scormId = $sourceData['scorm'];
|
||||
|
||||
return !$this->existsExtracted($scormId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Extractor;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Task\UsersTask;
|
||||
|
||||
/**
|
||||
* Class LoadedUsersFilterExtractor.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Extractor
|
||||
*/
|
||||
class LoadedUsersFilterExtractor extends FilterExtractor
|
||||
{
|
||||
/**
|
||||
* LoadedUsersFilterExtractor constructor.
|
||||
*/
|
||||
public function __construct(array $configuration)
|
||||
{
|
||||
parent::__construct($configuration);
|
||||
|
||||
$this->calledClass = UsersTask::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function filter(array $sourceData)
|
||||
{
|
||||
$userId = $sourceData['id'];
|
||||
|
||||
if (isset($sourceData['userid'])) {
|
||||
$userId = $sourceData['userid'];
|
||||
}
|
||||
|
||||
return !$this->existsExtracted($userId);
|
||||
}
|
||||
}
|
||||
22
plugin/migrationmoodle/src/Interfaces/ExtractorInterface.php
Normal file
22
plugin/migrationmoodle/src/Interfaces/ExtractorInterface.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Interfaces;
|
||||
|
||||
/**
|
||||
* Interface ExtractorInterface.
|
||||
*/
|
||||
interface ExtractorInterface
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function filter(array $sourceData);
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function extract();
|
||||
}
|
||||
17
plugin/migrationmoodle/src/Interfaces/LoaderInterface.php
Normal file
17
plugin/migrationmoodle/src/Interfaces/LoaderInterface.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Interfaces;
|
||||
|
||||
/**
|
||||
* Interface LoaderInterface.
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Interfaces;
|
||||
|
||||
/**
|
||||
* Interface TransformPropertyInterface.
|
||||
*/
|
||||
interface TransformPropertyInterface
|
||||
{
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function transform(array $data);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Interfaces;
|
||||
|
||||
/**
|
||||
* Interface TransformerInterface.
|
||||
*/
|
||||
interface TransformerInterface
|
||||
{
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function transform(array $sourceData);
|
||||
}
|
||||
67
plugin/migrationmoodle/src/Loader/CQuizLoader.php
Normal file
67
plugin/migrationmoodle/src/Loader/CQuizLoader.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CQuizLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CQuizLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->updateTitle(\Exercise::format_title_variable($incomingData['exerciseTitle']));
|
||||
$exercise->updateDescription($incomingData['exerciseDescription']);
|
||||
$exercise->updateAttempts($incomingData['exerciseAttempts']);
|
||||
$exercise->updateFeedbackType(0);
|
||||
$exercise->updateType(2);
|
||||
$exercise->setRandom(0);
|
||||
$exercise->updateRandomAnswers($incomingData['randomAnswers']);
|
||||
$exercise->updateResultsDisabled(0);
|
||||
$exercise->updateExpiredTime($incomingData['enabletimercontroltotalminutes']);
|
||||
//$exercise->updatePropagateNegative($incomingData['propagate_neg']);
|
||||
//$exercise->updateSaveCorrectAnswers($incomingData['save_correct_answers']);
|
||||
//$exercise->updateRandomByCat($incomingData['randomByCat']);
|
||||
$exercise->updateTextWhenFinished('');
|
||||
$exercise->updateDisplayCategoryName(1);
|
||||
//$exercise->updateReviewAnswers($incomingData['review_answers']);
|
||||
$exercise->updatePassPercentage($incomingData['pass_percentage']);
|
||||
//$exercise->updateCategories($incomingData['category']);
|
||||
//$exercise->updateEndButton($incomingData['end_button']);
|
||||
//$exercise->setOnSuccessMessage($incomingData['on_success_message']);
|
||||
//$exercise->setOnFailedMessage($incomingData['on_failed_message']);
|
||||
//$exercise->updateEmailNotificationTemplate($incomingData['email_notification_template']);
|
||||
//$exercise->setEmailNotificationTemplateToUser($incomingData['email_notification_template_to_user']);
|
||||
//$exercise->setNotifyUserByEmail($incomingData['notify_user_by_email']);
|
||||
//$exercise->setModelType($incomingData['model_type']);
|
||||
$exercise->setQuestionSelectionType(1);
|
||||
$exercise->setHideQuestionTitle(0);
|
||||
$exercise->sessionId = 0;
|
||||
//$exercise->setScoreTypeModel($incomingData['score_type_model']);
|
||||
//$exercise->setGlobalCategoryId($incomingData['global_category_id']);
|
||||
//$exercise->setShowPreviousButton($incomingData['show_previous_button']);
|
||||
//$exercise->setNotifications($incomingData['notifications']);
|
||||
//$exercise->setExerciseCategoryId($incomingData['exercise_category_id']);
|
||||
$exercise->setPageResultConfiguration($incomingData);
|
||||
$exercise->start_time = api_get_utc_datetime($incomingData['start_time'], true);
|
||||
$exercise->end_time = api_get_utc_datetime($incomingData['end_time'], true);
|
||||
$exercise->expired_time = $incomingData['enabletimercontroltotalminutes'];
|
||||
$exercise->random_answers = $incomingData['randomAnswers'] == 1 ? 1 : 0;
|
||||
|
||||
$iId = $exercise->save();
|
||||
|
||||
return $iId;
|
||||
}
|
||||
}
|
||||
42
plugin/migrationmoodle/src/Loader/CourseCategoriesLoader.php
Normal file
42
plugin/migrationmoodle/src/Loader/CourseCategoriesLoader.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CourseCategoriesLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseCategoriesLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$id = \CourseCategory::addNode(
|
||||
$incomingData['code'],
|
||||
$incomingData['name'],
|
||||
'TRUE',
|
||||
$incomingData['parent_id']
|
||||
);
|
||||
|
||||
if (empty($id)) {
|
||||
throw new \Exception("Course category ({$incomingData['code']}) not migrated. Maybe it already exists.");
|
||||
}
|
||||
|
||||
$tblUrlCategory = \Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
|
||||
$accessUrlId = \MigrationMoodlePlugin::create()->getAccessUrlId();
|
||||
|
||||
\Database::query("UPDATE $tblUrlCategory SET access_url_id = $accessUrlId WHERE course_category_id = $id");
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
65
plugin/migrationmoodle/src/Loader/CourseFilesLoader.php
Normal file
65
plugin/migrationmoodle/src/Loader/CourseFilesLoader.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Traits\FileFinderTrait;
|
||||
|
||||
/**
|
||||
* Class CourseFilesLoader.
|
||||
*
|
||||
* Loader to create the files needed for Chamilo course documents coming from the files in Moodle course.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseFilesLoader implements LoaderInterface
|
||||
{
|
||||
use FileFinderTrait;
|
||||
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$userId = 1;
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['course']);
|
||||
|
||||
$filePath = $this->findFilePath($incomingData['contenthash']);
|
||||
|
||||
$file = [
|
||||
'file' => [
|
||||
'name' => $incomingData['filename'],
|
||||
'tmp_name' => $filePath,
|
||||
'type' => $incomingData['mimetype'],
|
||||
'size' => $incomingData['filesize'],
|
||||
'error' => 0,
|
||||
'from_file' => true,
|
||||
'move_file' => true,
|
||||
],
|
||||
];
|
||||
|
||||
$_POST['language'] = $courseInfo['language'];
|
||||
|
||||
$fileData = \DocumentManager::upload_document(
|
||||
$file,
|
||||
'/',
|
||||
$incomingData['filename'],
|
||||
'',
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
'file',
|
||||
false,
|
||||
$userId,
|
||||
$courseInfo
|
||||
);
|
||||
|
||||
return $fileData['iid'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CourseIntroductionLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseIntroductionLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
return \Database::insert(
|
||||
\Database::get_course_table(TABLE_TOOL_INTRO),
|
||||
[
|
||||
'session_id' => 0,
|
||||
'c_id' => $incomingData['c_id'],
|
||||
'id' => TOOL_COURSE_HOMEPAGE,
|
||||
'intro_text' => $incomingData['description'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CourseModulesLessonLoader.
|
||||
*
|
||||
* Loader for create and Chamilo learning path section coming from a Moodle course module.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseModulesLessonLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$lp = new \learnpath(
|
||||
$incomingData['c_code'],
|
||||
$incomingData['lp_id'],
|
||||
1
|
||||
);
|
||||
$itemId = $lp->add_item(
|
||||
0,
|
||||
0,
|
||||
'dir',
|
||||
0,
|
||||
$incomingData['title'],
|
||||
''
|
||||
);
|
||||
|
||||
return $itemId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CourseModulesQuizLoader.
|
||||
*
|
||||
* Loader for create a Chamilo learning path item (quiz type) coming from transformed data of Moodle course quiz module.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseModulesQuizLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$lp = new \learnpath(
|
||||
$incomingData['c_code'],
|
||||
$incomingData['lp_id'],
|
||||
1
|
||||
);
|
||||
|
||||
return $lp->add_item(
|
||||
0,
|
||||
0,
|
||||
'quiz',
|
||||
0,
|
||||
$incomingData['title'],
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
123
plugin/migrationmoodle/src/Loader/CourseModulesScormLoader.php
Normal file
123
plugin/migrationmoodle/src/Loader/CourseModulesScormLoader.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* Class CourseModulesScormLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseModulesScormLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblLpMain = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$resultDisplayOrder = \Database::query(
|
||||
"SELECT
|
||||
CASE WHEN MAX(display_order) > 0 THEN MAX(display_order) + 1 ELSE 1 END AS display_order
|
||||
FROM $tblLpMain WHERE c_id = {$incomingData['c_id']}"
|
||||
);
|
||||
$row = \Database::fetch_assoc($resultDisplayOrder);
|
||||
$displayOrder = $row['display_order'];
|
||||
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
$userId = 1;
|
||||
|
||||
$incomingData['path'] = $this->createDirectory($incomingData['name'], $courseInfo['code']);
|
||||
$incomingData['use_max_score'] = $incomingData['use_max_score'] == 100;
|
||||
|
||||
$incomingData['created_on'] = $incomingData['created_on']
|
||||
? $incomingData['created_on']->format('Y-m-d h:i:s')
|
||||
: null;
|
||||
$incomingData['modified_on'] = $incomingData['modified_on']
|
||||
? $incomingData['modified_on']->format('Y-m-d h:i:s')
|
||||
: null;
|
||||
$incomingData['publicated_on'] = $incomingData['publicated_on']
|
||||
? $incomingData['publicated_on']->format('Y-m-d h:i:s')
|
||||
: null;
|
||||
|
||||
$params = array_merge(
|
||||
$incomingData,
|
||||
[
|
||||
'lp_type' => 2,
|
||||
'description' => '',
|
||||
'force_commit' => 0,
|
||||
'default_view_mod' => 'embedded',
|
||||
'default_encoding' => 'UTF-8',
|
||||
'js_lib' => 'scorm_api.php',
|
||||
'display_order' => $displayOrder,
|
||||
'session_id' => 0,
|
||||
'content_maker' => '',
|
||||
'content_license' => '',
|
||||
'debug' => 0,
|
||||
'theme' => '',
|
||||
'preview_image' => '',
|
||||
'author' => '',
|
||||
'prerequisite' => 0,
|
||||
'seriousgame_mode' => 0,
|
||||
'autolaunch' => 0,
|
||||
'category_id' => 0,
|
||||
'max_attempts' => 0,
|
||||
'subscribe_users' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
$lpId = \Database::insert($tblLpMain, $params);
|
||||
|
||||
if ($lpId) {
|
||||
\Database::query("UPDATE $tblLpMain SET id = iid WHERE iid = $lpId");
|
||||
|
||||
api_item_property_update($courseInfo, TOOL_LEARNPATH, $lpId, 'LearnpathAdded', $userId);
|
||||
api_item_property_update($courseInfo, TOOL_LEARNPATH, $lpId, 'visible', $userId);
|
||||
}
|
||||
|
||||
return $lpId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generateDirectoryName($fileName)
|
||||
{
|
||||
$newDirectory = trim($fileName);
|
||||
$newDirectory = trim($newDirectory, '/');
|
||||
|
||||
return api_replace_dangerous_char($newDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $courseCode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function createDirectory($name, $courseCode)
|
||||
{
|
||||
$courseRelDir = api_get_path(SYS_COURSE_PATH).api_get_course_path($courseCode).'/scorm';
|
||||
|
||||
$newDirectory = self::generateDirectoryName($name);
|
||||
|
||||
$fullPath = "$courseRelDir/$newDirectory";
|
||||
|
||||
$fileSystem = new Filesystem();
|
||||
|
||||
if (!is_dir($fullPath)) {
|
||||
$fileSystem->mkdir(
|
||||
$fullPath,
|
||||
api_get_permissions_for_new_directories()
|
||||
);
|
||||
}
|
||||
|
||||
return "$newDirectory/.";
|
||||
}
|
||||
}
|
||||
35
plugin/migrationmoodle/src/Loader/CourseModulesUrlLoader.php
Normal file
35
plugin/migrationmoodle/src/Loader/CourseModulesUrlLoader.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CourseModulesUrlLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseModulesUrlLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$lp = new \learnpath(
|
||||
$incomingData['c_code'],
|
||||
$incomingData['lp_id'],
|
||||
1
|
||||
);
|
||||
|
||||
return $lp->add_item(
|
||||
0,
|
||||
0,
|
||||
'link',
|
||||
0,
|
||||
$incomingData['title'],
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
52
plugin/migrationmoodle/src/Loader/CourseSectionsLoader.php
Normal file
52
plugin/migrationmoodle/src/Loader/CourseSectionsLoader.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CourseSectionsLoader.
|
||||
*
|
||||
* Loader for create a Chamilo learning path coming from a Moodle course section.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CourseSectionsLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info($incomingData['course_code']);
|
||||
|
||||
$lpId = \learnpath::add_lp(
|
||||
$incomingData['course_code'],
|
||||
$incomingData['name'],
|
||||
'',
|
||||
'chamilo',
|
||||
'manual'
|
||||
);
|
||||
|
||||
$incomingData['description'] = trim($incomingData['description']);
|
||||
|
||||
if (!empty($incomingData['description'])) {
|
||||
$lp = new \learnpath(
|
||||
$incomingData['course_code'],
|
||||
$lpId,
|
||||
1
|
||||
);
|
||||
$lp->generate_lp_folder($courseInfo);
|
||||
|
||||
$itemTitle = get_lang('Description');
|
||||
|
||||
$documentId = $lp->create_document($courseInfo, $incomingData['description'], $itemTitle);
|
||||
$lp->add_item(0, 0, 'document', $documentId, $itemTitle, '');
|
||||
}
|
||||
|
||||
return $lpId;
|
||||
}
|
||||
}
|
||||
50
plugin/migrationmoodle/src/Loader/CoursesLoader.php
Normal file
50
plugin/migrationmoodle/src/Loader/CoursesLoader.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class CoursesLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class CoursesLoader implements LoaderInterface
|
||||
{
|
||||
public const LOAD_MODE_REUSE = 'reuse';
|
||||
public const LOAD_MODE_DUPLICATE = 'duplicate';
|
||||
|
||||
/**
|
||||
* @var string Load mode: "reuse" or "duplicate". Default is "duplicate".
|
||||
*/
|
||||
private $loadMode = self::LOAD_MODE_DUPLICATE;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info($incomingData['wanted_code']);
|
||||
|
||||
if (!empty($courseInfo)) {
|
||||
if ($this->loadMode === self::LOAD_MODE_REUSE) {
|
||||
return $courseInfo['real_id'];
|
||||
}
|
||||
|
||||
if ($this->loadMode === self::LOAD_MODE_DUPLICATE) {
|
||||
$incomingData['wanted_code'] = $incomingData['wanted_code'].substr(md5(uniqid(rand())), 0, 10);
|
||||
}
|
||||
}
|
||||
|
||||
$incomingData['subscribe'] = false;
|
||||
$incomingData['unsubscribe'] = false;
|
||||
$incomingData['disk_quota'] = 500 * 1024 * 1024;
|
||||
|
||||
$accessUrlId = \MigrationMoodlePlugin::create()->getAccessUrlId();
|
||||
|
||||
$courseInfo = \CourseManager::create_course($incomingData, 1, $accessUrlId);
|
||||
|
||||
return $courseInfo['real_id'];
|
||||
}
|
||||
}
|
||||
46
plugin/migrationmoodle/src/Loader/FilesForScormScoLoader.php
Normal file
46
plugin/migrationmoodle/src/Loader/FilesForScormScoLoader.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Traits\FileFinderTrait;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* Class FilesForScormScoLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class FilesForScormScoLoader extends CourseFilesLoader
|
||||
{
|
||||
use FileFinderTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$course = api_get_course_entity($incomingData['c_id']);
|
||||
|
||||
$moodleFilePath = $this->findFilePath($incomingData['contenthash']);
|
||||
|
||||
$sysCourseScormPath = api_get_path(SYS_COURSE_PATH).$course->getDirectory().'/scorm';
|
||||
$lpDirectory = CourseModulesScormLoader::generateDirectoryName($incomingData['lp_name']);
|
||||
$lpDirectoryPath = "$sysCourseScormPath/$lpDirectory";
|
||||
$fileDirectoryPath = $lpDirectoryPath.$incomingData['filepath'];
|
||||
$filePath = $fileDirectoryPath.$incomingData['filename'];
|
||||
|
||||
$fileSystem = new Filesystem();
|
||||
|
||||
if ($incomingData['filepath'] != '/') {
|
||||
$fileSystem->mkdir(
|
||||
$fileDirectoryPath,
|
||||
api_get_permissions_for_new_directories()
|
||||
);
|
||||
}
|
||||
|
||||
$fileSystem->copy($moodleFilePath, $filePath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersEssayLoader.
|
||||
*
|
||||
* Loader to create Free Answer question answers comming from Essay lesson page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonAnswersEssayLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::read($incomingData['question_id'], $courseInfo);
|
||||
|
||||
$question->weighting = $incomingData['score'];
|
||||
$question->save($exercise);
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersMatchingLoader.
|
||||
*
|
||||
* Loader to create Matching question answers comming from Matching lesson page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonAnswersMatchingLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::read($incomingData['question_id'], $courseInfo);
|
||||
|
||||
$answer = new \Answer($incomingData['question_id'], $incomingData['c_id'], $exercise);
|
||||
$questionsAnswers = $answer->getAnswers();
|
||||
|
||||
foreach ($questionsAnswers as $questionsAnswer) {
|
||||
$answer->createAnswer(
|
||||
$questionsAnswer['answer'],
|
||||
$questionsAnswer['correct'],
|
||||
$questionsAnswer['comment'],
|
||||
$questionsAnswer['ponderation'],
|
||||
$questionsAnswer['position'],
|
||||
$questionsAnswer['hotspot_coordinates'],
|
||||
$questionsAnswer['hotspot_type'],
|
||||
$questionsAnswer['destination']
|
||||
);
|
||||
}
|
||||
|
||||
$optionPosition = $question->countAnswers() + 1;
|
||||
|
||||
$answer->createAnswer($incomingData['feedback'], 0, '', 0, $optionPosition);
|
||||
|
||||
$answerPosition = $optionPosition + 1;
|
||||
|
||||
$answer->createAnswer(
|
||||
$incomingData['answer'],
|
||||
$optionPosition,
|
||||
'',
|
||||
$incomingData['score'],
|
||||
$answerPosition
|
||||
);
|
||||
|
||||
$answer->save();
|
||||
|
||||
$question->weighting += $incomingData['score'];
|
||||
$question->save($exercise);
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CQuizAnswer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersMultipleAnswerLoader.
|
||||
*
|
||||
* Loader to create Unique Answer question comming from Multiple Choice lesson page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonAnswersMultipleAnswerLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::read($incomingData['question_id'], $courseInfo);
|
||||
|
||||
$answer = new \Answer($incomingData['question_id'], $incomingData['c_id'], $exercise);
|
||||
$questionsAnswers = $answer->getAnswers();
|
||||
|
||||
foreach ($questionsAnswers as $questionsAnswer) {
|
||||
$answer->createAnswer(
|
||||
$questionsAnswer['answer'],
|
||||
$questionsAnswer['correct'],
|
||||
$questionsAnswer['comment'],
|
||||
$questionsAnswer['ponderation'],
|
||||
$questionsAnswer['position'],
|
||||
$questionsAnswer['hotspot_coordinates'],
|
||||
$questionsAnswer['hotspot_type'],
|
||||
$questionsAnswer['destination']
|
||||
);
|
||||
}
|
||||
|
||||
$incomingData['score'] = abs($incomingData['score']);
|
||||
|
||||
if (!$incomingData['is_correct']) {
|
||||
$incomingData['score'] = -$incomingData['score'];
|
||||
}
|
||||
|
||||
if ($incomingData['score'] > 0) {
|
||||
$question->weighting += $incomingData['score'];
|
||||
}
|
||||
|
||||
$answer->createAnswer(
|
||||
$incomingData['answer'],
|
||||
$incomingData['is_correct'],
|
||||
$incomingData['feedback'],
|
||||
$incomingData['score'],
|
||||
$question->countAnswers() + 1,
|
||||
null,
|
||||
null,
|
||||
CQuizAnswer::DEFAULT_DESTINATION
|
||||
);
|
||||
|
||||
$answer->save();
|
||||
$question->save($exercise);
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersMultipleChoiceLoader.
|
||||
*
|
||||
* Loader to create Unique Answer question comming from Multiple Choice lesson page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonAnswersMultipleChoiceLoader extends LessonAnswersTrueFalseLoader
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
return parent::load($incomingData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersShortAnswerLoader.
|
||||
*
|
||||
* Loader to create Fill Blanks question answers comming from Short Answer and Numerical lesson page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonAnswersShortAnswerLoader implements LoaderInterface
|
||||
{
|
||||
public const INPUT_WIDTH = 300;
|
||||
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::read($incomingData['question_id'], $courseInfo);
|
||||
$question->weighting = 0;
|
||||
|
||||
$answer = new \Answer($incomingData['question_id'], $incomingData['c_id'], $exercise);
|
||||
|
||||
$incomingData['answers'] = '['.$incomingData['answers'].']';
|
||||
// Remove the "::" eventually written by the user
|
||||
$incomingData['answers'] = str_replace('::', '', $incomingData['answers']);
|
||||
// Remove starting and ending space and
|
||||
$incomingData['answers'] = api_preg_replace("/\xc2\xa0/", " ", $incomingData['answers']);
|
||||
|
||||
$blankStartSeparator = '[';
|
||||
$blankEndSeparator = ']';
|
||||
$blankStartSeparatorRegexp = \FillBlanks::escapeForRegexp($blankStartSeparator);
|
||||
$blankEndSeparatorRegexp = \FillBlanks::escapeForRegexp($blankEndSeparator);
|
||||
|
||||
// Remove spaces at the beginning and the end of text in square brackets
|
||||
$return = preg_replace_callback(
|
||||
"/".$blankStartSeparatorRegexp."[^]]+".$blankEndSeparatorRegexp."/",
|
||||
function ($matches) use ($blankStartSeparator, $blankEndSeparator) {
|
||||
$matchingResult = $matches[0];
|
||||
$matchingResult = trim($matchingResult, $blankStartSeparator);
|
||||
$matchingResult = trim($matchingResult, $blankEndSeparator);
|
||||
$matchingResult = trim($matchingResult);
|
||||
// Remove forbidden chars
|
||||
$matchingResult = str_replace("/\\/", "", $matchingResult);
|
||||
$matchingResult = str_replace('/"/', "", $matchingResult);
|
||||
|
||||
return $blankStartSeparator.$matchingResult.$blankEndSeparator;
|
||||
},
|
||||
$incomingData['answers']
|
||||
);
|
||||
|
||||
$question->weighting += $incomingData['scores'];
|
||||
|
||||
$return .= '::'.$incomingData['scores'].':';
|
||||
$return .= self::INPUT_WIDTH;
|
||||
$return .= ':0@';
|
||||
|
||||
$answer->createAnswer($return, 0, $incomingData['comment'], 0, 1);
|
||||
$answer->save();
|
||||
|
||||
$question->save($exercise);
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CQuizAnswer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersTrueFalseLoader.
|
||||
*
|
||||
* Loader for True-False answers from lesson pages.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonAnswersTrueFalseLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::read($incomingData['question_id'], $courseInfo);
|
||||
|
||||
$answer = new \Answer($incomingData['question_id'], $incomingData['c_id'], $exercise);
|
||||
$questionsAnswers = $answer->getAnswers();
|
||||
|
||||
foreach ($questionsAnswers as $questionsAnswer) {
|
||||
$answer->createAnswer(
|
||||
$questionsAnswer['answer'],
|
||||
$questionsAnswer['correct'],
|
||||
$questionsAnswer['comment'],
|
||||
$questionsAnswer['ponderation'],
|
||||
$questionsAnswer['position'],
|
||||
$questionsAnswer['hotspot_coordinates'],
|
||||
$questionsAnswer['hotspot_type'],
|
||||
$questionsAnswer['destination']
|
||||
);
|
||||
}
|
||||
|
||||
if ($incomingData['is_correct']) {
|
||||
$incomingData['score'] = abs($incomingData['score']);
|
||||
|
||||
$question->weighting += $incomingData['score'];
|
||||
}
|
||||
|
||||
$answer->createAnswer(
|
||||
$incomingData['answer'],
|
||||
$incomingData['is_correct'],
|
||||
$incomingData['feedback'],
|
||||
$incomingData['score'],
|
||||
$question->countAnswers() + 1,
|
||||
null,
|
||||
null,
|
||||
CQuizAnswer::DEFAULT_DESTINATION
|
||||
);
|
||||
|
||||
$answer->save();
|
||||
$question->save($exercise);
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonPagesLoader.
|
||||
*
|
||||
* Loader for create a HTML document with the transformed data coming from a Moodle lesson page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonPagesDocumentLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$lp = new \learnpath(
|
||||
$courseInfo['code'],
|
||||
$incomingData['lp_id'],
|
||||
1
|
||||
);
|
||||
|
||||
$lp->generate_lp_folder($courseInfo);
|
||||
|
||||
$docId = $lp->create_document(
|
||||
$courseInfo,
|
||||
$incomingData['item_content'],
|
||||
$incomingData['item_title'],
|
||||
'html'
|
||||
);
|
||||
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
|
||||
\Database::query("UPDATE $tblLpItem SET path = '$docId' WHERE iid = {$incomingData['item_id']}");
|
||||
|
||||
return $docId;
|
||||
}
|
||||
}
|
||||
40
plugin/migrationmoodle/src/Loader/LessonPagesLoader.php
Normal file
40
plugin/migrationmoodle/src/Loader/LessonPagesLoader.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LpDocumentsLoader.
|
||||
*
|
||||
* Loader to create the items for Chamilo learning paths coming from the list of Moodle lesson pages in a course.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonPagesLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$lp = new \learnpath(
|
||||
$incomingData['c_code'],
|
||||
$incomingData['lp_id'],
|
||||
1
|
||||
);
|
||||
$itemId = $lp->add_item(
|
||||
$incomingData['parent'],
|
||||
$incomingData['previous'],
|
||||
$incomingData['item_type'],
|
||||
0,
|
||||
$incomingData['title'],
|
||||
''
|
||||
);
|
||||
|
||||
return $itemId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonQuestionPagesQuestionLoader.
|
||||
*
|
||||
* Loader for create a question to be added in a quiz according the transformed data
|
||||
* coming from a moodle's lesson question page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonQuestionPagesQuestionLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::getInstance($incomingData['question_type']);
|
||||
$question->course = api_get_course_info_by_id($incomingData['c_id']);
|
||||
$question->updateTitle($incomingData['question_title']);
|
||||
$question->updateLevel(1);
|
||||
$question->updateCategory(0);
|
||||
$question->save($exercise);
|
||||
|
||||
$exercise->addToList($question->id);
|
||||
$exercise->update_question_positions();
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class LessonQuestionPagesQuizLoader.
|
||||
*
|
||||
* Loader for create a quiz according the transformed data coming from a moodle's lesson question page.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class LessonQuestionPagesQuizLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->updateTitle(\Exercise::format_title_variable($incomingData['item_title']));
|
||||
$exercise->updateDescription('');
|
||||
$exercise->updateAttempts(0);
|
||||
$exercise->updateFeedbackType(0);
|
||||
$exercise->updateType(ALL_ON_ONE_PAGE);
|
||||
$exercise->setRandom(0);
|
||||
$exercise->updateRandomAnswers(0);
|
||||
$exercise->updateResultsDisabled(0);
|
||||
$exercise->updateExpiredTime(0);
|
||||
$exercise->updateTextWhenFinished('');
|
||||
$exercise->updateDisplayCategoryName(1);
|
||||
$exercise->updatePassPercentage(0);
|
||||
$exercise->setQuestionSelectionType(1);
|
||||
$exercise->setHideQuestionTitle(0);
|
||||
$exercise->sessionId = 0;
|
||||
$exercise->start_time = null;
|
||||
$exercise->end_time = null;
|
||||
$exercise->active = false;
|
||||
|
||||
$quizId = $exercise->save();
|
||||
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
|
||||
\Database::query("UPDATE $tblLpItem SET path = '$quizId' WHERE iid = {$incomingData['item_id']}");
|
||||
|
||||
return $quizId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class QuestionCategoriesLoader.
|
||||
*
|
||||
* Loader for create a category for Chamilo quiz questions coming from a Moodle question category.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class QuestionCategoriesLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$course = api_get_course_entity($incomingData['c_id']);
|
||||
|
||||
if (!$course) {
|
||||
throw new \Exception("The question category ({$incomingData['name']}) found, but it will not be migrated.");
|
||||
}
|
||||
|
||||
$category = new \TestCategory();
|
||||
$category->name = $incomingData['name'];
|
||||
$category->description = $incomingData['description'];
|
||||
|
||||
$id = $category->save($incomingData['c_id']);
|
||||
|
||||
if (false === $id) {
|
||||
throw new \Exception("The quiz category \"{$incomingData['name']}\" already exists.");
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class QuestionGapselectLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class QuestionGapselectLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($incomingData['c_id']);
|
||||
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->read($incomingData['quiz_id']);
|
||||
|
||||
$question = \Question::read($incomingData['question_id'], $courseInfo);
|
||||
$question->setTitle(get_lang('FillBlanks'));
|
||||
$question->weighting = $incomingData['score'];
|
||||
|
||||
$answer = new \Answer($incomingData['question_id'], $incomingData['c_id'], $exercise);
|
||||
$answer->createAnswer($incomingData['answer'], 0, $incomingData['comment'], 0, 1);
|
||||
$answer->save();
|
||||
|
||||
$question->save($exercise);
|
||||
|
||||
return $question->id;
|
||||
}
|
||||
}
|
||||
50
plugin/migrationmoodle/src/Loader/QuizzesLoader.php
Normal file
50
plugin/migrationmoodle/src/Loader/QuizzesLoader.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class QuizzesLoader.
|
||||
*
|
||||
* Loader for create a Chamilo quiz inside a learning path item coming from a Moodle quiz.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class QuizzesLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$exercise = new \Exercise($incomingData['c_id']);
|
||||
$exercise->updateTitle(\Exercise::format_title_variable($incomingData['exerciseTitle']));
|
||||
$exercise->updateDescription($incomingData['exerciseDescription']);
|
||||
$exercise->updateAttempts($incomingData['exerciseAttempts']);
|
||||
$exercise->updateFeedbackType(0);
|
||||
$exercise->updateType(ALL_ON_ONE_PAGE);
|
||||
$exercise->setRandom(0);
|
||||
$exercise->updateRandomAnswers($incomingData['randomAnswers']);
|
||||
$exercise->updateResultsDisabled(0);
|
||||
$exercise->updateExpiredTime($incomingData['enabletimercontroltotalminutes']);
|
||||
$exercise->updateTextWhenFinished('');
|
||||
$exercise->updateDisplayCategoryName(1);
|
||||
$exercise->updatePassPercentage($incomingData['pass_percentage']);
|
||||
$exercise->setQuestionSelectionType(1);
|
||||
$exercise->setHideQuestionTitle(0);
|
||||
$exercise->sessionId = 0;
|
||||
$exercise->start_time = api_get_utc_datetime($incomingData['start_time'], true);
|
||||
$exercise->end_time = api_get_utc_datetime($incomingData['end_time'], true);
|
||||
|
||||
$quizId = $exercise->save();
|
||||
|
||||
\Database::query("UPDATE c_quiz SET active = 0 WHERE iid = $quizId");
|
||||
\Database::query("UPDATE c_lp_item SET path = '$quizId' WHERE iid = {$incomingData['item_id']}");
|
||||
|
||||
return $quizId;
|
||||
}
|
||||
}
|
||||
39
plugin/migrationmoodle/src/Loader/QuizzesScoresLoader.php
Normal file
39
plugin/migrationmoodle/src/Loader/QuizzesScoresLoader.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class QuizzesScoresLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class QuizzesScoresLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblQuizQuestion = \Database::get_course_table(TABLE_QUIZ_QUESTION);
|
||||
$tblQuizRelQuestion = \Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
|
||||
$sql = "SELECT SUM(ponderation)
|
||||
FROM $tblQuizQuestion as quiz_question
|
||||
INNER JOIN $tblQuizRelQuestion as quiz_rel_question
|
||||
ON quiz_question.iid = quiz_rel_question.question_id
|
||||
WHERE
|
||||
quiz_rel_question.exercice_id = {$incomingData['quiz_id']}
|
||||
AND quiz_rel_question.c_id = {$incomingData['c_id']}";
|
||||
|
||||
$rsQuiz = \Database::query($sql);
|
||||
$maxScore = \Database::result($rsQuiz, 0, 0) ?: 0;
|
||||
|
||||
\Database::query("UPDATE $tblLpItem SET max_score = $maxScore WHERE iid = {$incomingData['item_id']}");
|
||||
|
||||
return $incomingData['item_id'];
|
||||
}
|
||||
}
|
||||
31
plugin/migrationmoodle/src/Loader/RoleAssignmentsLoader.php
Normal file
31
plugin/migrationmoodle/src/Loader/RoleAssignmentsLoader.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class RoleAssignmentsLoader.
|
||||
*
|
||||
* Loader to subscribe a Chamilo user in a course according their Moodle role assignment.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class RoleAssignmentsLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the data and return the ID inserted.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$result = \CourseManager::subscribeUser(
|
||||
$incomingData['user_id'],
|
||||
$incomingData['course_code'],
|
||||
$incomingData['status']
|
||||
);
|
||||
|
||||
return (int) $result;
|
||||
}
|
||||
}
|
||||
43
plugin/migrationmoodle/src/Loader/ScormScoLoader.php
Normal file
43
plugin/migrationmoodle/src/Loader/ScormScoLoader.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class ScormScoLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class ScormScoLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$scorm = new \scorm(
|
||||
$incomingData['c_code'],
|
||||
$incomingData['lp_id'],
|
||||
1
|
||||
);
|
||||
|
||||
$itemId = $scorm->add_item(
|
||||
$incomingData['parent_item_id'],
|
||||
0,
|
||||
$incomingData['item_type'],
|
||||
0,
|
||||
$incomingData['title'],
|
||||
''
|
||||
);
|
||||
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
|
||||
\Database::query(
|
||||
"UPDATE $tblLpItem SET path = '{$incomingData['path']}', ref = '{$incomingData['ref']}' WHERE iid = $itemId"
|
||||
);
|
||||
|
||||
return $itemId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class SortSectionModuleLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class SortSectionModuleLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
// Search the Description document to put it as first item
|
||||
$firstItem = \Database::select(
|
||||
'iid',
|
||||
\Database::get_course_table(TABLE_LP_ITEM),
|
||||
[
|
||||
'where' => [
|
||||
'c_id = ? AND lp_id = ? AND parent_item_id = ? AND item_type = ?' => [
|
||||
$incomingData['c_id'],
|
||||
$incomingData['lp_id'],
|
||||
0,
|
||||
TOOL_DOCUMENT,
|
||||
],
|
||||
],
|
||||
'order' => 'iid ASC',
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
$orderList = $incomingData['order_list'];
|
||||
|
||||
if ($firstItem) {
|
||||
$orderList = [$firstItem['iid'] => 0] + $orderList;
|
||||
}
|
||||
|
||||
\learnpath::sortItemByOrderList(
|
||||
$orderList,
|
||||
$incomingData['c_id']
|
||||
);
|
||||
|
||||
return $incomingData['lp_id'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class TrackCourseAccessLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class TrackCourseAccessLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
list($userId, $cId, $loginCourseDate, $ip, $sessionId) = array_values($incomingData);
|
||||
|
||||
$sessionLifetime = api_get_configuration_value('session_lifetime');
|
||||
|
||||
/** @var \DateTime $time */
|
||||
$time = clone $loginCourseDate;
|
||||
$time->modify("-$sessionLifetime seconds");
|
||||
|
||||
$time = $time->format('Y-m-d H:i:s');
|
||||
$loginCourseDate = $loginCourseDate->format('Y-m-d H:i:s');
|
||||
|
||||
$tableCourseAccess = \Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
|
||||
|
||||
$result = \Database::query(
|
||||
"SELECT course_access_id
|
||||
FROM $tableCourseAccess
|
||||
WHERE user_id = $userId AND c_id = $cId AND session_id = $sessionId AND login_course_date > '$time'
|
||||
ORDER BY login_course_date DESC
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
if (\Database::num_rows($result) > 0) {
|
||||
$row = \Database::fetch_assoc($result);
|
||||
|
||||
\Database::query(
|
||||
"UPDATE $tableCourseAccess
|
||||
SET logout_course_date = '$loginCourseDate', counter = counter + 1
|
||||
WHERE course_access_id = {$row['course_access_id']}"
|
||||
);
|
||||
|
||||
return $row['course_access_id'];
|
||||
}
|
||||
|
||||
return \Database::insert(
|
||||
$tableCourseAccess,
|
||||
[
|
||||
'c_id' => $cId,
|
||||
'user_ip' => $ip,
|
||||
'user_id' => $userId,
|
||||
'login_course_date' => $loginCourseDate,
|
||||
'logout_course_date' => $loginCourseDate,
|
||||
'counter' => 1,
|
||||
'session_id' => $sessionId,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
57
plugin/migrationmoodle/src/Loader/TrackLoginLoader.php
Normal file
57
plugin/migrationmoodle/src/Loader/TrackLoginLoader.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class TrackLoginLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class TrackLoginLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$incomingData['login_date'] = $incomingData['login_date']->format('Y-m-d H:i:s');
|
||||
|
||||
if ($incomingData['logout_date']) {
|
||||
$incomingData['logout_date'] = $incomingData['logout_date']->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$tblTrackELogin = \Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
|
||||
|
||||
$firstId = \Database::insert(
|
||||
$tblTrackELogin,
|
||||
[
|
||||
'login_user_id' => $incomingData['login_user_id'],
|
||||
'login_date' => $incomingData['login_date'],
|
||||
'user_ip' => '',
|
||||
]
|
||||
);
|
||||
|
||||
\Database::update(
|
||||
$tblTrackELogin,
|
||||
['logout_date' => $incomingData['logout_date']],
|
||||
['login_id = ?' => [$firstId]]
|
||||
);
|
||||
|
||||
$incomingData['user_ip'] = '';
|
||||
|
||||
\Database::insert(
|
||||
$tblTrackELogin,
|
||||
[
|
||||
'login_user_id' => $incomingData['login_user_id'],
|
||||
'login_date' => $incomingData['logout_date'],
|
||||
'logout_date' => $incomingData['logout_date'],
|
||||
'user_ip' => '',
|
||||
]
|
||||
);
|
||||
|
||||
return $incomingData['login_user_id'];
|
||||
}
|
||||
}
|
||||
45
plugin/migrationmoodle/src/Loader/UrlLoader.php
Normal file
45
plugin/migrationmoodle/src/Loader/UrlLoader.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UrlLoader.
|
||||
*
|
||||
* The Link created is added in a learning path (from a Moodle course section).
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UrlLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$params = [
|
||||
'c_id' => $incomingData['c_id'],
|
||||
'url' => $incomingData['url'],
|
||||
'title' => $incomingData['title'],
|
||||
'description' => null,
|
||||
'category_id' => null,
|
||||
'on_homepage' => '0',
|
||||
'target' => '_self',
|
||||
'session_id' => 0,
|
||||
];
|
||||
|
||||
$link = new \Link();
|
||||
$link->setCourse(
|
||||
api_get_course_info_by_id($incomingData['c_id'])
|
||||
);
|
||||
$linkId = $link->save($params);
|
||||
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
|
||||
\Database::query("UPDATE $tblLpItem SET path = '$linkId' WHERE iid = {$incomingData['item_id']}");
|
||||
|
||||
return $linkId;
|
||||
}
|
||||
}
|
||||
28
plugin/migrationmoodle/src/Loader/UserLastLoginLoader.php
Normal file
28
plugin/migrationmoodle/src/Loader/UserLastLoginLoader.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserLastLoginLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserLastLoginLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
\Database::update(
|
||||
\Database::get_main_table(TABLE_MAIN_USER),
|
||||
['last_login' => $incomingData['last_login']->format('Y-m-d H:i:s')],
|
||||
['id = ?' => [$incomingData['user_id']]]
|
||||
);
|
||||
|
||||
return $incomingData['user_id'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
/**
|
||||
* Class UserLearnPathLessonAttemptLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserLearnPathLessonAttemptLoader extends UserLearnPathLessonBranchLoader
|
||||
{
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblLpItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
|
||||
$itemViewId = parent::load($incomingData);
|
||||
|
||||
if ((bool) $incomingData['is_correct']) {
|
||||
\Database::query("UPDATE $tblLpItemView SET score = max_score WHERE iid = $itemViewId");
|
||||
} else {
|
||||
\Database::query("UPDATE $tblLpItemView SET score = 0 WHERE iid = $itemViewId");
|
||||
}
|
||||
|
||||
return $itemViewId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserLearnPathLessonBranchLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserLearnPathLessonBranchLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
$tblLpItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
|
||||
$item = \Database::fetch_assoc(
|
||||
\Database::query("SELECT display_order FROM $tblLpItem WHERE iid = {$incomingData['item_id']}")
|
||||
);
|
||||
|
||||
if (!$item) {
|
||||
throw new \Exception("LP item ({$incomingData['item_id']}) not found.");
|
||||
}
|
||||
|
||||
$itemView = $this->findViewOfItem($incomingData);
|
||||
|
||||
$itemViewParams = ['status' => 'completed'];
|
||||
|
||||
if ($item['display_order'] != 1) {
|
||||
$previousItemView = $this->findViewOfPreviousItem($incomingData);
|
||||
|
||||
$itemViewParams['start_time'] = $previousItemView['start_time'] + $previousItemView['total_time'];
|
||||
$itemView['start_time'] = $itemViewParams['start_time'];
|
||||
}
|
||||
|
||||
$itemViewParams['total_time'] = $incomingData['end_time'] - $itemView['start_time'];
|
||||
|
||||
\Database::update(
|
||||
$tblLpItemView,
|
||||
$itemViewParams,
|
||||
['iid = ?' => [$itemView['iid']]]
|
||||
);
|
||||
|
||||
return $itemView['iid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findViewOfItem(array $incomingData)
|
||||
{
|
||||
$itemView = \Database::fetch_assoc(
|
||||
\Database::query(
|
||||
"SELECT lpiv.iid, lpiv.start_time
|
||||
FROM c_lp_item_view lpiv
|
||||
INNER JOIN c_lp_view lpv ON (lpv.iid = lpiv.lp_view_id AND lpv.c_id = lpiv.c_id)
|
||||
WHERE lpiv.lp_item_id = {$incomingData['item_id']} AND lpv.user_id = {$incomingData['user_id']}
|
||||
LIMIT 1"
|
||||
)
|
||||
);
|
||||
|
||||
if (!$itemView) {
|
||||
throw new \Exception("Item view not found for "."item ({$incomingData['item_id']}) and user ({$incomingData['user_id']}).");
|
||||
}
|
||||
|
||||
return $itemView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findViewOfPreviousItem(array $incomingData)
|
||||
{
|
||||
$result = \Database::query(
|
||||
"SELECT lpiv.start_time, lpiv.total_time
|
||||
FROM c_lp_item_view lpiv
|
||||
INNER JOIN c_lp_view lpv ON (lpv.iid = lpiv.lp_view_id AND lpv.c_id = lpiv.c_id)
|
||||
INNER JOIN c_lp_item lpi ON (lpi.iid = lpiv.lp_item_id AND lpi.c_id = lpiv.c_id)
|
||||
WHERE lpi.next_item_id = {$incomingData['item_id']} AND lpv.user_id = {$incomingData['user_id']}
|
||||
LIMIT 1"
|
||||
);
|
||||
$previousItemView = \Database::fetch_assoc($result);
|
||||
|
||||
if (!$previousItemView) {
|
||||
throw new \Exception("Item view not found for "."previous item ({$incomingData['item_id']}) and user ({$incomingData['user_id']}).");
|
||||
}
|
||||
|
||||
return $previousItemView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserLearnPathLessonTimerLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserLearnPathLessonTimerLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
|
||||
$parentItemView = $this->findViewOfParentItem($incomingData);
|
||||
$itemView = $this->findViewOfFirstItem($incomingData);
|
||||
|
||||
\Database::query(
|
||||
"UPDATE $tblItemView SET start_time = {$incomingData['start_time']} WHERE iid = {$parentItemView['iid']}"
|
||||
);
|
||||
\Database::query(
|
||||
"UPDATE $tblItemView SET start_time = {$incomingData['start_time']} WHERE iid = {$itemView['iid']}"
|
||||
);
|
||||
|
||||
return $itemView['iid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findViewOfParentItem(array $incomingData)
|
||||
{
|
||||
$parentItemView = \Database::fetch_assoc(
|
||||
\Database::query(
|
||||
"SELECT lpiv.iid
|
||||
FROM c_lp_item_view lpiv
|
||||
INNER JOIN c_lp_view lpv ON (lpv.iid = lpiv.lp_view_id AND lpv.c_id = lpiv.c_id)
|
||||
WHERE lpiv.lp_item_id = {$incomingData['parent_item_id']}
|
||||
AND lpv.user_id = {$incomingData['user_id']}
|
||||
LIMIT 1"
|
||||
)
|
||||
);
|
||||
|
||||
if (!$parentItemView) {
|
||||
throw new \Exception("Item dir ({$incomingData['parent_item_id']}) not found.");
|
||||
}
|
||||
|
||||
return $parentItemView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findViewOfFirstItem(array $incomingData)
|
||||
{
|
||||
$itemView = \Database::fetch_assoc(
|
||||
\Database::query(
|
||||
"SELECT lpiv.iid
|
||||
FROM c_lp_item_view lpiv
|
||||
INNER JOIN c_lp_view lpv
|
||||
ON (lpv.iid = lpiv.lp_view_id AND lpv.c_id = lpiv.c_id)
|
||||
INNER JOIN c_lp_item lpi
|
||||
ON (lpi.lp_id = lpv.lp_id AND lpi.c_id = lpv.c_id AND lpi.iid = lpiv.lp_item_id)
|
||||
WHERE lpi.item_type = 'document'
|
||||
AND lpv.user_id = {$incomingData['user_id']}
|
||||
AND lpi.parent_item_id = {$incomingData['parent_item_id']}
|
||||
AND lpv.session_id = {$incomingData['session_id']}
|
||||
ORDER BY lpi.display_order ASC
|
||||
LIMIT 1"
|
||||
)
|
||||
);
|
||||
|
||||
if (!$itemView) {
|
||||
throw new \Exception("Item view not found for item with"." parent item ({$incomingData['parent_item_id']}) and user ({$incomingData['user_id']})");
|
||||
}
|
||||
|
||||
return $itemView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserLearnPathQuizLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserLearnPathQuizLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$itemView = $this->findViewOfItem(
|
||||
$incomingData['item_id'],
|
||||
$incomingData['user_id'],
|
||||
$incomingData['session_id']
|
||||
);
|
||||
|
||||
\Database::update(
|
||||
\Database::get_course_table(TABLE_LP_ITEM_VIEW),
|
||||
[
|
||||
'start_time' => $incomingData['start_time'],
|
||||
'total_time' => $incomingData['total_time'],
|
||||
'score' => $incomingData['score'],
|
||||
'status' => $incomingData['status'],
|
||||
],
|
||||
['iid = ?' => $itemView['iid']]
|
||||
);
|
||||
|
||||
return $itemView['iid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $itemId
|
||||
* @param int $userId
|
||||
* @param int $sessionId
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findViewOfItem($itemId, $userId, $sessionId)
|
||||
{
|
||||
$result = \Database::query(
|
||||
"SELECT lpiv.iid
|
||||
FROM c_lp_item_view lpiv
|
||||
INNER JOIN c_lp_view lpv ON (lpv.iid = lpiv.lp_view_id AND lpv.c_id = lpiv.c_id)
|
||||
WHERE lpiv.lp_item_id = $itemId AND lpv.user_id = $userId AND lpv.session_id = $sessionId
|
||||
LIMIT 1"
|
||||
);
|
||||
$itemView = \Database::fetch_assoc($result);
|
||||
|
||||
if (!$itemView) {
|
||||
throw new \Exception("Item view not found for item ($itemId) and user ($userId) in session ($sessionId).");
|
||||
}
|
||||
|
||||
return $itemView;
|
||||
}
|
||||
}
|
||||
73
plugin/migrationmoodle/src/Loader/UserLearnPathsLoader.php
Normal file
73
plugin/migrationmoodle/src/Loader/UserLearnPathsLoader.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserLearnPathsLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserLearnPathsLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
$tblLpItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
$tblLpItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
$tblSrCrU = \Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
|
||||
|
||||
$resSubscriptions = \Database::query(
|
||||
"SELECT c_id, session_id FROM $tblSrCrU WHERE user_id = {$incomingData['user_id']}"
|
||||
);
|
||||
|
||||
while ($subscription = \Database::fetch_assoc($resSubscriptions)) {
|
||||
$resLps = \Database::query("SELECT iid FROM $tblLp WHERE c_id = {$subscription['c_id']} AND lp_type = 1");
|
||||
|
||||
while ($lp = \Database::fetch_assoc($resLps)) {
|
||||
$lpViewId = \Database::insert(
|
||||
$tblLpView,
|
||||
[
|
||||
'c_id' => $subscription['c_id'],
|
||||
'lp_id' => $lp['iid'],
|
||||
'user_id' => $incomingData['user_id'],
|
||||
'view_count' => 1,
|
||||
'session_id' => $subscription['session_id'],
|
||||
'last_item' => 0,
|
||||
]
|
||||
);
|
||||
\Database::query("UPDATE $tblLpView SET id = iid WHERE iid = $lpViewId");
|
||||
|
||||
$resItems = \Database::query(
|
||||
"SELECT iid, max_score FROM $tblLpItem
|
||||
WHERE lp_id = {$lp['iid']} ORDER BY parent_item_id ASC, display_order ASC"
|
||||
);
|
||||
while ($lpItem = \Database::fetch_assoc($resItems)) {
|
||||
$lpItemViewId = \Database::insert(
|
||||
$tblLpItemView,
|
||||
[
|
||||
'c_id' => $subscription['c_id'],
|
||||
'lp_item_id' => $lpItem['iid'],
|
||||
'lp_view_id' => $lpViewId,
|
||||
'view_count' => 1,
|
||||
'status' => 'not attempted',
|
||||
'start_time' => 0,
|
||||
'total_time' => 0,
|
||||
'score' => 0,
|
||||
'max_score' => $lpItem['max_score'],
|
||||
]
|
||||
);
|
||||
\Database::query("UPDATE $tblLpItemView SET id = iid WHERE iid = $lpItemViewId");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $incomingData['user_id'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserQuestionAttemptLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserQuestionAttemptLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$incomingData['marks'] = (float) $incomingData['marks'];
|
||||
$incomingData['teacher_comment'] = '';
|
||||
$incomingData['tms'] = $incomingData['tms']->format('Y-m-d H:i:s');
|
||||
$incomingData['position'] = 0;
|
||||
|
||||
return \Database::insert(
|
||||
\Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
|
||||
$incomingData
|
||||
);
|
||||
}
|
||||
}
|
||||
80
plugin/migrationmoodle/src/Loader/UserQuizAttemptLoader.php
Normal file
80
plugin/migrationmoodle/src/Loader/UserQuizAttemptLoader.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserQuizAttemptLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserQuizAttemptLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$view = $this->findViewByQuiz(
|
||||
$incomingData['exo_id'],
|
||||
$incomingData['user_id'],
|
||||
$incomingData['session_id']
|
||||
);
|
||||
|
||||
/** @var \DateTime $exeDate */
|
||||
$exeDate = clone $incomingData['date'];
|
||||
$exeDate->modify("+{$incomingData['duration']} seconds");
|
||||
|
||||
return \Database::insert(
|
||||
\Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES),
|
||||
[
|
||||
'exe_exo_id' => $incomingData['exo_id'],
|
||||
'exe_user_id' => $incomingData['user_id'],
|
||||
'c_id' => $view['c_id'],
|
||||
'status' => $incomingData['status'] === 'finished' ? '' : 'incomplete',
|
||||
'session_id' => $incomingData['session_id'],
|
||||
'data_tracking' => $incomingData['data_tracking'],
|
||||
'start_date' => $incomingData['date']->format('Y-m-d H:i:s'),
|
||||
'orig_lp_id' => $view['lp_id'],
|
||||
'orig_lp_item_id' => $view['lp_item_id'],
|
||||
'orig_lp_item_view_id' => $view['iid'],
|
||||
'exe_weighting' => $incomingData['weighting'],
|
||||
'user_ip' => '',
|
||||
'exe_date' => $exeDate->format('Y-m-d H:i:s'),
|
||||
'exe_result' => (float) $incomingData['result'],
|
||||
'steps_counter' => 0,
|
||||
'exe_duration' => $incomingData['duration'],
|
||||
'questions_to_check' => '',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $quizId
|
||||
* @param int $userId
|
||||
* @param int $sessionId
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findViewByQuiz($quizId, $userId, $sessionId)
|
||||
{
|
||||
$query = \Database::query("SELECT lpiv.lp_item_id, lpv.c_id, lpiv.iid, lpv.lp_id
|
||||
FROM c_lp_item_view lpiv
|
||||
INNER JOIN c_lp_item lpi ON (lpiv.lp_item_id = lpi.iid AND lpiv.c_id = lpi.c_id)
|
||||
INNER JOIN c_lp_view lpv ON (lpv.iid = lpiv.lp_view_id AND lpv.c_id = lpiv.c_id)
|
||||
WHERE lpi.path = $quizId AND lpv.user_id = $userId AND lpv.session_id = $sessionId
|
||||
LIMIT 1"
|
||||
);
|
||||
$result = \Database::fetch_assoc($query);
|
||||
|
||||
if (!$result) {
|
||||
throw new \Exception("Item view not found for quiz ($quizId) and user ($userId) in session ($sessionId).");
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
79
plugin/migrationmoodle/src/Loader/UserSessionLoader.php
Normal file
79
plugin/migrationmoodle/src/Loader/UserSessionLoader.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UserSessionLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UserSessionLoader implements LoaderInterface
|
||||
{
|
||||
public const LOAD_MODE_REUSE = 'reuse';
|
||||
public const LOAD_MODE_DUPLICATE = 'duplicate';
|
||||
|
||||
/**
|
||||
* @var string Load mode: "reuse" or "duplicate". Default is "duplicate".
|
||||
*/
|
||||
private $loadMode = self::LOAD_MODE_DUPLICATE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
foreach ($incomingData['course_ids'] as $courseId) {
|
||||
if (empty($courseId)) {
|
||||
throw new \Exception("Course ($courseId) not found when creating course session for user ({$incomingData['user_id']}). ".'Session will not be created.');
|
||||
}
|
||||
}
|
||||
|
||||
$tblSession = \Database::get_main_table(TABLE_MAIN_SESSION);
|
||||
|
||||
$sessionInfo = \Database::fetch_assoc(
|
||||
\Database::query("SELECT id FROM $tblSession WHERE name = '{$incomingData['name']}'")
|
||||
);
|
||||
|
||||
if (!empty($sessionInfo)) {
|
||||
if ($this->loadMode == self::LOAD_MODE_REUSE) {
|
||||
return $sessionInfo['id'];
|
||||
}
|
||||
|
||||
if ($this->loadMode === self::LOAD_MODE_DUPLICATE) {
|
||||
$incomingData['name'] = '['.substr(md5(uniqid(rand())), 0, 5).'] '.$incomingData['name'];
|
||||
}
|
||||
}
|
||||
|
||||
$urlId = \MigrationMoodlePlugin::create()->getAccessUrlId();
|
||||
$datetime = api_get_utc_datetime();
|
||||
$coachId = 1;
|
||||
|
||||
$sessionId = \SessionManager::create_session(
|
||||
$incomingData['name'],
|
||||
$datetime,
|
||||
'',
|
||||
$datetime,
|
||||
'',
|
||||
$datetime,
|
||||
'',
|
||||
$coachId,
|
||||
0,
|
||||
1,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
[],
|
||||
0,
|
||||
false,
|
||||
$urlId
|
||||
);
|
||||
\SessionManager::add_courses_to_session($sessionId, $incomingData['course_ids']);
|
||||
\SessionManager::subscribeUsersToSession($sessionId, [$incomingData['user_id']]);
|
||||
|
||||
return $sessionId;
|
||||
}
|
||||
}
|
||||
97
plugin/migrationmoodle/src/Loader/UsersLoader.php
Normal file
97
plugin/migrationmoodle/src/Loader/UsersLoader.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
use Chamilo\UserBundle\Entity\User;
|
||||
|
||||
/**
|
||||
* Class UsersLoader.
|
||||
*
|
||||
* Loader to create a Chamilo user coming from a Moodle user.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UsersLoader implements LoaderInterface
|
||||
{
|
||||
public const LOAD_MODE_REUSE = 'reuse';
|
||||
public const LOAD_MODE_DUPLICATE = 'duplicate';
|
||||
|
||||
/**
|
||||
* @var string Load mode: "reuse" or "duplicate". Default is "duplicate".
|
||||
*/
|
||||
private $loadMode = self::LOAD_MODE_DUPLICATE;
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblUser = \Database::get_main_table(TABLE_MAIN_USER);
|
||||
|
||||
$userInfo = \Database::fetch_assoc(
|
||||
\Database::query("SELECT id FROM $tblUser WHERE username = '{$incomingData['username']}'")
|
||||
);
|
||||
|
||||
if (!empty($userInfo)) {
|
||||
if ($this->loadMode == self::LOAD_MODE_REUSE) {
|
||||
return $userInfo['id'];
|
||||
}
|
||||
|
||||
if ($this->loadMode === self::LOAD_MODE_DUPLICATE) {
|
||||
$incomingData['username'] .= substr(md5(uniqid(rand())), 0, 10);
|
||||
}
|
||||
}
|
||||
|
||||
$userId = \UserManager::create_user(
|
||||
$incomingData['firstname'],
|
||||
$incomingData['lastname'],
|
||||
$incomingData['status'],
|
||||
$incomingData['email'],
|
||||
$incomingData['username'],
|
||||
md5(time()),
|
||||
'',
|
||||
$incomingData['language'],
|
||||
$incomingData['phone'],
|
||||
null,
|
||||
$incomingData['auth_source'],
|
||||
null,
|
||||
$incomingData['active'],
|
||||
0,
|
||||
[],
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
$incomingData['address'],
|
||||
false,
|
||||
null,
|
||||
0,
|
||||
[]
|
||||
);
|
||||
|
||||
if (empty($userId)) {
|
||||
throw new \Exception('User was not created');
|
||||
}
|
||||
|
||||
if ($incomingData['registration_date']) {
|
||||
$incomingData['registration_date'] = $incomingData['registration_date']->format('Y-m-d H:i:s');
|
||||
|
||||
\Database::query(
|
||||
"UPDATE $tblUser SET registration_date = '{$incomingData['registration_date']}' WHERE id = $userId"
|
||||
);
|
||||
}
|
||||
|
||||
\UserManager::update_extra_field_value($userId, 'moodle_password', $incomingData['plain_password']);
|
||||
|
||||
$urlId = \MigrationMoodlePlugin::create()->getAccessUrlId();
|
||||
|
||||
if ($urlId) {
|
||||
\Database::query("UPDATE access_url_rel_user SET access_url_id = $urlId WHERE user_id = $userId");
|
||||
}
|
||||
|
||||
return $userId;
|
||||
}
|
||||
}
|
||||
163
plugin/migrationmoodle/src/Loader/UsersScormsViewLoader.php
Normal file
163
plugin/migrationmoodle/src/Loader/UsersScormsViewLoader.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Loader;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Class UsersScormsViewLoader.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Loader
|
||||
*/
|
||||
class UsersScormsViewLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $incomingData)
|
||||
{
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
$tblLpItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
|
||||
$sessionId = $this->getUserSubscriptionInSession($incomingData['user_id'], $incomingData['c_id']);
|
||||
|
||||
$lpViewId = $this->getLpView(
|
||||
$incomingData['user_id'],
|
||||
$incomingData['lp_id'],
|
||||
$incomingData['c_id'],
|
||||
$sessionId
|
||||
);
|
||||
|
||||
$lpItemViewId = $this->getLpItemView($lpViewId, $incomingData['lp_item_id']);
|
||||
|
||||
$itemView = [
|
||||
'c_id' => $incomingData['c_id'],
|
||||
'lp_item_id' => $incomingData['lp_item_id'],
|
||||
'lp_view_id' => $lpViewId,
|
||||
'view_count' => $incomingData['lp_item_view_count'],
|
||||
'status' => 'not attempted',
|
||||
'start_time' => 0,
|
||||
'total_time' => 0,
|
||||
'score' => 0,
|
||||
'max_score' => 100,
|
||||
];
|
||||
|
||||
foreach (array_keys($itemView) as $key) {
|
||||
if (isset($incomingData['item_data'][$key])) {
|
||||
$itemView[$key] = $incomingData['item_data'][$key];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($lpItemViewId)) {
|
||||
$lpItemViewId = \Database::insert($tblLpItemView, $itemView);
|
||||
\Database::query("UPDATE $tblLpItemView SET id = iid WHERE iid = $lpItemViewId");
|
||||
} else {
|
||||
\Database::update($tblLpItemView, $itemView, ['iid = ?' => [$lpItemViewId]]);
|
||||
}
|
||||
|
||||
\Database::query(
|
||||
"UPDATE $tblLpView
|
||||
SET last_item = {$incomingData['lp_item_id']},
|
||||
view_count = {$incomingData['lp_item_view_count']}
|
||||
WHERE iid = $lpViewId"
|
||||
);
|
||||
|
||||
return $lpViewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $courseId
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getUserSubscriptionInSession($userId, $courseId)
|
||||
{
|
||||
$srcru = \Database::select(
|
||||
'session_id',
|
||||
\Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
|
||||
[
|
||||
'where' => [
|
||||
'user_id = ? AND c_id = ?' => [$userId, $courseId],
|
||||
],
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
if (empty($srcru)) {
|
||||
throw new \Exception("Session not found for user ($userId) with course ($courseId)");
|
||||
}
|
||||
|
||||
return $srcru['session_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $lpId
|
||||
* @param int $cId
|
||||
* @param int $sessionId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getLpView($userId, $lpId, $cId, $sessionId)
|
||||
{
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
|
||||
$lpView = \Database::select(
|
||||
'iid',
|
||||
$tblLpView,
|
||||
[
|
||||
'where' => [
|
||||
'user_id = ? AND lp_id = ? AND c_id = ? AND session_id = ?' => [
|
||||
$userId,
|
||||
$lpId,
|
||||
$cId,
|
||||
$sessionId,
|
||||
],
|
||||
],
|
||||
'order' => 'view_count DESC',
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
if (empty($lpView)) {
|
||||
$lpView = [
|
||||
'c_id' => $cId,
|
||||
'lp_id' => $lpId,
|
||||
'user_id' => $userId,
|
||||
'view_count' => 1,
|
||||
'session_id' => $sessionId,
|
||||
'last_item' => 0,
|
||||
];
|
||||
|
||||
$lpViewId = \Database::insert($tblLpView, $lpView);
|
||||
\Database::query("UPDATE $tblLpView SET id = iid WHERE iid = $lpViewId");
|
||||
|
||||
return $lpViewId;
|
||||
}
|
||||
|
||||
return $lpView['iid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $lpViewId
|
||||
* @param int $lpItemId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getLpItemView($lpViewId, $lpItemId)
|
||||
{
|
||||
$lpItemView = \Database::fetch_assoc(
|
||||
\Database::query("SELECT iid FROM c_lp_item_view WHERE lp_view_id = $lpViewId AND lp_item_id = $lpItemId")
|
||||
);
|
||||
|
||||
if (empty($lpItemView)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $lpItemView['iid'];
|
||||
}
|
||||
}
|
||||
24
plugin/migrationmoodle/src/Messages/ExtractMessage.php
Normal file
24
plugin/migrationmoodle/src/Messages/ExtractMessage.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Messages;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class ExtractException.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Messages
|
||||
*/
|
||||
class ExtractMessage extends Message
|
||||
{
|
||||
/**
|
||||
* ExtractMessage constructor.
|
||||
*/
|
||||
public function __construct(Throwable $previous = null)
|
||||
{
|
||||
$message = 'Error while extracting data.';
|
||||
|
||||
parent::__construct($message, $previous);
|
||||
}
|
||||
}
|
||||
42
plugin/migrationmoodle/src/Messages/LoadMessage.php
Normal file
42
plugin/migrationmoodle/src/Messages/LoadMessage.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Messages;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class LoadMessage.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Messages
|
||||
*/
|
||||
class LoadMessage extends Message
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $incomingData;
|
||||
|
||||
/**
|
||||
* LoadMessage constructor.
|
||||
*
|
||||
* @param $incomingData
|
||||
*/
|
||||
public function __construct($incomingData, Throwable $previous = null)
|
||||
{
|
||||
$message = 'Error while loading transformed data.';
|
||||
$this->incomingData = $incomingData;
|
||||
|
||||
parent::__construct($message, $previous);
|
||||
}
|
||||
|
||||
public function displayAsString()
|
||||
{
|
||||
$pieces = [
|
||||
parent::displayAsString(),
|
||||
"\t".print_r($this->incomingData, true),
|
||||
];
|
||||
|
||||
echo implode(PHP_EOL, $pieces);
|
||||
}
|
||||
}
|
||||
63
plugin/migrationmoodle/src/Messages/Message.php
Normal file
63
plugin/migrationmoodle/src/Messages/Message.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Messages;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class Message.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Messages
|
||||
*/
|
||||
abstract class Message
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message;
|
||||
/**
|
||||
* @var Throwable
|
||||
*/
|
||||
protected $previous;
|
||||
|
||||
/**
|
||||
* Message constructor.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct($message = "", Throwable $previous = null)
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
|
||||
$this->displayAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Throwable
|
||||
*/
|
||||
public function getPrevious()
|
||||
{
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
public function displayAsString()
|
||||
{
|
||||
$pieces = [$this->message];
|
||||
|
||||
if ($this->previous) {
|
||||
$pieces[] = "\t".$this->previous->getMessage();
|
||||
}
|
||||
|
||||
echo implode(PHP_EOL, $pieces);
|
||||
}
|
||||
}
|
||||
40
plugin/migrationmoodle/src/Messages/TransformMessage.php
Normal file
40
plugin/migrationmoodle/src/Messages/TransformMessage.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Messages;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class TransformMessage.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Messages
|
||||
*/
|
||||
class TransformMessage extends Message
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $extractedData;
|
||||
|
||||
/**
|
||||
* TransformMessage constructor.
|
||||
*/
|
||||
public function __construct(array $extractedData, Throwable $previous = null)
|
||||
{
|
||||
$message = 'Error while transforming extracted data.';
|
||||
$this->extractedData = $extractedData;
|
||||
|
||||
parent::__construct($message, $previous);
|
||||
}
|
||||
|
||||
public function displayAsString()
|
||||
{
|
||||
$pieces = [
|
||||
parent::displayAsString(),
|
||||
"\t".print_r($this->extractedData, true),
|
||||
];
|
||||
|
||||
echo implode(PHP_EOL, $pieces);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\ExtraField;
|
||||
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
|
||||
|
||||
/**
|
||||
* Class MigrationMoodleCheckLoginCredentialsHook.
|
||||
*/
|
||||
class MigrationMoodleCheckLoginCredentialsHook extends HookObserver implements CheckLoginCredentialsHookObserverInterface
|
||||
{
|
||||
/**
|
||||
* MigrationMoodleCheckLoginCredentialsHook constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'plugin/migrationmoodle/src/MigrationMoodlePlugin.php',
|
||||
'migrationmoodle'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function checkLoginCredentials(CheckLoginCredentialsHookEventInterface $event)
|
||||
{
|
||||
$data = $event->getEventData();
|
||||
/** @var array $userData */
|
||||
$userData = $data['user'];
|
||||
/** @var array $credentials */
|
||||
$credentials = $data['credentials'];
|
||||
|
||||
$extraField = $this->getExtraField();
|
||||
|
||||
if (empty($extraField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fieldValue = $this->getExtraFieldValue($extraField, $userData);
|
||||
|
||||
if (empty($fieldValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$isPasswordVerified = password_verify(
|
||||
$credentials['password'],
|
||||
$fieldValue->getValue()
|
||||
);
|
||||
|
||||
if (!$isPasswordVerified) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ExtraField|null
|
||||
*/
|
||||
private function getExtraField()
|
||||
{
|
||||
return Database::getManager()
|
||||
->getRepository('ChamiloCoreBundle:ExtraField')
|
||||
->findOneBy(
|
||||
[
|
||||
'variable' => 'moodle_password',
|
||||
'extraFieldType' => ExtraField::USER_FIELD_TYPE,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ExtraFieldValues|null
|
||||
*/
|
||||
private function getExtraFieldValue(ExtraField $extraField, array $userData)
|
||||
{
|
||||
return Database::getManager()
|
||||
->getRepository('ChamiloCoreBundle:ExtraFieldValues')
|
||||
->findOneBy(['field' => $extraField, 'itemId' => $userData['user_id']]);
|
||||
}
|
||||
}
|
||||
169
plugin/migrationmoodle/src/MigrationMoodlePlugin.php
Normal file
169
plugin/migrationmoodle/src/MigrationMoodlePlugin.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
|
||||
/**
|
||||
* Class MigrationMoodlePlugin.
|
||||
*/
|
||||
class MigrationMoodlePlugin extends Plugin implements HookPluginInterface
|
||||
{
|
||||
public const SETTING_USER_FILTER = 'user_filter';
|
||||
public const SETTING_URL_ID = 'url_id';
|
||||
public const SETTING_MOODLE_PATH = 'moodle_path';
|
||||
|
||||
public $isAdminPlugin = true;
|
||||
|
||||
/**
|
||||
* MigrationMoodlePlugin constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
$version = '0.0.1';
|
||||
$author = 'Angel Fernando Quiroz Campos';
|
||||
$settings = [
|
||||
'active' => 'boolean',
|
||||
'db_host' => 'text',
|
||||
'db_user' => 'text',
|
||||
'db_password' => 'text',
|
||||
'db_name' => 'text',
|
||||
self::SETTING_USER_FILTER => 'text',
|
||||
self::SETTING_URL_ID => 'text',
|
||||
self::SETTING_MOODLE_PATH => 'text',
|
||||
];
|
||||
|
||||
parent::__construct($version, $author, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MigrationMoodlePlugin|null
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
static $result = null;
|
||||
|
||||
return $result ? $result : $result = new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
$params = [
|
||||
'host' => $this->get('db_host'),
|
||||
'user' => $this->get('db_user'),
|
||||
'password' => $this->get('db_password'),
|
||||
'dbname' => $this->get('db_name'),
|
||||
'driver' => 'pdo_mysql',
|
||||
];
|
||||
|
||||
$connection = DriverManager::getConnection($params, new Configuration());
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actions after configure the plugin.
|
||||
*
|
||||
* Add user extra field.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return MigrationMoodlePlugin
|
||||
*/
|
||||
public function performActionsAfterConfigure()
|
||||
{
|
||||
if ('true' === $this->get('active')) {
|
||||
$this->installHook();
|
||||
} else {
|
||||
$this->uninstallHook();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will call the Hook management insertHook to add Hook observer from this plugin.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function installHook()
|
||||
{
|
||||
$hookObserver = MigrationMoodleCheckLoginCredentialsHook::create();
|
||||
|
||||
CheckLoginCredentialsHook::create()->attach($hookObserver);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will call the Hook management deleteHook to disable Hook observer from this plugin.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function uninstallHook()
|
||||
{
|
||||
$hookObserver = MigrationMoodleCheckLoginCredentialsHook::create();
|
||||
|
||||
CheckLoginCredentialsHook::create()->detach($hookObserver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUserFilterSetting()
|
||||
{
|
||||
$userFilter = $this->get(self::SETTING_USER_FILTER);
|
||||
|
||||
return trim($userFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getAccessUrlId()
|
||||
{
|
||||
$urlId = (int) $this->get(self::SETTING_URL_ID);
|
||||
|
||||
return $urlId ?: 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMoodledataPath()
|
||||
{
|
||||
$path = $this->get(self::SETTING_MOODLE_PATH);
|
||||
|
||||
return rtrim($path, ' /');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTaskDone($name)
|
||||
{
|
||||
$result = Database::select(
|
||||
'COUNT(1) c',
|
||||
'plugin_migrationmoodle_task',
|
||||
[
|
||||
'where' => [
|
||||
'name = ?' => Database::escape_string($name.'_task'),
|
||||
'or name = ?' => Database::escape_string($name.'_script'),
|
||||
],
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
return $result['c'] > 0;
|
||||
}
|
||||
}
|
||||
94
plugin/migrationmoodle/src/Script/BaseScript.php
Normal file
94
plugin/migrationmoodle/src/Script/BaseScript.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Script;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Traits\MapTrait\MapTrait;
|
||||
|
||||
/**
|
||||
* Class BaseScript.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Script
|
||||
*/
|
||||
abstract class BaseScript
|
||||
{
|
||||
use MapTrait;
|
||||
|
||||
/**
|
||||
* BaseScript constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->calledClass = get_called_class();
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
\Database::insert(
|
||||
'plugin_migrationmoodle_task',
|
||||
['name' => $this->getTaskName()]
|
||||
);
|
||||
|
||||
$this->process();
|
||||
}
|
||||
|
||||
abstract public function process();
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLoadedUser($userId)
|
||||
{
|
||||
return $this->isLoadedId($userId, 'users_task');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $lpId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMigratedLearningPath($lpId)
|
||||
{
|
||||
return $this->isLoadedId($lpId, 'course_sections_task');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $scormId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMigratedScorm($scormId)
|
||||
{
|
||||
return $this->isLoadedId($scormId, 'course_modules_scorm_task');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*/
|
||||
protected function showMessage($message)
|
||||
{
|
||||
echo '['.date(\DateTime::ATOM)."]\t$message".PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $taskName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isLoadedId($id, $taskName)
|
||||
{
|
||||
$row = \Database::fetch_assoc(
|
||||
\Database::query(
|
||||
"SELECT COUNT(pmi.id) AS nbr
|
||||
FROM plugin_migrationmoodle_item pmi
|
||||
INNER JOIN plugin_migrationmoodle_task pmt ON pmi.task_id = pmt.id
|
||||
WHERE pmt.name = '$taskName' AND pmi.loaded_id = $id"
|
||||
)
|
||||
);
|
||||
|
||||
return $row['nbr'] > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Script;
|
||||
|
||||
/**
|
||||
* Class UserLearnPathsProgressScript.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Script
|
||||
*/
|
||||
class UserLearnPathsProgressScript extends BaseScript
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
$itemsInLp = $this->countItemsInLp();
|
||||
|
||||
foreach ($this->getUsersAndLps() as $lpView) {
|
||||
$userId = $lpView['user_id'];
|
||||
$lpId = $lpView['lp_id'];
|
||||
$cId = $lpView['c_id'];
|
||||
$lpViewId = $lpView['iid'];
|
||||
|
||||
$completedItems = $this->countCompletedItems($userId, $lpId, $cId);
|
||||
|
||||
if (empty($completedItems) || empty($itemsInLp[$lpId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$progress = (int) ($completedItems / $itemsInLp[$lpId] * 100);
|
||||
|
||||
\Database::query(
|
||||
"UPDATE c_lp_view
|
||||
SET progress = $progress
|
||||
WHERE user_id = $userId
|
||||
AND lp_id = $lpId
|
||||
AND c_id = $cId
|
||||
AND iid = $lpViewId"
|
||||
);
|
||||
|
||||
$this->showMessage("Updated: c_lp_view $lpViewId with progress $progress.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function countItemsInLp()
|
||||
{
|
||||
$tblItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$result = \Database::query(
|
||||
"SELECT lpi.lp_id, COUNT(lpi.iid) AS c_lpi
|
||||
FROM $tblItem lpi
|
||||
INNER JOIN $tblLp lp ON lpi.lp_id = lp.iid
|
||||
WHERE lpi.item_type != 'dir' AND lp.lp_type = 1
|
||||
GROUP BY lpi.lp_id"
|
||||
);
|
||||
|
||||
$data = [];
|
||||
|
||||
while ($row = \Database::fetch_assoc($result)) {
|
||||
$data[$row['lp_id']] = $row['c_lpi'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Generator
|
||||
*/
|
||||
private function getUsersAndLps()
|
||||
{
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$result = \Database::query(
|
||||
"SELECT lpv.iid, lpv.lp_id, lpv.user_id, lpv.c_id
|
||||
FROM $tblLpView lpv
|
||||
INNER JOIN $tblLp lp ON lpv.lp_id = lp.iid
|
||||
INNER JOIN plugin_migrationmoodle_item pmi ON pmi.loaded_id = lpv.user_id
|
||||
INNER JOIN plugin_migrationmoodle_task pmt ON pmi.task_id = pmt.id
|
||||
WHERE lp.lp_type = 1 AND pmt.name = 'users_task'"
|
||||
);
|
||||
|
||||
while ($row = \Database::fetch_assoc($result)) {
|
||||
if (!$this->isLoadedUser($row['user_id']) ||
|
||||
!$this->isMigratedLearningPath($row['lp_id'])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $lpId
|
||||
* @param int $cId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function countCompletedItems($userId, $lpId, $cId)
|
||||
{
|
||||
$tblItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$result = \Database::query("SELECT
|
||||
lpiv.lp_view_id,
|
||||
lpiv.c_id,
|
||||
COUNT(lpiv.lp_item_id) c_lpiv
|
||||
FROM $tblItemView lpiv
|
||||
INNER JOIN $tblLpView lpv ON (lpiv.lp_view_id = lpv.iid AND lpiv.c_id = lpv.c_id)
|
||||
INNER JOIN $tblLp lp ON (lpv.lp_id = lp.iid AND lpv.c_id = lp.c_id)
|
||||
WHERE lpiv.status = 'completed'
|
||||
AND lpv.user_id = $userId
|
||||
AND lp.iid = $lpId
|
||||
AND lp.c_id = $cId
|
||||
AND lp.lp_type = 1
|
||||
GROUP BY lpiv.lp_view_id");
|
||||
|
||||
$row = \Database::fetch_assoc($result);
|
||||
|
||||
if (empty($row) || empty($row['c_lpiv'])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $row['c_lpiv'];
|
||||
}
|
||||
}
|
||||
138
plugin/migrationmoodle/src/Script/UserScormsProgressScript.php
Normal file
138
plugin/migrationmoodle/src/Script/UserScormsProgressScript.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Script;
|
||||
|
||||
/**
|
||||
* Class UserScormsProgressScript.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Script
|
||||
*/
|
||||
class UserScormsProgressScript extends BaseScript
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
$itemsInLp = $this->countItemsInLp();
|
||||
|
||||
foreach ($this->getUsersAndLps() as $lpView) {
|
||||
$userId = $lpView['user_id'];
|
||||
$lpId = $lpView['lp_id'];
|
||||
$cId = $lpView['c_id'];
|
||||
$lpViewId = $lpView['iid'];
|
||||
|
||||
$completedItems = $this->countCompletedItems($userId, $lpId, $cId);
|
||||
|
||||
if (empty($completedItems) || empty($itemsInLp[$lpId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($completedItems > $itemsInLp[$lpId]) {
|
||||
$progress = 100;
|
||||
} else {
|
||||
$progress = (int) ($completedItems / $itemsInLp[$lpId] * 100);
|
||||
}
|
||||
|
||||
\Database::query(
|
||||
"UPDATE c_lp_view
|
||||
SET progress = $progress
|
||||
WHERE user_id = $userId
|
||||
AND lp_id = $lpId
|
||||
AND c_id = $cId
|
||||
AND iid = $lpViewId"
|
||||
);
|
||||
|
||||
$this->showMessage("Updated: c_lp_view $lpViewId with progress $progress.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function countItemsInLp()
|
||||
{
|
||||
$tblItem = \Database::get_course_table(TABLE_LP_ITEM);
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$result = \Database::query(
|
||||
"SELECT lpi.lp_id, COUNT(lpi.iid) AS c_lpi
|
||||
FROM $tblItem lpi
|
||||
INNER JOIN $tblLp lp ON lpi.lp_id = lp.iid
|
||||
WHERE lpi.item_type = 'sco' AND lp.lp_type = 2
|
||||
GROUP BY lpi.lp_id"
|
||||
);
|
||||
|
||||
$data = [];
|
||||
|
||||
while ($row = \Database::fetch_assoc($result)) {
|
||||
$data[$row['lp_id']] = $row['c_lpi'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Generator
|
||||
*/
|
||||
private function getUsersAndLps()
|
||||
{
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$result = \Database::query(
|
||||
"SELECT lpv.iid, lpv.lp_id, lpv.user_id, lpv.c_id
|
||||
FROM $tblLpView lpv
|
||||
INNER JOIN $tblLp lp ON lpv.lp_id = lp.iid
|
||||
WHERE lp.lp_type = 2"
|
||||
);
|
||||
|
||||
while ($row = \Database::fetch_assoc($result)) {
|
||||
if (!$this->isLoadedUser($row['user_id']) ||
|
||||
!$this->isMigratedScorm($row['lp_id'])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $lpId
|
||||
* @param int $cId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function countCompletedItems($userId, $lpId, $cId)
|
||||
{
|
||||
$tblItemView = \Database::get_course_table(TABLE_LP_ITEM_VIEW);
|
||||
$tblLpView = \Database::get_course_table(TABLE_LP_VIEW);
|
||||
$tblLp = \Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$result = \Database::query("SELECT
|
||||
lpiv.lp_view_id,
|
||||
lpiv.c_id,
|
||||
COUNT(lpiv.lp_item_id) c_lpiv
|
||||
FROM $tblItemView lpiv
|
||||
INNER JOIN $tblLpView lpv ON (lpiv.lp_view_id = lpv.iid AND lpiv.c_id = lpv.c_id)
|
||||
INNER JOIN $tblLp lp ON (lpv.lp_id = lp.iid AND lpv.c_id = lp.c_id)
|
||||
WHERE lpiv.status = 'completed'
|
||||
AND lpv.user_id = $userId
|
||||
AND lp.iid = $lpId
|
||||
AND lp.c_id = $cId
|
||||
AND lp.lp_type = 2
|
||||
GROUP BY lpiv.lp_view_id, lpiv.lp_item_id");
|
||||
|
||||
if (\Database::num_rows($result) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
while ($row = \Database::fetch_assoc($result)) {
|
||||
$count += (int) $row['c_lpiv'];
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
199
plugin/migrationmoodle/src/Task/BaseTask.php
Normal file
199
plugin/migrationmoodle/src/Task/BaseTask.php
Normal file
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\ExtractorInterface;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\LoaderInterface;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Interfaces\TransformerInterface;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Messages\ExtractMessage;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Messages\LoadMessage;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Messages\TransformMessage;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Traits\MapTrait\MapTrait;
|
||||
|
||||
/**
|
||||
* Class BaseTask.
|
||||
*/
|
||||
abstract class BaseTask
|
||||
{
|
||||
use MapTrait;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $taskId;
|
||||
/**
|
||||
* @var ExtractorInterface
|
||||
*/
|
||||
protected $extractor;
|
||||
/**
|
||||
* @var TransformerInterface
|
||||
*/
|
||||
protected $transformer;
|
||||
/**
|
||||
* @var LoaderInterface
|
||||
*/
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* @var \MigrationMoodlePlugin
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* BaseTask constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->plugin = \MigrationMoodlePlugin::create();
|
||||
|
||||
$this->extractor = $this->getExtractor();
|
||||
|
||||
$this->transformer = $this->getTransformer();
|
||||
|
||||
$this->loader = $this->getLoader();
|
||||
|
||||
$this->calledClass = get_called_class();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getExtractConfiguration();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getTransformConfiguration();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getLoadConfiguration();
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$outputBuffering = isset($GLOBALS['outputBuffering']) ? $GLOBALS['outputBuffering'] : true;
|
||||
|
||||
$taskId = \Database::insert(
|
||||
'plugin_migrationmoodle_task',
|
||||
['name' => $this->getTaskName()]
|
||||
);
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ($this->executeETL() as $hash => $ids) {
|
||||
\Database::insert(
|
||||
'plugin_migrationmoodle_item',
|
||||
[
|
||||
'hash' => $hash,
|
||||
'extracted_id' => (int) $ids['extracted'],
|
||||
'loaded_id' => (int) $ids['loaded'],
|
||||
'task_id' => $taskId,
|
||||
]
|
||||
);
|
||||
|
||||
echo "[".date(\DateTime::ATOM)."]\tData migrated: $hash".PHP_EOL;
|
||||
|
||||
$i++;
|
||||
|
||||
if ($i % 10 === 0 && $outputBuffering) {
|
||||
flush();
|
||||
ob_flush();
|
||||
}
|
||||
}
|
||||
|
||||
if ($outputBuffering) {
|
||||
ob_end_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Generator
|
||||
*/
|
||||
private function executeETL()
|
||||
{
|
||||
foreach ($this->extractFiltered() as $extractedData) {
|
||||
try {
|
||||
$incomingData = $this->transformer->transform($extractedData);
|
||||
} catch (\Exception $exception) {
|
||||
new TransformMessage($extractedData, $exception);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$loadedId = $this->loader->load($incomingData);
|
||||
} catch (\Exception $exception) {
|
||||
new LoadMessage($incomingData, $exception);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
yield md5("{$extractedData['id']}@@$loadedId") => [
|
||||
'extracted' => $extractedData['id'],
|
||||
'loaded' => $loadedId,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Generator
|
||||
*/
|
||||
private function extractFiltered()
|
||||
{
|
||||
try {
|
||||
foreach ($this->extractor->extract() as $extractedData) {
|
||||
if ($this->extractor->filter($extractedData)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $extractedData;
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
new ExtractMessage($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ExtractorInterface
|
||||
*/
|
||||
private function getExtractor()
|
||||
{
|
||||
$configuration = $this->getExtractConfiguration();
|
||||
|
||||
$extractorClass = $configuration['class'];
|
||||
/** @var ExtractorInterface $extractor */
|
||||
$extractor = new $extractorClass($configuration);
|
||||
|
||||
return $extractor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransformerInterface
|
||||
*/
|
||||
private function getTransformer()
|
||||
{
|
||||
$configuration = $this->getTransformConfiguration();
|
||||
|
||||
$transformerClass = $configuration['class'];
|
||||
/** @var TransformerInterface $extractor */
|
||||
$extractor = new $transformerClass($configuration);
|
||||
|
||||
return $extractor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoaderInterface
|
||||
*/
|
||||
private function getLoader()
|
||||
{
|
||||
$configuration = $this->getLoadConfiguration();
|
||||
|
||||
$loaderClass = $configuration['class'];
|
||||
/** @var LoaderInterface $extractor */
|
||||
$extractor = new $loaderClass($configuration);
|
||||
|
||||
return $extractor;
|
||||
}
|
||||
}
|
||||
77
plugin/migrationmoodle/src/Task/CQuizTask.php
Normal file
77
plugin/migrationmoodle/src/Task/CQuizTask.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\BaseExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CQuizLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\Percentage;
|
||||
|
||||
/**
|
||||
* Class CQuizTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CQuizTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseExtractor::class,
|
||||
'query' => 'SELECT * FROM mdl_quiz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'exerciseTitle' => 'name',
|
||||
'exerciseDescription' => 'intro',
|
||||
//'exerciseFeedbackType',
|
||||
//'results_disabled',
|
||||
//'exerciseType',
|
||||
//'question_selection_type',
|
||||
//'randomQuestions' => 'shufflequestions',
|
||||
'randomAnswers' => 'shuffleanswers',
|
||||
//'display_category_name',
|
||||
//'hide_question_title',
|
||||
'exerciseAttempts' => 'attempts',
|
||||
//'activate_start_date_check',
|
||||
'start_time' => 'timeopen',
|
||||
//'activate_end_date_check',
|
||||
'end_time' => 'timeclose',
|
||||
//'enabletimercontrol',
|
||||
'enabletimercontroltotalminutes' => 'timelimit',
|
||||
'pass_percentage' => [
|
||||
'class' => Percentage::class,
|
||||
'properties' => ['sumgrades', 'grade'],
|
||||
],
|
||||
//'text_when_finished',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CQuizLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
61
plugin/migrationmoodle/src/Task/CourseCategoriesTask.php
Normal file
61
plugin/migrationmoodle/src/Task/CourseCategoriesTask.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\BaseExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseCategoriesLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\CourseCategoryLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\CourseCode;
|
||||
|
||||
/**
|
||||
* Class CourseCategoriesTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseCategoriesTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseExtractor::class,
|
||||
'query' => 'SELECT * FROM mdl_course_categories ORDER BY parent ASC, id ASC',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'name' => 'name',
|
||||
'code' => [
|
||||
'class' => CourseCode::class,
|
||||
'properties' => ['name'],
|
||||
],
|
||||
'description' => 'description',
|
||||
'parent_id' => [
|
||||
'class' => CourseCategoryLookup::class,
|
||||
'properties' => ['parent'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseCategoriesLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
47
plugin/migrationmoodle/src/Task/CourseFilesTask.php
Normal file
47
plugin/migrationmoodle/src/Task/CourseFilesTask.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseFilesLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
|
||||
/**
|
||||
* Class CourseFilesTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
abstract class CourseFilesTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'contenthash' => 'contenthash',
|
||||
'filepath' => 'filepath',
|
||||
'filename' => 'filename',
|
||||
'filesize' => 'filesize',
|
||||
'mimetype' => 'mimetype',
|
||||
'course' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseFilesLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
64
plugin/migrationmoodle/src/Task/CourseIntroductionsTask.php
Normal file
64
plugin/migrationmoodle/src/Task/CourseIntroductionsTask.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseIntroductionLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\ReplaceFilePaths;
|
||||
|
||||
/**
|
||||
* Class CourseIntroductionsTask.
|
||||
*
|
||||
* Migrate the first section (section 0) from a moodle course as introduction for a chamilo course.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseIntroductionsTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT id, course, name, summary
|
||||
FROM mdl_course_sections
|
||||
WHERE section = 0 AND (summary != '' AND summary IS NOT NULL)",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'name' => 'name',
|
||||
'description' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['summary', 'course'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseIntroductionLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
68
plugin/migrationmoodle/src/Task/CourseModulesLessonTask.php
Normal file
68
plugin/migrationmoodle/src/Task/CourseModulesLessonTask.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseModulesLessonLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseCodeLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseSectionLookup;
|
||||
|
||||
/**
|
||||
* Class CourseModulesLessonTask.
|
||||
*
|
||||
* Task for convert a Moodle course module in a Chamilo learning path section.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseModulesLessonTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT cm.id, l.course, l.name, cm.section
|
||||
FROM mdl_lesson l
|
||||
INNER JOIN mdl_course_modules cm ON (l.course = cm.course AND cm.instance = l.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'lesson'
|
||||
ORDER BY cs.id, FIND_IN_SET(cm.id, cs.sequence)",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_code' => [
|
||||
'class' => LoadedCourseCodeLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'lp_id' => [
|
||||
'class' => LoadedCourseSectionLookup::class,
|
||||
'properties' => ['section'],
|
||||
],
|
||||
'title' => 'name',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseModulesLessonLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
68
plugin/migrationmoodle/src/Task/CourseModulesQuizTask.php
Normal file
68
plugin/migrationmoodle/src/Task/CourseModulesQuizTask.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseModulesQuizLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseCodeLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseSectionLookup;
|
||||
|
||||
/**
|
||||
* Class CourseModulesQuizTask.
|
||||
*
|
||||
* Task for convert a Moodle quiz inside a page section in a quiz item of Chamilo learning path.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseModulesQuizTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT cm.id, q.course, q.name, cm.section
|
||||
FROM mdl_quiz q
|
||||
INNER JOIN mdl_course_modules cm ON (q.course = cm.course AND cm.instance = q.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'quiz'
|
||||
ORDER BY cs.id, FIND_IN_SET(cm.id, cs.sequence)",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_code' => [
|
||||
'class' => LoadedCourseCodeLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'lp_id' => [
|
||||
'class' => LoadedCourseSectionLookup::class,
|
||||
'properties' => ['section'],
|
||||
],
|
||||
'title' => 'name',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseModulesQuizLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
92
plugin/migrationmoodle/src/Task/CourseModulesScormTask.php
Normal file
92
plugin/migrationmoodle/src/Task/CourseModulesScormTask.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseModulesScormLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\DateTimeObject;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
|
||||
/**
|
||||
* Class CourseModulesScormTask.
|
||||
*
|
||||
* Task to convert Moodle scorm in Chamilo scorm.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseModulesScormTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
sco.id,
|
||||
sco.course,
|
||||
sco.name,
|
||||
sco.reference,
|
||||
sco.version,
|
||||
sco.maxgrade,
|
||||
sco.hidetoc,
|
||||
i.identifier,
|
||||
cm.added,
|
||||
sco.timemodified
|
||||
FROM mdl_scorm sco
|
||||
INNER JOIN mdl_scorm_scoes i on sco.id = i.scorm
|
||||
INNER JOIN mdl_course_modules cm ON (sco.course = cm.course AND cm.instance = sco.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'scorm'
|
||||
AND i.parent = '/'
|
||||
ORDER BY cs.id, FIND_IN_SET(cm.id, cs.sequence)",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'name' => 'name',
|
||||
'ref' => 'identifier',
|
||||
'path' => 'reference',
|
||||
'use_max_score' => 'maxgrade',
|
||||
'hide_toc_frame' => 'hidetoc',
|
||||
'created_on' => [
|
||||
'class' => DateTimeObject::class,
|
||||
'properties' => ['added'],
|
||||
],
|
||||
'modified_on' => [
|
||||
'class' => DateTimeObject::class,
|
||||
'properties' => ['timemodified'],
|
||||
],
|
||||
'publicated_on' => [
|
||||
'class' => DateTimeObject::class,
|
||||
'properties' => ['added'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseModulesScormLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
75
plugin/migrationmoodle/src/Task/CourseModulesUrlTask.php
Normal file
75
plugin/migrationmoodle/src/Task/CourseModulesUrlTask.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseModulesUrlLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseCodeLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseSectionLookup;
|
||||
|
||||
/**
|
||||
* Class CourseModulesUrlTask.
|
||||
*
|
||||
* Task to create a Chamilo Link from a Moodle URL module.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseModulesUrlTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT cm.id, u.course, u.name, cm.section
|
||||
FROM mdl_url u
|
||||
INNER JOIN mdl_course_modules cm ON (u.course = cm.course AND cm.instance = u.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'url'
|
||||
AND u.course NOT IN (
|
||||
SELECT sco.course
|
||||
FROM mdl_scorm sco
|
||||
INNER JOIN mdl_course_modules cm ON (sco.course = cm.course AND cm.instance = sco.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'scorm'
|
||||
)",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_code' => [
|
||||
'class' => LoadedCourseCodeLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'lp_id' => [
|
||||
'class' => LoadedCourseSectionLookup::class,
|
||||
'properties' => ['section'],
|
||||
],
|
||||
'title' => 'name',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseModulesUrlLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
74
plugin/migrationmoodle/src/Task/CourseSectionsTask.php
Normal file
74
plugin/migrationmoodle/src/Task/CourseSectionsTask.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CourseSectionsLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseCodeLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\WrapHtmlReplacingFilePaths;
|
||||
|
||||
/**
|
||||
* Class CourseSectionsTask.
|
||||
*
|
||||
* Task to convert Moodle course sections in a Chamilo learning paths.
|
||||
* The section summary will be the first item in the learning path.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CourseSectionsTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT id, course, name, summary
|
||||
FROM mdl_course_sections
|
||||
WHERE section > 0 AND (name != '' OR name IS NOT NULL)
|
||||
AND course NOT IN (
|
||||
SELECT sco.course
|
||||
FROM mdl_scorm sco
|
||||
INNER JOIN mdl_course_modules cm ON (sco.course = cm.course AND cm.instance = sco.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'scorm'
|
||||
)
|
||||
ORDER BY course, section",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'course_code' => [
|
||||
'class' => LoadedCourseCodeLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'name' => 'name',
|
||||
'description' => [
|
||||
'class' => WrapHtmlReplacingFilePaths::class,
|
||||
'properties' => ['summary', 'course'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CourseSectionsLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
85
plugin/migrationmoodle/src/Task/CoursesTask.php
Normal file
85
plugin/migrationmoodle/src/Task/CoursesTask.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\BaseExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\CoursesLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\CourseCategoryLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\CourseVisibility;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\DateTimeObject;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\Language;
|
||||
|
||||
/**
|
||||
* Class CoursesTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class CoursesTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
$query = "SELECT * FROM mdl_course";
|
||||
|
||||
$userFilter = $this->plugin->getUserFilterSetting();
|
||||
|
||||
if (!empty($userFilter)) {
|
||||
$query = "SELECT DISTINCT c.*
|
||||
FROM mdl_course c
|
||||
INNER JOIN mdl_context ctx ON c.id = ctx.instanceid
|
||||
INNER JOIN mdl_role_assignments ra ON ctx.id = ra.contextid
|
||||
INNER JOIN mdl_user u ON ra.userid = u.id
|
||||
WHERE u.username LIKE '$userFilter%'";
|
||||
}
|
||||
|
||||
return [
|
||||
'class' => BaseExtractor::class,
|
||||
'query' => $query,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'title' => 'fullname',
|
||||
'wanted_code' => 'shortname',
|
||||
'course_category' => [
|
||||
'class' => CourseCategoryLookup::class,
|
||||
'properties' => ['category'],
|
||||
],
|
||||
'course_language' => [
|
||||
'class' => Language::class,
|
||||
'properties' => ['lang'],
|
||||
],
|
||||
'visibility' => [
|
||||
'class' => CourseVisibility::class,
|
||||
'properties' => ['visible'],
|
||||
],
|
||||
'description' => 'summary',
|
||||
'creation_date' => [
|
||||
'class' => DateTimeObject::class,
|
||||
'properties' => ['timecreated'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => CoursesLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
|
||||
/**
|
||||
* Class FilesForCourseIntroductionsTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class FilesForCourseIntroductionsTask extends CourseFilesTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
f.id,
|
||||
f.contenthash,
|
||||
f.filepath,
|
||||
f.filename,
|
||||
f.filesize,
|
||||
f.mimetype,
|
||||
c.id course
|
||||
FROM mdl_files f
|
||||
INNER JOIN mdl_context ctx ON f.contextid = ctx.id
|
||||
INNER JOIN mdl_course c ON ctx.instanceid = c.id
|
||||
INNER JOIN mdl_course_sections cs ON (cs.course = c.id AND cs.id = f.itemid)
|
||||
WHERE f.component = 'course'
|
||||
AND f.filearea = 'section'
|
||||
AND ctx.contextlevel = 50
|
||||
AND f.filename NOT IN ('.', '..')
|
||||
AND cs.section = 0 AND (cs.summary != '' AND cs.summary IS NOT NULL)",
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
|
||||
/**
|
||||
* Class FilesForCourseSectionsTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class FilesForCourseSectionsTask extends CourseFilesTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
f.id,
|
||||
f.contenthash,
|
||||
f.filepath,
|
||||
f.filename,
|
||||
f.filesize,
|
||||
f.mimetype,
|
||||
c.id course
|
||||
FROM mdl_files f
|
||||
INNER JOIN mdl_context ctx ON f.contextid = ctx.id
|
||||
INNER JOIN mdl_course c ON ctx.instanceid = c.id
|
||||
INNER JOIN mdl_course_sections cs ON (cs.course = c.id AND cs.id = f.itemid)
|
||||
WHERE f.component = 'course'
|
||||
AND f.filearea = 'section'
|
||||
AND ctx.contextlevel = 50
|
||||
AND f.filename NOT IN ('.', '..')
|
||||
AND cs.section > 0
|
||||
AND c.id NOT IN (
|
||||
SELECT sco.course
|
||||
FROM mdl_scorm sco
|
||||
INNER JOIN mdl_course_modules cm ON (sco.course = cm.course AND cm.instance = sco.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'scorm'
|
||||
)",
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
|
||||
/**
|
||||
* Class FilesForLessonAnswersTask.
|
||||
*
|
||||
* Task for migrate the files for Moodle lesson answers in the files for Chamilo course documents.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class FilesForLessonAnswersTask extends CourseFilesTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
f.id,
|
||||
f.contenthash,
|
||||
f.filepath,
|
||||
f.filename,
|
||||
f.filesize,
|
||||
f.mimetype,
|
||||
cm.course
|
||||
FROM mdl_files f
|
||||
INNER JOIN mdl_context c ON f.contextid = c.id
|
||||
INNER JOIN mdl_course_modules cm ON c.instanceid = cm.id
|
||||
WHERE f.component = 'mod_lesson'
|
||||
AND f.filearea = 'page_answers'
|
||||
AND c.contextlevel = 70
|
||||
AND f.filename NOT IN ('.', '..')",
|
||||
];
|
||||
}
|
||||
}
|
||||
41
plugin/migrationmoodle/src/Task/FilesForLessonPagesTask.php
Normal file
41
plugin/migrationmoodle/src/Task/FilesForLessonPagesTask.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
|
||||
/**
|
||||
* Class FilesForLessonPagesTask.
|
||||
*
|
||||
* Task for migrate the files for Moodle lesson pages in the files for Chamilo course documents.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class FilesForLessonPagesTask extends CourseFilesTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
f.id,
|
||||
f.contenthash,
|
||||
f.filepath,
|
||||
f.filename,
|
||||
f.filesize,
|
||||
f.mimetype,
|
||||
cm.course
|
||||
FROM mdl_files f
|
||||
INNER JOIN mdl_context c ON f.contextid = c.id
|
||||
INNER JOIN mdl_course_modules cm ON c.instanceid = cm.id
|
||||
WHERE f.component = 'mod_lesson'
|
||||
AND f.filearea = 'page_contents'
|
||||
AND c.contextlevel = 70
|
||||
AND f.filename NOT IN ('.', '..')",
|
||||
];
|
||||
}
|
||||
}
|
||||
39
plugin/migrationmoodle/src/Task/FilesForQuizzesTask.php
Normal file
39
plugin/migrationmoodle/src/Task/FilesForQuizzesTask.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
|
||||
/**
|
||||
* Class FilesForQuizzesTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class FilesForQuizzesTask extends CourseFilesTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
f.id,
|
||||
f.contenthash,
|
||||
f.filepath,
|
||||
f.filename,
|
||||
f.filesize,
|
||||
f.mimetype,
|
||||
cm.course
|
||||
FROM mdl_files f
|
||||
INNER JOIN mdl_context c ON f.contextid = c.id
|
||||
INNER JOIN mdl_course_modules cm ON c.instanceid = cm.id
|
||||
WHERE f.component = 'mod_quiz'
|
||||
AND f.filearea = 'intro'
|
||||
AND c.contextlevel = 70
|
||||
AND f.filename NOT IN ('.', '..')",
|
||||
];
|
||||
}
|
||||
}
|
||||
83
plugin/migrationmoodle/src/Task/FilesForScormScoesTask.php
Normal file
83
plugin/migrationmoodle/src/Task/FilesForScormScoesTask.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\FilesForScormScoLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
|
||||
/**
|
||||
* Class FilesForScormScoesTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class FilesForScormScoesTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
f.id,
|
||||
f.contenthash,
|
||||
f.filepath,
|
||||
f.filename,
|
||||
f.mimetype,
|
||||
s.name scorm_name,
|
||||
cm.course
|
||||
FROM mdl_files f
|
||||
INNER JOIN mdl_context ctx ON f.contextid = ctx.id
|
||||
INNER JOIN mdl_course_modules cm ON ctx.instanceid = cm.id
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_scorm s ON (cm.course = s.course AND cm.instance = s.id)
|
||||
WHERE
|
||||
m.name = 'scorm'
|
||||
AND ctx.contextlevel = 70
|
||||
AND f.filename NOT IN ('.', '..')
|
||||
AND s.reference != f.filename
|
||||
AND f.filearea = 'content'
|
||||
AND f.component = 'mod_scorm'
|
||||
ORDER BY s.course, s.id",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'contenthash' => 'contenthash',
|
||||
'filepath' => 'filepath',
|
||||
'filename' => 'filename',
|
||||
'mimetype' => 'mimetype',
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'lp_name' => 'scorm_name',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => FilesForScormScoLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
70
plugin/migrationmoodle/src/Task/LessonAnswersEssayTask.php
Normal file
70
plugin/migrationmoodle/src/Task/LessonAnswersEssayTask.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersEssayLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizQuestionLookup;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersEssayTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonAnswersEssayTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT la.id, la.pageid, la.score, l.course
|
||||
FROM mdl_lesson_answers la
|
||||
INNER JOIN mdl_lesson_pages lp ON (la.pageid = lp.id AND la.lessonid = lp.lessonid)
|
||||
INNER JOIN mdl_lesson l ON (lp.lessonid = l.id AND la.lessonid = l.id)
|
||||
WHERE lp.qtype = 10
|
||||
ORDER BY lp.id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedLessonPageQuizQuestionLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'score' => 'score',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersEssayLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersMatchingLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LessonAnswersMatchingScore;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizQuestionLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\ReplaceFilePaths;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersMatchingTask.
|
||||
*
|
||||
* Task to convert Matching answers from a lesson page in quiz answers for chamilo.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonAnswersMatchingTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT la.id, la.pageid, la.answer, la.response, la.lessonid, l.course
|
||||
FROM mdl_lesson_answers la
|
||||
INNER JOIN mdl_lesson_pages lp ON (la.pageid = lp.id AND la.lessonid = lp.lessonid)
|
||||
INNER JOIN mdl_lesson l ON (lp.lessonid = l.id AND la.lessonid = l.id)
|
||||
WHERE lp.qtype = 5
|
||||
AND (la.response IS NOT NULL OR la.response != '')
|
||||
ORDER BY lp.id",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedLessonPageQuizQuestionLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'score' => [
|
||||
'class' => LessonAnswersMatchingScore::class,
|
||||
'properties' => ['pageid', 'lessonid', 'course'],
|
||||
],
|
||||
'answer' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['answer', 'course'],
|
||||
],
|
||||
'feedback' => 'response',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersMatchingLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersMultipleAnswerLoader;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersMultipleAnswerTask.
|
||||
*
|
||||
* Task to convert Multiple Choice answers from a Moodle lesson page in answers for Unique Answer question for Chamilo.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonAnswersMultipleAnswerTask extends LessonAnswersMultipleChoiceTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT la.id, la.pageid, la.score, la.answer, la.response, l.course
|
||||
FROM mdl_lesson_answers la
|
||||
INNER JOIN mdl_lesson_pages lp ON (la.pageid = lp.id AND la.lessonid = lp.lessonid)
|
||||
INNER JOIN mdl_lesson l ON (lp.lessonid = l.id AND la.lessonid = l.id)
|
||||
WHERE lp.qtype = 3 AND lp.qoption = 1
|
||||
ORDER BY lp.id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersMultipleAnswerLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersMultipleChoiceLoader;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersMultipleChoiceTask.
|
||||
*
|
||||
* Task to convert Multiple Choice answers from a Moodle lesson page in answers for Unique Answer question for Chamilo.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonAnswersMultipleChoiceTask extends LessonAnswersTrueFalseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT la.id, la.pageid, la.score, la.answer, la.response, l.course
|
||||
FROM mdl_lesson_answers la
|
||||
INNER JOIN mdl_lesson_pages lp ON (la.pageid = lp.id AND la.lessonid = lp.lessonid)
|
||||
INNER JOIN mdl_lesson l ON (lp.lessonid = l.id AND la.lessonid = l.id)
|
||||
WHERE lp.qtype = 3 AND lp.qoption = 0
|
||||
ORDER BY lp.id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersMultipleChoiceLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersShortAnswerLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizQuestionLookup;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersShortAnswerTask.
|
||||
*
|
||||
* Task to convert Short Answers and Numerical answers from a lesson page in quiz answers for chamilo.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonAnswersShortAnswerTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
la.id,
|
||||
la.pageid,
|
||||
GROUP_CONCAT(la.answer SEPARATOR '||') answers,
|
||||
GROUP_CONCAT(la.response SEPARATOR '') comment,
|
||||
MAX(la.score) scores,
|
||||
l.course,
|
||||
COUNT(la.pageid) nb
|
||||
FROM mdl_lesson_answers la
|
||||
INNER JOIN mdl_lesson_pages lp ON (la.pageid = lp.id AND la.lessonid = lp.lessonid)
|
||||
INNER JOIN mdl_lesson l ON (lp.lessonid = l.id AND la.lessonid = l.id)
|
||||
WHERE lp.qtype IN (1, 8)
|
||||
GROUP BY lp.id
|
||||
ORDER BY lp.id",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedLessonPageQuizQuestionLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'scores' => 'scores',
|
||||
'answers' => 'answers',
|
||||
'comment' => 'comment',
|
||||
'nb' => 'nb',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersShortAnswerLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersTrueFalseLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizQuestionLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\ReplaceFilePaths;
|
||||
|
||||
/**
|
||||
* Class LessonAnswersTrueFalseTask.
|
||||
*
|
||||
* Task to convert True/False answers from a lesson page in quiz answers for chamilo.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonAnswersTrueFalseTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT la.id, la.pageid, la.score, la.answer, la.response, l.course,
|
||||
(
|
||||
SELECT MIN(id) = la.id
|
||||
FROM mdl_lesson_answers
|
||||
WHERE pageid = la.pageid
|
||||
GROUP BY lessonid, pageid
|
||||
) is_correct
|
||||
FROM mdl_lesson_answers la
|
||||
INNER JOIN mdl_lesson_pages lp ON (la.pageid = lp.id AND la.lessonid = lp.lessonid)
|
||||
INNER JOIN mdl_lesson l ON (lp.lessonid = l.id AND la.lessonid = l.id)
|
||||
WHERE lp.qtype = 2
|
||||
ORDER BY lp.id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedLessonPageQuizQuestionLookup::class,
|
||||
'properties' => ['pageid'],
|
||||
],
|
||||
'score' => 'score',
|
||||
'answer' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['answer', 'course'],
|
||||
],
|
||||
'feedback' => 'response',
|
||||
'is_correct' => 'is_correct',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersTrueFalseLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
75
plugin/migrationmoodle/src/Task/LessonPagesDocumentTask.php
Normal file
75
plugin/migrationmoodle/src/Task/LessonPagesDocumentTask.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonPagesDocumentLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseSectionFromLessonLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\WrapHtmlReplacingFilePaths;
|
||||
|
||||
/**
|
||||
* Class LessonPagesDocumentTask.
|
||||
*
|
||||
* Task for convert the Moodle lesson pages in Chamilo course documents.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonPagesDocumentTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT lp.id, l.id lessonid, l.course, lp.title, lp.contents
|
||||
FROM mdl_lesson_pages lp
|
||||
INNER JOIN mdl_lesson l ON lp.lessonid = l.id
|
||||
WHERE lp.qtype = 20',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'lp_id' => [
|
||||
'class' => LoadedCourseSectionFromLessonLookup::class,
|
||||
'properties' => ['lessonid'],
|
||||
],
|
||||
'item_id' => [
|
||||
'class' => LoadedLessonPageLookup::class,
|
||||
'properties' => ['id'],
|
||||
],
|
||||
'item_title' => 'title',
|
||||
'item_content' => [
|
||||
'class' => WrapHtmlReplacingFilePaths::class,
|
||||
'properties' => ['contents', 'course'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonPagesDocumentLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonQuestionPagesQuestionLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\QuizQuestionTypeFromLessonPage;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\ReplaceFilePaths;
|
||||
|
||||
/**
|
||||
* Class LessonPagesQuizQuestionTask.
|
||||
*
|
||||
* Task to convert the question pages from a moodle lesson in one chamilo question to be added in quiz already creadted.
|
||||
*
|
||||
* The types question pages are:
|
||||
* 1, short answer; 2, true-false; 3, multiple choice or multiple answer; 5, matching; 8, numerical; 10, essay.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonPagesQuizQuestionTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT lp.id, l.course, lp.contents, lp.qoption, lp.qtype
|
||||
FROM mdl_lesson_pages lp
|
||||
INNER JOIN mdl_lesson l ON lp.lessonid = l.id
|
||||
WHERE lp.qtype IN (1, 2, 3, 5, 8, 10)',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['id'],
|
||||
],
|
||||
'question_title' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['contents', 'course'],
|
||||
],
|
||||
'question_type' => [
|
||||
'class' => QuizQuestionTypeFromLessonPage::class,
|
||||
'properties' => ['qtype', 'qoption'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonQuestionPagesQuestionLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
65
plugin/migrationmoodle/src/Task/LessonPagesQuizTask.php
Normal file
65
plugin/migrationmoodle/src/Task/LessonPagesQuizTask.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonQuestionPagesQuizLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageLookup;
|
||||
|
||||
/**
|
||||
* Class LessonPagesQuizTask.
|
||||
*
|
||||
* Task to convert the question pages from a moodle lesson in one chamilo quiz with one question.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonPagesQuizTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => 'SELECT lp.id, l.course, lp.title
|
||||
FROM mdl_lesson_pages lp
|
||||
INNER JOIN mdl_lesson l ON lp.lessonid = l.id
|
||||
WHERE lp.qtype IN (1, 2, 3, 5, 8, 10)',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'item_id' => [
|
||||
'class' => LoadedLessonPageLookup::class,
|
||||
'properties' => ['id'],
|
||||
],
|
||||
'item_title' => 'title',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonQuestionPagesQuizLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
104
plugin/migrationmoodle/src/Task/LessonPagesTask.php
Normal file
104
plugin/migrationmoodle/src/Task/LessonPagesTask.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonPagesLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LessonPageType;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseCodeLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseModuleLessonLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseSectionFromLessonLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageLookup;
|
||||
|
||||
/**
|
||||
* Class LessonPagesTask.
|
||||
*
|
||||
* Task to conver the Moodle lesson pages in items for Chamilo learning paths.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class LessonPagesTask extends BaseTask
|
||||
{
|
||||
public const TYPE_END_BRANCH = 21;
|
||||
public const TYPE_CLUSTER = 30;
|
||||
public const TYPE_END_CLUSTER = 31;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "WITH RECURSIVE lesson_pages_ordered (id, title, qtype, prev, next, lesson, display_order) AS
|
||||
(
|
||||
SELECT id, title, qtype, prevpageid, nextpageid, lessonid, '01'
|
||||
FROM mdl_lesson_pages
|
||||
WHERE prevpageid = 0
|
||||
UNION
|
||||
SELECT lp.id, lp.title, lp.qtype, lp.prevpageid, lp.nextpageid, lp.lessonid, lpo.display_order + 1
|
||||
FROM lesson_pages_ordered lpo
|
||||
LEFT JOIN mdl_lesson_pages lp
|
||||
ON (lpo.next = lp.id AND lpo.lesson = lp.lessonid)
|
||||
)
|
||||
SELECT
|
||||
lpo.id,
|
||||
lpo.title,
|
||||
lpo.qtype,
|
||||
lpo.prev,
|
||||
lpo.lesson,
|
||||
CAST(lpo.display_order AS SIGNED) lpo_display_order,
|
||||
l.course
|
||||
FROM lesson_pages_ordered lpo
|
||||
INNER JOIN mdl_lesson l ON lpo.lesson = l.id
|
||||
WHERE lpo.qtype NOT IN (".self::TYPE_END_BRANCH.", ".self::TYPE_CLUSTER.", ".self::TYPE_END_CLUSTER.")
|
||||
ORDER BY l.course, lpo.lesson, lpo_display_order",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_code' => [
|
||||
'class' => LoadedCourseCodeLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'lp_id' => [
|
||||
'class' => LoadedCourseSectionFromLessonLookup::class,
|
||||
'properties' => ['lesson'],
|
||||
],
|
||||
'parent' => [
|
||||
'class' => LoadedCourseModuleLessonLookup::class,
|
||||
'properties' => ['lesson'],
|
||||
],
|
||||
'previous' => [
|
||||
'class' => LoadedLessonPageLookup::class,
|
||||
'properties' => ['prev'],
|
||||
],
|
||||
'item_type' => [
|
||||
'class' => LessonPageType::class,
|
||||
'properties' => ['qtype'],
|
||||
],
|
||||
'title' => 'title',
|
||||
'display_order' => 'lpo_display_order',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonPagesLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
62
plugin/migrationmoodle/src/Task/QuestionCategoriesTask.php
Normal file
62
plugin/migrationmoodle/src/Task/QuestionCategoriesTask.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\BaseExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\QuestionCategoriesLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseFromQuestionCategoryLookup;
|
||||
|
||||
/**
|
||||
* Class QuestionCategoriesTask.
|
||||
*
|
||||
* Task for create categories for Chamilo quiz questions coming from a Moodle questions categories.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class QuestionCategoriesTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseExtractor::class,
|
||||
'query' => "SELECT qc.id, qc.name, qc.info, c.contextlevel, c.instanceid
|
||||
FROM mdl_question_categories qc
|
||||
INNER JOIN mdl_context c ON qc.contextid = c.id
|
||||
WHERE c.contextlevel IN (50, 70)
|
||||
AND qc.parent != 0",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseFromQuestionCategoryLookup::class,
|
||||
'properties' => ['contextlevel', 'instanceid'],
|
||||
],
|
||||
'name' => 'name',
|
||||
'description' => 'info',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => QuestionCategoriesLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
90
plugin/migrationmoodle/src/Task/QuestionGapselectTask.php
Normal file
90
plugin/migrationmoodle/src/Task/QuestionGapselectTask.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\QuestionGapselectLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedQuestionLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\QuestionGapselectAnswer;
|
||||
|
||||
/**
|
||||
* Class QuestionGapselectTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class QuestionGapselectTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
qa.id,
|
||||
qq.id,
|
||||
qa.question,
|
||||
GROUP_CONCAT(
|
||||
CONCAT(qa.feedback, '==>>', qa.answer) ORDER BY qa.id ASC SEPARATOR '@||@'
|
||||
) answers,
|
||||
qq.questiontext,
|
||||
qs.maxmark,
|
||||
qg.correctfeedback,
|
||||
q.id quiz_id,
|
||||
q.course
|
||||
FROM mdl_question_answers qa
|
||||
INNER JOIN mdl_question qq ON qa.question = qq.id
|
||||
INNER JOIN mdl_question_gapselect qg ON qq.id = qg.questionid
|
||||
INNER JOIN mdl_quiz_slots qs ON qq.id = qs.questionid
|
||||
INNER JOIN mdl_quiz q ON qs.quizid = q.id
|
||||
WHERE qq.qtype = 'gapselect'
|
||||
GROUP BY q.id, qq.id
|
||||
ORDER BY q.id, qq.id",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedQuizLookup::class,
|
||||
'properties' => ['quiz_id'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedQuestionLookup::class,
|
||||
'properties' => ['question'],
|
||||
],
|
||||
'answer' => [
|
||||
'class' => QuestionGapselectAnswer::class,
|
||||
'properties' => ['answers', 'questiontext', 'maxmark'],
|
||||
],
|
||||
'score' => 'maxmark',
|
||||
'comment' => 'correctfeedback',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => QuestionGapselectLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersMultipleAnswerLoader;
|
||||
|
||||
/**
|
||||
* Class QuestionMultiChoiceMultipleTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class QuestionMultiChoiceMultipleTask extends QuestionMultiChoiceSingleTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
qa.id,
|
||||
qa.question,
|
||||
qa.answer,
|
||||
qa.feedback,
|
||||
(qa.fraction * qq.defaultmark) score,
|
||||
IF (qa.fraction > 0, TRUE, FALSE) is_correct,
|
||||
q.id quizid,
|
||||
q.course
|
||||
FROM mdl_question_answers qa
|
||||
INNER JOIN mdl_question qq ON qa.question = qq.id
|
||||
INNER JOIN mdl_qtype_multichoice_options qo ON qq.id = qo.questionid
|
||||
INNER JOIN mdl_quiz_slots qs ON qq.id = qs.questionid
|
||||
INNER JOIN mdl_quiz q ON qs.quizid = q.id
|
||||
WHERE qq.qtype = 'multichoice'
|
||||
AND qo.single = 0",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersMultipleAnswerLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonAnswersMultipleChoiceLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedQuestionLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\ReplaceFilePaths;
|
||||
|
||||
/**
|
||||
* Class QuestionMultiChoiceSingleTask.
|
||||
*
|
||||
* Task to convert Moodle question answers of multichoice type in Chamilo unique/multiple answers.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class QuestionMultiChoiceSingleTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
qa.id,
|
||||
qa.question,
|
||||
qa.answer,
|
||||
qa.feedback,
|
||||
(qa.fraction * qq.defaultmark) score,
|
||||
IF (qa.fraction = 1, TRUE, FALSE) is_correct,
|
||||
q.id quizid,
|
||||
q.course
|
||||
FROM mdl_question_answers qa
|
||||
INNER JOIN mdl_question qq ON qa.question = qq.id
|
||||
INNER JOIN mdl_qtype_multichoice_options qo ON qq.id = qo.questionid
|
||||
INNER JOIN mdl_quiz_slots qs ON qq.id = qs.questionid
|
||||
INNER JOIN mdl_quiz q ON qs.quizid = q.id
|
||||
WHERE qq.qtype = 'multichoice'
|
||||
AND qo.single = 1",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['quizid'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedQuestionLookup::class,
|
||||
'properties' => ['question'],
|
||||
],
|
||||
'score' => 'score',
|
||||
'answer' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['answer', 'course'],
|
||||
],
|
||||
'feedback' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['feedback', 'course'],
|
||||
],
|
||||
'is_correct' => 'is_correct',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonAnswersMultipleChoiceLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
73
plugin/migrationmoodle/src/Task/QuestionShortAnswerTask.php
Normal file
73
plugin/migrationmoodle/src/Task/QuestionShortAnswerTask.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedLessonPageQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedQuestionLookup;
|
||||
|
||||
/**
|
||||
* Class QuestionShortAnswerTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class QuestionShortAnswerTask extends LessonAnswersShortAnswerTask
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT
|
||||
qa.id,
|
||||
qa.question,
|
||||
GROUP_CONCAT(qa.answer SEPARATOR '||') answers,
|
||||
qq.defaultmark,
|
||||
GROUP_CONCAT(qa.feedback SEPARATOR '\n') feedback,
|
||||
COUNT(qa.id) nb,
|
||||
q.id quizid,
|
||||
q.course
|
||||
FROM mdl_question_answers qa
|
||||
INNER JOIN mdl_question qq ON qa.question = qq.id
|
||||
INNER JOIN mdl_qtype_shortanswer_options qo ON qq.id = qo.questionid
|
||||
INNER JOIN mdl_quiz_slots qs ON qq.id = qs.questionid
|
||||
INNER JOIN mdl_quiz q ON qs.quizid = q.id
|
||||
WHERE qq.qtype = 'shortanswer'
|
||||
GROUP BY qq.id
|
||||
ORDER BY q.course, qq.id",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedLessonPageQuizLookup::class,
|
||||
'properties' => ['quizid'],
|
||||
],
|
||||
'question_id' => [
|
||||
'class' => LoadedQuestionLookup::class,
|
||||
'properties' => ['question'],
|
||||
],
|
||||
'scores' => 'defaultmark',
|
||||
'answers' => 'answers',
|
||||
'comment' => 'feedback',
|
||||
'nb' => 'nb',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
76
plugin/migrationmoodle/src/Task/QuestionsTask.php
Normal file
76
plugin/migrationmoodle/src/Task/QuestionsTask.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\MigrationMoodle\Task;
|
||||
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Extractor\LoadedCoursesFilterExtractor;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Loader\LessonQuestionPagesQuestionLoader;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\BaseTransformer;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedCourseLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\LoadedQuizLookup;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\QuestionType;
|
||||
use Chamilo\PluginBundle\MigrationMoodle\Transformer\Property\ReplaceFilePaths;
|
||||
|
||||
/**
|
||||
* Class QuestionsTask.
|
||||
*
|
||||
* @package Chamilo\PluginBundle\MigrationMoodle\Task
|
||||
*/
|
||||
class QuestionsTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LoadedCoursesFilterExtractor::class,
|
||||
'query' => "SELECT qq.id, qq.category, qq.questiontext, qq.qtype, q.course, q.id quiz_id
|
||||
FROM mdl_question qq
|
||||
INNER JOIN mdl_quiz_slots qs ON qq.id = qs.questionid
|
||||
INNER JOIN mdl_quiz q ON qs.quizid = q.id
|
||||
INNER JOIN mdl_course_modules cm ON (q.course = cm.course AND cm.instance = q.id)
|
||||
INNER JOIN mdl_modules m ON cm.module = m.id
|
||||
INNER JOIN mdl_course_sections cs ON (cm.course = cs.course AND cm.section = cs.id )
|
||||
WHERE m.name = 'quiz'",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => BaseTransformer::class,
|
||||
'map' => [
|
||||
'c_id' => [
|
||||
'class' => LoadedCourseLookup::class,
|
||||
'properties' => ['course'],
|
||||
],
|
||||
'quiz_id' => [
|
||||
'class' => LoadedQuizLookup::class,
|
||||
'properties' => ['quiz_id'],
|
||||
],
|
||||
'question_title' => [
|
||||
'class' => ReplaceFilePaths::class,
|
||||
'properties' => ['questiontext', 'course'],
|
||||
],
|
||||
'question_type' => [
|
||||
'class' => QuestionType::class,
|
||||
'properties' => ['qtype', 'id'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadConfiguration()
|
||||
{
|
||||
return [
|
||||
'class' => LessonQuestionPagesQuestionLoader::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user