Skip to content

Commit

Permalink
refactor code
Browse files Browse the repository at this point in the history
- a lot more code now uses the repository pattern
- added tests for lib.php
  • Loading branch information
Glutamat42 committed May 11, 2024
1 parent 579825e commit fac7142
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 91 deletions.
41 changes: 25 additions & 16 deletions backup/moodle2/restore_adleradaptivity_stepslib.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
<?php

use mod_adleradaptivity\local\db\adleradaptivity_attempt_repository;
use mod_adleradaptivity\local\db\adleradaptivity_question_repository;
use mod_adleradaptivity\local\db\adleradaptivity_repository;
use mod_adleradaptivity\local\db\adleradaptivity_task_repository;
use mod_adleradaptivity\local\db\moodle_core_repository;

/**
* Structure step to restore one adleradaptivity activity
*/
class restore_adleradaptivity_activity_structure_step extends restore_questions_activity_structure_step {

private adleradaptivity_repository $adleradaptivity_repository;
private adleradaptivity_task_repository $adleradaptivity_task_repository;
private adleradaptivity_question_repository $adleradaptivity_question_repository;
private adleradaptivity_attempt_repository $adleradaptivity_attempt_repository;
private moodle_core_repository $moodle_core_repository;
private ?object $current_adleradaptivity_attempt;

public function __construct(...$args) {
parent::__construct(...$args);
$this->adleradaptivity_repository = new adleradaptivity_repository();
$this->adleradaptivity_task_repository = new adleradaptivity_task_repository();
$this->adleradaptivity_question_repository = new adleradaptivity_question_repository();
$this->adleradaptivity_attempt_repository = new adleradaptivity_attempt_repository();
$this->moodle_core_repository = new moodle_core_repository();
}

protected function define_structure() {
$paths = [];
$userinfo = $this->get_setting_value('userinfo');
Expand All @@ -33,8 +52,6 @@ protected function define_structure() {
}

protected function process_adleradaptivity($data) {
global $DB;

$data = (object)$data;
$data->course = $this->get_courseid();

Expand All @@ -44,32 +61,27 @@ protected function process_adleradaptivity($data) {
}

// insert the adleradaptivity record
$newitemid = $DB->insert_record('adleradaptivity', $data);
$newitemid = $this->adleradaptivity_repository->create_adleradaptivity($data);
// immediately after inserting "activity" record, call this
$this->apply_activity_instance($newitemid);
}

protected function process_task($data) {
global $DB;

$data = (object)$data;
$oldid = $data->id;

$data->adleradaptivity_id = $this->get_new_parentid('adleradaptivity');

$newitemid = $DB->insert_record('adleradaptivity_tasks', $data);
$newitemid = $this->adleradaptivity_task_repository->create_task($data);
$this->set_mapping('task', $oldid, $newitemid);
}

protected function process_question($data) {
global $DB;

$data = (object)$data;

$data->adleradaptivity_task_id = $this->get_new_parentid("task");


$newitemid = $DB->insert_record('adleradaptivity_questions', $data);
$newitemid = $this->adleradaptivity_question_repository->create_question($data);
$this->set_mapping('question', $data->id, $newitemid);
}

Expand All @@ -81,14 +93,13 @@ protected function process_question($data) {
* @param array $data the data from the XML file.
*/
public function process_question_reference($data) {
global $DB;
$data = (object)$data;
$data->usingcontextid = $this->get_mappingid('context', $data->usingcontextid);
$data->itemid = $this->get_new_parentid('question');
if ($entry = $this->get_mappingid('question_bank_entry', $data->questionbankentryid)) {
$data->questionbankentryid = $entry;
}
$DB->insert_record('question_references', $data);
$this->moodle_core_repository->create_question_reference($data);
}

protected function after_execute() {
Expand Down Expand Up @@ -119,8 +130,6 @@ protected function process_adleradaptivity_attempt($data) {
* @param int $newusageid the id of the newly created question usage.
*/
protected function inform_new_usage_id($newusageid) {
global $DB;

$data = $this->current_adleradaptivity_attempt;
if ($data === null) {
return;
Expand All @@ -129,7 +138,7 @@ protected function inform_new_usage_id($newusageid) {
$oldid = $data->id;
$data->attempt_id = $newusageid;

$newitemid = $DB->insert_record('adleradaptivity_attempts', $data);
$newitemid = $this->adleradaptivity_attempt_repository->create_adleradaptivity_attempt($data);

// Save adleradaptivity attempt id mapping
$this->set_mapping('adleradaptivity', $oldid, $newitemid);
Expand Down
34 changes: 33 additions & 1 deletion classes/local/db/adleradaptivity_attempt_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

namespace mod_adleradaptivity\local\db;

use context_module;
use dml_exception;
use moodle_database;
use dml_missing_record_exception;
use stdClass;

class adleradaptivity_attempt_repository extends base_repository {
Expand All @@ -18,6 +19,13 @@ public function get_adleradaptivity_attempt_by_quba_id(int $attempt_id): stdClas
return $this->db->get_record('adleradaptivity_attempts', ['attempt_id' => $attempt_id], '*', MUST_EXIST);
}

/**
* @throws dml_exception
*/
public function delete_adleradaptivity_attempt_by_question_usage_id(int $question_usage_id): bool {
return $this->db->delete_records('adleradaptivity_attempts', ['attempt_id' => $question_usage_id]);
}

/**
* Create adleradaptivity_attempt in database
*
Expand All @@ -28,4 +36,28 @@ public function get_adleradaptivity_attempt_by_quba_id(int $attempt_id): stdClas
public function create_adleradaptivity_attempt(stdClass $adleradaptivity_attempt): int {
return $this->db->insert_record('adleradaptivity_attempts', $adleradaptivity_attempt);
}

/** Load adleradaptivity_attempts by cmid
* - Get context by cmid
* - with the context id get the question_usage
* - question_usage and adleradaptivity_attempts are a 1:1 relation
*
* @param int $cmid The course module ID of the adleradaptivity element.
* @return array adleradaptivity_attempt The question usage object.
* @throws dml_exception
* @throws dml_missing_record_exception If the expected records are not found.
*/
public function get_adleradaptivity_attempt_by_cmid($cmid) {
// Get the context for the provided course module ID.
$modulecontext = context_module::instance($cmid);

// Create SQL to join adleradaptivity_attempts with question_usages based on context ID
$sql = "
SELECT aa.*
FROM {adleradaptivity_attempts} AS aa
JOIN {question_usages} AS qu ON qu.id = aa.attempt_id
WHERE qu.contextid = ?
";
return $this->db->get_records_sql($sql, [$modulecontext->id]);
}
}
14 changes: 14 additions & 0 deletions classes/local/db/adleradaptivity_question_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
use stdClass;

class adleradaptivity_question_repository extends base_repository {
/**
* @throws dml_exception
*/
public function create_question(stdClass $question): bool|int {
return $this->db->insert_record('adleradaptivity_questions', $question);
}

/**
* @throws dml_exception
*/
public function delete_question_by_id(int $question_id): bool {
return $this->db->delete_records('adleradaptivity_questions', ['id' => $question_id]);
}

/**
* Get adleradaptivity question by question_bank_entries_id
*
Expand Down
20 changes: 20 additions & 0 deletions classes/local/db/adleradaptivity_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,27 @@

namespace mod_adleradaptivity\local\db;

use dml_exception;
use stdClass;

class adleradaptivity_repository extends base_repository {
/**
* @throws dml_exception
*/
public function create_adleradaptivity(stdClass $module_instance): bool|int {
return $this->db->insert_record('adleradaptivity', $module_instance);
}

/**
* @throws dml_exception
*/
public function delete_adleradaptivity_by_id(int $instance_id): bool {
return $this->db->delete_records('adleradaptivity', ['id' => $instance_id]);
}

/**
* @throws dml_exception
*/
public function get_instance_by_instance_id(int $instance_id) {
return $this->db->get_record('adleradaptivity', ['id' => $instance_id], '*', MUST_EXIST);
}
Expand Down
22 changes: 22 additions & 0 deletions classes/local/db/adleradaptivity_task_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,26 @@

namespace mod_adleradaptivity\local\db;

use dml_exception;
use moodle_database;
use moodle_exception;
use stdClass;

class adleradaptivity_task_repository extends base_repository {
/**
* @throws dml_exception
*/
public function create_task(stdClass $task): bool|int {
return $this->db->insert_record('adleradaptivity_tasks', $task);
}

/**
* @throws dml_exception
*/
public function delete_task_by_id(int $task_id): bool {
return $this->db->delete_records('adleradaptivity_tasks', ['id' => $task_id]);
}

/**
* Get task by question uuid
*
Expand Down Expand Up @@ -41,4 +56,11 @@ public function get_task_by_question_uuid($question_uuid, $instance_id) {
MUST_EXIST
);
}

/**
* @throws dml_exception
*/
public function get_tasks_by_adleradaptivity_id($adleradaptivity_instance_id): array {
return $this->db->get_records('adleradaptivity_tasks', ['adleradaptivity_id' => $adleradaptivity_instance_id]);
}
}
41 changes: 41 additions & 0 deletions classes/local/db/moodle_core_repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace mod_adleradaptivity\local\db;

use dml_exception;
use dml_missing_record_exception;
use stdClass;

class moodle_core_repository extends base_repository {
public function create_question_reference(stdClass $question_reference): int {
return $this->db->insert_record('question_references', $question_reference);
}

/**
* Retrieves the course module ID (cmid) for a given question usage ID.
*
* @param int $quid The ID of the question usage.
* @return int The course module ID (cmid) associated with the question usage.
* @throws dml_exception If there's an error with the database query.
* @throws dml_missing_record_exception If the expected records are not found.
*/
public function get_cmid_by_question_usage_id(int $quid): int {
// First, retrieve the contextid from the question_usages table using the question usage ID
$contextid = $this->db->get_field('question_usages', 'contextid', ['id' => $quid], MUST_EXIST);

if (!$contextid) {
throw new dml_missing_record_exception('context not found for the provided question usage ID');
}

// Now, use the contextid to find the corresponding cmid in the context table
// Note: CONTEXT_MODULE is a constant equal to 80, representing the context level for course modules in Moodle.
// instance id refers to the instance of the context level. For CONTEXT_MODULE, this is the course module ID.
$cmid = $this->db->get_field_select('context', 'instanceid', "contextlevel = ? AND id = ?", [CONTEXT_MODULE, $contextid]);

if (!$cmid) {
throw new dml_missing_record_exception('course module (cmid) not found for the provided context ID');
}

return $cmid;
}
}
62 changes: 4 additions & 58 deletions classes/local/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace mod_adleradaptivity\local;

global $CFG;
require_once($CFG->libdir . '/questionlib.php');

use context_module;
use dml_exception;
use dml_missing_record_exception;
use mod_adleradaptivity\local\db\adleradaptivity_attempt_repository;
use moodle_exception;
use question_bank;
Expand All @@ -15,61 +15,6 @@
use stdClass;

class helpers {
/** Load adleradaptivity_attempts by cmid
* - Get context by cmid
* - with the context id get the question_usage
* - question_usage and adleradaptivity_attempts are a 1:1 relation
*
* @param int $cmid The course module ID of the adleradaptivity element.
* @return array adleradaptivity_attempt The question usage object.
* @throws dml_exception
* @throws dml_missing_record_exception If the expected records are not found.
*/
public static function load_adleradaptivity_attempt_by_cmid($cmid) {
global $DB;

// Get the context for the provided course module ID.
$modulecontext = context_module::instance($cmid);

// Create SQL to join adleradaptivity_attempts with question_usages based on context ID
$sql = "
SELECT aa.*
FROM {adleradaptivity_attempts} AS aa
JOIN {question_usages} AS qu ON qu.id = aa.attempt_id
WHERE qu.contextid = ?
";
return $DB->get_records_sql($sql, [$modulecontext->id]);
}

/**
* Retrieves the course module ID (cmid) for a given question usage ID.
*
* @param int $quid The ID of the question usage.
* @return int The course module ID (cmid) associated with the question usage.
* @throws dml_exception If there's an error with the database query.
* @throws dml_missing_record_exception If the expected records are not found.
*/
public static function get_cmid_for_question_usage($quid) {
global $DB;

// First, retrieve the contextid from the question_usages table using the question usage ID
$contextid = $DB->get_field('question_usages', 'contextid', ['id' => $quid], MUST_EXIST);

if (!$contextid) {
throw new dml_missing_record_exception('context not found for the provided question usage ID');
}

// Now, use the contextid to find the corresponding cmid in the context table
// Note: CONTEXT_MODULE is a constant equal to 80, representing the context level for course modules in Moodle.
$cmid = $DB->get_field_select('context', 'instanceid', "contextlevel = ? AND id = ?", [CONTEXT_MODULE, $contextid]);

if (!$cmid) {
throw new dml_missing_record_exception('course module (cmid) not found for the provided context ID');
}

return $cmid;
}

/** Gets the attempt object (question usage aka $quba) for the given cm and given user.
* If there is no attempt object for the given cm and user, a new attempt object is created.
* If there is more than one attempt object for the given cm and user, an exception is thrown.
Expand All @@ -82,14 +27,15 @@ public static function get_cmid_for_question_usage($quid) {
* @throws moodle_exception If multiple question usages are found for the given criteria.
*/
public static function load_or_create_question_usage(int $cmid, int|null $userid = null, bool $create_new_attempt = true): false|question_usage_by_activity {
global $DB, $USER;
global $USER;
$adleradaptivity_attempt_repository = new adleradaptivity_attempt_repository();

if (!isset($userid)) {
$userid = $USER->id;
}

// Fetch existing question usages for the given cmid and userid
$adleradaptivity_attempts_all_users = static::load_adleradaptivity_attempt_by_cmid($cmid);
$adleradaptivity_attempts_all_users = $adleradaptivity_attempt_repository->get_adleradaptivity_attempt_by_cmid($cmid);
// filter the results by userid
$adleradaptivity_attempts = array_filter($adleradaptivity_attempts_all_users, function ($attempt) use ($userid) {
return $attempt->user_id == $userid;
Expand Down
Loading

0 comments on commit fac7142

Please sign in to comment.