Skip to content

Commit ba32823

Browse files
committed
WIP
1 parent 7a285f6 commit ba32823

8 files changed

+294
-27
lines changed

classes/external/condition_form.php

+4-8
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@
1818

1919
use context_system;
2020
use moodle_exception;
21-
use external_api;
22-
use external_function_parameters;
23-
use external_single_structure;
24-
use external_value;
21+
use core_external\external_api;
22+
use core_external\external_function_parameters;
23+
use core_external\external_single_structure;
24+
use core_external\external_value;
2525
use tool_dynamic_cohorts\condition_base;
2626
use tool_dynamic_cohorts\condition_form as form;
2727

28-
defined('MOODLE_INTERNAL') || die();
29-
30-
require_once($CFG->dirroot . '/lib/externallib.php');
31-
3228
/**
3329
* Condition form AJAX submission.
3430
*

classes/external/matching_users.php

+3-7
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,13 @@
1717
namespace tool_dynamic_cohorts\external;
1818

1919
use context_system;
20-
use external_api;
21-
use external_function_parameters;
22-
use external_value;
20+
use core_external\external_api;
21+
use core_external\external_function_parameters;
22+
use core_external\external_value;
2323
use tool_dynamic_cohorts\rule;
2424
use invalid_parameter_exception;
2525
use tool_dynamic_cohorts\rule_manager;
2626

27-
defined('MOODLE_INTERNAL') || die();
28-
29-
require_once($CFG->dirroot . '/lib/externallib.php');
30-
3127
/**
3228
* Matching users external APIs.
3329
*

classes/external/rule_conditions.php

+5-9
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,15 @@
1717
namespace tool_dynamic_cohorts\external;
1818

1919
use context_system;
20-
use external_api;
21-
use external_function_parameters;
22-
use external_value;
23-
use external_multiple_structure;
24-
use external_single_structure;
20+
use core_external\external_api;
21+
use core_external\external_function_parameters;
22+
use core_external\external_value;
23+
use core_external\external_multiple_structure;
24+
use core_external\external_single_structure;
2525
use tool_dynamic_cohorts\condition_base;
2626
use tool_dynamic_cohorts\rule;
2727
use invalid_parameter_exception;
2828

29-
defined('MOODLE_INTERNAL') || die();
30-
31-
require_once($CFG->dirroot . '/lib/externallib.php');
32-
3329
/**
3430
* Rule conditions external APIs.
3531
*

classes/external/rules.php

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<?php
2+
// This file is part of Moodle - https://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
16+
17+
namespace tool_dynamic_cohorts\external;
18+
19+
use context_system;
20+
use core_external\external_api;
21+
use core_external\external_function_parameters;
22+
use core_external\external_multiple_structure;
23+
use core_external\external_value;
24+
use core_external\external_single_structure;
25+
use Throwable;
26+
use tool_dynamic_cohorts\event\rule_updated;
27+
use tool_dynamic_cohorts\rule;
28+
use invalid_parameter_exception;
29+
use tool_dynamic_cohorts\rule_manager;
30+
31+
/**
32+
* Rules external APIs.
33+
*
34+
* @package tool_dynamic_cohorts
35+
* @copyright 2024 Catalyst IT
36+
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37+
*/
38+
class rules extends external_api {
39+
40+
/**
41+
* Describes the parameters for delete_rule webservice.
42+
*
43+
* @return external_function_parameters
44+
*/
45+
public static function delete_rules_parameters(): external_function_parameters {
46+
return new external_function_parameters(
47+
[
48+
'ruleids' => new external_multiple_structure(new external_value(PARAM_INT, 'Rule IDs'),
49+
'List of rule ids to delete.'),
50+
]
51+
);
52+
}
53+
54+
/**
55+
* Deletes provided rules.
56+
*
57+
* @param array $ruleids Rule IDs.
58+
* @return array
59+
*/
60+
public static function delete_rules(array $ruleids): array {
61+
global $DB;
62+
63+
self::validate_parameters(self::delete_rules_parameters(), ['ruleids' => $ruleids]);
64+
65+
$context = context_system::instance();
66+
self::validate_context($context);
67+
require_capability('tool/dynamic_cohorts:manage', $context);
68+
69+
// We would like to treat deletion for multiple rules as one operation.
70+
// If one failed we would like to fail whole call and roll back.
71+
$transaction = $DB->start_delegated_transaction();
72+
try {
73+
foreach ($ruleids as $ruleid) {
74+
$rule = rule::get_record(['id' => (int) $ruleid]);
75+
if (empty($rule)) {
76+
throw new invalid_parameter_exception('Rule does not exist. ID: ' . $ruleid);
77+
}
78+
rule_manager::delete_rule($rule);
79+
//$transaction->allow_commit();
80+
}
81+
} catch (throwable $ex) {
82+
$transaction->rollback($ex);
83+
}
84+
85+
return [];
86+
}
87+
88+
/**
89+
* Returns description of method result value.
90+
*
91+
* @return external_single_structure
92+
*/
93+
public static function delete_rules_returns(): external_single_structure {
94+
return new external_single_structure([]);
95+
}
96+
97+
/**
98+
* Enable or disable rule.
99+
*
100+
* @return external_function_parameters
101+
*/
102+
public static function toggle_status_parameters(): external_function_parameters {
103+
return new external_function_parameters([
104+
'ruleid' => new external_value(PARAM_INT, 'The rule ID to toggle'),
105+
]);
106+
}
107+
108+
/**
109+
* Toggle rule.
110+
*
111+
* @param int $ruleid Rule ID.
112+
* @return array
113+
*/
114+
public static function toggle_status(int $ruleid): array {
115+
self::validate_parameters(self::delete_rules_parameters(), ['ruleid' => $ruleid]);
116+
117+
self::validate_context(context_system::instance());
118+
require_capability('tool/dynamic_cohorts:manage', context_system::instance());
119+
120+
$rule = rule::get_record(['id' => $ruleid]);
121+
if (empty($rule)) {
122+
throw new invalid_parameter_exception('Rule does not exist.');
123+
}
124+
125+
if ($rule->is_broken()) {
126+
// Disable broken rule
127+
$rule->set('enabled', 0);
128+
$rule->save();
129+
rule_updated::create(['other' => ['ruleid' => $rule->get('id')]])->trigger();
130+
131+
throw new invalid_parameter_exception('A broken rule can\'t be enabled');
132+
}
133+
134+
$newvalue = (int) !$rule->is_enabled();
135+
$rule->set('enabled', $newvalue);
136+
$rule->save();
137+
rule_updated::create(['other' => ['ruleid' => $rule->get('id')]])->trigger();
138+
139+
return [
140+
'ruleid' => $rule->get('id'),
141+
'enabled' => $newvalue,
142+
];
143+
}
144+
145+
/**
146+
* Returns description of method result value.
147+
*
148+
* @return external_single_structure
149+
*/
150+
public static function toggle_status_returns(): external_single_structure {
151+
return new external_single_structure([
152+
'ruleid' => new external_value(PARAM_INT, 'The rule ID'),
153+
'enabled' => new external_value(PARAM_INT, 'New status for the rule'),
154+
]);
155+
}
156+
}

