Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue #4 issue #5 issue #6: processing new tags, courses and categories #12

Merged
merged 10 commits into from
Sep 4, 2024
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ jobs:
with:
disable_behat: true
disable_phpcpd: true
extra_plugin_runners: 'moodle-plugin-ci add-plugin --branch MOODLE_404_STABLE catalyst/moodle-tool_dynamic_cohorts'
265 changes: 265 additions & 0 deletions classes/helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
<?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_enrolprofile;

use context_system;
use stdClass;
use tool_dynamic_cohorts\cohort_manager;
use tool_dynamic_cohorts\condition_base;
use tool_dynamic_cohorts\rule;

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

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

/**
* Helper class.
*
* @package tool_enrolprofile
* @copyright 2024 Dmitrii Metelkin <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class helper {

/**
* Tag item type.
*/
public const ITEM_TYPE_TAG = 'tag';

/**
* Category item type.
*/
public const ITEM_TYPE_CATEGORY = 'category';

/**
* Course item type.
*/
public const ITEM_TYPE_COURSE = 'course';

/**
* Field shortname
*/
public const FIELD_ENROLLED_UNTIL = 'enrolleduntil';

/**
* Course field name.
*/
public const COURSE_NAME = 'fullname';

/**
* Field shortname
*/
public const COHORT_FIELD_ID = 'id';

/**
* Field shortname
*/
public const COHORT_FIELD_TYPE = 'type';

/**
* Role shortname.
*/
public const STUDENT_ROLE = 'student';

/**
* Set up configuration item.
*
* @param int $itemid Item ID number
* @param string $itemtype Item type (tag, course, category).
* @param string $itemname Item name.
* @param stdClass|null $course Course to set up enrolment method. If not set, the no enrolment method will be created.
* @return void
*/
public static function set_up_item(int $itemid, string $itemtype, string $itemname, ?stdClass $course = null): void {
$cohort = self::get_cohort_by_item($itemid, $itemtype);

if (empty($cohort)) {
$cohort = new stdClass();
$cohort->contextid = context_system::instance()->id;
$cohort->name = $itemname;
$cohort->idnumber = $itemname;
$cohort->description = ucfirst($itemtype) . ' related';
$typefieled = 'customfield_' . self::COHORT_FIELD_TYPE;
$cohort->$typefieled = $itemtype;
$idfieled = 'customfield_' . self::COHORT_FIELD_ID;
$cohort->$idfieled = $itemid;

// Create a new cohort.
$cohort->id = self::add_cohort($cohort);
}

// Create a dynamic cohort rule associated with this cohort.
self::add_rule($cohort, $itemtype);
// Add a tag to a custom profile field.
self::update_profile_field($itemtype, $itemname);

// Create enrolment method for the cohort for a given course.
if (!empty($course)) {
self::add_enrolment_method($course, $cohort);
}
}

/**
* Get cohort by provided item type and item id.
*
* @param int $itemid Item ID.
* @param string $itemtype Item type.
*
* @return stdClass|null
*/
public static function get_cohort_by_item(int $itemid, string $itemtype): ?stdClass {
$systemcontext = context_system::instance();

$allcohorts = cohort_get_cohorts($systemcontext->id, 0, 0, '', true);
// Load custom fields data and filter bby custom field type and id.
$cohorts = array_filter($allcohorts['cohorts'], function ($cohortdata) use ($itemid, $itemtype) {
foreach ($cohortdata->customfields as $customfield) {
$name = 'customfield_' . $customfield->get_field()->get('shortname');
$cohortdata->$name = $customfield->export_value();
}
$typefieled = 'customfield_' . self::COHORT_FIELD_TYPE;
$idfieled = 'customfield_' . self::COHORT_FIELD_ID;

return $cohortdata->$typefieled == $itemtype && $cohortdata->$idfieled == $itemid;
});

if (!empty($cohorts)) {
return reset($cohorts);
} else {
return null;
}
}

/**
* Helper method to add enrolment method to a course.
*
* @param stdClass $course Course.
* @param stdClass $cohort Cohort.
*
* @return void
*/
public static function add_enrolment_method(stdClass $course, stdClass $cohort): void {
global $DB;

$studentrole = $DB->get_record('role', ['shortname' => self::STUDENT_ROLE]);

$fields = [
'customint1' => $cohort->id,
'roleid' => $studentrole->id,
'courseid' => $course->id,
];

if (!$DB->record_exists('enrol', $fields)) {
$enrol = enrol_get_plugin('cohort');
$enrol->add_instance($course, $fields);
}
}

/**
* Update profile field with new item.
*
* @param string $shortname Field short name.
* @param string $newitem A new item to add to the field.
*
* @return void
*/
public static function update_profile_field(string $shortname, string $newitem): void {
global $DB;

$field = $DB->get_record('user_info_field', ['shortname' => $shortname]);
$fielddata = [];
if (!empty($field->param1)) {
$fielddata = explode("\n", $field->param1);
}

if (!in_array($newitem, $fielddata)) {
$fielddata[] = $newitem;
sort($fielddata);
$field->param1 = implode("\n", $fielddata);
$DB->update_record('user_info_field', $field);
}
}

