From abc1fad6c1f6797545c6903333af8c6c14945e93 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Thu, 8 Sep 2011 17:49:16 -0500 Subject: [PATCH] more refactoring and changes. --- application/composers.php | 4 +- application/config/aliases.php | 8 +-- laravel/arr.php | 2 +- laravel/asset.php | 38 ++++++------ laravel/benchmark.php | 16 ++++- laravel/blade.php | 67 ++++++++++++++++++++ laravel/bootstrap.php | 7 +-- laravel/cache/driver.php | 6 +- laravel/config.php | 29 +++++++-- laravel/config/container.php | 12 ++-- laravel/container.php | 65 ++++++++++++------- laravel/controller.php | 24 ++++--- laravel/cookie.php | 21 +++++-- laravel/download.php | 51 --------------- laravel/facades.php | 45 +++++++------- laravel/file.php | 44 ++++++++++--- laravel/form.php | 110 ++++++++++++++++++++++++++++++--- laravel/html.php | 96 ++++++++++++++++++++++++++-- laravel/inflector.php | 29 ++++++--- laravel/input.php | 58 ++++++++++++----- laravel/lang.php | 66 ++++++++++---------- laravel/laravel.php | 80 ++++++++++-------------- laravel/loader.php | 58 ++++------------- laravel/package.php | 45 -------------- laravel/redirect.php | 39 +++++++----- laravel/request.php | 6 +- laravel/response.php | 51 +++++++++++---- laravel/routing/caller.php | 2 +- laravel/routing/delegator.php | 2 +- laravel/session/driver.php | 24 ++++--- laravel/str.php | 59 +++++++++--------- laravel/url.php | 86 ++++++++++++++++++++++++-- laravel/view.php | 102 ++++++++++++++++++++---------- public/index.php | 13 +++- 34 files changed, 883 insertions(+), 482 deletions(-) create mode 100644 laravel/blade.php delete mode 100644 laravel/download.php delete mode 100644 laravel/package.php diff --git a/application/composers.php b/application/composers.php index 218536e0..777cf3da 100644 --- a/application/composers.php +++ b/application/composers.php @@ -39,12 +39,12 @@ | */ - 'shared' => function($view, $laravel) + 'shared' => function($view) { // }, - 'home.index' => array('name' => 'home', function($view, $laravel) + 'home.index' => array('name' => 'home', function($view) { // }), diff --git a/application/config/aliases.php b/application/config/aliases.php index 47b8a07d..cebb431c 100644 --- a/application/config/aliases.php +++ b/application/config/aliases.php @@ -19,7 +19,7 @@ */ 'Arr' => 'Laravel\\Arr', - 'Asset' => 'Laravel\\Asset', + 'Asset' => 'Laravel\\Facades\\Asset', 'Auth' => 'Laravel\\Facades\\Auth', 'Benchmark' => 'Laravel\\Benchmark', 'Cache' => 'Laravel\\Facades\\Cache', @@ -37,16 +37,16 @@ 'Inflector' => 'Laravel\\Inflector', 'Input' => 'Laravel\\Facades\\Input', 'IoC' => 'Laravel\\IoC', - 'Lang' => 'Laravel\\Lang', + 'Lang' => 'Laravel\\Facades\\Lang', 'Loader' => 'Laravel\\Facades\\Loader', 'Package' => 'Laravel\\Facades\\Package', 'URL' => 'Laravel\\Facades\\URL', 'Redirect' => 'Laravel\\Facades\\Redirect', 'Request' => 'Laravel\\Facades\\Request', - 'Response' => 'Laravel\\Response', + 'Response' => 'Laravel\\Facades\\Response', 'Session' => 'Laravel\\Facades\\Session', 'Str' => 'Laravel\\Str', 'Validator' => 'Laravel\\Facades\\Validator', - 'View' => 'Laravel\\View', + 'View' => 'Laravel\\Facades\\View', ); \ No newline at end of file diff --git a/laravel/arr.php b/laravel/arr.php index f07ff663..21535c7d 100644 --- a/laravel/arr.php +++ b/laravel/arr.php @@ -47,7 +47,7 @@ public static function get($array, $key, $default = null) * method, JavaScript "dot" syntax is supported. * * - * // Set the "name" item to "Fred" in the array + * // Set an array's "name" item to "Fred" * Arr::set($array, 'name', 'Fred'); * * diff --git a/laravel/asset.php b/laravel/asset.php index e43c7b1b..0a4ee68e 100644 --- a/laravel/asset.php +++ b/laravel/asset.php @@ -58,8 +58,8 @@ public function container($container = 'default') /** * Magic Method for calling methods on the default Asset container. * - * This provides a convenient API, allowing the develop to skip the "container" - * method when using the default container. + * This provides a convenient API, allowing the developer to skip the + * "container" method when using the default container. * * * // Add a JavaScript file to the default container @@ -81,8 +81,6 @@ class Asset_Container { /** * The asset container name. * - * This name may be used to access the container instance via the Asset::container method. - * * @var string */ public $name; @@ -127,10 +125,10 @@ public function __construct($name, HTML $html) * * * // Add an asset to the container - * Asset::container()->add('jquery', 'js/jquery.js'); + * Asset::add('jquery', 'js/jquery.js'); * * // Add an asset that has dependencies - * Asset::container()->add('jquery', 'js/jquery.js', array('jquery-ui')); + * Asset::add('jquery', 'js/jquery.js', array('jquery-ui')); * * * @param string $name @@ -147,13 +145,13 @@ public function add($name, $source, $dependencies = array(), $attributes = array } /** - * Add CSS to the registered assets. + * Add a CSS file to the registered assets. * - * @param string $name - * @param string $source - * @param array $dependencies - * @param array $attributes - * @return void + * @param string $name + * @param string $source + * @param array $dependencies + * @param array $attributes + * @return Asset_Container */ public function style($name, $source, $dependencies = array(), $attributes = array()) { @@ -163,20 +161,24 @@ public function style($name, $source, $dependencies = array(), $attributes = arr } $this->register('style', $name, $source, $dependencies, $attributes); + + return $this; } /** - * Add JavaScript to the registered assets. + * Add a JavaScript file to the registered assets. * - * @param string $name - * @param string $source - * @param array $dependencies - * @param array $attributes - * @return void + * @param string $name + * @param string $source + * @param array $dependencies + * @param array $attributes + * @return Asset_Container */ public function script($name, $source, $dependencies = array(), $attributes = array()) { $this->register('script', $name, $source, $dependencies, $attributes); + + return $this; } /** diff --git a/laravel/benchmark.php b/laravel/benchmark.php index 34168b41..c53403ec 100644 --- a/laravel/benchmark.php +++ b/laravel/benchmark.php @@ -10,9 +10,14 @@ class Benchmark { protected static $marks = array(); /** - * Start a benchmark. + * Start a benchmark starting time. * - * After starting a benchmark, the elapsed time in milliseconds may be retrieved via the "check" method. + * The elapsed time since setting a benchmark may checked via the "check" method. + * + * + * // Set a benchmark starting time + * Benchmark::start('database'); + * * * @param string $name * @return void @@ -25,6 +30,11 @@ public static function start($name) /** * Get the elapsed time in milliseconds since starting a benchmark. * + * + * // Get the elapsed time since starting a benchmark + * $time = Benchmark::check('database'); + * + * * @param string $name * @return float */ @@ -45,7 +55,7 @@ public static function check($name) */ public static function memory() { - return number_format(memory_get_usage() / 1024 / 1024, 2); + return (float) number_format(memory_get_usage() / 1024 / 1024, 2); } } \ No newline at end of file diff --git a/laravel/blade.php b/laravel/blade.php new file mode 100644 index 00000000..98052992 --- /dev/null +++ b/laravel/blade.php @@ -0,0 +1,67 @@ +', $value); + } + + /** + * Rewrites Blade structure openings into PHP structure openings. + * + * @param string $value + * @return string + */ + protected static function rewrite_openings($value) + { + return preg_replace('/@(if|elseif|foreach|for|while)(\s*\(.*?\))\:/', '', $value); + } + + /** + * Rewrites Blade structure closings into PHP structure closings. + * + * @param string $value + * @return string + */ + protected static function rewrite_closings($value) + { + $value = preg_replace('/(\s*)@(else)(.*?)\:/', '$1', $value); + $value = preg_replace('/(\s*)@(endif|endforeach|endfor|endwhile)(\s*)/', '$1 $3', $value); + + return $value; + } + +} \ No newline at end of file diff --git a/laravel/bootstrap.php b/laravel/bootstrap.php index 8cd44a90..5ad080f8 100644 --- a/laravel/bootstrap.php +++ b/laravel/bootstrap.php @@ -25,9 +25,7 @@ define('CONTROLLER_PATH', APP_PATH.'controllers/'); define('DATABASE_PATH', STORAGE_PATH.'database/'); define('LANG_PATH', APP_PATH.'language/'); -define('SCRIPT_PATH', PUBLIC_PATH.'js/'); define('SESSION_PATH', STORAGE_PATH.'sessions/'); -define('STYLE_PATH', PUBLIC_PATH.'css/'); define('SYS_CONFIG_PATH', SYS_PATH.'config/'); define('SYS_LANG_PATH', SYS_PATH.'language/'); define('VIEW_PATH', APP_PATH.'views/'); @@ -36,7 +34,6 @@ // Load the configuration manager and its dependencies. // -------------------------------------------------------------- require SYS_PATH.'facades'.EXT; -require SYS_PATH.'loader'.EXT; require SYS_PATH.'config'.EXT; require SYS_PATH.'arr'.EXT; @@ -62,6 +59,6 @@ IoC::$container = $container; // -------------------------------------------------------------- -// Register the auto-loader on the stack. +// Register the auto-loader on the auto-loader stack. // -------------------------------------------------------------- -spl_autoload_register(array($container->loader, 'load')); \ No newline at end of file +spl_autoload_register(array($container->resolve('laravel.loader'), 'load')); \ No newline at end of file diff --git a/laravel/cache/driver.php b/laravel/cache/driver.php index 9e4c4def..756c38ae 100644 --- a/laravel/cache/driver.php +++ b/laravel/cache/driver.php @@ -1,5 +1,7 @@ retrieve($key))) return $item; - return ($default instanceof \Closure) ? call_user_func($default) : $default; + return ($default instanceof Closure) ? call_user_func($default) : $default; } /** @@ -59,7 +61,7 @@ public function remember($key, $value, $minutes) { if ( ! is_null($item = $this->get($key, null))) return $item; - $default = ($default instanceof \Closure) ? call_user_func($default) : $default; + $default = ($default instanceof Closure) ? call_user_func($default) : $default; $this->put($key, $default, $minutes); diff --git a/laravel/config.php b/laravel/config.php index d63c9901..2cd2a4b6 100644 --- a/laravel/config.php +++ b/laravel/config.php @@ -5,14 +5,14 @@ class Config { /** * All of the loaded configuration items. * - * The configuration arrays are keyed by file names. + * The configuration arrays are keyed by their owning file name. * * @var array */ protected $items = array(); /** - * The paths containing the configuration files. + * The paths to the configuration files. * * @var array */ @@ -46,6 +46,17 @@ public function has($key) * If the name of a configuration file is passed without specifying an item, the * entire configuration array will be returned. * + * + * // Get the "timezone" option from the "application" file + * $timezone = Config::get('application.timezone'); + * + * // Get the SQLite connection configuration from the "database" file + * $sqlite = Config::get('database.connections.sqlite'); + * + * // Get a configuration option and return "Fred" if it doesn't exist + * $option = Config::get('config.option', 'Fred'); + * + * * @param string $key * @param string $default * @return array @@ -70,6 +81,14 @@ public function get($key, $default = null) * If a specific configuration item is not specified, the entire configuration * array will be replaced with the given value. * + * + * // Set the "timezone" option in the "application" file + * Config::set('application.timezone', 'America/Chicago'); + * + * // Set the entire "session" array to an empty array + * Config::set('session', array()); + * + * * @param string $key * @param mixed $value * @return void @@ -91,11 +110,13 @@ public function set($key, $value) * @param string $key * @return array */ - private function parse($key) + protected function parse($key) { $segments = explode('.', $key); - return array($segments[0], (count($segments) > 1) ? implode('.', array_slice($segments, 1)) : null); + $key = (count($segments) > 1) ? implode('.', array_slice($segments, 1)) : null; + + return array($segments[0], $key); } /** diff --git a/laravel/config/container.php b/laravel/config/container.php index a5f70d47..71d5ce09 100644 --- a/laravel/config/container.php +++ b/laravel/config/container.php @@ -110,7 +110,7 @@ ($request->spoofed()) ? $input = $_POST : parse_str(file_get_contents('php://input'), $input); } - return new Input($input, $_FILES, $container->resolve('laravel.cookie')); + return new Input($container->resolve('laravel.file'), $container->resolve('laravel.cookie'), $input, $_FILES); }), @@ -124,9 +124,11 @@ 'laravel.loader' => array('singleton' => true, 'resolver' => function($container) { - $paths = array(BASE_PATH, APP_PATH.'models/', APP_PATH.'libraries/'); + require_once SYS_PATH.'loader'.EXT; - return new Loader($container->resolve('laravel.config')->get('aliases'), $paths); + $aliases = $container->resolve('laravel.config')->get('aliases'); + + return new Loader(array(BASE_PATH, APP_PATH.'models/', APP_PATH.'libraries/'), $aliases); }), @@ -152,7 +154,7 @@ { require_once SYS_PATH.'response'.EXT; - return new Response_Factory($container->resolve('laravel.view')); + return new Response_Factory($container->resolve('laravel.view'), $container->resolve('laravel.file')); }), @@ -220,7 +222,7 @@ 'laravel.view.composer' => array('resolver' => function($container) { - return new View_Composer($container, require APP_PATH.'composers'.EXT); + return new View_Composer(require APP_PATH.'composers'.EXT); }), /* diff --git a/laravel/container.php b/laravel/container.php index 2a72f9d3..5c9e546f 100644 --- a/laravel/container.php +++ b/laravel/container.php @@ -46,26 +46,31 @@ class Container { * * @var array */ - protected $resolvers = array(); + protected $registry = array(); /** * Create a new IoC container instance. * - * @param array $dependencies + * @param array $registry * @return void */ - public function __construct($dependencies = array()) + public function __construct($registry = array()) { - foreach ($dependencies as $key => $value) - { - $this->register($key, $value['resolver'], (isset($value['singleton'])) ? $value['singleton'] : false); - } + $this->registry = $registry; } /** * Register a dependency and its resolver. * - * The resolver function when the registered dependency is requested. + * The resolver function is called when the registered dependency is requested. + * + * + * // Register a dependency in the container + * IoC::register('something', function($container) {return new Something;}); + * + * // Register a dependency in the container as a singleton + * IoC::register('something', function($container) {return new Something;}, true); + * * * @param string $name * @param Closure $resolver @@ -73,7 +78,7 @@ public function __construct($dependencies = array()) */ public function register($name, $resolver, $singleton = false) { - $this->resolvers[$name] = array('resolver' => $resolver, 'singleton' => $singleton); + $this->registry[$name] = array('resolver' => $resolver, 'singleton' => $singleton); } /** @@ -84,7 +89,7 @@ public function register($name, $resolver, $singleton = false) */ public function registered($name) { - return array_key_exists($name, $this->resolvers); + return array_key_exists($name, $this->registry); } /** @@ -93,6 +98,11 @@ public function registered($name) * Singletons will only be instantiated the first time they are resolved. On subsequent * requests for the object, the original instance will be returned. * + * + * // Register a dependency in the container as a singleton + * IoC::singleton('something', function($container) {return new Something;}); + * + * * @param string $name * @param Closure $resolver * @return void @@ -108,6 +118,13 @@ public function singleton($name, $resolver) * This method allows you to register an already existing object instance with the * container as a singleton instance. * + * + * // Register an instance with the IoC container + * $something = new Something; + * + * IoC::instance('something', $something); + * + * * @param string $name * @param mixed $instance * @return void @@ -122,6 +139,11 @@ public function instance($name, $instance) * * The dependency's resolver will be called and its result will be returned. * + * + * // Get the "something" dependency out of the IoC container + * $something = IoC::resolve('something'); + * + * * @param string $name * @return mixed */ @@ -134,26 +156,25 @@ public function resolve($name) throw new \Exception("Error resolving [$name]. No resolver has been registered in the container."); } - $object = call_user_func($this->resolvers[$name]['resolver'], $this); + $object = call_user_func($this->registry[$name]['resolver'], $this); - if ($this->resolvers[$name]['singleton']) $this->singletons[$name] = $object; - - return $object; + return (isset($this->registry[$name]['singleton'])) ? $this->singletons[$name] = $object : $object; } /** * Magic Method for resolving classes out of the IoC container. + * + * + * // Get the "something" instance out of the IoC container + * $something = IoC::container()->something; + * + * // Equivalent method of retrieving the instance using the resolve method + * $something = IoC::container()->resolve('something'); + * */ public function __get($key) { - if ($this->registered('laravel.'.$key)) - { - return $this->resolve('laravel.'.$key); - } - elseif ($this->registered($key)) - { - return $this->resolve($key); - } + if ($this->registered($key)) return $this->resolve($key); throw new \Exception("Attempting to resolve undefined class [$key]."); } diff --git a/laravel/controller.php b/laravel/controller.php index c5659791..08f7a2cb 100644 --- a/laravel/controller.php +++ b/laravel/controller.php @@ -2,13 +2,6 @@ abstract class Controller { - /** - * The IoC container instance. - * - * @var Container - */ - public $container; - /** * A stub method that will be called before every request to the controller. * @@ -28,15 +21,26 @@ public function before() {} */ public function __call($method, $parameters) { - return $this->container->resolve('laravel.response')->error('404'); + return IoC::container()->resolve('laravel.response')->error('404'); } /** - * Magic Method for retrieving items out of the IoC container. + * Dynamically resolve items from the application IoC container. */ public function __get($key) { - return $this->container->$key; + $container = IoC::container(); + + if ($container->registered('laravel.'.$key)) + { + return $container->resolve('laravel.'.$key); + } + elseif ($container->registered($key)) + { + return $container->resolve($key); + } + + throw new \Exception("Attempting to access undefined property [$key] on controller."); } } \ No newline at end of file diff --git a/laravel/cookie.php b/laravel/cookie.php index 3b7a3be0..4eaea702 100644 --- a/laravel/cookie.php +++ b/laravel/cookie.php @@ -7,7 +7,7 @@ class Cookie { * * @var array */ - private $cookies; + protected $cookies; /** * Create a new cookie manager instance. @@ -34,6 +34,14 @@ public function has($name) /** * Get the value of a cookie. * + * + * // Get the value of a cookie + * $value = Cookie::get('color'); + * + * // Get the value of a cookie and return "blue" if the cookie doesn't exist + * $value = Cookie::get('color', 'blue'); + * + * * @param string $name * @param mixed $default * @return string @@ -60,8 +68,9 @@ public function forever($name, $value, $path = '/', $domain = null, $secure = fa } /** - * Set the value of a cookie. If a negative number of minutes is - * specified, the cookie will be deleted. + * Set the value of a cookie. + * + * If a negative number of minutes is specified, the cookie will be deleted. * * @param string $name * @param string $value @@ -74,9 +83,11 @@ public function forever($name, $value, $path = '/', $domain = null, $secure = fa */ public function put($name, $value, $minutes = 0, $path = '/', $domain = null, $secure = false, $http_only = false) { - if ($minutes < 0) unset($_COOKIE[$name]); + if ($minutes < 0) unset($this->cookies[$name]); - return setcookie($name, $value, ($minutes != 0) ? time() + ($minutes * 60) : 0, $path, $domain, $secure, $http_only); + $time = ($minutes != 0) ? time() + ($minutes * 60) : 0; + + return setcookie($name, $value, $time, $path, $domain, $secure, $http_only); } /** diff --git a/laravel/download.php b/laravel/download.php deleted file mode 100644 index 4504a08b..00000000 --- a/laravel/download.php +++ /dev/null @@ -1,51 +0,0 @@ -file = $file; - } - - /** - * Create a new download response instance. - * - * @param string $path - * @param string $name - * @param array $headers - * @return Response - */ - public function of($path, $name = null, $headers = array()) - { - if (is_null($name)) $name = basename($path); - - $headers = array_merge(array( - 'Content-Description' => 'File Transfer', - 'Content-Type' => $this->mime($this->file->extension($path)), - 'Content-Disposition' => 'attachment; filename="'.$name.'"', - 'Content-Transfer-Encoding' => 'binary', - 'Expires' => 0, - 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', - 'Pragma' => 'public', - 'Content-Length' => $this->file-size($path), - ), $headers); - - $response = parent::__construct($this->file->get($path), 200, $headers); - - return $response; - } - -} \ No newline at end of file diff --git a/laravel/facades.php b/laravel/facades.php index 55a92a59..06812c42 100644 --- a/laravel/facades.php +++ b/laravel/facades.php @@ -15,28 +15,31 @@ abstract class Facade { */ public static function __callStatic($method, $parameters) { - return call_user_func_array(array(IoC::container()->resolve('laravel.'.static::$resolve), $method), $parameters); + return call_user_func_array(array(IoC::container()->resolve(static::$resolve), $method), $parameters); } } -class Asset extends Facade { public static $resolve = 'asset'; } -class Auth extends Facade { public static $resolve = 'auth'; } -class Cache extends Facade { public static $resolve = 'cache'; } -class Config extends Facade { public static $resolve = 'config'; } -class Cookie extends Facade { public static $resolve = 'cookie'; } -class Crypter extends Facade { public static $resolve = 'crypter'; } -class DB extends Facade { public static $resolve = 'database'; } -class Download extends Facade { public static $resolve = 'download'; } -class File extends Facade { public static $resolve = 'file'; } -class Form extends Facade { public static $resolve = 'form'; } -class Hasher extends Facade { public static $resolve = 'hasher'; } -class HTML extends Facade { public static $resolve = 'html'; } -class Input extends Facade { public static $resolve = 'input'; } -class Loader extends Facade { public static $resolve = 'loader'; } -class Package extends Facade { public static $resolve = 'package'; } -class Redirect extends Facade { public static $resolve = 'redirect'; } -class Request extends Facade { public static $resolve = 'request'; } -class Session extends Facade { public static $resolve = 'session'; } -class URL extends Facade { public static $resolve = 'url'; } -class Validator extends Facade { public static $resolve = 'validator'; } \ No newline at end of file +class Asset extends Facade { public static $resolve = 'laravel.asset'; } +class Auth extends Facade { public static $resolve = 'laravel.auth'; } +class Cache extends Facade { public static $resolve = 'laravel.cache'; } +class Config extends Facade { public static $resolve = 'laravel.config'; } +class Cookie extends Facade { public static $resolve = 'laravel.cookie'; } +class Crypter extends Facade { public static $resolve = 'laravel.crypter'; } +class DB extends Facade { public static $resolve = 'laravel.database'; } +class Download extends Facade { public static $resolve = 'laravel.download'; } +class File extends Facade { public static $resolve = 'laravel.file'; } +class Form extends Facade { public static $resolve = 'laravel.form'; } +class Hasher extends Facade { public static $resolve = 'laravel.hasher'; } +class HTML extends Facade { public static $resolve = 'laravel.html'; } +class Input extends Facade { public static $resolve = 'laravel.input'; } +class Lang extends Facade { public static $resolve = 'laravel.lang'; } +class Loader extends Facade { public static $resolve = 'laravel.loader'; } +class Package extends Facade { public static $resolve = 'laravel.package'; } +class Redirect extends Facade { public static $resolve = 'laravel.redirect'; } +class Request extends Facade { public static $resolve = 'laravel.request'; } +class Response extends Facade { public static $resolve = 'laravel.response'; } +class Session extends Facade { public static $resolve = 'laravel.session'; } +class URL extends Facade { public static $resolve = 'laravel.url'; } +class Validator extends Facade { public static $resolve = 'laravel.validator'; } +class View extends Facade { public static $resolve = 'laravel.view'; } \ No newline at end of file diff --git a/laravel/file.php b/laravel/file.php index 2f39e81a..fe3378be 100644 --- a/laravel/file.php +++ b/laravel/file.php @@ -121,9 +121,29 @@ public function modified($path) return filemtime($path); } + /** + * Move an uploaded file to permanenet storage. + * + * @param string $key + * @param string $path + * @param array $files + * @return bool + */ + public function upload($key, $path, $files) + { + return move_uploaded_file($files[$key]['tmp_name'], $path); + } + /** * Get a file MIME type by extension. * + * If the MIME type can't be determined, "application/octet-stream" will be returned. + * + * + * // Returns 'application/x-tar' + * $mime = File::mime('path/to/file.tar'); + * + * * @param string $extension * @param string $default * @return string @@ -140,20 +160,28 @@ public function mime($extension, $default = 'application/octet-stream') * * The Fileinfo PHP extension will be used to determine the MIME type of the file. * - * @param string $extension - * @param string $path + * + * // Determine if a file is a JPG image + * $image = File::is('jpg', 'path/to/image.jpg'); + * + * // Determine if a file is any one of an array of types + * $image = File::is(array('jpg', 'png', 'gif'), 'path/to/image.jpg'); + * + * + * @param array|string $extension + * @param string $path * @return bool */ - public function is($extension, $path) + public function is($extensions, $path) { - if ( ! array_key_exists($extension, $this->mimes)) + foreach ((array) $extensions as $extension) { - throw new \Exception("File extension [$extension] is unknown. Cannot determine file type."); + $mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path); + + if (isset($this->mimes[$extension]) and in_array((array) $this->mimes[$extension])) return true; } - $mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path); - - return (is_array($this->mimes[$extension])) ? in_array($mime, $this->mimes[$extension]) : $mime === $this->mimes[$extension]; + return false; } } \ No newline at end of file diff --git a/laravel/form.php b/laravel/form.php index 4a1fba48..73d607b7 100644 --- a/laravel/form.php +++ b/laravel/form.php @@ -7,21 +7,21 @@ class Form { * * @var Request */ - private $request; + protected $request; /** * The HTML writer instance. * * @var HTML */ - private $html; + protected $html; /** * The URL generator instance. * * @var URL */ - private $url; + protected $url; /** * All of the label names that have been created. @@ -31,7 +31,7 @@ class Form { * * @var array */ - private $labels = array(); + protected $labels = array(); /** * Create a new form writer instance. @@ -55,6 +55,17 @@ public function __construct(Request $request, HTML $html, URL $url) * containing the request method. PUT and DELETE are not supported by HTML forms, so the * hidden field will allow us to "spoof" PUT and DELETE requests. * + * + * // Open a POST form to the current URI + * echo Form::open(); + * + * // Open a POST form to a given URI + * echo Form::open('user/profile'); + * + * // Open a PUT form to a given URI and add form attributes + * echo Form::open('user/profile', 'put', array('class' => 'profile')); + * + * * @param string $action * @param string $method * @param array $attributes @@ -84,7 +95,7 @@ public function open($action = null, $method = 'POST', $attributes = array(), $h * @param string $method * @return string */ - private function method($method) + protected function method($method) { return strtoupper(($method == 'PUT' or $method == 'DELETE') ? 'POST' : $method); } @@ -98,7 +109,7 @@ private function method($method) * @param bool $https * @return string */ - private function action($action, $https) + protected function action($action, $https) { return $this->html->entities($this->url->to(((is_null($action)) ? $this->request->uri() : $action), $https)); } @@ -172,12 +183,25 @@ public function token() */ public function raw_token() { + if (IoC::container()->resolve('laravel.config')->get('session.driver') == '') + { + throw new \Exception("A session driver must be specified before using CSRF tokens."); + } + return IoC::container()->resolve('laravel.session')->get('csrf_token'); } /** * Create a HTML label element. * + * + * // Create a form label + * echo Form::label('email', 'E-Mail Address'); + * + * // Create a form label with attributes + * echo Form::label('email', 'E-Mail Address', array('class' => 'login')); + * + * * @param string $name * @param string $value * @param array $attributes @@ -196,6 +220,17 @@ public function label($name, $value, $attributes = array()) * If an ID attribute is not specified and a label has been generated matching the input * element name, the label name will be used as the element ID. * + * + * // Create a "text" type input element + * echo Form::input('text', 'email'); + * + * // Create an input element with a specified value + * echo Form::input('text', 'email', 'example@gmail.com'); + * + * // Create an input element with attributes + * echo Form::input('text', 'email', 'example@gmail.com', array('class' => 'login')); + * + * * @param string $name * @param mixed $value * @param array $attributes @@ -203,6 +238,8 @@ public function label($name, $value, $attributes = array()) */ public function input($type, $name, $value = null, $attributes = array()) { + $name = (isset($attributes['name'])) ? $attributes['name'] : $name; + $id = $this->id($name, $attributes); return 'html->attributes(array_merge($attributes, compact('type', 'name', 'value', 'id'))).'>'.PHP_EOL; @@ -326,6 +363,14 @@ public function file($name, $attributes = array()) /** * Create a HTML textarea element. * + * + * // Create a textarea element + * echo Form::textarea('comment'); + * + * // Create a textarea with specified rows and columns + * echo Form::textarea('comment', '', array('rows' => 10, 'columns' => 50)); + * + * * @param string $name * @param string $value * @param array $attributes @@ -345,6 +390,14 @@ public function textarea($name, $value = '', $attributes = array()) /** * Create a HTML select element. * + * + * // Create a selection element + * echo Form::select('sizes', array('S' => 'Small', 'L' => 'Large')); + * + * // Create a selection element with a given option pre-selected + * echo Form::select('sizes', array('S' => 'Small', 'L' => 'Large'), 'L'); + * + * * @param string $name * @param array $options * @param string $selected @@ -370,13 +423,21 @@ public function select($name, $options = array(), $selected = null, $attributes /** * Create a HTML checkbox input element. * + * + * // Create a checkbox element + * echo Form::checkbox('terms'); + * + * // Create a checkbox element that is checked by default + * echo Form::checkbox('terms', 'yes', true); + * + * * @param string $name * @param string $value * @param bool $checked * @param array $attributes * @return string */ - public function checkbox($name, $value = null, $checked = false, $attributes = array()) + public function checkbox($name, $value = 1, $checked = false, $attributes = array()) { return $this->checkable('checkbox', $name, $value, $checked, $attributes); } @@ -384,6 +445,14 @@ public function checkbox($name, $value = null, $checked = false, $attributes = a /** * Create a HTML radio button input element. * + * + * // Create a radio button element + * echo Form::radio('apple'); + * + * // Create a radio button element that is selected by default + * echo Form::radio('microsoft', 'pc', true); + * + * * @param string $name * @param string $value * @param bool $checked @@ -392,6 +461,8 @@ public function checkbox($name, $value = null, $checked = false, $attributes = a */ public function radio($name, $value = null, $checked = false, $attributes = array()) { + if (is_null($value)) $value = $name; + return $this->checkable('radio', $name, $value, $checked, $attributes); } @@ -405,7 +476,7 @@ public function radio($name, $value = null, $checked = false, $attributes = arra * @param array $attributes * @return string */ - private function checkable($type, $name, $value, $checked, $attributes) + protected function checkable($type, $name, $value, $checked, $attributes) { $attributes = array_merge($attributes, array('id' => $this->id($name, $attributes), 'checked' => ($checked) ? 'checked' : null)); @@ -415,6 +486,14 @@ private function checkable($type, $name, $value, $checked, $attributes) /** * Create a HTML submit input element. * + * + * // Create a submit input element + * echo Form::submit('Login!'); + * + * // Create a submit input element with attributes + * echo Form::submit('Login!', array('class' => 'login')); + * + * * @param string $value * @param array $attributes * @return string @@ -439,6 +518,11 @@ public function reset($value, $attributes = array()) /** * Create a HTML image input element. * + * + * // Create an image input element + * echo Form::image('img/login.jpg'); + * + * * @param string $url * @param array $attributes * @return string @@ -453,6 +537,14 @@ public function image($url, $name = null, $attributes = array()) /** * Create a HTML button element. * + * + * // Create a button input element + * echo Form::button('Login!'); + * + * // Create a button input element with attributes + * echo Form::button('Login!', array('class' => 'login')); + * + * * @param string $name * @param string $value * @param array $attributes @@ -473,7 +565,7 @@ public function button($value, $attributes = array()) * @param array $attributes * @return mixed */ - private function id($name, $attributes) + protected function id($name, $attributes) { if (array_key_exists('id', $attributes)) return $attributes['id']; diff --git a/laravel/html.php b/laravel/html.php index dd77bfcf..c98d31ec 100644 --- a/laravel/html.php +++ b/laravel/html.php @@ -44,6 +44,14 @@ public function entities($value) /** * Generate a JavaScript reference. * + * + * // Generate a link to a JavaScript file + * echo HTML::script('js/jquery.js'); + * + * // Generate a link to a JavaScript file with attributes + * echo HTML::script('js/jquery.js', array('defer')); + * + * * @param string $url * @param array $attributes * @return string @@ -58,6 +66,16 @@ public function script($url, $attributes = array()) /** * Generate a CSS reference. * + * If no media type is selected, "all" will be used. + * + * + * // Generate a link to a CSS file + * echo HTML::style('css/common.css'); + * + * // Generate a link to a CSS file with attributes + * echo HTML::style('css/common.css', array('media' => 'print')); + * + * * @param string $url * @param array $attributes * @return string @@ -74,6 +92,14 @@ public function style($url, $attributes = array()) /** * Generate a HTML span. * + * + * // Generate a HTML span element + * echo HTML::span('This is inside a span element.'); + * + * // Generate a HTML span element with attributes + * echo HTML::span('This is inside a span.', array('class' => 'text')); + * + * * @param string $value * @param array $attributes * @return string @@ -86,6 +112,14 @@ public function span($value, $attributes = array()) /** * Generate a HTML link. * + * + * // Generate a HTML link element + * echo HTML::link('user/profile', 'User Profile'); + * + * // Generate a HTML link element with attributes + * echo HTML::link('user/profile', 'User Profile', array('class' => 'profile')); + * + * * @param string $url * @param string $title * @param array $attributes @@ -116,6 +150,8 @@ public function link_to_secure($url, $title, $attributes = array()) /** * Generate an HTML link to an asset. * + * The application index page will not be added to asset links. + * * @param string $url * @param string $title * @param array $attributes @@ -144,6 +180,15 @@ public function link_to_secure_asset($url, $title, $attributes = array()) * * An array of parameters may be specified to fill in URI segment wildcards. * + * + * // Generate a link to the "profile" route + * echo HTML::link_to_route('profile', 'User Profile'); + * + * // Generate a link to a route that has wildcard segments + * // Example: /user/profile/(:any) + * echo HTML::link_to_route('profile', 'User Profile', array($username)); + * + * * @param string $name * @param string $title * @param array $parameters @@ -174,6 +219,17 @@ public function link_to_secure_route($name, $title, $parameters = array(), $attr * * The E-Mail address will be obfuscated to protect it from spam bots. * + * + * // Generate a HTML mailto link + * echo HTML::mailto('example@gmail.com'); + * + * // Generate a HTML mailto link with a title + * echo HTML::mailto('example@gmail.com', 'E-Mail Me!'); + * + * // Generate a HTML mailto link with attributes + * echo HTML::mailto('example@gmail.com', 'E-Mail Me', array('class' => 'email')); + * + * * @param string $email * @param string $title * @param array $attributes @@ -202,7 +258,18 @@ public function email($email) } /** - * Generate an HTML image. + * Generate an HTML image element. + * + * + * // Generate a HTML image element + * echo HTML::image('img/profile.jpg'); + * + * // Generate a HTML image element with Alt text + * echo HTML::image('img/profile.jpg', 'Profile Photo'); + * + * // Generate a HTML image element with attributes + * echo HTML::image('img/profile.jpg', 'Profile Photo', array('class' => 'profile')); + * * * @param string $url * @param string $alt @@ -217,7 +284,15 @@ public function image($url, $alt = '', $attributes = array()) } /** - * Generate an ordered list. + * Generate an ordered list of items. + * + * + * // Generate an ordered list of items + * echo HTML::ol(array('Small', 'Medium', 'Large')); + * + * // Generate an ordered list of items with attributes + * echo HTML::ol(array('Small', 'Medium', 'Large'), array('class' => 'sizes')); + * * * @param array $list * @param array $attributes @@ -229,7 +304,15 @@ public function ol($list, $attributes = array()) } /** - * Generate an un-ordered list. + * Generate an un-ordered list of items. + * + * + * // Generate an un-ordered list of items + * echo HTML::ul(array('Small', 'Medium', 'Large')); + * + * // Generate an un-ordered list of items with attributes + * echo HTML::ul(array('Small', 'Medium', 'Large'), array('class' => 'sizes')); + * * * @param array $list * @param array $attributes @@ -261,7 +344,12 @@ private function list_elements($type, $list, $attributes = array()) } /** - * Build a list of HTML attributes. + * Build a list of HTML attributes from an array. + * + * + * // Returns: class="profile" id="picture" + * echo HTML::attributes(array('class' => 'profile', 'id' => 'picture')); + * * * @param array $attributes * @return string diff --git a/laravel/inflector.php b/laravel/inflector.php index bbcbc9d8..03e30d52 100644 --- a/laravel/inflector.php +++ b/laravel/inflector.php @@ -86,14 +86,14 @@ class Inflector { * @var array */ private static $irregular = array( - 'move' => 'moves', + 'child' => 'children', 'foot' => 'feet', 'goose' => 'geese', - 'sex' => 'sexes', - 'child' => 'children', 'man' => 'men', - 'tooth' => 'teeth', + 'move' => 'moves', 'person' => 'people', + 'sex' => 'sexes', + 'tooth' => 'teeth', ); /** @@ -102,20 +102,29 @@ class Inflector { * @var array */ private static $uncountable = array( - 'sheep', - 'fish', + 'equipment', + 'data', 'deer', - 'series', - 'species', + 'fish', + 'information', 'money', 'rice', - 'information', - 'equipment', + 'series', + 'sheep', + 'species', ); /** * Get the plural form of a word if the specified count is greater than one. * + * + * // Returns "friend" + * echo Inflector::plural_if('friend', 1); + * + * // Returns "friends" + * echo Inflector::plural_if('friend', 2); + * + * * @param string $value * @param int $count * @return string diff --git a/laravel/input.php b/laravel/input.php index 4cff23a8..0fc8c10d 100644 --- a/laravel/input.php +++ b/laravel/input.php @@ -10,18 +10,18 @@ class Input { protected $input; /** - * The $_GET array for the request. + * The $_FILES array for the request. * * @var array */ - public $get; + protected $files; /** - * The $_POST array for the request. + * The file manager instance. * - * @var array + * @var File */ - public $post; + protected $file; /** * The cookie engine instance. @@ -30,23 +30,17 @@ class Input { */ public $cookies; - /** - * The $_FILES array for the request. - * - * @var array - */ - public $files; - /** * Create a new Input instance. * + * @param Cookie $cookies * @param array $input * @param array $files - * @param Cookie $cookies * @return void */ - public function __construct($input, $files, Cookie $cookies) + public function __construct(File $file, Cookie $cookies, $input, $files) { + $this->file = $file; $this->input = $input; $this->files = $files; $this->cookies = $cookies; @@ -80,6 +74,14 @@ public function has($key) * * This method should be used for all request methods (GET, POST, PUT, and DELETE). * + * + * // Get an item from the input to the application + * $value = Input::get('name'); + * + * // Get an item from the input and return "Fred" if the item doesn't exist + * $value = Input::get('name', 'Fred'); + * + * * @param string $key * @param mixed $default * @return mixed @@ -103,12 +105,25 @@ public function had($key) /** * Get input data from the previous request. * + * + * // Get an item from the previous request's input + * $value = Input::old('name'); + * + * // Get an item from the previous request's input and return "Fred" if it doesn't exist. + * $value = Input::old('name', 'Fred'); + * + * * @param string $key * @param mixed $default * @return string */ public function old($key = null, $default = null) { + if (IoC::container()->resolve('laravel.config')->get('session.driver') == '') + { + throw new \Exception('A session driver must be specified in order to access old input.'); + } + $driver = IoC::container()->resolve('laravel.session'); return Arr::get($driver->get('laravel_old_input', array()), $key, $default); @@ -119,6 +134,14 @@ public function old($key = null, $default = null) * * "Dot" syntax may be used to get a specific item from the file array. * + * + * // Get the array of information regarding an uploaded file + * $file = Input::file('picture'); + * + * // Get an element from the array of information regarding an uploaded file + * $size = Input::file('picture.size'); + * + * * @param string $key * @param mixed $default * @return array @@ -133,13 +156,18 @@ public function file($key = null, $default = null) * * This method is simply a convenient wrapper around move_uploaded_file. * + * + * // Move the "picture" file to a permament location on disk + * Input::upload('picture', PUBLIC_PATH.'img/picture.jpg'); + * + * * @param string $key * @param string $path * @return bool */ public function upload($key, $path) { - return array_key_exists($key, $this->files) ? move_uploaded_file($this->files[$key]['tmp_name'], $path) : false; + return array_key_exists($key, $this->files) ? $this->file->upload($key, $path, $this->files) : false; } /** diff --git a/laravel/lang.php b/laravel/lang.php index 78a408a2..ee4a39f2 100644 --- a/laravel/lang.php +++ b/laravel/lang.php @@ -35,6 +35,14 @@ public function __construct(Config $config, $paths) /** * Begin retrieving a language line. * + * + * // Begin retrieving a language line + * $lang = Lang::line('messages.welcome'); + * + * // Begin retrieving a language line with replacements + * $lang = Lang::line('validation.required', array('attribute' => 'email')); + * + * * @param string $key * @param array $replacements * @return Lang @@ -55,35 +63,35 @@ class Lang { * * @var array */ - private static $lines = array(); + protected static $lines = array(); /** * The key of the language line being retrieved. * * @var string */ - private $key; + protected $key; /** * The replacements that should be made on the language line. * * @var array */ - private $replacements; + protected $replacements; /** - * The default language being used by the application. + * The language in which the line should be retrieved. * * @var string */ - private $language; + protected $language; /** * The paths containing the language files. * * @var array */ - private $paths; + protected $paths; /** * Create a new Lang instance. @@ -102,28 +110,30 @@ public function __construct($key, $replacements, $language, $paths) $this->replacements = $replacements; } - /** - * Create a new Lang instance. - * - * @param string $key - * @param array $replacements - * @return Lang - */ - public static function line($key, $replacements = array()) - { - return IoC::container()->resolve('laravel.lang')->line($key, $replacements); - } - /** * Get the language line. * * A default value may also be specified, which will be returned in the language line doesn't exist. * + * + * // Retrieve a language line in the default language + * echo Lang::line('validation.required')->get(); + * + * // Retrieve a language line for a given language + * echo Lang::line('validation.required')->get('sp'); + * + * // Retrieve a language line and return "Fred" if it doesn't exist + * echo Lang::line('validation.required')->get('en', 'Fred'); + * + * * @param string $language + * @param string $default * @return string */ - public function get($default = null) + public function get($language = null, $default = null) { + if ( ! is_null($language)) $this->language = $language; + list($file, $line) = $this->parse($this->key); if ( ! $this->load($file)) @@ -151,7 +161,7 @@ public function get($default = null) * @param string $key * @return array */ - private function parse($key) + protected function parse($key) { if (count($segments = explode('.', $key)) > 1) { @@ -169,7 +179,7 @@ private function parse($key) * @param string $file * @return bool */ - private function load($file) + protected function load($file) { if (isset(static::$lines[$this->language.$file])) return; @@ -188,20 +198,6 @@ private function load($file) return isset(static::$lines[$this->language.$file]); } - /** - * Set the language the line should be returned in. - * - * The language specified in this method should correspond to a language directory in your application. - * - * @param string $language - * @return Lang - */ - public function in($language) - { - $this->language = $language; - return $this; - } - /** * Get the string content of the language line. */ diff --git a/laravel/laravel.php b/laravel/laravel.php index 5ac5fc78..100a8cc0 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -5,6 +5,33 @@ // -------------------------------------------------------------- require 'bootstrap.php'; +// -------------------------------------------------------------- +// Get an instance of the configuration manager. +// -------------------------------------------------------------- +$config = $container->resolve('laravel.config'); + +set_exception_handler(function($e) use ($config) +{ + call_user_func($config->get('error.handler'), $e); +}); + +set_error_handler(function($number, $error, $file, $line) use ($config) +{ + $exception = new \ErrorException($error, $number, 0, $file, $line); + + call_user_func($config->get('error.handler'), $exception); +}); + +register_shutdown_function(function() use ($config) +{ + if ( ! is_null($error = error_get_last())) + { + $exception = new \ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']); + + call_user_func($config->get('error.handler'), $exception); + } +}); + // -------------------------------------------------------------- // Set the error reporting and display levels. // -------------------------------------------------------------- @@ -12,58 +39,21 @@ ini_set('display_errors', 'Off'); -// -------------------------------------------------------------- -// Register the error / exception handlers. -// -------------------------------------------------------------- -set_exception_handler(function($e) use ($container) -{ - call_user_func($container->config->get('error.handler'), $e); -}); - -set_error_handler(function($number, $error, $file, $line) use ($container) -{ - $exception = new \ErrorException($error, $number, 0, $file, $line); - - call_user_func($container->config->get('error.handler'), $exception); -}); - -register_shutdown_function(function() use ($container) -{ - if ( ! is_null($error = error_get_last())) - { - $exception = new \ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']); - - call_user_func($container->config->get('error.handler'), $exception); - } -}); - // -------------------------------------------------------------- // Set the default timezone. // -------------------------------------------------------------- -date_default_timezone_set($container->config->get('application.timezone')); +date_default_timezone_set($config->get('application.timezone')); // -------------------------------------------------------------- // Load the session and session manager. // -------------------------------------------------------------- -if ($container->config->get('session.driver') !== '') +if ($config->get('session.driver') !== '') { - $cookie = $container->input->cookies->get('laravel_session'); + $cookie = $container->resolve('laravel.input')->cookies->get('laravel_session'); - $container->session->start($cookie, $container->config->get('session.lifetime')); + $container->resolve('laravel.session')->start($cookie, $config->get('session')); } -// -------------------------------------------------------------- -// Load the packages that are in the auto-loaded packages array. -// -------------------------------------------------------------- -$packages = $container->config->get('application.packages'); - -if (count($packages) > 0) -{ - $container->package->load($packages); -} - -unset($packages); - // -------------------------------------------------------------- // Route the request and get the response from the route. // -------------------------------------------------------------- @@ -71,13 +61,11 @@ if ( ! is_null($route)) { - $route->filters = require APP_PATH.'filters'.EXT; - $response = $container->resolve('laravel.routing.caller')->call($route); } else { - $response = $container->response->error('404'); + $response = $container->resolve('laravel.response')->error('404'); } // -------------------------------------------------------------- @@ -88,9 +76,9 @@ // -------------------------------------------------------------- // Close the session. // -------------------------------------------------------------- -if ($container->config->get('session.driver') !== '') +if ($config->get('session.driver') !== '') { - $container->session->close($container->input, $container->config->get('session')); + $container->resolve('laravel.session')->close($container->resolve('laravel.input')); } // -------------------------------------------------------------- diff --git a/laravel/loader.php b/laravel/loader.php index 9a0dd253..bc6296fb 100644 --- a/laravel/loader.php +++ b/laravel/loader.php @@ -3,35 +3,34 @@ class Loader { /** - * The paths to be searched by the loader. + * The paths that will be searched by the loader. * * @var array */ - protected $paths; + public $paths; /** - * All of the class aliases. + * The class aliases defined for the application. * * @var array */ - protected $aliases; + public $aliases; /** - * Bootstrap the auto-loader. + * Create a new class loader instance. * + * @param array $paths + * @param array $aliases * @return void */ - public function __construct($aliases, $paths) + public function __construct($paths, $aliases) { $this->paths = $paths; $this->aliases = $aliases; } /** - * Load a class file for a given class name. - * - * This function is registered on the SPL auto-loader stack by the front controller during each request. - * All Laravel class names follow a namespace to directory convention. + * Load the file for a given class. * * @param string $class * @return void @@ -45,9 +44,9 @@ public function load($class) return class_alias($this->aliases[$class], $class); } - foreach ($this->paths as $directory) + foreach ($this->paths as $path) { - if (file_exists($path = $directory.$file.EXT)) + if (file_exists($path = $path.$file.EXT)) { require_once $path; @@ -56,39 +55,4 @@ public function load($class) } } - /** - * Register a path with the auto-loader. - * - * After registering the path, it will be checked similarly to the models and libraries directories. - * - * @param string $path - * @return void - */ - public function register_path($path) - { - $this->paths[] = rtrim($path, '/').'/'; - } - - /** - * Register an alias with the auto-loader. - * - * @param array $alias - * @return void - */ - public function register_alias($alias) - { - $this->aliases = array_merge($this->aliases, $alias); - } - - /** - * Remove an alias from the auto-loader's list of aliases. - * - * @param string $alias - * @return void - */ - public function forget_alias($alias) - { - unset($this->aliases[$alias]); - } - } \ No newline at end of file diff --git a/laravel/package.php b/laravel/package.php deleted file mode 100644 index 9839b2f6..00000000 --- a/laravel/package.php +++ /dev/null @@ -1,45 +0,0 @@ -loaded($package) and file_exists($bootstrap = $path.$package.'/bootstrap'.EXT)) - { - require $bootstrap; - } - - $this->loaded[] = $package; - } - } - - /** - * Determine if a given package has been loaded. - * - * @param string $package - * @return bool - */ - public function loaded($package) - { - return array_key_exists($package, $this->loaded); - } - -} \ No newline at end of file diff --git a/laravel/redirect.php b/laravel/redirect.php index 3001eb0d..1c00ae37 100644 --- a/laravel/redirect.php +++ b/laravel/redirect.php @@ -12,7 +12,7 @@ class Redirect extends Response { /** * Create a new redirect generator instance. * - * @param URL $url + * @param URL $url * @return void */ public function __construct(URL $url) @@ -23,39 +23,41 @@ public function __construct(URL $url) /** * Create a redirect response. * + * + * // Create a redirect response to a given URL + * return Redirect::to('user/profile'); + * + * // Create a redirect with a given status code + * return Redirect::to('user/profile', 301); + * + * * @param string $url * @param int $status - * @param string $method * @param bool $https * @return Redirect */ - public function to($url, $status = 302, $method = 'location', $https = false) + public function to($url, $status = 302, $https = false) { - $url = $this->url->to($url, $https); - parent::__construct('', $status); - if ($method == 'location') - { - return $this->header('Refresh', '0;url='.$url); - } - else - { - return $this->header('Location', $url); - } + return $this->header('Location', $this->url->to($url, $https)); } /** * Create a redirect response to a HTTPS URL. * + * + * // Create a redirect response to a HTTPS URL + * return Redirect::to_secure('user/profile'); + * + * * @param string $url * @param int $status - * @param string $method * @return Response */ - public function to_secure($url, $status = 302, $method = 'location') + public function to_secure($url, $status = 302) { - return $this->to($url, $status, $method, true); + return $this->to($url, $status, true); } /** @@ -69,6 +71,11 @@ public function to_secure($url, $status = 302, $method = 'location') */ public function with($key, $value) { + if (IoC::container()->resolve('laravel.config')->get('session.driver') == '') + { + throw new \Exception('A session driver must be set before setting flash data.'); + } + IoC::container()->resolve('laravel.session')->flash($key, $value); return $this; diff --git a/laravel/request.php b/laravel/request.php index 582b1619..187e20a6 100644 --- a/laravel/request.php +++ b/laravel/request.php @@ -21,14 +21,14 @@ class Request { * * @var array */ - private $post; + protected $post; /** * The base URL of the application. * * @var string */ - private $url; + protected $url; /** * The request URI. @@ -38,7 +38,7 @@ class Request { * * @var string */ - private $uri; + protected $uri; /** * Create a new request instance. diff --git a/laravel/response.php b/laravel/response.php index 2b10d5d4..3bc877be 100644 --- a/laravel/response.php +++ b/laravel/response.php @@ -7,17 +7,26 @@ class Response_Factory { * * @var View_Factory */ - private $view; + protected $view; + + /** + * The file manager instance. + * + * @var File + */ + protected $file; /** * Create a new response factory instance. * - * @param File $file + * @param View_Factory $view + * @param File $file * @return void */ - public function __construct(View_Factory $view) + public function __construct(View_Factory $view, File $file) { $this->view = $view; + $this->file = $file; } /** @@ -54,13 +63,39 @@ public function view($view, $data = array()) * * @param int $code * @param array $data - * @return void + * @return Response */ public function error($code, $data = array()) { return new Response($this->view->make('error/'.$code, $data), $code); } + /** + * Create a new download response instance. + * + * @param string $path + * @param string $name + * @param array $headers + * @return Response + */ + public function download($path, $name = null, $headers = array()) + { + if (is_null($name)) $name = basename($path); + + $headers = array_merge(array( + 'Content-Description' => 'File Transfer', + 'Content-Type' => $this->file->mime($this->file->extension($path)), + 'Content-Disposition' => 'attachment; filename="'.$name.'"', + 'Content-Transfer-Encoding' => 'binary', + 'Expires' => 0, + 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', + 'Pragma' => 'public', + 'Content-Length' => $this->file-size($path), + ), $headers); + + return new Response($this->file->get($path), 200, $headers); + } + } class Response { @@ -224,12 +259,4 @@ public function status($status) return $this; } - /** - * Magic Method for calling methods on the response factory instance. - */ - public static function __callStatic($method, $parameters) - { - return call_user_func_array(array(IoC::container()->resolve('laravel.response'), $method), $parameters); - } - } \ No newline at end of file diff --git a/laravel/routing/caller.php b/laravel/routing/caller.php index b82c24b0..5218e023 100644 --- a/laravel/routing/caller.php +++ b/laravel/routing/caller.php @@ -67,7 +67,7 @@ public function call(Route $route) return $this->finish($route, $response); } - return $this->finish($route, $this->container->response->error('404')); + return $this->finish($route, $this->container->resolve('laravel.response')->error('404')); } /** diff --git a/laravel/routing/delegator.php b/laravel/routing/delegator.php index 2f31870f..1bbe3b03 100644 --- a/laravel/routing/delegator.php +++ b/laravel/routing/delegator.php @@ -49,7 +49,7 @@ public function delegate(Route $route, $delegate) // an underscore are not publicly available. if (is_null($controller) or ($method == 'before' or strncmp($method, '_', 1) === 0)) { - return $this->container->response->error('404'); + return $this->container->resolve('laravel.response')->error('404'); } $controller->container = $this->container; diff --git a/laravel/session/driver.php b/laravel/session/driver.php index 20d19b0c..67077119 100644 --- a/laravel/session/driver.php +++ b/laravel/session/driver.php @@ -13,6 +13,13 @@ abstract class Driver { */ public $session = array(); + /** + * The application session configuration. + * + * @var array + */ + public $config = array(); + /** * Load the session for a given session ID. * @@ -22,14 +29,16 @@ abstract class Driver { * If the session has expired, a new, empty session will be generated. * * @param string $id - * @param int $lifetime + * @param array $config * @return void */ - public function start($id, $lifetime) + public function start($id, $config) { + $this->config = $config; + $this->session = ( ! is_null($id)) ? $this->load($id) : null; - if (is_null($this->session) or (time() - $this->session['last_activity']) > ($lifetime * 60)) + if (is_null($this->session) or (time() - $this->session['last_activity']) > ($this->config['lifetime'] * 60)) { $this->session = array('id' => Str::random(40), 'data' => array()); } @@ -169,20 +178,19 @@ public function regenerate() * available for the next request via the "old" method on the input class. * * @param Laravel\Input $input - * @param array $config * @return void */ - public function close(Input $input, $config) + public function close(Input $input) { $this->flash('laravel_old_input', $input->get())->age(); $this->save(); - $this->write_cookie($input->cookies, $config); + $this->write_cookie($input->cookies, $this->config); if ($this instanceof Sweeper and mt_rand(1, 100) <= 2) { - $this->sweep(time() - ($config['lifetime'] * 60)); + $this->sweep(time() - ($this->config['lifetime'] * 60)); } } @@ -214,7 +222,7 @@ protected function age() * already been sent to the browser. * * @param Laravel\Cookie $cookie - * @param array $config + * @param array $config * @return void */ protected function write_cookie(Cookie $cookies, $config) diff --git a/laravel/str.php b/laravel/str.php index 1d682611..6baec824 100644 --- a/laravel/str.php +++ b/laravel/str.php @@ -10,7 +10,12 @@ class Str { */ public static function lower($value) { - return function_exists('mb_strtolower') ? mb_strtolower($value, static::encoding()) : strtolower($value); + if (function_exists('mb_strtolower')) + { + return mb_strtolower($value, static::encoding()); + } + + return strtolower($value); } /** @@ -21,7 +26,12 @@ public static function lower($value) */ public static function upper($value) { - return function_exists('mb_strtoupper') ? mb_strtoupper($value, static::encoding()) : strtoupper($value); + if (function_exists('mb_strtoupper')) + { + return mb_strtoupper($value, static::encoding()); + } + + return strtoupper($value); } /** @@ -32,7 +42,12 @@ public static function upper($value) */ public static function title($value) { - return (function_exists('mb_convert_case')) ? mb_convert_case($value, MB_CASE_TITLE, static::encoding()) : ucwords(strtolower($value)); + if (function_exists('mb_convert_case')) + { + return mb_convert_case($value, MB_CASE_TITLE, static::encoding()); + } + + return ucwords(strtolower($value)); } /** @@ -43,7 +58,12 @@ public static function title($value) */ public static function length($value) { - return function_exists('mb_strlen') ? mb_strlen($value, static::encoding()) : strlen($value); + if (function_exists('mb_strlen')) + { + return mb_strlen($value, static::encoding()); + } + + return strlen($value); } /** @@ -72,34 +92,11 @@ public static function ascii($value) */ public static function random($length = 16, $type = 'alpha_num') { - $value = ''; + $alpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $pool_length = strlen($pool = static::pool($type)) - 1; + $pool = ($type == 'alpha_num') ? '0123456789'.$alpha : $alpha; - for ($i = 0; $i < $length; $i++) - { - $value .= $pool[mt_rand(0, $pool_length)]; - } - - return $value; - } - - /** - * Get a chracter pool. - * - * @param string $type - * @return string - */ - private static function pool($type = 'alpha_num') - { - switch ($type) - { - case 'alpha_num': - return '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - default: - return 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - } + return implode('', array_map(function() use ($pool) { return $pool[mt_rand(0, strlen($pool) - 1)]; }, range(0, $length))); } /** @@ -107,7 +104,7 @@ private static function pool($type = 'alpha_num') * * @return string */ - public static function encoding() + protected static function encoding() { return IoC::container()->resolve('laravel.config')->get('application.encoding'); } diff --git a/laravel/url.php b/laravel/url.php index befcf435..ff50e463 100644 --- a/laravel/url.php +++ b/laravel/url.php @@ -2,13 +2,41 @@ class URL { + /** + * The application router instance. + * + * @var Routing\Router + */ + protected $router; + + /** + * The base URL of the application. + * + * @var string + */ + protected $base; + + /** + * The application index file. + * + * @var string + */ + protected $index; + + /** + * Indicates if the current request is using HTTPS. + * + * @var bool + */ + protected $https; + /** * Create a new URL writer instance. * - * @param Router $router - * @param string $base - * @param string $index - * @param bool $https + * @param Routing\Router $router + * @param string $base + * @param string $index + * @param bool $https * @return void */ public function __construct(Routing\Router $router, $base, $index, $https) @@ -24,6 +52,14 @@ public function __construct(Routing\Router $router, $base, $index, $https) * * If the given URL is already well-formed, it will be returned unchanged. * + * + * // Generate an application URL from a given URI + * echo URL::to('user/profile'); + * + * // Generate an application URL with HTTPS + * echo URL::to('user/profile', true); + * + * * @param string $url * @param bool $https * @return string @@ -36,12 +72,17 @@ public function to($url = '', $https = false) if ($https) $base = preg_replace('~http://~', 'https://', $base, 1); - return rtrim($base, '/').'/'.trim($url, '/'); + return rtrim($base, '/').'/'.ltrim($url, '/'); } /** * Generate an application URL with HTTPS. * + * + * // Generate an application URL with HTTPS + * echo URL::to_secure('user/profile'); + * + * * @param string $url * @return string */ @@ -56,6 +97,14 @@ public function to_secure($url = '') * The index file will not be added to asset URLs. If the HTTPS option is not * specified, HTTPS will be used when the active request is also using HTTPS. * + * + * // Generate a URL to an asset + * echo URL::to_asset('img/picture.jpg'); + * + * // Generate a URL to a an asset with HTTPS + * echo URL::to_asset('img/picture.jpg', true); + * + * * @param string $url * @param bool $https * @return string @@ -76,6 +125,14 @@ public function to_asset($url, $https = null) * * Optional parameters will be convereted to spaces if no parameter values are specified. * + * + * // Generate the URL for a given route + * echo URL::to_route('profile'); + * + * // Generate the URL for a given route with wildcard segments + * echo URL::to_route('profile', array($username)); + * + * * @param string $name * @param array $parameters * @param bool $https @@ -103,6 +160,14 @@ public function to_route($name, $parameters = array(), $https = false) /** * Generate a HTTPS URL from a route name. * + * + * // Generate the URL for a route with HTTPS + * echo URL::to_secure_route('profile'); + * + * // Generate the URL for a route with HTTPS and wildcard segments + * echo URL::to_secure_route('profile', array($username)); + * + * * @param string $name * @param array $parameters * @return string @@ -134,6 +199,17 @@ public function slug($title, $separator = '-') /** * Magic Method for dynamically creating URLs to named routes. + * + * + * // Generate the URL for the "profile" named route + * echo URL::to_profile(); + * + * // Generate the URL for the "profile" named route with wildcard segments + * echo URL::to_profile(array($username)); + * + * // Generate the URL for the "profile" named route with HTTPS + * echo URL::to_secure_profile(); + * */ public function __call($method, $parameters) { diff --git a/laravel/view.php b/laravel/view.php index c121f611..d2934de2 100644 --- a/laravel/view.php +++ b/laravel/view.php @@ -37,6 +37,18 @@ public function __construct(View_Composer $composer, $path) /** * Create a new view instance. * + * The name of the view given to this method should correspond to a view + * within your application views directory. Dots or slashes may used to + * reference views within sub-directories. + * + * + * // Create a new view instance + * $view = View::make('home.index'); + * + * // Create a new view instance with bound data + * $view = View::make('home.index', array('name' => 'Fred')); + * + * * @param string $view * @param array $data * @return View @@ -49,6 +61,16 @@ public function make($view, $data = array()) /** * Create a new view instance from a view name. * + * View names are defined in the application composers file. + * + * + * // Create a new named view instance + * $view = View::of('layout'); + * + * // Create a new named view instance with bound data + * $view = View::of('layout', array('name' => 'Fred')); + * + * * @param string $name * @param array $data * @return View @@ -71,11 +93,30 @@ protected function of($name, $data = array()) */ protected function path($view) { - return $this->path.str_replace('.', '/', $view).EXT; + $view = str_replace('.', '/', $view); + + if (file_exists($path = $this->path.$view.'.blade'.EXT)) + { + return $path; + } + elseif (file_exists($path = $this->path.$view.EXT)) + { + return $path; + } + + throw new \Exception('View ['.$view.'] does not exist.'); } /** * Magic Method for handling the dynamic creation of named views. + * + * + * // Create an instance of the "layout" named view + * $view = View::of_layout(); + * + * // Create an instance of the "layout" named view with bound data + * $view = View::of_layout(array('name' => 'Fred')); + * */ public function __call($method, $parameters) { @@ -95,13 +136,6 @@ public function __call($method, $parameters) */ class View_Composer { - /** - * The IoC container instance. - * - * @var Container - */ - protected $container; - /** * The view composers. * @@ -112,13 +146,11 @@ class View_Composer { /** * Create a new view composer instance. * - * @param Container $container * @param array $composers * @return void */ - public function __construct(Container $container, $composers) + public function __construct($composers) { - $this->container = $container; $this->composers = $composers; } @@ -144,13 +176,13 @@ public function name($name) */ public function compose(View $view) { - if (isset($this->composers['shared'])) call_user_func($this->composers['shared'], $view, $this->container); + if (isset($this->composers['shared'])) call_user_func($this->composers['shared'], $view); if (isset($this->composers[$view->view])) { foreach ((array) $this->composers[$view->view] as $key => $value) { - if ($value instanceof \Closure) return call_user_func($value, $view, $this->container); + if ($value instanceof \Closure) return call_user_func($value, $view); } } } @@ -216,23 +248,6 @@ public function __construct(View_Factory $factory, View_Composer $composer, $vie $this->path = $path; $this->factory = $factory; $this->composer = $composer; - - if ( ! file_exists($this->path)) - { - throw new \Exception('View ['.$this->path.'] does not exist.'); - } - } - - /** - * Create a new view instance. - * - * @param string $view - * @param array $data - * @return View - */ - public static function make($view, $data = array()) - { - return IoC::container()->resolve('laravel.view')->make($view, $data); } /** @@ -254,14 +269,34 @@ public function render() ob_start() and extract($this->data, EXTR_SKIP); - try { include $this->path; } catch (\Exception $e) { ob_get_clean(); throw $e; } + $content = ($this->bladed()) ? Blade::parse($this->path) : file_get_contents($this->path); + + eval('?>'.$content); return ob_get_clean(); } + /** + * Determine if the view is using the blade view engine. + * + * @return bool + */ + protected function bladed() + { + return (strpos($this->path, '.blade'.EXT) !== false); + } + /** * Add a view instance to the view data. * + * + * // Bind a partial view to the view data + * $view->partial('footer', 'partials/footer'); + * + * // Bind a partial view to the view data with it's own bound data + * $view->partial('footer', 'partials/footer', array('name' => 'Fred')); + * + * * @param string $key * @param string $view * @param array $data @@ -277,6 +312,11 @@ public function partial($key, $view, $data = array()) * * Bound data will be available to the view as variables. * + * + * // Bind a piece of data to a view instance + * $view->with('name', 'Fred'); + * + * * @param string $key * @param mixed $value * @return View diff --git a/public/index.php b/public/index.php index 19a2f0a5..e2a3fcc0 100644 --- a/public/index.php +++ b/public/index.php @@ -10,7 +10,14 @@ /* |-------------------------------------------------------------------------- -| Installation Paths +| Tick... Tock... Tick... Tock +|-------------------------------------------------------------------------- +*/ +define('START_TIME', microtime(true)); + +/* +|-------------------------------------------------------------------------- +| Where Am I? |-------------------------------------------------------------------------- | | Here you may specify the location of the various Laravel framework @@ -36,4 +43,6 @@ | 3... 2... 1... Lift-off! |-------------------------------------------------------------------------- */ -require $laravel.'/laravel.php'; \ No newline at end of file +require $laravel.'/laravel.php'; + +echo (microtime(true) - START_TIME) * 1000; \ No newline at end of file