From 08d7954f8ff5fbeee11205c4ff862e5a19b3f9c2 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 13 Oct 2015 20:43:12 +0800 Subject: [PATCH] MDL-49231 mod_glossary: External function get_entry_by_id --- mod/glossary/classes/entry_query_builder.php | 12 ++-- mod/glossary/classes/external.php | 58 ++++++++++++++++++++ mod/glossary/lib.php | 23 ++++++++ mod/glossary/tests/external_test.php | 47 ++++++++++++++++ 4 files changed, 135 insertions(+), 5 deletions(-) diff --git a/mod/glossary/classes/entry_query_builder.php b/mod/glossary/classes/entry_query_builder.php index 8130e613f3e..7de6d51e266 100644 --- a/mod/glossary/classes/entry_query_builder.php +++ b/mod/glossary/classes/entry_query_builder.php @@ -84,12 +84,14 @@ class mod_glossary_entry_query_builder { * * @param object $glossary The glossary. */ - public function __construct($glossary) { - $this->glossary = $glossary; + public function __construct($glossary = null) { $this->from = sprintf('FROM {glossary_entries} %s', self::ALIAS_ENTRIES); - $this->where[] = sprintf('(%s.glossaryid = :gid OR %s.sourceglossaryid = :gid2)', self::ALIAS_ENTRIES, self::ALIAS_ENTRIES); - $this->params['gid'] = $glossary->id; - $this->params['gid2'] = $glossary->id; + if (!empty($glossary)) { + $this->glossary = $glossary; + $this->where[] = sprintf('(%s.glossaryid = :gid OR %s.sourceglossaryid = :gid2)', self::ALIAS_ENTRIES, self::ALIAS_ENTRIES); + $this->params['gid'] = $glossary->id; + $this->params['gid2'] = $glossary->id; + } } /** diff --git a/mod/glossary/classes/external.php b/mod/glossary/classes/external.php index 9923119c500..0b18d4bfa8d 100644 --- a/mod/glossary/classes/external.php +++ b/mod/glossary/classes/external.php @@ -1199,4 +1199,62 @@ class mod_glossary_external extends external_api { 'warnings' => new external_warnings() )); } + + /** + * Returns the description of the external function parameters. + * + * @return external_function_parameters + * @since Moodle 3.1 + */ + public static function get_entry_by_id_parameters() { + return new external_function_parameters(array( + 'id' => new external_value(PARAM_INT, 'Glossary entry ID'), + )); + } + + /** + * Get an entry. + * + * @param int $id The entry ID. + * @return array of warnings and status result + * @since Moodle 3.1 + * @throws moodle_exception + */ + public static function get_entry_by_id($id) { + global $DB, $USER; + + $params = self::validate_parameters(self::get_entry_by_id_parameters(), array('id' => $id)); + $id = $params['id']; + $warnings = array(); + + // Get and validate the glossary. + $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST); + list($glossary, $context) = self::validate_glossary($entry->glossaryid); + + if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) { + throw new invalid_parameter_exception('invalidentry'); + } + + $entry = glossary_get_entry_by_id($id); + self::fill_entry_details($entry, $context); + + return array( + 'entry' => $entry, + 'warnings' => $warnings + ); + } + + /** + * Returns the description of the external function return value. + * + * @return external_description + * @since Moodle 3.1 + */ + public static function get_entry_by_id_returns() { + return new external_single_structure(array( + 'entry' => self::get_entry_return_structure(), + 'warnings' => new external_warnings() + )); + } + } diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index cacf84c739e..a6c53ac0b95 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -3693,3 +3693,26 @@ function glossary_get_entries_by_search($glossary, $context, $query, $fullsearch return array($entries, $count); } + +/** + * Fetch an entry. + * + * @param int $id The entry ID. + * @return object|false + */ +function glossary_get_entry_by_id($id) { + + // Build the query. + $qb = new mod_glossary_entry_query_builder(); + $qb->add_field('*', 'entries'); + $qb->join_user(); + $qb->add_user_fields(); + $qb->where('id', 'entries', $id); + + // Fetching the entries. + $entries = $qb->get_records(); + if (empty($entries)) { + return false; + } + return array_pop($entries); +} diff --git a/mod/glossary/tests/external_test.php b/mod/glossary/tests/external_test.php index 0e1ad3cc600..6c536df8a6f 100644 --- a/mod/glossary/tests/external_test.php +++ b/mod/glossary/tests/external_test.php @@ -868,4 +868,51 @@ class mod_glossary_external_testcase extends externallib_advanced_testcase { $this->assertEquals($e8->id, $return['entries'][1]['id']); } + public function test_get_entry_by_id() { + $this->resetAfterTest(true); + + // Generate all the things. + $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary'); + $c1 = $this->getDataGenerator()->create_course(); + $c2 = $this->getDataGenerator()->create_course(); + $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id)); + $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'visible' => 0)); + $u1 = $this->getDataGenerator()->create_user(); + $u2 = $this->getDataGenerator()->create_user(); + $ctx = context_module::instance($g1->cmid); + $this->getDataGenerator()->enrol_user($u1->id, $c1->id); + + $e1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id)); + $e2 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u1->id)); + $e3 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u2->id)); + $e4 = $gg->create_content($g2, array('approved' => 1)); + + $this->setUser($u1); + $return = mod_glossary_external::get_entry_by_id($e1->id); + $return = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $return); + $this->assertEquals($e1->id, $return['entry']['id']); + + $return = mod_glossary_external::get_entry_by_id($e2->id); + $return = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $return); + $this->assertEquals($e2->id, $return['entry']['id']); + + try { + $return = mod_glossary_external::get_entry_by_id($e3->id); + $this->fail('Cannot view unapproved entries of others.'); + } catch (invalid_parameter_exception $e) { + } + + try { + $return = mod_glossary_external::get_entry_by_id($e4->id); + $this->fail('Cannot view entries from another course.'); + } catch (require_login_exception $e) { + } + + // An admin can be other's entries to be approved. + $this->setAdminUser(); + $return = mod_glossary_external::get_entry_by_id($e3->id); + $return = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $return); + $this->assertEquals($e3->id, $return['entry']['id']); + } + }