Commit c026a28d authored by Marina Glancy's avatar Marina Glancy
Browse files

MDL-50851 core_tag: introduce tag collections

parent e65dfd9f
...@@ -1648,7 +1648,6 @@ function course_delete_module($cmid) { ...@@ -1648,7 +1648,6 @@ function course_delete_module($cmid) {
require_once($CFG->libdir.'/questionlib.php'); require_once($CFG->libdir.'/questionlib.php');
require_once($CFG->dirroot.'/blog/lib.php'); require_once($CFG->dirroot.'/blog/lib.php');
require_once($CFG->dirroot.'/calendar/lib.php'); require_once($CFG->dirroot.'/calendar/lib.php');
require_once($CFG->dirroot.'/tag/lib.php');
// Get the course module. // Get the course module.
if (!$cm = $DB->get_record('course_modules', array('id' => $cmid))) { if (!$cm = $DB->get_record('course_modules', array('id' => $cmid))) {
...@@ -1717,7 +1716,7 @@ function course_delete_module($cmid) { ...@@ -1717,7 +1716,7 @@ function course_delete_module($cmid) {
'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY)); 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
// Delete all tag instances associated with the instance of this module. // Delete all tag instances associated with the instance of this module.
tag_delete_instances('mod_' . $modulename, $modcontext->id); core_tag::delete_instances('mod_' . $modulename, null, $modcontext->id);
// Delete the context. // Delete the context.
context_helper::delete_instance(CONTEXT_MODULE, $cm->id); context_helper::delete_instance(CONTEXT_MODULE, $cm->id);
......
...@@ -60,6 +60,7 @@ $string['cachedef_plugin_manager'] = 'Plugin info manager'; ...@@ -60,6 +60,7 @@ $string['cachedef_plugin_manager'] = 'Plugin info manager';
$string['cachedef_questiondata'] = 'Question definitions'; $string['cachedef_questiondata'] = 'Question definitions';
$string['cachedef_repositories'] = 'Repositories instances data'; $string['cachedef_repositories'] = 'Repositories instances data';
$string['cachedef_string'] = 'Language string cache'; $string['cachedef_string'] = 'Language string cache';
$string['cachedef_tags'] = 'Tags collections and areas';
$string['cachedef_userselections'] = 'Data used to persist user selections throughout Moodle'; $string['cachedef_userselections'] = 'Data used to persist user selections throughout Moodle';
$string['cachedef_yuimodules'] = 'YUI Module definitions'; $string['cachedef_yuimodules'] = 'YUI Module definitions';
$string['cachelock_file_default'] = 'Default file locking'; $string['cachelock_file_default'] = 'Default file locking';
......
...@@ -20,3 +20,4 @@ updated,core_tag ...@@ -20,3 +20,4 @@ updated,core_tag
withselectedtags,core_tag withselectedtags,core_tag
tag:create,core_role tag:create,core_role
categoriesanditems,core_grades categoriesanditems,core_grades
taggedwith,core_tag
...@@ -421,6 +421,7 @@ $string['submissionoutofsequencefriendlymessage'] = "You have entered data outsi ...@@ -421,6 +421,7 @@ $string['submissionoutofsequencefriendlymessage'] = "You have entered data outsi
$string['submit'] = 'Submit'; $string['submit'] = 'Submit';
$string['submitandfinish'] = 'Submit and finish'; $string['submitandfinish'] = 'Submit and finish';
$string['submitted'] = 'Submit: {$a}'; $string['submitted'] = 'Submit: {$a}';
$string['tagarea_question'] = 'Questions';
$string['technicalinfo'] = 'Technical information'; $string['technicalinfo'] = 'Technical information';
$string['technicalinfo_help'] = 'This technical information is probably only useful for developers working on new question types. It may also be helpful when trying to diagnose problems with questions.'; $string['technicalinfo_help'] = 'This technical information is probably only useful for developers working on new question types. It may also be helpful when trying to diagnose problems with questions.';
$string['technicalinfominfraction'] = 'Minimum fraction: {$a}'; $string['technicalinfominfraction'] = 'Minimum fraction: {$a}';
......
...@@ -24,12 +24,19 @@ ...@@ -24,12 +24,19 @@
$string['added'] = 'Official tag(s) added'; $string['added'] = 'Official tag(s) added';
$string['addotags'] = 'Add official tags'; $string['addotags'] = 'Add official tags';
$string['addtagcoll'] = 'Add tag collection';
$string['addtagtomyinterests'] = 'Add "{$a}" to my interests'; $string['addtagtomyinterests'] = 'Add "{$a}" to my interests';
$string['alltagpages'] = 'All tag pages'; $string['alltagpages'] = 'All tag pages';
$string['backtoallitems'] = 'Back to all items tagged with "{$a}"';
$string['changessaved'] = 'Changes saved';
$string['changetagcoll'] = 'Change tag collection of area {$a}';
$string['collnameexplained'] = 'Leave the field empty to use the default value: {$a}';
$string['component'] = 'Component';
$string['confirmdeletetag'] = 'Are you sure you want to delete this tag?'; $string['confirmdeletetag'] = 'Are you sure you want to delete this tag?';
$string['confirmdeletetags'] = 'Are you sure you want to delete selected tags?'; $string['confirmdeletetags'] = 'Are you sure you want to delete selected tags?';
$string['count'] = 'Count'; $string['count'] = 'Count';
$string['coursetags'] = 'Course tags'; $string['coursetags'] = 'Course tags';
$string['defautltagcoll'] = 'Default collection';
$string['delete'] = 'Delete'; $string['delete'] = 'Delete';
$string['deleteselected'] = 'Delete selected'; $string['deleteselected'] = 'Delete selected';
$string['deleted'] = 'Tag(s) deleted'; $string['deleted'] = 'Tag(s) deleted';
...@@ -38,15 +45,20 @@ $string['description'] = 'Description'; ...@@ -38,15 +45,20 @@ $string['description'] = 'Description';
$string['editname'] = 'Edit tag name'; $string['editname'] = 'Edit tag name';
$string['edittag'] = 'Edit this tag'; $string['edittag'] = 'Edit this tag';
$string['entertags'] = 'Enter tags...'; $string['entertags'] = 'Enter tags...';
$string['edittagcoll'] = 'Edit tag collection {$a}';
$string['errortagfrontpage'] = 'Tagging the site main page is not allowed'; $string['errortagfrontpage'] = 'Tagging the site main page is not allowed';
$string['errorupdatingrecord'] = 'Error updating tag record'; $string['errorupdatingrecord'] = 'Error updating tag record';
$string['eventtagadded'] = 'Tag added to an item'; $string['eventtagadded'] = 'Tag added to an item';
$string['eventtagcolldeleted'] = 'Tag collection deleted';
$string['eventtagcollcreated'] = 'Tag collection created';
$string['eventtagcollupdated'] = 'Tag collection updatedhp ';
$string['eventtagcreated'] = 'Tag created'; $string['eventtagcreated'] = 'Tag created';
$string['eventtagdeleted'] = 'Tag deleted'; $string['eventtagdeleted'] = 'Tag deleted';
$string['eventtagflagged'] = 'Tag flagged'; $string['eventtagflagged'] = 'Tag flagged';
$string['eventtagremoved'] = 'Tag removed from an item'; $string['eventtagremoved'] = 'Tag removed from an item';
$string['eventtagunflagged'] = 'Tag unflagged'; $string['eventtagunflagged'] = 'Tag unflagged';
$string['eventtagupdated'] = 'Tag updated'; $string['eventtagupdated'] = 'Tag updated';
$string['exclusivemode'] = 'Show only tagged {$a->tagarea}';
$string['flag'] = 'Flag'; $string['flag'] = 'Flag';
$string['flagged'] = 'Tag flagged'; $string['flagged'] = 'Tag flagged';
$string['flagasinappropriate'] = 'Flag as inappropriate'; $string['flagasinappropriate'] = 'Flag as inappropriate';
...@@ -54,17 +66,25 @@ $string['helprelatedtags'] = 'Comma separated related tags'; ...@@ -54,17 +66,25 @@ $string['helprelatedtags'] = 'Comma separated related tags';
$string['changename'] = 'Change tag name'; $string['changename'] = 'Change tag name';
$string['changetype'] = 'Change tag type'; $string['changetype'] = 'Change tag type';
$string['id'] = 'id'; $string['id'] = 'id';
$string['inalltagcoll'] = 'Everywhere';
$string['itemstaggedwith'] = '{$a->tagarea} tagged with "{$a->tag}"';
$string['lesstags'] = 'less...';
$string['manageofficialtags'] = 'Manage official tags'; $string['manageofficialtags'] = 'Manage official tags';
$string['managetags'] = 'Manage tags'; $string['managetags'] = 'Manage tags';
$string['managetagcolls'] = 'Manage tag collections';
$string['moretags'] = 'more...';
$string['name'] = 'Tag name'; $string['name'] = 'Tag name';
$string['namesalreadybeeingused'] = 'Tag names already being used'; $string['namesalreadybeeingused'] = 'Tag names already being used';
$string['newnamefor'] = 'New name for tag {$a}'; $string['newnamefor'] = 'New name for tag {$a}';
$string['nextpage'] = 'More';
$string['notagsfound'] = 'No tags matching "{$a}" found';
$string['noresultsfor'] = 'No results for "{$a}"'; $string['noresultsfor'] = 'No results for "{$a}"';
$string['nothingtoupdate'] = 'Nothing to update'; $string['nothingtoupdate'] = 'Nothing to update';
$string['officialtag'] = 'Official'; $string['officialtag'] = 'Official';
$string['otags'] = 'Official tags'; $string['otags'] = 'Official tags';
$string['othertags'] = 'Other tags'; $string['othertags'] = 'Other tags';
$string['owner'] = 'Owner'; $string['owner'] = 'Owner';
$string['prevpage'] = 'Back';
$string['ptags'] = 'User defined tags (Comma separated)'; $string['ptags'] = 'User defined tags (Comma separated)';
$string['relatedblogs'] = 'Most recent blog entries'; $string['relatedblogs'] = 'Most recent blog entries';
$string['relatedtags'] = 'Related tags'; $string['relatedtags'] = 'Related tags';
...@@ -75,16 +95,29 @@ $string['responsiblewillbenotified'] = 'The person responsible will be notified' ...@@ -75,16 +95,29 @@ $string['responsiblewillbenotified'] = 'The person responsible will be notified'
$string['rssdesc'] = 'This RSS feed was automatically generated by Moodle and contains user generated tags for courses.'; $string['rssdesc'] = 'This RSS feed was automatically generated by Moodle and contains user generated tags for courses.';
$string['rsstitle'] = 'Course tags RSS feed for user: {$a}'; $string['rsstitle'] = 'Course tags RSS feed for user: {$a}';
$string['search'] = 'Search'; $string['search'] = 'Search';
$string['searchable'] = 'Searchable';
$string['searchable_help'] = 'Tags in this tag collection can be searched for on "Search tags" page. If unchecked, tags can still be accessed by clicking on them or via different search interfaces.';
$string['searchresultsfor'] = 'Search results for "{$a}"'; $string['searchresultsfor'] = 'Search results for "{$a}"';
$string['searchtags'] = 'Search tags'; $string['searchtags'] = 'Search tags';
$string['seeallblogs'] = 'See all blog entries tagged with "{$a}"...'; $string['seeallblogs'] = 'See all blog entries tagged with "{$a}"';
$string['select'] = 'Select'; $string['select'] = 'Select';
$string['selectcoll'] = 'Select tag collection';
$string['selecttag'] = 'Select tag {$a}'; $string['selecttag'] = 'Select tag {$a}';
$string['settypedefault'] = 'Remove from official tags'; $string['settypedefault'] = 'Remove from official tags';
$string['settypeofficial'] = 'Make official'; $string['settypeofficial'] = 'Make official';
$string['showingfirsttags'] = 'Showing {$a} most popular tags';
$string['suredeletecoll'] = 'Are you sure you want to delete tag collection "{$a}"?';
$string['tag'] = 'Tag'; $string['tag'] = 'Tag';
$string['tagarea_blog_external'] = 'External blog posts';
$string['tagarea_post'] = 'Blog posts';
$string['tagarea_user'] = 'User interests';
$string['tagarea_course'] = 'Courses';
$string['tagareaenabled'] = 'Enabled';
$string['tagareaname'] = 'Name';
$string['tagareas'] = 'Tag areas';
$string['tagcollection'] = 'Tag collection';
$string['tagcollections'] = 'Tag collections';
$string['tagdescription'] = 'Tag description'; $string['tagdescription'] = 'Tag description';
$string['taggedwith'] = 'tagged with "{$a}"';
$string['tags'] = 'Tags'; $string['tags'] = 'Tags';
$string['tagsaredisabled'] = 'Tags are disabled'; $string['tagsaredisabled'] = 'Tags are disabled';
$string['tagtype'] = 'Tag type'; $string['tagtype'] = 'Tag type';
...@@ -107,3 +140,7 @@ $string['tagtype_official'] = 'Official'; ...@@ -107,3 +140,7 @@ $string['tagtype_official'] = 'Official';
$string['thistaghasnodesc'] = 'This tag currently has no description.'; $string['thistaghasnodesc'] = 'This tag currently has no description.';
$string['updated'] = 'Updated'; $string['updated'] = 'Updated';
$string['withselectedtags'] = 'With selected tags...'; $string['withselectedtags'] = 'With selected tags...';
// Deprecated since 3.1 .
$string['taggedwith'] = 'tagged with "{$a}"';
...@@ -166,9 +166,8 @@ function uninstall_plugin($type, $name) { ...@@ -166,9 +166,8 @@ function uninstall_plugin($type, $name) {
echo $OUTPUT->heading($pluginname); echo $OUTPUT->heading($pluginname);
// Delete all tag instances associated with this plugin. // Delete all tag areas, collections and instances associated with this plugin.
require_once($CFG->dirroot . '/tag/lib.php'); core_tag_area::uninstall($component);
tag_delete_instances($component);
// Custom plugin uninstall. // Custom plugin uninstall.
$plugindirectory = core_component::get_plugin_directory($type, $name); $plugindirectory = core_component::get_plugin_directory($type, $name);
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
...@@ -27,9 +27,37 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str' ...@@ -27,9 +27,37 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
return /** @alias module:core/tag */ { return /** @alias module:core/tag */ {
/** /**
* Initialises handlers for AJAX methods. * Initialises tag index page.
* *
* @method init * @method init_tagindex_page
*/
init_tagindex_page: function() {
// Click handler for changing tag type.
$('body').delegate('.tagarea[data-ta] a[data-quickload=1]', 'click', function(e) {
e.preventDefault();
var target = $( this ),
query = target.context.search.replace(/^\?/, ''),
tagarea = target.closest('.tagarea[data-ta]'),
args = query.split('&').reduce(function(s,c){var t=c.split('=');s[t[0]]=decodeURIComponent(t[1]);return s;},{});
var promises = ajax.call([{
methodname: 'core_tag_get_tagindex',
args: { tagindex: args }
}], true);
$.when.apply($, promises)
.done( function(data) {
templates.render('core_tag/index', data).done(function(html) {
tagarea.replaceWith(html);
});
});
});
},
/**
* Initialises tag management page.
*
* @method init_manage_page
*/ */
init_manage_page: function() { init_manage_page: function() {
......
...@@ -1497,10 +1497,10 @@ class block_manager { ...@@ -1497,10 +1497,10 @@ class block_manager {
if ($bits[0] == 'tag' && !empty($this->page->subpage)) { if ($bits[0] == 'tag' && !empty($this->page->subpage)) {
// better navbar for tag pages // better navbar for tag pages
$editpage->navbar->add(get_string('tags'), new moodle_url('/tag/')); $editpage->navbar->add(get_string('tags'), new moodle_url('/tag/'));
$tag = tag_get('id', $this->page->subpage, '*'); $tag = core_tag_tag::get($this->page->subpage);
// tag search page doesn't have subpageid // tag search page doesn't have subpageid
if ($tag) { if ($tag) {
$editpage->navbar->add($tag->name, new moodle_url('/tag/index.php', array('id'=>$tag->id))); $editpage->navbar->add($tag->get_display_name(), $tag->get_view_url());
} }
} }
$editpage->navbar->add($block->get_title()); $editpage->navbar->add($block->get_title());
......
...@@ -74,6 +74,34 @@ class tag_added extends base { ...@@ -74,6 +74,34 @@ class tag_added extends base {
s($this->other['itemtype']) . "' with id '{$this->other['itemid']}'."; s($this->other['itemtype']) . "' with id '{$this->other['itemid']}'.";
} }
/**
* Creates an event from taginstance object
*
* @since Moodle 3.1
* @param stdClass $taginstance
* @param string $tagname
* @param string $tagrawname
* @param bool $addsnapshot trust that $taginstance has all necessary fields and add it as a record snapshot
* @return tag_added
*/
public static function create_from_tag_instance($taginstance, $tagname, $tagrawname, $addsnapshot = false) {
$event = self::create(array(
'objectid' => $taginstance->id,
'contextid' => $taginstance->contextid,
'other' => array(
'tagid' => $taginstance->tagid,
'tagname' => $tagname,
'tagrawname' => $tagrawname,
'itemid' => $taginstance->itemid,
'itemtype' => $taginstance->itemtype
)
));
if ($addsnapshot) {
$event->add_record_snapshot('tag_instance', $taginstance);
}
return $event;
}
/** /**
* Return legacy data for add_to_log(). * Return legacy data for add_to_log().
* *
......
<?php
// This file is part of Moodle - http://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 <http://www.gnu.org/licenses/>.
/**
* Tag collection created event.
*
* @package core
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\event;
defined('MOODLE_INTERNAL') || die();
/**
* Tag collection created event class.
*
* @package core
* @since Moodle 3.0
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tag_collection_created extends base {
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['objecttable'] = 'tag_coll';
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Utility method to create new event.
*
* @param object $tagcoll
* @return user_graded
*/
public static function create_from_record($tagcoll) {
$event = self::create(array(
'objectid' => $tagcoll->id,
'context' => \context_system::instance(),
));
$event->add_record_snapshot('tag_coll', $tagcoll);
return $event;
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventtagcollcreated', 'core_tag');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' created the tag collection with id '$this->objectid'";
}
}
<?php
// This file is part of Moodle - http://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 <http://www.gnu.org/licenses/>.
/**
* Tag collection deleted event.
*
* @package core
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\event;
defined('MOODLE_INTERNAL') || die();
/**
* Tag collection deleted event class.
*
* @package core
* @since Moodle 3.0
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tag_collection_deleted extends base {
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['objecttable'] = 'tag_coll';
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Utility method to create new event.
*
* @param object $tagcoll
* @return user_graded
*/
public static function create_from_record($tagcoll) {
$event = self::create(array(
'objectid' => $tagcoll->id,
'context' => \context_system::instance(),
));
$event->add_record_snapshot('tag_coll', $tagcoll);
return $event;
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventtagcolldeleted', 'core_tag');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' deleted the tag collection with id '$this->objectid'";
}
}
<?php
// This file is part of Moodle - http://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 <http://www.gnu.org/licenses/>.
/**
* Tag collection updated event.
*
* @package core
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\event;
defined('MOODLE_INTERNAL') || die();
/**
* Tag collection updated event class.
*
* @package core
* @since Moodle 3.0
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tag_collection_updated extends base {
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['objecttable'] = 'tag_coll';
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Utility method to create new event.
*
* @param object $tagcoll
* @return user_graded
*/
public static function create_from_record($tagcoll) {
$event = self::create(array(
'objectid' => $tagcoll->id,
'context' => \context_system::instance(),
));
$event->add_record_snapshot('tag_coll', $tagcoll);
return $event;
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventtagcollupdated', 'core_tag');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' updated the tag collection with id '$this->objectid'";
}
}
...@@ -52,6 +52,26 @@ class tag_created extends base { ...@@ -52,6 +52,26 @@ class tag_created extends base {
$this->data['edulevel'] = self::LEVEL_OTHER; $this->data['edulevel'] = self::LEVEL_OTHER;
} }
/**
* Creates an event from tag object
*
* @since Moodle 3.1
* @param \core_tag_tag|\stdClass $tag
* @return tag_created
*/
public static function create_from_tag($tag) {
$event = self::create(array(
'objectid' => $tag->id,
'relateduserid' => $tag->userid,
'context' => \context_system::instance(),
'other' => array(
'name' => $tag->name,