Merge branch 'MDL-68454-master' of git://github.com/andrewnicols/moodle
authorAdrian Greeve <abgreeve@gmail.com>
Mon, 4 May 2020 04:18:54 +0000 (12:18 +0800)
committerAdrian Greeve <abgreeve@gmail.com>
Mon, 4 May 2020 04:18:54 +0000 (12:18 +0800)
lib/table/classes/dynamic.php
lib/table/classes/external/dynamic/fetch.php
lib/tablelib.php
lib/upgrade.txt
mod/feedback/classes/responses_table.php
user/classes/table/participants.php
user/index.php

index 69701a0..4288756 100644 (file)
@@ -19,7 +19,6 @@
  *
  * @package core_table
  * @copyright 2020 Simey Lameze <simey@moodle.com>
- *
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
@@ -27,60 +26,19 @@ declare(strict_types=1);
 
 namespace core_table;
 
-defined('MOODLE_INTERNAL') || die();
-
-use moodle_url;
-use context;
-use core_table\local\filter\filterset;
-
 /**
- * Interface dynamic.
+ * Interface to identify this table as a table which can be dynamically updated via webservice calls.
+ *
+ * For a table to be defined as dynamic it must meet the following requirements:
+ *
+ * # it must be located with a namespaced class of \[component]\table\[tablename]
+ * # it must define a \core_table\local\filter\filterset implementation in \[component]\table\[tablename]_filterset
+ * # it must override the {{guess_base_url}} function and specify a base URL to be used when constructing URLs
+ * # it must override the {{get_context}} function to specify the correct context
  *
  * @package core_table
+ * @copyright 2020 Simey Lameze <simey@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 interface dynamic {
-
-    /**
-     * Take a string and convert it to the format expected by the table.
-     * For example, you may have a format such as:
-     *
-     *   mod_assign-submissions-[courseid]
-     *
-     * Passing this function an argument of [courseid] would return the fully-formed string.
-     *
-     * @param string $argument
-     * @return string
-     */
-    public static function get_unique_id_from_argument(string $argument): string;
-
-    /**
-     * Get the base url.
-     *
-     * @return moodle_url
-     */
-    public function get_base_url(): moodle_url;
-
-    /**
-     * Set the filterset filters build table object.
-     *
-     * @param filterset $filterset The filterset object to get the filters from.
-     * @return void
-     */
-    public function set_filterset(filterset $filterset): void;
-
-    /**
-     * Get the currently defined filterset.
-     *
-     * @return filterset
-     */
-    public function get_filterset(): ?filterset;
-
-    /**
-     * Get the context of the current table.
-     *
-     * Note: This function should not be called until after the filterset has been provided.
-     *
-     * @return context
-     */
-    public function get_context(): ?context;
 }
