MDL-83941 tags: prevent users from browsing unsearchable collections
This commit is contained in:
@@ -77,24 +77,14 @@ class block_tags_edit_form extends block_edit_form {
|
||||
* @param object $mform the form being built.
|
||||
*/
|
||||
protected function add_collection_selector($mform) {
|
||||
$tagcolls = core_tag_collection::get_collections_menu(false, false, get_string('anycollection', 'block_tags'));
|
||||
$tagcolls = core_tag_collection::get_collections_menu(false, true, get_string('anycollection', 'block_tags'));
|
||||
if (count($tagcolls) <= 1) {
|
||||
$mform->addElement('hidden', 'config_tagcoll', 0);
|
||||
$mform->setType('config_tagcoll', PARAM_INT);
|
||||
return;
|
||||
}
|
||||
|
||||
$tagcollssearchable = core_tag_collection::get_collections_menu(false, true);
|
||||
$hasunsearchable = false;
|
||||
foreach ($tagcolls as $id => $name) {
|
||||
if ($id && !array_key_exists($id, $tagcollssearchable)) {
|
||||
$hasunsearchable = true;
|
||||
$tagcolls[$id] = $name . '*';
|
||||
}
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'config_tagcoll', get_string('tagcollection', 'block_tags'), $tagcolls);
|
||||
if ($hasunsearchable) {
|
||||
$mform->addHelpButton('config_tagcoll', 'tagcollection', 'block_tags');
|
||||
}
|
||||
$mform->setDefault('config_tagcoll', 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,3 +47,33 @@ Feature: Block tags displaying tag cloud
|
||||
And I should see "User interests" in the ".tag-index-items h3" "css_element"
|
||||
And I should see "Teacher 1"
|
||||
And I log out
|
||||
|
||||
@javascript
|
||||
Scenario: Tag block configuration allows to select from searchable tag collections only
|
||||
When I log in as "student1"
|
||||
And I turn editing mode on
|
||||
And I add the "Tags" block
|
||||
And I configure the "Tags" block
|
||||
Then I should not see "Tag collection"
|
||||
And I press "Save changes"
|
||||
And I log out
|
||||
And I log in as "admin"
|
||||
And I navigate to "Appearance > Manage tags" in site administration
|
||||
And I follow "Add tag collection"
|
||||
And I set the following fields to these values:
|
||||
| Name | Collection1 |
|
||||
| Searchable | 1 |
|
||||
And I press "Create"
|
||||
And I follow "Add tag collection"
|
||||
And I set the following fields to these values:
|
||||
| Name | Collection2 |
|
||||
| Searchable | 0 |
|
||||
And I press "Create"
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I turn editing mode on
|
||||
And I am on homepage
|
||||
And I configure the "Tags" block
|
||||
And the "Tag collection" select box should contain "Collection1"
|
||||
And the "Tag collection" select box should not contain "Collection2"
|
||||
And I press "Save changes"
|
||||
|
||||
@@ -359,9 +359,15 @@ class core_tag_collection {
|
||||
|
||||
$fromclause = 'FROM {tag_instance} ti JOIN {tag} tg ON tg.id = ti.tagid';
|
||||
$whereclause = 'WHERE ti.itemtype <> \'tag\'';
|
||||
list($sql, $params) = $DB->get_in_or_equal($tagcollid ? array($tagcollid) :
|
||||
array_keys(self::get_collections(true)));
|
||||
|
||||
// Get tags from all searchable tag collections, if $tagcollid is specifid, limit only to this collection.
|
||||
$tagcollids = array_keys(self::get_collections(true));
|
||||
if ($tagcollid) {
|
||||
$tagcollids = array_intersect($tagcollids, [$tagcollid]);
|
||||
}
|
||||
list($sql, $params) = $DB->get_in_or_equal($tagcollids, SQL_PARAMS_QM, 'param', true, -1);
|
||||
$whereclause .= ' AND tg.tagcollid ' . $sql;
|
||||
|
||||
if ($isstandard) {
|
||||
$whereclause .= ' AND tg.isstandard = 1';
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace core_tag;
|
||||
use core_tag_area;
|
||||
use core_tag_collection;
|
||||
use core_tag_tag;
|
||||
use core_tag;
|
||||
|
||||
/**
|
||||
* Tag related unit tests.
|
||||
@@ -1940,4 +1941,51 @@ final class taglib_test extends \advanced_testcase {
|
||||
$record['id'] = $DB->insert_record('tag_instance', $record);
|
||||
return (object) $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the contents of the a tagcloud
|
||||
*
|
||||
* @param array $tags
|
||||
* @param \core_tag\output\tagcloud $tagcloud
|
||||
*/
|
||||
protected function assert_tag_cloud_contains_tags(array $tags, \core_tag\output\tagcloud $tagcloud) {
|
||||
global $PAGE;
|
||||
$renderer = $PAGE->get_renderer('core', 'tag');
|
||||
$result = $tagcloud->export_for_template($renderer);
|
||||
$result = json_decode(json_encode($result), true);
|
||||
$this->assertEqualsCanonicalizing($tags, array_values(array_column($result['tags'], 'name')));
|
||||
}
|
||||
|
||||
public function test_get_tag_cloud(): void {
|
||||
global $DB, $PAGE;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create a course and a user with tags.
|
||||
$this->getDataGenerator()->create_course(['tags' => 'cats,animals']);
|
||||
$this->getDataGenerator()->create_user(['interests' => 'dogs,animals']);
|
||||
|
||||
// Default tag cloud contains all three tags.
|
||||
$tagcloud = core_tag_collection::get_tag_cloud(0);
|
||||
$this->assert_tag_cloud_contains_tags(['animals', 'cats', 'dogs'], $tagcloud);
|
||||
|
||||
// Create two new tag collections, move course tags to C1 and user tags to C2.
|
||||
$c1 = core_tag_collection::create((object)['name' => 'C1', 'searchable' => 1]);
|
||||
$c2 = core_tag_collection::create((object)['name' => 'C2', 'searchable' => 1]);
|
||||
$tagareacourse = $DB->get_record('tag_area', ['component' => 'core', 'itemtype' => 'course'], '*', MUST_EXIST);
|
||||
core_tag_area::update($tagareacourse, ['tagcollid' => $c1->id]);
|
||||
$tagareauser = $DB->get_record('tag_area', ['component' => 'core', 'itemtype' => 'user'], '*', MUST_EXIST);
|
||||
core_tag_area::update($tagareauser, ['tagcollid' => $c2->id]);
|
||||
|
||||
// Tag cloud still has all tags and you can also search by a collection. Tag 'animals' now has two different view links.
|
||||
$this->assert_tag_cloud_contains_tags(['animals', 'animals', 'cats', 'dogs'], core_tag_collection::get_tag_cloud(0));
|
||||
$this->assert_tag_cloud_contains_tags(['animals', 'cats'], core_tag_collection::get_tag_cloud($c1->id));
|
||||
$this->assert_tag_cloud_contains_tags(['animals', 'dogs'], core_tag_collection::get_tag_cloud($c2->id));
|
||||
|
||||
// Make user interest tag area not searchable.
|
||||
core_tag_collection::update($c2, ['searchable' => 0]);
|
||||
// Check that the user interest tags do not appear in the tagclouds.
|
||||
$this->assert_tag_cloud_contains_tags(['animals', 'cats'], core_tag_collection::get_tag_cloud(0));
|
||||
$this->assert_tag_cloud_contains_tags(['animals', 'cats'], core_tag_collection::get_tag_cloud($c1->id));
|
||||
$this->assert_tag_cloud_contains_tags([], core_tag_collection::get_tag_cloud($c2->id));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user