Skip to content

Commit

Permalink
MDL-49231 mod_glossary: External function get_entries_by_term
Browse files Browse the repository at this point in the history
  • Loading branch information
Frederic Massart authored and jleyva committed Dec 31, 2015
1 parent 08d7954 commit 93e122e
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 0 deletions.
20 changes: 20 additions & 0 deletions mod/glossary/classes/entry_query_builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,21 @@ public function filter_by_non_approved($constant, $userid = null) {
}
}

/**
* 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.
*
Expand Down Expand Up @@ -335,6 +350,11 @@ public function filter_by_search_terms(array $terms, $fullsearch = true) {
}
}

// 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);
}
Expand Down
83 changes: 83 additions & 0 deletions mod/glossary/classes/external.php
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,89 @@ public static function get_entries_by_search_returns() {
));
}

/**
* 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.
*
Expand Down
41 changes: 41 additions & 0 deletions mod/glossary/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
59 changes: 59 additions & 0 deletions mod/glossary/tests/external_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,65 @@ public function test_get_entries_by_search() {
$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);

Expand Down

0 comments on commit 93e122e

Please sign in to comment.