Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitriim committed Nov 23, 2024
1 parent 7a285f6 commit ba32823
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 27 deletions.
12 changes: 4 additions & 8 deletions classes/external/condition_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,13 @@

use context_system;
use moodle_exception;
use external_api;
use external_function_parameters;
use external_single_structure;
use external_value;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use tool_dynamic_cohorts\condition_base;
use tool_dynamic_cohorts\condition_form as form;

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

require_once($CFG->dirroot . '/lib/externallib.php');

/**
* Condition form AJAX submission.
*
Expand Down
10 changes: 3 additions & 7 deletions classes/external/matching_users.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@
namespace tool_dynamic_cohorts\external;

use context_system;
use external_api;
use external_function_parameters;
use external_value;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_value;
use tool_dynamic_cohorts\rule;
use invalid_parameter_exception;
use tool_dynamic_cohorts\rule_manager;

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

require_once($CFG->dirroot . '/lib/externallib.php');

/**
* Matching users external APIs.
*
Expand Down
14 changes: 5 additions & 9 deletions classes/external/rule_conditions.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@
namespace tool_dynamic_cohorts\external;

use context_system;
use external_api;
use external_function_parameters;
use external_value;
use external_multiple_structure;
use external_single_structure;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_value;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use tool_dynamic_cohorts\condition_base;
use tool_dynamic_cohorts\rule;
use invalid_parameter_exception;

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

require_once($CFG->dirroot . '/lib/externallib.php');

/**
* Rule conditions external APIs.
*
Expand Down
156 changes: 156 additions & 0 deletions classes/external/rules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace tool_dynamic_cohorts\external;

use context_system;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_value;
use core_external\external_single_structure;
use Throwable;
use tool_dynamic_cohorts\event\rule_updated;
use tool_dynamic_cohorts\rule;
use invalid_parameter_exception;
use tool_dynamic_cohorts\rule_manager;

/**
* Rules external APIs.
*
* @package tool_dynamic_cohorts
* @copyright 2024 Catalyst IT
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class rules extends external_api {

/**
* Describes the parameters for delete_rule webservice.
*
* @return external_function_parameters
*/
public static function delete_rules_parameters(): external_function_parameters {
return new external_function_parameters(
[
'ruleids' => new external_multiple_structure(new external_value(PARAM_INT, 'Rule IDs'),
'List of rule ids to delete.'),
]
);
}

/**
* Deletes provided rules.
*
* @param array $ruleids Rule IDs.
* @return array
*/
public static function delete_rules(array $ruleids): array {
global $DB;

self::validate_parameters(self::delete_rules_parameters(), ['ruleids' => $ruleids]);

$context = context_system::instance();
self::validate_context($context);
require_capability('tool/dynamic_cohorts:manage', $context);

// We would like to treat deletion for multiple rules as one operation.
// If one failed we would like to fail whole call and roll back.
$transaction = $DB->start_delegated_transaction();
try {
foreach ($ruleids as $ruleid) {
$rule = rule::get_record(['id' => (int) $ruleid]);
if (empty($rule)) {
throw new invalid_parameter_exception('Rule does not exist. ID: ' . $ruleid);
}
rule_manager::delete_rule($rule);
//$transaction->allow_commit();
}
} catch (throwable $ex) {
$transaction->rollback($ex);
}

return [];
}

/**
* Returns description of method result value.
*
* @return external_single_structure
*/
public static function delete_rules_returns(): external_single_structure {
return new external_single_structure([]);
}

/**
* Enable or disable rule.
*
* @return external_function_parameters
*/
public static function toggle_status_parameters(): external_function_parameters {
return new external_function_parameters([
'ruleid' => new external_value(PARAM_INT, 'The rule ID to toggle'),
]);
}

/**
* Toggle rule.
*
* @param int $ruleid Rule ID.
* @return array
*/
public static function toggle_status(int $ruleid): array {
self::validate_parameters(self::delete_rules_parameters(), ['ruleid' => $ruleid]);

self::validate_context(context_system::instance());
require_capability('tool/dynamic_cohorts:manage', context_system::instance());

$rule = rule::get_record(['id' => $ruleid]);
if (empty($rule)) {
throw new invalid_parameter_exception('Rule does not exist.');
}

if ($rule->is_broken()) {
// Disable broken rule
$rule->set('enabled', 0);
$rule->save();
rule_updated::create(['other' => ['ruleid' => $rule->get('id')]])->trigger();

throw new invalid_parameter_exception('A broken rule can\'t be enabled');
}

$newvalue = (int) !$rule->is_enabled();
$rule->set('enabled', $newvalue);
$rule->save();
rule_updated::create(['other' => ['ruleid' => $rule->get('id')]])->trigger();

return [
'ruleid' => $rule->get('id'),
'enabled' => $newvalue,
];
}

