From 4bc92b822eb0659622242d47b0736a23d2e9e3a8 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Thu, 30 May 2013 16:07:26 +0200 Subject: [PATCH] Adding App.fullbaseURL as a recognized Configure value --- app/Config/core.php | 9 ++++ lib/Cake/Console/ShellDispatcher.php | 4 +- .../Console/Templates/skel/Config/core.php | 9 ++++ lib/Cake/Core/Object.php | 5 ++- lib/Cake/Network/CakeRequest.php | 7 +-- lib/Cake/Routing/Router.php | 43 ++++++++++++++++--- lib/Cake/Test/Case/Core/ObjectTest.php | 4 +- .../Test/Case/Network/CakeRequestTest.php | 14 +++--- lib/Cake/Test/Case/Routing/RouterTest.php | 18 ++++++-- .../Test/Case/View/Helper/HtmlHelperTest.php | 2 +- lib/Cake/Test/Case/View/HelperTest.php | 4 +- lib/Cake/View/Helper.php | 2 +- lib/Cake/bootstrap.php | 18 ++++---- 13 files changed, 102 insertions(+), 37 deletions(-) diff --git a/app/Config/core.php b/app/Config/core.php index e85f1d224..baf608fac 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -108,6 +108,15 @@ */ //Configure::write('App.baseUrl', env('SCRIPT_NAME')); +/** + * To configure CakePHP to use a particular domain URL + * for any URL generation inside the application, set the following + * configuration variable to the http(s) address to your domain. This + * will override the automatic detection of full base URL and can be + * useful when generating links from the CLI (e.g. sending emails) + */ + //Configure::write('App.fullBaseURL', 'http://example.com'); + /** * Uncomment the define below to use CakePHP prefix routes. * diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php index 9f4073611..95a5a8fae 100644 --- a/lib/Cake/Console/ShellDispatcher.php +++ b/lib/Cake/Console/ShellDispatcher.php @@ -137,7 +137,9 @@ class ShellDispatcher { $this->setErrorHandlers(); if (!defined('FULL_BASE_URL')) { - define('FULL_BASE_URL', 'http://localhost'); + $url = Configure::read('App.fullBaseURL'); + define('FULL_BASE_URL', $url ? $url : 'http://localhost'); + Configure::write('App.fullBaseURL', FULL_BASE_URL); } return true; diff --git a/lib/Cake/Console/Templates/skel/Config/core.php b/lib/Cake/Console/Templates/skel/Config/core.php index 7ceeeea2c..bda4331dc 100644 --- a/lib/Cake/Console/Templates/skel/Config/core.php +++ b/lib/Cake/Console/Templates/skel/Config/core.php @@ -99,6 +99,15 @@ */ //Configure::write('App.baseUrl', env('SCRIPT_NAME')); +/** + * To configure CakePHP to use a particular domain URL + * for any URL generation inside the application, set the following + * configuration variable to the http(s) address to your domain. This + * will override the automatic detection of full base URL and can be + * useful when generating links from the CLI (e.g. sending emails) + */ + //Configure::write('App.fullBaseURL', 'http://example.com'); + /** * Uncomment the define below to use CakePHP prefix routes. * diff --git a/lib/Cake/Core/Object.php b/lib/Cake/Core/Object.php index c0ad29adf..533046084 100644 --- a/lib/Cake/Core/Object.php +++ b/lib/Cake/Core/Object.php @@ -16,6 +16,7 @@ App::uses('CakeLog', 'Log'); App::uses('Dispatcher', 'Routing'); +App::uses('Router', 'Routing'); App::uses('Set', 'Utility'); App::uses('CakeLog', 'Log'); @@ -87,8 +88,8 @@ class Object { $data = isset($extra['data']) ? $extra['data'] : null; unset($extra['data']); - if (is_string($url) && strpos($url, FULL_BASE_URL) === 0) { - $url = Router::normalize(str_replace(FULL_BASE_URL, '', $url)); + if (is_string($url) && strpos($url, Router::baseURL()) === 0) { + $url = Router::normalize(str_replace(Router::baseURL(), '', $url)); } if (is_string($url)) { $request = new CakeRequest($url); diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 3cbcc69fe..3a0b3e1fc 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -237,7 +237,7 @@ class CakeRequest implements ArrayAccess { if ($qPosition !== false && strpos($_SERVER['REQUEST_URI'], '://') > $qPosition) { $uri = $_SERVER['REQUEST_URI']; } else { - $uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL)); + $uri = substr($_SERVER['REQUEST_URI'], strlen(Configure::read('App.fullBaseURL'))); } } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) { $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']); @@ -405,10 +405,7 @@ class CakeRequest implements ArrayAccess { $ref = $forwarded; } - $base = ''; - if (defined('FULL_BASE_URL')) { - $base = FULL_BASE_URL . $this->webroot; - } + $base = Configure::read('App.fullBaseURL') . $this->webroot; if (!empty($ref) && !empty($base)) { if ($local && strpos($ref, $base) === 0) { $ref = substr($ref, strlen($base)); diff --git a/lib/Cake/Routing/Router.php b/lib/Cake/Routing/Router.php index 1266430fd..615ac3186 100644 --- a/lib/Cake/Routing/Router.php +++ b/lib/Cake/Routing/Router.php @@ -56,6 +56,14 @@ class Router { */ public static $initialized = false; +/** + * Contains the base string that will be applied to all generated URLs + * For example `https://example.com` + * + * @var string + */ + protected static $_baseURL; + /** * List of action prefixes used in connected routes. * Includes admin prefix @@ -759,7 +767,7 @@ class Router { * cake relative URLs are required when using requestAction. * - `?` - Takes an array of query string parameters * - `#` - Allows you to set URL hash fragments. - * - `full_base` - If true the `FULL_BASE_URL` constant will be prepended to generated URLs. + * - `full_base` - If true the `Router::baseURL()` value will be prepended to generated URLs. * * @param string|array $url Cake-relative URL, like "/products/edit/92" or "/presidents/elect/4" * or an array specifying any of the following: 'controller', 'action', @@ -796,8 +804,8 @@ class Router { if (empty($url)) { $output = isset($path['here']) ? $path['here'] : '/'; - if ($full && defined('FULL_BASE_URL')) { - $output = FULL_BASE_URL . $output; + if ($full) { + $output = self::baseURL() . $output; } return $output; } elseif (is_array($url)) { @@ -884,8 +892,8 @@ class Router { if ($protocol === 0) { $output = str_replace('//', '/', $base . '/' . $output); - if ($full && defined('FULL_BASE_URL')) { - $output = FULL_BASE_URL . $output; + if ($full) { + $output = self::baseURL() . $output; } if (!empty($extension)) { $output = rtrim($output, '/'); @@ -894,6 +902,31 @@ class Router { return $output . $extension . self::queryString($q, array(), $escape) . $frag; } +/** + * Sets the full base url that will be used as a prefix for generating + * fully qualified URLs for this application. If not parameters are passed, + * the currently configured value is returned + * + * ## Note: + * + * If you change during runtime the configuration value ``App.fullBaseURL`` + * and expect the router to produce links using the new setting, you are + * required to call this method passing such value again. + * + * @param string $base the prefix for URLs generated containing the domain. + * For example: ``http://example.com`` + * @return string + */ + public static function baseURL($base = null) { + if ($base !== null) { + self::$_baseURL = $base; + } + if (empty(self::$_baseURL)) { + self::$_baseURL = Configure::read('App.fullBaseURL'); + } + return self::$_baseURL; + } + /** * A special fallback method that handles URL arrays that cannot match * any defined routes. diff --git a/lib/Cake/Test/Case/Core/ObjectTest.php b/lib/Cake/Test/Case/Core/ObjectTest.php index 5c5e32d10..e2bf2ad2d 100644 --- a/lib/Cake/Test/Case/Core/ObjectTest.php +++ b/lib/Cake/Test/Case/Core/ObjectTest.php @@ -467,7 +467,9 @@ class ObjectTest extends CakeTestCase { $expected = 'This is a test'; $this->assertEquals($expected, $result); - $result = $this->object->requestAction(FULL_BASE_URL . '/request_action/test_request_action'); + $result = $this->object->requestAction( + Configure::read('App.fullBaseURL') . '/request_action/test_request_action' + ); $expected = 'This is a test'; $this->assertEquals($expected, $result); diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index 6d99f7484..2ba7f8358 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -142,7 +142,7 @@ class CakeRequestTest extends CakeTestCase { $request = new CakeRequest(); $this->assertEquals('some/path', $request->url); - $_SERVER['REQUEST_URI'] = FULL_BASE_URL . '/other/path?url=http://cakephp.org'; + $_SERVER['REQUEST_URI'] = Configure::read('App.fullBaseURL') . '/other/path?url=http://cakephp.org'; $request = new CakeRequest(); $this->assertEquals('other/path', $request->url); } @@ -674,19 +674,19 @@ class CakeRequestTest extends CakeTestCase { $result = $request->referer(); $this->assertSame($result, '/'); - $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/some/path'; + $_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseURL') . '/some/path'; $result = $request->referer(true); $this->assertSame($result, '/some/path'); - $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/some/path'; + $_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseURL') . '/some/path'; $result = $request->referer(false); - $this->assertSame($result, FULL_BASE_URL . '/some/path'); + $this->assertSame($result, Configure::read('App.fullBaseURL') . '/some/path'); - $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/some/path'; + $_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseURL') . '/some/path'; $result = $request->referer(true); $this->assertSame($result, '/some/path'); - $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/recipes/add'; + $_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseURL') . '/recipes/add'; $result = $request->referer(true); $this->assertSame($result, '/recipes/add'); @@ -1712,7 +1712,7 @@ class CakeRequestTest extends CakeTestCase { 'SERVER_NAME' => 'localhost', 'DOCUMENT_ROOT' => '/Library/WebServer/Documents', 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php', - 'REQUEST_URI' => FULL_BASE_URL . '/site/posts/index', + 'REQUEST_URI' => '/site/posts/index', 'SCRIPT_NAME' => '/site/app/webroot/index.php', 'PHP_SELF' => '/site/app/webroot/index.php', ), diff --git a/lib/Cake/Test/Case/Routing/RouterTest.php b/lib/Cake/Test/Case/Routing/RouterTest.php index aff6e9f60..4076e27ad 100644 --- a/lib/Cake/Test/Case/Routing/RouterTest.php +++ b/lib/Cake/Test/Case/Routing/RouterTest.php @@ -49,6 +49,7 @@ class RouterTest extends CakeTestCase { public function tearDown() { parent::tearDown(); CakePlugin::unload(); + Router::baseURL(''); } /** @@ -57,16 +58,25 @@ class RouterTest extends CakeTestCase { * @return void */ public function testFullBaseURL() { - $skip = PHP_SAPI === 'cli'; - if ($skip) { - $this->markTestSkipped('Cannot validate base URLs in CLI'); - } $this->assertRegExp('/^http(s)?:\/\//', Router::url('/', true)); $this->assertRegExp('/^http(s)?:\/\//', Router::url(null, true)); $this->assertRegExp('/^http(s)?:\/\//', Router::url(array('full_base' => true))); $this->assertSame(FULL_BASE_URL . '/', Router::url(array('full_base' => true))); } +/** + * Tests that the base URL can be changed at runtime + * + * @return void + */ + public function testBaseURL() { + $this->assertEquals(FULL_BASE_URL, Router::baseUrl()); + Router::baseURL('http://example.com'); + $this->assertEquals('http://example.com/', Router::url('/', true)); + Router::baseURL('https://example.com'); + $this->assertEquals('https://example.com/', Router::url('/', true)); + } + /** * testRouteDefaultParams method * diff --git a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php index 748bc3380..bfbb52d6e 100644 --- a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php @@ -210,7 +210,7 @@ class HtmlHelperTest extends CakeTestCase { Router::reload(); $result = $this->Html->link('Posts', array('controller' => 'posts', 'action' => 'index', 'full_base' => true)); - $expected = array('a' => array('href' => FULL_BASE_URL . '/posts'), 'Posts', '/a'); + $expected = array('a' => array('href' => Router::baseURL() . '/posts'), 'Posts', '/a'); $this->assertTags($result, $expected); $result = $this->Html->link('Home', '/home', array('confirm' => 'Are you sure you want to do this?')); diff --git a/lib/Cake/Test/Case/View/HelperTest.php b/lib/Cake/Test/Case/View/HelperTest.php index 74794bd6c..7348561af 100644 --- a/lib/Cake/Test/Case/View/HelperTest.php +++ b/lib/Cake/Test/Case/View/HelperTest.php @@ -644,13 +644,13 @@ class HelperTest extends CakeTestCase { ), array('fullBase' => true) ); - $this->assertEquals(FULL_BASE_URL . '/js/post.js', $result); + $this->assertEquals(Router::baseURL() . '/js/post.js', $result); $result = $this->Helper->assetUrl('foo.jpg', array('pathPrefix' => 'img/')); $this->assertEquals('img/foo.jpg', $result); $result = $this->Helper->assetUrl('foo.jpg', array('fullBase' => true)); - $this->assertEquals(FULL_BASE_URL . '/foo.jpg', $result); + $this->assertEquals(Router::baseURL() . '/foo.jpg', $result); $result = $this->Helper->assetUrl('style', array('ext' => '.css')); $this->assertEquals('style.css', $result); diff --git a/lib/Cake/View/Helper.php b/lib/Cake/View/Helper.php index 95cbd1dd6..952810784 100644 --- a/lib/Cake/View/Helper.php +++ b/lib/Cake/View/Helper.php @@ -328,7 +328,7 @@ class Helper extends Object { $path = $this->_encodeUrl($this->assetTimestamp($this->webroot($path))); if (!empty($options['fullBase'])) { - $path = rtrim(FULL_BASE_URL, '/') . '/' . ltrim($path, '/'); + $path = rtrim(Router::baseURL(), '/') . '/' . ltrim($path, '/'); } return $path; } diff --git a/lib/Cake/bootstrap.php b/lib/Cake/bootstrap.php index 228145b34..3e3cb876d 100644 --- a/lib/Cake/bootstrap.php +++ b/lib/Cake/bootstrap.php @@ -140,6 +140,15 @@ require CAKE . 'basics.php'; require CAKE . 'Core' . DS . 'App.php'; require CAKE . 'Error' . DS . 'exceptions.php'; +spl_autoload_register(array('App', 'load')); + +App::uses('ErrorHandler', 'Error'); +App::uses('Configure', 'Core'); +App::uses('CakePlugin', 'Core'); +App::uses('Cache', 'Cache'); +App::uses('Object', 'Core'); +App::uses('Multibyte', 'I18n'); + /** * Full URL prefix */ @@ -153,18 +162,11 @@ if (!defined('FULL_BASE_URL')) { if (isset($httpHost)) { define('FULL_BASE_URL', 'http' . $s . '://' . $httpHost); + Configure::write('App.fullBaseURL', FULL_BASE_URL); } unset($httpHost, $s); } -spl_autoload_register(array('App', 'load')); - -App::uses('ErrorHandler', 'Error'); -App::uses('Configure', 'Core'); -App::uses('CakePlugin', 'Core'); -App::uses('Cache', 'Cache'); -App::uses('Object', 'Core'); -App::uses('Multibyte', 'I18n'); App::$bootstrapping = true; Configure::bootstrap(isset($boot) ? $boot : true);