From 6a8aafc259128d31a74a037cf2357bd48b12556e Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 24 Aug 2011 22:51:32 -0500 Subject: [PATCH 1/2] refactoring and adding more dependency injection through ioc container. --- application/config/aliases.php | 1 + application/config/ascii.php | 73 ----------------- application/config/mimes.php | 97 ---------------------- application/filters.php | 2 +- laravel/auth.php | 18 +++++ laravel/cache.php | 6 +- laravel/cache/apc.php | 68 +++++++++++++++- laravel/cache/file.php | 80 +++++++++++++++++- laravel/cache/memcached.php | 25 +++++- laravel/config.php | 59 ++++++-------- laravel/config/aliases.php | 48 ----------- laravel/config/application.php | 98 ---------------------- laravel/config/auth.php | 44 ---------- laravel/config/cache.php | 52 ------------ laravel/config/db.php | 73 ----------------- laravel/config/dependencies.php | 88 ++++++++++++++++++++ laravel/config/error.php | 58 ------------- laravel/config/session.php | 104 ------------------------ laravel/container.php | 94 +++++++++++++++++++++ laravel/db/query.php | 8 +- laravel/download.php | 35 ++++++++ laravel/exception/examiner.php | 2 +- laravel/file.php | 32 +------- laravel/input.php | 34 ++++++++ laravel/ioc.php | 70 ++++++++++++++++ laravel/lang.php | 99 ++++++++++++++++------- laravel/lang/en/pagination.php | 6 ++ laravel/laravel.php | 106 ++++++++---------------- laravel/loader.php | 69 ++-------------- laravel/memcached.php | 55 ------------- laravel/messages.php | 40 ++++++++- laravel/module.php | 84 ------------------- laravel/package.php | 15 ++++ laravel/paginator.php | 139 +++++++++++++++++++++----------- laravel/redirect.php | 78 +++++++++++------- laravel/renderable.php | 12 +++ laravel/request.php | 23 +++++- laravel/response.php | 50 ++++++------ laravel/routing/loader.php | 42 ++++------ laravel/session/driver.php | 2 +- laravel/str.php | 11 --- laravel/url.php | 54 +++++++++---- laravel/validator.php | 23 +++++- laravel/view.php | 119 +++++++++++---------------- modules/.gitignore | 0 public/index.php | 19 ----- 46 files changed, 1039 insertions(+), 1276 deletions(-) delete mode 100644 application/config/ascii.php delete mode 100644 application/config/mimes.php delete mode 100644 laravel/config/aliases.php delete mode 100644 laravel/config/application.php delete mode 100644 laravel/config/auth.php delete mode 100644 laravel/config/cache.php delete mode 100644 laravel/config/db.php create mode 100644 laravel/config/dependencies.php delete mode 100644 laravel/config/error.php delete mode 100644 laravel/config/session.php create mode 100644 laravel/container.php create mode 100644 laravel/download.php create mode 100644 laravel/ioc.php delete mode 100644 laravel/memcached.php delete mode 100644 laravel/module.php create mode 100644 laravel/renderable.php delete mode 100644 modules/.gitignore diff --git a/application/config/aliases.php b/application/config/aliases.php index d18c90a1..c9c547a1 100644 --- a/application/config/aliases.php +++ b/application/config/aliases.php @@ -26,6 +26,7 @@ 'Cookie' => 'Laravel\\Cookie', 'Crypter' => 'Laravel\\Crypter', 'DB' => 'Laravel\\DB', + 'Download' => 'Laravel\\Download', 'Eloquent' => 'Laravel\\DB\\Eloquent\\Model', 'File' => 'Laravel\\File', 'Form' => 'Laravel\\Form', diff --git a/application/config/ascii.php b/application/config/ascii.php deleted file mode 100644 index def811d6..00000000 --- a/application/config/ascii.php +++ /dev/null @@ -1,73 +0,0 @@ - 'ae', - '/œ/' => 'oe', - '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|А/' => 'A', - '/à|á|â|ã|ä|å|ǻ|ā|ă|ą|ǎ|ª|а/' => 'a', - '/Б/' => 'B', - '/б/' => 'b', - '/Ç|Ć|Ĉ|Ċ|Č|Ц/' => 'C', - '/ç|ć|ĉ|ċ|č|ц/' => 'c', - '/Ð|Ď|Đ|Д/' => 'D', - '/ð|ď|đ|д/' => 'd', - '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Е|Ё|Э/' => 'E', - '/è|é|ê|ë|ē|ĕ|ė|ę|ě|е|ё|э/' => 'e', - '/Ф/' => 'F', - '/ƒ|ф/' => 'f', - '/Ĝ|Ğ|Ġ|Ģ|Г/' => 'G', - '/ĝ|ğ|ġ|ģ|г/' => 'g', - '/Ĥ|Ħ|Х/' => 'H', - '/ĥ|ħ|х/' => 'h', - '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|И/' => 'I', - '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|и/' => 'i', - '/Ĵ|Й/' => 'J', - '/ĵ|й/' => 'j', - '/Ķ|К/' => 'K', - '/ķ|к/' => 'k', - '/Ĺ|Ļ|Ľ|Ŀ|Ł|Л/' => 'L', - '/ĺ|ļ|ľ|ŀ|ł|л/' => 'l', - '/М/' => 'M', - '/м/' => 'm', - '/Ñ|Ń|Ņ|Ň|Н/' => 'N', - '/ñ|ń|ņ|ň|ʼn|н/' => 'n', - '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|О/' => 'O', - '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|о/' => 'o', - '/П/' => 'P', - '/п/' => 'p', - '/Ŕ|Ŗ|Ř|Р/' => 'R', - '/ŕ|ŗ|ř|р/' => 'r', - '/Ś|Ŝ|Ş|Š|С/' => 'S', - '/ś|ŝ|ş|š|ſ|с/' => 's', - '/Ţ|Ť|Ŧ|Т/' => 'T', - '/ţ|ť|ŧ|т/' => 't', - '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|У/' => 'U', - '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|у/' => 'u', - '/В/' => 'V', - '/в/' => 'v', - '/Ý|Ÿ|Ŷ|Ы/' => 'Y', - '/ý|ÿ|ŷ|ы/' => 'y', - '/Ŵ/' => 'W', - '/ŵ/' => 'w', - '/Ź|Ż|Ž|З/' => 'Z', - '/ź|ż|ž|з/' => 'z', - '/Æ|Ǽ/' => 'AE', - '/ß/'=> 'ss', - '/IJ/' => 'IJ', - '/ij/' => 'ij', - '/Œ/' => 'OE', - '/Ч/' => 'Ch', - '/ч/' => 'ch', - '/Ю/' => 'Ju', - '/ю/' => 'ju', - '/Я/' => 'Ja', - '/я/' => 'ja', - '/Ш/' => 'Sh', - '/ш/' => 'sh', - '/Щ/' => 'Shch', - '/щ/' => 'shch', - '/Ж/' => 'Zh', - '/ж/' => 'zh', - -); \ No newline at end of file diff --git a/application/config/mimes.php b/application/config/mimes.php deleted file mode 100644 index e2bd4fbb..00000000 --- a/application/config/mimes.php +++ /dev/null @@ -1,97 +0,0 @@ - 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream'), - 'bin' => 'application/macbinary', - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => array('application/octet-stream', 'application/x-msdownload'), - 'class' => 'application/octet-stream', - 'psd' => 'application/x-photoshop', - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => array('application/pdf', 'application/x-download'), - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), - 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'php' => array('application/x-httpd-php', 'text/x-php'), - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => 'application/x-javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => 'audio/x-wav', - 'bmp' => 'image/bmp', - 'gif' => 'image/gif', - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'png' => 'image/png', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', - 'shtml' => 'text/html', - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => array('text/plain', 'text/x-log'), - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'word' => array('application/msword', 'application/octet-stream'), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => array('application/json', 'text/json'), - -); \ No newline at end of file diff --git a/application/filters.php b/application/filters.php index d86f35d7..daf0a6a6 100644 --- a/application/filters.php +++ b/application/filters.php @@ -56,7 +56,7 @@ 'auth' => function() { - return ( ! Auth::check()) ? Redirect::to_login() : null; + return ( ! Auth::make()->check()) ? Redirect::to_login() : null; }, diff --git a/laravel/auth.php b/laravel/auth.php index 86bbcabf..5a271a2a 100644 --- a/laravel/auth.php +++ b/laravel/auth.php @@ -48,6 +48,24 @@ public function __construct(Session\Driver $driver, Hash\Engine $hasher) $this->session = $driver; } + /** + * Create a new Auth class instance. + * + * If no session driver or hasher is provided, the default implementations will be used. + * + * @param Session\Driver $driver + * @param Hash\Engine $hasher + * @return void + */ + public static function make(Session\Driver $driver = null, Hash\Engine $hasher = null) + { + if (is_null($driver)) $driver = Session::driver(); + + if (is_null($hasher)) $hasher = Hasher::make(); + + return new static($driver, $hasher); + } + /** * Determine if the current user of the application is authenticated. * diff --git a/laravel/cache.php b/laravel/cache.php index bc35c634..4b580210 100644 --- a/laravel/cache.php +++ b/laravel/cache.php @@ -35,13 +35,13 @@ public static function driver($driver = null) switch ($driver) { case 'file': - return static::$drivers[$driver] = new Cache\File; + return static::$drivers[$driver] = IoC::container()->resolve('laravel.cache.file'); case 'memcached': - return static::$drivers[$driver] = new Cache\Memcached; + return static::$drivers[$driver] = IoC::container()->resolve('laravel.cache.memcached'); case 'apc': - return static::$drivers[$driver] = new Cache\APC; + return static::$drivers[$driver] = IoC::container()->resolve('laravel.cache.apc'); default: throw new \Exception("Cache driver [$driver] is not supported."); diff --git a/laravel/cache/apc.php b/laravel/cache/apc.php index 0d57f090..08ca44c4 100644 --- a/laravel/cache/apc.php +++ b/laravel/cache/apc.php @@ -2,8 +2,70 @@ use Laravel\Config; +/** + * Wrap the APC functions in a class that can be injected into driver. + * Since the APC functions are global, the driver is untestable without + * injecting a wrapper around them. + */ +class APC_Engine { + + /** + * Get an item from the APC cache. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + return apc_fetch($key); + } + + /** + * Store an item in the APC cache. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $seconds) + { + apc_store($key, $value, $seconds); + } + + /** + * Delete an item from the APC cache. + * + * @param string $key + * @return void + */ + public function forget($key) + { + apc_delete($key); + } + +} + class APC extends Driver { + /** + * The APC Engine instance. + * + * @var APC_Engine + */ + private $apc; + + /** + * Create a new APC cache driver instance. + * + * @param APC_Engine $apc + * @return void + */ + public function __construct(APC_Engine $apc) + { + $this->apc = $apc; + } + /** * Determine if an item exists in the cache. * @@ -28,7 +90,7 @@ public function has($key) */ protected function retrieve($key) { - return ( ! is_null($cache = apc_fetch(Config::get('cache.key').$key))) ? $cache : null; + return ( ! is_null($cache = $this->apc->get(Config::get('cache.key').$key))) ? $cache : null; } /** @@ -46,7 +108,7 @@ protected function retrieve($key) */ public function put($key, $value, $minutes) { - apc_store(Config::get('cache.key').$key, $value, $minutes * 60); + $this->apc->put(Config::get('cache.key').$key, $value, $minutes * 60); } /** @@ -57,7 +119,7 @@ public function put($key, $value, $minutes) */ public function forget($key) { - apc_delete(Config::get('cache.key').$key); + $this->apc->forget(Config::get('cache.key').$key); } } \ No newline at end of file diff --git a/laravel/cache/file.php b/laravel/cache/file.php index e1ac5689..29fe1649 100644 --- a/laravel/cache/file.php +++ b/laravel/cache/file.php @@ -1,7 +1,79 @@ file = $file; + } + /** * Determine if an item exists in the cache. * @@ -26,9 +98,9 @@ public function has($key) */ protected function retrieve($key) { - if ( ! file_exists(CACHE_PATH.$key)) return null; + if ( ! $this->file->exists(CACHE_PATH.$key)) return null; - if (time() >= substr($cache = file_get_contents(CACHE_PATH.$key), 0, 10)) + if (time() >= substr($cache = $this->file->get(CACHE_PATH.$key), 0, 10)) { return $this->forget($key); } @@ -51,7 +123,7 @@ protected function retrieve($key) */ public function put($key, $value, $minutes) { - file_put_contents(CACHE_PATH.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX); + $this->file->put(CACHE_PATH.$key, (time() + ($minutes * 60)).serialize($value)); } /** @@ -62,7 +134,7 @@ public function put($key, $value, $minutes) */ public function forget($key) { - @unlink(CACHE_PATH.$key); + $this->file->forget(CACHE_PATH.$key); } } \ No newline at end of file diff --git a/laravel/cache/memcached.php b/laravel/cache/memcached.php index 37e5c33c..41df1315 100644 --- a/laravel/cache/memcached.php +++ b/laravel/cache/memcached.php @@ -1,10 +1,27 @@ memcache = $memcache; + } + /** * Determine if an item exists in the cache. * @@ -29,7 +46,7 @@ public function has($key) */ protected function retrieve($key) { - return (($cache = Mem::instance()->get(Config::get('cache.key').$key)) !== false) ? $cache : null; + return (($cache = $this->memcache->get(Config::get('cache.key').$key)) !== false) ? $cache : null; } /** @@ -47,7 +64,7 @@ protected function retrieve($key) */ public function put($key, $value, $minutes) { - Mem::instance()->set(Config::get('cache.key').$key, $value, 0, $minutes * 60); + $this->memcache->set(Config::get('cache.key').$key, $value, 0, $minutes * 60); } /** @@ -58,7 +75,7 @@ public function put($key, $value, $minutes) */ public function forget($key) { - Mem::instance()->delete(Config::get('cache.key').$key); + $this->memcache->delete(Config::get('cache.key').$key); } } \ No newline at end of file diff --git a/laravel/config.php b/laravel/config.php index 6e3b43fa..c8874dc8 100644 --- a/laravel/config.php +++ b/laravel/config.php @@ -5,7 +5,7 @@ class Config { /** * All of the loaded configuration items. * - * The configuration arrays are keyed by module and file names. + * The configuration arrays are keyed by file names. * * @var array */ @@ -46,9 +46,6 @@ public static function has($key) * * // Get the SQLite database connection configuration * $sqlite = Config::get('db.connections.sqlite'); - * - * // Get a configuration item from a module configuration file - * $option = Config::get('module::file.option'); * * * @param string $key @@ -57,16 +54,16 @@ public static function has($key) */ public static function get($key, $default = null) { - list($module, $file, $key) = static::parse($key); + list($file, $key) = static::parse($key); - if ( ! static::load($module, $file)) + if ( ! static::load($file)) { return is_callable($default) ? call_user_func($default) : $default; } - if (is_null($key)) return static::$items[$module][$file]; + if (is_null($key)) return static::$items[$file]; - return Arr::get(static::$items[$module][$file], $key, $default); + return Arr::get(static::$items[$file], $key, $default); } /** @@ -92,31 +89,26 @@ public static function get($key, $default = null) */ public static function set($key, $value) { - list($module, $file, $key) = static::parse($key); + list($file, $key) = static::parse($key); - if ( ! static::load($module, $file)) - { - throw new \Exception("Error setting configuration option. Configuration file [$file] is not defined."); - } + static::load($file); - Arr::set(static::$items[$module][$file], $key, $value); + (is_null($key)) ? Arr::set(static::$items, $file, $value) : Arr::set(static::$items[$file], $key, $value); } /** - * Parse a configuration key and return its module, file, and key segments. + * Parse a configuration key and return its file and key segments. * - * Modular configuration keys follow a {module}::{file}.{key} convention. + * Configuration keys follow a {file}.{key} convention. * * @param string $key * @return array */ private static function parse($key) { - list($module, $key) = Module::parse($key); - $segments = explode('.', $key); - return array($module, $segments[0], (count($segments) > 1) ? implode('.', array_slice($segments, 1)) : null); + return array($segments[0], (count($segments) > 1) ? implode('.', array_slice($segments, 1)) : null); } /** @@ -125,23 +117,25 @@ private static function parse($key) * If the configuration file has already been loaded, it will not be loaded again. * * @param string $file - * @param string $module * @return bool */ - private static function load($module, $file) + private static function load($file) { - if (isset(static::$items[$module]) and array_key_exists($file, static::$items[$module])) return true; + if (isset(static::$items[$file])) return true; $config = array(); - foreach (static::paths($module, $file) as $directory) + foreach (static::paths() as $directory) { $config = (file_exists($path = $directory.$file.EXT)) ? array_merge($config, require $path) : $config; } - if (count($config) > 0) static::$items[$module][$file] = $config; + if (count($config) > 0) + { + static::$items[$file] = $config; + } - return isset(static::$items[$module][$file]); + return isset(static::$items[$file]); } /** @@ -150,23 +144,18 @@ private static function load($module, $file) * The paths returned by this method paths will be searched by the load method when merging * configuration files, meaning the configuration files will cascade in this order. * - * By default, the base configuration directory will be searched first, followed by the configuration - * directory for the active module. Next, any environment specific configuration directories - * will be searched. + * The system configuration directory will be searched first, followed by the application + * directory, and finally the environment directory. * - * @param string $module - * @param string $file * @return array */ - private static function paths($module, $file) + private static function paths() { - $module = str_replace('.', '/', $module); - - $paths = array(CONFIG_PATH, Module::path($module).'config/'); + $paths = array(SYS_CONFIG_PATH, CONFIG_PATH); if (isset($_SERVER['LARAVEL_ENV'])) { - $paths[] = Module::path($module).'/config/'.$_SERVER['LARAVEL_ENV'].'/'; + $paths[] = CONFIG_PATH.$_SERVER['LARAVEL_ENV'].'/'; } return $paths; diff --git a/laravel/config/aliases.php b/laravel/config/aliases.php deleted file mode 100644 index d18c90a1..00000000 --- a/laravel/config/aliases.php +++ /dev/null @@ -1,48 +0,0 @@ - 'Laravel\\Asset', - 'Auth' => 'Laravel\\Auth', - 'Benchmark' => 'Laravel\\Benchmark', - 'Cache' => 'Laravel\\Cache', - 'Config' => 'Laravel\\Config', - 'Cookie' => 'Laravel\\Cookie', - 'Crypter' => 'Laravel\\Crypter', - 'DB' => 'Laravel\\DB', - 'Eloquent' => 'Laravel\\DB\\Eloquent\\Model', - 'File' => 'Laravel\\File', - 'Form' => 'Laravel\\Form', - 'Hasher' => 'Laravel\\Hasher', - 'HTML' => 'Laravel\\HTML', - 'Inflector' => 'Laravel\\Inflector', - 'Input' => 'Laravel\\Input', - 'Lang' => 'Laravel\\Lang', - 'Loader' => 'Laravel\\Loader', - 'Package' => 'Laravel\\Package', - 'URL' => 'Laravel\\URL', - 'Redirect' => 'Laravel\\Redirect', - 'Request' => 'Laravel\\Request', - 'Response' => 'Laravel\\Response', - 'Session' => 'Laravel\\Session', - 'Str' => 'Laravel\\Str', - 'Validator' => 'Laravel\\Validator', - 'View' => 'Laravel\\View', - -); \ No newline at end of file diff --git a/laravel/config/application.php b/laravel/config/application.php deleted file mode 100644 index 2c0028a4..00000000 --- a/laravel/config/application.php +++ /dev/null @@ -1,98 +0,0 @@ - 'http://localhost', - - /* - |-------------------------------------------------------------------------- - | Application Index - |-------------------------------------------------------------------------- - | - | If you are including the "index.php" in your URLs, you can ignore this. - | - | However, if you are using mod_rewrite or something similar to get - | cleaner URLs, set this option to an empty string. - | - */ - - 'index' => 'index.php', - - /* - |-------------------------------------------------------------------------- - | Application Language - |-------------------------------------------------------------------------- - | - | The default language of your application. This language will be used by - | Lang library as the default language when doing string localization. - | - */ - - 'language' => 'en', - - /* - |-------------------------------------------------------------------------- - | Application Character Encoding - |-------------------------------------------------------------------------- - | - | The default character encoding used by your application. This is the - | character encoding that will be used by the Str, Text, and Form classes. - | - */ - - 'encoding' => 'UTF-8', - - /* - |-------------------------------------------------------------------------- - | Application Timezone - |-------------------------------------------------------------------------- - | - | The default timezone of your application. This timezone will be used when - | Laravel needs a date, such as when writing to a log file. - | - */ - - 'timezone' => 'UTC', - - /* - |-------------------------------------------------------------------------- - | Auto-Loaded Packages - |-------------------------------------------------------------------------- - | - | The packages that should be auto-loaded each time Laravel handles - | a request. These should generally be packages that you use on almost - | every request to your application. - | - | Each package specified here will be bootstrapped and can be conveniently - | used by your application's routes, models, and libraries. - | - | Note: The package names in this array should correspond to a package - | directory in application/packages. - | - */ - - 'packages' => array(), - - /* - |-------------------------------------------------------------------------- - | Application Key - |-------------------------------------------------------------------------- - | - | Your application key should be a 32 character string that is totally - | random and secret. This key is used by the encryption class to generate - | secure, encrypted strings. - | - */ - - 'key' => '', - -); \ No newline at end of file diff --git a/laravel/config/auth.php b/laravel/config/auth.php deleted file mode 100644 index 7c3ee766..00000000 --- a/laravel/config/auth.php +++ /dev/null @@ -1,44 +0,0 @@ - function($id) - { - return User::find($id); - }, - - /* - |-------------------------------------------------------------------------- - | Retrieve Users By Username - |-------------------------------------------------------------------------- - | - | This method is called by the Auth::check() method when attempting to - | retrieve a user by their username, such as when checking credentials - | received from a login form. - | - | You are free to change this method for your application however you wish. - | - | Note: This method must return an object that has "id" and "password" - | properties. The type of object returned does not matter. - | - */ - - 'by_username' => function($username) - { - return User::where_email($username)->first(); - }, - -); \ No newline at end of file diff --git a/laravel/config/cache.php b/laravel/config/cache.php deleted file mode 100644 index 7c6bf32e..00000000 --- a/laravel/config/cache.php +++ /dev/null @@ -1,52 +0,0 @@ - 'file', - - /* - |-------------------------------------------------------------------------- - | Cache Key - |-------------------------------------------------------------------------- - | - | This key will be prepended to item keys stored using Memcached and APC to - | prevent collisions with other applications on the server. - | - */ - - 'key' => 'laravel', - - /* - |-------------------------------------------------------------------------- - | Memcached Servers - |-------------------------------------------------------------------------- - | - | The Memcached servers used by your application. - | - | Memcached is a free and open source, high-performance, distributed memory - | object caching system, generic in nature, but intended for use in speeding - | up dynamic web applications by alleviating database load. - | - | For more information about Memcached, check out: http://memcached.org - | - */ - - 'servers' => array( - array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - ), - -); \ No newline at end of file diff --git a/laravel/config/db.php b/laravel/config/db.php deleted file mode 100644 index d8109118..00000000 --- a/laravel/config/db.php +++ /dev/null @@ -1,73 +0,0 @@ - 'sqlite', - - /* - |-------------------------------------------------------------------------- - | Database Connections - |-------------------------------------------------------------------------- - | - | All of the database connections used by your application. - | - | Supported Drivers: 'mysql', 'pgsql', 'sqlite'. - | - | Note: When using the SQLite driver, the path and "sqlite" extention will - | be added automatically. You only need to specify the database name. - | - | Using a driver that isn't supported? You can still establish a PDO - | connection. Simply specify a driver and DSN option: - | - | 'odbc' => array( - | 'driver' => 'odbc', - | 'dsn' => 'your-dsn', - | 'username' => 'username', - | 'password' => 'password', - | ) - | - | Note: When using an unsupported driver, Eloquent and the fluent query - | builder may not work as expected. - | - */ - - 'connections' => array( - - 'sqlite' => array( - 'driver' => 'sqlite', - 'database' => 'application', - ), - - 'mysql' => array( - 'driver' => 'mysql', - 'host' => 'localhost', - 'database' => 'database', - 'username' => 'root', - 'password' => 'password', - 'charset' => 'utf8', - ), - - 'pgsql' => array( - 'driver' => 'pgsql', - 'host' => 'localhost', - 'database' => 'database', - 'username' => 'root', - 'password' => 'password', - 'charset' => 'utf8', - ), - - ), - -); \ No newline at end of file diff --git a/laravel/config/dependencies.php b/laravel/config/dependencies.php new file mode 100644 index 00000000..9f7abcd1 --- /dev/null +++ b/laravel/config/dependencies.php @@ -0,0 +1,88 @@ + array('resolver' => function($container) + { + return new Cache\File($container->resolve('laravel.cache.file_engine')); + }), + + /* + |-------------------------------------------------------------------------- + | Laravel File Cache Driver Engine + |-------------------------------------------------------------------------- + */ + + 'laravel.cache.file_engine' => array('resolver' => function($container) + { + return new Cache\File_Engine; + }), + + /* + |-------------------------------------------------------------------------- + | Laravel APC Cache Driver + |-------------------------------------------------------------------------- + */ + + 'laravel.cache.apc' => array('resolver' => function($container) + { + return new Cache\APC($container->resolve('laravel.cache.apc_engine')); + }), + + /* + |-------------------------------------------------------------------------- + | Laravel APC Cache Driver Engine + |-------------------------------------------------------------------------- + */ + + 'laravel.cache.apc_engine' => array('resolver' => function($container) + { + return new Cache\APC_Engine; + }), + + /* + |-------------------------------------------------------------------------- + | Laravel Memcached Cache Driver + |-------------------------------------------------------------------------- + */ + + 'laravel.cache.memcached' => array('resolver' => function($container) + { + return new Cache\Memcached($container->resolve('laravel.memcache')); + }), + + /* + |-------------------------------------------------------------------------- + | Memcache Connection + |-------------------------------------------------------------------------- + */ + + 'laravel.memcache' => array('singleton' => true, 'resolver' => function($container) + { + if ( ! class_exists('Memcache')) + { + throw new \Exception('Attempting to use Memcached, but the Memcache PHP extension is not installed on this server.'); + } + + $memcache = new \Memcache; + + foreach (Config::get('cache.servers') as $server) + { + $memcache->addServer($server['host'], $server['port'], true, $server['weight']); + } + + if ($memcache->getVersion() === false) + { + throw new \Exception('Memcached is configured. However, no connections could be made. Please verify your memcached configuration.'); + } + + return $memcache; + }), + +); \ No newline at end of file diff --git a/laravel/config/error.php b/laravel/config/error.php deleted file mode 100644 index 885e95c1..00000000 --- a/laravel/config/error.php +++ /dev/null @@ -1,58 +0,0 @@ - true, - - /* - |-------------------------------------------------------------------------- - | Error Logging - |-------------------------------------------------------------------------- - | - | Error Logging will use the "logger" function defined below to log error - | messages, which gives you complete freedom to determine how error - | messages are logged. Enjoy the flexibility. - | - */ - - 'log' => false, - - /* - |-------------------------------------------------------------------------- - | Error Logger - |-------------------------------------------------------------------------- - | - | Because of the various ways of managing error logging, you get complete - | flexibility to manage error logging as you see fit. - | - | This function will be called when an error occurs in your application. - | You can log the error however you like. - | - | The error "severity" passed to the method is a human-readable severity - | level such as "Parsing Error" or "Fatal Error". - | - | A simple logging system has been setup for you. By default, all errors - | will be logged to the storage/log.txt file. - | - */ - - 'logger' => function($severity, $message, $trace) - { - File::append(STORAGE_PATH.'log.txt', date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL); - }, - -); \ No newline at end of file diff --git a/laravel/config/session.php b/laravel/config/session.php deleted file mode 100644 index 12ccb6ff..00000000 --- a/laravel/config/session.php +++ /dev/null @@ -1,104 +0,0 @@ - '', - - /* - |-------------------------------------------------------------------------- - | Session Database - |-------------------------------------------------------------------------- - | - | The database table on which the session should be stored. - | - | This option is only relevant when using the "db" session driver. - | - */ - - 'table' => 'sessions', - - /* - |-------------------------------------------------------------------------- - | Session Lifetime - |-------------------------------------------------------------------------- - | - | The number of minutes a session can be idle before expiring. - | - */ - - 'lifetime' => 60, - - /* - |-------------------------------------------------------------------------- - | Session Expiration On Close - |-------------------------------------------------------------------------- - | - | Determines if the session should expire when the user's web browser closes. - | - */ - - 'expire_on_close' => false, - - /* - |-------------------------------------------------------------------------- - | Session Cookie Path - |-------------------------------------------------------------------------- - | - | The path for which the session cookie is available. - | - */ - - 'path' => '/', - - /* - |-------------------------------------------------------------------------- - | Session Cookie Domain - |-------------------------------------------------------------------------- - | - | The domain for which the session cookie is available. - | - */ - - 'domain' => null, - - /* - |-------------------------------------------------------------------------- - | Session Cookie HTTPS - |-------------------------------------------------------------------------- - | - | Determines if the session cookie should only be transported over HTTPS. - | - */ - - 'https' => false, - - /* - |-------------------------------------------------------------------------- - | HTTP Only Session Cookie - |-------------------------------------------------------------------------- - | - | Determines if the session cookie should only be accessible over HTTP. - | - | Note: The intention of the "HTTP Only" option is to keep cookies from - | being accessed by client-side scripting languages. However, this - | setting should not be viewed as providing total XSS protection. - | - */ - - 'http_only' => false, - -); \ No newline at end of file diff --git a/laravel/container.php b/laravel/container.php new file mode 100644 index 00000000..a3ffeaab --- /dev/null +++ b/laravel/container.php @@ -0,0 +1,94 @@ + + * // Register a simple dependency + * $container->register('name', function() { return 'Fred'; }); + * + * // Register a dependency as a singleton + * $container->register('name', function() { return new Name; }, true); + * + * + * @param string $name + * @param Closure $resolver + * @return void + */ + public function register($name, $resolver, $singleton = false) + { + $this->resolvers[$name] = compact('resolver', 'singleton'); + } + + /** + * Register a dependency as a singleton. + * + * @param string $name + * @param Closure $resolver + * @return void + */ + public function singleton($name, $resolver) + { + $this->register($name, $resolver, true); + } + + /** + * Register an instance as a singleton. + * + * @param string $name + * @param mixed $instance + * @return void + */ + public function instance($name, $instance) + { + $this->singletons[$name] = $instance; + } + + /** + * Resolve a dependency. + * + * The dependency's resolver will be called and its result will be returned. + * + * + * // Resolver the "name" dependency + * $name = $container->resolve('name'); + * + * + * @param string $name + * @return mixed + */ + public function resolve($name) + { + if (array_key_exists($name, $this->singletons)) return $this->singletons[$name]; + + if ( ! array_key_exists($name, $this->resolvers)) + { + throw new \Exception("Error resolving [$name]. No resolver has been registered in the container."); + } + + $object = call_user_func($this->resolvers[$name]['resolver'], $this); + + if ($this->resolvers[$name]['singleton']) $this->singletons[$name] = $object; + + return $object; + } + +} \ No newline at end of file diff --git a/laravel/db/query.php b/laravel/db/query.php index 75638cee..7f4cb1c0 100644 --- a/laravel/db/query.php +++ b/laravel/db/query.php @@ -2,6 +2,7 @@ use Laravel\Str; use Laravel\Config; +use Laravel\Request; use Laravel\Paginator; class Query { @@ -569,15 +570,18 @@ private function aggregate($aggregator, $column) * * @param int $per_page * @param array $columns + * @param int $page * @return Paginator */ public function paginate($per_page, $columns = array('*')) { $total = $this->count(); - $results = $this->skip((Paginator::page($total, $per_page) - 1) * $per_page)->take($per_page)->get($columns); + $paginator = new Paginator(Request::active()->input->get('page', 1), $total, $per_page); - return Paginator::make($results, $total, $per_page); + $paginator->results = $this->skip(($paginator->page - 1) * $per_page)->take($per_page)->get($columns); + + return $paginator; } /** diff --git a/laravel/download.php b/laravel/download.php new file mode 100644 index 00000000..1d042a5b --- /dev/null +++ b/laravel/download.php @@ -0,0 +1,35 @@ + + * // Return a download response for a given file + * return new Download('path/to/image.jpg'); + * + * // Return a download response for a given file and assign a name + * return new Download('path/to/image.jpg', 'you.jpg'); + * + * + * @param string $path + * @param string $name + */ + public function __construct($path, $name = null) + { + if (is_null($name)) $name = basename($path); + + parent::__construct(file_get_contents($path)); + + $this->header('Content-Description', 'File Transfer'); + $this->header('Content-Type', File::mime(File::extension($path))); + $this->header('Content-Disposition', 'attachment; filename="'.$name.'"'); + $this->header('Content-Transfer-Encoding', 'binary'); + $this->header('Expires', 0); + $this->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); + $this->header('Pragma', 'public'); + $this->header('Content-Length', filesize($path)); + } + +} \ No newline at end of file diff --git a/laravel/exception/examiner.php b/laravel/exception/examiner.php index f996eb17..14f49b31 100644 --- a/laravel/exception/examiner.php +++ b/laravel/exception/examiner.php @@ -68,7 +68,7 @@ public function severity() */ public function message() { - $file = str_replace(array(ACTIVE_MODULE_PATH, SYS_PATH), array('MODULE_PATH/', 'SYS_PATH/'), $this->exception->getFile()); + $file = str_replace(array(APP_PATH, SYS_PATH), array('APP_PATH/', 'SYS_PATH/'), $this->exception->getFile()); return rtrim($this->exception->getMessage(), '.').' in '.$file.' on line '.$this->exception->getLine().'.'; } diff --git a/laravel/file.php b/laravel/file.php index c3a9d630..0349f3cf 100644 --- a/laravel/file.php +++ b/laravel/file.php @@ -71,7 +71,9 @@ public static function snapshot($path, $line, $padding = 5) array_unshift($file, ''); - $length = ($line - ($start = $line - $padding)) + $padding + 1; + $start = $line - $padding; + + $length = ($line - $start) + $padding + 1; return array_slice($file, ($start > 0) ? $start : 0, ($length > 0) ? $length : 0, true); } @@ -128,32 +130,4 @@ public static function is($extension, $path) return (is_array($mimes[$extension])) ? in_array($mime, $mimes[$extension]) : $mime === $mimes[$extension]; } - /** - * Create a response that will force a file to be downloaded. - * - * @param string $path - * @param string $name - * @return Response - */ - public static function download($path, $name = null) - { - if (is_null($name)) - { - $name = basename($path); - } - - $response = Response::make(static::get($path)); - - $response->header('Content-Description', 'File Transfer'); - $response->header('Content-Type', static::mime(static::extension($path))); - $response->header('Content-Disposition', 'attachment; filename="'.$name.'"'); - $response->header('Content-Transfer-Encoding', 'binary'); - $response->header('Expires', 0); - $response->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); - $response->header('Pragma', 'public'); - $response->header('Content-Length', filesize($path)); - - return $response; - } - } \ No newline at end of file diff --git a/laravel/input.php b/laravel/input.php index 06fc7822..c74a969e 100644 --- a/laravel/input.php +++ b/laravel/input.php @@ -105,6 +105,16 @@ public function has($key) /** * Get an item from the input data. * + * This method should be used for all request methods (GET, POST, PUT, and DELETE). + * + * + * // Get the "name" item from the input data + * $name = Request::active()->input->get('name'); + * + * // Get the "name" item and return "Fred" if it doesn't exist. + * $name = Request::active()->input->get('name', 'Fred'); + * + * * @param string $key * @param mixed $default * @return string @@ -128,6 +138,13 @@ public function had($key) /** * Get input data from the previous request. * + * If no session driver is provided, the default driver will be used. + * + * + * // Get the "name" item from the old input data + * $name = Request::active()->input->old('name'); + * + * * @param string $key * @param mixed $default * @param Session\Driver $driver @@ -143,6 +160,16 @@ public function old($key = null, $default = null, Session\Driver $driver = null) /** * Get an item from the uploaded file data. * + * "Dot" syntax may be used to get a specific item from the file array. + * + * + * // Get the array of information regarding a given file + * $file = Request::active()->input->file('picture'); + * + * // Get the size of a given file + * $file = Request::active()->input->file('picture.size'); + * + * * @param string $key * @param mixed $default * @return array @@ -155,6 +182,8 @@ public function file($key = null, $default = null) /** * Move an uploaded file to permanent storage. * + * This method is simply a convenient wrapper around move_uploaded_file. + * * @param string $key * @param string $path * @return bool @@ -166,6 +195,11 @@ public function upload($key, $path) /** * Magic Method for retrieving items from the request input. + * + * + * // Retrieve the "name" item from the input data + * $name = Request::active()->input->name; + * */ public function __get($key) { diff --git a/laravel/ioc.php b/laravel/ioc.php new file mode 100644 index 00000000..551579d4 --- /dev/null +++ b/laravel/ioc.php @@ -0,0 +1,70 @@ + $value) + { + $container->register($key, $value['resolver'], (isset($value['singleton'])) ? $value['singleton'] : false); + } + } + + /** + * Get a container instance. + * + * If no container name is specified, the default container will be returned. + * + * + * // Get the default container instance + * $container = IoC::container(); + * + * // Get a specific container instance + * $container = IoC::container('models'); + * + * + * @param string $container + * @return Container + */ + public static function container($container = 'default') + { + if ( ! array_key_exists($container, static::$containers)) + { + static::$containers[$container] = new Container; + } + + return static::$containers[$container]; + } + + /** + * Magic Method for passing methods to the default container. + * + * + * // Resolve an object from the default container + * $user = IoC::resolve('user'); + * + * // Equivalent method of resolving using the container method + * $user = IoC::container()->resolve('user'); + * + */ + public static function __callStatic($method, $parameters) + { + return call_user_func_array(array(static::container(), $method), $parameters); + } + +} \ No newline at end of file diff --git a/laravel/lang.php b/laravel/lang.php index a8088406..a1f244db 100644 --- a/laravel/lang.php +++ b/laravel/lang.php @@ -18,6 +18,13 @@ class Lang { */ public $key; + /** + * The language the line should be returned in. + * + * @var string + */ + public $language; + /** * The place-holder replacements. * @@ -28,22 +35,30 @@ class Lang { /** * Create a new Lang instance. * - * Language lines are retrieved using "dot" notation. So, asking for the - * "messages.required" language line would return the "required" line - * from the "messages" language file. - * * @param string $key * @param array $replacements * @return void */ - public function __construct($key, $replacements = array()) + private function __construct($key, $replacements = array()) { $this->key = $key; $this->replacements = $replacements; + $this->language = Config::get('application.language'); } /** - * Create a Lang instance for a language line. + * Create a new Lang instance. + * + * Language lines are retrieved using "dot" notation. So, asking for the "messages.required" langauge + * line would return the "required" line from the "messages" language file. + * + * + * // Get the "required" line from the "validation" language file + * $line = Lang::line('validation.required')->get(); + * + * // Specify a replacement for a language line + * $line = Lang::line('welcome.message', array('name' => 'Fred'))->get(); + * * * @param string $key * @param array $replacements @@ -55,24 +70,47 @@ public static function line($key, $replacements = array()) } /** - * Get the language line. + * Set the language the line should be returned in. + * + * The language specified in this method should correspond to a language directory in your application. + * + * + * // Get a "fr" language line + * $line = Lang::line('validation.required')->in('fr')->get(); + * + * + * @param string $language + * @return Lang + */ + public function in($language) + { + $this->language = $language; + return $this; + } + + /** + * Get the language line. + * + * A default value may also be specified, which will be returned in the language line doesn't exist. + * + * + * // Get a validation line and return a default value if the line doesn't exist + * $line = Lang::line('welcome.message')->get('Hello!'); + * * * @param string $language - * @param mixed $default * @return string */ - public function get($language = null, $default = null) + public function get($default = null) { - if (is_null($language)) $language = Config::get('application.language'); + list($file, $line) = $this->parse($this->key); - list($module, $file, $line) = $this->parse($this->key, $language); - - if ( ! $this->load($module, $file, $language)) + if ( ! $this->load($file)) { return is_callable($default) ? call_user_func($default) : $default; } - $line = Arr::get(static::$lines[$module][$language.$file], $line, $default); + $line = Arr::get(static::$lines[$this->language.$file], $line, $default); foreach ($this->replacements as $key => $value) { @@ -85,17 +123,16 @@ public function get($language = null, $default = null) /** * Parse a language key. * + * Language keys follow a {file}.{key} convention. + * * @param string $key - * @param string $language * @return array */ - private function parse($key, $language) + private function parse($key) { - list($module, $key) = Module::parse($key); - if (count($segments = explode('.', $key)) > 1) { - return array($module, $segments[0], implode('.', array_slice($segments, 1))); + return array($segments[0], implode('.', array_slice($segments, 1))); } throw new \Exception("Invalid language line [$key]. A specific line must be specified."); @@ -104,25 +141,31 @@ private function parse($key, $language) /** * Load a language file. * - * @param string $module + * If the language file has already been loaded, it will not be loaded again. + * * @param string $file - * @param string $language * @return bool */ - private function load($module, $file, $language) + private function load($file) { - if (isset(static::$lines[$module][$language.$file])) return; + if (isset(static::$lines[$this->language.$file])) return; - $lang = array(); + $language = array(); - foreach (array(LANG_PATH, Module::path($module).'lang/') as $directory) + foreach (array(SYS_LANG_PATH, LANG_PATH) as $directory) { - $lang = (file_exists($path = $directory.$language.'/'.$file.EXT)) ? array_merge($lang, require $path) : $lang; + if (file_exists($path = $directory.$this->language.'/'.$file.EXT)) + { + $language = array_merge($language, require $path); + } } - if (count($lang) > 0) static::$lines[$module][$language.$file] = $lang; + if (count($language) > 0) + { + static::$lines[$this->language.$file] = $language; + } - return isset(static::$lines[$module][$language.$file]); + return isset(static::$lines[$this->language.$file]); } /** diff --git a/laravel/lang/en/pagination.php b/laravel/lang/en/pagination.php index 7c5790bb..eef78c03 100644 --- a/laravel/lang/en/pagination.php +++ b/laravel/lang/en/pagination.php @@ -2,6 +2,12 @@ return array( + /* + |-------------------------------------------------------------------------- + | Pagination "Next" and "Previous" Language + |-------------------------------------------------------------------------- + */ + 'previous' => '« Previous', 'next' => 'Next »', diff --git a/laravel/laravel.php b/laravel/laravel.php index 966434c1..8e9d27a1 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -10,61 +10,45 @@ // -------------------------------------------------------------- define('APP_PATH', realpath($application).'/'); define('BASE_PATH', realpath(str_replace('laravel', '', $laravel)).'/'); -define('MODULE_PATH', realpath($modules).'/'); define('PACKAGE_PATH', realpath($packages).'/'); define('PUBLIC_PATH', realpath($public).'/'); define('STORAGE_PATH', realpath($storage).'/'); define('SYS_PATH', realpath($laravel).'/'); -unset($laravel, $application, $config, $modules, $packages, $public, $storage); +unset($laravel, $application, $config, $packages, $public, $storage); // -------------------------------------------------------------- // Define various other framework paths. // -------------------------------------------------------------- -define('CACHE_PATH', STORAGE_PATH.'cache/'); -define('CONFIG_PATH', APP_PATH.'config/'); -define('DATABASE_PATH', STORAGE_PATH.'db/'); -define('LANG_PATH', SYS_PATH.'lang/'); -define('SCRIPT_PATH', PUBLIC_PATH.'js/'); -define('SESSION_PATH', STORAGE_PATH.'sessions/'); -define('STYLE_PATH', PUBLIC_PATH.'css/'); - -// -------------------------------------------------------------- -// Define the default module and path. -// -------------------------------------------------------------- -define('DEFAULT_MODULE', 'application'); - -define('DEFAULT_MODULE_PATH', APP_PATH); +define('CACHE_PATH', STORAGE_PATH.'cache/'); +define('CONFIG_PATH', APP_PATH.'config/'); +define('DATABASE_PATH', STORAGE_PATH.'db/'); +define('LANG_PATH', APP_PATH.'lang/'); +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.'lang/'); +define('VIEW_PATH', APP_PATH.'views/'); // -------------------------------------------------------------- // Load the classes used by the auto-loader. // -------------------------------------------------------------- require SYS_PATH.'loader'.EXT; require SYS_PATH.'config'.EXT; -require SYS_PATH.'module'.EXT; require SYS_PATH.'arr'.EXT; -// -------------------------------------------------------------- -// Register the active modules. -// -------------------------------------------------------------- -Module::$modules = array_merge(array(DEFAULT_MODULE => DEFAULT_MODULE_PATH), $active); - -unset($active); - // -------------------------------------------------------------- // Register the auto-loader. // -------------------------------------------------------------- -Loader::bootstrap(array( - APP_PATH.'libraries/', - APP_PATH.'models/', -)); +Loader::bootstrap(Config::get('aliases'), array(APP_PATH.'libraries/', APP_PATH.'models/')); spl_autoload_register(array('Laravel\\Loader', 'load')); // -------------------------------------------------------------- -// Set the default timezone. +// Bootstrap the IoC container. // -------------------------------------------------------------- -date_default_timezone_set(Config::get('application.timezone')); +IoC::bootstrap(Config::get('dependencies')); // -------------------------------------------------------------- // Set the error reporting and display levels. @@ -73,28 +57,6 @@ ini_set('display_errors', 'Off'); -// -------------------------------------------------------------- -// Initialize the request instance for the request. -// -------------------------------------------------------------- -$request = new Request($_SERVER); - -// -------------------------------------------------------------- -// Hydrate the input for the current request. -// -------------------------------------------------------------- -$request->input = new Input($request, $_GET, $_POST, $_COOKIE, $_FILES); - -// -------------------------------------------------------------- -// Determine the module that should handle the request. -// -------------------------------------------------------------- -$segments = explode('/', $request->uri()); - -define('ACTIVE_MODULE', (array_key_exists($segments[0], Module::$modules)) ? $segments[0] : DEFAULT_MODULE); - -// -------------------------------------------------------------- -// Determine the path to the root of the active module. -// -------------------------------------------------------------- -define('ACTIVE_MODULE_PATH', Module::path(ACTIVE_MODULE)); - // -------------------------------------------------------------- // Register the error / exception handlers. // -------------------------------------------------------------- @@ -131,14 +93,20 @@ } }); +// -------------------------------------------------------------- +// Set the default timezone. +// -------------------------------------------------------------- +date_default_timezone_set(Config::get('application.timezone')); + // -------------------------------------------------------------- // Load the session. // -------------------------------------------------------------- if (Config::get('session.driver') != '') Session::driver()->start(Cookie::get('laravel_session')); // -------------------------------------------------------------- -// Load all of the core routing classes. +// Load all of the core routing and response classes. // -------------------------------------------------------------- +require SYS_PATH.'renderable'.EXT; require SYS_PATH.'response'.EXT; require SYS_PATH.'routing/route'.EXT; require SYS_PATH.'routing/router'.EXT; @@ -156,34 +124,31 @@ } // -------------------------------------------------------------- -// Register the filters for the default module. +// Initialize the request instance for the request. // -------------------------------------------------------------- -Routing\Filter::register(require DEFAULT_MODULE_PATH.'filters'.EXT); +$request = new Request($_SERVER); // -------------------------------------------------------------- -// Register the filters for the active module. +// Hydrate the input for the current request. // -------------------------------------------------------------- -if (file_exists(ACTIVE_MODULE_PATH.'filters'.EXT)) -{ - Routing\Filter::register(require ACTIVE_MODULE_PATH.'filters'.EXT); -} +$request->input = new Input($request, $_GET, $_POST, $_COOKIE, $_FILES); + +// -------------------------------------------------------------- +// Register the filters for the default module. +// -------------------------------------------------------------- +Routing\Filter::register(require APP_PATH.'filters'.EXT); // -------------------------------------------------------------- // Call the "before" filter for the application and module. // -------------------------------------------------------------- -foreach (array('before', ACTIVE_MODULE.'::before') as $filter) -{ - $response = Routing\Filter::call($filter, array($request->method(), $request->uri()), true); - - if ( ! is_null($response)) break; -} +$response = Routing\Filter::call('before', array($request->method(), $request->uri()), true); // -------------------------------------------------------------- // Route the request and get the response from the route. // -------------------------------------------------------------- if (is_null($response)) { - $loader = new Routing\Loader(ACTIVE_MODULE_PATH); + $loader = new Routing\Loader(APP_PATH); $route = Routing\Router::make($request, $loader)->route(); @@ -195,15 +160,12 @@ // -------------------------------------------------------------- // Call the "after" filter for the application and module. // -------------------------------------------------------------- -foreach (array(ACTIVE_MODULE.'::after', 'after') as $filter) -{ - Routing\Filter::call($filter, array($response, $request->method(), $request->uri())); -} +Routing\Filter::call('after', array($response, $request->method(), $request->uri())); // -------------------------------------------------------------- // Stringify the response. // -------------------------------------------------------------- -$response->content = ($response->content instanceof View) ? $response->content->get() : (string) $response->content; +$response->content = $response->render(); // -------------------------------------------------------------- // Close the session. diff --git a/laravel/loader.php b/laravel/loader.php index ef48984a..6d0c9e30 100644 --- a/laravel/loader.php +++ b/laravel/loader.php @@ -16,22 +16,16 @@ class Loader { */ public static $aliases = array(); - /** - * All of the active modules. - * - * @var array - */ - public static $modules = array(); - /** * Bootstrap the auto-loader. * + * @param array $aliases * @param array $paths * @return void */ - public static function bootstrap($paths = array()) + public static function bootstrap($aliases, $paths) { - static::$aliases = Config::get('aliases'); + static::$aliases = $aliases; foreach ($paths as $path) { static::register_path($path); } } @@ -49,67 +43,20 @@ public static function load($class) { $file = strtolower(str_replace('\\', '/', $class)); - if (array_key_exists($class, static::$aliases)) return class_alias(static::$aliases[$class], $class); + if (array_key_exists($class, static::$aliases)) + { + return class_alias(static::$aliases[$class], $class); + } - (static::load_from_registered($file)) or static::load_from_module($file); - } - - /** - * Load a class that is stored in the registered directories. - * - * @param string $file - * @return bool - */ - private static function load_from_registered($file) - { foreach (static::$paths as $directory) { if (file_exists($path = $directory.$file.EXT)) { require $path; - return true; + return; } } - - return false; - } - - /** - * Search the active modules for a given file. - * - * @param string $file - * @return void - */ - private static function load_from_module($file) - { - if (is_null($module = static::module_path($file))) return; - - // Slice the module name off of the filename. Even though module libraries - // and models are namespaced under the module, there will obviously not be - // a folder matching that namespace in the libraries or models directory. - $file = substr($file, strlen($module)); - - foreach (array(MODULE_PATH.$module.'/models', MODULE_PATH.$module.'/libraries') as $directory) - { - if (file_exists($path = $directory.'/'.$file.EXT)) return require $path; - } - } - - /** - * Search the module paths for a match on the file. - * - * The file namespace should correspond to a directory within the module directory. - * - * @param string $file - * @return string - */ - private static function module_path($file) - { - foreach (Module::$modules as $key => $module) - { - if (strpos($file, $module) === 0) return $module; - } } /** diff --git a/laravel/memcached.php b/laravel/memcached.php deleted file mode 100644 index 115d89cd..00000000 --- a/laravel/memcached.php +++ /dev/null @@ -1,55 +0,0 @@ -addServer($server['host'], $server['port'], true, $server['weight']); - } - - if ($memcache->getVersion() === false) - { - throw new \Exception('Memcached is configured. However, no connections could be made. Please verify your memcached configuration.'); - } - - return $memcache; - } - -} \ No newline at end of file diff --git a/laravel/messages.php b/laravel/messages.php index e8645d27..a919440a 100644 --- a/laravel/messages.php +++ b/laravel/messages.php @@ -12,6 +12,8 @@ class Messages { /** * Create a new Messages instance. * + * The Messages class provides a convenient wrapper around an array of generic messages. + * * @return void */ public function __construct($messages = array()) @@ -24,6 +26,11 @@ public function __construct($messages = array()) * * Duplicate messages will not be added. * + * + * // Add an error message for the "email" key + * $messages->add('email', 'The e-mail address is invalid.'); + * + * * @param string $key * @param string $message * @return void @@ -39,6 +46,11 @@ public function add($key, $message) /** * Determine if messages exist for a given key. * + * + * // Determine if there are any messages for the "email" key + * $has = $messages->has('email'); + * + * * @param string $key * @return bool */ @@ -50,6 +62,16 @@ public function has($key) /** * Get the first message for a given key. * + * Optionally, a format may be specified for the returned message. + * + * + * // Get the first message for the "email" key + * $message = $messages->first('email'); + * + * // Get the first message for the "email" key wrapped in