/**
* Returns description of method result value.
*
* @return external_single_structure
*/
public static function toggle_status_returns(): external_single_structure {
return new external_single_structure([
'ruleid' => new external_value(PARAM_INT, 'The rule ID'),
'enabled' => new external_value(PARAM_INT, 'New status for the rule'),
]);
}
}
16 changes: 16 additions & 0 deletions db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,20 @@
'capabilities' => 'tool/dynamic_cohorts:manage',
'ajax' => true,
],
'tool_dynamic_cohorts_delete_rules' => [
'classname' => 'tool_dynamic_cohorts\external\rules',
'methodname' => 'delete_rules',
'description' => 'Delete provided rules',
'type' => 'write',
'capabilities' => 'tool/dynamic_cohorts:manage',
'ajax' => true,
],
'tool_dynamic_cohorts_toggle_rule_status' => [
'classname' => 'tool_dynamic_cohorts\external\rules',
'methodname' => 'toggle_status',
'description' => 'Toggles status for given rule (disable or enable)',
'type' => 'write',
'capabilities' => 'tool/dynamic_cohorts:manage',
'ajax' => true,
],
];
1 change: 0 additions & 1 deletion tests/external/matching_users_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
* @copyright 2024 Catalyst IT
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @runTestsInSeparateProcesses
* @covers \tool_dynamic_cohorts\external\matching_users
*/
class matching_users_test extends externallib_advanced_testcase {
Expand Down
3 changes: 1 addition & 2 deletions tests/external/rule_conditions_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@
* @package tool_dynamic_cohorts
* @copyright 2024 Catalyst IT
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @runTestsInSeparateProcesses
*
* @covers \tool_dynamic_cohorts\external\rule_conditions
*/
class rule_conditions_test extends externallib_advanced_testcase {
Expand Down
109 changes: 109 additions & 0 deletions tests/external/rules_test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace tool_dynamic_cohorts\external;

use externallib_advanced_testcase;
use tool_dynamic_cohorts\rule;

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

global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');

/**
* Tests for matching users external APIs .
*
* @package tool_dynamic_cohorts
* @copyright 2024 Catalyst IT
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @covers \tool_dynamic_cohorts\external\rules
*/
class rules_test extends externallib_advanced_testcase {

/**
* Test exception if rule is not exist.
*/
public function test_delete_rules_exception_on_invalid_rule() {
$this->resetAfterTest();

$this->setAdminUser();
$this->expectException(\invalid_parameter_exception::class);
$this->expectExceptionMessage('Rule does not exist. ID: 777');

rules::delete_rules([777]);
}

/**
* Test required permissions.
*/
public function test_delete_rules_permissions() {
$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);

$this->expectException(\required_capability_exception::class);
$this->expectExceptionMessage('Sorry, but you do not currently have permissions to do that (Manage rules).');

rules::delete_rules([777]);
}

/**
* Test can get total.
*/
public function test_exception_delete_rules_when_one_is_invalid() {
$this->resetAfterTest();
$this->setAdminUser();

$rule = new rule(0, (object)['name' => 'Test rule 1']);
$rule->save();

$this->expectException(\invalid_parameter_exception::class);
$this->expectExceptionMessage('Rule does not exist. ID: 777');

rules::delete_rules([$rule->get('id'), 777]);
}

/**
* Test can get total.
*/
public function test_delete_rules_keep_rules_when_one_is_invalid() {
$this->resetAfterTest();
$this->setAdminUser();

$rule1 = new rule(0, (object)['name' => 'Test rule 1']);
$rule1->save();

$rule2 = new rule(0, (object)['name' => 'Test rule 2']);
$rule2->save();

$this->assertCount(2, rule::get_records());

$this->expectException(\required_capability_exception::class);
$this->expectExceptionMessage('Rule does not exist. ID: 777');

try {
rules::delete_rules([$rule1->get('id'), $rule2->get('id'), 777]);
} catch (\invalid_parameter_exception $exception) {
$this->assertSame(
'Invalid parameter value detected (Rule does not exist. ID: 777)',
$exception->getMessage()
);
$this->assertCount(2, rule::get_records());
}
}
}

0 comments on commit ba32823

Please sign in to comment.