]> git.mjollnir.org Git - moodle.git/commitdiff
moodle_page: MDL-12212 ->url and cleanup init of $FULLME, etc.
authortjhunt <tjhunt>
Wed, 6 May 2009 08:50:32 +0000 (08:50 +0000)
committertjhunt <tjhunt>
Wed, 6 May 2009 08:50:32 +0000 (08:50 +0000)
lib/pagelib.php
lib/setuplib.php
lib/simpletest/testpagelib_moodlepage.php
lib/weblib.php

index 45377264d64eda830922796bb18a9eef80fd8b5f..95af986993117233c911b29c2170ab6ef6fc54b4 100644 (file)
@@ -75,6 +75,8 @@ class moodle_page {
 
     protected $_legacyclass = null;
 
+    protected $_url = null;
+
 /// Getter methods =============================================================
 /// Due to the __get magic below, you normally do not call these as $PAGE->get_x
 /// methods, but instead use the $PAGE->x syntax.
@@ -173,6 +175,18 @@ class moodle_page {
         }
     }
 
+    /**
+     * @return moodle_url the clean URL required to load the current page. (You
+     * should normally use this in preference to $ME or $FULLME.)
+     */
+    public function get_url() {
+        if (is_null($this->_url)) {
+            debugging('This page did no call $PAGE->set_url(...). Realying on a guess.', DEBUG_DEVELOPER);
+            return new moodle_url($ME);
+        }
+        return $this->_url;
+    }
+
     /**
      * PHP overloading magic to make the $PAGE->course syntax work.
      */
@@ -319,6 +333,24 @@ class moodle_page {
         $this->_docspath = $path;
     }
 
+    /**
+     * You should call this method from every page to set the cleaned-up URL
+     * that should be used to return to this page. Used, for example, by the
+     * blocks editing UI to know where to return the user after an action.
+     * For example, course/view.php does:
+     *      $id = optional_param('id', 0, PARAM_INT);
+     *      $PAGE->set_url('course/view.php', array('id' => $id));
+     * @param string $url a URL, relative to $CFG->wwwroot.
+     * @param array $params paramters to add ot the URL.
+     */
+    public function set_url($url, $params = array()) {
+        global $CFG;
+        $this->_url = new moodle_url($CFG->wwwroot . '/' . $url, $params);
+        if (is_null($this->_pagetype)) {
+            $this->initialise_default_pagetype($url);
+        }
+    }
+
 /// Initialisation methods =====================================================
 /// These set various things up in a default way.
 
