Thomas Bruederli
2014-08-13 06fdaf88cb1a355e445294beba4a89d0209ac71e
Extend rcmail::url() to produce absolute and fully qualified URLs
1 files added
2 files modified
131 ■■■■■ changed files
program/include/rcmail.php 45 ●●●● patch | view | raw | blame | history
tests/RcmailFunc.php 85 ●●●●● patch | view | raw | blame | history
tests/phpunit.xml 1 ●●●● patch | view | raw | blame | history
program/include/rcmail.php
@@ -789,11 +789,13 @@
    /**
     * Build a valid URL to this instance of Roundcube
     *
     * @param mixed Either a string with the action or url parameters as key-value pairs
     * @param mixed   Either a string with the action or url parameters as key-value pairs
     * @param boolean Build an URL absolute to document root
     * @param boolean Create fully qualified URL including http(s):// and hostname
     *
     * @return string Valid application URL
     */
    public function url($p)
    public function url($p, $absolute = false, $full = false)
    {
        if (!is_array($p)) {
            if (strpos($p, 'http') === 0) {
@@ -803,14 +805,15 @@
            $p = array('_action' => @func_get_arg(0));
        }
        $task = $p['_task'] ? $p['_task'] : ($p['task'] ? $p['task'] : $this->task);
        $p['_task'] = $task;
        unset($p['task']);
        $pre = array();
        $task = $p['_task'] ?: ($p['task'] ?: $this->task);
        $pre['_task'] = $task;
        unset($p['task'], $p['_task']);
        $url  = './' . $this->filename;
        $url  = $this->filename;
        $delm = '?';
        foreach (array_reverse($p) as $key => $val) {
        foreach (array_merge($pre, $p) as $key => $val) {
            if ($val !== '' && $val !== null) {
                $par  = $key[0] == '_' ? $key : '_'.$key;
                $url .= $delm.urlencode($par).'='.urlencode($val);
@@ -818,7 +821,33 @@
            }
        }
        return $url;
        if ($absolute || $full) {
            $prefix = '';
            // prepend protocol://hostname:port
            if ($full) {
                $schema = 'http';
                $default_port = 80;
                if (rcube_utils::https_check()) {
                    $schema = 'https';
                    $default_port = 443;
                }
                $prefix = $schema . '://' . preg_replace('/:\d+$/', '', $_SERVER['HTTP_HOST']);
                if ($_SERVER['SERVER_PORT'] != $default_port) {
                  $prefix .= ':' . $_SERVER['SERVER_PORT'];
                }
            }
            // add base path to this Roundcube installation
            $base_path = preg_replace('![^/]+$!', '', strval($_SERVER['SCRIPT_NAME']));
            if ($base_path == '') $base_path = '/';
            $prefix .= $base_path;
        }
        else {
            $prefix = './';
        }
        return $prefix . $url;
    }
    /**
tests/RcmailFunc.php
New file
@@ -0,0 +1,85 @@
<?php
/**
 * Test class to test rcmail class
 *
 * @package Tests
 */
class RcmailFunc extends PHPUnit_Framework_TestCase
{
    function setUp()
    {
        // set some HTTP env vars
        $_SERVER['HTTP_HOST'] = 'mail.example.org';
        $_SERVER['SERVER_PORT'] = '443';
        $_SERVER['SCRIPT_NAME'] = '/sub/index.php';
        $_SERVER['HTTPS'] = true;
        rcmail::get_instance()->filename = '';
    }
    /**
     * Class constructor
     */
    function test_class()
    {
        $object = rcmail::get_instance();
        $this->assertInstanceOf('rcmail', $object, "Class singleton");
    }
    /**
     * Test rcmail::url()
     */
    function test_url()
    {
        $rcmail = rcmail::get_instance();
        $this->assertEquals(
            './?_task=cli&_action=test',
            $rcmail->url('test'),
            "Action only"
        );
        $this->assertEquals(
            './?_task=cli&_action=test&_a=AA',
            $rcmail->url(array('action' => 'test', 'a' => 'AA')),
            "Unprefixed parameters"
        );
        $this->assertEquals(
            './?_task=cli&_action=test&_b=BB',
            $rcmail->url(array('_action' => 'test', '_b' => 'BB', '_c' => null)),
            "Prefixed parameters (skip empty)"
        );
        $this->assertEquals(
            '/sub/?_task=cli&_action=test&_mode=ABS',
            $rcmail->url(array('_action' => 'test', '_mode' => 'ABS'), true),
            "Absolute URL"
        );
        $this->assertEquals(
            'https://mail.example.org/sub/?_task=calendar&_action=test&_mode=FQ',
            $rcmail->url(array('task' => 'calendar', '_action' => 'test', '_mode' => 'FQ'), true, true),
            "Fully Qualified URL"
        );
        // with different SCRIPT_NAME values
        $_SERVER['SCRIPT_NAME'] = 'index.php';
        $this->assertEquals(
            '/?_task=cli&_action=test&_mode=ABS',
            $rcmail->url(array('_action' => 'test', '_mode' => 'ABS'), true),
            "Absolute URL (root)"
        );
        $_SERVER['SCRIPT_NAME'] = '';
        $this->assertEquals(
            '/?_task=cli&_action=test&_mode=ABS',
            $rcmail->url(array('_action' => 'test', '_mode' => 'ABS'), true),
            "Absolute URL (root)"
        );
        $_SERVER['HTTPS'] = false;
        $_SERVER['SERVER_PORT'] = '8080';
        $this->assertEquals(
            'http://mail.example.org:8080/?_task=cli&_action=test&_mode=ABS',
            $rcmail->url(array('_action' => 'test', '_mode' => 'ABS'), true, true),
            "Full URL with port"
        );
    }
}
tests/phpunit.xml
@@ -46,6 +46,7 @@
            <file>Framework/VCard.php</file>
            <file>Framework/Washtml.php</file>
            <file>MailFunc.php</file>
            <file>RcmailFunc.php</file>
        </testsuite>
        <testsuite name="Plugins Tests">
            <file>./../plugins/acl/tests/Acl.php</file>