MDL-64656 core_tag: New WebService core_tag_get_tagindex_per_area
authorJuan Leyva <juanleyvadelgado@gmail.com>
Wed, 20 Feb 2019 14:23:44 +0000 (15:23 +0100)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Thu, 11 Apr 2019 08:20:44 +0000 (10:20 +0200)
lib/db/services.php
tag/classes/external.php
tag/tests/external_test.php

index 30fdec8..0ea1fd2 100644 (file)
@@ -1514,6 +1514,13 @@ $functions = array(
         'type' => 'write',
         'ajax' => true,
     ),
+    'core_tag_get_tagindex_per_area' => array(
+        'classname' => 'core_tag_external',
+        'methodname' => 'get_tagindex_per_area',
+        'description' => 'Gets tag index page per different areas.',
+        'type' => 'read',
+        'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+    ),
     'core_update_inplace_editable' => array(
         'classname' => 'core_external',
         'methodname' => 'update_inplace_editable',
index 54fa204..86e8212 100644 (file)
@@ -335,4 +335,122 @@ class core_tag_external extends external_api {
             ), 'tag index'
         );
     }
+
+
+    /**
+     * Parameters for function get_tagindex_per_area()
+     *
+     * @return external_function_parameters
+     * @since  Moodle 3.7
+     */
+    public static function get_tagindex_per_area_parameters() {
+        return new external_function_parameters(
+            array(
+                'tagindex' => new external_single_structure(array(
+                    'id' => new external_value(PARAM_INT, 'tag id', VALUE_OPTIONAL, 0),
+                    'tag' => new external_value(PARAM_TAG, 'tag name', VALUE_OPTIONAL, ''),
+                    'tc' => new external_value(PARAM_INT, 'tag collection id', VALUE_OPTIONAL, 0),
+                    'ta' => new external_value(PARAM_INT, 'tag area id', VALUE_OPTIONAL, 0),
+                    'excl' => new external_value(PARAM_BOOL, 'exlusive mode for this tag area', VALUE_OPTIONAL, 0),
+                    'from' => new external_value(PARAM_INT, 'context id where the link was displayed', VALUE_OPTIONAL, 0),
+                    'ctx' => new external_value(PARAM_INT, 'context id where to search for items', VALUE_OPTIONAL, 0),
+                    'rec' => new external_value(PARAM_INT, 'search in the context recursive', VALUE_OPTIONAL, 1),
+                    'page' => new external_value(PARAM_INT, 'page number (0-based)', VALUE_OPTIONAL, 0),
+                ), 'parameters')
+            )
+        );
+    }
+
+    /**
+     * Returns the tag index per multiple areas if requested.
+     *
+     * @param array $params Tag index required information.
+     * @throws moodle_exception
+     * @since  Moodle 3.7
+     */
+    public static function get_tagindex_per_area($params) {
+        global $CFG, $PAGE;
+        // Validate and normalize parameters.
+        $tagindex = self::validate_parameters(
+            self::get_tagindex_per_area_parameters(), array('tagindex' => $params));
+        $params = $tagindex['tagindex'] + array(    // Force defaults.
+            'id' => 0,
+            'tag' => '',
+            'tc' => 0,
+            'ta' => 0,
+            'excl' => 0,
+            'from' => 0,
+            'ctx' => 0,
+            'rec' => 1,
+            'page' => 0,
+        );
+
+        if (empty($CFG->usetags)) {
+            throw new moodle_exception('tagsaredisabled', 'tag');
+        }
+
+        if (!empty($params['tag'])) {
+            if (empty($params['tc'])) {
+                // Tag name specified but tag collection was not. Try to guess it.
+                $tags = core_tag_tag::guess_by_name($params['tag'], '*');
+                if (count($tags) > 1) {
+                    // It is in more that one collection, do not display.
+                    throw new moodle_exception('Tag is in more that one collection, please indicate one.');
+                } else if (count($tags) == 1) {
+                    $tag = reset($tags);
+                }
+            } else {
+                if (!$tag = core_tag_tag::get_by_name($params['tc'], $params['tag'], '*')) {
+                    // Not found in collection.
+                    throw new moodle_exception('notagsfound', 'tag');
+                }
+            }
+        } else if (!empty($params['id'])) {
+            $tag = core_tag_tag::get($params['id'], '*');
+        }
+
+        if (empty($tag)) {
+            throw new moodle_exception('notagsfound', 'tag');
+        }
+
+        // Login to the course / module if applicable.
+        $context = !empty($params['ctx']) ? context::instance_by_id($params['ctx']) : context_system::instance();
+        self::validate_context($context);
+
+        $tag = core_tag_tag::get_by_name($params['tc'], $tag->name, '*', MUST_EXIST);
+        $tagareas = core_tag_collection::get_areas($params['tc']);
+        $tagareaid = $params['ta'];
+
+         $exclusivemode = 0;
+        // Find all areas in this collection and their items tagged with this tag.
+        if ($tagareaid) {
+            $tagareas = array($tagareas[$tagareaid]);
+        }
+        if (!$tagareaid && count($tagareas) == 1) {
+            // Automatically set "exclusive" mode for tag collection with one tag area only.
+            $params['excl'] = 1;
+        }
+
+        $renderer = $PAGE->get_renderer('core');
+        $result = array();
+        foreach ($tagareas as $ta) {
+            $tagindex = $tag->get_tag_index($ta, $params['excl'], $params['from'], $params['ctx'], $params['rec'], $params['page']);
+            if (!empty($tagindex->hascontent)) {
+                $result[] = $tagindex->export_for_template($renderer);
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Return structure for get_tagindex_per_area
+     *
+     * @return external_description
+     * @since  Moodle 3.7
+     */
+    public static function get_tagindex_per_area_returns() {
+        return new external_multiple_structure(
+            self::get_tagindex_returns()
+        );
+    }
 }
index c451d69..cdf8a62 100644 (file)
@@ -181,4 +181,57 @@ class core_tag_external_testcase extends externallib_advanced_testcase {
         $this->assertEquals('Rename me again', $res['value']);
         $this->assertEquals('Rename me again', $DB->get_field('tag', 'rawname', array('id' => $tag->id)));
     }
+
+    /**
+     * Test get_tagindex_per_area.
+     */
+    public function test_get_tagindex_per_area() {
+        global $USER;
+        $this->resetAfterTest(true);
+
+        // Create tags for two user profiles and one course.
+        $this->setAdminUser();
+        $context = context_user::instance($USER->id);
+        core_tag_tag::set_item_tags('core', 'user', $USER->id, $context, array('test'));
+
+        $this->setUser($this->getDataGenerator()->create_user());
+        $context = context_user::instance($USER->id);
+        core_tag_tag::set_item_tags('core', 'user', $USER->id, $context, array('test'));
+
+        $course = $this->getDataGenerator()->create_course();
+        $context = context_course::instance($course->id);
+        core_tag_tag::set_item_tags('core', 'course', $course->id, $context, array('test'));
+
+        $tag = core_tag_tag::get_by_name(0, 'test');
+
+        // First, search by id.
+        $result = core_tag_external::get_tagindex_per_area(array('id' => $tag->id));
+        $result = external_api::clean_returnvalue(core_tag_external::get_tagindex_per_area_returns(), $result);
+        $this->assertCount(2, $result); // Two different areas: course and user.
+        $this->assertEquals($tag->id, $result[0]['tagid']);
+        $this->assertEquals('course', $result[0]['itemtype']);
+        $this->assertEquals($tag->id, $result[1]['tagid']);
+        $this->assertEquals('user', $result[1]['itemtype']);
+
+        // Now, search by name.
+        $result = core_tag_external::get_tagindex_per_area(array('tag' => 'test'));
+        $result = external_api::clean_returnvalue(core_tag_external::get_tagindex_per_area_returns(), $result);
+        $this->assertCount(2, $result); // Two different areas: course and user.
+        $this->assertEquals($tag->id, $result[0]['tagid']);
+        $this->assertEquals('course', $result[0]['itemtype']);
+        $this->assertEquals($tag->id, $result[1]['tagid']);
+        $this->assertEquals('user', $result[1]['itemtype']);
+
+        // Filter by tag area.
+        $result = core_tag_external::get_tagindex_per_area(array('tag' => 'test', 'ta' => $result[0]['ta']));
+        $result = external_api::clean_returnvalue(core_tag_external::get_tagindex_per_area_returns(), $result);
+        $this->assertCount(1, $result); // Just the given area.
+        $this->assertEquals($tag->id, $result[0]['tagid']);
+        $this->assertEquals('course', $result[0]['itemtype']);
+
+        // Now, search by tag collection (use default).
+        $result = core_tag_external::get_tagindex_per_area(array('id' => $tag->id, 'tc' => 1));
+        $result = external_api::clean_returnvalue(core_tag_external::get_tagindex_per_area_returns(), $result);
+        $this->assertCount(2, $result); // Two different areas: course and user.
+    }
 }