Skip to content

Commit

Permalink
Assign rle synchronization to course category context (#1)
Browse files Browse the repository at this point in the history
Will help to solve paulholden#1
  • Loading branch information
Adrian Perez committed Feb 18, 2021
1 parent 3b820df commit f5a5a69
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 73 deletions.
21 changes: 19 additions & 2 deletions classes/form/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ protected function definition() {
$mform->setType('roleid', PARAM_INT);
$mform->addHelpButton('roleid', 'role', 'local_cohortrole');

$mform->addElement('select', 'categoryid', get_string('category', 'local_cohortrole'), self::get_categories());
$mform->setType('categoryid', PARAM_INT);
$mform->addHelpButton('categoryid', 'category', 'local_cohortrole');

$this->add_action_buttons();
}

Expand All @@ -63,8 +67,8 @@ protected function definition() {
* @return array
*/
public function extra_validation($data, $files, array &$errors) {
if ($this->get_persistent()->record_exists_select('cohortid = :cohortid AND roleid = :roleid',
['cohortid' => $data->cohortid, 'roleid' => $data->roleid])) {
if ($this->get_persistent()->record_exists_select('cohortid = :cohortid AND roleid = :roleid AND categoryid = :categoryid',
['cohortid' => $data->cohortid, 'roleid' => $data->roleid, 'categoryid' => $data->categoryid])) {

$errors['cohortid'] = get_string('errorexists', 'local_cohortrole');
}
Expand Down Expand Up @@ -100,4 +104,17 @@ protected static function get_roles() {

return $roles;
}

/**
* Get categories from the system
*
* @return array
*/
protected static function get_categories() {
$categories = [0 => get_string('choosedots')] + \core_course_category::make_categories_list();

\core_collator::asort($categories, \core_collator::SORT_STRING);

return $categories;
}
}
14 changes: 7 additions & 7 deletions classes/observers.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,10 @@ public static function cohort_deleted(\core\event\cohort_deleted $event) {
$cohort = $event->get_record_snapshot('cohort', $event->objectid);

$instances = persistent::get_records(['cohortid' => $cohort->id]);
if (count($instances) > 0) {
local_cohortrole_unsynchronize($cohort->id);
foreach ($instances as $instance) {
local_cohortrole_unsynchronize($cohort->id, $instance->get('roleid'), $instance->get('categoryid'));

foreach ($instances as $instance) {
$instance->delete();
}
$instance->delete();
}
}
}
Expand All @@ -64,7 +62,8 @@ public static function cohort_member_added(\core\event\cohort_member_added $even
$user = \core_user::get_user($event->relateduserid, '*', MUST_EXIST);

foreach ($instances as $instance) {
local_cohortrole_role_assign($instance->get('cohortid'), $instance->get('roleid'), [$user->id]);
local_cohortrole_role_assign($instance->get('cohortid'), $instance->get('roleid'), $instance->get('categoryid'),
[$user->id]);
}
}
}
Expand All @@ -85,7 +84,8 @@ public static function cohort_member_removed(\core\event\cohort_member_removed $
$user = \core_user::get_user($event->relateduserid, '*', MUST_EXIST);

foreach ($instances as $instance) {
local_cohortrole_role_unassign($instance->get('cohortid'), $instance->get('roleid'), [$user->id]);
local_cohortrole_role_unassign($instance->get('cohortid'), $instance->get('roleid'),
$instance->get('categoryid'), [$user->id]);
}
}
}
Expand Down
17 changes: 17 additions & 0 deletions classes/output/summary_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function __construct() {
$columns = [
'cohort' => get_string('cohort', 'local_cohortrole'),
'role' => get_string('role', 'local_cohortrole'),
'category' => get_string('category', 'local_cohortrole'),
'timecreated' => get_string('modified'),
'edit' => get_string('edit'),
];
Expand Down Expand Up @@ -124,6 +125,22 @@ public function col_role(\stdClass $record) {
return role_get_name($persistent->get_role(), \context_system::instance(), ROLENAME_ALIAS);
}

/**
* Format record category column
*
* @param stdClass $record
* @return string
*/
public function col_category(\stdClass $record) {
if ($record->categoryid == 0) {
return '';
}

$persistent = new persistent(0, $record);

return $persistent->get_category()->name;
}

/**
* Format record time created column
*
Expand Down
34 changes: 34 additions & 0 deletions classes/persistent.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ protected static function define_properties() {
'roleid' => array(
'type' => PARAM_INT,
),
'categoryid' => array(
'type' => PARAM_INT,
),
);
}

Expand Down Expand Up @@ -82,6 +85,26 @@ protected function validate_roleid($roleid) {
return true;
}

/**
* Validate category ID
*
* @param int $categoryid
* @return true|lang_string
*/
protected function validate_categoryid($categoryid) {
global $DB;

if ($categoryid == 0) {
return true;
}

if (! $DB->record_exists('course_categories', ['id' => $categoryid])) {
return new \lang_string('invalidcategoryid', 'error');
}

return true;
}

/**
* Hook to execute after model is created
*
Expand Down Expand Up @@ -122,4 +145,15 @@ public function get_role() {

return $DB->get_record('role', ['id' => $this->get('roleid')], '*', MUST_EXIST);
}

/**
* Returns the category object
*
* @return stdClass
*/
public function get_category() {
global $DB;

return $DB->get_record('course_categories', ['id' => $this->get('categoryid')], '*', MUST_EXIST);
}
}
4 changes: 3 additions & 1 deletion db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="cohortid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The id of the cohort"/>
<FIELD NAME="roleid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The id of the role"/>
<FIELD NAME="categoryid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The id of the category"/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The id of the user"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Time the definition was created"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Time the definition was modified"/>
Expand All @@ -17,10 +18,11 @@
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_cohort" TYPE="foreign" FIELDS="cohortid" REFTABLE="cohort" REFFIELDS="id"/>
<KEY NAME="fk_role" TYPE="foreign" FIELDS="roleid" REFTABLE="role" REFFIELDS="id"/>
<KEY NAME="fk_category" TYPE="foreign" FIELDS="categoryid" REFTABLE="course_categories" REFFIELDS="id"/>
<KEY NAME="fk_user" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="uq_cohort_role" UNIQUE="true" FIELDS="cohortid, roleid" COMMENT="Cohort and role identifiers must be unique"/>
<INDEX NAME="uq_cohort_role" UNIQUE="true" FIELDS="cohortid, roleid, categoryid" COMMENT="Cohort, role and category identifiers must be unique"/>
</INDEXES>
</TABLE>
</TABLES>
Expand Down
28 changes: 28 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,33 @@ function xmldb_local_cohortrole_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2018121001, 'local', 'cohortrole');
}

