/** * Returns tags related to a tag * * Related tags of a tag come from two sources: * - manually added related tags, which are tag_instance entries for that tag * - correlated tags, which are a calculated * * @param string $tag_name_or_id is a single **normalized** tag name or the id * of a tag * @param int $type the function will return either manually * (TAG_RELATED_MANUAL) related tags or correlated (TAG_RELATED_CORRELATED) * tags. Default is TAG_RELATED_ALL, which returns everything. * @param int $limitnum return a subset comprising this many records (optional, * default is 10) * @return array an array of tag objects */ function tag_get_related_tags($tagid, $type = TAG_RELATED_ALL, $limitnum = 10) { $related_tags = array(); if ($type == TAG_RELATED_ALL || $type == TAG_RELATED_MANUAL) { //gets the manually added related tags $related_tags = tag_get_tags('tag', $tagid); } if ($type == TAG_RELATED_ALL || $type == TAG_RELATED_CORRELATED) { //gets the correlated tags $automatic_related_tags = tag_get_correlated($tagid, $limitnum); if (is_array($automatic_related_tags)) { $related_tags = array_merge($related_tags, $automatic_related_tags); } } return array_slice(object_array_unique($related_tags), 0, $limitnum); }
/** * Test for function tag_compute_correlations() that is part of tag cron */ public function test_correlations() { global $DB; $task = new \core\task\tag_cron_task(); $user = $this->getDataGenerator()->create_user(); $this->setUser($user); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $user5 = $this->getDataGenerator()->create_user(); $user6 = $this->getDataGenerator()->create_user(); // Several records have both 'cat' and 'cats' tags attached to them. // This will make those tags automatically correlated. // Same with 'dog', 'dogs' and 'puppy. core_tag_tag::set_item_tags('core', 'user', $user1->id, context_user::instance($user1->id), array('cat', 'cats')); core_tag_tag::set_item_tags('core', 'user', $user2->id, context_user::instance($user2->id), array('cat', 'cats', 'kitten')); core_tag_tag::set_item_tags('core', 'user', $user3->id, context_user::instance($user3->id), array('cat', 'cats')); core_tag_tag::set_item_tags('core', 'user', $user4->id, context_user::instance($user4->id), array('dog', 'dogs', 'puppy')); core_tag_tag::set_item_tags('core', 'user', $user5->id, context_user::instance($user5->id), array('dog', 'dogs', 'puppy')); core_tag_tag::set_item_tags('core', 'user', $user6->id, context_user::instance($user6->id), array('dog', 'dogs', 'puppy')); $tags = core_tag_tag::get_by_name_bulk(core_tag_collection::get_default(), array('cat', 'cats', 'dog', 'dogs', 'kitten', 'puppy')); $tags = array_map(function ($t) { return $t->id; }, $tags); // Add manual relation between tags 'cat' and 'kitten'. core_tag_tag::get($tags['cat'])->set_related_tags(array('kitten')); $task->compute_correlations(); $this->assertEquals($tags['cats'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cat']))); $this->assertEquals($tags['cat'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cats']))); $this->assertEquals($tags['dogs'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dog']))); $this->assertEquals($tags['dog'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dogs']))); $this->assertEquals($tags['dog'] . ',' . $tags['dogs'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['puppy']))); // Make sure get_correlated_tags() returns 'cats' as the only correlated tag to the 'cat'. $correlatedtags = array_values(core_tag_tag::get($tags['cat'])->get_correlated_tags(true)); $this->assertCount(3, $correlatedtags); // This will return all existing instances but they all point to the same tag. $this->assertEquals('cats', $correlatedtags[0]->rawname); $this->assertEquals('cats', $correlatedtags[1]->rawname); $this->assertEquals('cats', $correlatedtags[2]->rawname); $correlatedtags = array_values(core_tag_tag::get($tags['cat'])->get_correlated_tags()); $this->assertCount(1, $correlatedtags); // Duplicates are filtered out here. $this->assertEquals('cats', $correlatedtags[0]->rawname); // Make sure tag_get_correlated() returns 'dogs' and 'puppy' as the correlated tags to the 'dog'. $correlatedtags = core_tag_tag::get($tags['dog'])->get_correlated_tags(true); $this->assertCount(6, $correlatedtags); // 2 tags times 3 instances. $correlatedtags = array_values(core_tag_tag::get($tags['dog'])->get_correlated_tags()); $this->assertCount(2, $correlatedtags); $this->assertEquals('dogs', $correlatedtags[0]->rawname); $this->assertEquals('puppy', $correlatedtags[1]->rawname); // Function get_related_tags() will return both related and correlated tags. $relatedtags = array_values(core_tag_tag::get($tags['cat'])->get_related_tags()); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // Also test deprecated method tag_get_related_tags() and tag_get_correlated(). $correlatedtags = array_values(tag_get_correlated($tags['cat'])); $this->assertDebuggingCalled(); $this->assertCount(3, $correlatedtags); // This will return all existing instances but they all point to the same tag. $this->assertEquals('cats', $correlatedtags[0]->rawname); $this->assertEquals('cats', $correlatedtags[1]->rawname); $this->assertEquals('cats', $correlatedtags[2]->rawname); $correlatedtags = array_values(tag_get_related_tags($tags['cat'], TAG_RELATED_CORRELATED)); $this->assertDebuggingCalled(); $this->assertCount(1, $correlatedtags); // Duplicates are filtered out here. $this->assertEquals('cats', $correlatedtags[0]->rawname); $correlatedtags = array_values(tag_get_correlated($tags['dog'])); $this->assertDebuggingCalled(); $this->assertCount(6, $correlatedtags); // 2 tags times 3 instances. $correlatedtags = array_values(tag_get_related_tags($tags['dog'], TAG_RELATED_CORRELATED)); $this->assertDebuggingCalled(); $this->assertCount(2, $correlatedtags); $this->assertEquals('dogs', $correlatedtags[0]->rawname); $this->assertEquals('puppy', $correlatedtags[1]->rawname); $relatedtags = array_values(tag_get_related_tags($tags['cat'])); $this->assertDebuggingCalled(); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // End of testing deprecated methods. // If we then manually set 'cat' and 'cats' as related, get_related_tags() will filter out duplicates. core_tag_tag::get($tags['cat'])->set_related_tags(array('kitten', 'cats')); $relatedtags = array_values(core_tag_tag::get($tags['cat'])->get_related_tags()); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // Make sure core_tag_tag::get_item_tags(), core_tag_tag::get_correlated_tags() return the same set of fields. $relatedtags = core_tag_tag::get_item_tags('core', 'tag', $tags['cat']); $relatedtag = reset($relatedtags); $correlatedtags = core_tag_tag::get($tags['cat'])->get_correlated_tags(); $correlatedtag = reset($correlatedtags); $this->assertEquals(array_keys((array) $relatedtag->to_object()), array_keys((array) $correlatedtag->to_object())); // Make sure tag_get_correlated() and tag_get_tags() return the same set of fields. // Both functions were deprecated in 3.1. $relatedtags = tag_get_tags('tag', $tags['cat']); $this->assertDebuggingCalled(); $relatedtag = reset($relatedtags); $correlatedtags = tag_get_correlated($tags['cat']); $this->assertDebuggingCalled(); $correlatedtag = reset($correlatedtags); $this->assertEquals(array_keys((array) $relatedtag), array_keys((array) $correlatedtag)); }
/** * Returns tags related to a tag * * Related tags of a tag come from two sources: * - manually added related tags, which are tag_instance entries for that tag * - correlated tags, which are calculated * * @package core_tag * @category tag * @access public * @param string $tagid is a single **normalized** tag name or the id of a tag * @param int $type the function will return either manually (TAG_RELATED_MANUAL) related tags or correlated * (TAG_RELATED_CORRELATED) tags. Default is TAG_RELATED_ALL, which returns everything. * @param int $limitnum (optional) return a subset comprising this many records, the default is 10 * @return array an array of tag objects */ function tag_get_related_tags($tagid, $type = TAG_RELATED_ALL, $limitnum = 10) { $related_tags = array(); if ($type == TAG_RELATED_ALL || $type == TAG_RELATED_MANUAL) { //gets the manually added related tags $related_tags = tag_get_tags('tag', $tagid); } if ($type == TAG_RELATED_ALL || $type == TAG_RELATED_CORRELATED) { //gets the correlated tags $automatic_related_tags = tag_get_correlated($tagid); $related_tags = array_merge($related_tags, $automatic_related_tags); } // Remove duplicated tags (multiple instances of the same tag). $seen = array(); foreach ($related_tags as $instance => $tag) { if (isset($seen[$tag->id])) { unset($related_tags[$instance]); } else { $seen[$tag->id] = 1; } } return array_slice($related_tags, 0, $limitnum); }
/** * Test for function tag_compute_correlations() that is part of tag cron */ public function test_correlations() { global $DB; $task = new \core\task\tag_cron_task(); $tags = array_map(function ($t) { return $t->id; }, $this->prepare_correlated()); $task->compute_correlations(); $this->assertEquals($tags['cats'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cat']))); $this->assertEquals($tags['cat'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cats']))); $this->assertEquals($tags['dogs'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dog']))); $this->assertEquals($tags['dog'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dogs']))); $this->assertEquals($tags['dog'] . ',' . $tags['dogs'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['puppy']))); // Make sure get_correlated_tags() returns 'cats' as the only correlated tag to the 'cat'. $correlatedtags = array_values(core_tag_tag::get($tags['cat'])->get_correlated_tags(true)); $this->assertCount(3, $correlatedtags); // This will return all existing instances but they all point to the same tag. $this->assertEquals('cats', $correlatedtags[0]->rawname); $this->assertEquals('cats', $correlatedtags[1]->rawname); $this->assertEquals('cats', $correlatedtags[2]->rawname); $correlatedtags = array_values(core_tag_tag::get($tags['cat'])->get_correlated_tags()); $this->assertCount(1, $correlatedtags); // Duplicates are filtered out here. $this->assertEquals('cats', $correlatedtags[0]->rawname); // Make sure tag_get_correlated() returns 'dogs' and 'puppy' as the correlated tags to the 'dog'. $correlatedtags = core_tag_tag::get($tags['dog'])->get_correlated_tags(true); $this->assertCount(6, $correlatedtags); // 2 tags times 3 instances. $correlatedtags = array_values(core_tag_tag::get($tags['dog'])->get_correlated_tags()); $this->assertCount(2, $correlatedtags); $this->assertEquals('dogs', $correlatedtags[0]->rawname); $this->assertEquals('puppy', $correlatedtags[1]->rawname); // Function get_related_tags() will return both related and correlated tags. $relatedtags = array_values(core_tag_tag::get($tags['cat'])->get_related_tags()); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // Also test deprecated method tag_get_related_tags() and tag_get_correlated(). $correlatedtags = array_values(tag_get_correlated($tags['cat'])); $this->assertDebuggingCalled(); $this->assertCount(3, $correlatedtags); // This will return all existing instances but they all point to the same tag. $this->assertEquals('cats', $correlatedtags[0]->rawname); $this->assertEquals('cats', $correlatedtags[1]->rawname); $this->assertEquals('cats', $correlatedtags[2]->rawname); $correlatedtags = array_values(tag_get_related_tags($tags['cat'], TAG_RELATED_CORRELATED)); $this->assertDebuggingCalled(); $this->assertCount(1, $correlatedtags); // Duplicates are filtered out here. $this->assertEquals('cats', $correlatedtags[0]->rawname); $correlatedtags = array_values(tag_get_correlated($tags['dog'])); $this->assertDebuggingCalled(); $this->assertCount(6, $correlatedtags); // 2 tags times 3 instances. $correlatedtags = array_values(tag_get_related_tags($tags['dog'], TAG_RELATED_CORRELATED)); $this->assertDebuggingCalled(); $this->assertCount(2, $correlatedtags); $this->assertEquals('dogs', $correlatedtags[0]->rawname); $this->assertEquals('puppy', $correlatedtags[1]->rawname); $relatedtags = array_values(tag_get_related_tags($tags['cat'])); $this->assertDebuggingCalled(); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // End of testing deprecated methods. // If we then manually set 'cat' and 'cats' as related, get_related_tags() will filter out duplicates. core_tag_tag::get($tags['cat'])->set_related_tags(array('kitten', 'cats')); $relatedtags = array_values(core_tag_tag::get($tags['cat'])->get_related_tags()); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // Make sure core_tag_tag::get_item_tags(), core_tag_tag::get_correlated_tags() return the same set of fields. $relatedtags = core_tag_tag::get_item_tags('core', 'tag', $tags['cat']); $relatedtag = reset($relatedtags); $correlatedtags = core_tag_tag::get($tags['cat'])->get_correlated_tags(); $correlatedtag = reset($correlatedtags); $this->assertEquals(array_keys((array) $relatedtag->to_object()), array_keys((array) $correlatedtag->to_object())); // Make sure tag_get_correlated() and tag_get_tags() return the same set of fields. // Both functions were deprecated in 3.1. $relatedtags = tag_get_tags('tag', $tags['cat']); $this->assertDebuggingCalled(); $relatedtag = reset($relatedtags); $correlatedtags = tag_get_correlated($tags['cat']); $this->assertDebuggingCalled(); $correlatedtag = reset($correlatedtags); $this->assertEquals(array_keys((array) $relatedtag), array_keys((array) $correlatedtag)); }
/** * Test for function tag_compute_correlations() that is part of tag cron */ public function test_correlations() { global $DB; $user = $this->getDataGenerator()->create_user(); $this->setUser($user); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $user5 = $this->getDataGenerator()->create_user(); $user6 = $this->getDataGenerator()->create_user(); // Several records have both 'cat' and 'cats' tags attached to them. // This will make those tags automatically correlated. // Same with 'dog', 'dogs' and 'puppy. tag_set('user', $user1->id, array('cat', 'cats'), 'core', context_user::instance($user1->id)->id); tag_set('user', $user2->id, array('cat', 'cats', 'kitten'), 'core', context_user::instance($user2->id)->id); tag_set('user', $user3->id, array('cat', 'cats'), 'core', context_user::instance($user3->id)->id); tag_set('user', $user4->id, array('dog', 'dogs', 'puppy'), 'core', context_user::instance($user4->id)->id); tag_set('user', $user5->id, array('dog', 'dogs', 'puppy'), 'core', context_user::instance($user5->id)->id); tag_set('user', $user6->id, array('dog', 'dogs', 'puppy'), 'core', context_user::instance($user6->id)->id); $tags = tag_get_id(array('cat', 'cats', 'dog', 'dogs', 'kitten', 'puppy')); // Add manual relation between tags 'cat' and 'kitten'. tag_set('tag', $tags['cat'], array('kitten'), 'core', context_system::instance()->id); tag_compute_correlations(); $this->assertEquals($tags['cats'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cat']))); $this->assertEquals($tags['cat'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cats']))); $this->assertEquals($tags['dogs'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dog']))); $this->assertEquals($tags['dog'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dogs']))); $this->assertEquals($tags['dog'] . ',' . $tags['dogs'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['puppy']))); // Make sure tag_get_correlated() returns 'cats' as the only correlated tag to the 'cat'. $correlatedtags = array_values(tag_get_correlated($tags['cat'])); $this->assertCount(3, $correlatedtags); // This will return all existing instances but they all point to the same tag. $this->assertEquals('cats', $correlatedtags[0]->rawname); $this->assertEquals('cats', $correlatedtags[1]->rawname); $this->assertEquals('cats', $correlatedtags[2]->rawname); $correlatedtags = array_values(tag_get_related_tags($tags['cat'], TAG_RELATED_CORRELATED)); $this->assertCount(1, $correlatedtags); // Duplicates are filtered out here. $this->assertEquals('cats', $correlatedtags[0]->rawname); // Make sure tag_get_correlated() returns 'dogs' and 'puppy' as the correlated tags to the 'dog'. $correlatedtags = array_values(tag_get_correlated($tags['dog'])); $this->assertCount(6, $correlatedtags); // 2 tags times 3 instances. $correlatedtags = array_values(tag_get_related_tags($tags['dog'], TAG_RELATED_CORRELATED)); $this->assertCount(2, $correlatedtags); $this->assertEquals('dogs', $correlatedtags[0]->rawname); $this->assertEquals('puppy', $correlatedtags[1]->rawname); // Function tag_get_related_tags() with default argument will return both related and correlated tags. $relatedtags = array_values(tag_get_related_tags($tags['cat'])); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // If we then manually set 'cat' and 'cats' as related, tag_get_related_tags() will filter out duplicates. tag_set('tag', $tags['cat'], array('kitten', 'cats'), 'core', context_system::instance()->id); $relatedtags = array_values(tag_get_related_tags($tags['cat'])); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // Make sure tag_get_correlated() and tag_get_tags() return the same set of fields. $relatedtags = tag_get_tags('tag', $tags['cat']); $relatedtag = reset($relatedtags); $correlatedtags = tag_get_correlated($tags['cat']); $correlatedtag = reset($correlatedtags); $this->assertEquals(array_keys((array) $relatedtag), array_keys((array) $correlatedtag)); }