Actualización

This commit is contained in:
Xes
2025-04-10 12:36:07 +02:00
parent 1da7c3f3b9
commit 4aff98e77b
3147 changed files with 320647 additions and 0 deletions
@@ -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;
}
}
@@ -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;
}
}
@@ -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'],
''
);
}
}
@@ -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/.";
}
}
@@ -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'],
''
);
}
}
@@ -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;
}
}
@@ -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'];
}
}
@@ -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 &nbsp;
$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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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'];
}
}
@@ -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;
}
}
@@ -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,
]
);
}
}
@@ -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'];
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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
);
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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'];
}
}