if ($oldversion < 2020110901) {
// Define field categoryid to be added to local_cohortrole.
$table = new xmldb_table('local_cohortrole');
$field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'roleid');

// Conditionally launch add field categoryid.
if (! $dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Define key fk_category (foreign) to be added to local_cohortrole.
$key = new xmldb_key('fk_category', XMLDB_KEY_FOREIGN, array('categoryid'), 'course_categories', array('id'));
$dbman->add_key($table, $key);

// Conditionally launch drop and add index 'uq_cohort_role'.
$index = new xmldb_index('uq_cohort_role', XMLDB_INDEX_UNIQUE, array('cohortid', 'roleid'));

if ($dbman->index_exists($table, $index)) {
$dbman->drop_index($table, $index);
}

$index = new xmldb_index('uq_cohort_role', XMLDB_INDEX_UNIQUE, array('cohortid', 'roleid', 'categoryid'));
$dbman->add_index($table, $index);

// Cohortrole savepoint reached.
upgrade_plugin_savepoint(true, 2020110901, 'local', 'cohortrole');
}

return true;
}
10 changes: 5 additions & 5 deletions edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@

use \local_cohortrole\persistent;

$delete = optional_param('delete', 0, PARAM_INT);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$delete = optional_param('delete', 0, PARAM_INT);
$confirm = optional_param('confirm', 0, PARAM_BOOL);

admin_externalpage_setup('local_cohortrole');

$editurl = new moodle_url('/local/cohortrole/edit.php');
$editurl = new moodle_url('/local/cohortrole/edit.php');
$returnurl = clone($PAGE->url);