db/services.php

+16
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,20 @@
4949
'capabilities' => 'tool/dynamic_cohorts:manage',
5050
'ajax' => true,
5151
],
52+
'tool_dynamic_cohorts_delete_rules' => [
53+
'classname' => 'tool_dynamic_cohorts\external\rules',
54+
'methodname' => 'delete_rules',
55+
'description' => 'Delete provided rules',
56+
'type' => 'write',
57+
'capabilities' => 'tool/dynamic_cohorts:manage',
58+
'ajax' => true,
59+
],
60+
'tool_dynamic_cohorts_toggle_rule_status' => [
61+
'classname' => 'tool_dynamic_cohorts\external\rules',
62+
'methodname' => 'toggle_status',
63+
'description' => 'Toggles status for given rule (disable or enable)',
64+
'type' => 'write',
65+
'capabilities' => 'tool/dynamic_cohorts:manage',
66+
'ajax' => true,
67+
],
5268
];

tests/external/matching_users_test.php

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
* @copyright 2024 Catalyst IT
3333
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
3434
*
35-
* @runTestsInSeparateProcesses
3635
* @covers \tool_dynamic_cohorts\external\matching_users
3736
*/
3837
class matching_users_test extends externallib_advanced_testcase {

tests/external/rule_conditions_test.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@
3333
* @package tool_dynamic_cohorts
3434
* @copyright 2024 Catalyst IT
3535
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36-
37-
* @runTestsInSeparateProcesses
36+
*
3837
* @covers \tool_dynamic_cohorts\external\rule_conditions
3938
*/
4039
class rule_conditions_test extends externallib_advanced_testcase {

tests/external/rules_test.php

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
// This file is part of Moodle - https://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
16+
17+
namespace tool_dynamic_cohorts\external;
18+
19+
use externallib_advanced_testcase;
20+
use tool_dynamic_cohorts\rule;
21+
22+
defined('MOODLE_INTERNAL') || die();
23+
24+
global $CFG;
25+
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
26+
27+
/**
28+
* Tests for matching users external APIs .
29+
*
30+
* @package tool_dynamic_cohorts
31+
* @copyright 2024 Catalyst IT
32+
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33+
*
34+
* @covers \tool_dynamic_cohorts\external\rules
35+
*/
36+
class rules_test extends externallib_advanced_testcase {
37+
38+
/**
39+
* Test exception if rule is not exist.
40+
*/
41+
public function test_delete_rules_exception_on_invalid_rule() {
42+
$this->resetAfterTest();
43+
44+
$this->setAdminUser();
45+
$this->expectException(\invalid_parameter_exception::class);
46+
$this->expectExceptionMessage('Rule does not exist. ID: 777');
47+
48+
rules::delete_rules([777]);
49+
}
50+
51+
/**
52+
* Test required permissions.
53+
*/
54+
public function test_delete_rules_permissions() {
55+
$this->resetAfterTest();
56+
$user = $this->getDataGenerator()->create_user();
57+
$this->setUser($user);
58+
59+
$this->expectException(\required_capability_exception::class);
60+
$this->expectExceptionMessage('Sorry, but you do not currently have permissions to do that (Manage rules).');
61+
62+
rules::delete_rules([777]);
63+
}
64+
65+
/**
66+
* Test can get total.
67+
*/
68+
public function test_exception_delete_rules_when_one_is_invalid() {
69+
$this->resetAfterTest();
70+
$this->setAdminUser();
71+
72+
$rule = new rule(0, (object)['name' => 'Test rule 1']);
73+
$rule->save();
74+
75+
$this->expectException(\invalid_parameter_exception::class);
76+
$this->expectExceptionMessage('Rule does not exist. ID: 777');
77+
78+
rules::delete_rules([$rule->get('id'), 777]);
79+
}
80+
81+
/**
82+
* Test can get total.
83+
*/
84+
public function test_delete_rules_keep_rules_when_one_is_invalid() {
85+
$this->resetAfterTest();
86+
$this->setAdminUser();
87+
88+
$rule1 = new rule(0, (object)['name' => 'Test rule 1']);
89+
$rule1->save();
90+
91+
$rule2 = new rule(0, (object)['name' => 'Test rule 2']);
92+
$rule2->save();
93+
94+
$this->assertCount(2, rule::get_records());
95+
96+
$this->expectException(\required_capability_exception::class);
97+
$this->expectExceptionMessage('Rule does not exist. ID: 777');
98+
99+
try {
100+
rules::delete_rules([$rule1->get('id'), $rule2->get('id'), 777]);
101+
} catch (\invalid_parameter_exception $exception) {
102+
$this->assertSame(
103+
'Invalid parameter value detected (Rule does not exist. ID: 777)',
104+
$exception->getMessage()
105+
);
106+
$this->assertCount(2, rule::get_records());
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)