Commit fe28fbba authored by Taylor Otwell's avatar Taylor Otwell

Merge branch 'develop'

parents dead6c0a 21f33bb4
<?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.
|
| We have already setup a few to make your life easier.
|
*/
'Auth' => 'System\\Auth',
'Benchmark' => 'System\\Benchmark',
'Cache' => 'System\\Cache',
'Config' => 'System\\Config',
'Cookie' => 'System\\Cookie',
'Crypt' => 'System\\Crypt',
'Date' => 'System\\Date',
'DB' => 'System\\DB',
'Eloquent' => 'System\\DB\\Eloquent',
'File' => 'System\\File',
'Form' => 'System\\Form',
'Hash' => 'System\\Hash',
'HTML' => 'System\\HTML',
'Inflector' => 'System\\Inflector',
'Input' => 'System\\Input',
'Lang' => 'System\\Lang',
'Log' => 'System\\Log',
'URL' => 'System\\URL',
'Redirect' => 'System\\Redirect',
'Request' => 'System\\Request',
'Response' => 'System\\Response',
'Session' => 'System\\Session',
'Str' => 'System\\Str',
'Text' => 'System\\Text',
'Validator' => 'System\\Validator',
'View' => 'System\\View',
);
\ No newline at end of file
......@@ -80,45 +80,4 @@ return array(
'key' => '',
/*
|--------------------------------------------------------------------------
| 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.
|
| We have already setup a few to make your life easier.
|
*/
'aliases' => array(
'Auth' => 'System\\Auth',
'Benchmark' => 'System\\Benchmark',
'Cache' => 'System\\Cache',
'Config' => 'System\\Config',
'Cookie' => 'System\\Cookie',
'Crypt' => 'System\\Crypt',
'Date' => 'System\\Date',
'DB' => 'System\\DB',
'Download' => 'System\\Download',
'Eloquent' => 'System\\DB\\Eloquent',
'File' => 'System\\File',
'Form' => 'System\\Form',
'Hash' => 'System\\Hash',
'HTML' => 'System\\HTML',
'Inflector' => 'System\\Inflector',
'Input' => 'System\\Input',
'Lang' => 'System\\Lang',
'Log' => 'System\\Log',
'URL' => 'System\\URL',
'Redirect' => 'System\\Redirect',
'Request' => 'System\\Request',
'Response' => 'System\\Response',
'Session' => 'System\\Session',
'Str' => 'System\\Str',
'Text' => 'System\\Text',
'View' => 'System\View',
),
);
\ No newline at end of file
......@@ -12,12 +12,24 @@ return array(
| 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'.
| Supported Drivers: 'file', 'memcached', 'apc'.
|
*/
'driver' => 'file',
/*
|--------------------------------------------------------------------------
| Cache Key
|--------------------------------------------------------------------------
|
| This key will be prepended to items stored using Memcached and APC to
| prevent collisions with other applications on the server.
|
*/
'key' => 'laravel',
/*
|--------------------------------------------------------------------------
| Memcached Servers
......@@ -37,16 +49,4 @@ return array(
array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),
),
/*
|--------------------------------------------------------------------------
| Memcached Key
|--------------------------------------------------------------------------
|
| This key will be prepended to items stored using Memcached to avoid
| collisions with other applications on the server.
|
*/
'key' => 'laravel',
);
\ 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
......@@ -12,7 +12,7 @@ return array(
| Since HTTP is stateless, sessions are used to maintain "state" across
| multiple requests from the same user of your application.
|
| Supported Drivers: 'file', 'db', 'memcached'.
| Supported Drivers: 'file', 'db', 'memcached', 'apc'.
|
*/
......
<?php
return array(
/*
|--------------------------------------------------------------------------
| General Validation Messages
|--------------------------------------------------------------------------
*/
"acceptance_of" => "The :attribute must be accepted.",
"confirmation_of" => "The :attribute confirmation does not match.",
"exclusion_of" => "The :attribute value is invalid.",
"format_of" => "The :attribute format is invalid.",
"inclusion_of" => "The :attribute value is invalid.",
"presence_of" => "The :attribute can't be empty.",
"uniqueness_of" => "The :attribute has already been taken.",
"with_callback" => "The :attribute is invalid.",
/*
|--------------------------------------------------------------------------
| Numericality_Of Validation Messages
|--------------------------------------------------------------------------
*/
"number_not_valid" => "The :attribute must be a number.",
"number_not_integer" => "The :attribute must be an integer.",
"number_wrong_size" => "The :attribute must be :size.",
"number_too_big" => "The :attribute must be no more than :max.",
"number_too_small" => "The :attribute must be at least :min.",
/*
|--------------------------------------------------------------------------
| Length_Of Validation Messages
|--------------------------------------------------------------------------
*/
"string_wrong_size" => "The :attribute must be :size characters.",
"string_too_big" => "The :attribute must be no more than :max characters.",
"string_too_small" => "The :attribute must be at least :min characters.",
/*
|--------------------------------------------------------------------------
| Upload_Of Validation Messages
|--------------------------------------------------------------------------
*/
"file_wrong_type" => "The :attribute must be a file of type: :types.",
"file_too_big" => "The :attribute exceeds size limit of :maxkb.",
);
\ No newline at end of file
......@@ -4,74 +4,76 @@
<meta charset="utf-8">
<title>Welcome To Laravel!</title>
<link href="http://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet" type="text/css" media="all" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<link href="http://fonts.googleapis.com/css?family=Quattrocento&amp;v1" rel="stylesheet" type="text/css" media="all" />
<link href="http://fonts.googleapis.com/css?family=Ubuntu&amp;v1" rel="stylesheet" type="text/css" media="all" />
<link href="http://fonts.googleapis.com/css?family=Lobster+Two&amp;v1" rel="stylesheet" type="text/css" media="all" />
<style type="text/css">
body {
background-color: #fff;
font-family: 'Ubuntu', sans-serif;
font-size: 16px;
color: #3f3f3f;
}
h1 {
font-size: 40px;
background-color: #eee;
color: #6d6d6d;
margin: 0 0 10px 0;
text-shadow: 1px 1px #000;
font-family: 'Ubuntu';
font-size: 15px;
}
a {
color: #000;
color: #7089b3;
font-weight: bold;
text-decoration: none;
}
#wrapper {
width: 740px;
h1.laravel {
font-family: 'Lobster Two', Helvetica, serif;
font-size: 60px;
margin: 0 0 15px -10px;
padding: 0;
text-shadow: -1px 1px 1px #fff;
}
#content {
padding: 10px 10px 10px 10px;
background-color: #eee;
border-radius: 10px;
h2 {
font-family: 'Quattrocento', serif;
font-size: 30px;
margin: 30px 0 0 0;
padding: 0;
text-shadow: -1px 1px 1px #fff;
}
#footer {
font-size: 12px;
padding-top: 10px;
text-align: right;
p {
margin: 10px 0 0 0;
line-height: 25px;
}
#wrapper {
background-color: #fff;
border-radius: 10px;
margin: 0 auto;
padding: 10px;
width: 80%;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$(window).resize(function(){
$('#wrapper').css({
position:'absolute',
left: ($(window).width() - $('#wrapper').outerWidth()) / 2,
top: ($(window).height() - $('#wrapper').outerHeight()) / 3
});
});
#wrapper h2:first-of-type {
margin-top: 0;
}
$(window).resize();
});
</script>
#header {
margin: 0 auto;
margin-bottom: 15px;
margin-top: 20px;
width: 80%;
}
</style>
</head>
<body>
<div id="wrapper">
<h1>Laravel</h1>
<div id="header">
<h1 class="laravel">Laravel</h1>
</div>
<div id="content">
You have successfully installed Laravel.
<div id="wrapper">
<h2>Installation Complete!</h2>
<br /><br />
<p>Ready to dig in? Start building your application in the <strong>application/routes.php</strong> file.</p>
Perhaps you would like to <a href="http://laravel.com/docs">peruse the documentation</a> or <a href="http://github.com/taylorotwell/laravel">contribute on GitHub</a>?
</div>
<div id="footer">
<?php echo Benchmark::memory(); ?>mb &middot; <?php echo Benchmark::check('laravel'); ?>ms
</div>
<p>Need to learn more? Peruse our <a href="http://laravel.com/docs">wonderful documentation</a>.</p>
</div>
</body>
</html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
* Laravel - A clean and classy framework for PHP web development.
*
* @package Laravel
* @version 1.0.0 Beta 2
* @version 1.1.0
* @author Taylor Otwell
* @license MIT License
* @link http://laravel.com
......@@ -17,10 +17,11 @@ define('LARAVEL_START', microtime(true));
// --------------------------------------------------------------
// Define the framework paths.
// --------------------------------------------------------------
define('BASE_PATH', realpath('../').'/');
define('APP_PATH', realpath('../application').'/');
define('SYS_PATH', realpath('../system').'/');
define('BASE_PATH', realpath('../').'/');
define('PUBLIC_PATH', realpath(__DIR__.'/'));
define('PACKAGE_PATH', APP_PATH.'packages/');
// --------------------------------------------------------------
// Define the PHP file extension.
......@@ -28,21 +29,15 @@ define('PUBLIC_PATH', realpath(__DIR__.'/'));
define('EXT', '.php');
// --------------------------------------------------------------
// Load the configuration, error, and string classes.
// Load the configuration class.
// --------------------------------------------------------------
require SYS_PATH.'config'.EXT;
require SYS_PATH.'str'.EXT;
// --------------------------------------------------------------
// Register the auto-loader.
// --------------------------------------------------------------
spl_autoload_register(require SYS_PATH.'loader'.EXT);
// --------------------------------------------------------------
// Set the Laravel starting time in the Benchmark class.
// --------------------------------------------------------------
System\Benchmark::$marks['laravel'] = LARAVEL_START;
// --------------------------------------------------------------
// Set the error reporting level.
// --------------------------------------------------------------
......@@ -88,7 +83,7 @@ if (System\Config::get('session.driver') != '')
// --------------------------------------------------------------
// Execute the global "before" filter.
// --------------------------------------------------------------
$response = System\Filter::call('before', array(), true);
$response = System\Route\Filter::call('before', array(), true);
// --------------------------------------------------------------
// Only execute the route function if the "before" filter did
......@@ -121,7 +116,7 @@ else
// ----------------------------------------------------------
// Execute the global "after" filter.
// ----------------------------------------------------------
System\Filter::call('after', array($response));
System\Route\Filter::call('after', array($response));
// ----------------------------------------------------------
// Stringify the response.
......
# Laravel - A Clean & Classy PHP Framework
## For more information, visit [http://laravel.com](http://laravel.com/ "Laravel")
### For more information, visit [http://laravel.com](http://laravel.com)
### For complete documentation, visit [http://docs.laravel.com](http://docs.laravel.com)
\ No newline at end of file
<?php namespace System\Cache\Driver;
class APC implements \System\Cache\Driver {
/**
* All of the loaded cache items.
*
* @var array
*/
private $items = array();
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ( ! is_null($this->get($key)));
}
/**
* Get an item from the cache.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
if (array_key_exists($key, $this->items))
{
return $this->items[$key];
}
$cache = apc_fetch(\System\Config::get('cache.key').$key);
if ($cache === false)
{
return $default;
}
return $this->items[$key] = $cache;
}
/**
* Write an item to the cache.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
apc_store(\System\Config::get('cache.key').$key, $value, $minutes * 60);
}
/**
* Delete an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
apc_delete(\System\Config::get('cache.key').$key);
}
}
\ No newline at end of file
......@@ -34,12 +34,12 @@ class File implements \System\Cache\Driver {
return $this->items[$key];
}
if ( ! file_exists(APP_PATH.'cache/'.$key))
if ( ! file_exists(APP_PATH.'storage/cache/'.$key))
{
return $default;
}
$cache = file_get_contents(APP_PATH.'cache/'.$key);
$cache = file_get_contents(APP_PATH.'storage/cache/'.$key);
// --------------------------------------------------
// Has the cache expired? The UNIX expiration time
......@@ -65,7 +65,7 @@ class File implements \System\Cache\Driver {
*/
public function put($key, $value, $minutes)
{
file_put_contents(APP_PATH.'cache/'.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX);
file_put_contents(APP_PATH.'storage/cache/'.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX);
}
/**
......@@ -76,7 +76,7 @@ class File implements \System\Cache\Driver {
*/
public function forget($key)
{
@unlink(APP_PATH.'cache/'.$key);
@unlink(APP_PATH.'storage/cache/'.$key);
}
}
\ No newline at end of file
......@@ -18,6 +18,9 @@ class Factory {
case 'memcached':
return new Driver\Memcached;
case 'apc':
return new Driver\APC;
default:
throw new \Exception("Cache driver [$driver] is not supported.");
}
......
......@@ -9,35 +9,57 @@ class Config {
*/
private static $items = array();
/**
* Determine if a configuration item exists.
*
* @param string $key
* @return bool
*/
public static function has($key)
{
return ! is_null(static::get($key));
}
/**
* Get a configuration item.
*
* @param string $key
* @param string $default
* @return mixed
*/
public static function get($key)
public static function get($key, $default = null)
{
// -----------------------------------------------------
// If a dot is not present, we will just return the
// entire configuration array.
//
// If the configuration file does not exist, the default
// value will be returned.
// -----------------------------------------------------
if(strpos($key, '.') === false)
{
static::load($key);
return static::$items[$key];
return (array_key_exists($key, static::$items)) ? static::$items[$key] : $default;
}
list($file, $key) = static::parse($key);
static::load($file);
if (array_key_exists($key, static::$items[$file]))
// -----------------------------------------------------
// If the file doesn't exist, return the default.
// -----------------------------------------------------
if ( ! array_key_exists($file, static::$items))
{
return static::$items[$file][$key];
return $default;
}
throw new \Exception("Configuration item [$key] is not defined.");
// -----------------------------------------------------
// Return the configuration item. If the item doesn't
// exist, the default value will be returned.
// -----------------------------------------------------
return (array_key_exists($key, static::$items[$file])) ? static::$items[$file][$key] : $default;
}
/**
......@@ -91,18 +113,13 @@ class Config {
public static function load($file)
{
// -----------------------------------------------------
// If we have already loaded the file, bail out.
// Bail out if already loaded or doesn't exist.
// -----------------------------------------------------
if (array_key_exists($file, static::$items))
if (array_key_exists($file, static::$items) or ! file_exists($path = APP_PATH.'config/'.$file.EXT))
{
return;
}
if ( ! file_exists($path = APP_PATH.'config/'.$file.EXT))
{
throw new \Exception("Configuration file [$file] does not exist.");
}
// -----------------------------------------------------
// Load the configuration array into the array of items.
// The items array is keyed by filename.
......
......@@ -66,11 +66,11 @@ class DB {
//
// For all other statements, return a boolean.
// ---------------------------------------------------
if (strpos(Str::upper($sql), 'SELECT') === 0)
if (strpos(strtoupper($sql), 'SELECT') === 0)
{
return $query->fetchAll(\PDO::FETCH_CLASS, 'stdClass');
}
elseif (strpos(Str::upper($sql), 'UPDATE') === 0 or strpos(Str::upper($sql), 'DELETE') === 0)
elseif (strpos(strtoupper($sql), 'UPDATE') === 0 or strpos(strtoupper($sql), 'DELETE') === 0)
{
return $query->rowCount();
}
......@@ -105,4 +105,22 @@ class DB {
return static::connection($connection)->getAttribute(\PDO::ATTR_DRIVER_NAME);
}
/**
* Get the table prefix for a database connection.
*
* @param string $connection
* @return string
*/
public static function prefix($connection = null)
{
$connections = Config::get('db.connections');
if (is_null($connection))
{
$connection = Config::get('db.default');
}
return (array_key_exists('prefix', $connections[$connection])) ? $connections[$connection]['prefix'] : '';
}
}
\ No newline at end of file
......@@ -33,7 +33,7 @@ class Connector {
// If the database doesn't exist there, maybe the full
// path was specified as the database name?
// -----------------------------------------------------
if (file_exists($path = APP_PATH.'db/'.$config->database.'.sqlite'))
if (file_exists($path = APP_PATH.'storage/db/'.$config->database.'.sqlite'))
{
return new \PDO('sqlite:'.$path, null, null, static::$options);
}
......@@ -41,14 +41,31 @@ class Connector {
{
return new \PDO('sqlite:'.$config->database, null, null, static::$options);
}
else
{
throw new \Exception("SQLite database [".$config->database."] could not be found.");
}
}
// -----------------------------------------------------
// Connect to MySQL or Postgres.
// -----------------------------------------------------
elseif ($config->driver == 'mysql' or $config->driver == 'pgsql')
{
$connection = new \PDO($config->driver.':host='.$config->host.';dbname='.$config->database, $config->username, $config->password, static::$options);
// -----------------------------------------------------
// Build the PDO connection DSN.
// -----------------------------------------------------
$dsn = $config->driver.':host='.$config->host.';dbname='.$config->database;
if (isset($config->port))
{
$dsn .= ';port='.$config->port;
}
$connection = new \PDO($dsn, $config->username, $config->password, static::$options);
// -----------------------------------------------------
// Set the appropriate character set for the datbase.
// -----------------------------------------------------
if (isset($config->charset))
{
$connection->prepare("SET NAMES '".$config->charset."'")->execute();
......
<?php namespace System\DB;
use System\Str;
use System\Config;
use System\Inflector;
abstract class Eloquent {
......@@ -102,7 +103,7 @@ abstract class Eloquent {
return $class::$table;
}
return Str::lower(Inflector::plural($class));
return strtolower(Inflector::plural($class));
}
/**
......@@ -213,7 +214,7 @@ abstract class Eloquent {
// For example, the foreign key for a User model would
// be user_id. Photo would be photo_id, etc.
// -----------------------------------------------------
$this->relating_key = (is_null($foreign_key)) ? Str::lower(get_class($this)).'_id' : $foreign_key;
$this->relating_key = (is_null($foreign_key)) ? strtolower(get_class($this)).'_id' : $foreign_key;
return static::make($model)->where($this->relating_key, '=', $this->id);
}
......@@ -276,7 +277,7 @@ abstract class Eloquent {
sort($models);
$this->relating_table = Str::lower($models[0].'_'.$models[1]);
$this->relating_table = strtolower($models[0].'_'.$models[1]);
}
// -----------------------------------------------------
......@@ -286,11 +287,11 @@ abstract class Eloquent {
//
// This is the same convention as has_one and has_many.
// -----------------------------------------------------
$this->relating_key = Str::lower(get_class($this)).'_id';
$this->relating_key = strtolower(get_class($this)).'_id';
return static::make($model)
->select(static::table($model).'.*')
->join($this->relating_table, static::table($model).'.id', '=', $this->relating_table.'.'.Str::lower($model).'_id')
->join($this->relating_table, static::table($model).'.id', '=', $this->relating_table.'.'.strtolower($model).'_id')
->where($this->relating_table.'.'.$this->relating_key, '=', $this->id);
}
......@@ -365,7 +366,7 @@ abstract class Eloquent {
// -----------------------------------------------------
if ($this->exists)
{
return Query::table(static::table(get_class($this)))->delete($this->id) == 1;
return Query::table(static::table(get_class($this)))->delete($this->id);
}
return $this->query->delete($id);
......@@ -477,7 +478,7 @@ abstract class Eloquent {
{
$model = static::make(get_called_class());
if ($method == 'get')
if ($method == 'get' or $method == 'all')
{
return $model->_get();
}
......
......@@ -78,8 +78,9 @@ class Hydrator {
// -----------------------------------------------------
// Get the relationship Eloquent model.
//
// We temporarily spoof the "belongs_to" key to allow
// the query to be fetched without any problems.
// We temporarily spoof the belongs_to key to allow the
// query to be fetched without any problems, since the
// belongs_to method actually gets the attribute.
// -----------------------------------------------------
$eloquent->attributes[$spoof = $include.'_id'] = 0;
......
......@@ -326,7 +326,7 @@ class Query {
*/
public function order_by($column, $direction)
{
$this->orderings[] = $this->wrap($column).' '.Str::upper($direction);
$this->orderings[] = $this->wrap($column).' '.strtoupper($direction);
return $this;
}
......@@ -500,9 +500,23 @@ class Query {
*/
public function __call($method, $parameters)
{
// ---------------------------------------------------------
// Dynamic methods allows the building of very expressive
// queries. All dynamic methods start with "where_".
//
// Ex: DB::table('users')->where_email($email)->first();
// ---------------------------------------------------------
if (strpos($method, 'where_') === 0)
{
return Query\Dynamic::build($method, $parameters, $this);
}
// ---------------------------------------------------------
// Handle any of the aggregate functions.
// ---------------------------------------------------------
if (in_array($method, array('count', 'min', 'max', 'avg', 'sum')))
{
return ($method == 'count') ? $this->aggregate(Str::upper($method), '*') : $this->aggregate(Str::upper($method), $parameters[0]);
return ($method == 'count') ? $this->aggregate(strtoupper($method), '*') : $this->aggregate(strtoupper($method), $parameters[0]);
}
throw new \Exception("Method [$method] is not defined on the Query class.");
......
<?php namespace System\DB\Query;
use System\Str;
class Dynamic {
/**
* Add conditions to a query from a dynamic method call.
*
* @param string $method
* @param array $parameters
* @param Query $query
* @return Query
*/
public static function build($method, $parameters, $query)
{
// ---------------------------------------------------------
// Strip the "where_" off of the method.
// ---------------------------------------------------------
$finder = substr($method, 6);
// ---------------------------------------------------------
// Split the column names from the connectors.
// ---------------------------------------------------------
$segments = preg_split('/(_and_|_or_)/i', $finder, -1, PREG_SPLIT_DELIM_CAPTURE);
// ---------------------------------------------------------
// The connector variable will determine which connector
// will be used for the condition. We'll change it as we
// come across new connectors in the dynamic method string.
//
// The index variable helps us get the correct parameter
// value for the where condition. We increment it each time
// we add a condition.
// ---------------------------------------------------------
$connector = 'AND';
$index = 0;
// ---------------------------------------------------------
// Iterate through each segment and add the conditions.
// ---------------------------------------------------------
foreach ($segments as $segment)
{
if ($segment != '_and_' and $segment != '_or_')
{
if ( ! array_key_exists($index, $parameters))
{
throw new \Exception("Wrong number of parameters for dynamic finder [$method].");
}
$query->where($segment, '=', $parameters[$index], $connector);
$index++;
}
else
{
$connector = trim(strtoupper($segment), '_');
}
}
return $query;
}
}
\ No newline at end of file
......@@ -2,104 +2,6 @@
class File {
/**
* Extensions and their matching MIME types.
*
* @var array
*/
public static $mimes = array(
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'csv' => 'text/x-comma-separated-values',
'bin' => 'application/macbinary',
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'exe' => 'application/octet-stream',
'class' => 'application/octet-stream',
'psd' => 'application/x-photoshop',
'so' => 'application/octet-stream',
'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => 'application/pdf',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => 'application/excel',
'ppt' => 'application/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' => 'application/x-httpd-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' => 'application/x-tar',
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => 'application/x-zip',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'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' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'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' => 'text/plain',
'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' => 'application/msword',
'xl' => 'application/excel',
'eml' => 'message/rfc822'
);
/**
* Get the contents of a file.
*
......@@ -155,7 +57,35 @@ class File {
*/
public static function mime($extension, $default = 'application/octet-stream')
{
return (array_key_exists($extension, static::$mimes)) ? static::$mimes[$extension] : $default;
$mimes = Config::get('mimes');
if (array_key_exists($extension, $mimes))
{
return (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
return $default;
}
/**
* Determine if a file is a given type.
*
* The Fileinfo PHP extension will be used to determine the MIME type
* of the file. Any extension in the mimes configuration array may
* be passed as a type.
*/
public static function is($extension, $path)
{
$mimes = Config::get('mimes');
if ( ! array_key_exists($extension, $mimes))
{
throw new \Exception("File extension [$extension] is unknown. Cannot determine file type.");
}
$mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
return (is_array($mimes[$extension])) ? in_array($mime, $mimes[$extension]) : $mime === $mimes[$extension];
}
/**
......@@ -186,4 +116,20 @@ class File {
return $response;
}
/**
* Move an uploaded file to storage.
*
* @param string $key
* @param string $path
* @return bool
*/
public static function upload($key, $path)
{
if ( ! array_key_exists($key, $_FILES))
{
return false;
}
return move_uploaded_file($_FILES[$key]['tmp_name'], $path);
}
}
\ No newline at end of file
......@@ -50,6 +50,20 @@ class Form {
return $html.PHP_EOL;
}
/**
* Open a HTML form that accepts file uploads.
*
* @param string $action
* @param string $method
* @param array $attributes
* @return string
*/
public static function open_multipart($action = null, $method = 'POST', $attributes = array())
{
$attributes['enctype'] = 'multipart/form-data';
return static::open($action, $method, $attributes);
}
/**
* Close a HTML form.
*
......@@ -100,7 +114,6 @@ class Form {
public static function label($name, $value, $attributes = array())
{
static::$labels[] = $name;
return '<label for="'.$name.'"'.HTML::attributes($attributes).'>'.HTML::entities($value).'</label>'.PHP_EOL;
}
......
......@@ -21,7 +21,7 @@ class HTML {
*/
public static function script($url)
{
return '<script type="text/javascript" src="'.trim(static::entities(URL::to_asset($url)), '.js').'.js"></script>'.PHP_EOL;
return '<script type="text/javascript" src="'.static::entities(URL::to_asset($url)).'"></script>'.PHP_EOL;
}
/**
......@@ -32,7 +32,7 @@ class HTML {
*/
public static function style($url, $media = 'all')
{
return '<link href="'.trim(static::entities(URL::to_asset($url)), '.css').'.css" rel="stylesheet" type="text/css" media="'.$media.'" />'.PHP_EOL;
return '<link href="'.static::entities(URL::to_asset($url)).'" rel="stylesheet" type="text/css" media="'.$media.'" />'.PHP_EOL;
}
/**
......@@ -76,6 +76,34 @@ class HTML {
return static::link($url, $title, $attributes, false, true);
}
/**
* Generate an HTML link to a route.
*
* @param string $name
* @param string $title
* @param array $parameters
* @param array $attributes
* @return string
*/
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);
}
/**
* Generate an HTTPS HTML link to a route.
*
* @param string $name
* @param string $title
* @param array $parameters
* @param array $attributes
* @return string
*/
public static function link_to_secure_route($name, $title, $parameters = array(), $attributes = array())
{
return static::link_to_route($name, $title, $parameters, $attributes, true);
}
/**
* Generate an HTML mailto link.
*
......@@ -250,4 +278,28 @@ class HTML {
return $safe;
}
/**
* Magic Method for handling dynamic static methods.
*/
public static function __callStatic($method, $parameters)
{
// -------------------------------------------------------
// Handle the dynamic creation of links to secure routes.
// -------------------------------------------------------
if (strpos($method, 'link_to_secure_') === 0)
{
array_unshift($parameters, substr($method, 15));
return forward_static_call_array('HTML::link_to_secure_route', $parameters);
}
// -------------------------------------------------------
// Handle the dynamic creation of links to routes.
// -------------------------------------------------------
if (strpos($method, 'link_to_') === 0)
{
array_unshift($parameters, substr($method, 8));
return forward_static_call_array('HTML::link_to_route', $parameters);
}
}
}
\ No newline at end of file
......@@ -126,7 +126,7 @@ class Inflector {
return static::$plural_cache[$value];
}
if (in_array(Str::lower($value), static::$uncountable))
if (in_array(strtolower($value), static::$uncountable))
{
return static::$plural_cache[$value] = $value;
}
......@@ -165,7 +165,7 @@ class Inflector {
return static::$singular_cache[$value];
}
if (in_array(Str::lower($value), static::$uncountable))
if (in_array(strtolower($value), static::$uncountable))
{
return static::$singular_cache[$value] = $value;
}
......
......@@ -69,6 +69,18 @@ class Input {
return Arr::get(Session::get('laravel_old_input', array()), $key, $default);
}
/**
* Get an item from the uploaded file data.
*
* @param string $key
* @param mixed $default
* @return array
*/
public static function file($key = null, $default = null)
{
return Arr::get($_FILES, $key, $default);
}
/**
* Hydrate the input data for the request.
*
......
......@@ -2,13 +2,6 @@
class Lang {
/**
* All of the loaded language files.
*
* @var array
*/
private static $loaded = array();
/**
* All of the loaded language lines.
*
......@@ -55,24 +48,30 @@ class Lang {
}
/**
* Get the language line for a given language.
* Get the language line.
*
* @param string $language
* @param mixed $default
* @return string
*/
public function get($language = null)
{
if (is_null($language))
public function get($default = null)
{
$language = Config::get('application.language');
}
list($file, $line) = $this->parse($this->key);
$this->load($file, $language);
// --------------------------------------------------------------
// If the language file did not exist, return the default value.
// --------------------------------------------------------------
if ( ! array_key_exists($language.$file, static::$lines))
{
return $default;
}
// --------------------------------------------------------------
// Get the language line from the appropriate file array.
// If the line doesn't exist, return the default value.
// --------------------------------------------------------------
if (array_key_exists($line, static::$lines[$language.$file]))
{
......@@ -80,7 +79,7 @@ class Lang {
}
else
{
throw new \Exception("Language line [$line] does not exist for language [$language]");
return $default;
}
// --------------------------------------------------------------
......@@ -127,28 +126,16 @@ class Lang {
private function load($file, $language)
{
// --------------------------------------------------------------
// If we have already loaded the language file, bail out.
// If we have already loaded the language file or the file
// doesn't exist, bail out.
// --------------------------------------------------------------
if (in_array($language.$file, static::$loaded))
if (array_key_exists($language.$file, static::$lines) or ! file_exists($path = APP_PATH.'lang/'.$language.'/'.$file.EXT))
{
return;
}
// --------------------------------------------------------------
// Load the language file into the array of lines. The array
// is keyed by the language and file name.
// --------------------------------------------------------------
if (file_exists($path = APP_PATH.'lang/'.$language.'/'.$file.EXT))
{
static::$lines[$language.$file] = require $path;
}
else
{
throw new \Exception("Language file [$file] does not exist for language [$language].");
}
static::$loaded[] = $language.$file;
}
/**
* Set the place-holder replacements.
......
......@@ -8,12 +8,12 @@ return function($class) {
// ----------------------------------------------------------
// Replace namespace slashes with directory slashes.
// ----------------------------------------------------------
$file = System\Str::lower(str_replace('\\', '/', $class));
$file = strtolower(str_replace('\\', '/', $class));
// ----------------------------------------------------------
// Should the class be aliased?
// ----------------------------------------------------------
if (array_key_exists($class, $aliases = System\Config::get('application.aliases')))
if (array_key_exists($class, $aliases = System\Config::get('aliases')))
{
return class_alias($aliases[$class], $class);
}
......@@ -33,9 +33,9 @@ return function($class) {
require $path;
}
// ----------------------------------------------------------
// Is the class in the application/packages directory?
// Is the class in the application/libraries directory?
// ----------------------------------------------------------
elseif (file_exists($path = APP_PATH.'packages/'.$file.EXT))
elseif (file_exists($path = APP_PATH.'libraries/'.$file.EXT))
{
require $path;
}
......
......@@ -47,7 +47,7 @@ class Log {
// -----------------------------------------------------
// Create the yearly and monthly directories if needed.
// -----------------------------------------------------
static::make_directory($directory = APP_PATH.'logs/'.date('Y'));
static::make_directory($directory = APP_PATH.'storage/logs/'.date('Y'));
static::make_directory($directory .= '/'.date('m'));
// -----------------------------------------------------
......
......@@ -77,6 +77,8 @@ class Redirect {
*/
public static function __callStatic($method, $parameters)
{
$parameters = (isset($parameters[0])) ? $parameters[0] : array();
// ----------------------------------------------------
// Dynamically redirect to a secure route URL.
// ----------------------------------------------------
......
......@@ -65,24 +65,20 @@ class Request {
// -------------------------------------------------------
// Remove the application index and any extra slashes.
// -------------------------------------------------------
$uri = trim(str_replace('/index.php', '', $uri), '/');
$index = Config::get('application.index');
if (strpos($uri, '/'.$index) === 0)
{
$uri = (string) substr($uri, strlen('/'.$index));
}
$uri = trim($uri, '/');
// -------------------------------------------------------
// If the requests is to the root of the application, we
// always return a single forward slash.
// -------------------------------------------------------
return ($uri == '') ? '/' : Str::lower($uri);
}
/**
* Determine if the route handling the request is a given name.
*
* @param string $name
* @return bool
*/
public static function is($name)
{
return (is_array(static::$route->callback) and isset(static::$route->callback['name']) and static::$route->callback['name'] === $name);
return ($uri == '') ? '/' : strtolower($uri);
}
/**
......@@ -120,34 +116,45 @@ class Request {
}
}
/**
* Get the HTTP protocol for the request.
*
* @return string
*/
public static function protocol()
{
return (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
}
/**
* Determine if the request is using HTTPS.
*
* @return bool
*/
public static function secure()
public static function is_secure()
{
return (static::protocol() == 'https');
}
/**
* Get the HTTP protocol for the request.
* Determine if the request is an AJAX request.
*
* @return string
* @return bool
*/
public static function protocol()
public static function is_ajax()
{
return (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
}
/**
* Determine if the request is an AJAX request.
* Determine if the route handling the request is a given name.
*
* @param string $name
* @return bool
*/
public static function ajax()
public static function route_is($name)
{
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and Str::lower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
return (is_array(static::$route->callback) and isset(static::$route->callback['name']) and static::$route->callback['name'] === $name);
}
/**
......@@ -160,9 +167,9 @@ class Request {
//
// Example: Request::is_login()
// --------------------------------------------------------------
if (strpos($method, 'is_') === 0)
if (strpos($method, 'route_is_') === 0)
{
return static::is(substr($method, 3));
return static::route_is(substr($method, 9));
}
}
......
......@@ -63,7 +63,7 @@ class Route {
// ------------------------------------------------------------
elseif (is_array($this->callback))
{
$response = isset($this->callback['before']) ? Filter::call($this->callback['before'], array(), true) : null;
$response = isset($this->callback['before']) ? Route\Filter::call($this->callback['before'], array(), true) : null;
// ------------------------------------------------------------
// We verify that the before filters did not return a response
......@@ -80,7 +80,7 @@ class Route {
if (is_array($this->callback) and isset($this->callback['after']))
{
Filter::call($this->callback['after'], array($response));
Route\Filter::call($this->callback['after'], array($response));
}
return $response;
......
<?php namespace System;
<?php namespace System\Route;
class Filter {
......
......@@ -25,18 +25,21 @@ class Loader {
// --------------------------------------------------------------
// If the request is to the root, load the "home" routes file.
//
// Otherwise, load the route file matching the first segment of
// the URI as well as the "home" routes file.
// --------------------------------------------------------------
if ($uri == '/')
{
return require APP_PATH.'routes/home'.EXT;
}
// --------------------------------------------------------------
// Load the route file matching the first segment of the URI.
// --------------------------------------------------------------
else
{
$segments = explode('/', trim($uri, '/'));
// --------------------------------------------------------------
// If the file doesn't exist, we'll just return the "home" file.
// --------------------------------------------------------------
if ( ! file_exists(APP_PATH.'routes/'.$segments[0].EXT))
{
return require APP_PATH.'routes/home'.EXT;
......
......@@ -56,7 +56,7 @@ class Router {
if (preg_match('#^'.$key.'$#', $method.' '.$uri))
{
return Request::$route = new Route($key, $callback, Route\Parser::parameters($uri, $key));
return Request::$route = new Route($keys, $callback, Route\Parser::parameters($uri, $key));
}
}
}
......
<?php namespace System\Session\Driver;
class APC implements \System\Session\Driver {
/**
* Load a session by ID.
*
* @param string $id
* @return array
*/
public function load($id)
{
return \System\Cache::driver('apc')->get($id);
}
/**
* Save a session.
*
* @param array $session
* @return void
*/
public function save($session)
{
\System\Cache::driver('apc')->put($session['id'], $session, \System\Config::get('session.lifetime'));
}
/**
* Delete a session by ID.
*
* @param string $id
* @return void
*/
public function delete($id)
{
\System\Cache::driver('apc')->forget($id);
}
/**
* Delete all expired sessions.
*
* @param int $expiration
* @return void
*/
public function sweep($expiration)
{
// APC sessions will expire automatically.
}
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ class File implements \System\Session\Driver {
*/
public function load($id)
{
if (file_exists($path = APP_PATH.'sessions/'.$id))
if (file_exists($path = APP_PATH.'storage/sessions/'.$id))
{
return unserialize(file_get_contents($path));
}
......@@ -24,7 +24,7 @@ class File implements \System\Session\Driver {
*/
public function save($session)
{
file_put_contents(APP_PATH.'sessions/'.$session['id'], serialize($session), LOCK_EX);
file_put_contents(APP_PATH.'storage/sessions/'.$session['id'], serialize($session), LOCK_EX);
}
/**
......@@ -35,7 +35,7 @@ class File implements \System\Session\Driver {
*/
public function delete($id)
{
@unlink(APP_PATH.'sessions/'.$id);
@unlink(APP_PATH.'storage/sessions/'.$id);
}
/**
......@@ -46,7 +46,7 @@ class File implements \System\Session\Driver {
*/
public function sweep($expiration)
{
foreach (glob(APP_PATH.'sessions/*') as $file)
foreach (glob(APP_PATH.'storage/sessions/*') as $file)
{
if (filetype($file) == 'file' and filemtime($file) < $expiration)
{
......
......@@ -21,6 +21,9 @@ class Factory {
case 'memcached':
return new Driver\Memcached;
case 'apc':
return new Driver\APC;
default:
throw new \Exception("Session driver [$driver] is not supported.");
}
......
......@@ -46,6 +46,17 @@ class Str {
return (function_exists('mb_convert_case')) ? mb_convert_case($value, MB_CASE_TITLE, Config::get('application.encoding')) : ucwords(strtolower($value));
}
/**
* Get the length of a string.
*
* @param string $value
* @return int
*/
public static function length($value)
{
return function_exists('mb_strlen') ? mb_strlen($value, Config::get('application.encoding')) : strlen($value);
}
/**
* Generate a random alpha or alpha-numeric string.
*
......
......@@ -142,6 +142,8 @@ class URL {
*/
public static function __callStatic($method, $parameters)
{
$parameters = (isset($parameters[0])) ? $parameters[0] : array();
// ----------------------------------------------------
// Dynamically create a secure route URL.
// ----------------------------------------------------
......
<?php namespace System\Validation;
class Error_Collector {
/**
* All of the error messages.
*
* @var array
*/
public $messages;
/**
* Create a new Error Collector instance.
*
* @return void
*/
public function __construct($messages = array())
{
$this->messages = $messages;
}
/**
* Add an error message to the collector.
*
* Duplicate messages will not be added.
*
* @param string $attribute
* @param string $message
* @return void
*/
public function add($attribute, $message)
{
// -------------------------------------------------------------
// Make sure the error message is not duplicated.
//
// For example, the Nullable rules can add a "required" message.
// If the same message has already been added we don't want to
// add it again.
// -------------------------------------------------------------
if ( ! array_key_exists($attribute, $this->messages) or ! is_array($this->messages[$attribute]) or ! in_array($message, $this->messages[$attribute]))
{
$this->messages[$attribute][] = $message;
}
}
/**
* Determine if errors exist for an attribute.
*
* @param string $attribute
* @return bool
*/
public function has($attribute)
{
return $this->first($attribute) !== '';
}
/**
* Get the first error message for an attribute.
*
* @param string $attribute
* @return string
*/
public function first($attribute)
{
return (count($messages = $this->get($attribute)) > 0) ? $messages[0] : '';
}
/**
* Get all of the error messages for an attribute.
*
* If no attribute is specified, all of the error messages will be returned.
*
* @param string $attribute
* @param string $format
* @return array
*/
public function get($attribute = null, $format = ':message')
{
if (is_null($attribute))
{
return $this->all($format);
}
return (array_key_exists($attribute, $this->messages)) ? $this->format($this->messages[$attribute], $format) : array();
}
/**
* Get all of the error messages.
*
* @param string $format
* @return array
*/
public function all($format = ':message')
{
$all = array();
// ---------------------------------------------------------
// Add each error message to the array of messages. Each
// messages will have the specified format applied to it.
// ---------------------------------------------------------
foreach ($this->messages as $messages)
{
$all = array_merge($all, $this->format($messages, $format));
}
return $all;
}
/**
* Format an array of messages.
*
* @param array $messages
* @param string $format
* @return array
*/
private function format($messages, $format)
{
array_walk($messages, function(&$message, $key) use ($format) { $message = str_replace(':message', $message, $format); });
return $messages;
}
}
\ No newline at end of file
<?php namespace System\Validation;
use System\Str;
use System\Lang;
class Message {
/**
* Get the appropriate validation message for a rule attribute.
*
* @param Rule $rule
* @param string $attribute
* @return string
*/
public static function get($rule, $attribute)
{
if ($rule instanceof Rangable_Rule)
{
$message = static::get_rangable_message($rule);
}
elseif ($rule instanceof Rules\Upload_of)
{
$message = static::get_upload_of_message($rule);
}
else
{
$message = static::get_message($rule);
}
return static::prepare($rule, $attribute, $message);
}
/**
* Get the error message for a typical validation rule.
*
* @param Rule $rule
* @return string
*/
private static function get_message($rule)
{
// ---------------------------------------------------------
// The built-in error messages are stored in the language
// directory and are keyed by the class name of the rule
// they are associated with.
// ---------------------------------------------------------
if (is_null($rule->error))
{
$class = explode('\\', get_class($rule));
$rule->error = strtolower(end($class));
}
return (is_null($rule->message)) ? Lang::line('validation.'.$rule->error)->get() : $rule->message;
}
/**
* Get the error message for a Rangable rule.
*
* @param Rule $rule
* @return string
*/
private static function get_rangable_message($rule)
{
// ---------------------------------------------------------
// Rangable rules sometimes set a "presence_of" error.
//
// This occurs when an attribute is null and the option to
// allow null values has not been set.
// ---------------------------------------------------------
if ($rule->error == 'presence_of')
{
return static::get_message($rule);
}
// ---------------------------------------------------------
// Slice "number_" or "string_" off of the error type.
// ---------------------------------------------------------
$error_type = substr($rule->error, 7);
return (is_null($rule->$error_type)) ? Lang::line('validation.'.$rule->error)->get() : $rule->$error_type;
}
/**
* Get the error message for an Upload_Of rule.
*
* @param Rule $rule
* @return string
*/
private static function get_upload_of_message($rule)
{
// ---------------------------------------------------------
// Slice "file_" off of the error type.
// ---------------------------------------------------------
$error_type = substr($rule->error, 5);
return (is_null($rule->$error_type)) ? Lang::line('validation.'.$rule->error)->get() : $rule->$error_type;
}
/**
* Prepare an error message for display. All place-holders will be replaced
* with their actual values.
*
* @param Rule $rule
* @param string $attribute
* @param string $message
* @return string
*/
private static function prepare($rule, $attribute, $message)
{
// ---------------------------------------------------------
// The rangable rule messages have three place-holders that
// must be replaced.
//
// :max = The maximum size of the attribute.
// :min = The minimum size of the attribute.
// :size = The exact size the attribute must be.
// ---------------------------------------------------------
if ($rule instanceof Rangable_Rule)
{
$message = str_replace(':max', $rule->maximum, $message);
$message = str_replace(':min', $rule->minimum, $message);
$message = str_replace(':size', $rule->size, $message);
}
// ---------------------------------------------------------
// The Upload_Of rule message have two place-holders taht
// must be replaced.
//
// :max = The maximum file size of the upload (kilobytes).
// :types = The allowed file types for the upload.
// ---------------------------------------------------------
elseif ($rule instanceof Rules\Upload_Of)
{
$message = str_replace(':max', $rule->maximum, $message);
if (is_array($rule->types))
{
$message = str_replace(':types', implode(', ', $rule->types), $message);
}
}
return str_replace(':attribute', Lang::line('attributes.'.$attribute)->get(str_replace('_', ' ', $attribute)), $message);
}
}
\ No newline at end of file
<?php namespace System\Validation;
use System\Str;
abstract class Nullable_Rule extends Rule {
/**
* Indicates an empty value should be considered valid.
*
* @var bool
*/
public $allow_empty = false;
/**
* Indicates null should be considered valid.
*
* @var bool
*/
public $allow_null = false;
/**
* Evaluate the validity of an attribute.
*
* If this method returns a value, the child class will return it
* as the result of the validation. Otherwise, the child class will
* continue validating as normal.
*
* @param string $attribute
* @param array $attributes
* @return mixed
*/
public function check($attribute, $attributes)
{
// -------------------------------------------------------------
// If the attribute doesn't exist, the child's validation
// check will be be halted, and a presence_of error will be
// raised if null is not allowed.
// -------------------------------------------------------------
if ( ! array_key_exists($attribute, $attributes))
{
if ( ! $this->allow_null)
{
$this->error = 'presence_of';
}
return is_null($this->error);
}
// -------------------------------------------------------------
// Make sure the attribute is not an empty string. An error
// will be raised if the attribute is empty and empty strings
// are not allowed, halting the child's validation.
// -------------------------------------------------------------
elseif (Str::length((string) $attributes[$attribute]) == 0 and ! $this->allow_empty)
{
$this->error = 'presence_of';
return false;
}
}
/**
* Allow a empty and null to be considered valid.
*
* @return Nullable_Rule
*/
public function not_required()
{
return $this->allow_empty()->allow_null();
}
/**
* Allow empty to be considered valid.
*
* @return Nullable_Rule
*/
public function allow_empty()
{
$this->allow_empty = true;
return $this;
}
/**
* Allow null to be considered valid.
*
* @return Nullable_Rule
*/
public function allow_null()
{
$this->allow_null = true;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation;
abstract class Rangable_Rule extends Nullable_Rule {
/**
* The exact size the attribute must be.
*
* @var int
*/
public $size;
/**
* The maximum size of the attribute.
*
* @var int
*/
public $maximum;
/**
* The minimum size of the attribute.
*
* @var int
*/
public $minimum;
/**
* The "wrong size" error message.
*
* @var string
*/
public $wrong_size;
/**
* The "too big" error message.
*
* @var string
*/
public $too_big;
/**
* The "too small" error message.
*
* @var string
*/
public $too_small;
/**
* Set the exact size the attribute must be.
*
* @param int $size
* @return Rangable_Rule
*/
public function is($size)
{
$this->size = $size;
return $this;
}
/**
* Set the minimum and maximum size of the attribute.
*
* @param int $minimum
* @param int $maximum
* @return Rangable_Rule
*/
public function between($minimum, $maximum)
{
$this->minimum = $minimum;
$this->maximum = $maximum;
return $this;
}
/**
* Set the minimum size the attribute.
*
* @param int $minimum
* @return Rangable_Rule
*/
public function minimum($minimum)
{
$this->minimum = $minimum;
return $this;
}
/**
* Set the maximum size the attribute.
*
* @param int $maximum
* @return Rangable_Rule
*/
public function maximum($maximum)
{
$this->maximum = $maximum;
return $this;
}
/**
* Set the validation error message.
*
* @param string $message
* @return Rangable_Rule
*/
public function message($message)
{
return $this->wrong_size($message)->too_big($message)->too_small($message);
}
/**
* Set the "wrong size" error message.
*
* @param string $message
* @return Rangable_Rule
*/
public function wrong_size($message)
{
$this->wrong_size = $message;
return $this;
}
/**
* Set the "too big" error message.
*
* @param string $message
* @return Rangable_Rule
*/
public function too_big($message)
{
$this->too_big = $message;
return $this;
}
/**
* Set the "too small" error message.
*
* @param string $message
* @return Rangable_Rule
*/
public function too_small($message)
{
$this->too_small = $message;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation;
use System\Lang;
abstract class Rule {
/**
* The attributes being validated by the rule.
*
* @var array
*/
public $attributes;
/**
* The validation error message.
*
* @var string
*/
public $message;
/**
* The error type. This is used for rules that have more than
* one type of error such as Size_Of and Upload_Of.
*
* @var string
*/
public $error;
/**
* Create a new validation Rule instance.
*
* @param array $attributes
* @return void
*/
public function __construct($attributes)
{
$this->attributes = $attributes;
}
/**
* Run the validation rule.
*
* @param array $attributes
* @param Error_Collector $errors
* @return void
*/
public function validate($attributes, $errors)
{
foreach ($this->attributes as $attribute)
{
$this->error = null;
if ( ! $this->check($attribute, $attributes))
{
$errors->add($attribute, Message::get($this, $attribute));
}
}
}
/**
* Set the validation error message.
*
* @param string $message
* @return Rule
*/
public function message($message)
{
$this->message = $message;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Input;
use System\Validation\Rule;
class Acceptance_Of extends Rule {
/**
* The value is that is considered accepted.
*
* @var string
*/
public $accepts = '1';
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
return Input::has($attribute) and (string) Input::get($attribute) === $this->accepts;
}
/**
* Set the accepted value.
*
* @param string $value
* @return Acceptance_Of
*/
public function accepts($value)
{
$this->accepts = $value;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Input;
use System\Validation\Rule;
class Confirmation_Of extends Rule {
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
return Input::has($attribute.'_confirmation') and $attributes[$attribute] === Input::get($attribute.'_confirmation');
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Nullable_Rule;
class Exclusion_Of extends Nullable_Rule {
/**
* The reserved values for the attribute.
*
* @var string
*/
public $reserved;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
return ! in_array($attributes[$attribute], $this->reserved);
}
/**
* Set the reserved values for the attribute
*
* @param array $reserved
* @return Exclusion_Of
*/
public function from($reserved)
{
$this->reserved = $reserved;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Nullable_Rule;
class Format_Of extends Nullable_Rule {
/**
* The regular expression that will be used to validate the attribute.
*
* @var string
*/
public $expression;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
return preg_match($this->expression, $attributes[$attribute]);
}
/**
* Set the regular expression.
*
* @param string $expression
* @return Format_Of
*/
public function using($expression)
{
$this->expression = $expression;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Nullable_Rule;
class Inclusion_Of extends Nullable_Rule {
/**
* The accepted values for the attribute.
*
* @var string
*/
public $accepted;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
return in_array($attributes[$attribute], $this->accepted);
}
/**
* Set the accepted values for the attribute.
*
* @param array $accepted
* @return Inclusion_Of
*/
public function in($accepted)
{
$this->accepted = $accepted;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Str;
use System\Validation\Rangable_Rule;
class Length_Of extends Rangable_Rule {
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
$value = trim((string) $attributes[$attribute]);
// ---------------------------------------------------------
// Validate the exact length of the attribute.
// ---------------------------------------------------------
if ( ! is_null($this->size) and Str::length($value) !== $this->size)
{
$this->error = 'string_wrong_size';
}
// ---------------------------------------------------------
// Validate the maximum length of the attribute.
// ---------------------------------------------------------
elseif ( ! is_null($this->maximum) and Str::length($value) > $this->maximum)
{
$this->error = 'string_too_big';
}
// ---------------------------------------------------------
// Validate the minimum length of the attribute.
// ---------------------------------------------------------
elseif ( ! is_null($this->minimum) and Str::length($value) < $this->minimum)
{
$this->error = 'string_too_small';
}
return is_null($this->error);
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Rangable_Rule;
class Numericality_Of extends Rangable_Rule {
/**
* Indicates that the attribute must be an integer.
*
* @var bool
*/
public $only_integer = false;
/**
* The "not valid" error message.
*
* @var string
*/
public $not_valid;
/**
* The "not integer" error message.
*
* @var string
*/
public $not_integer;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
// ---------------------------------------------------------
// Validate the attribute is a number.
// ---------------------------------------------------------
if ( ! is_numeric($attributes[$attribute]))
{
$this->error = 'number_not_valid';
}
// ---------------------------------------------------------
// Validate the attribute is an integer.
// ---------------------------------------------------------
elseif ($this->only_integer and filter_var($attributes[$attribute], FILTER_VALIDATE_INT) === false)
{
$this->error = 'number_not_integer';
}
// ---------------------------------------------------------
// Validate the exact size of the attribute.
// ---------------------------------------------------------
elseif ( ! is_null($this->size) and $attributes[$attribute] != $this->size)
{
$this->error = 'number_wrong_size';
}
// ---------------------------------------------------------
// Validate the maximum size of the attribute.
// ---------------------------------------------------------
elseif ( ! is_null($this->maximum) and $attributes[$attribute] > $this->maximum)
{
$this->error = 'number_too_big';
}
// ---------------------------------------------------------
// Validate the minimum size of the attribute.
// ---------------------------------------------------------
elseif ( ! is_null($this->minimum) and $attributes[$attribute] < $this->minimum)
{
$this->error = 'number_too_small';
}
return is_null($this->error);
}
/**
* Specify that the attribute must be an integer.
*
* @return Numericality_Of
*/
public function only_integer()
{
$this->only_integer = true;
return $this;
}
/**
* Set the "not valid" error message.
*
* @param string $message
* @return Numericality_Of
*/
public function not_valid($message)
{
$this->not_valid = $message;
return $this;
}
/**
* Set the "not integer" error message.
*
* @param string $message
* @return Numericality_Of
*/
public function not_integer($message)
{
$this->not_integer = $message;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Nullable_Rule;
class Presence_Of extends Nullable_Rule {
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
// ---------------------------------------------------------
// The Nullable_Rule check method essentially is a check for
// the presence of an attribute, so there is no further
// checking that needs to be done.
// ---------------------------------------------------------
return true;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\DB;
use System\Validation\Nullable_Rule;
class Uniqueness_Of extends Nullable_Rule {
/**
* The database table that should be checked.
*
* @var string
*/
public $table;
/**
* The database column that should be checked.
*
* @var string
*/
public $column;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
if (is_null($this->column))
{
$this->column = $attribute;
}
return DB::table($this->table)->where($this->column, '=', $attributes[$attribute])->count() == 0;
}
/**
* Set the database table and column.
*
* The attribute name will be used as the column name if no other
* column name is specified.
*
* @param string $table
* @param string $column
* @return Uniqueness_Of
*/
public function on($table, $column = null)
{
$this->table = $table;
$this->column = $column;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\File;
use System\Input;
use System\Validation\Nullable_Rule;
class Upload_Of extends Nullable_Rule {
/**
* The acceptable file types.
*
* @var array
*/
public $types = array();
/**
* The maximum file size in bytes.
*
* @var int
*/
public $maximum;
/**
* The "wrong type" error message.
*
* @var string
*/
public $wrong_type;
/**
* The "too big" error message.
*
* @var string
*/
public $too_big;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
// -----------------------------------------------------
// Check the presence of the upload. If the upload does
// not exist and the upload is required, a presence_of
// error will be raised.
//
// Otherwise no error will be raised.
// -----------------------------------------------------
if ( ! array_key_exists($attribute, Input::file()))
{
if ( ! $this->allow_null)
{
$this->error = 'presence_of';
}
return is_null($this->error);
}
// -----------------------------------------------------
// Uploaded files are stored in the $_FILES array, so
// we use that array instead of the $attributes.
// -----------------------------------------------------
$file = Input::file($attribute);
if ( ! is_null($this->maximum) and $file['size'] > $this->maximum * 1000)
{
$this->error = 'file_too_big';
}
// -----------------------------------------------------
// The File::is method uses the Fileinfo PHP extension
// to determine the MIME type of the file.
// -----------------------------------------------------
foreach ($this->types as $type)
{
if (File::is($type, $file['tmp_name']))
{
break;
}
$this->error = 'file_wrong_type';
}
return is_null($this->error);
}
/**
* Set the acceptable file types.
*
* @return Upload_Of
*/
public function is()
{
$this->types = func_get_args();
return $this;
}
/**
* Require that the uploaded file is an image type.
*
* @return Upload_Of
*/
public function is_image()
{
$this->types = array_merge($this->types, array('jpg', 'gif', 'png', 'bmp'));
return $this;
}
/**
* Set the maximum file size in kilobytes.
*
* @param int $maximum
* @return Upload_Of
*/
public function maximum($maximum)
{
$this->maximum = $maximum;
return $this;
}
/**
* Set the validation error message.
*
* @param string $message
* @return Upload_Of
*/
public function message($message)
{
return $this->wrong_type($message)->too_big($message);
}
/**
* Set the "wrong type" error message.
*
* @param string $message
* @return Upload_Of
*/
public function wrong_type($message)
{
$this->wrong_type = $message;
return $this;
}
/**
* Set the "too big" error message.
*
* @param string $message
* @return Upload_Of
*/
public function too_big($message)
{
$this->too_big = $message;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Nullable_Rule;
class With_Callback extends Nullable_Rule {
/**
* The callback that will be used to validate the attribute.
*
* @var function
*/
public $callback;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return bool
*/
public function check($attribute, $attributes)
{
if ( ! is_callable($this->callback))
{
throw new \Exception("The validation callback for the [$attribute] attribute is not callable.");
}
if ( ! is_null($nullable = parent::check($attribute, $attributes)))
{
return $nullable;
}
return call_user_func($this->callback, $attributes[$attribute]);
}
/**
* Set the validation callback.
*
* @param function $callback
* @return With_Callback
*/
public function using($callback)
{
$this->callback = $callback;
return $this;
}
}
\ No newline at end of file
<?php namespace System;
class Validator {
/**
* The attributes being validated.
*
* @var array
*/
public $attributes;
/**
* The validation error collector.
*
* @var Error_Collector
*/
public $errors;
/**
* The validation rules.
*
* @var array
*/
public $rules = array();
/**
* Create a new Validator instance.
*
* @param mixed $target
* @return void
*/
public function __construct($target = array())
{
$this->errors = new Validation\Error_Collector;
// ---------------------------------------------------------
// If the source is an Eloquent model, use the model's
// attributes as the validation attributes.
// ---------------------------------------------------------
$this->attributes = ($target instanceof DB\Eloquent) ? $target->attributes : (array) $target;
}
/**
* Create a new Validator instance.
*
* @param mixed $target
* @return Validator
*/
public static function make($target = array())
{
return new static($target);
}
/**
* Determine if the attributes pass all of the validation rules.
*
* @return bool
*/
public function is_valid()
{
$this->errors->messages = array();
foreach ($this->rules as $rule)
{
// ---------------------------------------------------------
// The error collector is passed to the rule so that the
// rule may conveniently add error messages.
// ---------------------------------------------------------
$rule->validate($this->attributes, $this->errors);
}
return count($this->errors->messages) == 0;
}
/**
* Magic Method for dynamically creating validation rules.
*/
public function __call($method, $parameters)
{
// ---------------------------------------------------------
// Check if the validation rule is defined in the rules
// directory. If it is, create a new rule and return it.
// ---------------------------------------------------------
if (file_exists(SYS_PATH.'validation/rules/'.$method.EXT))
{
$rule = '\\System\\Validation\\Rules\\'.$method;
return $this->rules[] = new $rule($parameters);
}
throw new \Exception("Method [$method] does not exist on Validator class.");
}
}
\ No newline at end of file
......@@ -85,6 +85,9 @@ class View {
// We include the view into the local scope within a
// try / catch block to catch any exceptions that may
// occur while the view is rendering.
//
// Otherwise, a white screen of death will be shown
// if an exception occurs while rendering the view.
// -----------------------------------------------------
try
{
......@@ -101,9 +104,8 @@ class View {
/**
* Get the full path to the view.
*
* Views are cascaded, so the application directory views
* will take precedence over the system directory's views
* of the same name.
* Views are cascaded, so the application directory views will take
* precedence over system directory views of the same name.
*
* @return string
*/
......
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