Browse Source

Adding App.fullbaseURL as a recognized Configure value

Jose Lorenzo Rodriguez 12 years ago
parent
commit
4bc92b822e

+ 9 - 0
app/Config/core.php

@@ -109,6 +109,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.
  *
  * The value of the define determines the names of the routes

+ 3 - 1
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;

+ 9 - 0
lib/Cake/Console/Templates/skel/Config/core.php

@@ -100,6 +100,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.
  *
  * The value of the define determines the names of the routes

+ 3 - 2
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);

+ 2 - 5
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));

+ 38 - 5
lib/Cake/Routing/Router.php

@@ -57,6 +57,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, '/');
@@ -895,6 +903,31 @@ class Router {
 	}
 
 /**
+ * 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.
  *

+ 3 - 1
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);
 

+ 7 - 7
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',
 					),

+ 14 - 4
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,10 +58,6 @@ 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)));
@@ -68,6 +65,19 @@ class RouterTest extends CakeTestCase {
 	}
 
 /**
+ * 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
  *
  * @return void

+ 1 - 1
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?'));

+ 2 - 2
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);

+ 1 - 1
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;
 	}

+ 10 - 8
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);