index 6e117e9..890efb5 100644 (file)
@@ -214,6 +214,8 @@ class fetch extends external_api {
 
         $instance = new $tableclass($uniqueid);
         $instance->set_filterset($filterset);
+        self::validate_context($instance->get_context());
+
         $instance->set_sorting($sortby, $sortorder);
 
         if ($firstinitial !== null) {
@@ -236,10 +238,6 @@ class fetch extends external_api {
             $instance->set_hidden_columns($hiddencolumns);
         }
 
-        $context = $instance->get_context();
-        self::validate_context($context);
-        $PAGE->set_url($instance->get_base_url());
-
         ob_start();
         $instance->out($pagesize, true);
         $tablehtml = ob_get_contents();
index 7e669a2..55a83c2 100644 (file)
@@ -46,6 +46,7 @@ define('TABLE_P_TOP',    1);
 define('TABLE_P_BOTTOM', 2);
 /**#@-*/
 
+use core_table\local\filter\filterset;
 
 /**
  * @package   moodlecore
@@ -157,6 +158,12 @@ class flexible_table {
     /** @var array $hiddencolumns List of hidden columns. */
     protected $hiddencolumns;
 
+    /**
+     * @var filterset The currently applied filerset
+     * This is required for dynamic tables, but can be used by other tables too if desired.
+     */
+    protected $filterset = null;
+
     /**
      * Constructor
      * @param string $uniqueid all tables have to have a unique id, this is used
@@ -831,9 +838,9 @@ class flexible_table {
      * @return string contents of cell in column 'fullname', for this row.
      */
     function col_fullname($row) {
-        global $PAGE, $COURSE;
+        global $COURSE;
 
-        $name = fullname($row, has_capability('moodle/site:viewfullnames', $PAGE->context));
+        $name = fullname($row, has_capability('moodle/site:viewfullnames', $this->get_context()));
         if ($this->download) {
             return $name;
         }
@@ -1211,7 +1218,7 @@ class flexible_table {
      * This function is not part of the public api.
      */
     function print_headers() {
-        global $CFG, $OUTPUT, $PAGE;
+        global $CFG, $OUTPUT;
 
         echo html_writer::start_tag('thead');
         echo html_writer::start_tag('tr');
@@ -1233,7 +1240,7 @@ class flexible_table {
 
                 case 'fullname':
                     // Check the full name display for sortable fields.
-                    if (has_capability('moodle/site:viewfullnames', $PAGE->context)) {
+                    if (has_capability('moodle/site:viewfullnames', $this->get_context())) {
                         $nameformat = $CFG->alternativefullnameformat;
                     } else {
                         $nameformat = $CFG->fullnamedisplay;
@@ -1693,6 +1700,55 @@ class flexible_table {
 
         return false;
     }
+
+    /**
+     * Get the context for the table.
+     *
+     * Note: This function _must_ be overridden by dynamic tables to ensure that the context is correctly determined
+     * from the filterset parameters.
+     *
+     * @return context
+     */
+    public function get_context(): context {
+        global $PAGE;
+
+        if (is_a($this, \core_table\dynamic::class)) {
+            throw new coding_exception('The get_context function must be defined for a dynamic table');
+        }
+
+        return $PAGE->context;
+    }
+
+    /**
+     * Set the filterset in the table class.
+     *
+     * The use of filtersets is a requirement for dynamic tables, but can be used by other tables too if desired.
+     *
+     * @param filterset $filterset The filterset object to get filters and table parameters from
+     */
+    public function set_filterset(filterset $filterset): void {
+        $this->filterset = $filterset;
+
+        $this->guess_base_url();
+    }
+
+    /**
+     * Get the currently defined filterset.
+     *
+     * @return filterset
+     */
+    public function get_filterset(): ?filterset {
+        return $this->filterset;
+    }
+
+    /**
+     * Attempt to guess the base URL.
+     */
+    public function guess_base_url(): void {
+        if (is_a($this, \core_table\dynamic::class)) {
+            throw new coding_exception('The guess_base_url function must be defined for a dynamic table');
+        }
+    }
 }
 
 
index eb04ddc..04d9108 100644 (file)
@@ -47,6 +47,8 @@ information provided here is intended especially for developers.
   db/services.php. Note - this also requires $CFG->enable_read_only_sessions to be set to true.
 * database_manager::check_database_schema() now checks for missing and extra indexes.
 * Implement a more direct xsendfile_file() method for an alternative_file_system_class
+* A new `dynamic` table interface has been defined, which allows any `flexible_table` to be converted into a table which
+  is updatable via ajax calls. See MDL-68495 and `\core_table\dynamic` for further information.
 
 === 3.8 ===
 * Add CLI option to notify all cron tasks to stop: admin/cli/cron.php --stop
index 9ce2b39..383a322 100644 (file)
@@ -181,7 +181,7 @@ class mod_feedback_responses_table extends table_sql {
      * Current context
      * @return context_module
      */
-    protected function get_context() {
+    public function get_context(): context {
         return context_module::instance($this->feedbackstructure->get_cm()->id);
     }
 
index b1f4395..6dee76b 100644 (file)
@@ -495,9 +495,6 @@ class participants extends \table_sql implements dynamic_table {
      * @param filterset $filterset The filterset object to get the filters from.
      */
     public function set_filterset(filterset $filterset): void {
-        // Store the filterset for later.
-        $this->filterset = $filterset;
-
         // Get the context.
         $this->courseid = $filterset->get_filter('courseid')->current();
         $this->course = get_course($this->courseid);
@@ -534,29 +531,14 @@ class participants extends \table_sql implements dynamic_table {
             $this->search = $filterset->get_filter('keywords')->get_filter_values();
         }
 
-        $this->define_baseurl($this->get_base_url());
+        parent::set_filterset($filterset);
     }
 
     /**
-     * Get an unique id for the participants table.
-     * @param string $argument An argument for the unique id, can be course id.
-     * @return string
-     */
-    public static function get_unique_id_from_argument(string $argument): string {
-        return "user-index-participants-{$argument}";
-    }
-
-    /**
-     * Get the base url for the participants table.
-     *
-     * @return moodle_url
+     * Guess the base url for the participants table.
      */
-    public function get_base_url(): moodle_url {
-        if ($this->baseurl === null) {
-            return new moodle_url('/user/index.php', ['id' => $this->courseid]);
-        }
-
-        return $this->baseurl;
+    public function guess_base_url(): void {
+        $this->baseurl = new moodle_url('/user/index.php', ['id' => $this->courseid]);
     }
 
     /**
@@ -566,16 +548,7 @@ class participants extends \table_sql implements dynamic_table {
      *
      * @return context
      */
-    public function get_context(): ?context {
+    public function get_context(): context {
         return $this->context;
     }
-
-    /**
-     * Get the currently defined filterset.
-     *
-     * @return filterset
-     */
-    public function get_filterset(): ?filterset {
-        return $this->filterset;
-    }
 }
index 1082bbc..92f81e2 100644 (file)
@@ -275,7 +275,7 @@ if (count($keywordfilter)) {
     $filterset->add_filter($keywordfilter);
 }
 
-$participanttable = new \core_user\table\participants(\core_user\table\participants::get_unique_id_from_argument($course->id));
+$participanttable = new \core_user\table\participants("user-index-participants-{$course->id}");
 $participanttable->set_selectall($selectall);
 $participanttable->set_filterset($filterset);
 $participanttable->define_baseurl($baseurl);