Absolute/Relative URL managment strategy close #363 #416

Closed
wants to merge 8 commits into
from
View
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace lithium\core;
+
+use lithium\core\Environment;
+use lithium\core\Object;
+
+/**
+ * The `Configurable` static class is the base class for class which need to be
+ * configured using `lithium\core\Environment` class
+ *
+ */
+class Configurable extends \lithium\core\Object {
+
+ /**
+ * Can provide configurations based on the environment,
+ * i.e. `'development'`, `'production'` or `'test'`
+ *
+ * @var array of configurations, indexed by name.
+ */
+ public $_configurations = array();
+
+ /**
+ * A closure called by `_config()` which allows to automatically
+ * assign or auto-generate additional configuration data, once a configuration is first
+ * accessed. This allows configuration data to be lazy-loaded from adapters or other data
+ * sources.
+ *
+ * @param string $name The name of the configuration which is being accessed. This is the key
+ * name containing the specific set of configuration passed into `config()`.
+ * @param array $config Contains the configuration assigned to `$name`. If this configuration is
+ * segregated by environment, then this will contain the configuration for the
+ * current environment.
+ * @return array Returns the final array of settings for the given named configuration.
+ */
+ public $initConfig = null;
+
+ /**
+ * Sets configurations for a particular adaptable implementation, or returns the current
+ * configuration settings.
+ *
+ * @param array $config Configurations, indexed by name.
+ * @return object `Collection` of configurations or void if setting configurations.
+ */
+ public function set($name = null, $config = null) {
+ if ($config && is_array($config)) {
+ $this->_configurations[$name] = $config;
+ return;
+ }
+ if($config === false){
+ unset($this->_configurations[$name]);
+ }
+ }
+
+ /**
+ * Gets an array of settings for the given named configuration in the current
+ * environment.
+ *
+ * @see lithium\core\Environment
+ * @param string $name Named configuration.
+ * @return array Settings for the named configuration.
+ */
+ public function get($name = null) {
+ if($name === null) {
+ $result = array();
+ $this->_configurations = array_filter($this->_configurations);
+
+ foreach ($this->_configurations as $key => $value) {
+ $result[$key] = $this->get($key);
+ }
+ return $result;
+ }
+
+ $settings = &$this->_configurations;
+
+ if (!isset($settings[$name])) {
+ return null;
+ }
+
+ if (isset($settings[$name][0])) {
+ return $settings[$name][0];
+ }
+ $env = Environment::get();
+
+ $config = isset($settings[$name][$env]) ? $settings[$name][$env] : $settings[$name];
+
+ $method = is_callable($this->initConfig) ? $this->initConfig : null;
+ $settings[$name][0] = $method ? $method($name, $config) : $config;
+ return $settings[$name][0];
+ }
+
+ /**
+ * Clears all configurations.
+ *
+ * @return void
+ */
+ public function reset() {
+ $this->_configurations = array();
+ }
+}
View
@@ -12,6 +12,7 @@
use lithium\util\String;
use lithium\core\Libraries;
use lithium\net\http\MediaException;
+use lithium\core\Configurable;
/**
* The `Media` class facilitates content-type mapping (mapping between content-types and file
@@ -31,6 +32,23 @@
*/
class Media extends \lithium\core\StaticObject {
+ /**
+ * Contain the configuration of locations.
+ *
+ * @var array of locations
+ */
+ protected static $_locations = null;
+
+ /**
+ * Stores the name of the location in use.
+ * If set to `false`, no location is used.
+ *
+ * @see lithium\net\http\Media::location()
+ * @see lithium\net\http\Media::setLocation()
+ * @var string
+ */
+ protected static $_location = false;
+
/**
* Maps file extensions to content-types. Used to set response types and determine request
* types. Can be modified with `Media::type()`.
@@ -423,11 +441,35 @@ public static function asset($path, $type, array $options = array()) {
'check' => false,
'library' => true
);
- if (!$base = static::_assets($type)) {
+ if (!$paths = static::_assets($type)) {
$type = 'generic';
- $base = static::_assets('generic');
+ $paths = static::_assets('generic');
}
- $options += ($base + $defaults);
+
+ $base = isset($options['base']) ? rtrim($options['base'], '/') : '';
+ $options += array('location' => static::getLocation());
+ $name = $options['location'];
+
+ if($name && $config = static::location($name)){
+ $defaults = array_merge($defaults, $config);
+
+ if(preg_match('/^((?:[a-z0-9-]+:)?\/\/)([^\/]*)/i', $base, $match)){
+ $defaults = array_merge($defaults, array('scheme' => $match[1], 'host' => $match[2]));
+ }
+ $host = '';
+ if($defaults['absolute']){
+ $host = $defaults['scheme'] . $defaults['host'];
+ }
+ if (substr($defaults['base'], 0, 1) != '/'){
+ $options['base'] = $host . $base . ($defaults['base'] ? '/' . $defaults['base'] : '');
+ }
+ else{
+ $options['base'] = $host . rtrim($defaults['base'], '/');
+ }
+ }
+
+ $options += ($paths + $defaults);
+
$params = compact('path', 'type', 'options');
return static::_filter(__FUNCTION__, $params, function($self, $params) {
@@ -484,11 +526,19 @@ public static function asset($path, $type, array $options = array()) {
*
* @param string|boolean $library The name of the library for which to find the path, or `true`
* for the default library.
+ * @param string|boolean $location The name of the to use to find the path.
* @return string Returns the physical path to the web assets directory for a library. For
* example, the `/webroot` directory of the default library would be
* `LITHIUM_APP_PATH . '/webroot'`.
*/
- public static function webroot($library = true) {
+ public static function webroot($library = true, $location = false) {
+ if ($location){
+ if($config = static::location($location)) {
+ return $config['path'];
+ }
+ return null;
+ }
+
if (!$config = Libraries::get($library)) {
return null;
}
@@ -517,20 +567,25 @@ public static function path($path, $type, array $options = array()) {
'base' => null,
'path' => array(),
'suffix' => null,
- 'library' => true
+ 'library' => true,
+ 'location' => false
);
if (!$base = static::_assets($type)) {
$type = 'generic';
$base = static::_assets('generic');
}
$options += ($base + $defaults);
- $config = Libraries::get($options['library']);
- $root = static::webroot($options['library']);
- $paths = $options['path'];
- $config['default'] ? end($paths) : reset($paths);
- $options['library'] = basename($config['path']);
+ $paths = $options['path'];
+ if($options['location']){
+ $root = static::webroot(false, $options['location']);
+ }
+ else{
+ $config = Libraries::get($options['library']);
+ $root = static::webroot($options['library']);
+ $config['default'] ? end($paths) : reset($paths);
+ }
if ($qOffset = strpos($path, '?')) {
$path = substr($path, 0, $qOffset);
}
@@ -542,6 +597,7 @@ public static function path($path, $type, array $options = array()) {
$insert = array('base' => $root) + compact('path');
$file = String::insert($template, $insert);
}
+
return realpath($file);
}
@@ -705,8 +761,11 @@ public static function decode($type, $data, array $options = array()) {
* @return void
*/
public static function reset() {
- foreach (get_class_vars(__CLASS__) as $name => $value) {
- static::${$name} = array();
+ static::$_handlers = array();
+ static::$_types = array();
+ static::$_location = false;
+ if (isset(static::$_locations)) {
+ static::$_locations->reset();
}
}
@@ -871,6 +930,82 @@ protected static function _assets($type = null) {
}
return $assets;
}
+
+ /**
+ * Add path location configurations
+ *
+ * For example:
+ * {{{
+ * Media::location('app', array(
+ * 'path' => '/var/www/website/app/webroot/extradir',
+ * 'base' => '/extradir'
+ * ));
+ * }}}
+ *
+ * {{{
+ * Media::location('cdn', array(
+ * 'path' => null,
+ * 'base' => 'http://my.cdn.com/project1/assets'
+ * ));
+ * }}}
+ *
+ * @param string $name The name by which this assets is referenced.
+ * @param array $params Contains all configuration information to use for reaching assets :
+ * - `'base'`: The base url of the assets.
+ * - `'check'`: Check for the existence of the file before returning. Defaults to
+ * `false`.
+ * - `'filter'`: An array of key/value pairs representing simple string replacements to
+ * be done on a path once it is generated.
+ * - `'path'` _string_: The filesytem root path of the assets if applicable.
+ * `String::insert()` formatting. See `Media::$_assets` for more.
+ * - `suffix`: The suffix to attach to the path, generally a file extension.
+ * - `'timestamp'`: Appends the last modified time of the file to the path if `true`.
+ * Defaults to `false`.
+ * - `'base'` _string_: The base url of the assets
+ * if $params is equals to false, the location is removed
+ * @return array Returns the stored configuration array.
+ */
+ public static function location($name = null, $params = null) {
+ if (!isset(static::$_locations)) {
+ static::$_locations = new Configurable();
+ static::$_locations->initConfig = function($name, $config) {
+ $defaults =array(
+ 'absolute' => false,
+ 'host' => 'localhost',
+ 'scheme' => 'http://',
+ 'base' => '',
+ 'path' => '',
+ 'timestamp' => false,
+ 'filter' => null,
+ 'suffix' => null,
+ 'check' => false
+ );
+ return $config + $defaults;
+ };
+ }
+ if (is_array($params) || $params === false) {
+ return static::$_locations->set($name, $params);
+ }
+ return static::$_locations->get($name);
+ }
+
+ /**
+ * Set the name of location to use for building assets urls
+ *
+ * @var string $location The name of location
+ */
+ public static function setLocation($location) {
+ static::$_location = $location;
+ }
+
+ /**
+ * Returns the name of the current location
+ *
+ * @return string
+ */
+ public static function getLocation() {
+ return static::$_location;
+ }
}
-?>
+?>
View
@@ -244,11 +244,10 @@ public function parse($request, array $options = array()) {
* Matches a set of parameters against the route, and returns a URL string if the route matches
* the parameters, or false if it does not match.
*
- * @param array $options
- * @param string $context
+ * @param array $options Urls parameters (i.e. controller, action, args...)
* @return mixed
*/
- public function match(array $options = array(), $context = null) {
+ public function match(array $options = array()) {
$defaults = array('action' => 'index');
$query = null;
@@ -460,4 +459,4 @@ protected function _regex($regex, $param, $token, $prefix) {
}
}
-?>
+?>
Oops, something went wrong.