Skip to content

Commit

Permalink
MDL-82130 gradepenalty_duedate: Update exemptions API
Browse files Browse the repository at this point in the history
  • Loading branch information
Fragonite committed Aug 26, 2024
1 parent ae9c39b commit 5aed158
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 54 deletions.
3 changes: 2 additions & 1 deletion exemptions/classes/local/repository/exemption_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,13 @@ protected function validate(exemption $exemption) {
* @throws \moodle_exception if the exemption has missing or invalid properties.
*/
public function add(exemption $exemption): exemption {
global $DB;
global $DB, $USER;
$this->validate($exemption);
$exemption = (array)$exemption;
$time = time();
$exemption['timecreated'] = $time;
$exemption['timemodified'] = $time;
$exemption['usermodified'] = $USER->id;
$id = $DB->insert_record($this->exemptiontable, $exemption);
return $this->find($id);
}
Expand Down
157 changes: 110 additions & 47 deletions exemptions/classes/local/service/component_exemption_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,33 +61,17 @@ public function __construct(string $component, exemption_repository_interface $r
$this->component = $component;
}


/**
* Delete a collection of exemptions by type and item, and optionally for a given context.
*
* E.g. delete all exemptions of type 'message_conversations' for the conversation '11' and in the CONTEXT_COURSE context.
*
* @param string $itemtype the type of the exempt items.
* @param int $itemid the id of the item to which the exemptions relate
* @param \context|null $context the context of the items which were exempt.
*/
public function delete_exemptions_by_type_and_item(string $itemtype, int $itemid, ?\context $context = null) {
$criteria = ['component' => $this->component, 'itemtype' => $itemtype, 'itemid' => $itemid] +
($context ? ['contextid' => $context->id] : []);
$this->repo->delete_by($criteria);
}

/**
* Exempt an item defined by itemid/context, in the area defined by component/itemtype.
*
* @param string $itemtype the type of the item being exempt.
* @param int $itemid the id of the item which is to be exempt.
* @param \context $context the context in which the item is to be exempt.
* @param int $contextid the context where the item is to be exempt.
* @param array $options optional parameters including 'reason', 'reasonformat', 'ordering', and 'usermodified'.
* @return exemption the exemption, once created.
* @throws \moodle_exception if the component name is invalid, or if the repository encounters any errors.
*/
public function create_exemption(string $itemtype, int $itemid, \context $context, array $options = []): exemption {
public function create_exemption(string $itemtype, int $itemid, int $contextid, array $options = []): exemption {
// Access: Any component can ask to exempt something, we can't verify access to that 'something' here though.

// Validate the component name.
Expand All @@ -101,11 +85,115 @@ public function create_exemption(string $itemtype, int $itemid, \context $contex
$ordering = $options['ordering'] ?? null;
$usermodified = $options['usermodified'] ?? null;

$exemption = new exemption($this->component, $itemtype, $itemid, $context->id, $reason, $reasonformat, $usermodified);
$exemption = new exemption($this->component, $itemtype, $itemid, $contextid, $reason, $reasonformat, $usermodified);
$exemption->ordering = $ordering > 0 ? $ordering : null;
return $this->repo->add($exemption);
}

/**
* Update an exemption item from an area and from within a context.
*
* @param exemption $exemption The exemption to update.
* @return exemption
*/
public function update_exemption(exemption $exemption): exemption {
return $this->repo->update($exemption);
}

/**
* Delete an exemption item from an area and from within a context.
*
* @param string $itemtype the type of the exempt item.
* @param int $itemid the id of the item which was exempt (not the exemption's id).
* @param int $contextid the context of the item which was exempt.
* @throws \dml_exception if any database errors are encountered.
*/
public function delete_exemption(string $itemtype, int $itemid, int $contextid) {
$params = [
'component' => $this->component,
'itemtype' => $itemtype,
'itemid' => $itemid,
'contextid' => $contextid,
];

$this->repo->delete_by($params);
}

/**
* Delete an exemption by id.
*
* @param int $id the id of the exemption to delete.
*/
public function delete_exemption_by_id(int $id) {
$this->repo->delete($id);
}

/**
* Find an exemption by id.
*
* @param int $id the id of the exemption to find.
* @return exemption|null
*/
public function find_exemption_by_id(int $id): ?exemption {
try {
return $this->repo->find($id);
} catch (\dml_missing_record_exception $e) {
return null;
}
}

/**
* Delete a collection of exemptions by type and item, and optionally for a given context.
*
* E.g. delete all exemptions of type 'message_conversations' for the conversation '11' and in the CONTEXT_COURSE context.
*
* @param string $itemtype the type of the exempt items.
* @param int $itemid the id of the item to which the exemptions relate
* @param \context|null $context the context of the items which were exempt.
*/
public function delete_exemptions_by_type_and_item(string $itemtype, int $itemid, ?\context $context = null) {
$criteria = ['component' => $this->component, 'itemtype' => $itemtype, 'itemid' => $itemid] +
($context ? ['contextid' => $context->id] : []);
$this->repo->delete_by($criteria);
}

/**
* Find a list of exemptions, by type and item, and optionally for a given context.
*
* @param string $itemtype the type of the exempt item.
* @param int $itemid the id of the item which was exempt (not the exemption's id).
* @param \context|null $context the context of the item which was exempt.
*
* @return array the list of exemptions found.
* @throws \moodle_exception if the component name is invalid, or if the repository encounters any errors.
*/
public function find_exemptions_by_type_and_item(string $itemtype, int $itemid, ?\context $context = null): array {
$criteria = [
'component' => $this->component,
'itemtype' => $itemtype,
'itemid' => $itemid,
];

if ($context) {
$criteria['contextid'] = $context->id;
}

return $this->repo->find_by($criteria);
}

/**
* Find a list of exemptions, by type and item, and optionally for a given context.
*
* @param array $options the options to filter the exemptions by, including 'itemtype', 'itemid' and 'contextid'.
*
* @return array the list of exemptions found.
* @throws \moodle_exception if the repository encounters any errors.
*/
public function find_exemptions(array $options): array {
$options['component'] = $this->component;
return $this->repo->find_by($options);
}

/**
* Find a list of exemptions, by type, where type is the component/itemtype pair.
*
Expand Down Expand Up @@ -204,31 +292,6 @@ public function get_join_sql_by_type(string $itemtype, string $tablealias, strin
return [$sql, $params];
}

/**
* Delete an exemption item from an area and from within a context.
*
* E.g. delete an exemption course from the area 'core_course', 'course' with itemid 3 and from within the CONTEXT_USER context.
*
* @param string $itemtype the type of the exempt item.
* @param int $itemid the id of the item which was exempt (not the exemption's id).
* @param \context $context the context of the item which was exempt.
* @throws \moodle_exception if the user does not control the exemption, or it doesn't exist.
*/
public function delete_exemption(string $itemtype, int $itemid, \context $context) {
if (!in_array($this->component, \core_component::get_component_names())) {
throw new \moodle_exception("Invalid component name '$this->component'");
}

// Business logic: check the user owns the exemption.
try {
$exemption = $this->repo->find_exemption($this->component, $itemtype, $itemid, $context->id);
} catch (\moodle_exception $e) {
throw new \moodle_exception("exemption does not exist for the user. Cannot delete.");
}

$this->repo->delete($exemption->id);
}

/**
* Check whether an item has been marked as an exemption in the respective area.
*
Expand All @@ -253,16 +316,16 @@ public function exemption_exists(string $itemtype, int $itemid, \context $contex
*
* @param string $itemtype the type of the exempt item.
* @param int $itemid the id of the item which was exempt (not the exemption's id).
* @param \context $context the context of the item which was exempt.
* @param int $contextid the context id of the item which was exempt.
* @return exemption|null
*/
public function get_exemption(string $itemtype, int $itemid, \context $context) {
public function get_exemption(string $itemtype, int $itemid, int $contextid) {
try {
return $this->repo->find_exemption(
$this->component,
$itemtype,
$itemid,
$context->id
$contextid
);
} catch (\dml_missing_record_exception $e) {
return null;
Expand Down
9 changes: 4 additions & 5 deletions lib/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2024080500.00);
}

if ($oldversion < 2024081000.01) {
if ($oldversion < 2024082300.01) {
$table = new xmldb_table('exemption');

// Adding fields to table exemption.
Expand All @@ -1265,13 +1265,12 @@ function xmldb_main_upgrade($oldversion) {
$table->add_index('uniqueuserexemptionitem', XMLDB_INDEX_UNIQUE, ['component', 'itemtype', 'itemid', 'contextid']);

// Conditionally launch create table for exemption.
if ($dbman->table_exists($table)) {
$dbman->drop_table($table);
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
$dbman->create_table($table);

// Main savepoint reached.
upgrade_main_savepoint(true, 2024081000.01);
upgrade_main_savepoint(true, 2024082300.01);
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

defined('MOODLE_INTERNAL') || die();

$version = 2024082300.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2024082300.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.5dev+ (Build: 20240823)'; // Human-friendly version name
Expand Down

0 comments on commit 5aed158

Please sign in to comment.