/**
* Add cohort.
*
* @param stdClass $cohort Cohort.
*
* @return int
*/
public static function add_cohort(stdClass $cohort): int {
global $DB;
if (!$existingcohort = $DB->get_record('cohort', ['name' => $cohort->name])) {
return cohort_add_cohort($cohort);
} else {
return $existingcohort->id;
}
}

/**
* A helper method to set up rule for given cohort.
*
* @param stdClass $cohort Cohort.
* @param string $fieldshortname Related profile field shortname.
*
* @return void
*/
public static function add_rule(stdClass $cohort, string $fieldshortname): void {
if (rule::get_record(['cohortid' => $cohort->id])) {
return;
}

cohort_manager::manage_cohort($cohort->id);
$rule = new rule(0, (object)[
'name' => $cohort->name,
'cohortid' => $cohort->id,
'description' => $cohort->description,
]);
$rule->save();

$condition = condition_base::get_instance(0, (object)[
'classname' => 'tool_dynamic_cohorts\local\tool_dynamic_cohorts\condition\user_custom_profile',
]);

$fieldname = 'profile_field_' . $fieldshortname;
$condition->set_config_data([
'profilefield' => $fieldname,
$fieldname . '_operator' => condition_base::TEXT_IS_EQUAL_TO,
$fieldname . '_value' => $cohort->name,
]);
$condition->get_record()->set('ruleid', $rule->get('id'));
$condition->get_record()->set('sortorder', 0);
$condition->get_record()->save();

$condition = condition_base::get_instance(0, (object)[
'classname' => 'tool_dynamic_cohorts\local\tool_dynamic_cohorts\condition\user_custom_profile',
]);

$fieldname = 'profile_field_' . self::FIELD_ENROLLED_UNTIL;
$condition->set_config_data([
'profilefield' => $fieldname,
$fieldname . '_operator' => condition_base::DATE_IN_THE_FUTURE,
$fieldname . '_value' => 0,
]);
$condition->get_record()->set('ruleid', $rule->get('id'));
$condition->get_record()->set('sortorder', 0);
$condition->get_record()->save();

$rule->set('enabled', 1);
$rule->save();
}
}
77 changes: 77 additions & 0 deletions classes/observer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?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_enrolprofile;

use core\event\course_category_created;
use core\event\course_created;
use core\event\tag_added;

/**
* Event observer class.
*
* @package tool_enrolprofile
* @copyright 2024 Dmitrii Metelkin <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class observer {

/**
* Process tag_added event.
*
* @param tag_added $event The event.
*/
public static function tag_added(tag_added $event): void {
// Check context is course context.
$context = $event->get_context();
if ($context->contextlevel != CONTEXT_COURSE && $event->other['itemtype'] != 'course') {
return;
}

$tagid = $event->other['tagid'];
$tagname = $event->other['tagrawname'];
$course = get_course($event->other['itemid']);

helper::set_up_item($tagid, helper::ITEM_TYPE_TAG, $tagname, $course);
}

/**
* Process course_created event.
*
* @param course_created $event The event.
*/
public static function course_created(course_created $event): void {
global $DB;

$course = get_course($event->courseid);
helper::set_up_item($course->id, helper::ITEM_TYPE_COURSE, $course->{helper::COURSE_NAME}, $course);

$category = $DB->get_record('course_categories', ['id' => $course->category]);
helper::set_up_item($category->id, helper::ITEM_TYPE_CATEGORY, $category->name, $course);
}

/**
* Process course_category_created event.
*
* @param course_category_created $event The event.
*/
public static function course_category_created(course_category_created $event): void {
global $DB;

$category = $DB->get_record('course_categories', ['id' => $event->objectid]);
helper::set_up_item($category->id, helper::ITEM_TYPE_CATEGORY, $category->name);
}
}
40 changes: 40 additions & 0 deletions db/events.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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/>.

/**
* Plugin event observers are registered here.
*
* @package tool_enrolprofile
* @copyright 2024 Dmitrii Metelkin <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

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

$observers = [
[
'eventname' => '\core\event\tag_added',
'callback' => '\tool_enrolprofile\observer::tag_added',
],
[
'eventname' => '\core\event\course_created',
'callback' => '\tool_enrolprofile\observer::course_created',
],
[
'eventname' => '\core\event\course_category_created',
'callback' => '\tool_enrolprofile\observer::course_category_created',
],
];
2 changes: 1 addition & 1 deletion lang/en/tool_enrolprofile.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*
* @package tool_enrolprofile
* @category string
* @copyright 2024 Your Name <[email protected]>
* @copyright 2024 Dmitrii Metelkin <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

Expand Down
Loading
Loading