MDL-52715 lib: Clean up of comments and variable names.
authorAdrian Greeve <adrian@moodle.com>
Thu, 21 Jan 2016 02:43:26 +0000 (10:43 +0800)
committerAdrian Greeve <adrian@moodle.com>
Wed, 3 Feb 2016 02:07:08 +0000 (10:07 +0800)
lib/amd/build/fragment.min.js
lib/amd/src/fragment.js
lib/db/services.php
lib/external/externallib.php
lib/outputfragmentrequirementslib.php
lib/outputlib.php
lib/pagelib.php
version.php

index 2cc8888..89a6952 100644 (file)
Binary files a/lib/amd/build/fragment.min.js and b/lib/amd/build/fragment.min.js differ
index 79a59a8..92d7e6d 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since      3.1
  */
-define(['jquery', 'core/ajax'], function($, ajax) {
+define(['jquery', 'core/ajax', 'core/notification'], function($, ajax, notification) {
 
     /**
      * Loads an HTML fragment through a callback.
      *
-     * @method load_fragment
+     * @method loadFragment
      * @param {string} component Component where callback is located.
      * @param {string} callback Callback function name.
+     * @param {integer} contextid Context ID of the fragment.
      * @param {object} params Parameters for the callback.
      * @return {Promise} JQuery promise object resolved when the fragment has been loaded.
      */
-    var load_fragment = function(component, callback, params) {
+    var loadFragment = function(component, callback, contextid, params) {
         // Change params into required webservice format.
         var formattedparams = [];
         for (var index in params) {
@@ -49,12 +50,11 @@ define(['jquery', 'core/ajax'], function($, ajax) {
             args:{
                 component: component,
                 callback: callback,
+                contextid: contextid,
                 args: formattedparams
             }
         }], false);
 
-        // Worth noting somewhere that the assign module seems to require userid, rownum etc. to be passed via POST / GET.
-
         promises[0].done(function(data) {
             deferred.resolve(data);
         }).fail(function(ex) {
@@ -63,6 +63,14 @@ define(['jquery', 'core/ajax'], function($, ajax) {
         return deferred.promise();
     };
 
+    /**
+     * Removes and cleans children of a node. This includes event handlers and listeners that may be
+     * attached to the nodes for both jquery and yui.
+     *
+     * @method recursiveCleanup
+     * @param {object} DOM node to be cleaned.
+     * @return {void}
+     */
     var recursiveCleanup = function(node) {
         node.children().each(function(index, el) {
             var child = $(el);
@@ -75,50 +83,35 @@ define(['jquery', 'core/ajax'], function($, ajax) {
         if (yuinode.get('childNodes')) {
             yuinode.empty();
         }
-        yuinode.remove();
+        yuinode.remove(true);
     };
 
     return /** @alias module:core/fragment */{
-
-        /**
-         * Loads an HTML fragment through a callback.
-         *
-         * @method fragment_load
-         * @param {string} component Component where callback is located.
-         * @param {string} callback Callback function name.
-         * @param {object} params Parameters for the callback.
-         * @return {Promise} JQuery promise object resolved when the fragment has been loaded.
-         */
-        fragment_load: function(component, callback, params) {
-
-            return load_fragment(component, callback, params);
-        },
-
         /**
          * Appends HTML and JavaScript fragments to specified nodes.
+         * Callbacks called by this AMD module are responsible for doing the appropriate security checks
+         * to access the information that is returned. This only does minimal validation on the context.
          *
-         * @method fragment_append
+         * @method fragmentAppend
          * @param {string} component Component where callback is located.
          * @param {string} callback Callback function name.
+         * @param {integer} contextid Context ID of the fragment.
          * @param {object} params Parameters for the callback.
          * @param {string} htmlnodeidentifier The 'class' or 'id' to attach the HTML.
          * @param {string} javascriptnodeidentifier The 'class' or 'id' to attach the JavaScript.
          * @return {void}
          */
-        fragment_append: function(component, callback, params, htmlnodeidentifier, javascriptnodeidentifier) {
-            // Clean up previous code if found first.
-            recursiveCleanup($('#fragment-html'));
-            recursiveCleanup($('#ajax-import-scripts'));
-
-            $.when(load_fragment('mod_assign', "fragment", params)).then(function(data) {
+        fragmentAppend: function(component, callback, contextid, params, htmlnodeidentifier, javascriptnodeidentifier) {
+            $.when(loadFragment(component, callback, contextid, params)).then(function(data) {
+                // Clean up previous code if found first.
+                recursiveCleanup($('#fragment-html'));
+                recursiveCleanup($('#fragment-scripts'));
                 // Attach new HTML and JavaScript.
-                $(htmlnodeidentifier).append("<div id=\"fragment-html\">");
-                $(htmlnodeidentifier).append("</div>");
-                $('#fragment-html').append(data.html);
+                $(htmlnodeidentifier).append('<div id="fragment-html">' + data.html + '</div>');
+                $(javascriptnodeidentifier).append('<div id="fragment-scripts">' + data.javascript + '</div>');
 
-                $(javascriptnodeidentifier).append("<div id=\"ajax-import-scripts\">");
-                $(javascriptnodeidentifier).append("</div>");
-                $('#ajax-import-scripts').append(data.javascript);
+            }).fail(function(ex) {
+                notification.exception(ex);
             });
         }
     };
index 6707877..f422c5d 100644 (file)
@@ -1057,7 +1057,6 @@ $functions = array(
         'classpath'   => 'lib/external/externallib.php',
         'description' => 'Return a fragment for inclusion, such as a JavaScript page.',
         'type'        => 'read',
-        'loginrequired' => false,
         'ajax'        => true,
     ),
 
index 4a37c83..6114f99 100644 (file)
@@ -270,13 +270,14 @@ class core_external extends external_api {
     public static function get_fragment_parameters() {
         return new external_function_parameters(
             array(
-                'component' => new external_value(PARAM_RAW, 'Component for the callback e.g. mod_asign'),
-                'callback' => new external_value(PARAM_RAW, 'Name of the callback to execute'),
+                'component' => new external_value(PARAM_COMPONENT, 'Component for the callback e.g. mod_assign'),
+                'callback' => new external_value(PARAM_ALPHANUMEXT, 'Name of the callback to execute'),
+                'contextid' => new external_value(PARAM_INT, 'Context ID that the fragment is from'),
                 'args' => new external_multiple_structure(
                     new external_single_structure(
                         array(
                             'name' => new external_value(PARAM_ALPHANUMEXT, 'param name'),
-                            'value' => new external_value(PARAM_TEXT, 'param value')
+                            'value' => new external_value(PARAM_RAW, 'param value')
                         )
                     ), 'args for the callback are optional', VALUE_OPTIONAL
                 )
@@ -287,20 +288,25 @@ class core_external extends external_api {
     /**
      * Get a HTML fragment for inserting into something. Initial use is for inserting mforms into
      * a page using AJAX.
+     * This web service is designed to be called only via AJAX and not directly.
+     * Callbacks that are called by this web service are responsible for doing the appropriate security checks
+     * to access the information returned. This only does minimal validation on the context.
      *
      * @param string $component Name of the component.
      * @param string $callback Function callback name.
+     * @param int $contextid Context ID this fragment is in.
      * @param array $args optional arguments for the callback.
      * @return array HTML and JavaScript fragments for insertion into stuff.
      * @since Moodle 3.1
      */
-    public static function get_fragment($component, $callback, $args = null) {
+    public static function get_fragment($component, $callback, $contextid, $args = null) {
         global $OUTPUT, $PAGE;
 
         $params = self::validate_parameters(self::get_fragment_parameters(),
                 array(
                     'component' => $component,
                     'callback' => $callback,
+                    'contextid' => $contextid,
                     'args' => $args
                 )
         );
@@ -311,16 +317,16 @@ class core_external extends external_api {
             $arguments[$paramargument['name']] = $paramargument['value'];
         }
 
-        // Remove warning about context not being set.
-        $PAGE->set_context(context_system::instance());
+        $context = context::instance_by_id($contextid);
+        self::validate_context($context);
 
         // Hack alert: Forcing bootstrap_renderer to initiate moodle page.
         $OUTPUT->header();
 
         // Overwriting page_requirements_manager with the fragment one so only JS included from
         // this point is returned to the user.
-        $PAGE->set_requirements_for_fragments();
-        $data = component_callback($params['component'], $params['callback'], $arguments);
+        $PAGE->start_collecting_javascript_requirements();
+        $data = component_callback($params['component'], 'output_fragment_' . $params['callback'], $arguments);
         $jsfooter = $PAGE->requires->get_end_code();
         $output = array('html' => $data, 'javascript' => $jsfooter);
         return $output;
index 0bba1f0..0ae13fb 100644 (file)
@@ -17,8 +17,6 @@
 /**
  * Library functions to facilitate the use of JavaScript in Moodle.
  *
- * Note: you can find history of this file in lib/ajax/ajaxlib.php
- *
  * @copyright 2016 Adrian Greeve <adrian@moodle.com>
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @package core
 defined('MOODLE_INTERNAL') || die();
 
 /**
- * This class tracks all the things that are needed by the current page.
- *
- * Normally, the only instance of this class you will need to work with is the
- * one accessible via $PAGE->requires.
- *
- * Typical usage would be
- * <pre>
- *     $PAGE->requires->js_call_amd('mod_forum/view', 'init');
- * </pre>
- *
- * It also supports obsoleted coding style with/without YUI3 modules.
- * <pre>
- *     $PAGE->requires->js_init_call('M.mod_forum.init_view');
- *     $PAGE->requires->css('/mod/mymod/userstyles.php?id='.$id); // not overridable via themes!
- *     $PAGE->requires->js('/mod/mymod/script.js');
- *     $PAGE->requires->js('/mod/mymod/small_but_urgent.js', true);
- *     $PAGE->requires->js_function_call('init_mymod', array($data), true);
- * </pre>
- *
- * There are some natural restrictions on some methods. For example, {@link css()}
- * can only be called before the <head> tag is output. See the comments on the
- * individual methods for details.
+ * This requirements manager captures the appropriate html for creating a fragment to
+ * be inserted elsewhere.
  *
  * @copyright 2016 Adrian Greeve <adrian@moodle.com>
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -60,57 +38,18 @@ defined('MOODLE_INTERNAL') || die();
 class fragment_requirements_manager extends page_requirements_manager {
 
     /**
-     * Append YUI3 module to default YUI3 JS loader.
-     * The structure of module array is described at {@link http://developer.yahoo.com/yui/3/yui/}
-     *
-     * @param string|array $module name of module (details are autodetected), or full module specification as array
-     * @return void
+     * Page fragment constructor.
      */
-    public function js_module($module) {
-        global $CFG;
-
-        if (empty($module)) {
-            throw new coding_exception('Missing YUI3 module name or full description.');
-        }
-
-        if (is_string($module)) {
-            $module = $this->find_module($module);
-        }
-
-        if (empty($module) or empty($module['name']) or empty($module['fullpath'])) {
-            throw new coding_exception('Missing YUI3 module details.');
-        }
-
-        $module['fullpath'] = $this->js_fix_url($module['fullpath'])->out(false);
-        // Add all needed strings.
-        if (!empty($module['strings'])) {
-            foreach ($module['strings'] as $string) {
-                $identifier = $string[0];
-                $component = isset($string[1]) ? $string[1] : 'moodle';
-                $a = isset($string[2]) ? $string[2] : null;
-                $this->string_for_js($identifier, $component, $a);
-            }
-        }
-        unset($module['strings']);
-
-        // Process module requirements and attempt to load each. This allows
-        // moodle modules to require each other.
-        if (!empty($module['requires'])) {
-            foreach ($module['requires'] as $requirement) {
-                $rmodule = $this->find_module($requirement);
-                if (is_array($rmodule)) {
-                    $this->js_module($rmodule);
-                }
-            }
-        }
-
-        $this->extramodules[$module['name']] = $module;
+    public function __construct() {
+        parent::__construct();
+        // As this is a fragment the header should already be done.
+        $this->headdone = true;
     }
 
-
     /**
      * Returns js code to load amd module loader, then insert inline script tags
      * that contain require() calls using RequireJS.
+     *
      * @return string
      */
     protected function get_amd_footercode() {
@@ -128,9 +67,6 @@ class fragment_requirements_manager extends page_requirements_manager {
     /**
      * Generate any HTML that needs to go at the end of the page.
      *
-     * Normally, this method is called automatically by the code that prints the
-     * page footer. You should not normally need to call it in your own code.
-     *
      * @return string the HTML code to to at the end of the page.
      */
     public function get_end_code() {
@@ -144,8 +80,6 @@ class fragment_requirements_manager extends page_requirements_manager {
         // Add other requested modules.
         $output .= $this->get_extra_modules_code();
 
-        $this->js_init_code('M.util.js_complete("init");', true);
-
         // All the other linked scripts - there should be as few as possible.
         if ($this->jsincludes['footer']) {
             foreach ($this->jsincludes['footer'] as $url) {
@@ -153,17 +87,19 @@ class fragment_requirements_manager extends page_requirements_manager {
             }
         }
 
-        // Add all needed strings.
-        $strings = array();
-        foreach ($this->stringsforjs as $component => $v) {
-            foreach ($v as $indentifier => $langstring) {
-                $strings[$component][$indentifier] = $langstring->out();
+        if (!empty($this->stringsforjs)) {
+            // Add all needed strings.
+            $strings = array();
+            foreach ($this->stringsforjs as $component => $v) {
+                foreach ($v as $indentifier => $langstring) {
+                    $strings[$component][$indentifier] = $langstring->out();
+                }
             }
+            // Append don't overwrite.
+            $output .= html_writer::script('require(["jquery"], function($) {
+                M.str = $.extend(true, M.str, ' . json_encode($strings) . ');
+            });');
         }
-        // Append don't overwrite.
-        $output .= html_writer::script('require(["jquery"], function($) {
-    M.str = $.extend(true, M.str, ' . json_encode($strings) . ');
-});');
 
         // Add variables.
         if ($this->jsinitvariables['footer']) {
@@ -186,8 +122,6 @@ class fragment_requirements_manager extends page_requirements_manager {
 
         $output .= html_writer::script($js);
 
-        // return 'bottom stuff';
         return $output;
-
     }
 }
index e438f71..64e0299 100644 (file)
@@ -33,7 +33,6 @@ require_once($CFG->libdir.'/outputactions.php');
 require_once($CFG->libdir.'/outputfactories.php');
 require_once($CFG->libdir.'/outputrenderers.php');
 require_once($CFG->libdir.'/outputrequirementslib.php');
-require_once($CFG->libdir.'/outputfragmentrequirementslib.php');
 
 /**
  * Invalidate all server and client side caches.
index 3fcf08e..811234f 100644 (file)
@@ -825,10 +825,26 @@ class moodle_page {
     }
 
     /**
-     * Changes the requirements manager over to receive fragments.
+     * Switches from the regular requirements manager to the fragment requirements manager to
+     * capture all necessary JavaScript to display a chunk of HTML such as an mform. This is for use
+     * by the get_fragment() web service and not for use elsewhere.
      */
-    public function set_requirements_for_fragments() {
-        $this->_requires = new fragment_requirements_manager();
+    public function start_collecting_javascript_requirements() {
+        global $CFG;
+        require_once($CFG->libdir.'/outputfragmentrequirementslib.php');
+
+        // Check that the requirements manager has not already been switched.
+        if (get_class($this->_requires) == 'fragment_requirements_manager') {
+            throw new coding_exception('JavaScript collection has already been started.');
+        }
+        // The header needs to have been called to flush out the generic JavaScript for the page. This allows only
+        // JavaScript for the fragment to be collected. _wherethemewasinitialised is set when header() is called.
+        if (!empty($this->_wherethemewasinitialised)) {
+            // Change the current requirements manager over to the fragment manager to capture JS.
+            $this->_requires = new fragment_requirements_manager();
+        } else {
+            throw new coding_exception('$OUTPUT->header() needs to be called before collecting JavaScript requirements.');
+        }
     }
 
     /**
index c60895d..cfaa55e 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2016012900.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2016012900.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.