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( ...@@ -80,45 +80,4 @@ return array(
'key' => '', '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( ...@@ -12,12 +12,24 @@ return array(
| Caching can be used to increase the performance of your application | Caching can be used to increase the performance of your application
| by storing commonly accessed data in memory or in a file. | by storing commonly accessed data in memory or in a file.
| |
| Supported Drivers: 'file', 'memcached'. | Supported Drivers: 'file', 'memcached', 'apc'.
| |
*/ */
'driver' => 'file', '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 | Memcached Servers
...@@ -35,18 +47,6 @@ return array( ...@@ -35,18 +47,6 @@ return array(
'servers' => array( 'servers' => array(
array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), 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( ...@@ -12,7 +12,7 @@ return array(
| Since HTTP is stateless, sessions are used to maintain "state" across | Since HTTP is stateless, sessions are used to maintain "state" across
| multiple requests from the same user of your application. | 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 @@ ...@@ -4,74 +4,76 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Welcome To Laravel!</title> <title>Welcome To Laravel!</title>
<link href="http://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet" type="text/css" media="all" /> <link href="http://fonts.googleapis.com/css?family=Quattrocento&amp;v1" 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=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"> <style type="text/css">
body { body {
background-color: #fff; background-color: #eee;
font-family: 'Ubuntu', sans-serif;
font-size: 16px;
color: #3f3f3f;
}
h1 {
font-size: 40px;
color: #6d6d6d; color: #6d6d6d;
margin: 0 0 10px 0; font-family: 'Ubuntu';
text-shadow: 1px 1px #000; font-size: 15px;
} }
a { a {
color: #000; color: #7089b3;
font-weight: bold;
text-decoration: none;
} }
#wrapper { h1.laravel {
width: 740px; font-family: 'Lobster Two', Helvetica, serif;
font-size: 60px;
margin: 0 0 15px -10px;
padding: 0;
text-shadow: -1px 1px 1px #fff;
} }
#content { h2 {
padding: 10px 10px 10px 10px; font-family: 'Quattrocento', serif;
background-color: #eee; font-size: 30px;
margin: 30px 0 0 0;
padding: 0;
text-shadow: -1px 1px 1px #fff;
}
p {
margin: 10px 0 0 0;
line-height: 25px;
}
#wrapper {
background-color: #fff;
border-radius: 10px; border-radius: 10px;
margin: 0 auto;
padding: 10px;
width: 80%;
} }
#footer { #wrapper h2:first-of-type {
font-size: 12px; margin-top: 0;
padding-top: 10px;
text-align: right;
} }
</style>
<script type="text/javascript"> #header {
$(document).ready(function(){ margin: 0 auto;
$(window).resize(function(){ margin-bottom: 15px;
$('#wrapper').css({ margin-top: 20px;
position:'absolute', width: 80%;
left: ($(window).width() - $('#wrapper').outerWidth()) / 2, }
top: ($(window).height() - $('#wrapper').outerHeight()) / 3 </style>
});
});
$(window).resize();
});
</script>
</head> </head>
<body> <body>
<div id="wrapper"> <div id="header">
<h1>Laravel</h1> <h1 class="laravel">Laravel</h1>
</div>
<div id="content">
You have successfully installed Laravel.
<br /><br /> <div id="wrapper">
<h2>Installation Complete!</h2>
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>? <p>Ready to dig in? Start building your application in the <strong>application/routes.php</strong> file.</p>
</div>
<div id="footer"> <p>Need to learn more? Peruse our <a href="http://laravel.com/docs">wonderful documentation</a>.</p>
<?php echo Benchmark::memory(); ?>mb &middot; <?php echo Benchmark::check('laravel'); ?>ms </div>
</div>
</div>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Laravel - A clean and classy framework for PHP web development. * Laravel - A clean and classy framework for PHP web development.
* *
* @package Laravel * @package Laravel
* @version 1.0.0 Beta 2 * @version 1.1.0
* @author Taylor Otwell * @author Taylor Otwell
* @license MIT License * @license MIT License
* @link http://laravel.com * @link http://laravel.com
...@@ -17,10 +17,11 @@ define('LARAVEL_START', microtime(true)); ...@@ -17,10 +17,11 @@ define('LARAVEL_START', microtime(true));
// -------------------------------------------------------------- // --------------------------------------------------------------
// Define the framework paths. // Define the framework paths.
// -------------------------------------------------------------- // --------------------------------------------------------------
define('BASE_PATH', realpath('../').'/');
define('APP_PATH', realpath('../application').'/'); define('APP_PATH', realpath('../application').'/');
define('SYS_PATH', realpath('../system').'/'); define('SYS_PATH', realpath('../system').'/');
define('BASE_PATH', realpath('../').'/');
define('PUBLIC_PATH', realpath(__DIR__.'/')); define('PUBLIC_PATH', realpath(__DIR__.'/'));
define('PACKAGE_PATH', APP_PATH.'packages/');
// -------------------------------------------------------------- // --------------------------------------------------------------
// Define the PHP file extension. // Define the PHP file extension.
...@@ -28,21 +29,15 @@ define('PUBLIC_PATH', realpath(__DIR__.'/')); ...@@ -28,21 +29,15 @@ define('PUBLIC_PATH', realpath(__DIR__.'/'));
define('EXT', '.php'); define('EXT', '.php');
// -------------------------------------------------------------- // --------------------------------------------------------------
// Load the configuration, error, and string classes. // Load the configuration class.
// -------------------------------------------------------------- // --------------------------------------------------------------
require SYS_PATH.'config'.EXT; require SYS_PATH.'config'.EXT;
require SYS_PATH.'str'.EXT;
// -------------------------------------------------------------- // --------------------------------------------------------------
// Register the auto-loader. // Register the auto-loader.
// -------------------------------------------------------------- // --------------------------------------------------------------
spl_autoload_register(require SYS_PATH.'loader'.EXT); 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. // Set the error reporting level.
// -------------------------------------------------------------- // --------------------------------------------------------------
...@@ -88,7 +83,7 @@ if (System\Config::get('session.driver') != '') ...@@ -88,7 +83,7 @@ if (System\Config::get('session.driver') != '')
// -------------------------------------------------------------- // --------------------------------------------------------------
// Execute the global "before" filter. // 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 // Only execute the route function if the "before" filter did
...@@ -121,7 +116,7 @@ else ...@@ -121,7 +116,7 @@ else
// ---------------------------------------------------------- // ----------------------------------------------------------
// Execute the global "after" filter. // Execute the global "after" filter.
// ---------------------------------------------------------- // ----------------------------------------------------------
System\Filter::call('after', array($response)); System\Route\Filter::call('after', array($response));
// ---------------------------------------------------------- // ----------------------------------------------------------
// Stringify the response. // Stringify the response.
......
# Laravel - A Clean & Classy PHP Framework # 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 { ...@@ -34,12 +34,12 @@ class File implements \System\Cache\Driver {
return $this->items[$key]; return $this->items[$key];
} }
if ( ! file_exists(APP_PATH.'cache/'.$key)) if ( ! file_exists(APP_PATH.'storage/cache/'.$key))
{ {
return $default; 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 // Has the cache expired? The UNIX expiration time
...@@ -65,7 +65,7 @@ class File implements \System\Cache\Driver { ...@@ -65,7 +65,7 @@ class File implements \System\Cache\Driver {
*/ */
public function put($key, $value, $minutes) 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 { ...@@ -76,7 +76,7 @@ class File implements \System\Cache\Driver {
*/ */
public function forget($key) 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 { ...@@ -18,6 +18,9 @@ class Factory {
case 'memcached': case 'memcached':
return new Driver\Memcached; return new Driver\Memcached;
case 'apc':
return new Driver\APC;
default: default:
throw new \Exception("Cache driver [$driver] is not supported."); throw new \Exception("Cache driver [$driver] is not supported.");
} }
......
...@@ -9,35 +9,57 @@ class Config { ...@@ -9,35 +9,57 @@ class Config {
*/ */
private static $items = array(); 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. * Get a configuration item.
* *
* @param string $key * @param string $key
* @param string $default
* @return mixed * @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 // If a dot is not present, we will just return the
// entire configuration array. // entire configuration array.
//
// If the configuration file does not exist, the default
// value will be returned.
// ----------------------------------------------------- // -----------------------------------------------------
if(strpos($key, '.') === false) if(strpos($key, '.') === false)
{ {
static::load($key); static::load($key);
return static::$items[$key]; return (array_key_exists($key, static::$items)) ? static::$items[$key] : $default;
} }
list($file, $key) = static::parse($key); list($file, $key) = static::parse($key);
static::load($file); 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 { ...@@ -91,18 +113,13 @@ class Config {
public static function load($file) 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; 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. // Load the configuration array into the array of items.
// The items array is keyed by filename. // The items array is keyed by filename.
......
...@@ -66,11 +66,11 @@ class DB { ...@@ -66,11 +66,11 @@ class DB {
// //
// For all other statements, return a boolean. // 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'); 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(); return $query->rowCount();
} }
...@@ -105,4 +105,22 @@ class DB { ...@@ -105,4 +105,22 @@ class DB {
return static::connection($connection)->getAttribute(\PDO::ATTR_DRIVER_NAME); 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 { ...@@ -33,7 +33,7 @@ class Connector {
// If the database doesn't exist there, maybe the full // If the database doesn't exist there, maybe the full
// path was specified as the database name? // 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); return new \PDO('sqlite:'.$path, null, null, static::$options);
} }
...@@ -41,14 +41,31 @@ class Connector { ...@@ -41,14 +41,31 @@ class Connector {
{ {
return new \PDO('sqlite:'.$config->database, null, null, static::$options); 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. // Connect to MySQL or Postgres.
// ----------------------------------------------------- // -----------------------------------------------------
elseif ($config->driver == 'mysql' or $config->driver == 'pgsql') 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)) if (isset($config->charset))
{ {
$connection->prepare("SET NAMES '".$config->charset."'")->execute(); $connection->prepare("SET NAMES '".$config->charset."'")->execute();
......
<?php namespace System\DB; <?php namespace System\DB;
use System\Str; use System\Str;
use System\Config;
use System\Inflector; use System\Inflector;
abstract class Eloquent { abstract class Eloquent {
...@@ -102,7 +103,7 @@ abstract class Eloquent { ...@@ -102,7 +103,7 @@ abstract class Eloquent {
return $class::$table; return $class::$table;
} }
return Str::lower(Inflector::plural($class)); return strtolower(Inflector::plural($class));
} }
/** /**
...@@ -213,7 +214,7 @@ abstract class Eloquent { ...@@ -213,7 +214,7 @@ abstract class Eloquent {
// For example, the foreign key for a User model would // For example, the foreign key for a User model would
// be user_id. Photo would be photo_id, etc. // 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); return static::make($model)->where($this->relating_key, '=', $this->id);
} }
...@@ -276,7 +277,7 @@ abstract class Eloquent { ...@@ -276,7 +277,7 @@ abstract class Eloquent {
sort($models); 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 { ...@@ -286,11 +287,11 @@ abstract class Eloquent {
// //
// This is the same convention as has_one and has_many. // 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) return static::make($model)
->select(static::table($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); ->where($this->relating_table.'.'.$this->relating_key, '=', $this->id);
} }
...@@ -365,7 +366,7 @@ abstract class Eloquent { ...@@ -365,7 +366,7 @@ abstract class Eloquent {
// ----------------------------------------------------- // -----------------------------------------------------
if ($this->exists) 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); return $this->query->delete($id);
...@@ -477,7 +478,7 @@ abstract class Eloquent { ...@@ -477,7 +478,7 @@ abstract class Eloquent {
{ {
$model = static::make(get_called_class()); $model = static::make(get_called_class());
if ($method == 'get') if ($method == 'get' or $method == 'all')
{ {
return $model->_get(); return $model->_get();
} }
......
...@@ -78,8 +78,9 @@ class Hydrator { ...@@ -78,8 +78,9 @@ class Hydrator {
// ----------------------------------------------------- // -----------------------------------------------------
// Get the relationship Eloquent model. // Get the relationship Eloquent model.
// //
// We temporarily spoof the "belongs_to" key to allow // We temporarily spoof the belongs_to key to allow the
// the query to be fetched without any problems. // query to be fetched without any problems, since the
// belongs_to method actually gets the attribute.
// ----------------------------------------------------- // -----------------------------------------------------
$eloquent->attributes[$spoof = $include.'_id'] = 0; $eloquent->attributes[$spoof = $include.'_id'] = 0;
......
...@@ -326,7 +326,7 @@ class Query { ...@@ -326,7 +326,7 @@ class Query {
*/ */
public function order_by($column, $direction) public function order_by($column, $direction)
{ {
$this->orderings[] = $this->wrap($column).' '.Str::upper($direction); $this->orderings[] = $this->wrap($column).' '.strtoupper($direction);
return $this; return $this;
} }
...@@ -500,9 +500,23 @@ class Query { ...@@ -500,9 +500,23 @@ class Query {
*/ */
public function __call($method, $parameters) 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'))) 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."); 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 @@ ...@@ -2,104 +2,6 @@
class File { 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. * Get the contents of a file.
* *
...@@ -155,7 +57,35 @@ class File { ...@@ -155,7 +57,35 @@ class File {
*/ */
public static function mime($extension, $default = 'application/octet-stream') 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 { ...@@ -186,4 +116,20 @@ class File {
return $response; 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 { ...@@ -50,6 +50,20 @@ class Form {
return $html.PHP_EOL; 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. * Close a HTML form.
* *
...@@ -100,7 +114,6 @@ class Form { ...@@ -100,7 +114,6 @@ class Form {
public static function label($name, $value, $attributes = array()) public static function label($name, $value, $attributes = array())
{ {
static::$labels[] = $name; static::$labels[] = $name;
return '<label for="'.$name.'"'.HTML::attributes($attributes).'>'.HTML::entities($value).'</label>'.PHP_EOL; return '<label for="'.$name.'"'.HTML::attributes($attributes).'>'.HTML::entities($value).'</label>'.PHP_EOL;
} }
......
...@@ -10,7 +10,7 @@ class HTML { ...@@ -10,7 +10,7 @@ class HTML {
*/ */
public static function entities($value) public static function entities($value)
{ {
return htmlentities($value, ENT_QUOTES, Config::get('application.encoding'), false); return htmlentities($value, ENT_QUOTES, Config::get('application.encoding'), false);
} }
/** /**
...@@ -21,7 +21,7 @@ class HTML { ...@@ -21,7 +21,7 @@ class HTML {
*/ */
public static function script($url) 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 { ...@@ -32,7 +32,7 @@ class HTML {
*/ */
public static function style($url, $media = 'all') 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 { ...@@ -76,6 +76,34 @@ class HTML {
return static::link($url, $title, $attributes, false, true); 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. * Generate an HTML mailto link.
* *
...@@ -250,4 +278,28 @@ class HTML { ...@@ -250,4 +278,28 @@ class HTML {
return $safe; 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 { ...@@ -126,7 +126,7 @@ class Inflector {
return static::$plural_cache[$value]; 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; return static::$plural_cache[$value] = $value;
} }
...@@ -165,7 +165,7 @@ class Inflector { ...@@ -165,7 +165,7 @@ class Inflector {
return static::$singular_cache[$value]; 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; return static::$singular_cache[$value] = $value;
} }
......
...@@ -69,6 +69,18 @@ class Input { ...@@ -69,6 +69,18 @@ class Input {
return Arr::get(Session::get('laravel_old_input', array()), $key, $default); 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. * Hydrate the input data for the request.
* *
......
...@@ -2,13 +2,6 @@ ...@@ -2,13 +2,6 @@
class Lang { class Lang {
/**
* All of the loaded language files.
*
* @var array
*/
private static $loaded = array();
/** /**
* All of the loaded language lines. * All of the loaded language lines.
* *
...@@ -55,24 +48,30 @@ class Lang { ...@@ -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 * @return string
*/ */
public function get($language = null) public function get($default = null)
{ {
if (is_null($language)) $language = Config::get('application.language');
{
$language = Config::get('application.language');
}
list($file, $line) = $this->parse($this->key); list($file, $line) = $this->parse($this->key);
$this->load($file, $language); $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. // 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])) if (array_key_exists($line, static::$lines[$language.$file]))
{ {
...@@ -80,7 +79,7 @@ class Lang { ...@@ -80,7 +79,7 @@ class Lang {
} }
else else
{ {
throw new \Exception("Language line [$line] does not exist for language [$language]"); return $default;
} }
// -------------------------------------------------------------- // --------------------------------------------------------------
...@@ -127,27 +126,15 @@ class Lang { ...@@ -127,27 +126,15 @@ class Lang {
private function load($file, $language) 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; return;
} }
// -------------------------------------------------------------- static::$lines[$language.$file] = require $path;
// 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;
} }
/** /**
......
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
* This function is registered on the auto-loader stack by the front controller. * This function is registered on the auto-loader stack by the front controller.
*/ */
return function($class) { return function($class) {
// ---------------------------------------------------------- // ----------------------------------------------------------
// Replace namespace slashes with directory slashes. // Replace namespace slashes with directory slashes.
// ---------------------------------------------------------- // ----------------------------------------------------------
$file = System\Str::lower(str_replace('\\', '/', $class)); $file = strtolower(str_replace('\\', '/', $class));
// ---------------------------------------------------------- // ----------------------------------------------------------
// Should the class be aliased? // 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); return class_alias($aliases[$class], $class);
} }
...@@ -33,9 +33,9 @@ return function($class) { ...@@ -33,9 +33,9 @@ return function($class) {
require $path; 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; require $path;
} }
......
...@@ -47,7 +47,7 @@ class Log { ...@@ -47,7 +47,7 @@ class Log {
// ----------------------------------------------------- // -----------------------------------------------------
// Create the yearly and monthly directories if needed. // 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')); static::make_directory($directory .= '/'.date('m'));
// ----------------------------------------------------- // -----------------------------------------------------
......
...@@ -77,6 +77,8 @@ class Redirect { ...@@ -77,6 +77,8 @@ class Redirect {
*/ */
public static function __callStatic($method, $parameters) public static function __callStatic($method, $parameters)
{ {
$parameters = (isset($parameters[0])) ? $parameters[0] : array();
// ---------------------------------------------------- // ----------------------------------------------------
// Dynamically redirect to a secure route URL. // Dynamically redirect to a secure route URL.
// ---------------------------------------------------- // ----------------------------------------------------
......
...@@ -65,24 +65,20 @@ class Request { ...@@ -65,24 +65,20 @@ class Request {
// ------------------------------------------------------- // -------------------------------------------------------
// Remove the application index and any extra slashes. // 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 // If the requests is to the root of the application, we
// always return a single forward slash. // always return a single forward slash.
// ------------------------------------------------------- // -------------------------------------------------------
return ($uri == '') ? '/' : Str::lower($uri); return ($uri == '') ? '/' : strtolower($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);
} }
/** /**
...@@ -120,34 +116,45 @@ class Request { ...@@ -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. * Determine if the request is using HTTPS.
* *
* @return bool * @return bool
*/ */
public static function secure() public static function is_secure()
{ {
return (static::protocol() == 'https'); 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 * @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 { ...@@ -160,9 +167,9 @@ class Request {
// //
// Example: Request::is_login() // 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 { ...@@ -63,7 +63,7 @@ class Route {
// ------------------------------------------------------------ // ------------------------------------------------------------
elseif (is_array($this->callback)) 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 // We verify that the before filters did not return a response
...@@ -80,7 +80,7 @@ class Route { ...@@ -80,7 +80,7 @@ class Route {
if (is_array($this->callback) and isset($this->callback['after'])) 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; return $response;
......
<?php namespace System; <?php namespace System\Route;
class Filter { class Filter {
......
...@@ -25,18 +25,21 @@ class Loader { ...@@ -25,18 +25,21 @@ class Loader {
// -------------------------------------------------------------- // --------------------------------------------------------------
// If the request is to the root, load the "home" routes file. // 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 == '/') if ($uri == '/')
{ {
return require APP_PATH.'routes/home'.EXT; return require APP_PATH.'routes/home'.EXT;
} }
// --------------------------------------------------------------
// Load the route file matching the first segment of the URI.
// --------------------------------------------------------------
else else
{ {
$segments = explode('/', trim($uri, '/')); $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)) if ( ! file_exists(APP_PATH.'routes/'.$segments[0].EXT))
{ {
return require APP_PATH.'routes/home'.EXT; return require APP_PATH.'routes/home'.EXT;
......
...@@ -56,7 +56,7 @@ class Router { ...@@ -56,7 +56,7 @@ class Router {
if (preg_match('#^'.$key.'$#', $method.' '.$uri)) 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 { ...@@ -10,7 +10,7 @@ class File implements \System\Session\Driver {
*/ */
public function load($id) 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)); return unserialize(file_get_contents($path));
} }
...@@ -24,7 +24,7 @@ class File implements \System\Session\Driver { ...@@ -24,7 +24,7 @@ class File implements \System\Session\Driver {
*/ */
public function save($session) 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 { ...@@ -35,7 +35,7 @@ class File implements \System\Session\Driver {
*/ */
public function delete($id) 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 { ...@@ -46,7 +46,7 @@ class File implements \System\Session\Driver {
*/ */
public function sweep($expiration) 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) if (filetype($file) == 'file' and filemtime($file) < $expiration)
{ {
......
...@@ -21,6 +21,9 @@ class Factory { ...@@ -21,6 +21,9 @@ class Factory {
case 'memcached': case 'memcached':
return new Driver\Memcached; return new Driver\Memcached;
case 'apc':
return new Driver\APC;
default: default:
throw new \Exception("Session driver [$driver] is not supported."); throw new \Exception("Session driver [$driver] is not supported.");
} }
......
...@@ -46,6 +46,17 @@ class Str { ...@@ -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)); 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. * Generate a random alpha or alpha-numeric string.
* *
......
...@@ -142,6 +142,8 @@ class URL { ...@@ -142,6 +142,8 @@ class URL {
*/ */
public static function __callStatic($method, $parameters) public static function __callStatic($method, $parameters)
{ {
$parameters = (isset($parameters[0])) ? $parameters[0] : array();
// ---------------------------------------------------- // ----------------------------------------------------
// Dynamically create a secure route URL. // 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 { ...@@ -85,6 +85,9 @@ class View {
// We include the view into the local scope within a // We include the view into the local scope within a
// try / catch block to catch any exceptions that may // try / catch block to catch any exceptions that may
// occur while the view is rendering. // occur while the view is rendering.
//
// Otherwise, a white screen of death will be shown
// if an exception occurs while rendering the view.
// ----------------------------------------------------- // -----------------------------------------------------
try try
{ {
...@@ -101,9 +104,8 @@ class View { ...@@ -101,9 +104,8 @@ class View {
/** /**
* Get the full path to the view. * Get the full path to the view.
* *
* Views are cascaded, so the application directory views * Views are cascaded, so the application directory views will take
* will take precedence over the system directory's views * precedence over system directory views of the same name.
* of the same name.
* *
* @return string * @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