MDL 38508 JavaScript: Split out AJAX and non-AJAX help
authorAndrew Robert Nicols <andrew.nicols@luns.net.uk>
Sat, 16 Mar 2013 01:29:05 +0000 (01:29 +0000)
committerAndrew Nicols <andrew@nicols.co.uk>
Mon, 8 Apr 2013 20:01:20 +0000 (21:01 +0100)
We need to keep these two separate as scripts which define AJAX_SCRIPT
before loading config.php will use a different default renderer and will
return appropriate exceptions which can be parsed by M.core.exception and
M.core.ajaxException correctly.

This also addresses an issue whereby a missing heading could break the
tooltip.

help.php
help_ajax.php [new file with mode: 0644]
lib/weblib.php
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-coverage.js
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-debug.js
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-min.js
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip.js
lib/yui/src/tooltip/js/tooltip.js

index 4323461..5b5a65f 100644 (file)
--- a/help.php
+++ b/help.php
@@ -32,73 +32,22 @@ require_once(dirname(__FILE__) . '/config.php');
 
 $identifier = required_param('identifier', PARAM_STRINGID);
 $component  = required_param('component', PARAM_COMPONENT);
-$lang       = required_param('lang', PARAM_LANG); // TODO: maybe split into separate scripts
-$ajax       = optional_param('ajax', 0, PARAM_BOOL);
+$lang       = optional_param('lang', 'en', PARAM_LANG);
 
-if (!$lang) {
-    $lang = 'en';
-}
-$SESSION->lang = $lang; // does not actually modify session because we do not use cookies here
-
-$sm = get_string_manager();
+// We don't actually modify the session here as we have NO_MOODLE_COOKIES set.
+$SESSION->lang = $lang;
 
 $PAGE->set_url('/help.php');
 $PAGE->set_pagelayout('popup');
 $PAGE->set_context(context_system::instance());
 
