From aefe9c5faabcb6f705f24d81210e1463c3f71ace Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Mon, 13 Feb 2017 12:38:56 +0100 Subject: [PATCH 1/2] MDL-57919 mod_data: Refactor and new method get_configs_for_external --- mod/data/field/checkbox/field.class.php | 15 +++++++++++++++ mod/data/field/date/field.class.php | 15 ++++++++++++++- mod/data/field/file/field.class.php | 14 ++++++++++++++ mod/data/field/latlong/field.class.php | 15 +++++++++++++++ mod/data/field/menu/field.class.php | 14 ++++++++++++++ mod/data/field/multimenu/field.class.php | 14 ++++++++++++++ mod/data/field/number/field.class.php | 15 +++++++++++++++ mod/data/field/picture/field.class.php | 15 +++++++++++++++ mod/data/field/radiobutton/field.class.php | 15 +++++++++++++++ mod/data/field/text/field.class.php | 15 +++++++++++++++ mod/data/field/textarea/field.class.php | 14 ++++++++++++++ mod/data/field/url/field.class.php | 14 ++++++++++++++ mod/data/lib.php | 16 ++++++++++++++++ mod/data/locallib.php | 19 +++++++++++++++++++ mod/data/upgrade.txt | 4 ++++ 15 files changed, 213 insertions(+), 1 deletion(-) diff --git a/mod/data/field/checkbox/field.class.php b/mod/data/field/checkbox/field.class.php index dbfb3de09cb..9bded8de5c3 100644 --- a/mod/data/field/checkbox/field.class.php +++ b/mod/data/field/checkbox/field.class.php @@ -266,4 +266,19 @@ class data_field_checkbox extends data_field_base { return trim($strvalue, "\r\n "); } + + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/date/field.class.php b/mod/data/field/date/field.class.php index 319727b85b1..84d3cc49a7f 100644 --- a/mod/data/field/date/field.class.php +++ b/mod/data/field/date/field.class.php @@ -167,5 +167,18 @@ class data_field_date extends data_field_base { return $DB->sql_cast_char2int($fieldname, true); } - + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/file/field.class.php b/mod/data/field/file/field.class.php index 5e6cf2fad02..59be112f07a 100644 --- a/mod/data/field/file/field.class.php +++ b/mod/data/field/file/field.class.php @@ -222,4 +222,18 @@ class data_field_file extends data_field_base { return false; } + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/latlong/field.class.php b/mod/data/field/latlong/field.class.php index e504bf2cd1a..5f4a182e63f 100644 --- a/mod/data/field/latlong/field.class.php +++ b/mod/data/field/latlong/field.class.php @@ -291,4 +291,19 @@ class data_field_latlong extends data_field_base { // If we get here then only one field has been filled in. return get_string('latlongboth', 'data'); } + + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/menu/field.class.php b/mod/data/field/menu/field.class.php index 075b033c2b0..eb48b8647d4 100644 --- a/mod/data/field/menu/field.class.php +++ b/mod/data/field/menu/field.class.php @@ -134,4 +134,18 @@ class data_field_menu extends data_field_base { return strval($value) !== ''; } + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/multimenu/field.class.php b/mod/data/field/multimenu/field.class.php index 885bbe8d302..73f496c2a35 100644 --- a/mod/data/field/multimenu/field.class.php +++ b/mod/data/field/multimenu/field.class.php @@ -293,4 +293,18 @@ class data_field_multimenu extends data_field_base { return trim($strvalue, "\r\n "); } + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/number/field.class.php b/mod/data/field/number/field.class.php index dc116156101..b29285017cc 100644 --- a/mod/data/field/number/field.class.php +++ b/mod/data/field/number/field.class.php @@ -105,6 +105,21 @@ class data_field_number extends data_field_base { function notemptyfield($value, $name) { return strval($value) !== ''; } + + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/picture/field.class.php b/mod/data/field/picture/field.class.php index fbcdf991332..9e0e762867d 100644 --- a/mod/data/field/picture/field.class.php +++ b/mod/data/field/picture/field.class.php @@ -324,4 +324,19 @@ class data_field_picture extends data_field_base { } return false; } + + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/radiobutton/field.class.php b/mod/data/field/radiobutton/field.class.php index ed508053c19..13bf158d1dc 100644 --- a/mod/data/field/radiobutton/field.class.php +++ b/mod/data/field/radiobutton/field.class.php @@ -132,5 +132,20 @@ class data_field_radiobutton extends data_field_base { function notemptyfield($value, $name) { return strval($value) !== ''; } + + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/text/field.class.php b/mod/data/field/text/field.class.php index 4c255953c3e..74db56b90e3 100644 --- a/mod/data/field/text/field.class.php +++ b/mod/data/field/text/field.class.php @@ -61,6 +61,21 @@ class data_field_text extends data_field_base { function notemptyfield($value, $name) { return strval($value) !== ''; } + + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/textarea/field.class.php b/mod/data/field/textarea/field.class.php index 3ae89d2ebf9..16893c035f9 100644 --- a/mod/data/field/textarea/field.class.php +++ b/mod/data/field/textarea/field.class.php @@ -294,4 +294,18 @@ class data_field_textarea extends data_field_base { return content_to_text($content->content, $content->content1); } + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/field/url/field.class.php b/mod/data/field/url/field.class.php index 2c8f5bb8b75..f474e2992df 100644 --- a/mod/data/field/url/field.class.php +++ b/mod/data/field/url/field.class.php @@ -224,4 +224,18 @@ class data_field_url extends data_field_base { return $record->content . " " . $record->content1; } + /** + * Return the plugin configs for external functions. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the config parameters. + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = $this->field->{"param$i"}; + } + return $configs; + } } diff --git a/mod/data/lib.php b/mod/data/lib.php index f74f6a2c633..594df7cbd20 100644 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -560,6 +560,22 @@ class data_field_base { // Base class for Database Field Types (see field/*/ public static function get_content_value($content) { return trim($content->content, "\r\n "); } + + /** + * Return the plugin configs for external functions, + * in some cases the configs will need formatting or be returned only if the current user has some capabilities enabled. + * + * @return array the list of config parameters + * @since Moodle 3.3 + */ + public function get_config_for_external() { + // Return all the field configs to null (maybe there is a private key for a service or something similar there). + $configs = []; + for ($i = 1; $i <= 10; $i++) { + $configs["param$i"] = null; + } + return $configs; + } } diff --git a/mod/data/locallib.php b/mod/data/locallib.php index ebf587ba970..ba97d1c156c 100644 --- a/mod/data/locallib.php +++ b/mod/data/locallib.php @@ -1058,3 +1058,22 @@ function data_can_view_record($data, $record, $currentgroup, $canmanageentries) } return false; } + +/** + * Return all the field instances for a given database. + * + * @param stdClass $data database object + * @return array field instances + * @since Moodle 3.3 + */ +function data_get_field_instances($data) { + global $DB; + + $instances = []; + if ($fields = $DB->get_records('data_fields', array('dataid' => $data->id), 'id')) { + foreach ($fields as $field) { + $instances[] = data_get_field($field, $data); + } + } + return $instances; +} diff --git a/mod/data/upgrade.txt b/mod/data/upgrade.txt index 401dee1c768..7e3a1c26bd0 100644 --- a/mod/data/upgrade.txt +++ b/mod/data/upgrade.txt @@ -6,6 +6,10 @@ information provided here is intended especially for developers. * 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. +* Data field classes extending data_field_base should implement the get_config_for_external method. + This method is used for returning the field settings for external functions. + You should check the user capabilities of the current user before returning any field setting value. + This is intended to protect field settings like private keys for external systems. === 3.2 === From a934c896398eada9d78cb9b72115bc5e15a927a7 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Mon, 13 Feb 2017 12:39:37 +0100 Subject: [PATCH 2/2] MDL-57919 mod_data: New WS mod_data_get_fields --- mod/data/classes/external.php | 75 +++++++++++++++++ mod/data/classes/external/field_exporter.php | 85 ++++++++++++++++++++ mod/data/db/services.php | 8 ++ mod/data/tests/externallib_test.php | 18 +++++ mod/data/version.php | 2 +- 5 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 mod/data/classes/external/field_exporter.php diff --git a/mod/data/classes/external.php b/mod/data/classes/external.php index 6d27f17ade7..c2b67ac9bc9 100644 --- a/mod/data/classes/external.php +++ b/mod/data/classes/external.php @@ -32,6 +32,7 @@ require_once($CFG->dirroot . "/mod/data/locallib.php"); use mod_data\external\database_summary_exporter; use mod_data\external\record_exporter; use mod_data\external\content_exporter; +use mod_data\external\field_exporter; /** * Database module external functions @@ -567,4 +568,78 @@ class mod_data_external extends external_api { ) ); } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.3 + */ + public static function get_fields_parameters() { + return new external_function_parameters( + array( + 'databaseid' => new external_value(PARAM_INT, 'Database instance id.'), + ) + ); + } + + /** + * Return the list of configured fields for the given database. + * + * @param int $databaseid the database id + * @return array of warnings and the fields + * @since Moodle 3.3 + * @throws moodle_exception + */ + public static function get_fields($databaseid) { + global $PAGE; + + $params = array('databaseid' => $databaseid); + $params = self::validate_parameters(self::get_fields_parameters(), $params); + $warnings = array(); + + list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); + + // Check database is open in time. + $canmanageentries = has_capability('mod/data:manageentries', $context); + data_require_time_available($database, $canmanageentries); + + $fieldinstances = data_get_field_instances($database); + + foreach ($fieldinstances as $fieldinstance) { + $record = $fieldinstance->field; + // Now get the configs the user can see with his current permissions. + $configs = $fieldinstance->get_config_for_external(); + foreach ($configs as $name => $value) { + // Overwrite. + $record->{$name} = $value; + } + + $exporter = new field_exporter($record, array('context' => $context)); + $fields[] = $exporter->export($PAGE->get_renderer('core')); + } + + $result = array( + 'fields' => $fields, + 'warnings' => $warnings + ); + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.3 + */ + public static function get_fields_returns() { + return new external_single_structure( + array( + 'fields' => new external_multiple_structure( + field_exporter::get_read_structure() + ), + 'warnings' => new external_warnings() + ) + ); + } } diff --git a/mod/data/classes/external/field_exporter.php b/mod/data/classes/external/field_exporter.php new file mode 100644 index 00000000000..42f065e566c --- /dev/null +++ b/mod/data/classes/external/field_exporter.php @@ -0,0 +1,85 @@ +. + +/** + * Class for exporting field data. + * + * @package mod_data + * @copyright 2017 Juan Leyva + * @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; + +/** + * Class for exporting field data. + * + * @copyright 2017 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class field_exporter extends exporter { + + protected static function define_properties() { + + $properties = array( + 'id' => array( + 'type' => PARAM_INT, + 'description' => 'Field id.', + ), + 'dataid' => array( + 'type' => PARAM_INT, + 'description' => 'The field type of the content.', + 'default' => 0, + ), + 'type' => array( + 'type' => PARAM_PLUGIN, + 'description' => 'The field type.', + ), + 'name' => array( + 'type' => PARAM_TEXT, + 'description' => 'The field name.', + ), + 'description' => array( + 'type' => PARAM_RAW, + 'description' => 'The field description.', + ), + 'required' => array( + 'type' => PARAM_BOOL, + 'description' => 'Whether is a field required or not.', + 'default' => 0, + ), + ); + // Field possible parameters. + for ($i = 1; $i <= 10; $i++) { + $properties["param$i"] = array( + 'type' => PARAM_RAW, + 'description' => 'Field parameters', + 'null' => NULL_ALLOWED, + ); + } + + return $properties; + } + + protected static function define_related() { + // Context is required for text formatting. + return array( + 'context' => 'context', + ); + } +} diff --git a/mod/data/db/services.php b/mod/data/db/services.php index c43e594de50..c98e19633ad 100644 --- a/mod/data/db/services.php +++ b/mod/data/db/services.php @@ -67,4 +67,12 @@ $functions = array( 'capabilities' => 'mod/data:viewentry', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), + 'mod_data_get_fields' => array( + 'classname' => 'mod_data_external', + 'methodname' => 'get_fields', + 'description' => 'Return the list of configured fields for the given database.', + 'type' => 'read', + 'capabilities' => 'mod/data:viewentry', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) + ), ); diff --git a/mod/data/tests/externallib_test.php b/mod/data/tests/externallib_test.php index 4f40b81eb08..30ec6d854b6 100644 --- a/mod/data/tests/externallib_test.php +++ b/mod/data/tests/externallib_test.php @@ -601,4 +601,22 @@ class mod_data_external_testcase extends externallib_advanced_testcase { $this->expectException('moodle_exception'); $result = mod_data_external::get_entry($entry21); } + + /** + * Test get_fields. + */ + public function test_get_fields() { + global $DB; + list($entry11, $entry12, $entry13, $entry21) = self::populate_database_with_entries(); + + $this->setUser($this->student1); + $result = mod_data_external::get_fields($this->data->id); + $result = external_api::clean_returnvalue(mod_data_external::get_fields_returns(), $result); + + // Basically compare we retrieve all the fields and the correct values. + $fields = $DB->get_records('data_fields', array('dataid' => $this->data->id), 'id'); + foreach ($result['fields'] as $field) { + $this->assertEquals($field, (array) $fields[$field['id']]); + } + } } diff --git a/mod/data/version.php b/mod/data/version.php index 54fe1cad169..f317280d5e0 100644 --- a/mod/data/version.php +++ b/mod/data/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2016120504; // The current module version (Date: YYYYMMDDXX) +$plugin->version = 2016120505; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2016112900; // Requires this Moodle version $plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics) $plugin->cron = 0;