Skip to content

Commit

Permalink
MDL-52252 Tags: Add tags to modules (Resources and Activities)
Browse files Browse the repository at this point in the history
  • Loading branch information
nadavkav authored and marinaglancy committed Mar 9, 2016
1 parent 7adc7ef commit dffcf46
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 2 deletions.
13 changes: 13 additions & 0 deletions backup/moodle2/backup_stepslib.php
Expand Up @@ -269,6 +269,9 @@ protected function define_structure() {
'completion', 'completiongradeitemnumber', 'completionview', 'completionexpected',
'availability', 'showdescription'));

$tags = new backup_nested_element('tags');
$tag = new backup_nested_element('tag', array('id'), array('name', 'rawname'));

// attach format plugin structure to $module element, only one allowed
$this->add_plugin_structure('format', $module, false);

Expand All @@ -279,6 +282,9 @@ protected function define_structure() {
// attach local plugin structure to $module, multiple allowed
$this->add_plugin_structure('local', $module, true);

$module->add_child($tags);
$tags->add_child($tag);

// Set the sources
$concat = $DB->sql_concat("'mod_'", 'm.name');
$module->set_source_sql("
Expand All @@ -289,6 +295,13 @@ protected function define_structure() {
JOIN {course_sections} s ON s.id = cm.section
WHERE cm.id = ?", array(backup::VAR_MODID));

$tag->set_source_sql("SELECT t.id, t.name, t.rawname
FROM {tag} t
JOIN {tag_instance} ti ON ti.tagid = t.id
WHERE ti.itemtype = 'course_modules'
AND ti.component = 'core'
AND ti.itemid = ?", array(backup::VAR_MODID));

// Define annotations
$module->annotate_ids('grouping', 'groupingid');

Expand Down
35 changes: 35 additions & 0 deletions backup/moodle2/restore_stepslib.php
Expand Up @@ -3584,6 +3584,8 @@ protected function define_structure() {
$paths[] = new restore_path_element('availability_field', '/module/availability_info/availability_field');
}

$paths[] = new restore_path_element('tag', '/module/tags/tag');

// Apply for 'format' plugins optional paths at module level
$this->add_plugin_structure('format', $module);

Expand Down Expand Up @@ -3691,6 +3693,25 @@ protected function process_module($data) {
}
}

/**
* Fetch all the existing because tag_set() deletes them
* so everything must be reinserted on each call.
*
* @param stdClass $data Record data
*/
protected function process_tag($data) {
global $CFG;

$data = (object)$data;

if (core_tag_tag::is_enabled('core', 'course_modules')) {
$modcontext = context::instance_by_id($this->task->get_contextid());
$instanceid = $this->task->get_moduleid();

core_tag_tag::add_item_tag('core', 'course_modules', $instanceid, $modcontext, $data->rawname);
}
}

/**
* Process the legacy availability table record. This table does not exist
* in Moodle 2.7+ but we still support restore.
Expand Down Expand Up @@ -3759,6 +3780,20 @@ protected function process_availability_field($data) {
array('id' => $availfield->coursemoduleid));
}
}
/**
* This method will be executed after the rest of the restore has been processed.
*
* Update old tag instance itemid(s).
*/
protected function after_restore() {
global $DB;

$contextid = $this->task->get_contextid();
$instanceid = $this->task->get_activityid();
$olditemid = $this->task->get_old_activityid();

$DB->set_field('tag_instance', 'itemid', $instanceid, array('contextid' => $contextid, 'itemid' => $olditemid));
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions course/lib.php
Expand Up @@ -1690,6 +1690,7 @@ function course_delete_module($cmid) {

// Delete all tag instances associated with the instance of this module.
core_tag_tag::delete_instances('mod_' . $modulename, null, $modcontext->id);
core_tag_tag::remove_all_item_tags('core', 'course_modules', $cm->id);

// Delete the context.
context_helper::delete_instance(CONTEXT_MODULE, $cm->id);
Expand Down
1 change: 1 addition & 0 deletions course/modedit.php
Expand Up @@ -156,6 +156,7 @@
$data->completionexpected = $cm->completionexpected;
$data->completionusegrade = is_null($cm->completiongradeitemnumber) ? 0 : 1;
$data->showdescription = $cm->showdescription;
$data->tags = core_tag_tag::get_item_tags_array('core', 'course_modules', $cm->id);
if (!empty($CFG->enableavailability)) {
$data->availabilityconditionsjson = $cm->availability;
}
Expand Down
10 changes: 10 additions & 0 deletions course/modlib.php
Expand Up @@ -151,6 +151,11 @@ function add_moduleinfo($moduleinfo, $course, $mform = null) {
$DB->set_field($moduleinfo->modulename, 'intro', $moduleinfo->intro, array('id'=>$moduleinfo->instance));
}

// Add module tags.
if (core_tag_tag::is_enabled('core', 'course_modules') && isset($moduleinfo->tags)) {
core_tag_tag::set_item_tags('core', 'course_modules', $moduleinfo->coursemodule, $modcontext, $moduleinfo->tags);
}

// Course_modules and course_sections each contain a reference to each other.
// So we have to update one of them twice.
$sectionid = course_add_cm_to_section($course, $moduleinfo->coursemodule, $moduleinfo->section);
Expand Down Expand Up @@ -578,6 +583,11 @@ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber);
}

// Update module tags.
if (core_tag_tag::is_enabled('core', 'course_modules') && isset($moduleinfo->tags)) {
core_tag_tag::set_item_tags('core', 'course_modules', $moduleinfo->coursemodule, $modcontext, $moduleinfo->tags);
}

// Now that module is fully updated, also update completion data if required.
// (this will wipe all user completion data and recalculate it)
if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) {
Expand Down
14 changes: 14 additions & 0 deletions course/moodleform_mod.php
Expand Up @@ -597,6 +597,20 @@ function standard_coursemodule_elements(){
$mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
}

// Populate module tags.
$categorycontext = context_coursecat::instance($COURSE->category);
$coursecontext = context_course::instance($COURSE->id);
if (core_tag_tag::is_enabled('core', 'course_modules')) {
$mform->addElement('header', 'tagshdr', get_string('tags', 'tag'));
$mform->addElement('tags', 'tags', get_string('tags'), array('itemtype' => 'course_modules', 'component' => 'core'));
if ($this->_cm) {
$modinfo = get_fast_modinfo($COURSE);
$cm = $modinfo->get_cm($this->_cm->id);
$tags = core_tag_tag::get_item_tags_array('core', 'course_modules', $cm->id);
$mform->setDefault('tags', $tags);
}
}

$this->standard_hidden_coursemodule_elements();
}

Expand Down
4 changes: 2 additions & 2 deletions course/tests/courselib_test.php
Expand Up @@ -1521,10 +1521,10 @@ public function test_course_delete_module($type, $options) {
switch ($type) {
case 'assign':
// Add some tags to this assignment.
core_tag_tag::set_item_tags('mod_assign', 'assign', $module->id, $modcontext, array('Tag 1', 'Tag 2', 'Tag 3'));
core_tag_tag::set_item_tags('core', 'course_modules', $module->id, $modcontext, array('Tag 1', 'Tag 2', 'Tag 3'));

// Confirm the tag instances were added.
$criteria = array('component' => 'mod_assign', 'contextid' => $modcontext->id);
$criteria = array('component' => 'core', 'itemtype' => 'course_modules', 'contextid' => $modcontext->id);
$this->assertEquals(3, $DB->count_records('tag_instance', $criteria));

// Verify event assignment event has been generated.
Expand Down
1 change: 1 addition & 0 deletions lang/en/tag.php
Expand Up @@ -116,6 +116,7 @@
$string['tagarea_post'] = 'Blog posts';
$string['tagarea_user'] = 'User interests';
$string['tagarea_course'] = 'Courses';
$string['tagarea_course_modules'] = 'Course modules';
$string['tagareaenabled'] = 'Enabled';
$string['tagareaname'] = 'Name';
$string['tagareas'] = 'Tag areas';
Expand Down
4 changes: 4 additions & 0 deletions lib/db/tag.php
Expand Up @@ -80,4 +80,8 @@
'itemtype' => 'blog_external', // External blogs.
'component' => 'core',
),
array(
'itemtype' => 'course_modules', // Course modules.
'component' => 'core',
),
);
4 changes: 4 additions & 0 deletions lib/testing/generator/module_generator.php
Expand Up @@ -248,6 +248,10 @@ public function create_instance($record = null, array $options = null) {
$record->introformat = FORMAT_MOODLE;
}

if (isset($record->tags) && !is_array($record->tags)) {
$record->tags = preg_split('/\s*,\s*/', trim($record->tags), -1, PREG_SPLIT_NO_EMPTY);
}

// Before Moodle 2.6 it was possible to create a module with completion tracking when
// it is not setup for course and/or site-wide. Display debugging message so it is
// easier to trace an error in unittests.
Expand Down
4 changes: 4 additions & 0 deletions lib/testing/tests/generator_test.php
Expand Up @@ -199,6 +199,10 @@ public function test_create_module() {
$cm = get_coursemodule_from_instance('page', $page->id, $SITE->id, true);
$this->assertEquals(3, $cm->sectionnum);

$page = $generator->create_module('page', array('course' => $SITE->id, 'tags' => 'Cat, Dog'));
$this->assertEquals(array('Cat', 'Dog'),
array_values(core_tag_tag::get_item_tags_array('core', 'course_modules', $page->cmid)));

// Prepare environment to generate modules with all possible options.

// Enable advanced functionality.
Expand Down

0 comments on commit dffcf46

Please sign in to comment.