Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implementing host mapping in `\core\Environment::is()`.

  • Loading branch information...
commit 7b422f41fc51d1765cd381073da06dca770bc37a 1 parent c46bd6f
@nateabele nateabele authored
View
46 core/Environment.php
@@ -135,20 +135,42 @@ public static function reset() {
* `'development'` is, in fact, the current environment.
*
* This method also handles how the environment is detected at the beginning of the request.
+ *
+ * #### Custom Detection
+ *
* While the default detection rules are very simple (if the `'SERVER_ADDR'` variable is set to
* `127.0.0.1`, the environment is assumed to be `'development'`, or if the string `'test'` is
* found anywhere in the host name, it is assumed to be `'test'`, and in all other cases it
* is assumed to be `'production'`), you can define your own detection rule set easily using a
* closure that accepts an instance of the `Request` object, and returns the name of the correct
* environment, as in the following example:
- * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testCustomDetector(1-9)}}}
+ * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testCustomDetector(1-9) }}}
*
* In the above example, the user-specified closure takes in a `Request` object, and using the
* server data which it encapsulates, returns the correct environment name as a string.
*
+ * #### Host Mapping
+ *
+ * The most common use case is to set the environment depending on host name. For convenience,
+ * the `is()` method also accepts an array that matches host names to environment names, where
+ * each key is an environment, and each value is either an array of valid host names, or a
+ * regular expression used to match a valid host name.
+ *
+ * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testDetectionWithArrayMap(1-5) }}}
+ *
+ * In this example, a regular expression is being used to match local domains
+ * (i.e. `localhost`), as well as the built-in `.console` domain, for console requests. Note
+ * that in the console, the environment can always be overridden by specifying the `--env`
+ * option.
+ *
+ * Then, one or more host names are matched up to `'test'` and `'staging'`, respectively. Note
+ * that no rule is present for production: this is because `'production'` is the default value
+ * if no other environment matches.
+ *
* @param mixed $detect Either the name of an environment to check against the current, i.e.
* `'development'` or `'production'`, or a closure which `Environment` will use
- * to determine the current environment name.
+ * to determine the current environment name, or an array mapping environment names
+ * to host names.
* @return boolean If `$detect` is a string, returns `true` if the current environment matches
* the value of `$detect`, or `false` if no match. If used to set a custom detector,
* returns `null`.
@@ -157,7 +179,25 @@ public static function is($detect) {
if (is_callable($detect)) {
static::$_detector = $detect;
}
- return (static::$_current == $detect);
+ if (!is_array($detect)) {
+ return (static::$_current == $detect);
+ }
+ static::$_detector = function($request) use ($detect) {
+ if ($request->env || $request->command == 'test') {
+ return ($request->env) ? $request->env : 'test';
+ }
+ $host = method_exists($request, 'get') ? $request->get('http:host') : '.console';
+
+ foreach ($detect as $environment => $hosts) {
+ if (is_string($hosts) && preg_match($hosts, $host)) {
+ return $environment;
+ }
+ if (is_array($hosts) && in_array($host, $hosts)) {
+ return $environment;
+ }
+ }
+ return "production";
+ };
}
/**
View
53 tests/cases/core/EnvironmentTest.php
@@ -20,8 +20,6 @@ public function setUp() {
/**
* Tests setting and getting current environment, and that invalid environments cannot be
* selected.
- *
- * @return void
*/
public function testSetAndGetCurrentEnvironment() {
Environment::set('production', array('foo' => 'bar'));
@@ -45,8 +43,6 @@ public function testSetAndGetCurrentEnvironment() {
/**
* Tests creating a custom environment, and verifies that settings are properly retrieved.
- *
- * @return void
*/
public function testCreateNonStandardEnvironment() {
Environment::set('custom', array('host' => 'server.local'));
@@ -63,8 +59,6 @@ public function testCreateNonStandardEnvironment() {
/**
* Tests modifying environment configuration.
- *
- * @return void
*/
public function testModifyEnvironmentConfig() {
Environment::set('test', array('foo' => 'bar'));
@@ -79,8 +73,6 @@ public function testModifyEnvironmentConfig() {
/**
* Tests auto-detecting environment settings through a series of mock request classes.
- *
- * @return void
*/
public function testEnvironmentDetection() {
Environment::set(new MockRequest(array('SERVER_ADDR' => '::1')));
@@ -121,9 +113,36 @@ public function testEnvironmentDetection() {
}
/**
+ * Tests that environment names can be mapped to lists of host names, or a hostname-matching
+ * regular expression.
+ */
+ public function testDetectionWithArrayMap() {
+ Environment::is(array(
+ 'development' => '/^local|^\.console/',
+ 'test' => array('test1.myapp.com', 'test2.myapp.com'),
+ 'staging' => array('staging.myapp.com')
+ ));
+
+ Environment::set(new MockRequest(array('http:host' => 'localhost')));
+ $this->assertTrue(Environment::is('development'));
+
+ Environment::set(new MockRequest(array('http:host' => 'test1.myapp.com')));
+ $this->assertTrue(Environment::is('test'));
+
+ Environment::set(new MockRequest(array('http:host' => 'test3.myapp.com')));
+ $this->assertTrue(Environment::is('production'));
+
+ Environment::set(new MockRequest(array('http:host' => 'localhost:3030')));
+ $this->assertTrue(Environment::is('development'));
+
+ $request = new MockRequest();
+ $request->params = array('env' => 'whatever');
+ Environment::set($request);
+ $this->assertTrue(Environment::is('whatever'));
+ }
+
+ /**
* Tests resetting the `Environment` class to its default state.
- *
- * @return void
*/
public function testReset() {
Environment::set('test', array('foo' => 'bar'));
@@ -138,8 +157,6 @@ public function testReset() {
/**
* Tests using a custom detector to get the current environment.
- *
- * @return void
*/
public function testCustomDetector() {
Environment::is(function($request) {
@@ -171,14 +188,8 @@ public function testCustomDetector() {
public function testDotPath() {
$data = array(
- 'foo' => array(
- 'bar' => array(
- 'baz' => 123
- )
- ),
- 'some' => array(
- 'path' => true
- )
+ 'foo' => array('bar' => array('baz' => 123)),
+ 'some' => array('path' => true)
);
Environment::set('dotPathIndex', $data);
@@ -190,8 +201,6 @@ public function testDotPath() {
/**
* Tests calling `get()` and `set()` with `true` as the envrionment name, to automatically
* select the current environment.
- *
- * @return void
*/
public function testReadWriteWithDefaultEnvironment() {
Environment::set('development');
View
4 tests/mocks/core/MockRequest.php
@@ -29,6 +29,10 @@ public function env($key) {
}
return null;
}
+
+ public function get($key) {
+ return $this->env($key);
+ }
}
?>
Please sign in to comment.
Something went wrong with that request. Please try again.