Merge branch 'MDL-61245-master' of git://github.com/jleyva/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 10 Oct 2018 09:14:57 +0000 (11:14 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 10 Oct 2018 09:14:57 +0000 (11:14 +0200)
blog/classes/external.php
blog/tests/external_test.php
lib/db/services.php
version.php

index 9333d2b..e199d35 100644 (file)
@@ -48,6 +48,72 @@ use core_blog\external\post_exporter;
  */
 class external extends external_api {
 
+    /**
+     * Validate access to the blog and the filters to apply when listing entries.
+     *
+     * @param  array  $rawwsfilters array containing the filters in WS format
+     * @return array  context, filters to apply and the calculated courseid and user
+     * @since  Moodle 3.6
+     */
+    protected static function validate_access_and_filters($rawwsfilters) {
+        global $CFG;
+
+        if (empty($CFG->enableblogs)) {
+            throw new moodle_exception('blogdisable', 'blog');
+        }
+
+        // Init filters.
+        $filterstype = array(
+            'courseid' => PARAM_INT,
+            'groupid' => PARAM_INT,
+            'userid' => PARAM_INT,
+            'tagid' => PARAM_INT,
+            'tag' => PARAM_NOTAGS,
+            'cmid' => PARAM_INT,
+            'entryid' => PARAM_INT,
+            'search' => PARAM_RAW
+        );
+        $filters = array(
+            'courseid' => null,
+            'groupid' => null,
+            'userid' => null,
+            'tagid' => null,
+            'tag' => null,
+            'cmid' => null,
+            'entryid' => null,
+            'search' => null
+        );
+
+        foreach ($rawwsfilters as $filter) {
+            $name = trim($filter['name']);
+            if (!isset($filterstype[$name])) {
+                throw new moodle_exception('errorinvalidparam', 'webservice', '', $name);
+            }
+            $filters[$name] = clean_param($filter['value'], $filterstype[$name]);
+        }
+
+        // Do not overwrite here the filters, blog_get_headers and blog_listing will take care of that.
+        list($courseid, $userid) = blog_validate_access($filters['courseid'], $filters['cmid'], $filters['groupid'],
+            $filters['entryid'], $filters['userid']);
+
+        if ($courseid && $courseid != SITEID) {
+            $context = context_course::instance($courseid);
+            self::validate_context($context);
+        } else {
+            $context = context_system::instance();
+            if ($CFG->bloglevel == BLOG_GLOBAL_LEVEL) {
+                // Everybody can see anything - no login required unless site is locked down using forcelogin.
+                if ($CFG->forcelogin) {
+                    self::validate_context($context);
+                }
+            } else {
+                self::validate_context($context);
+            }
+        }
+        // Courseid and userid may not be the same that the ones in $filters.
+        return array($context, $filters, $courseid, $userid);
+    }
+
     /**
      * Returns description of get_entries() parameters.
      *
@@ -92,49 +158,16 @@ class external extends external_api {
      * @since  Moodle 3.6
      */
     public static function get_entries($filters = array(), $page = 0, $perpage = 10) {
-        global $CFG, $DB, $PAGE;
+        global $PAGE;
 
         $warnings = array();
         $params = self::validate_parameters(self::get_entries_parameters(),
             array('filters' => $filters, 'page' => $page, 'perpage' => $perpage));
 
-        if (empty($CFG->enableblogs)) {
-            throw new moodle_exception('blogdisable', 'blog');
-        }
-
-        // Init filters.
-        $filterstype = array('courseid' => PARAM_INT, 'groupid' => PARAM_INT, 'userid' => PARAM_INT, 'tagid' => PARAM_INT,
-            'tag' => PARAM_NOTAGS, 'cmid' => PARAM_INT, 'entryid' => PARAM_INT, 'search' => PARAM_RAW);
-        $filters = array('courseid' => null, 'groupid' => null, 'userid' => null, 'tagid' => null,
-            'tag' => null, 'cmid' => null, 'entryid' => null, 'search' => null);
-
-        foreach ($params['filters'] as $filter) {
-            $name = trim($filter['name']);
-            if (!isset($filterstype[$name])) {
-                throw new moodle_exception('errorinvalidparam', 'webservice', '', $name);
-            }
-            $filters[$name] = clean_param($filter['value'], $filterstype[$name]);
-        }
-
-        // Do not overwrite here the filters, blog_get_headers and blog_listing will take care of that.
-        list($courseid, $userid) = blog_validate_access($filters['courseid'], $filters['cmid'], $filters['groupid'],
-            $filters['entryid'], $filters['userid']);
+        list($context, $filters, $courseid, $userid) = self::validate_access_and_filters($params['filters']);
 
-        if ($courseid && $courseid != SITEID) {
-            $context = context_course::instance($courseid);
-            self::validate_context($context);
-        } else {
-            $context = context_system::instance();
-            if ($CFG->bloglevel == BLOG_GLOBAL_LEVEL) {
-                // Everybody can see anything - no login required unless site is locked down using forcelogin.
-                if ($CFG->forcelogin) {
-                    self::validate_context($context);
-                }
-            } else {
-                self::validate_context($context);
-            }
-        }
         $PAGE->set_context($context); // Needed by internal APIs.
+        $output = $PAGE->get_renderer('core');
 
         // Get filters.
         $blogheaders = blog_get_headers($filters['courseid'], $filters['groupid'], $filters['userid'], $filters['tagid'],
@@ -148,7 +181,6 @@ class external extends external_api {
         $totalentries = $bloglisting->count_entries();
 
         $exportedentries = array();
-        $output = $PAGE->get_renderer('core');
         foreach ($entries as $entry) {
             $exporter = new post_exporter($entry, array('context' => $context));
             $exportedentries[] = $exporter->export($output);
@@ -177,4 +209,83 @@ class external extends external_api {
             )
         );
     }
+
+    /**
+     * Returns description of view_entries() parameters.
+     *
+     * @return external_function_parameters
+     * @since  Moodle 3.6
+     */
+    public static function view_entries_parameters() {
+        return new external_function_parameters(
+            array(
+                'filters' => new external_multiple_structure (
+                    new external_single_structure(
+                        array(
+                            'name' => new external_value(PARAM_ALPHA,
+                                'The expected keys (value format) are:
+                                tag      PARAM_NOTAGS blog tag
+                                tagid    PARAM_INT    blog tag id
+                                userid   PARAM_INT    blog author (userid)
+                                cmid     PARAM_INT    course module id
+                                entryid  PARAM_INT    entry id
+                                groupid  PARAM_INT    group id
+                                courseid PARAM_INT    course id
+                                search   PARAM_RAW    search term
+                                '
+                            ),
+                            'value' => new external_value(PARAM_RAW, 'The value of the filter.')
+                        )
+                    ), 'Parameters used in the filter of view_entries.', VALUE_DEFAULT, array()
+                ),
+            )
+        );
+    }
+
+    /**
+     * Trigger the blog_entries_viewed event.
+     *
+     * @param array $filters the parameters used in the filter of get_entries
+     * @return array with status result and warnings
+     * @since  Moodle 3.6
+     */
+    public static function view_entries($filters = array()) {
+
+        $warnings = array();
+        $params = self::validate_parameters(self::view_entries_parameters(), array('filters' => $filters));
+
+        list($context, $filters, $courseid, $userid) = self::validate_access_and_filters($params['filters']);
+
+        $eventparams = array(
+            'other' => array('entryid' => $filters['entryid'], 'tagid' => $filters['tagid'], 'userid' => $userid,
+                'modid' => $filters['cmid'], 'groupid' => $filters['groupid'], 'search' => $filters['search']
+            )
+        );
+        if (!empty($userid)) {
+            $eventparams['relateduserid'] = $userid;
+        }
+        $eventparams['other']['courseid'] = ($courseid === SITEID) ? 0 : $courseid;
+        $event = \core\event\blog_entries_viewed::create($eventparams);
+        $event->trigger();
+
+        return array(
+            'warnings' => $warnings,
+            'status' => true,
+        );
+    }
+
+    /**
+     * Returns description of view_entries() result value.
+     *
+     * @return external_description
+     * @since  Moodle 3.6
+     */
+    public static function view_entries_returns() {
+        return new external_single_structure(
+            array(
+                'status' => new external_value(PARAM_BOOL, 'status: true if success'),
+                'warnings' => new external_warnings(),
+            )
+        );
+    }
 }
index 016865c..f5822f4 100644 (file)
@@ -561,5 +561,64 @@ class core_blog_external_testcase extends advanced_testcase {
         $this->expectException('moodle_exception');
         $result = core_blog\external::get_entries(array(array('name' => 'zzZZzz', 'value' => 'wwWWww')));
     }
+
+    /**
+     * Test view_blog_entries without filter.
+     */
+    public function test_view_blog_entries_without_filtering() {
+        // Test user with full capabilities.
+        $this->setUser($this->userid);
+        // Trigger and capture the event.
+        $sink = $this->redirectEvents();
+        $result = core_blog\external::view_entries();
+        $result = external_api::clean_returnvalue(core_blog\external::view_entries_returns(), $result);
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = array_shift($events);
+        // Checking that the event contains the expected values (empty, no filtering done).
+        $this->assertInstanceOf('\core\event\blog_entries_viewed', $event);
+        $this->assertEmpty($event->get_data()['relateduserid']);
+        $this->assertEmpty($event->get_data()['other']['entryid']);
+        $this->assertEmpty($event->get_data()['other']['tagid']);
+        $this->assertEmpty($event->get_data()['other']['userid']);
+        $this->assertEmpty($event->get_data()['other']['modid']);
+        $this->assertEmpty($event->get_data()['other']['groupid']);
+        $this->assertEmpty($event->get_data()['other']['search']);
+        $this->assertEmpty($event->get_data()['other']['courseid']);
+        $this->assertEventContextNotUsed($event);
+        $this->assertNotEmpty($event->get_name());
+    }
+
+    /**
+     * Test view_blog_entries doing filtering.
+     */
+    public function test_view_blog_entries_with_filtering() {
+        // Test user with full capabilities.
+        $this->setUser($this->userid);
+        // Trigger and capture the event.
+        $sink = $this->redirectEvents();
+        $result = core_blog\external::view_entries(array(
+            array('name' => 'tagid', 'value' => $this->tagid),
+            array('name' => 'userid', 'value' => $this->userid),
+        ));
+        $result = external_api::clean_returnvalue(core_blog\external::view_entries_returns(), $result);
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = array_shift($events);
+        // Checking that the event contains the expected values (filter by user and tag).
+        $this->assertInstanceOf('\core\event\blog_entries_viewed', $event);
+        $this->assertEquals($this->userid, $event->get_data()['relateduserid']);
+        $this->assertEmpty($event->get_data()['other']['entryid']);
+        $this->assertEquals($this->tagid, $event->get_data()['other']['tagid']);
+        $this->assertEquals($this->userid, $event->get_data()['other']['userid']);
+        $this->assertEmpty($event->get_data()['other']['modid']);
+        $this->assertEmpty($event->get_data()['other']['groupid']);
+        $this->assertEmpty($event->get_data()['other']['search']);
+        $this->assertEmpty($event->get_data()['other']['courseid']);
+        $this->assertEventContextNotUsed($event);
+        $this->assertNotEmpty($event->get_name());
+    }
 }
 
index 4893b41..10bd788 100644 (file)
@@ -83,6 +83,15 @@ $functions = array(
         'ajax'          => true,
         'loginrequired' => false,
     ),
+    'core_blog_view_entries' => array(
+        'classname'   => 'core_blog\external',
+        'methodname'  => 'view_entries',
+        'description' => 'Trigger the blog_entries_viewed event.',
+        'type'        => 'read',
+        'services'    => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+        'ajax'          => true,
+        'loginrequired' => false,
+    ),
     'core_calendar_get_calendar_monthly_view' => array(
         'classname' => 'core_calendar_external',
         'methodname' => 'get_calendar_monthly_view',
index af137a1..829d906 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2018100500.01;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2018100900.00;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.