-if ($ajax) {
-    @header('Content-Type: text/plain; charset=utf-8');
-}
-
-if (!$sm->string_exists($identifier.'_help', $component)) {
-    // strings on disk-cache may be dirty - try to rebuild it and check again
-    $sm->load_component_strings($component, current_language(), true);
-}
-
-$data = new stdClass();
-
-if ($sm->string_exists($identifier.'_help', $component)) {
-    $options = new stdClass();
-    $options->trusted = false;
-    $options->noclean = false;
-    $options->smiley = false;
-    $options->filter = false;
-    $options->para = true;
-    $options->newlines = false;
-    $options->overflowdiv = !$ajax;
-
-    $data->heading = format_string(get_string($identifier, $component));
-    // Should be simple wiki only MDL-21695
-    $data->text =  format_text(get_string($identifier.'_help', $component), FORMAT_MARKDOWN, $options);
-
-    $helplink = $identifier . '_link';
-    if ($sm->string_exists($helplink, $component)) {  // Link to further info in Moodle docs
-        $link = get_string($helplink, $component);
-        $linktext = get_string('morehelp');
-
-        $data->doclink = new stdClass();
-        $url = new moodle_url(get_docs_url($link));
-        $data->doclink->link = $url->out();
-        $data->doclink->linktext = $linktext;
-        $data->doclink->class = ($CFG->doctonewwindow) ? 'helplinkpopup' : '';
-
-        $completedoclink = html_writer::tag('div', $OUTPUT->doc_link($link, $linktext), array('class' => 'helpdoclink'));
-    }
-} else {
-    $data->text = html_writer::tag('p',
-            html_writer::tag('strong', 'TODO') . ": missing help string [{$identifier}_help, {$component}]");
+$data = get_formatted_help_string($identifier, $component, false);
+echo $OUTPUT->header();
+if (!empty($data->heading)) {
+    echo $OUTPUT->heading($data->heading, 1, 'helpheading');
 }
-
-if ($ajax) {
-    echo json_encode($data);
-} else {
-    echo $OUTPUT->header();
-    if (isset($data->heading)) {
-        echo $OUTPUT->heading($data->heading, 1, 'helpheading');
-    }
-    echo $data->text;
-    if (isset($completedoclink)) {
-        echo $completedoclink;
-    }
-    echo $OUTPUT->footer();
+echo $data->text;
+if (isset($data->completedoclink)) {
+    echo $data->completedoclink;
 }
+echo $OUTPUT->footer();
diff --git a/help_ajax.php b/help_ajax.php
new file mode 100644 (file)
index 0000000..1fb4dbb
--- /dev/null
@@ -0,0 +1,40 @@
+<?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/>.
+
+/**
+ * Displays help via AJAX call
+ *
+ * @copyright 2013 onwards Andrew Nicols
+ * @package   core
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define('NO_MOODLE_COOKIES', true);
+define('AJAX_SCRIPT', true);
+require_once(__DIR__ . '/config.php');
+
+$identifier = required_param('identifier', PARAM_STRINGID);
+$component  = required_param('component', PARAM_COMPONENT);
+$lang       = optional_param('lang', 'en', PARAM_LANG);
+
+// We don't actually modify the session here as we have NO_MOODLE_COOKIES set.
+$SESSION->lang = $lang;
+$PAGE->set_url('/help_ajax.php');
+$PAGE->set_context(context_system::instance());
+
+$data = get_formatted_help_string($identifier, $component, true);
+echo json_encode($data);
index 4ee520b..767d78f 100644 (file)
@@ -3463,3 +3463,72 @@ function print_password_policy() {
     }
     return $message;
 }
+
+/**
+ * Get the value of a help string fully prepared for display in the current language.
+ *
+ * @param string $identifier The identifier of the string to search for.
+ * @param string $component The module the string is associated with.
+ * @param boolean $ajax Whether this help is called from an AJAX script.
+ *                This is used to influence text formatting and determines
+ *                which format to output the doclink in.
+ * @return Object An object containing:
+ * - heading: Any heading that there may be for this help string.
+ * - text: The wiki-formatted help string.
+ * - doclink: An object containing a link, the linktext, and any additional
+ *            CSS classes to apply to that link. Only present if $ajax = false.
+ * - completedoclink: A text representation of the doclink. Only present if $ajax = true.
+ */
+function get_formatted_help_string($identifier, $component, $ajax = false) {
+    global $CFG, $OUTPUT;
+    $sm = get_string_manager();
+
+    if (!$sm->string_exists($identifier, $component) ||
+        !$sm->string_exists($identifier . '_help', $component)) {
+        // Strings in the on-disk cache may be dirty - try to rebuild it and check again.
+        $sm->load_component_strings($component, current_language(), true);
+    }
+
+    $data = new stdClass();
+
+    if ($sm->string_exists($identifier, $component)) {
+        $data->heading = format_string(get_string($identifier, $component));
+    } else {
+        // Gracefully fall back to an empty string.
+        $data->heading = '';
+    }
+
+    if ($sm->string_exists($identifier . '_help', $component)) {
+        $options = new stdClass();
+        $options->trusted = false;
+        $options->noclean = false;
+        $options->smiley = false;
+        $options->filter = false;
+        $options->para = true;
+        $options->newlines = false;
+        $options->overflowdiv = !$ajax;
+
+        // Should be simple wiki only MDL-21695.
+        $data->text =  format_text(get_string($identifier.'_help', $component), FORMAT_MARKDOWN, $options);
+
+        $helplink = $identifier . '_link';
+        if ($sm->string_exists($helplink, $component)) {  // Link to further info in Moodle docs
+            $link = get_string($helplink, $component);
+            $linktext = get_string('morehelp');
+
+            $data->doclink = new stdClass();
+            $url = new moodle_url(get_docs_url($link));
+            if ($ajax) {
+                $data->doclink->link = $url->out();
+                $data->doclink->linktext = $linktext;
+                $data->doclink->class = ($CFG->doctonewwindow) ? 'helplinkpopup' : '';
+            } else {
+                $data->completedoclink = html_writer::tag('div', $OUTPUT->doc_link($link, $linktext), array('class' => 'helpdoclink'));
+            }
+        }
+    } else {
+        $data->text = html_writer::tag('p',
+                html_writer::tag('strong', 'TODO') . ": missing help string [{$identifier}_help, {$component}]");
+    }
+    return $data;
+}
index 74363b6..ca80fa6 100644 (file)
Binary files a/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-coverage.js and b/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-coverage.js differ
index d23e238..c6a8de7 100644 (file)
Binary files a/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-debug.js and b/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-debug.js differ
index e2a616c..5ee26df 100644 (file)
Binary files a/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-min.js and b/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-min.js differ
index d23e238..c6a8de7 100644 (file)
Binary files a/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip.js and b/lib/yui/build/moodle-core-tooltip/moodle-core-tooltip.js differ
index 10e9121..fb8c891 100644 (file)
@@ -188,6 +188,19 @@ ATTRS.footerhandler = {
     value: null
 };
 
+/**
+ * The function which handles modifying the URL that was clicked on.
+ *
+ * The default function rewrites '.php' to '_ajax.php'.
+ *
+ * @attribute urlmodifier
+ * @type Function|String|null
+ * @default null
+ */
+ATTRS.urlmodifier = {
+    value: null
+};
+
 /**
  * Set the Y.Cache object to use.
  *
@@ -245,6 +258,9 @@ Y.extend(TOOLTIP, M.core.dialogue, {
         if (!this.get('footerhandler')) {
             this.set('footerhandler', function() {});
         }
+        if (!this.get('urlmodifier')) {
+            this.set('urlmodifier', this.modify_url);
+        }
 
         // Set up the dialogue with initial content.
         this.setAttrs({
@@ -288,7 +304,7 @@ Y.extend(TOOLTIP, M.core.dialogue, {
     /**
      * Display the tooltip for the clicked link.
      *
-     * The anchor for the clicked link is used, additionally appending ajax=1 to the parameters.
+     * The anchor for the clicked link is used.
      *
      * @method display_panel
      * @param {EventFacade} e The event from the clicked link. This is used to determine the clicked URL.
@@ -330,7 +346,8 @@ Y.extend(TOOLTIP, M.core.dialogue, {
         thisevent = this.bb.on('mousedownoutside', this.close_panel, this);
         this.listenevents.push(thisevent);
 
-        ajaxurl = clickedlink.get('href');
+        // Modify the URL as required.
+        ajaxurl = Y.bind(this.get('urlmodifier'), this, clickedlink.get('href'))();
 
         cacheentry = this.get('textcache').retrieve(ajaxurl);
         if (cacheentry) {
@@ -342,10 +359,6 @@ Y.extend(TOOLTIP, M.core.dialogue, {
                 method: 'get',
                 context: this,
                 sync: false,
-                data: {
-                    // We use a slightly different AJAX URL to the one on the anchor to allow non-JS fallback.
-                    ajax: 1
-                },
                 on: {
                     complete: function(tid, response) {
                         this._set_panel_contents(response.responseText, ajaxurl);
@@ -353,7 +366,7 @@ Y.extend(TOOLTIP, M.core.dialogue, {
                 }
             };
 
-            Y.io(clickedlink.get('href'), config);
+            Y.io(ajaxurl, config);
         }
     },
 
@@ -369,10 +382,7 @@ Y.extend(TOOLTIP, M.core.dialogue, {
             }
         } catch (error) {
             this.close_panel();
-            return new M.core.exception({
-                name: error.name,
-                message: "Unable to retrieve the requested content. The following error was returned: " + error.message
-            });
+            return new M.core.exception(error);
         }
 
         // Set the contents using various handlers.
@@ -401,6 +411,10 @@ Y.extend(TOOLTIP, M.core.dialogue, {
         this.set('bodyContent', bodycontent);
     },
 
+    modify_url: function(url) {
+        return url.replace(/\.php\?/, '_ajax.php?');
+    },
+
     close_panel: function(e) {
         // Hide the panel first.
         this.hide();