From 06fdaf88cb1a355e445294beba4a89d0209ac71e Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Wed, 13 Aug 2014 19:15:12 +0200 Subject: Extend rcmail::url() to produce absolute and fully qualified URLs --- program/include/rcmail.php | 45 +++++++++++++++++++----- tests/RcmailFunc.php | 85 ++++++++++++++++++++++++++++++++++++++++++++++ tests/phpunit.xml | 1 + 3 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 tests/RcmailFunc.php 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 @@ +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 @@ Framework/VCard.php Framework/Washtml.php MailFunc.php + RcmailFunc.php ./../plugins/acl/tests/Acl.php -- cgit v1.2.3