diff --git a/mod/glossary/classes/external.php b/mod/glossary/classes/external.php index 58538c9c8a7..acf4f9982a1 100644 --- a/mod/glossary/classes/external.php +++ b/mod/glossary/classes/external.php @@ -903,4 +903,119 @@ 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_authors_parameters() { + return new external_function_parameters(array( + 'id' => new external_value(PARAM_INT, 'Glossary entry ID'), + '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 self even if all of their entries' . + ' require approval. When true, also includes authors only having entries pending approval.', VALUE_DEFAULT, 0) + ), 'An array of options', VALUE_DEFAULT, array()) + )); + } + + /** + * Get the authors of a glossary. + * + * @param int $id The glossary ID. + * @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_authors($id, $from = 0, $limit = 20, $options = array()) { + global $DB, $PAGE, $USER; + + $params = self::validate_parameters(self::get_authors_parameters(), array( + 'id' => $id, + 'from' => $from, + 'limit' => $limit, + 'options' => $options, + )); + $id = $params['id']; + $from = $params['from']; + $limit = $params['limit']; + $options = $params['options']; + $warnings = array(); + + // Fetch and confirm. + $glossary = $DB->get_record('glossary', array('id' => $id), '*', MUST_EXIST); + list($course, $cm) = get_course_and_cm_from_instance($glossary, 'glossary'); + $context = context_module::instance($cm->id); + self::validate_context($context); + + // Fetch the authors. + $params = array(); + $userfields = user_picture::fields('u', null); + + $approvedsql = '(ge.approved <> 0 OR ge.userid = :myid)'; + $params['myid'] = $USER->id; + if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) { + $approvedsql = '1 = 1'; + } + + $sqlselectcount = "SELECT COUNT(DISTINCT(u.id))"; + $sqlselect = "SELECT DISTINCT(u.id), $userfields"; + $sql = " FROM {user} u + JOIN {glossary_entries} ge + ON ge.userid = u.id + AND (ge.glossaryid = :gid1 OR ge.sourceglossaryid = :gid2) + AND $approvedsql"; + $ordersql = " ORDER BY u.lastname, u.firstname"; + + $params['gid1'] = $glossary->id; + $params['gid2'] = $glossary->id; + + $canviewfullnames = has_capability('moodle/site:viewfullnames', $context); + $count = $DB->count_records_sql($sqlselectcount . $sql, $params); + $users = $DB->get_recordset_sql($sqlselect . $sql . $ordersql, $params, $from, $limit); + $authors = array(); + foreach ($users as $user) { + $userpicture = new user_picture($user); + $userpicture->size = 1; + + $author = new stdClass(); + $author->id = $user->id; + $author->fullname = fullname($user, $canviewfullnames); + $author->pictureurl = $userpicture->get_url($PAGE)->out(false); + $authors[] = $author; + } + $users->close(); + + return array( + 'count' => $count, + 'authors' => $authors, + 'warnings' => array(), + ); + } + + /** + * Returns the description of the external function return value. + * + * @return external_description + * @since Moodle 3.1 + */ + public static function get_authors_returns() { + return new external_single_structure(array( + 'count' => new external_value(PARAM_INT, 'The total number of records.'), + 'authors' => new external_multiple_structure( + new external_single_structure(array( + 'id' => new external_value(PARAM_INT, 'The user ID'), + 'fullname' => new external_value(PARAM_NOTAGS, 'The fullname'), + 'pictureurl' => new external_value(PARAM_URL, 'The picture URL'), + )) + ), + 'warnings' => new external_warnings() + )); + } } diff --git a/mod/glossary/tests/external_test.php b/mod/glossary/tests/external_test.php index 73dc6fe7d50..082679d7665 100644 --- a/mod/glossary/tests/external_test.php +++ b/mod/glossary/tests/external_test.php @@ -485,4 +485,51 @@ class mod_glossary_external_testcase extends externallib_advanced_testcase { $this->assertEquals($e1a3->id, $return['entries'][1]['id']); } + public function test_get_authors() { + $this->resetAfterTest(true); + + $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(array('lastname' => 'Upsilon')); + $u2 = $this->getDataGenerator()->create_user(array('lastname' => 'Alpha')); + $u3 = $this->getDataGenerator()->create_user(array('lastname' => 'Omega')); + + $ctx = context_module::instance($g1->cmid); + + $e1a = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1)); + $e1b = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1)); + $e1c = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1)); + $e2a = $gg->create_content($g1, array('userid' => $u2->id, 'approved' => 1)); + $e3a = $gg->create_content($g1, array('userid' => $u3->id, 'approved' => 0)); + + $this->setAdminUser(); + + // Simple request. + $return = mod_glossary_external::get_authors($g1->id, 0, 20, array()); + $return = external_api::clean_returnvalue(mod_glossary_external::get_authors_returns(), $return); + $this->assertCount(2, $return['authors']); + $this->assertEquals(2, $return['count']); + $this->assertEquals($u2->id, $return['authors'][0]['id']); + $this->assertEquals($u1->id, $return['authors'][1]['id']); + + // Include users with entries pending approval. + $return = mod_glossary_external::get_authors($g1->id, 0, 20, array('includenotapproved' => true)); + $return = external_api::clean_returnvalue(mod_glossary_external::get_authors_returns(), $return); + $this->assertCount(3, $return['authors']); + $this->assertEquals(3, $return['count']); + $this->assertEquals($u2->id, $return['authors'][0]['id']); + $this->assertEquals($u3->id, $return['authors'][1]['id']); + $this->assertEquals($u1->id, $return['authors'][2]['id']); + + // Pagination. + $return = mod_glossary_external::get_authors($g1->id, 1, 1, array('includenotapproved' => true)); + $return = external_api::clean_returnvalue(mod_glossary_external::get_authors_returns(), $return); + $this->assertCount(1, $return['authors']); + $this->assertEquals(3, $return['count']); + $this->assertEquals($u3->id, $return['authors'][0]['id']); + } + }