MDL-49231 mod_glossary: External function get_entries_to_approve
authorFrederic Massart <fred@moodle.com>
Mon, 19 Oct 2015 06:39:56 +0000 (14:39 +0800)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Thu, 31 Dec 2015 14:18:40 +0000 (15:18 +0100)
mod/glossary/classes/external.php
mod/glossary/lib.php
mod/glossary/tests/external_test.php

index 33c96b5..d56eb48 100644 (file)
@@ -1283,6 +1283,96 @@ class mod_glossary_external extends external_api {
         ));
     }
 
+    /**
+     * Returns the description of the external function parameters.
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.1
+     */
+    public static function get_entries_to_approve_parameters() {
+        return new external_function_parameters(array(
+            'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
+            'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
+            'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
+                'CONCEPT'),
+            'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
+            'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
+            'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
+            'options' => new external_single_structure(array(), 'An array of options', VALUE_DEFAULT, array())
+        ));
+    }
+
+    /**
+     * Browse a glossary entries using a term matching the concept or alias.
+     *
+     * @param int $id The glossary ID.
+     * @param string $letter A letter, or a special keyword.
+     * @param string $order The way to order the records.
+     * @param string $sort The direction of the order.
+     * @param int $from Start returning records from here.
+     * @param int $limit Number of records to return.
+     * @param array $options Array of options.
+     * @return array of warnings and status result
+     * @since Moodle 3.1
+     * @throws moodle_exception
+     */
+    public static function get_entries_to_approve($id, $letter, $order = 'CONCEPT', $sort = 'ASC', $from = 0, $limit = 20) {
+        global $DB, $USER;
+
+        $params = self::validate_parameters(self::get_entries_to_approve_parameters(), array(
+            'id' => $id,
+            'letter' => $letter,
+            'order' => $order,
+            'sort' => $sort,
+            'from' => $from,
+            'limit' => $limit
+        ));
+        $id = $params['id'];
+        $letter = $params['letter'];
+        $order = $params['order'];
+        $sort = $params['sort'];
+        $from = $params['from'];
+        $limit = $params['limit'];
+        $warnings = array();
+
+        // Get and validate the glossary.
+        list($glossary, $context) = self::validate_glossary($id);
+
+        // Check the permissions.
+        require_capability('mod/glossary:approve', $context);
+
+        // Fetching the entries.
+        $entries = array();
+        list($records, $count) = glossary_get_entries_to_approve($glossary, $context, $letter, $order, $sort, $from, $limit);
+        foreach ($records as $key => $record) {
+            self::fill_entry_details($record, $context);
+            $entries[] = $record;
+        }
+        $records->close();
+
+        return array(
+            'count' => $count,
+            'entries' => $entries,
+            'warnings' => $warnings
+        );
+    }
+
+    /**
+     * Returns the description of the external function return value.
+     *
+     * @return external_description
+     * @since Moodle 3.1
+     */
+    public static function get_entries_to_approve_returns() {
+        return new external_single_structure(array(
+            'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
+            'entries' => new external_multiple_structure(
+                self::get_entry_return_structure()
+            ),
+            'warnings' => new external_warnings()
+        ));
+    }
+
     /**
      * Returns the description of the external function parameters.
      *
index 2bafd1c..508db11 100644 (file)
@@ -3735,6 +3735,49 @@ function glossary_get_entries_by_term($glossary, $context, $term, $from, $limit,
     return array($entries, $count);
 }
 
+/**
+ * Returns the entries to be approved.
+ *
+ * @param  object $glossary The glossary.
+ * @param  context $context The context of the glossary.
+ * @param  string $letter The letter, or ALL, or SPECIAL.
+ * @param  string $order The mode of ordering: CONCEPT, CREATION or UPDATE.
+ * @param  string $sort The direction of the ordering: ASC or DESC.
+ * @param  int $from Fetch records from.
+ * @param  int $limit Number of records to fetch.
+ * @return array The first element being the recordset, the second the number of entries.
+ * @since Moodle 3.1
+ */
+function glossary_get_entries_to_approve($glossary, $context, $letter, $order, $sort, $from, $limit) {
+
+    $qb = new mod_glossary_entry_query_builder($glossary);
+    if ($letter != 'ALL' && $letter != 'SPECIAL' && core_text::strlen($letter)) {
+        $qb->filter_by_concept_letter($letter);
+    }
+    if ($letter == 'SPECIAL') {
+        $qb->filter_by_concept_non_letter();
+    }
+
+    $qb->add_field('*', 'entries');
+    $qb->join_user();
+    $qb->add_user_fields();
+    $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ONLY);
+    if ($order == 'CREATION') {
+        $qb->order_by('timecreated', 'entries', $sort);
+    } else if ($order == 'UPDATE') {
+        $qb->order_by('timemodified', 'entries', $sort);
+    } else {
+        $qb->order_by('concept', 'entries', $sort);
+    }
+    $qb->limit($from, $limit);
+
+    // Fetching the entries.
+    $count = $qb->count_records();
+    $entries = $qb->get_recordset();
+
+    return array($entries, $count);
+}
+
 /**
  * Fetch an entry.
  *
index e09b602..c8b3b2b 100644 (file)
@@ -927,6 +927,112 @@ class mod_glossary_external_testcase extends externallib_advanced_testcase {
         $this->assertEquals($e2->id, $return['entries'][0]['id']);
     }
 
+    public function test_get_entries_to_approve() {
+        $this->resetAfterTest(true);
+
+        // Generate all the things.
+        $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
+        $c1 = $this->getDataGenerator()->create_course();
+        $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
+        $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
+        $u1 = $this->getDataGenerator()->create_user();
+        $ctx = context_module::instance($g1->cmid);
+        $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
+
+        $e1a = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Bob', 'userid' => $u1->id,
+            'timecreated' => time() + 3600));
+        $e1b = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Jane', 'userid' => $u1->id, 'timecreated' => 1));
+        $e1c = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Alice', 'userid' => $u1->id, 'timemodified' => 1));
+        $e1d = $gg->create_content($g1, array('approved' => 0, 'concept' => '0-day', 'userid' => $u1->id,
+            'timemodified' => time() + 3600));
+        $e1e = $gg->create_content($g1, array('approved' => 1, 'concept' => '1-day', 'userid' => $u1->id));
+        $e2a = $gg->create_content($g2);
+
+        $this->setAdminUser(true);
+
+        // Simple listing.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 0, 20);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(4, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1d->id, $return['entries'][0]['id']);
+        $this->assertEquals($e1c->id, $return['entries'][1]['id']);
+        $this->assertEquals($e1a->id, $return['entries'][2]['id']);
+        $this->assertEquals($e1b->id, $return['entries'][3]['id']);
+
+        // Revert ordering of concept.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'DESC', 0, 20);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(4, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1b->id, $return['entries'][0]['id']);
+        $this->assertEquals($e1a->id, $return['entries'][1]['id']);
+        $this->assertEquals($e1c->id, $return['entries'][2]['id']);
+        $this->assertEquals($e1d->id, $return['entries'][3]['id']);
+
+        // Filtering by letter.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'a', 'CONCEPT', 'ASC', 0, 20);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(1, $return['entries']);
+        $this->assertEquals(1, $return['count']);
+        $this->assertEquals($e1c->id, $return['entries'][0]['id']);
+
+        // Filtering by special.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'SPECIAL', 'CONCEPT', 'ASC', 0, 20);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(1, $return['entries']);
+        $this->assertEquals(1, $return['count']);
+        $this->assertEquals($e1d->id, $return['entries'][0]['id']);
+
+        // Pagination.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 0, 2);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(2, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1d->id, $return['entries'][0]['id']);
+        $this->assertEquals($e1c->id, $return['entries'][1]['id']);
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 1, 2);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(2, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1c->id, $return['entries'][0]['id']);
+        $this->assertEquals($e1a->id, $return['entries'][1]['id']);
+
+        // Ordering by creation date.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CREATION', 'ASC', 0, 1);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(1, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1b->id, $return['entries'][0]['id']);
+
+        // Ordering by creation date desc.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CREATION', 'DESC', 0, 1);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(1, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1a->id, $return['entries'][0]['id']);
+
+        // Ordering by update date.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'UPDATE', 'ASC', 0, 1);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(1, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1c->id, $return['entries'][0]['id']);
+
+        // Ordering by update date desc.
+        $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'UPDATE', 'DESC', 0, 1);
+        $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
+        $this->assertCount(1, $return['entries']);
+        $this->assertEquals(4, $return['count']);
+        $this->assertEquals($e1d->id, $return['entries'][0]['id']);
+
+        // Permissions are checked.
+        $this->setUser($u1);
+        $this->setExpectedException('required_capability_exception');
+        mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 0, 1);
+        $this->fail('Do not test anything else after this.');
+    }
+
     public function test_get_entry_by_id() {
         $this->resetAfterTest(true);