diff --git a/main/exercice/exercise.class.php b/main/exercice/exercise.class.php index 3974ef61e3..dfd37c9315 100644 --- a/main/exercice/exercise.class.php +++ b/main/exercice/exercise.class.php @@ -163,9 +163,10 @@ class Exercise * @todo use Doctrine to manage read/writes * @param int $id - exercise ID * @param bool parse exercise question list + * @param int $chamilo_session_id - chamilo session ID * @return boolean - true if exercise exists, otherwise false */ - public function read($id, $parseQuestionList = true) + public function read($id, $parseQuestionList = true, $chamilo_session_id = null) { if (empty($this->course_id)) { return false; @@ -243,7 +244,7 @@ class Exercise $this->trackExercise = $this->getStatTrackExerciseInfo(); if ($parseQuestionList) { - $this->setQuestionList($this->loadDistributions); + $this->setQuestionList($this->loadDistributions, $chamilo_session_id); } return true; } @@ -849,7 +850,8 @@ class Exercise $questionsPerMainCategory = array(); foreach ($temp_question_list as $categoryId => $questionList) { $parentId = $categoriesAddedInExercise[$categoryId]['parent_id']; - $cat = new Testcategory(); + // Default values and the course_id passed. + $cat = new Testcategory(0, '', '', 0, 'simple', $this->course_id); $cat->getCategory($parentId); if (!isset($questionsPerMainCategory[$cat->parent_id])) { @@ -885,8 +887,8 @@ class Exercise 'category_with_questions_list' => array() ); - // Order/random categories - $cat = new Testcategory(); + // Order/random categories. Default values and the course_id passed. + $cat = new Testcategory(0, '', '', 0, 'simple', $this->course_id); $courseId = $this->course_id; @@ -1047,7 +1049,8 @@ class Exercise if (!empty($questions_by_category)) { foreach ($questions_by_category as $categoryId => $questionList) { - $cat = new Testcategory($categoryId); + // Default values and the course_id passed. + $cat = new Testcategory($categoryId, '', '', 0, 'simple', $this->course_id); $cat = (array)$cat; $cat['iid'] = $cat['id']; $cat['name'] = $cat['title']; @@ -2968,7 +2971,8 @@ class Exercise $safe_lp_item_id = 0, $safe_lp_item_view_id = 0, $questionList = array(), - $weight = 0 + $weight = 0, + $chamilo_session_id = null ) { $track_exercises = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $safe_lp_id = intval($safe_lp_id); @@ -2994,10 +2998,13 @@ class Exercise $questionList = array_map('intval', $questionList); $weight = Database::escape_string($weight); + if (!$chamilo_session_id) { + $chamilo_session_id = api_get_session_id(); + } $sql = "INSERT INTO $track_exercises ($sql_fields exe_exo_id, exe_user_id, c_id, status, session_id, data_tracking, start_date, orig_lp_id, orig_lp_item_id, exe_weighting, quiz_distribution_id) VALUES - ( $sql_fields_values '".$this->id."','".api_get_user_id()."','".api_get_course_int_id()."', 'incomplete','".api_get_session_id()."','".implode(',', $questionList)."', '".api_get_utc_datetime()."', '$safe_lp_id', '$safe_lp_item_id', '$weight', '".$this->distributionId."')"; + ( $sql_fields_values '".$this->id."','".api_get_user_id()."','".$this->course_id."', 'incomplete','".$chamilo_session_id."','".implode(',', $questionList)."', '".api_get_utc_datetime()."', '$safe_lp_id', '$safe_lp_item_id', '$weight', '".$this->distributionId."')"; Database::query($sql); $id = Database::insert_id(); @@ -5595,13 +5602,15 @@ class Exercise /** * Sets the question list when the exercise->read() is executed */ - public function setQuestionList($loadDistributions = false) + public function setQuestionList($loadDistributions = false, $sessionId = null) { // Getting question list. $questionList = $this->selectQuestionList(true); // Looking for distributions - $sessionId = api_get_session_id(); + if (!$sessionId) { + $sessionId = api_get_session_id(); + } if (!empty($sessionId)) { $dataExists = !empty($this->trackExercise) && isset($this->trackExercise['data_tracking']) && !empty($this->trackExercise['data_tracking']) ? true : false; diff --git a/main/exercice/exercise.lib.php b/main/exercice/exercise.lib.php index 17ccfa86e9..aabf9e4572 100644 --- a/main/exercice/exercise.lib.php +++ b/main/exercice/exercise.lib.php @@ -789,8 +789,10 @@ function get_exercise_track_exercise_info($exe_id) { /** * Validates the time control key */ -function exercise_time_control_is_valid($exercise_id, $lp_id = 0 , $lp_item_id = 0) { - $course_id = api_get_course_int_id(); +function exercise_time_control_is_valid($exercise_id, $lp_id = 0 , $lp_item_id = 0, $course_id = null) { + if (!$course_id) { + $course_id = api_get_course_int_id(); + } $exercise_id = intval($exercise_id); $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); $sql = "SELECT expired_time FROM $TBL_EXERCICES WHERE c_id = $course_id AND id = $exercise_id"; diff --git a/main/exercice/testcategory.class.php b/main/exercice/testcategory.class.php index c106cf4db2..65bf956b3c 100644 --- a/main/exercice/testcategory.class.php +++ b/main/exercice/testcategory.class.php @@ -36,7 +36,7 @@ class Testcategory public function Testcategory($in_id = 0, $in_name = '', $in_description = "", $parent_id = 0, $type = 'simple', $course_id = null, $visibility = 1) { if ($in_id != 0 && $in_name == "") { - $tmpobj = new Testcategory(); + $tmpobj = new Testcategory(0, '', '', 0, 'simple', $course_id); $tmpobj->getCategory($in_id); $this->id = $tmpobj->id; $this->name = $tmpobj->name; @@ -44,12 +44,13 @@ class Testcategory $this->description = $tmpobj->description; $this->parent_id = $tmpobj->parent_id; $this->parent_path = $this->name; - $this->c_id = $tmpobj->c_id; + $this->c_id = isset($course_id) ? $course_id : $tmpobj->c_id; $this->root = $tmpobj->root; $this->visibility = $tmpobj->visibility; if (!empty($tmpobj->parent_id)) { - $category = new Testcategory($tmpobj->parent_id); + // Default values and the course_id passed. + $category = new Testcategory($tmpobj->parent_id, '', '', 0, 'simple', $course_id); $this->parent_path = $category->parent_path.' > '.$this->name; } } else { diff --git a/main/inc/lib/events.lib.inc.php b/main/inc/lib/events.lib.inc.php index dc29e5903e..d2a926021e 100644 --- a/main/inc/lib/events.lib.inc.php +++ b/main/inc/lib/events.lib.inc.php @@ -493,7 +493,7 @@ function saveQuestionAttempt( } //Validation in case of fraud with active control time - if (!ExerciseLib::exercise_time_control_is_valid($exercise_id, $learnpath_id, $learnpath_item_id)) { + if (!ExerciseLib::exercise_time_control_is_valid($exercise_id, $learnpath_id, $learnpath_item_id, $course_id, $session_id)) { if ($debug) { error_log("exercise_time_control_is_valid is false"); } diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index a916bbd75d..9b0619693a 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -48,16 +48,21 @@ class ExerciseLib /** * Validates the time control key */ - public static function exercise_time_control_is_valid($exercise_id, $lp_id = 0, $lp_item_id = 0) + public static function exercise_time_control_is_valid($exercise_id, $lp_id = 0, $lp_item_id = 0, $course_id = null, $session_id = null) { - $course_id = api_get_course_int_id(); + if (!$course_id) { + $course_id = api_get_course_int_id(); + } + if (!$session_id) { + $session_id = api_get_session_id(); + } $exercise_id = intval($exercise_id); $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); $sql = "SELECT expired_time FROM $TBL_EXERCICES WHERE c_id = $course_id AND iid = $exercise_id"; $result = Database::query($sql); $row = Database::fetch_array($result, 'ASSOC'); if (!empty($row['expired_time'])) { - $current_expired_time_key = ExerciseLib::get_time_control_key($exercise_id, $lp_id, $lp_item_id); + $current_expired_time_key = ExerciseLib::get_time_control_key($exercise_id, $lp_id, $lp_item_id, $course_id, $session_id); if (isset($_SESSION['expired_time'][$current_expired_time_key])) { $current_time = time(); $expired_time = api_strtotime($_SESSION['expired_time'][$current_expired_time_key], 'UTC'); @@ -88,12 +93,18 @@ class ExerciseLib /** Generates the time control key */ - public static function get_time_control_key($exercise_id, $lp_id = 0, $lp_item_id = 0) + public static function get_time_control_key($exercise_id, $lp_id = 0, $lp_item_id = 0, $course_id = null, $session_id = null) { $exercise_id = intval($exercise_id); $lp_id = intval($lp_id); $lp_item_id = intval($lp_item_id); - return api_get_course_int_id().'_'.api_get_session_id().'_'.$exercise_id.'_'.api_get_user_id().'_'.$lp_id.'_'.$lp_item_id; + if (!$course_id) { + $course_id = api_get_course_int_id(); + } + if (!$session_id) { + $session_id = api_get_session_id(); + } + return $course_id.'_'.$session_id.'_'.$exercise_id.'_'.api_get_user_id().'_'.$lp_id.'_'.$lp_item_id; } /** diff --git a/src/ChamiloLMS/Transaction/Envelope.php b/src/ChamiloLMS/Transaction/Envelope.php index d834f38076..658e53b0a8 100644 --- a/src/ChamiloLMS/Transaction/Envelope.php +++ b/src/ChamiloLMS/Transaction/Envelope.php @@ -218,7 +218,11 @@ class Envelope if ($blob === FALSE) { throw new UnwrapException('Invalid blob format passed: Empty content.'); } - $this->transactions = $this->wrapperPlugin->unwrap($blob, $blob_metadata); + $transactions = $this->wrapperPlugin->unwrap($blob, $blob_metadata); + foreach ($transactions as $transaction) { + // @fixme Decouple! + $this->transactions[] = TransactionLogController::createTransaction($transaction->action, (array)$transaction); + } $this->state |= self::STATE_OPEN; } catch (Exception $exception) { diff --git a/src/ChamiloLMS/Transaction/ExerciseAttemptTransactionLog.php b/src/ChamiloLMS/Transaction/ExerciseAttemptTransactionLog.php index 875a8f9f2b..b519b4a5d8 100644 --- a/src/ChamiloLMS/Transaction/ExerciseAttemptTransactionLog.php +++ b/src/ChamiloLMS/Transaction/ExerciseAttemptTransactionLog.php @@ -85,40 +85,40 @@ class ExerciseAttemptTransactionLog extends TransactionLog throw new TransactionImportException('Undefined item_id'); } $attempt_id = $this->item_id; - if (empty($this->data['stat_info'])) { + if (empty($this->data->stat_info)) { throw new TransactionImportException('Undefined exercise stat information.'); } - $stat_info = $this->data['stat_info']; - if (empty($this->data['attempt_info'])) { + $stat_info = $this->data->stat_info; + if (empty($this->data->attempt_info)) { throw new TransactionImportException('Undefined exercise attempt information.'); } - $attempt_info = $this->data['attempt_info']; + $attempt_info = (array)$this->data->attempt_info; // By pass one level which does not provide useful information. $attempt_info = array_shift($attempt_info); // Review consistency of provided information. - if (empty($stat_info['c_id'])) { + if (empty($stat_info->c_id)) { throw new TransactionImportException('Undefined course id on stat information.'); } - $course_id = $stat_info['c_id']; + $course_id = $stat_info->c_id; $course_info = api_get_course_info_by_id($course_id); if (empty($course_info)) { throw new TransactionImportException(sprintf('The included course id "%d" does not currently exist in the database.', $course_id)); } - if (empty($stat_info['exe_exo_id'])) { + if (empty($stat_info->exe_exo_id)) { throw new TransactionImportException('Undefined exercise id on stat information.'); } - $exercise_id = $stat_info['exe_exo_id']; + $exercise_id = $stat_info->exe_exo_id; $exercise = new Exercise($course_id); // Exercise read expects course id set. $exercise->course_id = $course_id; - if (!$exercise->read($exercise_id)) { + if (!$exercise->read($exercise_id, true, $stat_info->session_id)) { throw new TransactionImportException(sprintf('The included exercise id "%d" on course with id "%d" does not currently exist in the database.', $exercise_id, $course_id)); } - if (empty($stat_info['exe_user_id'])) { + if (empty($stat_info->exe_user_id)) { throw new TransactionImportException('Undefined user id on stat information.'); } - $user_id = $stat_info['exe_user_id']; + $user_id = $stat_info->exe_user_id; $user_info = api_get_user_info($user_id); if (!$user_info) { throw new TransactionImportException(sprintf('The included user id "%d" does not currently exist in the database.', $user_id)); @@ -129,17 +129,17 @@ class ExerciseAttemptTransactionLog extends TransactionLog // Process the attempt results. // First, create the exercise attempt to obtain an id in the // destination system. - $question_list = explode(',', $stat_info['data_tracking']); - $imported_exe_id = $exercise->save_stat_track_exercise_info($stat_info['expired_time_control'], $stat_info['orig_lp_id'], $stat_info['orig_lp_item_id'], 0, $question_list, $stat_info['exe_weighting']); + $question_list = explode(',', $stat_info->data_tracking); + $imported_exe_id = $exercise->save_stat_track_exercise_info($stat_info->expired_time_control, $stat_info->orig_lp_id, $stat_info->orig_lp_item_id, 0, $question_list, $stat_info->exe_weighting, $stat_info->session_id); if (!$imported_exe_id) { throw new TransactionImportException(sprintf('Could not create exercise stat information correctly on course with id "%d" for exercise_id "%d"', $course_id, $exercise_id)); } // Then, process the results. - foreach ($attempt_info['question_list'] as $question_id => $attempt_answer_info) { - // Use saveExerciseAttempt($score, $answer, $question_id, $exe_id, $position, $exercise_id = 0, $nano = null, $user_id = null, $course_id = null, $session_id = null, $learnpath_id = null, $learnpath_item_id = null) + foreach ($attempt_info->question_list as $question_id => $attempt_answer_info) { + // Use saveQuestionAttempt($score, $answer, $question_id, $exe_id, $position, $exercise_id = 0, $updateResults = false, $nano = null, $user_id = null, $course_id = null, $session_id = null, $learnpath_id = null, $learnpath_item_id = null) // @fixme What nano means and there to retrieve it? $nano = null; - $attempt_answer_id = saveExerciseAttempt($attempt_answer_info['marks'], $attempt_answer_info['answer'], $question_id, $imported_exe_id, $attempt_answer_info['position'], $exercise_id, $nano, $user_id, $course_id, $stat_info['session_id'], $stat_info['orig_lp_id'], $stat_info['orig_lp_item_id']); + $attempt_answer_id = saveQuestionAttempt($attempt_answer_info->marks, $attempt_answer_info->answer, $question_id, $imported_exe_id, $attempt_answer_info->position, $exercise_id, false, $nano, $user_id, $course_id, $stat_info->session_id, $stat_info->orig_lp_id, $stat_info->orig_lp_item_id); } // Finally return the associated id. diff --git a/src/ChamiloLMS/Transaction/TransactionLogController.php b/src/ChamiloLMS/Transaction/TransactionLogController.php index 886eb0b6f2..77f1368b44 100644 --- a/src/ChamiloLMS/Transaction/TransactionLogController.php +++ b/src/ChamiloLMS/Transaction/TransactionLogController.php @@ -147,6 +147,8 @@ class TransactionLogController { $added_transactions = array(); foreach ($exported_transactions as $exported_transaction) { + // Make sure it's an array. + $exported_transaction = (array) $exported_transaction; // Set the right id in the new system. $exported_transaction['transaction_id'] = $exported_transaction['id']; unset($exported_transaction['id']);