Merge branch 'MDL-57914-master' of git://github.com/jleyva/moodle

This commit is contained in:
Andrew Nicols
2017-03-10 18:04:45 +00:00
committed by Dan Poltawski
5 changed files with 328 additions and 89 deletions
+47
View File
@@ -1353,4 +1353,51 @@ class external_files extends external_multiple_structure {
$required
);
}
/**
* Return the properties ready to be used by an exporter.
*
* @return array properties
* @since Moodle 3.3
*/
public static function get_properties_for_exporter() {
return [
'filename' => array(
'type' => PARAM_FILE,
'description' => 'File name.',
'optional' => true,
'null' => NULL_NOT_ALLOWED,
),
'filepath' => array(
'type' => PARAM_PATH,
'description' => 'File path.',
'optional' => true,
'null' => NULL_NOT_ALLOWED,
),
'filesize' => array(
'type' => PARAM_INT,
'description' => 'File size.',
'optional' => true,
'null' => NULL_NOT_ALLOWED,
),
'fileurl' => array(
'type' => PARAM_URL,
'description' => 'Downloadable file url.',
'optional' => true,
'null' => NULL_NOT_ALLOWED,
),
'timemodified' => array(
'type' => PARAM_INT,
'description' => 'Time modified.',
'optional' => true,
'null' => NULL_NOT_ALLOWED,
),
'mimetype' => array(
'type' => PARAM_RAW,
'description' => 'File mime type.',
'optional' => true,
'null' => NULL_NOT_ALLOWED,
),
];
}
}
+22 -80
View File
@@ -28,6 +28,8 @@ defined('MOODLE_INTERNAL') || die;
require_once("$CFG->libdir/externallib.php");
use mod_data\external\database_summary_exporter;
/**
* Database module external functions
*
@@ -65,7 +67,7 @@ class mod_data_external extends external_api {
* @since Moodle 2.9
*/
public static function get_databases_by_courses($courseids = array()) {
global $CFG;
global $PAGE;
$params = self::validate_parameters(self::get_databases_by_courses_parameters(), array('courseids' => $courseids));
$warnings = array();
@@ -90,56 +92,36 @@ class mod_data_external extends external_api {
foreach ($databases as $database) {
$datacontext = context_module::instance($database->coursemodule);
// Entry to return.
$newdb = array();
// First, we return information that any user can see in the web interface.
$newdb['id'] = $database->id;
$newdb['coursemodule'] = $database->coursemodule;
$newdb['course'] = $database->course;
$newdb['name'] = external_format_string($database->name, $datacontext->id);
// Format intro.
list($newdb['intro'], $newdb['introformat']) =
external_format_text($database->intro, $database->introformat,
$datacontext->id, 'mod_data', 'intro', null);
$newdb['introfiles'] = external_util::get_area_files($datacontext->id, 'mod_data', 'intro', false, false);
$context = context_module::instance($database->coursemodule);
// Remove fields added by get_all_instances_in_courses.
unset($database->coursemodule, $database->section, $database->visible, $database->groupmode, $database->groupingid);
// This information should be only available if the user can see the database entries.
if (has_capability('mod/data:viewentry', $datacontext)) {
$viewablefields = array('comments', 'timeavailablefrom', 'timeavailableto', 'timeviewfrom',
'timeviewto', 'requiredentries', 'requiredentriestoview');
if (!has_capability('mod/data:viewentry', $context)) {
$fields = array('comments', 'timeavailablefrom', 'timeavailableto', 'timeviewfrom',
'timeviewto', 'requiredentries', 'requiredentriestoview', 'maxentries', 'rssarticles',
'singletemplate', 'listtemplate', 'listtemplateheader', 'listtemplatefooter', 'addtemplate',
'rsstemplate', 'rsstitletemplate', 'csstemplate', 'jstemplate', 'asearchtemplate', 'approval',
'manageapproved', 'defaultsort', 'defaultsortdir');
// This is for avoid a long repetitive list and for
// checking that we are retrieving all the required fields.
foreach ($viewablefields as $field) {
// We do not use isset because it won't work for existing null values.
if (!property_exists($database, $field)) {
throw new invalid_response_exception('Missing database module required field: ' . $field);
}
$newdb[$field] = $database->{$field};
foreach ($fields as $field) {
unset($database->{$field});
}
}
// Check additional permissions for returning optional private settings.
// I avoid intentionally to use can_[add|update]_moduleinfo.
if (has_capability('moodle/course:manageactivities', $datacontext)) {
if (!has_capability('moodle/course:manageactivities', $context)) {
$additionalfields = array('maxentries', 'rssarticles', 'singletemplate', 'listtemplate',
'listtemplateheader', 'listtemplatefooter', 'addtemplate', 'rsstemplate', 'rsstitletemplate',
'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', 'manageapproved', 'scale', 'assessed', 'assesstimestart',
'assesstimefinish', 'defaultsort', 'defaultsortdir', 'editany', 'notification', 'timemodified');
$fields = array('scale', 'assessed', 'assesstimestart', 'assesstimefinish', 'editany', 'notification',
'timemodified');
// This is for avoid a long repetitive list.
foreach ($additionalfields as $field) {
if (property_exists($database, $field)) {
$newdb[$field] = $database->{$field};
}
foreach ($fields as $field) {
unset($database->{$field});
}
}
$arrdatabases[] = $newdb;
$exporter = new database_summary_exporter($database, array('context' => $context));
$arrdatabases[] = $exporter->export($PAGE->get_renderer('core'));
}
}
@@ -160,47 +142,7 @@ class mod_data_external extends external_api {
return new external_single_structure(
array(
'databases' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'Database id'),
'coursemodule' => new external_value(PARAM_INT, 'Course module id'),
'course' => new external_value(PARAM_INT, 'Course id'),
'name' => new external_value(PARAM_RAW, 'Database name'),
'intro' => new external_value(PARAM_RAW, 'The Database intro'),
'introformat' => new external_format_value('intro'),
'introfiles' => new external_files('Files in the introduction text', VALUE_OPTIONAL),
'comments' => new external_value(PARAM_BOOL, 'comments enabled', VALUE_OPTIONAL),
'timeavailablefrom' => new external_value(PARAM_INT, 'timeavailablefrom field', VALUE_OPTIONAL),
'timeavailableto' => new external_value(PARAM_INT, 'timeavailableto field', VALUE_OPTIONAL),
'timeviewfrom' => new external_value(PARAM_INT, 'timeviewfrom field', VALUE_OPTIONAL),
'timeviewto' => new external_value(PARAM_INT, 'timeviewto field', VALUE_OPTIONAL),
'requiredentries' => new external_value(PARAM_INT, 'requiredentries field', VALUE_OPTIONAL),
'requiredentriestoview' => new external_value(PARAM_INT, 'requiredentriestoview field', VALUE_OPTIONAL),
'maxentries' => new external_value(PARAM_INT, 'maxentries field', VALUE_OPTIONAL),
'rssarticles' => new external_value(PARAM_INT, 'rssarticles field', VALUE_OPTIONAL),
'singletemplate' => new external_value(PARAM_RAW, 'singletemplate field', VALUE_OPTIONAL),
'listtemplate' => new external_value(PARAM_RAW, 'listtemplate field', VALUE_OPTIONAL),
'listtemplateheader' => new external_value(PARAM_RAW, 'listtemplateheader field', VALUE_OPTIONAL),
'listtemplatefooter' => new external_value(PARAM_RAW, 'listtemplatefooter field', VALUE_OPTIONAL),
'addtemplate' => new external_value(PARAM_RAW, 'addtemplate field', VALUE_OPTIONAL),
'rsstemplate' => new external_value(PARAM_RAW, 'rsstemplate field', VALUE_OPTIONAL),
'rsstitletemplate' => new external_value(PARAM_RAW, 'rsstitletemplate field', VALUE_OPTIONAL),
'csstemplate' => new external_value(PARAM_RAW, 'csstemplate field', VALUE_OPTIONAL),
'jstemplate' => new external_value(PARAM_RAW, 'jstemplate field', VALUE_OPTIONAL),
'asearchtemplate' => new external_value(PARAM_RAW, 'asearchtemplate field', VALUE_OPTIONAL),
'approval' => new external_value(PARAM_BOOL, 'approval field', VALUE_OPTIONAL),
'manageapproved' => new external_value(PARAM_BOOL, 'manageapproved field', VALUE_OPTIONAL),
'scale' => new external_value(PARAM_INT, 'scale field', VALUE_OPTIONAL),
'assessed' => new external_value(PARAM_INT, 'assessed field', VALUE_OPTIONAL),
'assesstimestart' => new external_value(PARAM_INT, 'assesstimestart field', VALUE_OPTIONAL),
'assesstimefinish' => new external_value(PARAM_INT, 'assesstimefinish field', VALUE_OPTIONAL),
'defaultsort' => new external_value(PARAM_INT, 'defaultsort field', VALUE_OPTIONAL),
'defaultsortdir' => new external_value(PARAM_INT, 'defaultsortdir field', VALUE_OPTIONAL),
'editany' => new external_value(PARAM_BOOL, 'editany field', VALUE_OPTIONAL),
'notification' => new external_value(PARAM_INT, 'notification field', VALUE_OPTIONAL),
'timemodified' => new external_value(PARAM_INT, 'Time modified', VALUE_OPTIONAL)
), 'Database'
)
database_summary_exporter::get_read_structure()
),
'warnings' => new external_warnings(),
)
+242
View File
@@ -0,0 +1,242 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class for exporting partial database data.
*
* @package mod_data
* @copyright 2017 Juan Leyva <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_data\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
use renderer_base;
use external_files;
use external_util;
/**
* Class for exporting partial database data (some fields are only viewable by admins).
*
* @copyright 2017 Juan Leyva <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class database_summary_exporter extends exporter {
protected static function define_properties() {
return array(
'id' => array(
'type' => PARAM_INT,
'description' => 'Database id'),
'course' => array(
'type' => PARAM_INT,
'description' => 'Course id'),
'name' => array(
'type' => PARAM_RAW,
'description' => 'Database name'),
'intro' => array(
'type' => PARAM_RAW,
'description' => 'The Database intro',
),
'introformat' => array(
'choices' => array(FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN),
'type' => PARAM_INT,
'default' => FORMAT_MOODLE
),
'comments' => array(
'type' => PARAM_BOOL,
'description' => 'comments enabled',
),
'timeavailablefrom' => array(
'type' => PARAM_INT,
'description' => 'timeavailablefrom field',
),
'timeavailableto' => array(
'type' => PARAM_INT,
'description' => 'timeavailableto field',
),
'timeviewfrom' => array(
'type' => PARAM_INT,
'description' => 'timeviewfrom field',
),
'timeviewto' => array(
'type' => PARAM_INT,
'description' => 'timeviewto field',
),
'requiredentries' => array(
'type' => PARAM_INT,
'description' => 'requiredentries field',
),
'requiredentriestoview' => array(
'type' => PARAM_INT,
'description' => 'requiredentriestoview field',
),
'maxentries' => array(
'type' => PARAM_INT,
'description' => 'maxentries field',
),
'rssarticles' => array(
'type' => PARAM_INT,
'description' => 'rssarticles field',
),
'singletemplate' => array(
'type' => PARAM_RAW,
'description' => 'singletemplate field',
'null' => NULL_ALLOWED,
),
'listtemplate' => array(
'type' => PARAM_RAW,
'description' => 'listtemplate field',
'null' => NULL_ALLOWED,
),
'listtemplateheader' => array(
'type' => PARAM_RAW,
'description' => 'listtemplateheader field',
'null' => NULL_ALLOWED,
),
'listtemplatefooter' => array(
'type' => PARAM_RAW,
'description' => 'listtemplatefooter field',
'null' => NULL_ALLOWED,
),
'addtemplate' => array(
'type' => PARAM_RAW,
'description' => 'addtemplate field',
'null' => NULL_ALLOWED,
),
'rsstemplate' => array(
'type' => PARAM_RAW,
'description' => 'rsstemplate field',
'null' => NULL_ALLOWED,
),
'rsstitletemplate' => array(
'type' => PARAM_RAW,
'description' => 'rsstitletemplate field',
'null' => NULL_ALLOWED,
),
'csstemplate' => array(
'type' => PARAM_RAW,
'description' => 'csstemplate field',
'null' => NULL_ALLOWED,
),
'jstemplate' => array(
'type' => PARAM_RAW,
'description' => 'jstemplate field',
'null' => NULL_ALLOWED,
),
'asearchtemplate' => array(
'type' => PARAM_RAW,
'description' => 'asearchtemplate field',
'null' => NULL_ALLOWED,
),
'approval' => array(
'type' => PARAM_BOOL,
'description' => 'approval field',
),
'manageapproved' => array(
'type' => PARAM_BOOL,
'description' => 'manageapproved field',
),
'scale' => array(
'type' => PARAM_INT,
'description' => 'scale field',
'optional' => true,
),
'assessed' => array(
'type' => PARAM_INT,
'description' => 'assessed field',
'optional' => true,
),
'assesstimestart' => array(
'type' => PARAM_INT,
'description' => 'assesstimestart field',
'optional' => true,
),
'assesstimefinish' => array(
'type' => PARAM_INT,
'description' => 'assesstimefinish field',
'optional' => true,
),
'defaultsort' => array(
'type' => PARAM_INT,
'description' => 'defaultsort field',
),
'defaultsortdir' => array(
'type' => PARAM_INT,
'description' => 'defaultsortdir field',
),
'editany' => array(
'type' => PARAM_BOOL,
'description' => 'editany field (not used any more)',
'optional' => true,
),
'notification' => array(
'type' => PARAM_INT,
'description' => 'notification field (not used any more)',
'optional' => true,
),
'timemodified' => array(
'type' => PARAM_INT,
'description' => 'Time modified',
'optional' => true,
),
);
}
protected static function define_related() {
return array(
'context' => 'context'
);
}
protected static function define_other_properties() {
return array(
'coursemodule' => array(
'type' => PARAM_INT
),
'introfiles' => array(
'type' => external_files::get_properties_for_exporter(),
'multiple' => true,
'optional' => true,
),
);
}
protected function get_other_values(renderer_base $output) {
$context = $this->related['context'];
$values = array(
'coursemodule' => $context->instanceid,
'introfiles' => external_util::get_area_files($context->id, 'mod_data', 'intro', false, false),
);
return $values;
}
/**
* Get the formatting parameters for the intro.
*
* @return array
*/
protected function get_format_parameters_for_intro() {
return [
'component' => 'mod_data',
'filearea' => 'intro',
];
}
}
+11 -9
View File
@@ -94,7 +94,9 @@ class mod_data_external_testcase extends externallib_advanced_testcase {
// First for the student user.
$expectedfields = array('id', 'coursemodule', 'course', 'name', 'comments', 'timeavailablefrom',
'timeavailableto', 'timeviewfrom', 'timeviewto', 'requiredentries', 'requiredentriestoview',
'intro', 'introformat', 'introfiles');
'intro', 'introformat', 'introfiles', 'maxentries', 'rssarticles', 'singletemplate', 'listtemplate',
'listtemplateheader', 'listtemplatefooter', 'addtemplate', 'rsstemplate', 'rsstitletemplate',
'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', 'defaultsort', 'defaultsortdir', 'manageapproved');
// Add expected coursemodule.
$database1->coursemodule = $database1->cmid;
@@ -105,6 +107,10 @@ class mod_data_external_testcase extends externallib_advanced_testcase {
$expected1 = array();
$expected2 = array();
foreach ($expectedfields as $field) {
if ($field == 'approval' or $field == 'manageapproved') {
$database1->{$field} = (bool) $database1->{$field};
$database2->{$field} = (bool) $database2->{$field};
}
$expected1[$field] = $database1->{$field};
$expected2[$field] = $database2->{$field};
}
@@ -143,17 +149,13 @@ class mod_data_external_testcase extends externallib_advanced_testcase {
// Now, try as a teacher for getting all the additional fields.
self::setUser($teacher);
$additionalfields = array('maxentries', 'rssarticles', 'singletemplate', 'listtemplate', 'timemodified',
'listtemplateheader', 'listtemplatefooter', 'addtemplate', 'rsstemplate', 'rsstitletemplate',
'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', 'scale', 'assessed', 'assesstimestart',
'assesstimefinish', 'defaultsort', 'defaultsortdir', 'editany', 'notification', 'manageapproved');
$additionalfields = array('scale', 'assessed', 'assesstimestart', 'assesstimefinish', 'editany', 'notification', 'timemodified');
foreach ($additionalfields as $field) {
if ($field == 'approval' or $field == 'editany') {
$expecteddatabases[0][$field] = (bool) $database1->{$field};
} else {
$expecteddatabases[0][$field] = $database1->{$field};
if ($field == 'editany') {
$database1->{$field} = (bool) $database1->{$field};
}
$expecteddatabases[0][$field] = $database1->{$field};
}
$result = mod_data_external::get_databases_by_courses();
$result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
+6
View File
@@ -1,6 +1,12 @@
This files describes API changes in /mod/data - plugins,
information provided here is intended especially for developers.
=== 3.3 ===
* External function get_databases_by_courses now return more fields for users with mod/data:viewentry capability enabled:
maxentries, rssarticles, singletemplate, listtemplate, listtemplateheader, listtemplatefooter, addtemplate,
rsstemplate, rsstitletemplate, csstemplate, jstemplate, asearchtemplate, approval, defaultsort, defaultsortdir, manageapproved.
=== 3.2 ===
* New hook - update_content_import - Can be implemented by field subplugins data_field_* class