if ($delete) {
$persistent = new persistent($delete);

if ($confirm and confirm_sesskey()) {
local_cohortrole_unsynchronize($persistent->get('cohortid'), $persistent->get('roleid'));
local_cohortrole_unsynchronize($persistent->get('cohortid'), $persistent->get('roleid'), $persistent->get('categoryid'));

$persistent->delete();

Expand All @@ -65,7 +65,7 @@
} else if ($data = $mform->get_data()) {
$persistent = (new persistent(0, $data))->create();

local_cohortrole_synchronize($persistent->get('cohortid'), $persistent->get('roleid'));
local_cohortrole_synchronize($persistent->get('cohortid'), $persistent->get('roleid'), $persistent->get('categoryid'));

redirect($returnurl, get_string('notificationcreated', 'local_cohortrole'), null,
\core\output\notification::NOTIFY_SUCCESS);
Expand Down
2 changes: 2 additions & 0 deletions lang/en/local_cohortrole.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@
$string['privacy:metadata:cohortrole:timecreated'] = 'The timestamp the definition was created';
$string['role'] = 'Role';
$string['role_help'] = 'List of assignable roles in the system context';
$string['category'] = 'Category';
$string['category_help'] = 'You can optionally select a course category to assign roles not in the system context';
48 changes: 34 additions & 14 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
/**
* Assign users to a role; using local role component
*
* @param integer $cohortid the id of a cohort
* @param integer $roleid the id of a role
* @param int $cohortid the id of a cohort
* @param int $roleid the id of a role
* @param int $categoryid the id of a category
* @param array $userids an array of user ids to assign
* @return void
*/
function local_cohortrole_role_assign($cohortid, $roleid, array $userids) {
$context = context_system::instance();
function local_cohortrole_role_assign($cohortid, $roleid, $categoryid, array $userids) {
$context = local_cohortrole_get_context($categoryid);

foreach ($userids as $userid) {
role_assign($roleid, $userid, $context->id, LOCAL_COHORTROLE_ROLE_COMPONENT, $cohortid);
Expand All @@ -43,13 +44,14 @@ function local_cohortrole_role_assign($cohortid, $roleid, array $userids) {
/**
* Unassign users from a role; using local role component
*
* @param integer $cohortid the id of a cohort
* @param integer $roleid the id of a role
* @param int $cohortid the id of a cohort
* @param int $roleid the id of a role
* @param int $categoryid the id of a category
* @param array $userids an array of user ids to unassign
* @return void
*/
function local_cohortrole_role_unassign($cohortid, $roleid, array $userids) {
$context = context_system::instance();
function local_cohortrole_role_unassign($cohortid, $roleid, $categoryid, array $userids) {
$context = local_cohortrole_get_context($categoryid);

foreach ($userids as $userid) {
role_unassign($roleid, $userid, $context->id, LOCAL_COHORTROLE_ROLE_COMPONENT, $cohortid);
Expand All @@ -59,16 +61,17 @@ function local_cohortrole_role_unassign($cohortid, $roleid, array $userids) {
/**
* Add users to a role that synchronizes from a cohort
*
* @param integer $cohortid the id of a cohort
* @param integer $roleid the id of a role
* @param int $cohortid the id of a cohort
* @param int $roleid the id of a role
* @param int $categoryid the id of a category
* @return void
*/
function local_cohortrole_synchronize($cohortid, $roleid) {
function local_cohortrole_synchronize($cohortid, $roleid, $categoryid) {
global $DB;

$userids = $DB->get_records_menu('cohort_members', array('cohortid' => $cohortid), null, 'id, userid');

local_cohortrole_role_assign($cohortid, $roleid, $userids);
local_cohortrole_role_assign($cohortid, $roleid, $categoryid, $userids);
}

/**
Expand All @@ -78,9 +81,11 @@ function local_cohortrole_synchronize($cohortid, $roleid) {
* @param integer|null $roleid the id of a role, all roles if null
* @return void
*/
function local_cohortrole_unsynchronize($cohortid, $roleid = null) {
function local_cohortrole_unsynchronize($cohortid, $roleid = null, $categoryid) {
$context = local_cohortrole_get_context($categoryid);

$params = array(
'contextid' => context_system::instance()->id, 'component' => LOCAL_COHORTROLE_ROLE_COMPONENT, 'itemid' => $cohortid);
'contextid' => $context->id, 'component' => LOCAL_COHORTROLE_ROLE_COMPONENT, 'itemid' => $cohortid);

if ($roleid === null) {
$roleids = local_cohortrole_get_cohort_roles($cohortid);
Expand All @@ -106,3 +111,18 @@ function local_cohortrole_get_cohort_roles($cohortid) {

return $DB->get_records_menu('local_cohortrole', array('cohortid' => $cohortid), null, 'id, roleid');
}

/**
* Get the context to assign and unassign roles.
*
* @param int $categoryid
* @return bool|context|context_coursecat|context_system|null
* @throws dml_exception
*/
function local_cohortrole_get_context($categoryid) {
if ($categoryid > 0) {
return context_coursecat::instance($categoryid);
}

return $context = context_system::instance();
}
5 changes: 4 additions & 1 deletion tests/behat/behat_local_cohortrole_data_generators.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function the_following_cohort_role_definitions_exist(TableNode $data) {

$generator = testing_util::get_data_generator()->get_plugin_generator('local_cohortrole');

$requiredfields = ['cohort', 'role'];
$requiredfields = ['cohort', 'role', 'category'];

foreach ($data->getHash() as $elementdata) {
foreach ($requiredfields as $requiredfield) {
Expand Down Expand Up @@ -71,6 +71,9 @@ protected function preprocess_definition(array $data) {
$data['roleid'] = $DB->get_field('role', 'id', ['shortname' => $data['role']], MUST_EXIST);
unset($data['role']);

$data['categoryid'] = $DB->get_field('course_categories', 'id', ['idnumber' => $data['category']], MUST_EXIST);
unset($data['category']);

return $data;
}
}
Loading

0 comments on commit f5a5a69

Please sign in to comment.