index 3aa0a2021456baf9fb0075a72769489622089645..3e24758a978b7c23f44eda3fc7084b54d1ccdea0 100644 (file)
@@ -103,45 +103,107 @@ function setup_validate_php_configuration() {
 }
 
 /**
- * Initialises $FULLME and friends.
- * @return void
+ * Initialises $FULLME and friends. Private function. Should only be called from
+ * setup.php.
  */
 function initialise_fullme() {
     global $CFG, $FULLME, $ME, $SCRIPT, $FULLSCRIPT;
 
+    // Detect common config error.
     if (substr($CFG->wwwroot, -1) == '/') {
         print_error('wwwrootslash', 'error');
     }
 
-    $url = parse_url($CFG->wwwroot);
-    if (!isset($url['path'])) {
-        $url['path'] = '';
+    if (CLI_SCRIPT) {
+        initialise_fullme_cli();
+        return;
     }
-    $url['path'] .= '/';
 
-    if (CLI_SCRIPT) {
-        // urls do not make much sense in CLI scripts
-        $backtrace = debug_backtrace();
-        $topfile = array_pop($backtrace);
-        $topfile = realpath($topfile['file']);
-        $dirroot = realpath($CFG->dirroot);
-
-        if (strpos($topfile, $dirroot) !== 0) {
-            $SCRIPT = $FULLSCRIPT = $FULLME = $ME = null;
-        } else {
-            $relme = substr($topfile, strlen($dirroot));
-            $relme = str_replace('\\', '/', $relme); // Win fix
-            $SCRIPT = $FULLSCRIPT = $FULLME = $ME = $relme;
-        }
+    $wwwroot = parse_url($CFG->wwwroot);
+    if (!isset($wwwroot['path'])) {
+        $wwwroot['path'] = '';
+    }
+    $wwwroot['path'] .= '/';
+
+    $rurl = setup_get_remote_url();
 
+    // Check that URL is under $CFG->wwwroot.
+    if (strpos($rurl['path'], $wwwroot['path']) === 0) {
+        $SCRIPT = substr($rurl['path'], strlen($wwwroot['path'])-1);
+    } else {
+        // Probably some weird external script
+        $SCRIPT = $FULLSCRIPT = $FULLME = $ME = null;
         return;
     }
 
+    // $CFG->sslproxy specifies if external SSL appliance is used
+    // (That is, the Moodle server uses http, with an external box translating everything to https).
+    if (empty($CFG->sslproxy)) {
+        if ($rurl['scheme'] == 'http' and $wwwroot['scheme'] == 'https') {
+            print_error('sslonlyaccess', 'error');
+        }
+    }
+
+    // $CFG->reverseproxy specifies if reverse proxy server used.
+    // Used in load balancing scenarios.
+    // Do not abuse this to try to solve lan/wan access problems!!!!!
+    if (empty($CFG->reverseproxy)) {
+        if (($rurl['host'] != $wwwroot['host']) or
+                (!empty($wwwroot['port']) and $rurl['port'] != $wwwroot['port'])) {
+            print_error('wwwrootmismatch', 'error', '', $CFG->wwwroot);
+        }
+    }
+
+    // hopefully this will stop all those "clever" admins trying to set up moodle
+    // with two different addresses in intranet and Internet
+    if (!empty($CFG->reverseproxy) && $rurl['host'] == $wwwroot['host']) {
+        print_error('reverseproxyabused', 'error');
+    }
+
+    $hostandport = $rurl['scheme'] . '://' . $wwwroot['host'];
+    if (!empty($wwwroot['port'])) {
+        $hostandport .= ':'.$wwwroot['port'];
+    }
+
+    $FULLSCRIPT = $hostandport . $rurl['path'];
+    $FULLME = $hostandport . $rurl['fullpath'];
+    $ME = $rurl['fullpath'];
+    $rurl['path'] = $rurl['fullpath'];
+}
+
+/**
+ * Initialises $FULLME and friends for command line scripts.
+ * This is a private method for use by initialise_fullme.
+ */
+function initialise_fullme_cli() {
+    // Urls do not make much sense in CLI scripts
+    $backtrace = debug_backtrace();
+    $topfile = array_pop($backtrace);
+    $topfile = realpath($topfile['file']);
+    $dirroot = realpath($CFG->dirroot);
+
+    if (strpos($topfile, $dirroot) !== 0) {
+        // Probably some weird external script
+        $SCRIPT = $FULLSCRIPT = $FULLME = $ME = null;
+    } else {
+        $relativefile = substr($topfile, strlen($dirroot));
+        $relativefile = str_replace('\\', '/', $relativefile); // Win fix
+        $SCRIPT = $FULLSCRIPT = $relativefile;
+        $FULLME = $ME = null;
+    }
+}
+
+/**
+ * Get the URL that PHP/the web server thinks it is serving. Private function
+ * used by initialise_fullme. In your code, use $PAGE->url, $SCRIPT, etc.
+ * @return array in the same format that parse_url returns, with the addition of
+ *      a 'fullpath' element, which includes any slasharguments path.
+ */
+function setup_get_remote_url() {
     $rurl = array();
-    $hostport = explode(':', $_SERVER['HTTP_HOST']);
-    $rurl['host'] = reset($hostport);
+    list($rurl['host']) = explode(':', $_SERVER['HTTP_HOST']);
     $rurl['port'] = $_SERVER['SERVER_PORT'];
-    $rurl['path'] = $_SERVER['SCRIPT_NAME']; // script path without slash arguments
+    $rurl['path'] = $_SERVER['SCRIPT_NAME']; // Script path without slash arguments
 
     if (stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false) {
         //Apache server
@@ -168,45 +230,9 @@ function initialise_fullme() {
         $_SERVER['REQUEST_URI'] = $rurl['fullpath']; // extra IIS compatibility
 
     } else {
-        print_error('unsupportedwebserver', 'error', '', $_SERVER['SERVER_SOFTWARE']);
+        throw new moodle_exception('unsupportedwebserver', 'error', '', $_SERVER['SERVER_SOFTWARE']);
     }
-
-    if (strpos($rurl['path'], $url['path']) === 0) {
-        $SCRIPT = substr($rurl['path'], strlen($url['path'])-1);
-    } else {
-        // probably some weird external script
-        $SCRIPT = $FULLSCRIPT = $FULLME = $ME = null;
-        return;
-    }
-
-    // $CFG->sslproxy specifies if external SSL apliance is used (server using http, ext box translating everything to https)
-    if (empty($CFG->sslproxy)) {
-        if ($rurl['scheme'] == 'http' and $url['scheme'] == 'https') {
-            print_error('sslonlyaccess', 'error');
-        }
-    }
-
-    // $CFG->reverseproxy specifies if reverse proxy server used - used in advanced load balancing setups only!
-    // this is not supposed to solve lan/wan access problems!!!!!
-    if (empty($CFG->reverseproxy)) {
-        if (($rurl['host'] != $url['host']) or (!empty($url['port']) and $rurl['port'] != $url['port'])) {
-            print_error('wwwrootmismatch', 'error', '', $CFG->wwwroot);
-        }
-    } else {
-        if ($rurl['host'] == $url['host']) {
-            // hopefully this will stop all those "clever" admins trying to set up moodle with two different addresses in intranet and Internet
-            print_error('reverseproxyabused', 'error');
-        }
-    }
-
-    $FULLME     = $rurl['scheme'].'://'.$url['host'];
-    if (!empty($url['port'])) {
-        $FULLME .= ':'.$url['port'];
-    }
-    $FULLSCRIPT = $FULLME.$rurl['path'];
-    $FULLME     = $FULLME.$rurl['fullpath'];
-    $ME         = $rurl['fullpath'];
-
+    return $rurl;
 }
 
 /**
index 43313e288e02519d4dec8dc3dadc09ceeef99c45..2f4d1f85d33ef9901b974048a292c5fae3c9a43d 100644 (file)
@@ -271,6 +271,46 @@ class moodle_page_test extends UnitTestCase {
         // Validate
         $this->assertEqual('a/page/type', $this->testpage->docspath);
     }
+
+    public function test_set_url_root() {
+        global $CFG;
+        // Exercise SUT
+        $this->testpage->set_url('');
+        // Validate
+        $this->assertEqual($CFG->wwwroot . '/', $this->testpage->url->out());
+    }
+
+    public function test_set_url_one_param() {
+        global $CFG;
+        // Exercise SUT
+        $this->testpage->set_url('mod/quiz/attempt.php', array('attempt' => 123));
+        // Validate
+        $this->assertEqual($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123', $this->testpage->url->out());
+    }
+
+    public function test_set_url_two_params() {
+        global $CFG;
+        // Exercise SUT
+        $this->testpage->set_url('mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
+        // Validate
+        $this->assertEqual($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123&amp;page=7', $this->testpage->url->out());
+    }
+
+    public function test_set_url_sets_page_type() {
+        // Exercise SUT
+        $this->testpage->set_url('mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
+        // Validate
+        $this->assertEqual('mod-quiz-attempt', $this->testpage->pagetype);
+    }
+
+    public function test_set_url_does_not_change_explicit_page_type() {
+        // Setup fixture
+        $this->testpage->set_pagetype('a-page-type');
+        // Exercise SUT
+        $this->testpage->set_url('mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
+        // Validate
+        $this->assertEqual('a-page-type', $this->testpage->pagetype);
+    }
 }
 
 /**
index 6050e07940d875bc7d2bab3861f867e37c10bf95..571bc2d3510eeb2f63ee49273a58aedd09460045 100644 (file)
@@ -241,21 +241,38 @@ class moodle_url {
     /**
      * Pass no arguments to create a url that refers to this page. Use empty string to create empty url.
      *
-     * @param string $url url default null means use this page url with no query string
-     *      empty string means empty url. If you pass any other type of url it will
-     *      be parsed into it's bits, including query string
+     * @param mixed $url a number of different forms are accespted:
+     *      null - create a URL that is the same as the URL used to load this page, but with no query string
+     *      '' - and empty URL
+     *      string - a URL, will be parsed into it's bits, including query string
+     *      array - as returned from the PHP function parse_url
+     *      moodle_url - make a copy of another moodle_url
      * @param array $params these params override anything in the query string
      *      where params have the same name.
      */
     public function __construct($url = null, $params = array()) {
-        global $ME;
-        if ($url !== '') {
+        if ($url === '') {
+            // Leave URL blank.
+        } else if (is_a($url, 'moodle_url')) {
+            $this->scheme = $url->scheme;
+            $this->host = $url->host;
+            $this->port = $url->port;
+            $this->user = $url->user;
+            $this->pass = $url->pass;
+            $this->path = $url->pass;
+            $this->fragment = $url->fragment;
+            $this->params = $url->params;
+        } else {
             if ($url === null) {
+                global $ME;
                 $url = $ME;
             }
-            $parts = parse_url($url);
+            if (is_string($url)) {
+                $url = parse_url($url);
+            }
+            $parts = $url;
             if ($parts === FALSE) {
-                print_error('invalidurl');
+                throw new moodle_exception('invalidurl');
             }
             if (isset($parts['query'])) {
                 parse_str(str_replace('&amp;', '&', $parts['query']), $this->params);
@@ -264,8 +281,8 @@ class moodle_url {
             foreach ($parts as $key => $value) {
                 $this->$key = $value;
             }
-            $this->params($params);
         }
+        $this->params($params);
     }
 
     /**
@@ -284,21 +301,25 @@ class moodle_url {
     }
 
     /**
-     * Remove all params if no arguments passed. Or else remove param $arg1, $arg2, etc.
+     * Remove all params if no arguments passed. Remove selected params if
+     * arguments are passed. Can be called as either remove_params('param1', 'param2')
+     * or remove_params(array('param1', 'param2')).
      *
-     * @param string $arg1
-     * @param string $arg2
-     * @param string $arg3
+     * @param mixed $params either an array of param names, or a string param name,
+     * @param string $params,... any number of additional param names.
      */
-    public function remove_params() {
-        if ($thisargs = func_get_args()) {
-            foreach ($thisargs as $arg) {
-                if (isset($this->params[$arg])) {
-                    unset($this->params[$arg]);
-                }
-            }
-        } else { // no args
+    public function remove_params($params) {
+        if (empty($params)) {
             $this->params = array();
+            return;
+        }
+        if (!is_array($params)) {
+            $params = func_get_args();
+        }
+        foreach ($params as $param) {
+            if (isset($this->params[$param])) {
+                unset($this->params[$param]);
+            }
         }
     }