summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <thomas@roundcube.net>2014-08-13 19:15:12 +0200
committerThomas Bruederli <thomas@roundcube.net>2014-08-13 19:15:12 +0200
commit06fdaf88cb1a355e445294beba4a89d0209ac71e (patch)
tree53ce0a305a69773169b00bbeae92069d20d3403c
parent48e340a82938a83ff337eadb7d6d64c2b13acffe (diff)
Extend rcmail::url() to produce absolute and fully qualified URLs
-rw-r--r--program/include/rcmail.php45
-rw-r--r--tests/RcmailFunc.php85
-rw-r--r--tests/phpunit.xml1
3 files changed, 123 insertions, 8 deletions
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index ceb369af8..bb2346f5e 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -789,11 +789,13 @@ class rcmail extends rcube
/**
* 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 @@ class rcmail extends rcube
$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 @@ class rcmail extends rcube
}
}
- 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;
}
/**
diff --git a/tests/RcmailFunc.php b/tests/RcmailFunc.php
new file mode 100644
index 000000000..09b54b22c
--- /dev/null
+++ b/tests/RcmailFunc.php
@@ -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"
+ );
+ }
+}
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index 4d50ad6a0..5c27d0e0d 100644
--- a/tests/phpunit.xml
+++ b/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>