From 9c317c83c5adbb4fefc0e7e27896fa354d8f949e Mon Sep 17 00:00:00 2001
From: Astor Bizard <astor.bizard@grenoble-inp.fr>
Date: Mon, 30 Mar 2020 13:27:19 +0200
Subject: [PATCH] Created 2 webservices to get and set a VPL activity settings.

---
 db/services.php             |  46 ++++++++----
 externallib.php             | 138 ++++++++++++++++++++++++++----------
 version.php                 |   2 +-
 views/vpl_grapher.class.php |   4 +-
 4 files changed, 134 insertions(+), 56 deletions(-)

diff --git a/db/services.php b/db/services.php
index 43583a81..eee1e1d7 100644
--- a/db/services.php
+++ b/db/services.php
@@ -66,30 +66,46 @@ $functions = array (
                 'requiredcapability' => 'mod/vpl:view',
                 'type' => 'write'
         ),
-	'mod_vpl_save_required_files' => array (
-                 'classname' => 'mod_vpl_webservice',
-                 'methodname' => 'save_required_files',
-                 'classpath' => 'mod/vpl/externallib.php',
-                 'description' => 'Save/submit the required files of a VPL activity',
-                 'requiredcapability' => 'mod/vpl:manage',
-                 'type' => 'write'
-         ),
-         'mod_vpl_save_corrected_files' => array (
+        'mod_vpl_save_required_files' => array (
+                'classname' => 'mod_vpl_webservice',
+                'methodname' => 'save_required_files',
+                'classpath' => 'mod/vpl/externallib.php',
+                'description' => 'Save/submit the required files of a VPL activity',
+                'requiredcapability' => 'mod/vpl:manage',
+                'type' => 'write'
+        ),
+        'mod_vpl_save_corrected_files' => array (
                  'classname' => 'mod_vpl_webservice',
                  'methodname' => 'save_corrected_files',
                  'classpath' => 'mod/vpl/externallib.php',
                  'description' => 'Save/submit the corrected files of a VPL activity',
                  'requiredcapability' => 'mod/vpl:manage',
                  'type' => 'write'
-         ),
-         'mod_vpl_save_execution_files' => array (
+        ),
+        'mod_vpl_save_execution_files' => array (
                  'classname' => 'mod_vpl_webservice',
                  'methodname' => 'save_execution_files',
                  'classpath' => 'mod/vpl/externallib.php',
                  'description' => 'Save/submit the execution files of a VPL activity',
                  'requiredcapability' => 'mod/vpl:manage',
                  'type' => 'write'
-         )
+        ),
+        'mod_vpl_get_setting' => array (
+                'classname' => 'mod_vpl_webservice',
+                'methodname' => 'get_setting',
+                'classpath' => 'mod/vpl/externallib.php',
+                'description' => 'Get a setting of a VPL activity',
+                'requiredcapability' => 'mod/vpl:manage',
+                'type' => 'read'
+        ),
+        'mod_vpl_set_setting' => array (
+                'classname' => 'mod_vpl_webservice',
+                'methodname' => 'set_setting',
+                'classpath' => 'mod/vpl/externallib.php',
+                'description' => 'Change a setting of a VPL activity',
+                'requiredcapability' => 'mod/vpl:manage',
+                'type' => 'write'
+        )
 );
 // Define web service.
 $services = array (
@@ -100,9 +116,11 @@ $services = array (
                         'mod_vpl_open',
                         'mod_vpl_evaluate',
                         'mod_vpl_get_result',
-			'mod_vpl_save_required_files',
+                        'mod_vpl_save_required_files',
                         'mod_vpl_save_corrected_files',
-                        'mod_vpl_save_execution_files'
+                        'mod_vpl_save_execution_files',
+                        'mod_vpl_get_setting',
+                        'mod_vpl_set_setting'
                 ),
                 'shortname' => 'mod_vpl_edit',
                 'restrictedusers' => 0,
diff --git a/externallib.php b/externallib.php
index 8de05c02..e2d00d1e 100644
--- a/externallib.php
+++ b/externallib.php
@@ -28,6 +28,7 @@ require_once($CFG->libdir . "/externallib.php");
 require_once(dirname( __FILE__ ) . '/locallib.php');
 require_once(dirname( __FILE__ ) . '/forms/edit.class.php');
 require_once(dirname( __FILE__ ) . '/vpl_submission.class.php');
+require_once(dirname( __FILE__ ) . '/mod_form.php');
 class mod_vpl_webservice extends external_api {
     private static function initial_checks($id, $password) {
         $vpl = new mod_vpl( $id );
@@ -112,17 +113,10 @@ class mod_vpl_webservice extends external_api {
     }
 
     /*
-     * save teacher files (required, corrected and execution) function. save/submit the teacher files
+     * save teacher files (required, corrected and execution) functions. save/submit the teacher files
      */
     public static function save_required_files_parameters() {
-        return new external_function_parameters( array (
-            'id' => new external_value( PARAM_INT, 'Activity id (course_module)', VALUE_REQUIRED ),
-            'files' => new external_multiple_structure( new external_single_structure( array (
-                'name' => new external_value( PARAM_RAW, 'File name' ),
-                'data' => new external_value( PARAM_RAW, 'File content' )
-            ) ) ),
-            'password' => new external_value( PARAM_RAW, 'Activity password', VALUE_DEFAULT, '' )
-        ) );
+        return self::save_teacher_files_parameters();
     }
     public static function save_required_files( $id, $files = array(), $password = '' ) {
         self::save_teacher_files( $id, $files, $password, 'required' );
@@ -132,14 +126,7 @@ class mod_vpl_webservice extends external_api {
     }
 
     public static function save_corrected_files_parameters() {
-        return new external_function_parameters( array (
-            'id' => new external_value( PARAM_INT, 'Activity id (course_module)', VALUE_REQUIRED ),
-            'files' => new external_multiple_structure( new external_single_structure( array (
-                'name' => new external_value( PARAM_RAW, 'File name' ),
-                'data' => new external_value( PARAM_RAW, 'File content' )
-            ) ) ),
-            'password' => new external_value( PARAM_RAW, 'Activity password', VALUE_DEFAULT, '' )
-        ) );
+        return self::save_teacher_files_parameters();
     }
     public static function save_corrected_files( $id, $files = array(), $password = '' ) {
         self::save_teacher_files( $id, $files, $password, 'corrected' );
@@ -149,14 +136,7 @@ class mod_vpl_webservice extends external_api {
     }
 
     public static function save_execution_files_parameters() {
-        return new external_function_parameters( array (
-            'id' => new external_value( PARAM_INT, 'Activity id (course_module)', VALUE_REQUIRED ),
-            'files' => new external_multiple_structure( new external_single_structure( array (
-                'name' => new external_value( PARAM_RAW, 'File name' ),
-                'data' => new external_value( PARAM_RAW, 'File content' )
-            ) ) ),
-            'password' => new external_value( PARAM_RAW, 'Activity password', VALUE_DEFAULT, '' )
-        ) );
+        return self::save_teacher_files_parameters();
     }
     public static function save_execution_files( $id, $files = array(), $password = '' ) {
         self::save_teacher_files( $id, $files, $password, 'execution' );
@@ -165,31 +145,34 @@ class mod_vpl_webservice extends external_api {
         return null;
     }
 
-    public static function save_teacher_files($id, $files = array(), $password = '', $type) {
+    private static function save_teacher_files($id, $files = array(), $password = '', $type) {
         global $USER;
-        $params = self::validate_parameters( self::save_parameters(), array (
-            'id' => $id,
-            'files' => $files,
-            'password' => $password
+        $params = self::validate_parameters( self::save_teacher_files_parameters(), array (
+                'id' => $id,
+                'files' => $files,
+                'password' => $password
         ) );
         $vpl = self::initial_checks( $id, $password );
         $vpl->require_capability( VPL_MANAGE_CAPABILITY );
-        if (! $vpl->is_submit_able()) {
-            throw new Exception( get_string( 'notavailable' ) );
-        }
-        $instance = $vpl->get_instance();
-        if ($instance->example or $instance->restrictededitor) {
-            throw new Exception( get_string( 'notavailable' ) );
-        }
         // Adapts to the file format VPL3.2.
         $oldfiles = $files;
         $files = array();
-        foreach ( $oldfiles as $file ) {
+        foreach ($oldfiles as $file) {
             $files [ $file['name'] ] = $file['data'];
         }
         mod_vpl_edit::save_teacher_files( $vpl, $USER->id, $files, $type );
     }
 
+    private static function save_teacher_files_parameters() {
+        return new external_function_parameters( array (
+                'id' => new external_value( PARAM_INT, 'Activity id (course_module)', VALUE_REQUIRED ),
+                'files' => new external_multiple_structure( new external_single_structure( array (
+                        'name' => new external_value( PARAM_RAW, 'File name' ),
+                        'data' => new external_value( PARAM_RAW, 'File content' )
+                ) ) ),
+                'password' => new external_value( PARAM_RAW, 'Activity password', VALUE_DEFAULT, '' )
+        ) );
+    }
 
     /*
      * save function. save/submit the students files
@@ -223,7 +206,7 @@ class mod_vpl_webservice extends external_api {
         // Adapts to the file format VPL3.2.
         $oldfiles = $files;
         $files = array();
-        foreach ( $oldfiles as $file ) {
+        foreach ($oldfiles as $file) {
             $files [ $file['name'] ] = $file['data'];
         }
         mod_vpl_edit::save( $vpl, $USER->id, $files );
@@ -363,4 +346,81 @@ if the websocket client send something to the server then the evaluation is stop
                 'grade' => new external_value( PARAM_RAW, 'Proposed or final grade' )
         ) );
     }
+
+    /*
+     * set_setting function. Change a setting of the VPL activity.
+     */
+    public static function set_setting_parameters() {
+        return new external_function_parameters( array (
+                'id' => new external_value( PARAM_INT, 'Activity id (course_module)', VALUE_REQUIRED ),
+                'settingname' => new external_value( PARAM_RAW, 'Setting name to set', VALUE_REQUIRED ),
+                'settingvalue' => new external_value( PARAM_RAW, 'Setting new value', VALUE_REQUIRED ),
+                'password' => new external_value( PARAM_RAW, 'Activity password', VALUE_DEFAULT, '' )
+        ) );
+    }
+    public static function set_setting($id, $settingname, $settingvalue, $password) {
+        self::validate_parameters( self::set_setting_parameters(), array (
+                'id' => $id,
+                'settingname' => $settingname,
+                'settingvalue' => $settingvalue,
+                'password' => $password
+        ) );
+
+        $vpl = self::initial_checks( $id, $password );
+        $vpl->require_capability( VPL_MANAGE_CAPABILITY );
+        $instance = $vpl->get_instance();
+        if (isset(mod_vpl_mod_form::$fieldsformat[$settingname])) {
+            $pattern = mod_vpl_mod_form::$fieldsformat[$settingname];
+            if (!preg_match($pattern, $settingvalue)) {
+                throw new moodle_exception('invalidsettingformat', VPL,
+                        null, mod_vpl_mod_form::$formatmessage[$pattern]);
+            }
+        }
+        $protectedfields = array( 'id', 'course' );
+        if (property_exists($instance, $settingname) && !in_array($settingname, $protectedfields)) {
+            $instance->$settingname = $settingvalue;
+            $success = $vpl->update();
+        } else {
+            throw new moodle_exception('nosuchsetting', VPL);
+        }
+        return array('success' => $success);
+    }
+    public static function set_setting_returns() {
+        return new external_single_structure( array (
+                'success' => new external_value( PARAM_RAW )
+        ) );
+    }
+
+    /*
+     * get_setting function. Get a setting of the VPL activity.
+     */
+    public static function get_setting_parameters() {
+        return new external_function_parameters( array (
+                'id' => new external_value( PARAM_INT, 'Activity id (course_module)', VALUE_REQUIRED ),
+                'settingname' => new external_value( PARAM_RAW, 'Setting name to set', VALUE_REQUIRED ),
+                'password' => new external_value( PARAM_RAW, 'Activity password', VALUE_DEFAULT, '' )
+        ) );
+    }
+    public static function get_setting($id, $settingname, $password) {
+        self::validate_parameters( self::get_setting_parameters(), array (
+                'id' => $id,
+                'settingname' => $settingname,
+                'password' => $password
+        ) );
+
+        $vpl = self::initial_checks( $id, $password );
+        $vpl->require_capability( VPL_MANAGE_CAPABILITY );
+        $instance = $vpl->get_instance();
+        if (property_exists($instance, $settingname)) {
+             $value = $instance->$settingname;
+        } else {
+            throw new moodle_exception('nosuchsetting', VPL);
+        }
+        return array('value' => $value);
+    }
+    public static function get_setting_returns() {
+        return new external_single_structure( array (
+                'value' => new external_value( PARAM_RAW )
+        ) );
+    }
 }
diff --git a/version.php b/version.php
index 7d3f191c..52f9159a 100644
--- a/version.php
+++ b/version.php
@@ -26,7 +26,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2018011319;
+$plugin->version = 2018011320;
 $plugin->cron    = 300; // Cron check this plugin every 5 minutes.
 $plugin->requires = 2014051200; // Moodle 2.7!
 $plugin->maturity = MATURITY_STABLE;
diff --git a/views/vpl_grapher.class.php b/views/vpl_grapher.class.php
index 5268a72b..5d3ab193 100644
--- a/views/vpl_grapher.class.php
+++ b/views/vpl_grapher.class.php
@@ -185,8 +185,8 @@ class vpl_grapher {
             }
             if ($diff && count($names) > 1) {
                 // Filter out all zero-diff files.
-                $names = array_filter($names, function($name) use(&$series){
-                    foreach ($series[$name] as $value){
+                $names = array_filter($names, function($name) use(&$series) {
+                    foreach ($series[$name] as $value) {
                         if ($value != 0) {
                             return true;
                         }
-- 
GitLab