You can then add to an existing configuration by calling the set() method again with the
same environment name:
embed:lithium\tests\cases\core\EnvironmentTest::testModifyEnvironmentConfig(6-6)
The settings for the environment will then be the aggregate of all set() calls:
embed:lithium\tests\cases\core\EnvironmentTest::testModifyEnvironmentConfig(7-7)
By passing an array to $env, you can assign the same configuration to multiple
environments:
embed:lithium\tests\cases\core\EnvironmentTest::testSetMultipleEnvironments(5-7)
The set() method can also be called to manually set which environment to operate in:
embed:lithium\tests\cases\core\EnvironmentTest::testSetAndGetCurrentEnvironment(5-5)
Finally, set() can accept a Request object, to automatically detect the correct
environment.
embed:lithium\tests\cases\core\EnvironmentTest::testEnvironmentDetection(9-10)
For more information on defining custom rules to automatically detect your application's
environment, see the documentation for Environment::is().
public static set ( mixed $env, array $config = null ) : array | ||
$env | mixed | The name(s) of the environment(s) you wish to create, update or switch to (string/array), or a `Request` object or `$_SERVER` / `$_ENV` array used to detect (and switch to) the application's current environment. |
$config | array | If creating or updating a configuration, accepts an array of settings. If the environment name specified in `$env` already exists, the values in `$config` will be recursively merged with any pre-existing settings. |
return | array | If creating or updating a configuration, returns an array of the environment's settings. If updating an existing configuration, this will be the newly-applied configuration merged with the pre-existing values. If setting the environment itself (i.e. `$config` is unspecified), returns `null`. |
public function testEnvironmentalDefaults() { $artist = Artists::create(['ja.name' => 'Richard Japper', 'ja.profile' => 'Dreaded Rasta Nihon', 'en.name' => 'Richard', 'en.profile' => 'Dreaded Rasta', 'something_else' => 'Something']); Environment::set('test', ['locales' => ['en' => 'English', 'es' => 'Espanol']]); $artist->_actsAs = ['Translatable' => ['default' => 'ja', 'fields' => ['name', 'profile']]]; $this->assertTrue($artist->save()); $artist = Artists::first(); }
public static function set($key, $productionValue, $testValue = null, $developmentValue = null) { $testValue = $testValue ?: $productionValue; $developmentValue = $developmentValue ?: $testValue; Environment::set('development', array($key => $developmentValue)); Environment::set('test', array($key => $testValue)); Environment::set('production', array($key => $productionValue)); }
protected function _init() { parent::_init(); Environment::set($this->env); if (file_exists($this->_config['routes'])) { return require $this->_config['routes']; } $this->error("The routes file for this library doesn't exist or can't be found."); }
/** * Runs a test group or a specific test file based on the passed * parameters. * * @param string $group If set, this test group is run. If not set, a group test may * also be run by passing the 'group' option to the $options parameter. * @param array $options Options array for the test run. Valid options are: * - 'case': The fully namespaced test case to be run. * - 'group': The fully namespaced test group to be run. * - 'filters': An array of filters that the test output should be run through. * @return array A compact array of the title, an array of the results, as well * as an additional array of the results after the $options['filters'] * have been applied. * @filter */ public static function run($group = null, array $options = array()) { $defaults = array('title' => $group, 'filters' => array(), 'reporter' => 'text'); $options += $defaults; $isCase = is_string($group) && preg_match('/Test$/', $group); $items = $isCase ? array(new $group()) : (array) $group; $options['filters'] = Set::normalize($options['filters']); $group = static::_group($items); $report = static::_report($group, $options); return static::_filter(__FUNCTION__, compact('report'), function ($self, $params, $chain) { $environment = Environment::get(); Environment::set('test'); $params['report']->run(); Environment::set($environment); return $params['report']; }); }
/** * Dispatches a request based on a request object (an instance of `lithium\console\Request`). * If `$request` is `null`, a new request object is instantiated based on the value of the * `'request'` key in the `$_classes` array. * * @param object $request An instance of a request object with console request information. If * `null`, an instance will be created. * @param array $options * @return object The command action result which is an instance of `lithium\console\Response`. * @filter */ public static function run($request = null, $options = array()) { $defaults = array('request' => array()); $options += $defaults; $classes = static::$_classes; $params = compact('request', 'options'); return static::_filter(__FUNCTION__, $params, function ($self, $params) use($classes) { $request = $params['request']; $options = $params['options']; $router = $classes['router']; $request = $request ?: new $classes['request']($options['request']); $request->params = $router::parse($request); $params = $self::applyRules($request->params); Environment::set($request); try { $callable = $self::invokeMethod('_callable', array($request, $params, $options)); return $self::invokeMethod('_call', array($callable, $request, $params)); } catch (UnexpectedValueException $e) { return (object) array('status' => $e->getMessage() . "\n"); } }); }
/** * The routes file is where you define your URL structure, which is an important part of the * [information architecture](http://en.wikipedia.org/wiki/Information_architecture) of your * application. Here, you can use _routes_ to match up URL pattern strings to a set of parameters, * usually including a controller and action to dispatch matching requests to. For more information, * see the `Router` and `Route` classes. * * @see lithium\net\http\Router * @see lithium\net\http\Route */ use lithium\net\http\Router; use lithium\core\Environment; use lithium\action\Dispatcher; // Set the evironment if ($_SERVER['HTTP_HOST'] == 'li3bootstrap.dev.local' || $_SERVER['HTTP_HOST'] == 'li3bootstrap.local' || $_SERVER['HTTP_HOST'] == 'localhost') { Environment::set('development'); } /** * Dispatcher rules to rewrite admin actions. */ Dispatcher::config(array('rules' => array('admin' => array('action' => 'admin_{:action}')))); /** * "/admin" is the prefix for all Lithium Bootstrap admin routes. * Any "plugin" or library written for use with Lithium Bootstrap can utilize these routes * without needing to write any additional routes in most cases as this handles the basic CRUD. * It also handles pagination. * * Admin pages can be added to the main app's "/views/_libraries/li3b_core/pages" directory * and are accessible viw /admin/page/{:args} * * NOTE: li3b_core has no controller other than the pages controller. Other libraries and the
/** * Create environment prefix location using `lihtium\net\http\Media::location` * Check if `lihtium\net\http\Media::asset` return the correct URL * for the test environement */ public function testEnvironmentAsset2() { Media::attach('appcdn', array('production' => array('absolute' => true, 'path' => null, 'scheme' => 'http://', 'host' => 'my.cdnapp.com', 'prefix' => 'assets'), 'test' => array('absolute' => true, 'path' => null, 'scheme' => 'http://', 'host' => 'my.cdntest.com', 'prefix' => 'assets'))); $env = Environment::get(); Environment::set('test'); $result = Media::asset('style', 'css', array('scope' => 'appcdn')); $expected = 'http://my.cdntest.com/assets/css/style.css'; $this->assertEqual($expected, $result); Environment::is($env); }
use lithium\action\Dispatcher; /** * This filter intercepts the `run()` method of the `Dispatcher`, and first passes the `'request'` * parameter (an instance of the `Request` object) to the `Environment` class to detect which * environment the application is running in. Then, loads all application routes in all plugins, * loading the default application routes last. * * Change this code if plugin routes must be loaded in a specific order (i.e. not the same order as * the plugins are added in your bootstrap configuration), or if application routes must be loaded * first (in which case the default catch-all routes should be removed). * * If `Dispatcher::run()` is called multiple times in the course of a single request, change the * `include`s to `include_once`. * * @see lithium\action\Request * @see lithium\core\Environment * @see lithium\net\http\Router */ Dispatcher::applyFilter('run', function ($self, $params, $chain) { Environment::set($params['request']); foreach (array_reverse(Libraries::get()) as $name => $config) { if ($name === 'lithium') { continue; } $file = "{$config['path']}/config/routes.php"; file_exists($file) ? call_user_func(function () use($file) { include $file; }) : null; } return $chain->next($self, $params, $chain); });
Environment::set('test', array('locale' => 'en', 'locales' => array('en' => 'English'))); /** * Effective/Request Locale * * Intercepts dispatching processes in order to set the effective locale by using * the locale of the request or if that is not available retrieving a locale preferred * by the client. * * @see lithium\g11n\Message * @see lithium\core\Environment */ $setLocale = function ($self, $params, $chain) { if (!$params['request']->locale()) { $params['request']->locale(Locale::preferred($params['request'])); } Environment::set(true, array('locale' => $params['request']->locale())); return $chain->next($self, $params, $chain); }; ActionDispatcher::applyFilter('_callable', $setLocale); ConsoleDispatcher::applyFilter('_callable', $setLocale); /** * Resources * * Globalization (g11n) catalog configuration. The catalog allows for obtaining and * writing globalized data. Each configuration can be adjusted through the following settings: * * - `'adapter'` _string_: The name of a supported adapter. The builtin adapters are `Memory` (a * simple adapter good for runtime data and testing), `Php`, `Gettext`, `Cldr` (for * interfacing with Unicode's common locale data repository) and `Code` (used mainly for * extracting message templates from source code). *
/** * Call class method * * @param string $callable * @param string $request * @param string $params * @return void * @filter */ protected static function _call($callable, $request, $params) { $params = compact('callable', 'request', 'params'); Environment::set($request); return static::_filter(__FUNCTION__, $params, function($self, $params) { if (is_callable($callable = $params['callable'])) { $request = $params['request']; $params = $params['params']; if (!method_exists($callable, $params['action'])) { array_unshift($params['args'], $request->params['action']); $params['action'] = 'run'; } $isHelp = ( !empty($params['help']) || !empty($params['h']) || !method_exists($callable, $params['action']) ); if ($isHelp) { $params['action'] = '_help'; } return $callable($params['action'], $params['args']); } throw new UnexpectedValueException("Callable `{$callable}` is actually not callable."); }); }
public function tearDown() { Catalog::reset(); Catalog::config($this->_backup['catalogConfig']); Environment::set('test', $this->_backup['environment']); }
}); /** * Integration with `Validator`. You can load locale dependent rules into the `Validator` * by specifying them manually or retrieving them with the `Catalog` class. */ foreach (array('phone', 'postalCode', 'ssn') as $name) { Validator::add($name, Catalog::read(true, "validation.{$name}", 'en_US')); } /** * Intercepts dispatching processes in order to set the effective locale by using * the locale of the request or if that is not available retrieving a locale preferred * by the client. */ ActionDispatcher::applyFilter('_callable', function ($self, $params, $chain) { $request = $params['request']; $controller = $chain->next($self, $params, $chain); if (!$request->locale) { $request->params['locale'] = Locale::preferred($request); } Environment::set(Environment::get(), array('locale' => $request->locale)); return $controller; }); ConsoleDispatcher::applyFilter('_callable', function ($self, $params, $chain) { $request = $params['request']; $command = $chain->next($self, $params, $chain); if (!$request->locale) { $request->params['locale'] = Locale::preferred($request); } Environment::set(Environment::get(), array('locale' => $request->locale)); return $command; });
/** * Executes a given task with the given set of arguments. * Called by li3_gearman deamon * * @param string $task Fully qualified task name * @param array $args Arguments for the call * @param array $env Environment settings to merge on $_SERVER * @param array $workload Full workload * @return mixed Returned value */ public function execute($task, array $args = [], array $env = [], array $workload = []) { if (!is_callable($task)) { throw new RuntimeException("Invalid task {$task}"); } $workload += ['id' => null, 'background' => false]; try { $status = $this->getStatus($workload['id']); } catch (Exception $e) { } if (!empty($status) && $status != static::STATUS_PENDING) { throw new Exception("Job #{$workload['id']} not on pending status. Status: {$status}"); } if (array_key_exists('environment', $env)) { Environment::set($env['environment']); unset($env['environment']); } if (!empty($env)) { $_SERVER = $env + $_SERVER; } $result = null; try { $this->setStatus($workload['id'], static::STATUS_RUNNING); if (isset($this->_config['beforeExecute']) && is_callable($this->_config['beforeExecute'])) { call_user_func_array($this->_config['beforeExecute'], [$task, $args]); } $result = call_user_func_array($task, $args); $this->setStatus($workload['id'], static::STATUS_FINISHED); if (isset($this->_config['afterExecute']) && is_callable($this->_config['afterExecute'])) { call_user_func_array($this->_config['afterExecute'], [$task, $args]); } } catch (Exception $e) { error_log('[' . date('r') . '] ' . $e->getMessage()); $this->setStatus($workload['id'], static::STATUS_ERROR); if (isset($this->_config['afterExecute']) && is_callable($this->_config['afterExecute'])) { call_user_func_array($this->_config['afterExecute'], [$task, $args]); } if (isset($this->_config['onException']) && is_callable($this->_config['onException'])) { call_user_func_array($this->_config['onException'], [$task, $args, $e]); } if (!empty($workload['retries']) && !empty($workload['retries']['maximum']) && $workload['retry'] < $workload['retries']['maximum']) { $this->run($task, $args, ['schedule' => new DateTime('now +' . $workload['retries']['increment'][$workload['retry']], new DateTimeZone('UTC')), 'retry' => $workload['retry'] + 1, 'retries' => $workload['retries']] + array_intersect_key($workload, ['configName' => null, 'env' => null, 'background' => null])); } throw $e; } return $result; }
/** * Generates different variations of the configured $this->model property name * * If no model is configured (i.e. `null`) - it automatically detects the corresponding * model for this Controller via Inflection and `Libraries::locate()`. * * @see lithium\core\Libraries::locate() * @param string $field defines, what variation of the default you want to have * available are 'class', 'model', 'singular', 'plural' and 'table' and 'human'. * if omitted, returns array containing all of them. * @return array|string **/ protected function _scaffold($field = null) { if (is_null($this->model)) { $this->model = (string) Libraries::locate('models', $this->request->controller); } if (is_null($this->scaffold)) { $class = basename(str_replace('\\', '/', $this->model)); $base = !empty($this->library) ? array('controller' => $this->controller, 'library' => $this->library) : array('controller' => $this->controller); $this->scaffold = array('base' => Router::match($base, $this->request), 'controller' => strtolower($this->controller), 'library' => $this->library, 'class' => $class, 'model' => $this->model, 'slug' => Inflector::underscore($class), 'singular' => Inflector::singularize($class), 'plural' => Inflector::pluralize($class), 'table' => Inflector::tableize($class), 'human' => Inflector::humanize($class)); } if (!is_null($field)) { return isset($this->scaffold[$field]) ? $this->scaffold[$field] : false; } Environment::set(true, array('scaffold' => $this->scaffold)); return $this->scaffold; }
protected function _init() { parent::_init(); Environment::set($this->env); }
/** * Setup. * * @param string $config Gearman configuration name */ protected function setup($config = 'default') { $this->setttings = Gearman::config($config); if (!isset($this->setttings)) { throw new ConfigException("{$config} is not a valid li3_gearman configuration"); } elseif (empty($this->setttings['servers'])) { throw new ConfigException("{$config} defines no servers"); } if (!empty($this->memlimit)) { $units = ['K' => 1024, 'M' => 1024 * 1024, 'G' => 1024 * 1024 * 1024]; $memoryLimit = ini_get('memory_limit'); $memoryLimit = (int) substr($memoryLimit, 0, -1) * $units[$memoryLimit[strlen($memoryLimit) - 1]]; $this->settings['memoryLimit'] = (int) floor($memoryLimit * ($this->memlimit / 100)); } if (isset($this->environment)) { Environment::set($this->environment); } else { $this->environment = Environment::get(); if (!$this->environment) { throw new ConfigException("Could not determine environment"); } } foreach ([SIGTERM, SIGHUP] as $signal) { if (!pcntl_signal($signal, [$this, 'signal'])) { throw new RuntimeException("Could not register signal {$signal}"); } } }
* * The environment settings are: * * - `'locale'` The default effective locale. * - `'locales'` Application locales available mapped to names. The available locales are used * to negotiate he effective locale, the names can be used i.e. when displaying * a menu for choosing the locale to users. * * @see lithium\g11n\Message * @see lithium\core\Environment */ $locale = 'en'; $locales = array('en' => 'English'); Environment::set('production', compact('locale', 'locales')); Environment::set('development', compact('locale', 'locales')); Environment::set('test', array('locale' => 'en', 'locales' => array('en' => 'English'))); /** * Effective/Request Locale * * Intercepts dispatching processes in order to set the effective locale by using * the locale of the request or if that is not available retrieving a locale preferred * by the client. * * @see lithium\g11n\Message * @see lithium\core\Environment */ /* $setLocale = function($self, $params, $chain) { if (!$params['request']->locale()) { $params['request']->locale(Locale::preferred($params['request'])); }
/** * 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'); Environment::set(true, array('foo' => 'bar')); $this->assertEqual(array('foo' => 'bar'), Environment::get('development')); $this->assertEqual(Environment::get(true), Environment::get('development')); Environment::set('production'); $this->assertFalse(Environment::get(true)); }
use lithium\core\Environment; use lithium\action\Dispatcher; use app\util\Config; /** * This filter intercepts the `run()` method of the `Dispatcher`, and first passes the `'request'` * parameter (an instance of the `Request` object) to the `Environment` class to detect which * environment the application is running in. Then, loads all application routes in all plugins, * loading the default application routes last. * * Change this code if plugin routes must be loaded in a specific order (i.e. not the same order as * the plugins are added in your bootstrap configuration), or if application routes must be loaded * first (in which case the default catch-all routes should be removed). * * If `Dispatcher::run()` is called multiple times in the course of a single request, change the * `include`s to `include_once`. * * @see lithium\action\Request * @see lithium\core\Environment * @see lithium\net\http\Router */ Dispatcher::applyFilter('run', function ($self, $params, $chain) { Environment::set(Config::get('environment', $params['request'])); foreach (array_reverse(Libraries::get()) as $name => $config) { if ($name === 'lithium') { continue; } $file = "{$config['path']}/config/routes.php"; file_exists($file) ? include $file : null; } return $chain->next($self, $params, $chain); });
/** * Tests using a custom detector to get the current environment. * * @return void */ public function testCustomDetector() { Environment::is(function ($request) { if ($request->env('HTTP_HOST') == 'localhost') { return 'development'; } if ($request->env('HTTP_HOST') == 'staging.server') { return 'test'; } return 'production'; }); $request = new MockRequest(array('HTTP_HOST' => 'localhost')); Environment::set($request); $this->assertTrue(Environment::is('development')); $request = new MockRequest(array('HTTP_HOST' => 'lappy.local')); Environment::set($request); $this->assertTrue(Environment::is('production')); $request = new MockRequest(array('HTTP_HOST' => 'staging.server')); Environment::set($request); $this->assertTrue(Environment::is('test')); $request = new MockRequest(array('HTTP_HOST' => 'test.local')); Environment::set($request); $this->assertTrue(Environment::is('production')); }
<?php use lithium\core\Environment; $config = ['service' => ['tumblr' => ['name' => 'unionofrad-li3', 'url' => 'http://news.li3.me', 'consumerKey' => '', 'consumerSecret' => '', 'token' => '', 'tokenSecret' => ''], 'recaptcha' => ['siteKey' => '', 'secretKey' => '']]]; Environment::set('development', $config); Environment::set('staging', $config); Environment::set('production', $config);