Commit 6a8aafc2 authored by Taylor Otwell's avatar Taylor Otwell

refactoring and adding more dependency injection through ioc container.

parent 99adf09a
......@@ -26,6 +26,7 @@ return array(
'Cookie' => 'Laravel\\Cookie',
'Crypter' => 'Laravel\\Crypter',
'DB' => 'Laravel\\DB',
'Download' => 'Laravel\\Download',
'Eloquent' => 'Laravel\\DB\\Eloquent\\Model',
'File' => 'Laravel\\File',
'Form' => 'Laravel\\Form',
......
<?php
return array(
'/æ|ǽ/' => '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
<?php
return array(
'hqx' => '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
......@@ -56,7 +56,7 @@ return array(
'auth' => function()
{
return ( ! Auth::check()) ? Redirect::to_login() : null;
return ( ! Auth::make()->check()) ? Redirect::to_login() : null;
},
......
......@@ -48,6 +48,24 @@ class Auth {
$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.
*
......
......@@ -35,13 +35,13 @@ class Cache {
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.");
......
......@@ -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 @@ class APC extends Driver {
*/
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 @@ class APC extends Driver {
*/
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 @@ class APC extends Driver {
*/
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
<?php namespace Laravel\Cache;
/**
* Wrap the file functions in a class that can be injected into driver.
* Since the file functions are global, the driver is untestable without
* injecting a wrapper around them.
*/
class File_Engine {
/**
* Determine if a file exists.
*
* @param string $file
* @return bool
*/
public function exists($file)
{
return file_exists($file);
}
/**
* Get the contents of a file.
*
* @param string $file
* @return string
*/
public function get($file)
{
return file_get_contents($file);
}
/**
* Write to a file.
*
* @param string $file
* @param string $value
* @return void
*/
public function put($file, $value)
{
file_put_contents($file, $value, LOCK_EX);
}
/**
* Delete a file.
*
* @param string $file
* @return void
*/
public function forget($file)
{
@unlink($file);
}
}
class File extends Driver {
/**
* The File cache engine.
*
* @var File_Engine
*/
private $file;
/**
* Create a new File cache driver instance.
*
* @param File_Engine $file
* @return void
*/
public function __construct(File_Engine $file)
{
$this->file = $file;
}
/**
* Determine if an item exists in the cache.
*
......@@ -26,9 +98,9 @@ class File extends Driver {
*/
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 @@ class File extends Driver {
*/
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 @@ class File extends Driver {
*/
public function forget($key)
{
@unlink(CACHE_PATH.$key);
$this->file->forget(CACHE_PATH.$key);
}
}
\ No newline at end of file
<?php namespace Laravel\Cache;
use Laravel\Config;
use Laravel\Memcached as Mem;
class Memcached extends Driver {
/**
* The Memcache instance.
*
* @var Memcache
*/
private $memcache;
/**
* Create a new Memcached cache driver instance.
*
* @param Memcache $memcache
* @return void
*/
public function __construct(\Memcache $memcache)
{
$this->memcache = $memcache;
}
/**
* Determine if an item exists in the cache.
*
......@@ -29,7 +46,7 @@ class Memcached extends Driver {
*/
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 @@ class Memcached extends Driver {
*/
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 @@ class Memcached extends Driver {
*/
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
......@@ -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 @@ class Config {
*
* // 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');
* </code>
*
* @param string $key
......@@ -57,16 +54,16 @@ class Config {
*/
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 @@ class Config {
*/
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 @@ class Config {
* 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 @@ class Config {
* 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;
......
<?php
return array(
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| Here, you can specify any class aliases that you would like registered
| when Laravel loads. Aliases are lazy-loaded, so add as many as you want.
|
| Aliases make it more convenient to use namespaced classes. Instead of
| referring to the class using its full namespace, you may simply use
| the alias defined here.
|
| We have already aliased common Laravel classes to make your life easier.
|
*/
'Asset' => '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
<?php
return array(
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| The URL used to access your application. No trailing slash.
|
*/
'url' => '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
<?php
return array(
/*
|--------------------------------------------------------------------------
| Retrieve Users By ID
|--------------------------------------------------------------------------
|
| This method is called by the Auth::user() method when attempting to
| retrieve a user by their user ID, such as when retrieving a user by the
| user ID stored in the session.
|
| You are free to change this method for your application however you wish.
|
*/
'by_id' => 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
<?php
return array(
/*
|--------------------------------------------------------------------------
| Cache Driver
|--------------------------------------------------------------------------
|
| The name of the default cache driver for your application.
|
| Caching can be used to increase the performance of your application
| by storing commonly accessed data in memory or in a file.
|
| Supported Drivers: 'file', 'memcached', 'apc'.
|
*/
'driver' => '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
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Database Connection
|--------------------------------------------------------------------------
|
| The name of your default database connection.
|
| This connection will be the default for all database operations unless a
| different connection is specified when performing the operation.
|
*/
'default' => '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
<?php
<?php namespace Laravel;
return array(
/*
|--------------------------------------------------------------------------
| Session Driver
| Laravel File Cache Driver
|--------------------------------------------------------------------------
|
| The name of the session driver for your application.
|
| Since HTTP is stateless, sessions are used to maintain "state" across
| multiple requests from the same user of your application.
|
| Supported Drivers: 'cookie', 'file', 'db', 'memcached', 'apc'.
|
*/
'driver' => '',
'laravel.cache.file' => array('resolver' => function($container)
{
return new Cache\File($container->resolve('laravel.cache.file_engine'));
}),
/*
|--------------------------------------------------------------------------
| Session Database
| Laravel File Cache Driver Engine
|--------------------------------------------------------------------------
|
| The database table on which the session should be stored.
|
| This option is only relevant when using the "db" session driver.
|
*/
'table' => 'sessions',
'laravel.cache.file_engine' => array('resolver' => function($container)
{
return new Cache\File_Engine;
}),
/*
|--------------------------------------------------------------------------
| Session Lifetime
| Laravel APC Cache Driver
|--------------------------------------------------------------------------
|
| The number of minutes a session can be idle before expiring.
|
*/
'lifetime' => 60,
'laravel.cache.apc' => array('resolver' => function($container)
{
return new Cache\APC($container->resolve('laravel.cache.apc_engine'));
}),
/*
|--------------------------------------------------------------------------
| Session Expiration On Close
| Laravel APC Cache Driver Engine
|--------------------------------------------------------------------------
|
| Determines if the session should expire when the user's web browser closes.
|
*/
'expire_on_close' => false,
'laravel.cache.apc_engine' => array('resolver' => function($container)
{
return new Cache\APC_Engine;
}),
/*
|--------------------------------------------------------------------------
| Session Cookie Path
| Laravel Memcached Cache Driver
|--------------------------------------------------------------------------
|
| The path for which the session cookie is available.
|
*/
'path' => '/',
'laravel.cache.memcached' => array('resolver' => function($container)
{
return new Cache\Memcached($container->resolve('laravel.memcache'));
}),
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
| Memcache Connection
|--------------------------------------------------------------------------
|
| The domain for which the session cookie is available.
|
*/
'domain' => null,
'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.');
}
/*
|--------------------------------------------------------------------------
| Session Cookie HTTPS
|--------------------------------------------------------------------------
|
| Determines if the session cookie should only be transported over HTTPS.
|
*/
$memcache = new \Memcache;
'https' => false,
foreach (Config::get('cache.servers') as $server)
{
$memcache->addServer($server['host'], $server['port'], true, $server['weight']);
}
/*
|--------------------------------------------------------------------------
| 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.
|
*/
if ($memcache->getVersion() === false)
{
throw new \Exception('Memcached is configured. However, no connections could be made. Please verify your memcached configuration.');
}
'http_only' => false,
return $memcache;
}),
);
\ No newline at end of file
<?php
return array(
/*
|--------------------------------------------------------------------------
| Error Detail
|--------------------------------------------------------------------------
|
| Detailed error messages contain information about the file in which
| an error occurs, a stack trace, and a snapshot of the source code
| in which the error occured.
|
| If your application is in production, consider turning off error details
| for enhanced security and user experience.
|
*/
'detail' => 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
<?php namespace Laravel;
class Container {
/**
* The resolved singleton instances.
*
* @var array
*/
private $singletons = array();
/**
* The registered dependencies.
*
* @var array
*/
private $resolvers = array();
/**
* Register a dependency and its resolver.
*
* The resolver function when the registered dependency is requested.
*
* <code>
* // Register a simple dependency
* $container->register('name', function() { return 'Fred'; });
*
* // Register a dependency as a singleton
* $container->register('name', function() { return new Name; }, true);
* </code>
*
* @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.
*
* <code>
* // Resolver the "name" dependency
* $name = $container->resolve('name');
* </code>
*
* @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
......@@ -2,6 +2,7 @@
use Laravel\Str;
use Laravel\Config;
use Laravel\Request;
use Laravel\Paginator;
class Query {
......@@ -569,15 +570,18 @@ class Query {
*
* @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;
}
/**
......
<?php namespace Laravel;
class Download extends Response {
/**
* Create a new download response instance.
*
* <code>
* // 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');
* </code>
*
* @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
......@@ -68,7 +68,7 @@ class Examiner {
*/
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().'.';
}
......
......@@ -71,7 +71,9 @@ class File {
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 @@ class File {
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
......@@ -105,6 +105,16 @@ class Input {
/**
* Get an item from the input data.
*
* This method should be used for all request methods (GET, POST, PUT, and DELETE).
*
* <code>
* // 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');
* </code>
*
* @param string $key
* @param mixed $default
* @return string
......@@ -128,6 +138,13 @@ class Input {
/**
* Get input data from the previous request.
*
* If no session driver is provided, the default driver will be used.
*
* <code>
* // Get the "name" item from the old input data
* $name = Request::active()->input->old('name');
* </code>
*
* @param string $key
* @param mixed $default
* @param Session\Driver $driver
......@@ -143,6 +160,16 @@ class Input {
/**
* Get an item from the uploaded file data.
*
* "Dot" syntax may be used to get a specific item from the file array.
*
* <code>
* // 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');
* </code>
*
* @param string $key
* @param mixed $default
* @return array
......@@ -155,6 +182,8 @@ class Input {
/**
* 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 @@ class Input {
/**
* Magic Method for retrieving items from the request input.
*
* <code>
* // Retrieve the "name" item from the input data
* $name = Request::active()->input->name;
* </code>
*/
public function __get($key)
{
......
<?php namespace Laravel;
class IoC {
/**
* The available IoC containers.
*
* @var array
*/
public static $containers = array();
/**
* Bootstrap the default container and register the dependencies.
*
* @param array $dependencies
* @return void
*/
public static function bootstrap($dependencies)
{
$container = static::container();
foreach ($dependencies as $key => $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.
*
* <code>
* // Get the default container instance
* $container = IoC::container();
*
* // Get a specific container instance
* $container = IoC::container('models');
* </code>
*
* @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.
*
* <code>
* // Resolve an object from the default container
* $user = IoC::resolve('user');
*
* // Equivalent method of resolving using the container method
* $user = IoC::container()->resolve('user');
* </code>
*/
public static function __callStatic($method, $parameters)
{
return call_user_func_array(array(static::container(), $method), $parameters);
}
}
\ No newline at end of file
......@@ -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.
*
* <code>
* // 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();
* </code>
*
* @param string $key
* @param array $replacements
......@@ -54,25 +69,48 @@ class Lang {
return new static($key, $replacements);
}
/**
* Set the language the line should be returned in.
*
* The language specified in this method should correspond to a language directory in your application.
*
* <code>
* // Get a "fr" language line
* $line = Lang::line('validation.required')->in('fr')->get();
* </code>
*
* @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.
*
* <code>
* // Get a validation line and return a default value if the line doesn't exist
* $line = Lang::line('welcome.message')->get('Hello!');
* </code>
*
* @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($module, $file, $line) = $this->parse($this->key, $language);
list($file, $line) = $this->parse($this->key);
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 @@ class Lang {
/**
* 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 @@ class Lang {
/**
* 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]);
}
/**
......
......@@ -2,6 +2,12 @@
return array(
/*
|--------------------------------------------------------------------------
| Pagination "Next" and "Previous" Language
|--------------------------------------------------------------------------
*/
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
......
......@@ -10,61 +10,45 @@ define('EXT', '.php');
// --------------------------------------------------------------
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 @@ error_reporting(E_ALL | E_STRICT);
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 @@ register_shutdown_function(function() use ($error_dependencies)
}
});
// --------------------------------------------------------------
// 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 @@ if (count(Config::get('application.packages')) > 0)
}
// --------------------------------------------------------------
// Register the filters for the default module.
// Initialize the request instance for the request.
// --------------------------------------------------------------
$request = new Request($_SERVER);
// --------------------------------------------------------------
// Hydrate the input for the current request.
// --------------------------------------------------------------
Routing\Filter::register(require DEFAULT_MODULE_PATH.'filters'.EXT);
$request->input = new Input($request, $_GET, $_POST, $_COOKIE, $_FILES);
// --------------------------------------------------------------
// Register the filters for the active module.
// Register the filters for the default module.
// --------------------------------------------------------------
if (file_exists(ACTIVE_MODULE_PATH.'filters'.EXT))
{
Routing\Filter::register(require ACTIVE_MODULE_PATH.'filters'.EXT);
}
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 @@ $response = Response::prepare($response);
// --------------------------------------------------------------
// 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.
......
......@@ -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 @@ class Loader {
{
$file = strtolower(str_replace('\\', '/', $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);
}
if (array_key_exists($class, static::$aliases))
{
return class_alias(static::$aliases[$class], $class);
}
/**
* 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;
}
}
/**
......
<?php namespace Laravel;
class Memcached {
/**
* The Memcache instance.
*
* @var Memcache
*/
private static $instance = null;
/**
* Get the singleton Memcache instance.
*
* @return Memcache
*/
public static function instance()
{
if (is_null(static::$instance))
{
static::$instance = static::connect(Config::get('cache.servers'));
}
return static::$instance;
}
/**
* Connect to the configured Memcached servers.
*
* @param array $servers
* @return Memcache
*/
private static function connect($servers)
{
if ( ! class_exists('Memcache'))
{
throw new \Exception('Attempting to use Memcached, but the Memcached PHP extension is not installed on this server.');
}
$memcache = new \Memcache;
foreach ($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
......@@ -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 @@ class Messages {
*
* Duplicate messages will not be added.
*
* <code>
* // Add an error message for the "email" key
* $messages->add('email', 'The e-mail address is invalid.');
* </code>
*
* @param string $key
* @param string $message
* @return void
......@@ -39,6 +46,11 @@ class Messages {
/**
* Determine if messages exist for a given key.
*
* <code>
* // Determine if there are any messages for the "email" key
* $has = $messages->has('email');
* </code>
*
* @param string $key
* @return bool
*/
......@@ -50,6 +62,16 @@ class Messages {
/**
* Get the first message for a given key.
*
* Optionally, a format may be specified for the returned message.
*
* <code>
* // Get the first message for the "email" key
* $message = $messages->first('email');
*
* // Get the first message for the "email" key wrapped in <p> tags
* $message = $messages->first('email', '<p>:message</p>');
* </code>
*
* @param string $key
* @param string $format
* @return string
......@@ -62,7 +84,13 @@ class Messages {
/**
* Get all of the messages for a key.
*
* If no key is specified, all of the messages will be returned.
* <code>
* // Get all of the messages for the "email" key
* $message = $messages->get('email');
*
* // Get all of the messages for the "email" key wrapped in <p> tags
* $message = $messages->get('email', '<p>:message</p>');
* </code>
*
* @param string $key
* @param string $format
......@@ -76,7 +104,15 @@ class Messages {
}
/**
* Get all of the messages.
* Get all of the messages for every key.
*
* <code>
* // Get all of the messages for every key
* $message = $messages->all();
*
* // Get all of the messages for every key wrapped in <p> tags
* $message = $messages->all('<p>:message</p>');
* </code>
*
* @param string $format
* @return array
......
<?php namespace Laravel;
class Module {
/**
* The active modules for the installation.
*
* This property is set in the Laravel bootstrap file, and the modules are defined
* by the developer in the front controller.
*
* @var array
*/
public static $modules = array();
/**
* All of the loaded module paths keyed by name.
*
* These are stored as the module paths are determined for convenient, fast access.
*
* @var array
*/
private static $paths = array();
/**
* Parse a modularized identifier and return the module and key.
*
* Modular identifiers follow typically follow a {module}::{key} convention.
* However, for convenience, the default module does not require a module qualifier.
*
* <code>
* // Returns array('admin', 'test.example')
* Module::parse('admin::test.example');
*
* // Returns array('application', 'test.example')
* Module::parse('test.example');
* </code>
*
* @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
......@@ -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.
*
* <code>
* // Load the "swift-mailer" package
* Package::load('swift-mailer');
*
* // Load the "swift-mailer" and "facebook" package
* Package::load(array('swift-mailer', 'facebook'));
* </code>
*
* @param string|array $packages
* @return void
*/
......@@ -31,6 +41,11 @@ class Package {
/**
* Determine if a given package has been loaded.
*
* <code>
* // Determine if the "swift-mailer" package has been loaded
* $loaded = Package::loaded('swift-mailer');
* </code>
*
* @param string $package
* @return bool
*/
......
......@@ -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.
*
* <code>
* // Create a Paginator for the first page of 10 total results and 2 items per page
* $paginator = new Paginator(1, 10, 2);
* </code>
*
* @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;
}
/**
* 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));
// 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);
}
/**
* 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 @@ class Paginator {
/**
* 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 '<div class="pagination">'.$this->previous().$numbers.$this->next().'</div>';
}
/**
* 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 @@ class Paginator {
/**
* 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 @@ class Paginator {
}
/**
* 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 @@ class Paginator {
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 @@ class Paginator {
$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 @@ class Paginator {
/**
* Set the items that should be appended to the link query strings.
*
* <code>
* // Set the "sort" query string item on the links that will be generated
* echo $paginator->append(array('sort' => 'desc'))->links();
* </code>
*
* @param array $values
* @return Paginator
*/
......
<?php namespace Laravel;
class Redirect {
class Redirect extends Response {
/**
* The redirect response.
* Create a redirect response.
*
* @var Response
*/
public $response;
/**
* Create a new redirect instance.
* <code>
* // Create a redirect for the "user/profile" URI
* return Redirect::to('user/profile');
*
* @param Response $response
* @return void
*/
public function __construct($response)
{
$this->response = $response;
}
/**
* Create a redirect response.
* // 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');
* </code>
*
* @param string $url
* @param int $status
......@@ -33,14 +26,24 @@ class Redirect {
{
$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.
*
* <code>
* // Create a HTTPS redirect to the "user/profile" URI
* return Redirect::to_secure('user/profile');
* </code>
*
* @param string $url
* @param int $status
* @param string $method
......@@ -54,24 +57,37 @@ class Redirect {
/**
* 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.
*
* <code>
* // Flash a status message to the session on a redirect
* return Redirect::to('user/profile')->with('status', 'Welcome Back!');
* </code>
*
* @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.
*
* <code>
* // 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();
* </code>
*/
public static function __callStatic($method, $parameters)
{
......
<?php namespace Laravel;
interface Renderable {
/**
* Get the evaluated string contents of the object.
*
* @return string
*/
public function render();
}
\ No newline at end of file
......@@ -79,10 +79,10 @@ class Request {
}
else
{
die('Unable to determine the request URI.');
throw new \Exception('Unable to determine the request URI.');
}
if ($uri === false) die('Malformed request URI. Request terminated.');
if ($uri === false) throw new \Exception('Malformed request URI. Request terminated.');
return $this->uri = $this->remove_from_uri($uri, array(parse_url(Config::get('application.url'), PHP_URL_PATH), '/index.php'));
}
......@@ -180,7 +180,12 @@ class Request {
}
/**
* Determine if the route handling the request is a given name.
* Determine if the route handling the request has a given name.
*
* <code>
* // Determine if the route handling the request is named "profile"
* $profile = Request::active()->route_is('profile');
* </code>
*
* @param string $name
* @return bool
......@@ -193,7 +198,12 @@ class Request {
}
/**
* Magic Method to handle dynamic static methods.
* Magic Method to handle dynamic method calls to determine the route handling the request.
*
* <code>
* // Determine if the route handling the request is named "profile"
* $profile = Request::active()->route_is_profile();
* </code>
*/
public function __call($method, $parameters)
{
......@@ -205,6 +215,11 @@ class Request {
/**
* Magic Method for dynamically retrieving properties of the request instance.
*
* <code>
* // Get all of the input for the request
* $input = Request::active()->input;
* </code>
*/
public function __get($key)
{
......
<?php namespace Laravel;
class Response {
class Response implements Renderable {
/**
* The content of the response.
......@@ -86,7 +86,7 @@ class Response {
public function __construct($content, $status = 200)
{
$this->content = $content;
$this->status = $status;
$this->status = $status;
}
/**
......@@ -104,6 +104,15 @@ class Response {
/**
* 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.
*
* <code>
* // Return a 404 error response
* return Response::error('404');
* </code>
*
* @param int $code
* @param array $data
* @return Response
......@@ -121,11 +130,19 @@ class Response {
*/
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 @@ class Response {
if ( ! headers_sent()) $this->send_headers();
echo (string) $this->content;
echo $this->render();
}
/**
......@@ -163,6 +180,11 @@ class Response {
/**
* Add a header to the response.
*
* <code>
* // Add a "location" header to a response
* $response->header('Location', 'http://google.com');
* </code>
*
* @param string $name
* @param string $value
* @return Response
......@@ -173,22 +195,4 @@ class Response {
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
......@@ -60,13 +60,6 @@ class Loader {
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 @@ class Loader {
* @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);
}
$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');
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);
$recursiveIterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($recursiveIterator as $file)
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);
}
}
}
......
......@@ -233,7 +233,7 @@ abstract class Driver {
{
$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'));
}
}
......
......@@ -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.
*
......
......@@ -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 @@ class 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.
*
* <code>
* // 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'));
* </code>
*
* @param string $name
* @param array $parameters
......@@ -90,6 +92,11 @@ class URL {
/**
* Generate a HTTPS URL from a route name.
*
* <code>
* // Generate a HTTPS URL for the "profile" named route
* $url = URL::to_secure_route('profile');
* </code>
*
* @param string $name
* @param array $parameters
* @return string
......@@ -102,6 +109,14 @@ class URL {
/**
* Generate a URL friendly "slug".
*
* <code>
* // Returns "my-first-post"
* $slug = URL::slug('My First Post!!');
*
* // Returns "my_first_post"
* $slug = URL::slug('My First Post!!', '_');
* </code>
*
* @param string $title
* @param string $separator
* @return string
......@@ -120,7 +135,18 @@ class URL {
}
/**
* Magic Method for dynamically creating route URLs.
* Magic Method for dynamically creating URLs to named routes.
*
* <code>
* // 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'));
* </code>
*/
public static function __callStatic($method, $parameters)
{
......
......@@ -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 @@ class Validator {
{
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 @@ class Validator {
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
<?php namespace Laravel;
class View {
class View implements Renderable {
/**
* The name of the view.
......@@ -9,6 +9,13 @@ class View {
*/
public $view;
/**
* The view name with dots replaced with slashes.
*
* @var string
*/
protected $path;
/**
* The view data.
*
......@@ -23,13 +30,6 @@ class View {
*/
public $module;
/**
* The path to the view.
*
* @var string
*/
public $path;
/**
* The defined view composers.
*
......@@ -46,11 +46,9 @@ class View {
*/
public function __construct($view, $data = array())
{
$this->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 @@ class View {
/**
* 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 @@ class 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 @@ class View {
}
/**
* 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 @@ class View {
/**
* Add a view instance to the view data.
*
* <code>
* // 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'));
* </code>
*
* @param string $key
* @param string $view
* @param array $data
......@@ -181,6 +153,13 @@ class View {
/**
* Add a key / value pair to the view data.
*
* Bound data will be available to the view as variables.
*
* <code>
* // Bind a "name" value to the view
* View::make('home')->bind('name', 'Fred');
* </code>
*
* @param string $key
* @param mixed $value
* @return View
......@@ -193,6 +172,14 @@ class View {
/**
* Magic Method for handling the dynamic creation of named views.
*
* <code>
* // 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'));
* </code>
*/
public static function __callStatic($method, $parameters)
{
......@@ -234,12 +221,4 @@ class View {
unset($this->data[$key]);
}
/**
* Get the parsed content of the View.
*/
public function __toString()
{
return $this->get();
}
}
\ No newline at end of file
......@@ -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 @@ $laravel = '../laravel';
$packages = '../packages';
$modules = '../modules';
$storage = '../storage';
$public = __DIR__;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment