MDL-49231 mod_glossary: External function get_entries_by_term

This commit is contained in:
Frederic Massart
2015-12-31 15:18:39 +01:00
committed by Juan Leyva
parent 08d7954f8f
commit 93e122e0dc
4 changed files with 203 additions and 0 deletions
@@ -272,6 +272,21 @@ class mod_glossary_entry_query_builder {
}
}
/**
* Filter by concept or alias.
*
* This requires the alias table to be joined in the query. See {@link self::join_alias()}.
*
* @param string $term What the concept or aliases should be.
*/
public function filter_by_term($term) {
$this->where[] = sprintf("(%s = :filterterma OR %s = :filtertermb)",
self::resolve_field('concept', 'entries'),
self::resolve_field('alias', 'alias'));
$this->params['filterterma'] = $term;
$this->params['filtertermb'] = $term;
}
/**
* Filter by search terms.
*
@@ -335,6 +350,11 @@ class mod_glossary_entry_query_builder {
}
}
// When there are no conditions we add a negative one to ensure that we don't return anything.
if (empty($conditions)) {
$conditions[] = '1 = 2';
}
$this->where[] = implode(' AND ', $conditions);
$this->params = array_merge($this->params, $params);
}
+83
View File
@@ -1200,6 +1200,89 @@ 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_by_term_parameters() {
return new external_function_parameters(array(
'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
'term' => new external_value(PARAM_NOTAGS, 'The entry concept, or alias'),
'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(
'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
), '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 $term The term.
* @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_by_term($id, $term, $from = 0, $limit = 20, $options = array()) {
global $DB, $USER;
$params = self::validate_parameters(self::get_entries_by_term_parameters(), array(
'id' => $id,
'term' => $term,
'from' => $from,
'limit' => $limit,
'options' => $options,
));
$id = $params['id'];
$term = $params['term'];
$from = $params['from'];
$limit = $params['limit'];
$options = $params['options'];
$warnings = array();
// Get and validate the glossary.
list($glossary, $context) = self::validate_glossary($id);
// Fetching the entries.
$entries = array();
list($records, $count) = glossary_get_entries_by_term($glossary, $context, $term, $from, $limit, $options);
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_by_term_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.
*
+41
View File
@@ -3694,6 +3694,47 @@ function glossary_get_entries_by_search($glossary, $context, $query, $fullsearch
return array($entries, $count);
}
/**
* Returns the entries of a glossary by term.
*
* @param object $glossary The glossary.
* @param context $context The context of the glossary.
* @param string $term The term we are searching for, a concept or alias.
* @param int $from Fetch records from.
* @param int $limit Number of records to fetch.
* @param array $options Accepts:
* - (bool) includenotapproved. When false, includes the non-approved entries created by
* the current user. When true, also includes the ones that the user has the permission to approve.
* @return array The first element being the recordset, the second the number of entries.
* @since Moodle 3.1
*/
function glossary_get_entries_by_term($glossary, $context, $term, $from, $limit, $options = array()) {
// Build the query.
$qb = new mod_glossary_entry_query_builder($glossary);
if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
$qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
} else {
$qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
}
$qb->add_field('*', 'entries');
$qb->join_alias();
$qb->distinct('id', 'entries');
$qb->join_user();
$qb->add_user_fields();
$qb->filter_by_term($term);
$qb->order_by('concept', 'entries');
$qb->limit($from, $limit);
// Fetching the entries.
$count = $qb->count_records();
$entries = $qb->get_recordset();
return array($entries, $count);
}
/**
* Fetch an entry.
*
+59
View File
@@ -868,6 +868,65 @@ class mod_glossary_external_testcase extends externallib_advanced_testcase {
$this->assertEquals($e8->id, $return['entries'][1]['id']);
}
public function test_get_entries_by_term() {
$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);
$this->setAdminUser();
$e1 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1, 'concept' => 'cat'));
$e2 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1), array('cat', 'dog'));
$e3 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1), array('dog'));
$e4 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 0, 'concept' => 'dog'));
$e5 = $gg->create_content($g2, array('userid' => $u1->id, 'approved' => 1, 'concept' => 'dog'), array('cat'));
// Search concept + alias.
$return = mod_glossary_external::get_entries_by_term($g1->id, 'cat', 0, 20, array('includenotapproved' => false));
$return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
$this->assertCount(2, $return['entries']);
$this->assertEquals(2, $return['count']);
$this->assertEquals($e1->id, $return['entries'][0]['id']);
$this->assertEquals($e2->id, $return['entries'][1]['id']);
// Search alias.
$return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 0, 20, array('includenotapproved' => false));
$return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
$this->assertCount(2, $return['entries']);
$this->assertEquals(2, $return['count']);
$this->assertEquals($e2->id, $return['entries'][0]['id']);
$this->assertEquals($e3->id, $return['entries'][1]['id']);
// Search including not approved.
$return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 0, 20, array('includenotapproved' => true));
$return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
$this->assertCount(3, $return['entries']);
$this->assertEquals(3, $return['count']);
$this->assertEquals($e4->id, $return['entries'][0]['id']);
$this->assertEquals($e2->id, $return['entries'][1]['id']);
$this->assertEquals($e3->id, $return['entries'][2]['id']);
// Pagination.
$return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 0, 1, array('includenotapproved' => true));
$return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
$this->assertCount(1, $return['entries']);
$this->assertEquals(3, $return['count']);
$this->assertEquals($e4->id, $return['entries'][0]['id']);
$return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 1, 1, array('includenotapproved' => true));
$return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
$this->assertCount(1, $return['entries']);
$this->assertEquals(3, $return['count']);
$this->assertEquals($e2->id, $return['entries'][0]['id']);
}
public function test_get_entry_by_id() {
$this->resetAfterTest(true);