From 932a70b6cf3d9679dc10c8dc866dd33436b9381e Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Sat, 29 Oct 2011 22:24:32 -0500 Subject: [PATCH] refactoring for better dependency injection on a few classes. --- application/config/application.php | 4 +- laravel/bootstrap/core.php | 1 + laravel/config/container.php | 63 +++++++++++++++++++ laravel/facades.php | 63 +++++++++++++++++++ laravel/form.php | 4 +- laravel/input.php | 48 ++++++++++----- laravel/laravel.php | 48 ++------------- laravel/paginator.php | 6 +- laravel/request.php | 97 +++++++++++++++++++----------- laravel/response.php | 4 +- laravel/routing/router.php | 7 ++- laravel/url.php | 2 +- laravel/validation/validator.php | 6 +- 13 files changed, 248 insertions(+), 105 deletions(-) create mode 100644 laravel/facades.php diff --git a/application/config/application.php b/application/config/application.php index f02bc76a..1f86469b 100644 --- a/application/config/application.php +++ b/application/config/application.php @@ -146,13 +146,13 @@ 'Hasher' => 'Laravel\\Security\\Hasher', 'HTML' => 'Laravel\\HTML', 'Inflector' => 'Laravel\\Inflector', - 'Input' => 'Laravel\\Input', + 'Input' => 'Laravel\\Facades\\Input', 'IoC' => 'Laravel\\IoC', 'Lang' => 'Laravel\\Lang', 'URL' => 'Laravel\\URL', 'Redirect' => 'Laravel\\Redirect', 'Redis' => 'Laravel\\Redis', - 'Request' => 'Laravel\\Request', + 'Request' => 'Laravel\\Facades\\Request', 'Response' => 'Laravel\\Response', 'Session' => 'Laravel\\Session\\Manager', 'Str' => 'Laravel\\Str', diff --git a/laravel/bootstrap/core.php b/laravel/bootstrap/core.php index 03b3b690..850bf667 100644 --- a/laravel/bootstrap/core.php +++ b/laravel/bootstrap/core.php @@ -9,6 +9,7 @@ */ require SYS_PATH.'arr'.EXT; require SYS_PATH.'config'.EXT; +require SYS_PATH.'facades'.EXT; /** * Load some core configuration files by default so we don't have to diff --git a/laravel/config/container.php b/laravel/config/container.php index a0284e0e..291bd73a 100644 --- a/laravel/config/container.php +++ b/laravel/config/container.php @@ -2,6 +2,69 @@ return array( + /* + |-------------------------------------------------------------------------- + | Various Laravel Components + |-------------------------------------------------------------------------- + | + | Many of the Laravel classes are resolved through the inversion of control + | container to maintain a high level of testability and flexibility. + | + | Most of them are also accessible through a "Facade", which simulates the + | class being usable via static methods for convenience. Facades allow the + | framework to keep a convenient API, while still having a testable core. + | + */ + + 'laravel.input' => array('singleton' => true, 'resolver' => function($c) + { + require SYS_PATH.'input'.EXT; + + $input = array(); + + $request = $c->core('request'); + + switch ($request->method()) + { + case 'GET': + $input = $_GET; + break; + + case 'POST': + $input = $_POST; + break; + + case 'PUT': + case 'DELETE': + if ($request->spoofed()) + { + $input = $_POST; + } + else + { + parse_str(file_get_contents('php://input'), $input); + } + } + + return new Input($input, $_FILES); + }), + + + 'laravel.request' => array('singleton' => true, 'resolver' => function($c) + { + require_once SYS_PATH.'request'.EXT; + + return new Request($c->core('uri'), $_POST, $_SERVER); + }), + + + 'laravel.uri' => array('singleton' => true, 'resolver' => function($c) + { + require_once SYS_PATH.'uri'.EXT; + + return new URI($_SERVER); + }), + /* |-------------------------------------------------------------------------- | Laravel Routing Components diff --git a/laravel/facades.php b/laravel/facades.php new file mode 100644 index 00000000..47acc97f --- /dev/null +++ b/laravel/facades.php @@ -0,0 +1,63 @@ +resolve(static::$resolve); + + $count = count($parameters); + + if ($count > 5) + { + return call_user_func_array(array($class, $method), $parameters); + } + elseif ($count == 1) + { + return $class->$method($parameters[0]); + } + elseif ($count == 2) + { + return $class->$method($parameters[0], $parameters[1]); + } + elseif ($count == 3) + { + return $class->$method($parameters[0], $parameters[1], $parameters[2]); + } + elseif ($count == 4) + { + return $class->$method($parameters[0], $parameters[1], $parameters[2], $parameters[3]); + } + elseif ($count == 5) + { + return $class->$method($parameters[0], $parameters[1], $parameters[2], $parameters[3], $parameters[4]); + } + } + +} + +class Input extends Facade { public static $resolve = 'laravel.input'; } +class Request extends Facade { public static $resolve = 'laravel.request'; } \ No newline at end of file diff --git a/laravel/form.php b/laravel/form.php index bf9feea1..8c991ffd 100644 --- a/laravel/form.php +++ b/laravel/form.php @@ -82,7 +82,9 @@ protected static function method($method) */ protected static function action($action, $https) { - return HTML::entities(URL::to(((is_null($action)) ? Request::uri()->get() : $action), $https)); + $request = IoC::container()->core('uri'); + + return HTML::entities(URL::to(((is_null($action)) ? $uri->get() : $action), $https)); } /** diff --git a/laravel/input.php b/laravel/input.php index ad888782..38275515 100644 --- a/laravel/input.php +++ b/laravel/input.php @@ -7,7 +7,14 @@ class Input { * * @var array */ - public static $input; + protected $input; + + /** + * The $_FILES array for the request. + * + * @var array + */ + protected $files; /** * The key used to store old input in the session. @@ -16,6 +23,19 @@ class Input { */ const old_input = 'laravel_old_input'; + /** + * Create a new instance of the Input manager. + * + * @param array $input + * @param array $files + * @return void + */ + public function __construct($input, $files) + { + $this->input = $input; + $this->files = $files; + } + /** * Get all of the input data for the request. * @@ -23,9 +43,9 @@ class Input { * * @return array */ - public static function all() + public function all() { - return array_merge(static::get(), static::file()); + return array_merge($this->get(), $this->file()); } /** @@ -36,9 +56,9 @@ public static function all() * @param string $key * @return bool */ - public static function has($key) + public function has($key) { - return ( ! is_null(static::get($key)) and trim((string) static::get($key)) !== ''); + return ( ! is_null($this->get($key)) and trim((string) $this->get($key)) !== ''); } /** @@ -58,9 +78,9 @@ public static function has($key) * @param mixed $default * @return mixed */ - public static function get($key = null, $default = null) + public function get($key = null, $default = null) { - return Arr::get(static::$input, $key, $default); + return Arr::get($this->input, $key, $default); } /** @@ -69,9 +89,9 @@ public static function get($key = null, $default = null) * @param string $key * @return bool */ - public static function had($key) + public function had($key) { - return ( ! is_null(static::old($key)) and trim((string) static::old($key)) !== ''); + return ( ! is_null($this->old($key)) and trim((string) $this->old($key)) !== ''); } /** @@ -89,7 +109,7 @@ public static function had($key) * @param mixed $default * @return string */ - public static function old($key = null, $default = null) + public function old($key = null, $default = null) { if (Config::get('session.driver') == '') { @@ -114,9 +134,9 @@ public static function old($key = null, $default = null) * @param mixed $default * @return array */ - public static function file($key = null, $default = null) + public function file($key = null, $default = null) { - return Arr::get($_FILES, $key, $default); + return Arr::get($this->files, $key, $default); } /** @@ -133,9 +153,9 @@ public static function file($key = null, $default = null) * @param string $path * @return bool */ - public static function upload($key, $path) + public function upload($key, $path) { - return array_key_exists($key, $_FILES) ? File::upload($key, $path, $_FILES) : false; + return array_key_exists($key, $this->files) ? File::upload($key, $path, $this->files) : false; } } \ No newline at end of file diff --git a/laravel/laravel.php b/laravel/laravel.php index d4d61cc0..ee7579ac 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -37,52 +37,12 @@ * Manually load some core classes that are used on every request * This allows to avoid using the loader for these classes. */ -require SYS_PATH.'uri'.EXT; -require SYS_PATH.'input'.EXT; -require SYS_PATH.'request'.EXT; require SYS_PATH.'response'.EXT; require SYS_PATH.'routing/route'.EXT; require SYS_PATH.'routing/router'.EXT; require SYS_PATH.'routing/loader'.EXT; require SYS_PATH.'routing/filter'.EXT; -/** - * Gather the input to the application for the current request. - * The input will be gathered based on the current request method - * and will be set on the Input manager. - */ -$input = array(); - -switch (Request::method()) -{ - case 'GET': - $input = $_GET; - break; - - case 'POST': - $input = $_POST; - break; - - case 'PUT': - case 'DELETE': - if (Request::spoofed()) - { - $input = $_POST; - } - else - { - parse_str(file_get_contents('php://input'), $input); - } -} - -/** - * The spoofed request method is removed from the input so it is - * not unexpectedly included in Input::all() or Input::get().s - */ -unset($input[Request::spoofer]); - -Input::$input = $input; - /** * Route the request to the proper route in the application. If a * route is found, the route will be called with the current request @@ -91,13 +51,13 @@ */ Routing\Filter::register(require APP_PATH.'filters'.EXT); -list($uri, $method) = array(Request::uri()->get(), Request::method()); +$request = IoC::container()->core('request'); -Request::$route = IoC::container()->core('routing.router')->route($method, $uri); +$request->route = IoC::container()->core('routing.router')->route($request); -if ( ! is_null(Request::$route)) +if ( ! is_null($request->route)) { - $response = Request::$route->call(); + $response = $request->route->call(); } else { diff --git a/laravel/paginator.php b/laravel/paginator.php index 2f9669c0..06de3136 100644 --- a/laravel/paginator.php +++ b/laravel/paginator.php @@ -105,7 +105,7 @@ public static function make($results, $total, $per_page) */ public static function page($total, $per_page) { - $page = Input::get('page', 1); + $page = IoC::container()->core('input')->get('page', 1); // The page will be validated and adjusted if it is less than one or greater // than the last page. For example, if the current page is not an integer or @@ -250,11 +250,11 @@ protected function element($element, $text, $page, $disabler) // We will assume the page links should use HTTPS if the current request // is also using HTTPS. Since pagination links automatically point to // the current URI, this makes pretty good sense. - list($uri, $secure) = array(Request::uri()->get(), Request::secure()); + $request = IoC::container()->core('request'); $appendage = $this->appendage($element, $page); - return HTML::link($uri.$appendage, $text, array('class' => $class), $secure); + return HTML::link($request->uri().$appendage, $text, array('class' => $class), $requst->secure()); } } diff --git a/laravel/request.php b/laravel/request.php index c9103b9b..e6620f80 100644 --- a/laravel/request.php +++ b/laravel/request.php @@ -2,19 +2,33 @@ class Request { - /** - * The request URI for the current request. - * - * @var URI - */ - public static $uri; - /** * The route handling the current request. * * @var Routing\Route */ - public static $route; + public $route; + + /** + * The request URI for the current request. + * + * @var URI + */ + protected $uri; + + /** + * The $_POST array for the request. + * + * @var array + */ + protected $post; + + /** + * The $_SERVER array for the request. + * + * @var array + */ + protected $server; /** * The request data key that is used to indicate a spoofed request method. @@ -24,13 +38,28 @@ class Request { const spoofer = '__spoofer'; /** - * Get the URI instance for the current request. + * Create a new Request instance. * - * @return URI + * @param URI $uri + * @param array $post + * @param array $server + * @return void */ - public static function uri() + public function __construct($uri, $post, $server) { - return (is_null(static::$uri)) ? static::$uri = new URI($_SERVER) : static::$uri; + $this->uri = $uri; + $this->post = $post; + $this->server = $server; + } + + /** + * Get the current request's URI. + * + * @return string + */ + public function uri() + { + return $this->uri->get(); } /** @@ -42,9 +71,9 @@ public static function uri() * * @return string */ - public static function method() + public function method() { - return (static::spoofed()) ? $_POST[Request::spoofer] : $_SERVER['REQUEST_METHOD']; + return ($this->spoofed()) ? $this->post[Request::spoofer] : $this->server['REQUEST_METHOD']; } /** @@ -56,9 +85,9 @@ public static function method() * @param mixed $default * @return string */ - public static function server($key = null, $default = null) + public function server($key = null, $default = null) { - return Arr::get($_SERVER, strtoupper($key), $default); + return Arr::get($this->server, strtoupper($key), $default); } /** @@ -66,9 +95,9 @@ public static function server($key = null, $default = null) * * @return bool */ - public static function spoofed() + public function spoofed() { - return is_array($_POST) and array_key_exists(Request::spoofer, $_POST); + return is_array($this->post) and array_key_exists(Request::spoofer, $this->post); } /** @@ -77,19 +106,19 @@ public static function spoofed() * @param mixed $default * @return string */ - public static function ip($default = '0.0.0.0') + public function ip($default = '0.0.0.0') { - if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) + if (isset($this->server['HTTP_X_FORWARDED_FOR'])) { - return $_SERVER['HTTP_X_FORWARDED_FOR']; + return $this->server['HTTP_X_FORWARDED_FOR']; } - elseif (isset($_SERVER['HTTP_CLIENT_IP'])) + elseif (isset($this->server['HTTP_CLIENT_IP'])) { - return $_SERVER['HTTP_CLIENT_IP']; + return $this->server['HTTP_CLIENT_IP']; } - elseif (isset($_SERVER['REMOTE_ADDR'])) + elseif (isset($this->server['REMOTE_ADDR'])) { - return $_SERVER['REMOTE_ADDR']; + return $this->server['REMOTE_ADDR']; } return ($default instanceof Closure) ? call_user_func($default) : $default; @@ -100,9 +129,9 @@ public static function ip($default = '0.0.0.0') * * @return string */ - public static function protocol() + public function protocol() { - return Arr::get($_SERVER, 'SERVER_PROTOCOL', 'HTTP/1.1'); + return Arr::get($this->server, 'SERVER_PROTOCOL', 'HTTP/1.1'); } /** @@ -110,9 +139,9 @@ public static function protocol() * * @return bool */ - public static function secure() + public function secure() { - return isset($_SERVER['HTTPS']) and strtolower($_SERVER['HTTPS']) !== 'off'; + return isset($this->server['HTTPS']) and strtolower($this->server['HTTPS']) !== 'off'; } /** @@ -120,11 +149,11 @@ public static function secure() * * @return bool */ - public static function ajax() + public function ajax() { - if ( ! isset($_SERVER['HTTP_X_REQUESTED_WITH'])) return false; + if ( ! isset($this->server['HTTP_X_REQUESTED_WITH'])) return false; - return strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; + return strtolower($this->server['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; } /** @@ -132,9 +161,9 @@ public static function ajax() * * @return Route */ - public static function route() + public function route() { - return static::$route; + return $this->route; } } \ No newline at end of file diff --git a/laravel/response.php b/laravel/response.php index 7c87e4d3..041356c7 100644 --- a/laravel/response.php +++ b/laravel/response.php @@ -261,7 +261,9 @@ public function headers() $this->header('Content-Type', 'text/html; charset='.Config::$items['application']['encoding']); } - header(Request::protocol().' '.$this->status.' '.$this->statuses[$this->status]); + $request = IoC::container()->core('request'); + + header($request->protocol().' '.$this->status.' '.$this->statuses[$this->status]); foreach ($this->headers as $name => $value) { diff --git a/laravel/routing/router.php b/laravel/routing/router.php index 50f83fb6..be601e47 100644 --- a/laravel/routing/router.php +++ b/laravel/routing/router.php @@ -102,12 +102,13 @@ public function find($name) /** * Search the routes for the route matching a request method and URI. * - * @param string $method - * @param string $uri + * @param Request $request * @return Route */ - public function route($method, $uri) + public function route(Request $request) { + list($method, $uri) = array($request->method(), $request->uri()); + $routes = $this->loader->load($uri); // All route URIs begin with the request method and have a leading diff --git a/laravel/url.php b/laravel/url.php index 60e8d3a9..37fa2080 100644 --- a/laravel/url.php +++ b/laravel/url.php @@ -53,7 +53,7 @@ public static function to_secure($url = '') */ public static function to_asset($url, $https = null) { - if (is_null($https)) $https = Request::secure(); + if (is_null($https)) $https = IoC::container()->core('request')->secure(); $url = static::to($url, $https); diff --git a/laravel/validation/validator.php b/laravel/validation/validator.php index bd808139..0124d75c 100644 --- a/laravel/validation/validator.php +++ b/laravel/validation/validator.php @@ -341,7 +341,7 @@ protected function size($attribute, $value) { return $this->attributes[$attribute]; } - elseif (array_key_exists($attribute, Input::file())) + elseif (array_key_exists($attribute, IoC::container()->core('input')->file())) { return $value['size'] / 1024; } @@ -529,7 +529,9 @@ protected function message($attribute, $rule) // type of attribute being validated, either a file or a string. elseif (in_array($rule, $this->size_rules) and ! $this->has_rule($attribute, $this->numeric_rules)) { - $line = (array_key_exists($attribute, Input::file())) ? "file" : "string"; + $files = IoC::container()->core('input')->file(); + + $line = (array_key_exists($attribute, $files)) ? "file" : "string"; return Lang::line("validation.{$rule}.{$line}")->get($this->language); }