tags + * $message = $messages->first('email', '

:message

'); + *
+ * * @param string $key * @param string $format * @return string @@ -62,7 +84,13 @@ public function first($key, $format = ':message') /** * Get all of the messages for a key. * - * If no key is specified, all of the messages will be returned. + * + * // Get all of the messages for the "email" key + * $message = $messages->get('email'); + * + * // Get all of the messages for the "email" key wrapped in

tags + * $message = $messages->get('email', '

:message

'); + *
* * @param string $key * @param string $format @@ -76,7 +104,15 @@ public function get($key = null, $format = ':message') } /** - * Get all of the messages. + * Get all of the messages for every key. + * + * + * // Get all of the messages for every key + * $message = $messages->all(); + * + * // Get all of the messages for every key wrapped in

tags + * $message = $messages->all('

:message

'); + *
* * @param string $format * @return array diff --git a/laravel/module.php b/laravel/module.php deleted file mode 100644 index 1a9609ee..00000000 --- a/laravel/module.php +++ /dev/null @@ -1,84 +0,0 @@ - - * // Returns array('admin', 'test.example') - * Module::parse('admin::test.example'); - * - * // Returns array('application', 'test.example') - * Module::parse('test.example'); - * - * - * @param string $key - * @return array - */ - public static function parse($key) - { - $module = (strpos($key, '::') !== false) ? substr($key, 0, strpos($key, ':')) : DEFAULT_MODULE; - - $module = str_replace('.', '/', $module); - - if ($module !== DEFAULT_MODULE) $key = substr($key, strpos($key, ':') + 2); - - return array($module, $key); - } - - /** - * Get the path for a given module. - * - * Once the path has been determined, it will be cached by the class for quick access. - * - * @param string $module - * @return string - */ - public static function path($module) - { - if (array_key_exists($module, static::$paths)) return static::$paths[$module]; - - if (array_key_exists($module, static::$modules)) - { - return (static::$modules[$module] == DEFAULT_MODULE_PATH) ? static::$modules[$module] : MODULE_PATH.static::$modules[$module].'/'; - } - elseif (in_array($module, static::$modules)) - { - return static::$paths[$module] = MODULE_PATH.$module.'/'; - } - } - - /** - * Get an array of paths to all of the modules. - * - * @return array - */ - public static function paths() - { - return array_map(function($module) { return Laravel\Module::path($module); }, static::$modules); - } - -} \ No newline at end of file diff --git a/laravel/package.php b/laravel/package.php index 289af68a..82e2f5fc 100644 --- a/laravel/package.php +++ b/laravel/package.php @@ -12,6 +12,16 @@ class Package { /** * Load a package or set of packages. * + * The package name should correspond to a package directory for your application. + * + * + * // Load the "swift-mailer" package + * Package::load('swift-mailer'); + * + * // Load the "swift-mailer" and "facebook" package + * Package::load(array('swift-mailer', 'facebook')); + * + * * @param string|array $packages * @return void */ @@ -31,6 +41,11 @@ public static function load($packages) /** * Determine if a given package has been loaded. * + * + * // Determine if the "swift-mailer" package has been loaded + * $loaded = Package::loaded('swift-mailer'); + * + * * @param string $package * @return bool */ diff --git a/laravel/paginator.php b/laravel/paginator.php index c3b1b44b..a369285d 100644 --- a/laravel/paginator.php +++ b/laravel/paginator.php @@ -37,6 +37,20 @@ class Paginator { */ public $last_page; + /** + * The number of links that should be adjacent to the current page. + * + * @var int + */ + public $adjacent = 3; + + /** + * Indicates if the generated links should use HTTPS. + * + * @var bool + */ + public $secure; + /** * The language that should be used when generating page links. * @@ -54,54 +68,48 @@ class Paginator { /** * Create a new Paginator instance. * - * @param array $results + * In general, the Paginator will be instantiated through the database query. However, you are free + * to instantiate a paginator for an arbitrary array if you wish. + * + * + * // Create a Paginator for the first page of 10 total results and 2 items per page + * $paginator = new Paginator(1, 10, 2); + * + * * @param int $page * @param int $total * @param int $per_page - * @param int $last_page * @return void */ - public function __construct($results, $page, $total, $per_page, $last_page) + public function __construct($page, $total, $per_page) { - $this->last_page = $last_page; + $this->last_page = ceil($total / $per_page); $this->per_page = $per_page; - $this->results = $results; $this->total = $total; - $this->page = $page; + + // Determine if the current request is using HTTPS. If it is, we will use HTTPS when + // generating the links unless otherwise specified by the secure() method. + $this->secure = Request::active()->is_secure(); + + // The page method will validate the given page number and adjust it if necessary. + // For example, when the given page number is greater than the last page or less + // than zero, the page number will be adjusted. + $this->page = $this->adjust($page); } /** - * Create a new Paginator instance. - * - * @param array $results - * @param int $total - * @param int $per_page - * @return Paginator - */ - public static function make($results, $total, $per_page) - { - return new static($results, static::page($total, $per_page), $total, $per_page, ceil($total / $per_page)); - } - - /** - * Get the current page from the request query string. + * Check a given page number for validity and adjust it if necessary. * * 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 less than one, one will be returned. * If the current page is greater than the last page, the last page will be returned. * - * @param int $total - * @param int $per_page + * @param int $page * @return int */ - public static function page($total, $per_page) + private function adjust($page) { - $page = Input::get('page', 1); - - if (is_numeric($page) and $page > $last_page = ceil($total / $per_page)) - { - return ($last_page > 0) ? $last_page : 1; - } + if (is_numeric($page) and $page > $this->last_page) return ($this->last_page > 0) ? $this->last_page : 1; return ($page < 1 or filter_var($page, FILTER_VALIDATE_INT) === false) ? 1 : $page; } @@ -109,43 +117,56 @@ public static function page($total, $per_page) /** * Create the HTML pagination links. * - * @param int $adjacent + * If there are enough pages, an intelligent, sliding list of links will be created. + * Otherwise, a simple list of page number links will be created. + * * @return string */ - public function links($adjacent = 3) + public function links() { if ($this->last_page <= 1) return ''; // The hard-coded "7" is to account for all of the constant elements in a sliding range. // Namely: The the current page, the two ellipses, the two beginning pages, and the two ending pages. - $numbers = ($this->last_page < 7 + ($adjacent * 2)) ? $this->range(1, $this->last_page) : $this->slider($adjacent); + $numbers = ($this->last_page < 7 + ($this->adjacent * 2)) ? $this->range(1, $this->last_page) : $this->slider(); return ''; } /** - * Build sliding list of HTML numeric page links. + * Build a sliding list of HTML numeric page links. + * + * If the current page is close to the beginning of the pages, all of the beginning links will be + * shown and the ending links will be abbreviated. + * + * If the current page is in the middle of the pages, the beginning and ending links will be abbreviated. + * + * If the current page is close to the end of the list of pages, all of the ending links will be + * shown and the beginning links will be abbreviated. * - * @param int $adjacent * @return string */ - private function slider($adjacent) + private function slider() { - if ($this->page <= $adjacent * 2) + if ($this->page <= $this->adjacent * 2) { - return $this->range(1, 2 + ($adjacent * 2)).$this->ending(); + return $this->range(1, 2 + ($this->adjacent * 2)).$this->ending(); } - elseif ($this->page >= $this->last_page - ($adjacent * 2)) + elseif ($this->page >= $this->last_page - ($this->adjacent * 2)) { - return $this->beginning().$this->range($this->last_page - 2 - ($adjacent * 2), $this->last_page); + return $this->beginning().$this->range($this->last_page - 2 - ($this->adjacent * 2), $this->last_page); + } + else + { + return $this->beginning().$this->range($this->page - $this->adjacent, $this->page + $this->adjacent).$this->ending(); } - - return $this->beginning().$this->range($this->page - $adjacent, $this->page + $adjacent).$this->ending(); } /** * Generate the "previous" HTML link. * + * The "previous" line from the "pagination" language file will be used to create the link text. + * * @return string */ public function previous() @@ -163,6 +184,8 @@ public function previous() /** * Generate the "next" HTML link. * + * The "next" line from the "pagination" language file will be used to create the link text. + * * @return string */ public function next() @@ -198,9 +221,9 @@ private function ending() } /** - * Build a range of page links. + * Build a range of page links. * - * For the current page, an HTML span element will be generated instead of a link. + * A span element will be generated for the current page. * * @param int $start * @param int $end @@ -212,7 +235,14 @@ private function range($start, $end) for ($i = $start; $i <= $end; $i++) { - $pages .= ($this->page == $i) ? HTML::span($i, array('class' => 'current')).' ' : $this->link($i, $i, null).' '; + if ($this->page == $i) + { + $pages .= HTML::span($i, array('class' => 'current')).' '; + } + else + { + $pages .= $this->link($i, $i, null).' '; + } } return $pages; @@ -235,12 +265,26 @@ private function link($page, $text, $class) $append .= '&'.$key.'='.$value; } - return HTML::link(Request::uri().'?page='.$page.$append, $text, compact('class'), Request::is_secure()); + return HTML::link(Request::active()->uri().'?page='.$page.$append, $text, compact('class'), $this->secure); + } + + /** + * Force the paginator to return links that use HTTPS. + * + * @param bool $secure + * @return Paginator + */ + public function secure($secure = true) + { + $this->secure = true; + return $this; } /** * Set the language that should be used when generating page links. * + * The language specified here should correspond to a language directory for your application. + * * @param string $language * @return Paginator */ @@ -253,6 +297,11 @@ public function lang($language) /** * Set the items that should be appended to the link query strings. * + * + * // Set the "sort" query string item on the links that will be generated + * echo $paginator->append(array('sort' => 'desc'))->links(); + * + * * @param array $values * @return Paginator */ diff --git a/laravel/redirect.php b/laravel/redirect.php index ba351aff..61e3b472 100644 --- a/laravel/redirect.php +++ b/laravel/redirect.php @@ -1,28 +1,21 @@ response = $response; - } +class Redirect extends Response { /** * Create a redirect response. * + * + * // Create a redirect for the "user/profile" URI + * return Redirect::to('user/profile'); + * + * // Create a redirect using the 301 status code + * return Redirect::to('user/profile', 301); + * + * // Create a redirect using the "refresh" method + * return Redirect::to('user/profile', 302, 'refresh'); + * + * * @param string $url * @param int $status * @param string $method @@ -33,14 +26,24 @@ public static function to($url, $status = 302, $method = 'location', $https = fa { $url = URL::to($url, $https); - return ($method == 'refresh') - ? new static(Response::make('', $status)->header('Refresh', '0;url='.$url)) - : new static(Response::make('', $status)->header('Location', $url)); + if ($method == 'location') + { + return static::make('', $status)->header('Refresh', '0;url='.$url); + } + else + { + return static::make('', $status)->header('Location', $url); + } } /** * Create a redirect response to a HTTPS URL. * + * + * // Create a HTTPS redirect to the "user/profile" URI + * return Redirect::to_secure('user/profile'); + * + * * @param string $url * @param int $status * @param string $method @@ -54,24 +57,37 @@ public static function to_secure($url, $status = 302, $method = 'location') /** * Add an item to the session flash data. * - * @param string $key - * @param mixed $value + * This is useful for passing status messages or other temporary data to the next request. + * + * + * // Flash a status message to the session on a redirect + * return Redirect::to('user/profile')->with('status', 'Welcome Back!'); + * + * + * @param string $key + * @param mixed $value + * @param Session\Driver $driver * @return Response */ - public function with($key, $value) + public function with($key, $value, Session\Driver $driver) { - if (Config::get('session.driver') == '') - { - throw new \Exception("Attempting to flash data to the session, but no session driver has been specified."); - } + if (is_null($driver)) $driver = Session::driver(); - Session::flash($key, $value); + $driver->flash($key, $value); return $this; } /** - * Magic Method to handle redirecting to routes. + * Magic Method to handle redirecting to named routes. + * + * + * // Create a redirect to the "profile" route + * return Redirect::to_profile(); + * + * // Create a redirect to the "profile" route using HTTPS + * return Redirect::to_secure_profile(); + * */ public static function __callStatic($method, $parameters) { diff --git a/laravel/renderable.php b/laravel/renderable.php new file mode 100644 index 00000000..5a095d9e --- /dev/null +++ b/laravel/renderable.php @@ -0,0 +1,12 @@ +uri = $this->remove_from_uri($uri, array(parse_url(Config::get('application.url'), PHP_URL_PATH), '/index.php')); } @@ -180,7 +180,12 @@ public function is_ajax() } /** - * Determine if the route handling the request is a given name. + * Determine if the route handling the request has a given name. + * + * + * // Determine if the route handling the request is named "profile" + * $profile = Request::active()->route_is('profile'); + * * * @param string $name * @return bool @@ -193,7 +198,12 @@ public function route_is($name) } /** - * Magic Method to handle dynamic static methods. + * Magic Method to handle dynamic method calls to determine the route handling the request. + * + * + * // Determine if the route handling the request is named "profile" + * $profile = Request::active()->route_is_profile(); + * */ public function __call($method, $parameters) { @@ -205,6 +215,11 @@ public function __call($method, $parameters) /** * Magic Method for dynamically retrieving properties of the request instance. + * + * + * // Get all of the input for the request + * $input = Request::active()->input; + * */ public function __get($key) { diff --git a/laravel/response.php b/laravel/response.php index 8bb63e79..8bedb1dd 100644 --- a/laravel/response.php +++ b/laravel/response.php @@ -1,6 +1,6 @@ content = $content; - $this->status = $status; + $this->status = $status; } /** @@ -104,6 +104,15 @@ public static function make($content, $status = 200) /** * Factory for creating new error response instances. * + * The response status code will be set using the specified code. + * + * Note: The specified error code should correspond to a view in your views/error directory. + * + * + * // Return a 404 error response + * return Response::error('404'); + * + * * @param int $code * @param array $data * @return Response @@ -121,11 +130,19 @@ public static function error($code, $data = array()) */ public static function prepare($response) { - if ($response instanceof Redirect) $response = $response->response; - return ( ! $response instanceof Response) ? new static($response) : $response; } + /** + * Get the evaluated string contents of the response. + * + * @return string + */ + public function render() + { + return ($this->content instanceof Renderable) ? $this->content->render() : (string) $this->content; + } + /** * Send the response to the browser. * @@ -140,7 +157,7 @@ public function send() if ( ! headers_sent()) $this->send_headers(); - echo (string) $this->content; + echo $this->render(); } /** @@ -163,6 +180,11 @@ public function send_headers() /** * Add a header to the response. * + * + * // Add a "location" header to a response + * $response->header('Location', 'http://google.com'); + * + * * @param string $name * @param string $value * @return Response @@ -173,22 +195,4 @@ public function header($name, $value) return $this; } - /** - * Determine if the response is a redirect. - * - * @return bool - */ - public function is_redirect() - { - return $this->status == 301 or $this->status == 302; - } - - /** - * Get the parsed content of the Response. - */ - public function __toString() - { - return (string) $this->content; - } - } \ No newline at end of file diff --git a/laravel/routing/loader.php b/laravel/routing/loader.php index db36b08b..b7c376a2 100644 --- a/laravel/routing/loader.php +++ b/laravel/routing/loader.php @@ -60,13 +60,6 @@ private function load_nested_routes($segments) array_push($segments, substr($segment, 0, strpos($segment, '.'))); } - // Since it is no part of the route directory structure, shift the module name off of the - // beginning of the array so we can locate the appropriate route file. - if (count($segments) > 0 and ACTIVE_MODULE !== DEFAULT_MODULE) - { - array_shift($segments); - } - // Work backwards through the URI segments until we find the deepest possible // matching route directory. Once we find it, we will return those routes. foreach (array_reverse($segments, true) as $key => $value) @@ -89,33 +82,30 @@ private function load_nested_routes($segments) * @param bool $reload * @return array */ - public static function all($reload = false) + public static function all($path = APP_PATH, $reload = false) { if ( ! is_null(static::$routes) and ! $reload) return static::$routes; $routes = array(); - foreach (Module::paths() as $path) + if (file_exists($path.'routes'.EXT)) { - if (file_exists($path.'routes'.EXT)) + $routes = array_merge($routes, require $path.'routes'.EXT); + } + + if (is_dir($path.'routes')) + { + // Since route files can be nested deep within the route directory, we need to + // recursively spin through the directory to find every file. + $directoryIterator = new \RecursiveDirectoryIterator($path.'routes'); + + $recursiveIterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST); + + foreach ($recursiveIterator as $file) { - $routes = array_merge($routes, require $path.'routes'.EXT); - } - - if (is_dir($path.'routes')) - { - // Since route files can be nested deep within the route directory, we need to - // recursively spin through the directory to find every file. - $directoryIterator = new \RecursiveDirectoryIterator($path.'routes'); - - $recursiveIterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST); - - foreach ($recursiveIterator as $file) + if (filetype($file) === 'file' and strpos($file, EXT) !== false) { - if (filetype($file) === 'file' and strpos($file, EXT) !== false) - { - $routes = array_merge($routes, require $file); - } + $routes = array_merge($routes, require $file); } } } diff --git a/laravel/session/driver.php b/laravel/session/driver.php index 6d51b347..928523ee 100644 --- a/laravel/session/driver.php +++ b/laravel/session/driver.php @@ -233,7 +233,7 @@ protected function write_cookie() { $minutes = (Config::get('session.expire_on_close')) ? 0 : Config::get('session.lifetime'); - Cookie::put('laravel_session', static::$session['id'], $minutes, Config::get('session.path'), Config::get('session.domain'), Config::get('session.https'), Config::get('session.http_only')); + Cookie::put('laravel_session', static::$session['id'], $minutes, Config::get('session.path'), Config::get('session.domain'), Config::get('session.https'), Config::get('http_only')); } } diff --git a/laravel/str.php b/laravel/str.php index 6f99a2f1..22ccd414 100644 --- a/laravel/str.php +++ b/laravel/str.php @@ -2,17 +2,6 @@ class Str { - /** - * Convert HTML characters to entities. - * - * @param string $value - * @return string - */ - public static function entities($value) - { - return htmlentities($value, ENT_QUOTES, Config::get('application.encoding'), false); - } - /** * Convert a string to lowercase. * diff --git a/laravel/url.php b/laravel/url.php index bb338c4f..50fde8ad 100644 --- a/laravel/url.php +++ b/laravel/url.php @@ -9,20 +9,14 @@ class URL { * * @param string $url * @param bool $https - * @param bool $asset * @return string */ - public static function to($url = '', $https = false, $asset = false) + public static function to($url = '', $https = false) { if (filter_var($url, FILTER_VALIDATE_URL) !== false) return $url; $base = Config::get('application.url').'/'.Config::get('application.index'); - if ($asset and Config::get('application.index') !== '') - { - $base = str_replace('/'.Config::get('application.index'), '', $base); - } - if ($https and strpos($base, 'http://') === 0) { $base = 'https://'.substr($base, 7); @@ -43,23 +37,31 @@ public static function to_secure($url = '') } /** - * Generate an application URL to an asset. The index file - * will not be added to the URL. + * Generate an application URL to an asset. + * + * The index file will not be added to asset URLs. * * @param string $url * @return string */ public static function to_asset($url) { - return static::to($url, Request::is_secure(), true); + return str_replace('index.php/', '', static::to($url, Request::active()->is_secure())); } /** * Generate a URL from a route name. * - * For routes that have wildcard parameters, an array may be passed as the - * second parameter to the method. The values of this array will be used - * to fill the wildcard segments of the route URI. + * For routes that have wildcard parameters, an array may be passed as the second parameter to the method. + * The values of this array will be used to fill the wildcard segments of the route URI. + * + * + * // Generate a URL for the "profile" named route + * $url = URL::to_route('profile'); + * + * // Generate a URL for the "profile" named route with parameters. + * $url = URL::to_route('profile', array('fred')); + * * * @param string $name * @param array $parameters @@ -90,6 +92,11 @@ public static function to_route($name, $parameters = array(), $https = false) /** * Generate a HTTPS URL from a route name. * + * + * // Generate a HTTPS URL for the "profile" named route + * $url = URL::to_secure_route('profile'); + * + * * @param string $name * @param array $parameters * @return string @@ -102,6 +109,14 @@ public static function to_secure_route($name, $parameters = array()) /** * Generate a URL friendly "slug". * + * + * // Returns "my-first-post" + * $slug = URL::slug('My First Post!!'); + * + * // Returns "my_first_post" + * $slug = URL::slug('My First Post!!', '_'); + * + * * @param string $title * @param string $separator * @return string @@ -120,7 +135,18 @@ public static function slug($title, $separator = '-') } /** - * Magic Method for dynamically creating route URLs. + * Magic Method for dynamically creating URLs to named routes. + * + * + * // Generate a URL for the "profile" named route + * $url = URL::to_profile(); + * + * // Generate a URL for the "profile" named route using HTTPS + * $url = URL::to_secure_profile(); + * + * // Generate a URL for the "profile" named route with parameters. + * $url = URL::to_profile(array('fred')); + * */ public static function __callStatic($method, $parameters) { diff --git a/laravel/validator.php b/laravel/validator.php index ffcd7cd4..7314d2f9 100644 --- a/laravel/validator.php +++ b/laravel/validator.php @@ -37,6 +37,13 @@ class Validator { */ public $language; + /** + * The database connection that should be used by the validator. + * + * @var DB\Connection + */ + public $connection; + /** * The size related validation rules. * @@ -302,7 +309,9 @@ protected function validate_unique($attribute, $parameters) { if ( ! isset($parameters[1])) $parameters[1] = $attribute; - return DB::connection()->table($parameters[0])->where($parameters[1], '=', $this->attributes[$attribute])->count() == 0; + if (is_null($this->connection)) $this->connection = DB::connection(); + + return $this->connection->table($parameters[0])->where($parameters[1], '=', $this->attributes[$attribute])->count() == 0; } /** @@ -514,4 +523,16 @@ public function lang($language) return $this; } + /** + * Set the database connection that should be used by the validator. + * + * @param DB\Connection $connection + * @return Validator + */ + public function connection(DB\Connection $connection) + { + $this->connection = $connection; + return $this; + } + } \ No newline at end of file diff --git a/laravel/view.php b/laravel/view.php index 2ca13aa0..a63483f7 100644 --- a/laravel/view.php +++ b/laravel/view.php @@ -1,6 +1,6 @@ view = $view; $this->data = $data; - - list($this->module, $this->path, $this->view) = static::parse($view); - - $this->compose(); + $this->path = str_replace('.', '/', $view); } /** @@ -68,44 +66,25 @@ public static function make($view, $data = array()) /** * Create a new view instance from a view name. * - * The view names for the active module will be searched first, followed by the view names - * for the default module. Finally, the names for all modules will be searched. - * * @param string $name * @param array $data * @return View */ protected static function of($name, $data = array()) { - foreach (array_unique(array_merge(array(ACTIVE_MODULE, DEFAULT_MODULE), Module::$modules)) as $module) - { - static::load_composers($module); + if (is_null(static::$composers)) static::$composers = require APP_PATH.'composers'.EXT; - foreach (static::$composers[$module] as $key => $value) + foreach (static::$composers as $key => $value) + { + if ($name === $value or (isset($value['name']) and $name === $value['name'])) { - if ($name === $value or (isset($value['name']) and $name === $value['name'])) - { - return new static($key, $data); - } + return new static($key, $data); } } throw new \Exception("Named view [$name] is not defined."); } - /** - * Parse a view identifier and get the module, path, and view name. - * - * @param string $view - * @return array - */ - protected static function parse($view) - { - list($module, $view) = Module::parse($view); - - return array($module, Module::path($module).'views/', $view); - } - /** * Call the composer for the view instance. * @@ -113,11 +92,11 @@ protected static function parse($view) */ protected function compose() { - static::load_composers($this->module); + if (is_null(static::$composers)) static::$composers = require APP_PATH.'composers'.EXT; - if (isset(static::$composers[$this->module][$this->view])) + if (isset(static::$composers[$this->view])) { - foreach ((array) static::$composers[$this->module][$this->view] as $key => $value) + foreach ((array) static::$composers[$this->view] as $key => $value) { if (is_callable($value)) return call_user_func($value, $this); } @@ -125,42 +104,27 @@ protected function compose() } /** - * Load the view composers for a given module. - * - * @param string $module - * @return void - */ - protected static function load_composers($module) - { - if (isset(static::$composers[$module])) return; - - $composers = Module::path($module).'composers'.EXT; - - static::$composers[$module] = (file_exists($composers)) ? require $composers : array(); - } - - /** - * Get the parsed content of the view. + * Get the evaluated string content of the view. * * @return string */ - public function get() + public function render() { - $view = str_replace('.', '/', $this->view); + $this->compose(); - if ( ! file_exists($this->path.$view.EXT)) + if ( ! file_exists(VIEW_PATH.$this->path.EXT)) { - Exception\Handler::make(new Exception("View [$view] does not exist."))->handle(); + Exception\Handler::make(new Exception('View ['.$this->path.'] does not exist.'))->handle(); } - foreach ($this->data as &$data) + foreach ($this->data as &$data) { - if ($data instanceof View or $data instanceof Response) $data = (string) $data; + if ($data instanceof Renderable) $data = $data->render(); } ob_start() and extract($this->data, EXTR_SKIP); - try { include $this->path.$view.EXT; } catch (\Exception $e) { Exception\Handler::make($e)->handle(); } + try { include VIEW_PATH.$this->path.EXT; } catch (\Exception $e) { Exception\Handler::make($e)->handle(); } return ob_get_clean(); } @@ -168,6 +132,14 @@ public function get() /** * Add a view instance to the view data. * + * + * // Bind the view "partial/login" to the view + * View::make('home')->partial('login', 'partial/login'); + * + * // Equivalent binding using the "bind" method + * View::make('home')->bind('login', View::make('partials/login')); + * + * * @param string $key * @param string $view * @param array $data @@ -181,6 +153,13 @@ public function partial($key, $view, $data = array()) /** * Add a key / value pair to the view data. * + * Bound data will be available to the view as variables. + * + * + * // Bind a "name" value to the view + * View::make('home')->bind('name', 'Fred'); + * + * * @param string $key * @param mixed $value * @return View @@ -193,6 +172,14 @@ public function bind($key, $value) /** * Magic Method for handling the dynamic creation of named views. + * + * + * // Create an instance of the "login" named view + * $view = View::of_login(); + * + * // Create an instance of the "login" named view and bind data to the view + * $view = View::of_login(array('name' => 'Fred')); + * */ public static function __callStatic($method, $parameters) { @@ -234,12 +221,4 @@ public function __unset($key) unset($this->data[$key]); } - /** - * Get the parsed content of the View. - */ - public function __toString() - { - return $this->get(); - } - } \ No newline at end of file diff --git a/modules/.gitignore b/modules/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/public/index.php b/public/index.php index 4b616b5e..e0868e92 100644 --- a/public/index.php +++ b/public/index.php @@ -8,23 +8,6 @@ * @link http://laravel.com */ -/* -|-------------------------------------------------------------------------- -| Active Modules -|-------------------------------------------------------------------------- -| -| Modules are a convenient way to organize your application into logical -| components. Each module may have its own libraries, models, routes, -| views, language files, and configuration. -| -| Here you may specify which modules are active for your application. -| This simply gives Laravel an easy way to know which directories to -| check when auto-loading your classes, routes, and views. -| -*/ - -$active = array(); - /* |-------------------------------------------------------------------------- | Installation Paths @@ -44,8 +27,6 @@ $packages = '../packages'; -$modules = '../modules'; - $storage = '../storage'; $public = __DIR__; From 82045e20d98956a4ed6602a191e3530f2a3dce3f Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 24 Aug 2011 23:44:50 -0500 Subject: [PATCH 2/2] more refactoring for dependency injection. --- laravel/config/dependencies.php | 17 ++++++++++--- laravel/container.php | 16 +++++++++++++ laravel/form.php | 18 +++++++------- laravel/html.php | 16 +++++++++---- laravel/inflector.php | 16 +++++++++++++ laravel/laravel.php | 26 +++++++++++--------- laravel/redirect.php | 8 ++++--- laravel/renderable.php | 12 ---------- laravel/response.php | 11 +++++++++ laravel/url.php | 42 ++++++++++++++++----------------- 10 files changed, 119 insertions(+), 63 deletions(-) delete mode 100644 laravel/renderable.php diff --git a/laravel/config/dependencies.php b/laravel/config/dependencies.php index 9f7abcd1..42d68654 100644 --- a/laravel/config/dependencies.php +++ b/laravel/config/dependencies.php @@ -2,6 +2,17 @@ return array( + /* + |-------------------------------------------------------------------------- + | Laravel URL Writer + |-------------------------------------------------------------------------- + */ + + 'laravel.url' => array('singleton' => true, 'resolver' => function() + { + return new URL; + }), + /* |-------------------------------------------------------------------------- | Laravel File Cache Driver @@ -19,7 +30,7 @@ |-------------------------------------------------------------------------- */ - 'laravel.cache.file_engine' => array('resolver' => function($container) + 'laravel.cache.file_engine' => array('resolver' => function() { return new Cache\File_Engine; }), @@ -41,7 +52,7 @@ |-------------------------------------------------------------------------- */ - 'laravel.cache.apc_engine' => array('resolver' => function($container) + 'laravel.cache.apc_engine' => array('resolver' => function() { return new Cache\APC_Engine; }), @@ -63,7 +74,7 @@ |-------------------------------------------------------------------------- */ - 'laravel.memcache' => array('singleton' => true, 'resolver' => function($container) + 'laravel.memcache' => array('singleton' => true, 'resolver' => function() { if ( ! class_exists('Memcache')) { diff --git a/laravel/container.php b/laravel/container.php index a3ffeaab..2f76eb28 100644 --- a/laravel/container.php +++ b/laravel/container.php @@ -41,6 +41,14 @@ public function register($name, $resolver, $singleton = false) /** * Register a dependency as a singleton. * + * 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 as a singleton + * $container->singleton('user', function() { return new User; }) + * + * * @param string $name * @param Closure $resolver * @return void @@ -53,6 +61,14 @@ public function singleton($name, $resolver) /** * Register an instance as a singleton. * + * This method allows you to register an already existing object instance with the + * container as a singleton instance. + * + * + * // Register an object instance as a singleton in the container + * $container->instance('user', new User); + * + * * @param string $name * @param mixed $instance * @return void diff --git a/laravel/form.php b/laravel/form.php index 63a25f55..03732c59 100644 --- a/laravel/form.php +++ b/laravel/form.php @@ -30,10 +30,10 @@ class Form { * 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. * - * @param string $action - * @param string $method - * @param array $attributes - * @param bool $https + * @param string $action + * @param string $method + * @param array $attributes + * @param bool $https * @return string */ public static function open($action = null, $method = 'POST', $attributes = array(), $https = false) @@ -69,13 +69,15 @@ private static function method($method) * * If no action is specified, the current request URI will be used. * - * @param string $action - * @param bool $https + * @param string $action + * @param bool $https * @return string */ private static function action($action, $https) { - return HTML::entities(URL::to(((is_null($action)) ? Request::uri() : $action), $https)); + $url = IoC::container()->resolve('laravel.url'); + + return HTML::entities($url->to(((is_null($action)) ? IoC::resolve('laravel.request')->uri() : $action), $https)); } /** @@ -447,7 +449,7 @@ public static function reset($value, $attributes = array()) */ public static function image($url, $name = null, $attributes = array()) { - $attributes['src'] = URL::to_asset($url); + $attributes['src'] = IoC::container()->resolve('laravel.url')->to_asset($url); return static::input('image', $name, null, $attributes); } diff --git a/laravel/html.php b/laravel/html.php index f4a51977..c665bc1a 100644 --- a/laravel/html.php +++ b/laravel/html.php @@ -24,7 +24,9 @@ public static function entities($value) */ public static function script($url, $attributes = array()) { - return ''.PHP_EOL; + $url = IoC::container()->resolve('laravel.url'); + + return ''.PHP_EOL; } /** @@ -40,7 +42,9 @@ public static function style($url, $attributes = array()) $attributes = array_merge($attributes, array('rel' => 'stylesheet', 'type' => 'text/css')); - return ''.PHP_EOL; + $url = IoC::container()->resolve('laravel.url'); + + return ''.PHP_EOL; } /** @@ -67,7 +71,9 @@ public static function span($value, $attributes = array()) */ public static function link($url, $title, $attributes = array(), $https = false, $asset = false) { - return ''.static::entities($title).''; + $url = IoC::container()->resolve('laravel.url'); + + return ''.static::entities($title).''; } /** @@ -130,7 +136,7 @@ public static function link_to_secure_asset($url, $title, $attributes = array()) */ public static function link_to_route($name, $title, $parameters = array(), $attributes = array(), $https = false) { - return static::link(URL::to_route($name, $parameters, $https), $title, $attributes); + return static::link(IoC::resolve('laravel.url')->to_route($name, $parameters, $https), $title, $attributes); } /** @@ -189,7 +195,7 @@ public static function image($url, $alt = '', $attributes = array()) { $attributes['alt'] = static::entities($alt); - return ''; + return ''; } /** diff --git a/laravel/inflector.php b/laravel/inflector.php index 231a09a7..8fdb977e 100644 --- a/laravel/inflector.php +++ b/laravel/inflector.php @@ -136,6 +136,14 @@ public static function plural_if($value, $count) /** * Convert a word to its plural form. * + * + * // Returns "friends" + * Inflector::plural('friend'); + * + * // Returns "children" + * Inflector::plural('child'); + * + * * @param string $value * @return string */ @@ -147,6 +155,14 @@ public static function plural($value) /** * Convert a word to its singular form. * + * + * // Returns "friend" + * Inflector::singular('friends'); + * + * // Returns "child" + * Inflector::singular('children'); + * + * * @param string $value * @return string */ diff --git a/laravel/laravel.php b/laravel/laravel.php index 8e9d27a1..40e79b61 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -45,11 +45,6 @@ spl_autoload_register(array('Laravel\\Loader', 'load')); -// -------------------------------------------------------------- -// Bootstrap the IoC container. -// -------------------------------------------------------------- -IoC::bootstrap(Config::get('dependencies')); - // -------------------------------------------------------------- // Set the error reporting and display levels. // -------------------------------------------------------------- @@ -98,21 +93,25 @@ // -------------------------------------------------------------- date_default_timezone_set(Config::get('application.timezone')); -// -------------------------------------------------------------- -// Load the session. -// -------------------------------------------------------------- -if (Config::get('session.driver') != '') Session::driver()->start(Cookie::get('laravel_session')); - // -------------------------------------------------------------- // Load all of the core routing and response classes. // -------------------------------------------------------------- -require SYS_PATH.'renderable'.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; +// -------------------------------------------------------------- +// Bootstrap the IoC container. +// -------------------------------------------------------------- +IoC::bootstrap(Config::get('dependencies')); + +// -------------------------------------------------------------- +// Load the session. +// -------------------------------------------------------------- +if (Config::get('session.driver') != '') Session::driver()->start(Cookie::get('laravel_session')); + // -------------------------------------------------------------- // Load the packages that are in the auto-loaded packages array. // -------------------------------------------------------------- @@ -133,6 +132,11 @@ // -------------------------------------------------------------- $request->input = new Input($request, $_GET, $_POST, $_COOKIE, $_FILES); +// -------------------------------------------------------------- +// Register the request as a singleton in the IoC container. +// -------------------------------------------------------------- +IoC::container()->instance('laravel.request', $request); + // -------------------------------------------------------------- // Register the filters for the default module. // -------------------------------------------------------------- diff --git a/laravel/redirect.php b/laravel/redirect.php index 61e3b472..98d71832 100644 --- a/laravel/redirect.php +++ b/laravel/redirect.php @@ -24,7 +24,7 @@ class Redirect extends Response { */ public static function to($url, $status = 302, $method = 'location', $https = false) { - $url = URL::to($url, $https); + $url = IoC::container()->resolve('laravel.url')->to($url, $https); if ($method == 'location') { @@ -93,14 +93,16 @@ public static function __callStatic($method, $parameters) { $parameters = (isset($parameters[0])) ? $parameters[0] : array(); + $url = IoC::container()->resolve('laravel.url'); + if (strpos($method, 'to_secure_') === 0) { - return static::to(URL::to_route(substr($method, 10), $parameters, true)); + return static::to($url->to_route(substr($method, 10), $parameters, true)); } if (strpos($method, 'to_') === 0) { - return static::to(URL::to_route(substr($method, 3), $parameters)); + return static::to($url->to_route(substr($method, 3), $parameters)); } throw new \Exception("Method [$method] is not defined on the Redirect class."); diff --git a/laravel/renderable.php b/laravel/renderable.php deleted file mode 100644 index 5a095d9e..00000000 --- a/laravel/renderable.php +++ /dev/null @@ -1,12 +0,0 @@ -to($url, true); } /** @@ -44,9 +44,9 @@ public static function to_secure($url = '') * @param string $url * @return string */ - public static function to_asset($url) + public function to_asset($url) { - return str_replace('index.php/', '', static::to($url, Request::active()->is_secure())); + return str_replace('index.php/', '', $this->to($url, IoC::resolve('laravel.request')->is_secure())); } /** @@ -57,10 +57,10 @@ public static function to_asset($url) * * * // Generate a URL for the "profile" named route - * $url = URL::to_route('profile'); + * $url = $url->to_route('profile'); * * // Generate a URL for the "profile" named route with parameters. - * $url = URL::to_route('profile', array('fred')); + * $url = $url->to_route('profile', array('fred')); * * * @param string $name @@ -68,7 +68,7 @@ public static function to_asset($url) * @param bool $https * @return string */ - public static function to_route($name, $parameters = array(), $https = false) + public function to_route($name, $parameters = array(), $https = false) { if ( ! is_null($route = Routing\Finder::find($name, Routing\Loader::all()))) { @@ -83,7 +83,7 @@ public static function to_route($name, $parameters = array(), $https = false) $uri = str_replace(array('/(:any?)', '/(:num?)'), '', $uri); - return static::to($uri, $https); + return $this->to($uri, $https); } throw new \Exception("Error generating named route for route [$name]. Route is not defined."); @@ -94,16 +94,16 @@ public static function to_route($name, $parameters = array(), $https = false) * * * // Generate a HTTPS URL for the "profile" named route - * $url = URL::to_secure_route('profile'); + * $url = $url->to_secure_route('profile'); * * * @param string $name * @param array $parameters * @return string */ - public static function to_secure_route($name, $parameters = array()) + public function to_secure_route($name, $parameters = array()) { - return static::to_route($name, $parameters, true); + return $this->to_route($name, $parameters, true); } /** @@ -111,17 +111,17 @@ public static function to_secure_route($name, $parameters = array()) * * * // Returns "my-first-post" - * $slug = URL::slug('My First Post!!'); + * $slug = $url->slug('My First Post!!'); * * // Returns "my_first_post" - * $slug = URL::slug('My First Post!!', '_'); + * $slug = $url->slug('My First Post!!', '_'); * * * @param string $title * @param string $separator * @return string */ - public static function slug($title, $separator = '-') + public function slug($title, $separator = '-') { $title = Str::ascii($title); @@ -139,27 +139,27 @@ public static function slug($title, $separator = '-') * * * // Generate a URL for the "profile" named route - * $url = URL::to_profile(); + * $url = $url->to_profile(); * * // Generate a URL for the "profile" named route using HTTPS - * $url = URL::to_secure_profile(); + * $url = $url->to_secure_profile(); * * // Generate a URL for the "profile" named route with parameters. - * $url = URL::to_profile(array('fred')); + * $url = $url->to_profile(array('fred')); * */ - public static function __callStatic($method, $parameters) + public function __call($method, $parameters) { $parameters = (isset($parameters[0])) ? $parameters[0] : array(); if (strpos($method, 'to_secure_') === 0) { - return static::to_route(substr($method, 10), $parameters, true); + return $this->to_route(substr($method, 10), $parameters, true); } if (strpos($method, 'to_') === 0) { - return static::to_route(substr($method, 3), $parameters); + return $this->to_route(substr($method, 3), $parameters); } throw new \Exception("Method [$method] is not defined on the URL class.");