Skip to content

Commit

Permalink
MDL-31356 enrol_imsenterprise: Continue development for added features
Browse files Browse the repository at this point in the history
    * Add the possibility to make it works as before (with categrory name or idnumber).
    * Add possibility to specify nested categories by name or idnumber.
    * Fix error in core_course_courselib_testcase::test_course_created_event because dependency with imsenterprise
  • Loading branch information
gauts authored and taboubi committed Jul 14, 2016
1 parent 08b2933 commit cc6b924
Show file tree
Hide file tree
Showing 6 changed files with 508 additions and 99 deletions.
9 changes: 8 additions & 1 deletion course/tests/courselib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1622,6 +1622,7 @@ public function test_course_created_event() {
ob_end_clean();

// Create the XML file we want to use.
$course->category = (array)$course->category;
$imstestcase = new enrol_imsenterprise_testcase();
$imstestcase->imsplugin = enrol_get_plugin('imsenterprise');
$imstestcase->set_test_config();
Expand All @@ -1632,7 +1633,13 @@ public function test_course_created_event() {
$imstestcase->imsplugin->cron();
$events = $sink->get_events();
$sink->close();
$event = $events[0];
$event = null;
foreach ($events as $eventinfo) {
if ($eventinfo instanceof \core\event\course_created ) {
$event = $eventinfo;
break;
}
}

// Validate the event triggered is \core\event\course_created. There is no need to validate the other values
// as they have already been validated in the previous steps. Here we only want to make sure that when the
Expand Down
6 changes: 5 additions & 1 deletion enrol/imsenterprise/lang/en/enrol_imsenterprise.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
$string['allowunenrol'] = 'Allow the IMS data to <strong>unenrol</strong> students/teachers';
$string['allowunenrol_desc'] = 'If enabled, course enrolments will be removed when specified in the Enterprise data.';
$string['basicsettings'] = 'Basic settings';
$string['categoryidnumber'] = 'Allow category idnumber';
$string['categoryidnumber_desc'] = 'If enabled IMS Enterprise will create category with idnumber';
$string['categoryseparator'] = 'Category Separator Character';
$string['categoryseparator_desc'] = 'You can create nested categories (if you allow category creation).';
$string['categoryseparator_desc'] = 'Required when "Category idnumber" is enabled. Character to separate the category name and idnumber.';
$string['coursesettings'] = 'Course data options';
$string['createnewcategories'] = 'Create new (hidden) course categories if not found in Moodle';
$string['createnewcategories_desc'] = 'If the <org><orgunit> element is present in a course\'s incoming data, its content will be used to specify a category if the course is to be created from scratch. The plugin will NOT re-categorise existing courses.
Expand Down Expand Up @@ -57,6 +59,8 @@
$string['mailusers'] = 'Notify users by email';
$string['messageprovider:imsenterprise_enrolment'] = 'IMS Enterprise enrolment messages';
$string['miscsettings'] = 'Miscellaneous';
$string['nestedcategories'] = 'Allow nested categories';
$string['nestedcategories_desc'] = 'If enabled IMS Enterprise will create nested categories';
$string['pluginname'] = 'IMS Enterprise file';
$string['pluginname_desc'] = 'This method will repeatedly check for and process a specially-formatted text file in the location that you specify. The file must follow the IMS Enterprise specifications containing person, group, and membership XML elements.';
$string['processphoto'] = 'Add user photo data to profile';
Expand Down
176 changes: 114 additions & 62 deletions enrol/imsenterprise/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();

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

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

/**
* IMS Enterprise file enrolment plugin.
Expand Down Expand Up @@ -79,6 +79,11 @@ class enrol_imsenterprise_plugin extends enrol_plugin {
*/
protected $rolemappings;

/**
* @var $defaultcategoryid id of default category.
*/
protected $defaultcategoryid;

/**
* Read in an IMS Enterprise file.
* Originally designed to handle v1.1 files but should be able to handle
Expand Down Expand Up @@ -108,6 +113,8 @@ public function cron() {
$this->logfp = fopen($logtolocation, 'a');
}

$this->defaultcategoryid = null;

$fileisnew = false;
if ( file_exists($filename) ) {
core_php_time_limit::raise();
Expand All @@ -118,6 +125,9 @@ public function cron() {
$this->log_line('Found file '.$filename);
$this->xmlcache = '';

$categoryseparator = trim($this->get_config('categoryseparator'));
$categoryidnumber = $this->get_config('categoryidnumber');

// Make sure we understand how to map the IMS-E roles to Moodle roles.
$this->load_role_mappings();
// Make sure we understand how to map the IMS-E course names to Moodle course names.
Expand All @@ -128,7 +138,9 @@ public function cron() {

// Decide if we want to process the file (based on filepath, modification time, and MD5 hash)
// This is so we avoid wasting the server's efforts processing a file unnecessarily.
if (empty($prevpath) || ($filename != $prevpath)) {
if ($categoryidnumber && empty($categoryseparator)) {
$this->log_line('Category idnumber is enabled but category separator is not defined - skipping processing.');
} else if (empty($prevpath) || ($filename != $prevpath)) {
$fileisnew = true;
} else if (isset($prevtime) && ($filemtime <= $prevtime)) {
$this->log_line('File modification time is not more recent than last update - skipping processing.');
Expand Down Expand Up @@ -292,13 +304,6 @@ protected function process_group_tag($tagcontents) {
$truncatecoursecodes = $this->get_config('truncatecoursecodes');
$createnewcourses = $this->get_config('createnewcourses');
$updatecourses = $this->get_config('updatecourses');
$createnewcategories = $this->get_config('createnewcategories');
$categoryseparator = trim($this->get_config('categoryseparator'));

// Ensure a default is set for the category separator.
if (empty($categoryseparator)) {
$categoryseparator = '|';
}

if ($createnewcourses) {
require_once("$CFG->dirroot/course/lib.php");
Expand All @@ -325,9 +330,10 @@ protected function process_group_tag($tagcontents) {
$group->full = trim($matches[1]);
}

$matches = array();
if (preg_match('{<org>.*?<orgunit>(.*?)</orgunit>.*?</org>}is', $tagcontents, $matches)) {
$group->category = trim($matches[1]);
if (preg_match('{<org>(.*?)</org>}is', $tagcontents, $matchesorg)) {
if (preg_match_all('{<orgunit>(.*?)</orgunit>}is', $matchesorg[1], $matchesorgunit)) {
$group->categories = array_map('trim', $matchesorgunit[1]);
}
}

$recstatus = ($this->get_recstatus($tagcontents, 'group'));
Expand Down Expand Up @@ -389,49 +395,8 @@ protected function process_group_tag($tagcontents) {
$course->enablecompletion = $courseconfig->enablecompletion;
// Insert default names for teachers/students, from the current language.

// Handle course categorisation (taken from the group.org.orgunit field if present).
if (strlen($group->category) > 0) {
$sep = '{\\'.$categoryseparator.'}';
$matches = preg_split($sep, $group->category, -1, PREG_SPLIT_NO_EMPTY);

// Categories can be nested.
// For example: "Fall 2013|Biology" is the "Biology" category nested under the "Fall 2013" category.
// Iterate through each category and create it if necessary.

$catid = 0;
$fullnestedcatname = '';
foreach ($matches as $catname) {
$catname = trim($catname);
if (strlen($fullnestedcatname)) {
$fullnestedcatname .= ' / ';
}
$fullnestedcatname .= $catname;
$parentid = $catid;
if ($catid = $DB->get_field('course_categories', 'id',
array('name' => $catname, 'parent' => $parentid))) {
$course->category = $catid;
continue; // This category already exists.
}
if ($createnewcategories) {
// Else if we're allowed to create new categories, let's create this one.
$newcat = new stdClass();
$newcat->name = $catname;
$newcat->visible = 0;
$newcat->parent = $parentid;
$catid = $DB->insert_record('course_categories', $newcat);
$this->log_line("Created new (hidden) category '$fullnestedcatname'");
$course->category = $catid;
} else {
// If not found and not allowed to create, stick with default.
$this->log_line('Category '.$group->category.' not found in Moodle database, so using '.
'default category instead.');
$course->category = $this->get_default_category_id();
break;
}
}
} else {
$course->category = $this->get_default_category_id();
}
// Handle course categorisation (taken from the group.org.orgunit or group.org.id fields if present).
$course->category = $this->get_category_from_group($group->categories);

$course->startdate = time();
// Choose a sort order that puts us at the start of the list!
Expand Down Expand Up @@ -480,7 +445,7 @@ protected function process_group_tag($tagcontents) {

/**
* Process the person tag. This defines a Moodle user.
*
*
* @param string $tagcontents The raw contents of the XML element
*/
protected function process_person_tag($tagcontents) {
Expand Down Expand Up @@ -591,7 +556,7 @@ protected function process_person_tag($tagcontents) {
$this->log_line("Ignoring update request for user $person->username");
}

} else { // Add record.
} else { // Add or update record.

// If the user exists (matching sourcedid) then we don't need to do anything.
if (!$DB->get_field('user', 'id', array('idnumber' => $person->idnumber)) && $createnewusers) {
Expand Down Expand Up @@ -909,14 +874,101 @@ private function get_default_category_id() {
global $CFG;
require_once($CFG->libdir.'/coursecatlib.php');

static $defaultcategoryid = null;

if ($defaultcategoryid === null) {
if ($this->defaultcategoryid === null) {
$category = coursecat::get_default();
$defaultcategoryid = $category->id;
$this->defaultcategoryid = $category->id;
}

return $this->defaultcategoryid;
}

/**
* Find the category using idnumber or name.
*
* @param array $categories List of categories
*
* @return int id of category found.
*/
private function get_category_from_group($categories) {
global $DB;

if (empty($categories)) {
$catid = $this->get_default_category_id();
} else {
$createnewcategories = $this->get_config('createnewcategories');
$categoryseparator = trim($this->get_config('categoryseparator'));
$nestedcategories = trim($this->get_config('nestedcategories'));
$searchbyidnumber = trim($this->get_config('categoryidnumber'));

if (!empty($categoryseparator)) {
$sep = '{\\'.$categoryseparator.'}';
}

$catid = 0;
$fullnestedcatname = '';

foreach ($categories as $categoryinfo) {
if ($searchbyidnumber) {
$values = preg_split($sep, $categoryinfo, -1, PREG_SPLIT_NO_EMPTY);
if (count($values) < 2) {
$this->log_line('Category ' . $categoryinfo . ' missing name or idnumber. Using default category instead.');
$catid = $this->get_default_category_id();
break;
}
$categoryname = $values[0];
$categoryidnumber = $values[1];
} else {
$categoryname = $categoryinfo;
$categoryidnumber = null;
if (empty($categoryname)) {
$this->log_line('Category ' . $categoryinfo . ' missing name. Using default category instead.');
$catid = $this->get_default_category_id();
break;
}
}

if (!empty($fullnestedcatname)) {
$fullnestedcatname .= ' / ';
}

$fullnestedcatname .= $categoryname;
$parentid = $catid;

// Check if category exist.
$params = array();
if ($searchbyidnumber) {
$params['idnumber'] = $categoryidnumber;
} else {
$params['name'] = $categoryname;
}
if ($nestedcategories) {
$params['parent'] = $parentid;
}

if ($catid = $DB->get_field('course_categories', 'id', $params)) {
continue; // This category already exists.
}

// If we're allowed to create new categories, let's create this one.
if ($createnewcategories) {
$newcat = new stdClass();
$newcat->name = $categoryname;
$newcat->visible = 0;
$newcat->parent = $parentid;
$newcat->idnumber = $categoryidnumber;
$newcat = coursecat::create($newcat);
$catid = $newcat->id;
$this->log_line("Created new (hidden) category '$fullnestedcatname'");
} else {
// If not found and not allowed to create, stick with default.
$this->log_line('Category ' . $categoryinfo . ' not found in Moodle database. Using default category instead.');
$catid = $this->get_default_category_id();
break;
}
}
}

return $defaultcategoryid;
return $catid;
}

/**
Expand Down
8 changes: 7 additions & 1 deletion enrol/imsenterprise/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,14 @@
get_string('createnewcategories', 'enrol_imsenterprise'), get_string('createnewcategories_desc', 'enrol_imsenterprise'),
0));

$settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/nestedcategories',
get_string('nestedcategories', 'enrol_imsenterprise'), get_string('nestedcategories_desc', 'enrol_imsenterprise'), 0));

$settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/categoryidnumber',
get_string('categoryidnumber', 'enrol_imsenterprise'), get_string('categoryidnumber_desc', 'enrol_imsenterprise'), 0));

$settings->add(new admin_setting_configtext('enrol_imsenterprise/categoryseparator',
get_string('categoryseparator', 'enrol_imsenterprise'), get_string('categoryseparator_desc', 'enrol_imsenterprise'), '|',
get_string('categoryseparator', 'enrol_imsenterprise'), get_string('categoryseparator_desc', 'enrol_imsenterprise'), '',
PARAM_TEXT, 3));

$settings->add(new admin_setting_configcheckbox('enrol_imsenterprise/imsunenrol',
Expand Down
Loading

0 comments on commit cc6b924

Please sign in to comment.