mirror of
https://github.com/laravel/laravel.git
synced 2025-02-20 11:53:14 +08:00
initial commit of laravel!
This commit is contained in:
commit
a188d62105
0
application/cache/.gitignore
vendored
Normal file
0
application/cache/.gitignore
vendored
Normal file
98
application/config/application.php
Normal file
98
application/config/application.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application URL
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The URL used to access your application. The trailing slash is optional.
|
||||
|
|
||||
| Note: Remove "index.php" from this URL when using mod_rewrite.
|
||||
|
|
||||
*/
|
||||
|
||||
'url' => 'http://localhost/index.php',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Language
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default language of your application. This language will be used by
|
||||
| default by the Lang library when doing string localization.
|
||||
|
|
||||
| If you are not using the Lang library, this option isn't really important.
|
||||
|
|
||||
*/
|
||||
|
||||
'language' => 'en',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Timezone
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default timezone of your application. This timezone will be used when
|
||||
| Laravel needs a date, such as when writing to a log file.
|
||||
|
|
||||
*/
|
||||
|
||||
'timezone' => 'UTC',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Your application key should be a 32 character string that is totally
|
||||
| random and secret. This key is used by the encryption class to generate
|
||||
| secure, encrypted strings.
|
||||
|
|
||||
| If you will not be using the encryption class, this doesn't matter.
|
||||
|
|
||||
*/
|
||||
|
||||
'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',
|
||||
'Form' => 'System\\Form',
|
||||
'Hash' => 'System\\Hash',
|
||||
'HTML' => 'System\\HTML',
|
||||
'Inflector' => 'System\\Inflector',
|
||||
'Input' => 'System\\Input',
|
||||
'Lang' => 'System\\Lang',
|
||||
'URL' => 'System\\URL',
|
||||
'Redirect' => 'System\\Redirect',
|
||||
'Request' => 'System\\Request',
|
||||
'Response' => 'System\\Response',
|
||||
'Session' => 'System\\Session',
|
||||
'Str' => 'System\\Str',
|
||||
'Text' => 'System\\Text',
|
||||
'View' => 'System\View',
|
||||
),
|
||||
|
||||
);
|
32
application/config/auth.php
Normal file
32
application/config/auth.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Model
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This model will be used by the Auth class when retrieving the users of
|
||||
| your application. Feel free to change it to the name of your user model.
|
||||
|
|
||||
| Note: The authentication model must be an Eloquent model.
|
||||
|
|
||||
*/
|
||||
|
||||
'model' => 'User',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Username
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The authentication username is the column on your users table that
|
||||
| is considered the username of the user. Typically, this is either "email"
|
||||
| or "username". However, you are free to make it whatever you wish.
|
||||
|
|
||||
*/
|
||||
|
||||
'username' => 'email',
|
||||
|
||||
);
|
52
application/config/cache.php
Normal file
52
application/config/cache.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Driver
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The name of the default cache driver for your application.
|
||||
|
|
||||
| Caching can be used to increase the performance of your application
|
||||
| by storing commonly accessed data in memory or in a file.
|
||||
|
|
||||
| Supported Drivers: 'file', 'memcached'.
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => 'file',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Memcached Servers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can define the Memcached servers used by your application.
|
||||
|
|
||||
| Memcached is a free and open source, high-performance, distributed memory
|
||||
| object caching system, generic in nature, but intended for use in speeding
|
||||
| up dynamic web applications by alleviating database load.
|
||||
|
|
||||
| For more information about Memcached, check out: http://memcached.org
|
||||
|
|
||||
*/
|
||||
|
||||
'servers' => array(
|
||||
array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),
|
||||
),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Memcached Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This key will be prepended to items stored using Memcached to avoid
|
||||
| collisions with other applications on the server.
|
||||
|
|
||||
*/
|
||||
|
||||
'key' => 'laravel',
|
||||
|
||||
);
|
60
application/config/db.php
Normal file
60
application/config/db.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Database Connection
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The name of your default database connection.
|
||||
|
|
||||
| This connection will be used by default for all database operations
|
||||
| unless a different connection is specified when performing the operation.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => 'sqlite',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Database Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can define all of the databases used by your application.
|
||||
|
|
||||
| Supported Drivers: 'mysql', 'pgsql', 'sqlite'.
|
||||
|
|
||||
| Note: When using the SQLite driver, the path and "sqlite" extention will
|
||||
| be added automatically. You only need to specify the database name.
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => array(
|
||||
|
||||
'sqlite' => array(
|
||||
'driver' => 'sqlite',
|
||||
'database' => 'application',
|
||||
),
|
||||
|
||||
'mysql' => array(
|
||||
'driver' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'database' => 'database',
|
||||
'username' => 'root',
|
||||
'password' => 'password',
|
||||
'charset' => 'utf8',
|
||||
),
|
||||
|
||||
'pgsql' => array(
|
||||
'driver' => 'pgsql',
|
||||
'host' => 'localhost',
|
||||
'database' => 'database',
|
||||
'username' => 'root',
|
||||
'password' => 'password',
|
||||
'charset' => 'utf8',
|
||||
),
|
||||
|
||||
),
|
||||
|
||||
);
|
34
application/config/error.php
Normal file
34
application/config/error.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Error Detail
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Would you like detailed error messages?
|
||||
|
|
||||
| If your application is in production, consider turning off error details
|
||||
| for enhanced security and user experience.
|
||||
|
|
||||
*/
|
||||
|
||||
'detail' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Error Logging
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Would you like errors to be logged? Error logging can be extremely
|
||||
| helpful when debugging a production application.
|
||||
|
|
||||
| Note: When error logging is enabled, errors will be logged even when
|
||||
| error detail is disabled.
|
||||
|
|
||||
*/
|
||||
|
||||
'log' => false,
|
||||
|
||||
);
|
89
application/config/session.php
Normal file
89
application/config/session.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Driver
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The name of the session driver for your application.
|
||||
|
|
||||
| Since HTTP is stateless, sessions are used to maintain "state" across
|
||||
| multiple requests from the same user of your application.
|
||||
|
|
||||
| Supported Drivers: 'file', 'db', 'memcached'.
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => '',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Database
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The database table on which the session should be stored.
|
||||
|
|
||||
| If you are not using database based sessions, don't worry about this.
|
||||
|
|
||||
*/
|
||||
|
||||
'table' => 'sessions',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Lifetime
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| How many minutes can a session be idle before expiring?
|
||||
|
|
||||
*/
|
||||
|
||||
'lifetime' => 60,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Expiration On Close
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Should the session expire when the user's web browser closes?
|
||||
|
|
||||
*/
|
||||
|
||||
'expire_on_close' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cookie Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The path for which the session cookie is available.
|
||||
|
|
||||
*/
|
||||
|
||||
'path' => '/',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cookie Domain
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The domain for which the session cookie is available.
|
||||
|
|
||||
*/
|
||||
|
||||
'domain' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cookie HTTPS
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Should the session cookie only be transported over HTTPS?
|
||||
|
|
||||
*/
|
||||
|
||||
'https' => false,
|
||||
|
||||
);
|
0
application/db/.gitignore
vendored
Normal file
0
application/db/.gitignore
vendored
Normal file
41
application/filters.php
Normal file
41
application/filters.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Filters
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Filters provide a convenient method for filtering access to your route
|
||||
| functions. To make your life easier, we have already setup basic filters
|
||||
| for authentication and CSRF protection.
|
||||
|
|
||||
| For more information, check out: http://laravel.com/docs/basics/routes#filters
|
||||
|
|
||||
*/
|
||||
|
||||
'before' => function()
|
||||
{
|
||||
// Do stuff before every request is executed.
|
||||
},
|
||||
|
||||
|
||||
'after' => function($response)
|
||||
{
|
||||
// Do stuff after every request is executed.
|
||||
},
|
||||
|
||||
|
||||
'auth' => function()
|
||||
{
|
||||
return ( ! Auth::check()) ? Redirect::to_login() : null;
|
||||
},
|
||||
|
||||
|
||||
'csrf' => function()
|
||||
{
|
||||
return (Input::get('csrf_token') !== Form::raw_token()) ? Response::view('error/500', 500) : null;
|
||||
},
|
||||
|
||||
);
|
0
application/lang/en/.gitignore
vendored
Normal file
0
application/lang/en/.gitignore
vendored
Normal file
0
application/logs/.gitignore
vendored
Normal file
0
application/logs/.gitignore
vendored
Normal file
0
application/models/.gitignore
vendored
Normal file
0
application/models/.gitignore
vendored
Normal file
0
application/packages/.gitignore
vendored
Normal file
0
application/packages/.gitignore
vendored
Normal file
25
application/routes.php
Normal file
25
application/routes.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is the "definition", or the public API, of your application.
|
||||
|
|
||||
| To add functionality to your application, you add to the array located
|
||||
| in this file. It's a breeze. Just tell Laravel the request method and
|
||||
| URI a function should respond to.
|
||||
|
|
||||
| To learn more, check out: http://laravel.com/docs/basics/routes
|
||||
|
|
||||
*/
|
||||
|
||||
'GET /' => function()
|
||||
{
|
||||
return View::make('home/index');
|
||||
},
|
||||
|
||||
);
|
0
application/sessions/.gitignore
vendored
Normal file
0
application/sessions/.gitignore
vendored
Normal file
56
application/views/error/404.php
Normal file
56
application/views/error/404.php
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>404 - Not Found</title>
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=Ubuntu&subset=latin' rel='stylesheet' type='text/css'>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #fff;
|
||||
margin: 45px 0 0 0;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
font-size: 16px;
|
||||
color: #3f3f3f;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 740px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 10px 10px 10px 10px;
|
||||
background-color: #ffebe8;
|
||||
border: 1px solid #dd3c10;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<?php
|
||||
$messages = array('Should we ask for directions?', 'This doesn\'t look familiar.', 'We need a map.');
|
||||
$message = $messages[mt_rand(0, 2)];
|
||||
?>
|
||||
|
||||
<h1><?php echo $message; ?></h1>
|
||||
|
||||
<div id="content">
|
||||
The resource you requested was not found.
|
||||
<br /><br />
|
||||
Would you like go to our <a href="<?php echo System\Config::get('application.url'); ?>">home page</a> instead?
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
56
application/views/error/500.php
Normal file
56
application/views/error/500.php
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>500 - Internal Server Error</title>
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=Ubuntu&subset=latin' rel='stylesheet' type='text/css'>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #fff;
|
||||
margin: 45px 0 0 0;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
font-size: 16px;
|
||||
color: #3f3f3f;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 740px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 10px 10px 10px 10px;
|
||||
background-color: #ffebe8;
|
||||
border: 1px solid #dd3c10;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<?php
|
||||
$messages = array('Whoops!', 'Oh no!', 'Ouch!');
|
||||
$message = $messages[mt_rand(0, 2)];
|
||||
?>
|
||||
|
||||
<h1><?php echo $message; ?></h1>
|
||||
|
||||
<div id="content">
|
||||
An error occured while we were processing your request.
|
||||
<br /><br />
|
||||
Would you like go to our <a href="<?php echo System\Config::get('application.url'); ?>">home page</a> instead?
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
77
application/views/home/index.php
Normal file
77
application/views/home/index.php
Normal file
@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<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>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #fff;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
font-size: 16px;
|
||||
color: #3f3f3f;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
color: #6d6d6d;
|
||||
margin: 0 0 10px 0;
|
||||
text-shadow: 1px 1px #000;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 740px;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 10px 10px 10px 10px;
|
||||
background-color: #eee;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
font-size: 12px;
|
||||
padding-top: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
</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
|
||||
});
|
||||
});
|
||||
|
||||
$(window).resize();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<h1>Laravel</h1>
|
||||
|
||||
<div id="content">
|
||||
You have successfully installed Laravel.
|
||||
|
||||
<br /><br />
|
||||
|
||||
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 · <?php echo Benchmark::check('laravel'); ?>ms
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
19
license.txt
Normal file
19
license.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011 Taylor Otwell - taylorotwell@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
5
public/.htaccess
Normal file
5
public/.htaccess
Normal file
@ -0,0 +1,5 @@
|
||||
Options +FollowSymLinks
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /index.php [L]
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
133
public/index.php
Normal file
133
public/index.php
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/**
|
||||
* Laravel - A clean and classy framework for PHP web development.
|
||||
*
|
||||
* @package Laravel
|
||||
* @version 1.0.0 Beta 1
|
||||
* @author Taylor Otwell
|
||||
* @license MIT License
|
||||
* @link http://laravel.com
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Set the framework starting time.
|
||||
// --------------------------------------------------------------
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Define the framework paths.
|
||||
// --------------------------------------------------------------
|
||||
define('APP_PATH', realpath('../application').'/');
|
||||
define('SYS_PATH', realpath('../system').'/');
|
||||
define('BASE_PATH', realpath('../').'/');
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Define the PHP file extension.
|
||||
// --------------------------------------------------------------
|
||||
define('EXT', '.php');
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Load the configuration and string classes.
|
||||
// --------------------------------------------------------------
|
||||
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.
|
||||
// --------------------------------------------------------------
|
||||
error_reporting((System\Config::get('error.detail')) ? E_ALL | E_STRICT : 0);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Register the error handlers.
|
||||
// --------------------------------------------------------------
|
||||
set_exception_handler(function($e)
|
||||
{
|
||||
System\Error::handle($e);
|
||||
});
|
||||
|
||||
set_error_handler(function($number, $error, $file, $line)
|
||||
{
|
||||
System\Error::handle(new ErrorException($error, 0, $number, $file, $line));
|
||||
});
|
||||
|
||||
register_shutdown_function(function()
|
||||
{
|
||||
if ( ! is_null($error = error_get_last()))
|
||||
{
|
||||
System\Error::handle(new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line']));
|
||||
}
|
||||
});
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Set the default timezone.
|
||||
// --------------------------------------------------------------
|
||||
date_default_timezone_set(System\Config::get('application.timezone'));
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Load the session.
|
||||
// --------------------------------------------------------------
|
||||
if (System\Config::get('session.driver') != '')
|
||||
{
|
||||
System\Session::load();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Execute the global "before" filter.
|
||||
// --------------------------------------------------------------
|
||||
$response = System\Filter::call('before');
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Only execute the route function if the "before" filter did
|
||||
// not override by sending a response.
|
||||
// --------------------------------------------------------------
|
||||
if (is_null($response))
|
||||
{
|
||||
// ----------------------------------------------------------
|
||||
// Route the request to the proper route.
|
||||
// ----------------------------------------------------------
|
||||
$route = System\Router::route(Request::method(), Request::uri());
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Execute the route function.
|
||||
// ----------------------------------------------------------
|
||||
if ( ! is_null($route))
|
||||
{
|
||||
$response = $route->call();
|
||||
}
|
||||
else
|
||||
{
|
||||
$response = System\Response::view('error/404', 404);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$response = ( ! $response instanceof System\Response) ? new System\Response($response) : $response;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Execute the global "after" filter.
|
||||
// ----------------------------------------------------------
|
||||
System\Filter::call('after', array($response));
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Close the session.
|
||||
// --------------------------------------------------------------
|
||||
if (System\Config::get('session.driver') != '')
|
||||
{
|
||||
System\Session::close();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Send the response to the browser.
|
||||
// --------------------------------------------------------------
|
||||
$response->send();
|
135
system/auth.php
Normal file
135
system/auth.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Auth {
|
||||
|
||||
/**
|
||||
* The current user of the application.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static $user;
|
||||
|
||||
/**
|
||||
* The key used to store the user ID in the session.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $key = 'laravel_user_id';
|
||||
|
||||
/**
|
||||
* Determine if the current user of the application is authenticated.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function check()
|
||||
{
|
||||
return ( ! is_null(static::user()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current user of the application.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function user()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Verify that sessions are enabled.
|
||||
// -----------------------------------------------------
|
||||
if (Config::get('session.driver') == '')
|
||||
{
|
||||
throw new \Exception("You must specify a session driver before using the Auth class.");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the authentication model.
|
||||
// -----------------------------------------------------
|
||||
$model = static::model();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Load the user using the ID stored in the session.
|
||||
// -----------------------------------------------------
|
||||
if (is_null(static::$user) and Session::has(static::$key))
|
||||
{
|
||||
static::$user = $model::find(Session::get(static::$key));
|
||||
}
|
||||
|
||||
return static::$user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to login a user.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*/
|
||||
public static function login($username, $password)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the authentication model.
|
||||
// -----------------------------------------------------
|
||||
$model = static::model();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the user by username.
|
||||
// -----------------------------------------------------
|
||||
$user = $model::where(Config::get('auth.username'), '=', $username)->first();
|
||||
|
||||
if ( ! is_null($user))
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Hash the password.
|
||||
// -----------------------------------------------------
|
||||
$password = (isset($user->salt)) ? Hash::make($password, $user->salt)->value : sha1($password);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Verify that the passwords match.
|
||||
// -----------------------------------------------------
|
||||
if ($user->password == $password)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Set the user property.
|
||||
// -----------------------------------------------------
|
||||
static::$user = $user;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Store the user ID in the session.
|
||||
// -----------------------------------------------------
|
||||
Session::put(static::$key, $user->id);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout the current user of the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function logout()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Remove the user ID from the session.
|
||||
// -----------------------------------------------------
|
||||
Session::forget(static::$key);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Clear the current user variable.
|
||||
// -----------------------------------------------------
|
||||
static::$user = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function model()
|
||||
{
|
||||
return '\\'.Config::get('auth.model');
|
||||
}
|
||||
|
||||
}
|
49
system/benchmark.php
Normal file
49
system/benchmark.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Benchmark {
|
||||
|
||||
/**
|
||||
* Benchmark starting times.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $marks = array();
|
||||
|
||||
/**
|
||||
* Start a benchmark.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public static function start($name)
|
||||
{
|
||||
static::$marks[$name] = microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elapsed time in milliseconds since starting a benchmark.
|
||||
*
|
||||
* @param string $name
|
||||
* @return float
|
||||
*/
|
||||
public static function check($name)
|
||||
{
|
||||
if (array_key_exists($name, static::$marks))
|
||||
{
|
||||
return number_format((microtime(true) - static::$marks[$name]) * 1000, 2);
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total memory usage in megabytes.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function memory()
|
||||
{
|
||||
return number_format(memory_get_usage() / 1024 / 1024, 2);
|
||||
}
|
||||
|
||||
}
|
47
system/cache.php
Normal file
47
system/cache.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Cache {
|
||||
|
||||
/**
|
||||
* The active cache drivers.
|
||||
*
|
||||
* @var Cache\Driver
|
||||
*/
|
||||
private static $drivers = array();
|
||||
|
||||
/**
|
||||
* Get the cache driver instance.
|
||||
*
|
||||
* @param string $driver
|
||||
* @return Cache\Driver
|
||||
*/
|
||||
public static function driver($driver = null)
|
||||
{
|
||||
if ( ! array_key_exists($driver, static::$drivers))
|
||||
{
|
||||
// --------------------------------------------------
|
||||
// If no driver was specified, use the default.
|
||||
// --------------------------------------------------
|
||||
if (is_null($driver))
|
||||
{
|
||||
$driver = Config::get('cache.driver');
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Create the cache driver.
|
||||
// --------------------------------------------------
|
||||
static::$drivers[$driver] = Cache\Factory::make($driver);
|
||||
}
|
||||
|
||||
return static::$drivers[$driver];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass all other methods to the default driver.
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
return call_user_func_array(array(static::driver(), $method), $parameters);
|
||||
}
|
||||
|
||||
}
|
40
system/cache/driver.php
vendored
Normal file
40
system/cache/driver.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?php namespace System\Cache;
|
||||
|
||||
interface Driver {
|
||||
|
||||
/**
|
||||
* Determine if an item exists in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key);
|
||||
|
||||
/**
|
||||
* Get an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null);
|
||||
|
||||
/**
|
||||
* Write an item to the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes);
|
||||
|
||||
/**
|
||||
* Delete an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public function forget($key);
|
||||
|
||||
}
|
95
system/cache/driver/file.php
vendored
Normal file
95
system/cache/driver/file.php
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
<?php namespace System\Cache\Driver;
|
||||
|
||||
class File 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 the item has already been loaded, return it.
|
||||
// --------------------------------------------------
|
||||
if (array_key_exists($key, $this->items))
|
||||
{
|
||||
return $this->items[$key];
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Verify that the cache file exists.
|
||||
// --------------------------------------------------
|
||||
if ( ! file_exists(APP_PATH.'cache/'.$key))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Read the contents of the cache file.
|
||||
// --------------------------------------------------
|
||||
$cache = file_get_contents(APP_PATH.'cache/'.$key);
|
||||
|
||||
// --------------------------------------------------
|
||||
// Has the cache expired? The UNIX expiration time
|
||||
// is stored at the beginning of the file.
|
||||
// --------------------------------------------------
|
||||
if (time() >= substr($cache, 0, 10))
|
||||
{
|
||||
$this->forget($key);
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->items[$key] = unserialize(substr($cache, 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an item to the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
{
|
||||
// --------------------------------------------------
|
||||
// The expiration time is stored as a UNIX timestamp
|
||||
// at the beginning of the cache file.
|
||||
// --------------------------------------------------
|
||||
file_put_contents(APP_PATH.'cache/'.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
@unlink(APP_PATH.'cache/'.$key);
|
||||
}
|
||||
|
||||
}
|
80
system/cache/driver/memcached.php
vendored
Normal file
80
system/cache/driver/memcached.php
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
<?php namespace System\Cache\Driver;
|
||||
|
||||
class Memcached 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 the item has already been loaded, return it.
|
||||
// --------------------------------------------------
|
||||
if (array_key_exists($key, $this->items))
|
||||
{
|
||||
return $this->items[$key];
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Attempt to the get the item from cache.
|
||||
// --------------------------------------------------
|
||||
$cache = \System\Memcached::instance()->get(\System\Config::get('cache.key').$key);
|
||||
|
||||
// --------------------------------------------------
|
||||
// Verify that the item was retrieved.
|
||||
// --------------------------------------------------
|
||||
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)
|
||||
{
|
||||
\System\Memcached::instance()->set(\System\Config::get('cache.key').$key, $value, 0, $minutes * 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
\System\Memcached::instance()->delete(\System\Config::get('cache.key').$key);
|
||||
}
|
||||
|
||||
}
|
26
system/cache/factory.php
vendored
Normal file
26
system/cache/factory.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php namespace System\Cache;
|
||||
|
||||
class Factory {
|
||||
|
||||
/**
|
||||
* Create a cache driver instance.
|
||||
*
|
||||
* @param string $driver
|
||||
* @return Driver
|
||||
*/
|
||||
public static function make($driver)
|
||||
{
|
||||
switch ($driver)
|
||||
{
|
||||
case 'file':
|
||||
return new Driver\File;
|
||||
|
||||
case 'memcached':
|
||||
return new Driver\Memcached;
|
||||
|
||||
default:
|
||||
throw new \Exception("Cache driver [$driver] is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
118
system/config.php
Normal file
118
system/config.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Config {
|
||||
|
||||
/**
|
||||
* All of the loaded configuration items.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $items = array();
|
||||
|
||||
/**
|
||||
* Get a configuration item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
// ---------------------------------------------
|
||||
// Parse the configuration key.
|
||||
// ---------------------------------------------
|
||||
list($file, $key) = static::parse($key);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Load the configuration file.
|
||||
// ---------------------------------------------
|
||||
static::load($file);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Return the requested item.
|
||||
// ---------------------------------------------
|
||||
return (array_key_exists($key, static::$items[$file])) ? static::$items[$file][$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a configuration item.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public static function set($file, $value)
|
||||
{
|
||||
// ---------------------------------------------
|
||||
// Parse the configuration key.
|
||||
// ---------------------------------------------
|
||||
list($file, $key) = static::parse($key);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Load the configuration file.
|
||||
// ---------------------------------------------
|
||||
static::load($file);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Set the item's value.
|
||||
// ---------------------------------------------
|
||||
static::$items[$file][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a configuration key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
private static function parse($key)
|
||||
{
|
||||
// ---------------------------------------------
|
||||
// Get the key segments.
|
||||
// ---------------------------------------------
|
||||
$segments = explode('.', $key);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Validate the key format.
|
||||
// ---------------------------------------------
|
||||
if (count($segments) < 2)
|
||||
{
|
||||
throw new \Exception("Invalid configuration key [$key].");
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// Return the file and item name.
|
||||
// ---------------------------------------------
|
||||
return array($segments[0], implode('.', array_slice($segments, 1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all of the configuration items.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
public static function load($file)
|
||||
{
|
||||
// ---------------------------------------------
|
||||
// If the file has already been loaded, bail.
|
||||
// ---------------------------------------------
|
||||
if (array_key_exists($file, static::$items))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// Verify that the configuration file exists.
|
||||
// ---------------------------------------------
|
||||
if ( ! file_exists($path = APP_PATH.'config/'.$file.EXT))
|
||||
{
|
||||
throw new \Exception("Configuration file [$file] does not exist.");
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// Load the configuration file.
|
||||
// ---------------------------------------------
|
||||
static::$items[$file] = require $path;
|
||||
}
|
||||
|
||||
}
|
78
system/cookie.php
Normal file
78
system/cookie.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Cookie {
|
||||
|
||||
/**
|
||||
* Determine if a cookie exists.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has($key)
|
||||
{
|
||||
return ( ! is_null(static::get($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a cookie.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return string
|
||||
*/
|
||||
public static function get($key, $default = null)
|
||||
{
|
||||
return (array_key_exists($key, $_COOKIE)) ? $_COOKIE[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "permanent" cookie. The cookie will last 5 years.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param string $path
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @return bool
|
||||
*/
|
||||
public static function forever($key, $value, $path = '/', $domain = null, $secure = false)
|
||||
{
|
||||
return static::put($key, $value, 2628000, $path, $domain, $secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a cookie.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param int $minutes
|
||||
* @param string $path
|
||||
* @param string $domain
|
||||
* @param bool $secure
|
||||
* @return bool
|
||||
*/
|
||||
public static function put($key, $value, $minutes = 0, $path = '/', $domain = null, $secure = false)
|
||||
{
|
||||
// ----------------------------------------------------------
|
||||
// If the lifetime is less than zero, delete the cookie.
|
||||
// ----------------------------------------------------------
|
||||
if ($minutes < 0)
|
||||
{
|
||||
unset($_COOKIE[$key]);
|
||||
}
|
||||
|
||||
return setcookie($key, $value, ($minutes != 0) ? time() + ($minutes * 60) : 0, $path, $domain, $secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cookie.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function forget($key)
|
||||
{
|
||||
return static::put($key, null, -60);
|
||||
}
|
||||
|
||||
}
|
132
system/crypt.php
Normal file
132
system/crypt.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Crypt {
|
||||
|
||||
/**
|
||||
* The encryption cipher.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $cipher = 'rijndael-256';
|
||||
|
||||
/**
|
||||
* The encryption mode.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $mode = 'cbc';
|
||||
|
||||
/**
|
||||
* Encrypt a value using the MCrypt library.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function encrypt($value)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Determine the input vector source.
|
||||
// -----------------------------------------------------
|
||||
if (defined('MCRYPT_DEV_URANDOM'))
|
||||
{
|
||||
$random = MCRYPT_DEV_URANDOM;
|
||||
}
|
||||
elseif (defined('MCRYPT_DEV_RANDOM'))
|
||||
{
|
||||
$random = MCRYPT_DEV_RANDOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
$random = MCRYPT_RAND;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// The system random number generator must be seeded.
|
||||
// -----------------------------------------------------
|
||||
if ($random === MCRYPT_RAND)
|
||||
{
|
||||
mt_srand();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Create the input vector.
|
||||
// -----------------------------------------------------
|
||||
$iv = mcrypt_create_iv(static::iv_size(), $random);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Encrypt the value using MCrypt.
|
||||
// -----------------------------------------------------
|
||||
$value = mcrypt_encrypt(static::$cipher, static::key(), $value, static::$mode, $iv);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Use base64 encoding to get a string value.
|
||||
// -----------------------------------------------------
|
||||
return base64_encode($iv.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a value using the MCrypt library.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function decrypt($value)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Decode the base64 value.
|
||||
// -----------------------------------------------------
|
||||
$value = base64_decode($value, true);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Validate the base64 conversion.
|
||||
// -----------------------------------------------------
|
||||
if ( ! $value)
|
||||
{
|
||||
throw new \Exception('Decryption error. Input value is not valid base64 data.');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Extract the input vector from the value.
|
||||
// -----------------------------------------------------
|
||||
$iv = substr($value, 0, static::iv_size());
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Remove the input vector from the value.
|
||||
// -----------------------------------------------------
|
||||
$value = substr($value, static::iv_size());
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Decrypt the value using MCrypt.
|
||||
// -----------------------------------------------------
|
||||
return rtrim(mcrypt_decrypt(static::$cipher, static::key(), $value, static::$mode, $iv), "\0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the application key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function key()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Validate the application key.
|
||||
// -----------------------------------------------------
|
||||
if (is_null($key = Config::get('application.key')) or $key == '')
|
||||
{
|
||||
throw new \Exception("The encryption class can not be used without an encryption key.");
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input vector size for the cipher and mode.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function iv_size()
|
||||
{
|
||||
return mcrypt_get_iv_size(static::$cipher, static::$mode);
|
||||
}
|
||||
|
||||
}
|
111
system/db.php
Normal file
111
system/db.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php namespace System;
|
||||
|
||||
class DB {
|
||||
|
||||
/**
|
||||
* The active database connections.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $connections = array();
|
||||
|
||||
/**
|
||||
* Get a database connection.
|
||||
*
|
||||
* @param string $connection
|
||||
* @return PDO
|
||||
*/
|
||||
public static function connection($connection = null)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// If no connection was given, use the default.
|
||||
// ---------------------------------------------------
|
||||
if (is_null($connection))
|
||||
{
|
||||
$connection = Config::get('db.default');
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// If we have already established this connection,
|
||||
// simply return the existing connection.
|
||||
// ---------------------------------------------------
|
||||
if ( ! array_key_exists($connection, static::$connections))
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Get the database configurations.
|
||||
// ---------------------------------------------------
|
||||
$config = Config::get('db.connections');
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Verify the connection has been defined.
|
||||
// ---------------------------------------------------
|
||||
if ( ! array_key_exists($connection, $config))
|
||||
{
|
||||
throw new \Exception("Database connection [$connection] is not defined.");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Establish the database connection.
|
||||
// ---------------------------------------------------
|
||||
static::$connections[$connection] = DB\Connector::connect((object) $config[$connection]);
|
||||
}
|
||||
|
||||
return static::$connections[$connection];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a SQL query against the connection.
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @param string $connection
|
||||
* @return mixed
|
||||
*/
|
||||
public static function query($sql, $bindings = array(), $connection = null)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Create a new PDO statement from the SQL.
|
||||
// ---------------------------------------------------
|
||||
$query = static::connection($connection)->prepare($sql);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Execute the query with the bindings.
|
||||
// ---------------------------------------------------
|
||||
$result = $query->execute($bindings);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// For SELECT statements, return the results in an
|
||||
// array of stdClasses.
|
||||
//
|
||||
// For UPDATE and DELETE statements, return the number
|
||||
// or rows affected by the query.
|
||||
//
|
||||
// For INSERT statements, return a boolean.
|
||||
// ---------------------------------------------------
|
||||
if (strpos(Str::upper($sql), 'SELECT') === 0)
|
||||
{
|
||||
return $query->fetchAll(\PDO::FETCH_CLASS, 'stdClass');
|
||||
}
|
||||
elseif (strpos(Str::upper($sql), 'UPDATE') === 0 or strpos(Str::upper($sql), 'DELETE') === 0)
|
||||
{
|
||||
return $query->rowCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a fluent query against a table.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $connection
|
||||
* @return Query
|
||||
*/
|
||||
public static function table($table, $connection = null)
|
||||
{
|
||||
return new DB\Query($table, $connection);
|
||||
}
|
||||
|
||||
}
|
58
system/db/connector.php
Normal file
58
system/db/connector.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php namespace System\DB;
|
||||
|
||||
class Connector {
|
||||
|
||||
/**
|
||||
* The PDO connection options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $options = array(
|
||||
\PDO::ATTR_CASE => \PDO::CASE_LOWER,
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_ORACLE_NULLS => \PDO::NULL_NATURAL,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* Establish a PDO database connection.
|
||||
*
|
||||
* @param object $config
|
||||
* @return PDO
|
||||
*/
|
||||
public static function connect($config)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Establish a SQLite PDO connection.
|
||||
// ---------------------------------------------------
|
||||
if ($config->driver == 'sqlite')
|
||||
{
|
||||
return new \PDO('sqlite:'.APP_PATH.'db/'.$config->database.'.sqlite', null, null, static::$options);
|
||||
}
|
||||
// ---------------------------------------------------
|
||||
// Establish a MySQL or Postgres PDO connection.
|
||||
// ---------------------------------------------------
|
||||
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);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Set the correct character set.
|
||||
// ---------------------------------------------------
|
||||
if (isset($config->charset))
|
||||
{
|
||||
$connection->prepare("SET NAMES '".$config->charset."'")->execute();
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
// ---------------------------------------------------
|
||||
// If the driver isn't supported, bail out.
|
||||
// ---------------------------------------------------
|
||||
else
|
||||
{
|
||||
throw new \Exception('Database driver '.$config->driver.' is not supported.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
353
system/db/eloquent.php
Normal file
353
system/db/eloquent.php
Normal file
@ -0,0 +1,353 @@
|
||||
<?php namespace System\DB;
|
||||
|
||||
abstract class Eloquent {
|
||||
|
||||
/**
|
||||
* Indicates if the model exists in the database.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $exists = false;
|
||||
|
||||
/**
|
||||
* The model attributes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $attributes = array();
|
||||
|
||||
/**
|
||||
* The model's dirty attributes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $dirty = array();
|
||||
|
||||
/**
|
||||
* The model's ignored attributes.
|
||||
*
|
||||
* Ignored attributes will not be saved to the database, and
|
||||
* are primarily used to hold relationships.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $ignore = array();
|
||||
|
||||
/**
|
||||
* The relationships that should be eagerly loaded.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $includes = array();
|
||||
|
||||
/**
|
||||
* The relationship type the model is currently resolving.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $relating;
|
||||
|
||||
/**
|
||||
* The foreign key of the "relating" relationship.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $relating_key;
|
||||
|
||||
/**
|
||||
* The table name of the model being resolved. Used during many-to-many eager loading.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $relating_table;
|
||||
|
||||
/**
|
||||
* The model query instance.
|
||||
*
|
||||
* @var Query
|
||||
*/
|
||||
public $query;
|
||||
|
||||
/**
|
||||
* Create a new model instance and set the relationships
|
||||
* that should be eagerly loaded.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function with()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Create a new model instance.
|
||||
// -----------------------------------------------------
|
||||
$model = Eloquent\Factory::make(get_called_class());
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the eager relationships.
|
||||
// -----------------------------------------------------
|
||||
$model->includes = func_get_args();
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a model by the primary key.
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
*/
|
||||
public static function find($id)
|
||||
{
|
||||
return Eloquent\Factory::make(get_called_class())->where('id', '=', $id)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of models from the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function _get()
|
||||
{
|
||||
return Eloquent\Hydrate::from($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first model result
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function _first()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Load the hydrated models.
|
||||
// -----------------------------------------------------
|
||||
$results = Eloquent\Hydrate::from($this->take(1));
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the first result.
|
||||
// -----------------------------------------------------
|
||||
if (count($results) > 0)
|
||||
{
|
||||
reset($results);
|
||||
|
||||
return current($results);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:1 relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function has_one($model)
|
||||
{
|
||||
return Eloquent\Relate::has_one($model, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:* relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function has_many($model)
|
||||
{
|
||||
return Eloquent\Relate::has_many($model, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:1 belonging relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function belongs_to($model)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the calling function name.
|
||||
// -----------------------------------------------------
|
||||
list(, $caller) = debug_backtrace(false);
|
||||
|
||||
return Eloquent\Relate::belongs_to($caller, $model, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a *:* relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function has_many_and_belongs_to($model)
|
||||
{
|
||||
return Eloquent\Relate::has_many_and_belongs_to($model, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the model to the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
Eloquent\Warehouse::store($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method for retrieving model attributes.
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Check the ignored attributes first.
|
||||
// -----------------------------------------------------
|
||||
if (array_key_exists($key, $this->ignore))
|
||||
{
|
||||
return $this->ignore[$key];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Is the attribute actually a relationship?
|
||||
// -----------------------------------------------------
|
||||
if (method_exists($this, $key))
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the query / model for the relationship.
|
||||
// -----------------------------------------------------
|
||||
$model = $this->$key();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the relationship results.
|
||||
// -----------------------------------------------------
|
||||
return ($this->relating == 'has_one' or $this->relating == 'belongs_to')
|
||||
? $this->ignore[$key] = $model->first()
|
||||
: $this->ignore[$key] = $model->get();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Check the "regular" attributes.
|
||||
// -----------------------------------------------------
|
||||
return (array_key_exists($key, $this->attributes)) ? $this->attributes[$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for setting model attributes.
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Is the key actually a relationship?
|
||||
// -----------------------------------------------------
|
||||
if (method_exists($this, $key))
|
||||
{
|
||||
$this->ignore[$key] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Add the value to the attributes.
|
||||
// -----------------------------------------------------
|
||||
$this->attributes[$key] = $value;
|
||||
$this->dirty[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for determining if a model attribute is set.
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return (array_key_exists($key, $this->attributes) or array_key_exists($key, $this->ignore));
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for unsetting model attributes.
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
unset($this->attributes[$key]);
|
||||
unset($this->ignore[$key]);
|
||||
unset($this->dirty[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for handling dynamic method calls.
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Is the "get" method being called?
|
||||
// -----------------------------------------------------
|
||||
if ($method == 'get')
|
||||
{
|
||||
return $this->_get();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Is the "first" method being called?
|
||||
// -----------------------------------------------------
|
||||
if ($method == 'first')
|
||||
{
|
||||
return $this->_first();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the method is an aggregate function, just return
|
||||
// the aggregate value from the query.
|
||||
// -----------------------------------------------------
|
||||
if (in_array($method, array('count', 'sum', 'min', 'max', 'avg')))
|
||||
{
|
||||
return call_user_func_array(array($this->query, $method), $parameters);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Pass the method call to the query instance.
|
||||
// -----------------------------------------------------
|
||||
call_user_func_array(array($this->query, $method), $parameters);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for handling dynamic static method calls.
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Create a new model instance.
|
||||
// -----------------------------------------------------
|
||||
$model = Eloquent\Factory::make(get_called_class());
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Do we need to return the entire table?
|
||||
// -----------------------------------------------------
|
||||
if ($method == 'get')
|
||||
{
|
||||
return $model->_get();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Do we need to return the first model from the table?
|
||||
// -----------------------------------------------------
|
||||
if ($method == 'first')
|
||||
{
|
||||
return $model->_first();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the method is an aggregate function, just return
|
||||
// the aggregate value from the query.
|
||||
// -----------------------------------------------------
|
||||
if (in_array($method, array('count', 'sum', 'min', 'max', 'avg')))
|
||||
{
|
||||
return call_user_func_array(array($model->query, $method), $parameters);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Pass the method call to the query instance.
|
||||
// -----------------------------------------------------
|
||||
call_user_func_array(array($model->query, $method), $parameters);
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
}
|
26
system/db/eloquent/factory.php
Normal file
26
system/db/eloquent/factory.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php namespace System\DB\Eloquent;
|
||||
|
||||
class Factory {
|
||||
|
||||
/**
|
||||
* Factory for creating new model instances.
|
||||
*
|
||||
* @param string $class
|
||||
* @return object
|
||||
*/
|
||||
public static function make($class)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Create a new model instance.
|
||||
// -----------------------------------------------------
|
||||
$model = new $class;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the active query instance on the model.
|
||||
// -----------------------------------------------------
|
||||
$model->query = \System\DB\Query::table(Meta::table($class));
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
}
|
272
system/db/eloquent/hydrate.php
Normal file
272
system/db/eloquent/hydrate.php
Normal file
@ -0,0 +1,272 @@
|
||||
<?php namespace System\DB\Eloquent;
|
||||
|
||||
class Hydrate {
|
||||
|
||||
/**
|
||||
* Load the array of hydrated models.
|
||||
*
|
||||
* @param object $eloquent
|
||||
* @return array
|
||||
*/
|
||||
public static function from($eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Load the base models.
|
||||
// -----------------------------------------------------
|
||||
$results = static::base(get_class($eloquent), $eloquent->query->get());
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Load all of the eager relationships.
|
||||
// -----------------------------------------------------
|
||||
if (count($results) > 0)
|
||||
{
|
||||
foreach ($eloquent->includes as $include)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Verify the relationship is defined.
|
||||
// -----------------------------------------------------
|
||||
if ( ! method_exists($eloquent, $include))
|
||||
{
|
||||
throw new \Exception("Attempting to eager load [$include], but the relationship is not defined.");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Eagerly load the relationship.
|
||||
// -----------------------------------------------------
|
||||
static::eagerly($eloquent, $include, $results);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate the base models for a query.
|
||||
*
|
||||
* @param string $class
|
||||
* @param array $models
|
||||
* @return array
|
||||
*/
|
||||
private static function base($class, $models)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Initialize the hydrated model array.
|
||||
// -----------------------------------------------------
|
||||
$results = array();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Hydrate the models from the results.
|
||||
// -----------------------------------------------------
|
||||
foreach ($models as $model)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Instantiate a new model instance.
|
||||
// -----------------------------------------------------
|
||||
$result = new $class;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the model's attributes.
|
||||
// -----------------------------------------------------
|
||||
$result->attributes = (array) $model;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Indicate that the model already exists.
|
||||
// -----------------------------------------------------
|
||||
$result->exists = true;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Add the hydrated model to the array of models.
|
||||
// The array is keyed by the primary keys of the models.
|
||||
// -----------------------------------------------------
|
||||
$results[$result->id] = $result;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly load a relationship.
|
||||
*
|
||||
* @param object $eloquent
|
||||
* @param string $include
|
||||
* @param array $results
|
||||
* @return void
|
||||
*/
|
||||
private static function eagerly($eloquent, $include, &$results)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the relationship Eloquent model.
|
||||
//
|
||||
// We spoof the "belongs_to" key to allow the query
|
||||
// to be fetched without any problems.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->attributes[$spoof = $include.'_id'] = 0;
|
||||
|
||||
$model = $eloquent->$include();
|
||||
|
||||
unset($eloquent->attributes[$spoof]);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Reset the WHERE clause on the query.
|
||||
// -----------------------------------------------------
|
||||
$model->query->where = 'WHERE 1 = 1';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Reset the bindings on the query.
|
||||
// -----------------------------------------------------
|
||||
$model->query->bindings = array();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Initialize the relationship on the parent models.
|
||||
// -----------------------------------------------------
|
||||
foreach ($results as &$result)
|
||||
{
|
||||
$result->ignore[$include] = (strpos($eloquent->relating, 'has_many') === 0) ? array() : null;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Eagerly load a 1:1 or 1:* relationship.
|
||||
// -----------------------------------------------------
|
||||
if ($eloquent->relating == 'has_one' or $eloquent->relating == 'has_many')
|
||||
{
|
||||
static::eagerly_load_one_or_many($eloquent->relating_key, $eloquent->relating, $include, $model, $results);
|
||||
}
|
||||
// -----------------------------------------------------
|
||||
// Eagerly load a 1:1 (belonging) relationship.
|
||||
// -----------------------------------------------------
|
||||
elseif ($eloquent->relating == 'belongs_to')
|
||||
{
|
||||
static::eagerly_load_belonging($eloquent->relating_key, $include, $model, $results);
|
||||
}
|
||||
// -----------------------------------------------------
|
||||
// Eagerly load a *:* relationship.
|
||||
// -----------------------------------------------------
|
||||
else
|
||||
{
|
||||
static::eagerly_load_many_to_many($eloquent->relating_key, $eloquent->relating_table, strtolower(get_class($eloquent)).'_id', $include, $model, $results);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly load a 1:1 or 1:* relationship.
|
||||
*
|
||||
* @param string $relating_key
|
||||
* @param string $relating
|
||||
* @param string $include
|
||||
* @param object $model
|
||||
* @param array $results
|
||||
* @return void
|
||||
*/
|
||||
private static function eagerly_load_one_or_many($relating_key, $relating, $include, $model, &$results)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the related models.
|
||||
// -----------------------------------------------------
|
||||
$inclusions = $model->where_in($relating_key, array_keys($results))->get();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Match the child models with their parent.
|
||||
// -----------------------------------------------------
|
||||
foreach ($inclusions as $key => $inclusion)
|
||||
{
|
||||
if ($relating == 'has_one')
|
||||
{
|
||||
$results[$inclusion->$relating_key]->ignore[$include] = $inclusion;
|
||||
}
|
||||
else
|
||||
{
|
||||
$results[$inclusion->$relating_key]->ignore[$include][$inclusion->id] = $inclusion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly load a 1:1 belonging relationship.
|
||||
*
|
||||
* @param string $relating_key
|
||||
* @param string $include
|
||||
* @param object $model
|
||||
* @param array $results
|
||||
* @return void
|
||||
*/
|
||||
private static function eagerly_load_belonging($relating_key, $include, $model, &$results)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Gather the keys from the parent models.
|
||||
// -----------------------------------------------------
|
||||
$keys = array();
|
||||
|
||||
foreach ($results as &$result)
|
||||
{
|
||||
$keys[] = $result->$relating_key;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the related models.
|
||||
// -----------------------------------------------------
|
||||
$inclusions = $model->where_in('id', array_unique($keys))->get();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Match the child models with their parent.
|
||||
// -----------------------------------------------------
|
||||
foreach ($results as &$result)
|
||||
{
|
||||
$result->ignore[$include] = $inclusions[$result->$relating_key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly load a many-to-many relationship.
|
||||
*
|
||||
* @param string $relating_key
|
||||
* @param string $relating_table
|
||||
* @param string $foreign_key
|
||||
* @param string $include
|
||||
* @param object $model
|
||||
* @param array $results
|
||||
* @return void
|
||||
*/
|
||||
private static function eagerly_load_many_to_many($relating_key, $relating_table, $foreign_key, $include, $model, &$results)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Reset the SELECT clause.
|
||||
// -----------------------------------------------------
|
||||
$model->query->select = null;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Retrieve the raw results as stdClasses.
|
||||
//
|
||||
// We also add the foreign key to the select which will allow us
|
||||
// to match the models back to their parents.
|
||||
// -----------------------------------------------------
|
||||
$inclusions = $model->query->where_in($relating_key, array_keys($results))->get(Meta::table(get_class($model)).'.*', $relating_table.'.'.$foreign_key);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the class name of the related model.
|
||||
// -----------------------------------------------------
|
||||
$class = get_class($model);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Create the related models.
|
||||
// -----------------------------------------------------
|
||||
foreach ($inclusions as $inclusion)
|
||||
{
|
||||
$related = new $class;
|
||||
|
||||
$related->exists = true;
|
||||
$related->attributes = (array) $inclusion;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Remove the foreign key from the attributes since it
|
||||
// was only added to the query to help us match the models.
|
||||
// -----------------------------------------------------
|
||||
unset($related->attributes[$foreign_key]);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Add the related model to the parent model's array.
|
||||
// -----------------------------------------------------
|
||||
$results[$inclusion->$foreign_key]->ignore[$include][$inclusion->id] = $related;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
24
system/db/eloquent/meta.php
Normal file
24
system/db/eloquent/meta.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php namespace System\DB\Eloquent;
|
||||
|
||||
class Meta {
|
||||
|
||||
/**
|
||||
* Get the table name for a model.
|
||||
*
|
||||
* @param string $class
|
||||
* @return string
|
||||
*/
|
||||
public static function table($class)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Check for a table name override.
|
||||
// -----------------------------------------------------
|
||||
if (property_exists($class, 'table'))
|
||||
{
|
||||
return $class::$table;
|
||||
}
|
||||
|
||||
return \System\Str::lower(\System\Inflector::plural($class));
|
||||
}
|
||||
|
||||
}
|
132
system/db/eloquent/relate.php
Normal file
132
system/db/eloquent/relate.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php namespace System\DB\Eloquent;
|
||||
|
||||
class Relate {
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:1 relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @param object $eloquent
|
||||
* @return mixed
|
||||
*/
|
||||
public static function has_one($model, $eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Set the relating type.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating = __FUNCTION__;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the Eloquent model.
|
||||
// -----------------------------------------------------
|
||||
return static::has_one_or_many($model, $eloquent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:* relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @param object $eloquent
|
||||
* @return mixed
|
||||
*/
|
||||
public static function has_many($model, $eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Set the relating type.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating = __FUNCTION__;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the Eloquent model.
|
||||
// -----------------------------------------------------
|
||||
return static::has_one_or_many($model, $eloquent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:1 or 1:* relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @param object $eloquent
|
||||
* @return mixed
|
||||
*/
|
||||
private static function has_one_or_many($model, $eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Set the relating key.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating_key = \System\Str::lower(get_class($eloquent)).'_id';
|
||||
|
||||
return Factory::make($model)->where($eloquent->relating_key, '=', $eloquent->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a 1:1 belonging relationship.
|
||||
*
|
||||
* @param array $caller
|
||||
* @param string $model
|
||||
* @param object $eloquent
|
||||
* @return mixed
|
||||
*/
|
||||
public static function belongs_to($caller, $model, $eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Set the relating type.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating = __FUNCTION__;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the relating key.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating_key = $caller['function'].'_id';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the Eloquent model.
|
||||
// -----------------------------------------------------
|
||||
return Factory::make($model)->where('id', '=', $eloquent->attributes[$eloquent->relating_key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query for a *:* relationship.
|
||||
*
|
||||
* @param string $model
|
||||
* @param object $eloquent
|
||||
* @return mixed
|
||||
*/
|
||||
public static function has_many_and_belongs_to($model, $eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the models involved in the relationship.
|
||||
// -----------------------------------------------------
|
||||
$models = array(\System\Str::lower($model), \System\Str::lower(get_class($eloquent)));
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Sort the model names involved in the relationship.
|
||||
// -----------------------------------------------------
|
||||
sort($models);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the intermediate table name, which is the names
|
||||
// of the two related models alphabetized.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating_table = implode('_', $models);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the relating type.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating = __FUNCTION__;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the relating key.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->relating_key = $eloquent->relating_table.'.'.\System\Str::lower(get_class($eloquent)).'_id';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the Eloquent model.
|
||||
// -----------------------------------------------------
|
||||
return Factory::make($model)
|
||||
->select(Meta::table($model).'.*')
|
||||
->join($eloquent->relating_table, Meta::table($model).'.id', '=', $eloquent->relating_table.'.'.\System\Str::lower($model).'_id')
|
||||
->where($eloquent->relating_key, '=', $eloquent->id);
|
||||
}
|
||||
|
||||
}
|
66
system/db/eloquent/warehouse.php
Normal file
66
system/db/eloquent/warehouse.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php namespace System\DB\Eloquent;
|
||||
|
||||
class Warehouse {
|
||||
|
||||
/**
|
||||
* Save an Eloquent model to the database.
|
||||
*
|
||||
* @param object $eloquent
|
||||
* @return void
|
||||
*/
|
||||
public static function store($eloquent)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the model name.
|
||||
// -----------------------------------------------------
|
||||
$model = get_class($eloquent);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get a fresh query instance for the model.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->query = \System\DB\Query::table(Meta::table($model));
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the activity timestamps.
|
||||
// -----------------------------------------------------
|
||||
if (property_exists($model, 'timestamps') and $model::$timestamps)
|
||||
{
|
||||
static::timestamp($eloquent);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the model exists in the database, update it.
|
||||
// Otherwise, insert the model and set the ID.
|
||||
// -----------------------------------------------------
|
||||
if ($eloquent->exists)
|
||||
{
|
||||
return $eloquent->query->where('id', '=', $eloquent->attributes['id'])->update($eloquent->dirty);
|
||||
}
|
||||
else
|
||||
{
|
||||
$eloquent->attributes['id'] = $eloquent->query->insert_get_id($eloquent->attributes);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the existence flag to true.
|
||||
// -----------------------------------------------------
|
||||
$eloquent->exists = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the activity timestamps on a model.
|
||||
*
|
||||
* @param object $eloquent
|
||||
* @return void
|
||||
*/
|
||||
private static function timestamp($eloquent)
|
||||
{
|
||||
$eloquent->updated_at = date('Y-m-d H:i:s');
|
||||
|
||||
if ( ! $eloquent->exists)
|
||||
{
|
||||
$eloquent->created_at = $eloquent->updated_at;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
593
system/db/query.php
Normal file
593
system/db/query.php
Normal file
@ -0,0 +1,593 @@
|
||||
<?php namespace System\DB;
|
||||
|
||||
class Query {
|
||||
|
||||
/**
|
||||
* The database connection name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* The SELECT clause.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $select;
|
||||
|
||||
/**
|
||||
* Indicates if the query should return distinct results.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $distinct = false;
|
||||
|
||||
/**
|
||||
* The FROM clause.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $from;
|
||||
|
||||
/**
|
||||
* The table name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $table;
|
||||
|
||||
/**
|
||||
* The WHERE clause.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $where = 'WHERE 1 = 1';
|
||||
|
||||
/**
|
||||
* The ORDER BY columns.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $orderings = array();
|
||||
|
||||
/**
|
||||
* The LIMIT value.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $limit;
|
||||
|
||||
/**
|
||||
* The OFFSET value.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $offset;
|
||||
|
||||
/**
|
||||
* The query value bindings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $bindings = array();
|
||||
|
||||
/**
|
||||
* Create a new query instance.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $connection
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($table, $connection = null)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Set the database connection name.
|
||||
// ---------------------------------------------------
|
||||
$this->connection = (is_null($connection)) ? \System\Config::get('db.default') : $connection;
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Build the FROM clause.
|
||||
// ---------------------------------------------------
|
||||
$this->from = 'FROM '.$this->wrap($this->table = $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new query instance.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $connection
|
||||
* @return Query
|
||||
*/
|
||||
public static function table($table, $connection = null)
|
||||
{
|
||||
return new static($table, $connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the query to return distinct results.
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
public function distinct()
|
||||
{
|
||||
$this->distinct = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns to the SELECT clause.
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Handle DISTINCT selections.
|
||||
// ---------------------------------------------------
|
||||
$this->select = ($this->distinct) ? 'SELECT DISTINCT ' : 'SELECT ';
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Wrap all of the columns in keyword identifiers.
|
||||
// ---------------------------------------------------
|
||||
$this->select .= implode(', ', array_map(array($this, 'wrap'), func_get_args()));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a join to the query.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $column1
|
||||
* @param string $operator
|
||||
* @param string $column2
|
||||
* @param string $type
|
||||
* @return Query
|
||||
*/
|
||||
public function join($table, $column1, $operator, $column2, $type = 'INNER')
|
||||
{
|
||||
$this->from .= ' '.$type.' JOIN '.$this->wrap($table).' ON '.$this->wrap($column1).' '.$operator.' '.$this->wrap($column2);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a left join to the query.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $column1
|
||||
* @param string $operator
|
||||
* @param string $column2
|
||||
* @return Query
|
||||
*/
|
||||
public function left_join($table, $column1, $operator, $column2)
|
||||
{
|
||||
return $this->join($table, $column1, $operator, $column2, 'LEFT');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a raw where condition to the query.
|
||||
*
|
||||
* @param string $where
|
||||
* @param array $bindings
|
||||
* @param string $connector
|
||||
* @return Query
|
||||
*/
|
||||
public function raw_where($where, $bindings = array(), $connector = 'AND')
|
||||
{
|
||||
$this->where .= ' '.$connector.' '.$where;
|
||||
$this->bindings = array_merge($this->bindings, $bindings);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a raw or where condition to the query.
|
||||
*
|
||||
* @param string $where
|
||||
* @param array $bindings
|
||||
* @return Query
|
||||
*/
|
||||
public function raw_or_where($where, $bindings = array())
|
||||
{
|
||||
return $this->raw_where($where, $bindings, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a where condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $operator
|
||||
* @param mixed $value
|
||||
* @param string $connector
|
||||
* @return Query
|
||||
*/
|
||||
public function where($column, $operator, $value, $connector = 'AND')
|
||||
{
|
||||
$this->where .= ' '.$connector.' '.$this->wrap($column).' '.$operator.' ?';
|
||||
$this->bindings[] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an or where condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $operator
|
||||
* @param mixed $value
|
||||
* @return Query
|
||||
*/
|
||||
public function or_where($column, $operator, $value)
|
||||
{
|
||||
return $this->where($column, $operator, $value, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a where in condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
* @param string $connector
|
||||
* @return Query
|
||||
*/
|
||||
public function where_in($column, $values, $connector = 'AND')
|
||||
{
|
||||
$this->where .= ' '.$connector.' '.$this->wrap($column).' IN ('.$this->parameterize($values).')';
|
||||
$this->bindings = array_merge($this->bindings, $values);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an or where in condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
* @return Query
|
||||
*/
|
||||
public function or_where_in($column, $values)
|
||||
{
|
||||
return $this->where_in($column, $values, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a where not in condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
* @param string $connector
|
||||
* @return Query
|
||||
*/
|
||||
public function where_not_in($column, $values, $connector = 'AND')
|
||||
{
|
||||
$this->where .= ' '.$connector.' '.$this->wrap($column).' NOT IN ('.$this->parameterize($values).')';
|
||||
$this->bindings = array_merge($this->bindings, $values);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an or where not in condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
* @return Query
|
||||
*/
|
||||
public function or_where_not_in($column, $values)
|
||||
{
|
||||
return $this->where_not_in($column, $values, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a where null condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $connector
|
||||
* @return Query
|
||||
*/
|
||||
public function where_null($column, $connector = 'AND')
|
||||
{
|
||||
$this->where .= ' '.$connector.' '.$this->wrap($column).' IS NULL';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an or where null condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @return Query
|
||||
*/
|
||||
public function or_where_null($column)
|
||||
{
|
||||
return $this->where_null($column, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a where not null condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $connector
|
||||
* @return Query
|
||||
*/
|
||||
public function where_not_null($column, $connector = 'AND')
|
||||
{
|
||||
$this->where .= ' '.$connector.' '.$this->wrap($column).' IS NOT NULL';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an or where not null condition to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @return Query
|
||||
*/
|
||||
public function or_where_not_null($column)
|
||||
{
|
||||
return $this->where_not_null($column, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an ordering to the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $direction
|
||||
* @return Query
|
||||
*/
|
||||
public function order_by($column, $direction)
|
||||
{
|
||||
$this->orderings[] = $this->wrap($column).' '.\System\Str::upper($direction);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query offset.
|
||||
*
|
||||
* @param int $value
|
||||
* @return Query
|
||||
*/
|
||||
public function skip($value)
|
||||
{
|
||||
$this->offset = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query limit.
|
||||
*
|
||||
* @param int $value
|
||||
* @return Query
|
||||
*/
|
||||
public function take($value)
|
||||
{
|
||||
$this->limit = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a record by the primary key.
|
||||
*
|
||||
* @param int $id
|
||||
* @return object
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Set the primary key.
|
||||
// ---------------------------------------------------
|
||||
$this->where('id', '=', $id);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Get the first result.
|
||||
// ---------------------------------------------------
|
||||
return $this->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query as a SELECT statement and return the first result.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return (count($results = call_user_func_array(array($this->take(1), 'get'), func_get_args())) > 0) ? $results[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query as a SELECT statement.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Initialize the SELECT clause if it's null.
|
||||
// ---------------------------------------------------
|
||||
if (is_null($this->select))
|
||||
{
|
||||
call_user_func_array(array($this, 'select'), (count(func_get_args()) > 0) ? func_get_args() : array('*'));
|
||||
}
|
||||
|
||||
return \System\DB::query(Query\Compiler::select($this), $this->bindings, $this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an aggregate value.
|
||||
*
|
||||
* @param string $aggregate
|
||||
* @param string $column
|
||||
* @return mixed
|
||||
*/
|
||||
private function aggregate($aggregator, $column)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Build the SELECT clause.
|
||||
// ---------------------------------------------------
|
||||
$this->select = 'SELECT '.$aggregator.'('.$this->wrap($column).') AS '.$this->wrap('aggregate');
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Execute the statement.
|
||||
// ---------------------------------------------------
|
||||
$results = \System\DB::query(Query\Compiler::select($this), $this->bindings);
|
||||
|
||||
return $results[0]->aggregate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an INSERT statement.
|
||||
*
|
||||
* @param array $values
|
||||
* @return bool
|
||||
*/
|
||||
public function insert($values)
|
||||
{
|
||||
return \System\DB::query(Query\Compiler::insert($this, $values), array_values($values), $this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an INSERT statement and get the insert ID.
|
||||
*
|
||||
* @param array $values
|
||||
* @return int
|
||||
*/
|
||||
public function insert_get_id($values)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Compile the SQL statement.
|
||||
// ---------------------------------------------------
|
||||
$sql = Query\Compiler::insert($this, $values);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// The Postgres PDO implementation does not cleanly
|
||||
// implement the last insert ID function. So, we'll
|
||||
// use the RETURNING clause available in Postgres.
|
||||
// ---------------------------------------------------
|
||||
if (\System\DB::connection($this->connection)->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'pgsql')
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Add the RETURNING clause to the SQL.
|
||||
// ---------------------------------------------------
|
||||
$sql .= ' RETURNING '.$this->wrap('id');
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Prepare the PDO statement.
|
||||
// ---------------------------------------------------
|
||||
$query = \System\DB::connection($this->connection)->prepare($sql);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Execute the PDO statement.
|
||||
// ---------------------------------------------------
|
||||
$query->execute(array_values($values));
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Fetch the insert ID from the results.
|
||||
// ---------------------------------------------------
|
||||
$result = $query->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $result['id'];
|
||||
}
|
||||
// ---------------------------------------------------
|
||||
// When using MySQL or SQLite, we can just use the PDO
|
||||
// last insert ID function.
|
||||
// ---------------------------------------------------
|
||||
else
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Execute the statement.
|
||||
// ---------------------------------------------------
|
||||
\System\DB::query($sql, array_values($values), $this->connection);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Get the last insert ID.
|
||||
// ---------------------------------------------------
|
||||
return \System\DB::connection($this->connection)->lastInsertId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query as an UPDATE statement.
|
||||
*
|
||||
* @param array $values
|
||||
* @return bool
|
||||
*/
|
||||
public function update($values)
|
||||
{
|
||||
return \System\DB::query(Query\Compiler::update($this, $values), array_merge(array_values($values), $this->bindings), $this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query as a DELETE statement.
|
||||
*
|
||||
* @param int $id
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($id = null)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Set the primary key.
|
||||
// ---------------------------------------------------
|
||||
if ( ! is_null($id))
|
||||
{
|
||||
$this->where('id', '=', $id);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Execute the statement.
|
||||
// ---------------------------------------------------
|
||||
return \System\DB::query(Query\Compiler::delete($this), $this->bindings, $this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a value in keyword identifiers.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $wrap
|
||||
* @return string
|
||||
*/
|
||||
public function wrap($value, $wrap = '"')
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// If the application is using MySQL, we need to use
|
||||
// a non-standard keyword identifier.
|
||||
// ---------------------------------------------------
|
||||
if (\System\DB::connection($this->connection)->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'mysql')
|
||||
{
|
||||
$wrap = '`';
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Wrap the element in keyword identifiers.
|
||||
// ---------------------------------------------------
|
||||
return implode('.', array_map(function($segment) use ($wrap) {return ($segment != '*') ? $wrap.$segment.$wrap : $segment;}, explode('.', $value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create query parameters from an array of values.
|
||||
*
|
||||
* @param array $values
|
||||
* @return string
|
||||
*/
|
||||
public function parameterize($values)
|
||||
{
|
||||
return implode(', ', array_fill(0, count($values), '?'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for handling dynamic functions.
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Handle any of the aggregate functions.
|
||||
// ---------------------------------------------------
|
||||
if (in_array($method, array('count', 'min', 'max', 'avg', 'sum')))
|
||||
{
|
||||
return ($method == 'count') ? $this->aggregate(\System\Str::upper($method), '*') : $this->aggregate(\System\Str::upper($method), $parameters[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception("Method [$method] is not defined on the Query class.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
116
system/db/query/compiler.php
Normal file
116
system/db/query/compiler.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php namespace System\DB\Query;
|
||||
|
||||
class Compiler {
|
||||
|
||||
/**
|
||||
* Build a SQL SELECT statement.
|
||||
*
|
||||
* @param Query $query
|
||||
* @return string
|
||||
*/
|
||||
public static function select($query)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Add the SELECT, FROM, and WHERE clauses.
|
||||
// ---------------------------------------------------
|
||||
$sql = $query->select.' '.$query->from.' '.$query->where;
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Add the ORDER BY clause.
|
||||
// ---------------------------------------------------
|
||||
if (count($query->orderings) > 0)
|
||||
{
|
||||
$sql .= ' ORDER BY '.implode(', ', $query->orderings);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Add the LIMIT.
|
||||
// ---------------------------------------------------
|
||||
if ( ! is_null($query->limit))
|
||||
{
|
||||
$sql .= ' LIMIT '.$query->limit;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Add the OFFSET.
|
||||
// ---------------------------------------------------
|
||||
if ( ! is_null($query->offset))
|
||||
{
|
||||
$sql .= ' OFFSET '.$query->offset;
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a SQL INSERT statement.
|
||||
*
|
||||
* @param Query $query
|
||||
* @param array $values
|
||||
* @return string
|
||||
*/
|
||||
public static function insert($query, $values)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Start the query. Add the table name.
|
||||
// ---------------------------------------------------
|
||||
$sql = 'INSERT INTO '.$query->table.' (';
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Wrap each column name in keyword identifiers.
|
||||
// ---------------------------------------------------
|
||||
$columns = array();
|
||||
|
||||
foreach (array_keys($values) as $column)
|
||||
{
|
||||
$columns[] = $query->wrap($column);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Concatenate the column names and values.
|
||||
// ---------------------------------------------------
|
||||
return $sql .= implode(', ', $columns).') VALUES ('.$query->parameterize($values).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a SQL UPDATE statement.
|
||||
*
|
||||
* @param Query $query
|
||||
* @param array $values
|
||||
* @return string
|
||||
*/
|
||||
public static function update($query, $values)
|
||||
{
|
||||
// ---------------------------------------------------
|
||||
// Start the query. Add the table name.
|
||||
// ---------------------------------------------------
|
||||
$sql = 'UPDATE '.$query->table.' SET ';
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Wrap each column name in keyword identifiers.
|
||||
// ---------------------------------------------------
|
||||
$columns = array();
|
||||
|
||||
foreach (array_keys($values) as $column)
|
||||
{
|
||||
$columns[] = $query->wrap($column).' = ?';
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Concatenate the column names and the WHERE clause.
|
||||
// ---------------------------------------------------
|
||||
return $sql .= implode(', ', $columns).' '.$query->where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a SQL DELETE statement.
|
||||
*
|
||||
* @param Query $query
|
||||
* @return string
|
||||
*/
|
||||
public static function delete($query)
|
||||
{
|
||||
return 'DELETE FROM '.$query->wrap($query->table).' '.$query->where;
|
||||
}
|
||||
|
||||
}
|
145
system/download.php
Normal file
145
system/download.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Download {
|
||||
|
||||
/**
|
||||
* 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'
|
||||
);
|
||||
|
||||
/**
|
||||
* Create a download response.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $name
|
||||
* @return Response
|
||||
*/
|
||||
public static function file($path, $name = null)
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// If no name was specified, just use the basename.
|
||||
// -------------------------------------------------
|
||||
if (is_null($name))
|
||||
{
|
||||
$name = basename($path);
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Set the headers to force the download to occur.
|
||||
// -------------------------------------------------
|
||||
return Response::make(file_get_contents($path))->header('Content-Description', 'File Transfer')
|
||||
->header('Content-Type', static::mime(pathinfo($path, PATHINFO_EXTENSION)))
|
||||
->header('Content-Disposition', 'attachment; filename="'.$name.'"')
|
||||
->header('Content-Transfer-Encoding', 'binary')
|
||||
->header('Expires', 0)
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', filesize($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a MIME type by extension.
|
||||
*
|
||||
* @param string $extension
|
||||
* @param string $default
|
||||
* @return string
|
||||
*/
|
||||
public static function mime($extension, $default = 'application/octet-stream')
|
||||
{
|
||||
return (array_key_exists($extension, static::$mimes)) ? static::$mimes[$extension] : $default;
|
||||
}
|
||||
|
||||
}
|
156
system/error.php
Normal file
156
system/error.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Error {
|
||||
|
||||
/**
|
||||
* Error levels.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $levels = array(
|
||||
0 => 'Error',
|
||||
E_ERROR => 'Error',
|
||||
E_WARNING => 'Warning',
|
||||
E_PARSE => 'Parsing Error',
|
||||
E_NOTICE => 'Notice',
|
||||
E_CORE_ERROR => 'Core Error',
|
||||
E_CORE_WARNING => 'Core Warning',
|
||||
E_COMPILE_ERROR => 'Compile Error',
|
||||
E_COMPILE_WARNING => 'Compile Warning',
|
||||
E_USER_ERROR => 'User Error',
|
||||
E_USER_WARNING => 'User Warning',
|
||||
E_USER_NOTICE => 'User Notice',
|
||||
E_STRICT => 'Runtime Notice'
|
||||
);
|
||||
|
||||
/**
|
||||
* Handle an exception.
|
||||
*
|
||||
* @param Exception $e
|
||||
* @return void
|
||||
*/
|
||||
public static function handle($e)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Clean the output buffer.
|
||||
// -----------------------------------------------------
|
||||
if (ob_get_level() > 0)
|
||||
{
|
||||
ob_clean();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the error severity.
|
||||
// -----------------------------------------------------
|
||||
$severity = (array_key_exists($e->getCode(), static::$levels)) ? static::$levels[$e->getCode()] : $e->getCode();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the error file. Views require special handling
|
||||
// since view errors occur within eval'd code.
|
||||
// -----------------------------------------------------
|
||||
if (strpos($e->getFile(), 'view.php') !== false and strpos($e->getFile(), "eval()'d code") !== false)
|
||||
{
|
||||
$file = APP_PATH.'views/'.View::$last.EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
$file = $e->getFile();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Trim the period off of the error message.
|
||||
// -----------------------------------------------------
|
||||
$message = rtrim($e->getMessage(), '.');
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Log the error.
|
||||
// -----------------------------------------------------
|
||||
if (Config::get('error.log'))
|
||||
{
|
||||
Log::error($message.' in '.$e->getFile().' on line '.$e->getLine());
|
||||
}
|
||||
|
||||
if (Config::get('error.detail'))
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Build the error view.
|
||||
// -----------------------------------------------------
|
||||
$view = View::make('error/exception')
|
||||
->bind('severity', $severity)
|
||||
->bind('message', $message)
|
||||
->bind('file', $file)
|
||||
->bind('line', $e->getLine())
|
||||
->bind('trace', $e->getTraceAsString())
|
||||
->bind('contexts', static::context($file, $e->getLine()));
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Send the detailed error response.
|
||||
// -----------------------------------------------------
|
||||
Response::make($view, 500)->send();
|
||||
}
|
||||
else
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Send the generic error response.
|
||||
// -----------------------------------------------------
|
||||
Response::make(View::make('error/500'), 500)->send();
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file context of an exception.
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $line
|
||||
* @param int $padding
|
||||
* @return array
|
||||
*/
|
||||
private static function context($path, $line, $padding = 5)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Verify that the file exists.
|
||||
// -----------------------------------------------------
|
||||
if (file_exists($path))
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the contents of the file.
|
||||
// -----------------------------------------------------
|
||||
$file = file($path, FILE_IGNORE_NEW_LINES);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Unshift the array.
|
||||
// -----------------------------------------------------
|
||||
array_unshift($file, '');
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Calculate the starting position.
|
||||
// -----------------------------------------------------
|
||||
$start = $line - $padding;
|
||||
|
||||
if ($start < 0)
|
||||
{
|
||||
$start = 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Calculate the context length.
|
||||
// -----------------------------------------------------
|
||||
$length = ($line - $start) + $padding + 1;
|
||||
|
||||
if (($start + $length) > count($file) - 1)
|
||||
{
|
||||
$length = null;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Return the context.
|
||||
// -----------------------------------------------------
|
||||
return array_slice($file, $start, $length, true);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
51
system/filter.php
Normal file
51
system/filter.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Filter {
|
||||
|
||||
/**
|
||||
* The loaded route filters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $filters;
|
||||
|
||||
/**
|
||||
* Call a set of route filters.
|
||||
*
|
||||
* @param string $filter
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public static function call($filters, $parameters = array())
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Load the route filters.
|
||||
// --------------------------------------------------------------
|
||||
if (is_null(static::$filters))
|
||||
{
|
||||
static::$filters = require APP_PATH.'filters'.EXT;
|
||||
}
|
||||
|
||||
foreach (explode(', ', $filters) as $filter)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Verify that the filter is defined.
|
||||
// --------------------------------------------------------------
|
||||
if ( ! isset(static::$filters[$filter]))
|
||||
{
|
||||
throw new \Exception("Route filter [$filter] is not defined.");
|
||||
}
|
||||
|
||||
$response = call_user_func_array(static::$filters[$filter], $parameters);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// If the filter returned a response, return it.
|
||||
// --------------------------------------------------------------
|
||||
if ( ! is_null($response))
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
327
system/form.php
Normal file
327
system/form.php
Normal file
@ -0,0 +1,327 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Form {
|
||||
|
||||
/**
|
||||
* Open a HTML form.
|
||||
*
|
||||
* @param string $action
|
||||
* @param string $method
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function open($action = null, $method = 'POST', $attributes = array())
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// If no action was given, use the current URI.
|
||||
// -------------------------------------------------------
|
||||
if (is_null($action))
|
||||
{
|
||||
$action = Request::uri();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Prepare the action URL.
|
||||
// -------------------------------------------------------
|
||||
$action = URL::to($action);
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the action attribute.
|
||||
// -------------------------------------------------------
|
||||
$attributes['action'] = $action;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the method attribute.
|
||||
// -------------------------------------------------------
|
||||
$attributes['method'] = ($method == 'GET' or $method == 'POST') ? $method : 'POST';
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the default character set.
|
||||
// -------------------------------------------------------
|
||||
if ( ! array_key_exists('accept-charset', $attributes))
|
||||
{
|
||||
$attributes['accept-charset'] = 'UTF-8';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Build the form tag.
|
||||
// -------------------------------------------------------
|
||||
$html = '<form'.HTML::attributes($attributes).'>';
|
||||
|
||||
// -------------------------------------------------------
|
||||
// If the method is PUT or DELETE, we'll need to spoof it
|
||||
// using a hidden input field.
|
||||
//
|
||||
// For more information, see the Input library.
|
||||
// -------------------------------------------------------
|
||||
if ($method == 'PUT' or $method == 'DELETE')
|
||||
{
|
||||
$html .= PHP_EOL.static::hidden('request_method', $method);
|
||||
}
|
||||
|
||||
return $html.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hidden field containing the current CSRF token.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function token()
|
||||
{
|
||||
return static::hidden('csrf_token', static::raw_token());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current CSRF token.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function raw_token()
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Verify that sessions are enabled.
|
||||
// -------------------------------------------------------
|
||||
if (Config::get('session.driver') == '')
|
||||
{
|
||||
throw new \Exception('Sessions must be enabled to retrieve a CSRF token.');
|
||||
}
|
||||
|
||||
return Session::get('csrf_token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML text input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function text($name, $value = null, $attributes = array())
|
||||
{
|
||||
return static::input('text', $name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML password input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function password($name, $attributes = array())
|
||||
{
|
||||
return static::input('password', $name, null, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML hidden input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function hidden($name, $value = null, $attributes = array())
|
||||
{
|
||||
return static::input('hidden', $name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML file input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function file($name, $attributes = array())
|
||||
{
|
||||
return static::input('file', $name, null, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML submit input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function submit($value, $attributes = array())
|
||||
{
|
||||
return static::input('submit', null, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML button element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function button($value, $attributes = array())
|
||||
{
|
||||
return '<button'.HTML::attributes($attributes).'>'.$value.'</button>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML checkbox input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $checked
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function checkbox($name, $value = null, $checked = false, $attributes = array())
|
||||
{
|
||||
return static::checkable('checkbox', $name, $value, $checked, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML radio button input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $checked
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function radio($name, $value = null, $checked = false, $attributes = array())
|
||||
{
|
||||
return static::checkable('radio', $name, $value, $checked, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a checkable input element.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $checked
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
private static function checkable($type, $name, $value, $checked, $attributes)
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Set the checked attribute.
|
||||
// -------------------------------------------------------
|
||||
if ($checked === true)
|
||||
{
|
||||
$attributes['checked'] = 'checked';
|
||||
}
|
||||
|
||||
return static::input($type, $name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML textarea element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function textarea($name, $value = '', $attributes = array())
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Add the name to the attributes.
|
||||
// -------------------------------------------------------
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the default number of rows.
|
||||
// -------------------------------------------------------
|
||||
if ( ! isset($attributes['rows']))
|
||||
{
|
||||
$attributes['rows'] = 10;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the default number of columns.
|
||||
// -------------------------------------------------------
|
||||
if ( ! isset($attributes['cols']))
|
||||
{
|
||||
$attributes['cols'] = 50;
|
||||
}
|
||||
|
||||
return '<textarea'.HTML::attributes($attributes).'>'.Str::entities($value).'</textarea>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML select element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $options
|
||||
* @param string $selected
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function select($name, $options = array(), $selected = null, $attributes = array())
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Set the name attribute.
|
||||
// -------------------------------------------------------
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Initialize the options array.
|
||||
// -------------------------------------------------------
|
||||
$html_options = array();
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Build the options in HTML.
|
||||
// -------------------------------------------------------
|
||||
foreach ($options as $value => $display)
|
||||
{
|
||||
$option_attributes = array();
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the value attribute.
|
||||
// -------------------------------------------------------
|
||||
$option_attributes['value'] = $value;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the selected attribute.
|
||||
// -------------------------------------------------------
|
||||
$option_attributes['selected'] = ($value == $selected) ? 'selected' : null;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Add the option HTML to the array of options.
|
||||
// -------------------------------------------------------
|
||||
$html_options[] = '<option'.HTML::attributes($option_attributes).'>'.$display.'</option>';
|
||||
}
|
||||
|
||||
return '<select'.HTML::attributes($attributes).'>'.implode('', $html_options).'</select>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML input element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
private static function input($type, $name, $value = null, $attributes = array())
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Set the type attribute.
|
||||
// -------------------------------------------------------
|
||||
$attributes['type'] = $type;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the name attribute.
|
||||
// -------------------------------------------------------
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Set the value attribute.
|
||||
// -------------------------------------------------------
|
||||
$attributes['value'] = $value;
|
||||
|
||||
return '<input'.HTML::attributes($attributes).' />'.PHP_EOL;
|
||||
}
|
||||
|
||||
}
|
52
system/hash.php
Normal file
52
system/hash.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Hash {
|
||||
|
||||
/**
|
||||
* The salty, hashed value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* The salt used during hashing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $salt;
|
||||
|
||||
/**
|
||||
* Create a new hash instance.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $salt
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($value, $salt = null)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Get a random salt to hash the value with.
|
||||
// --------------------------------------------------------------
|
||||
$this->salt = (is_null($salt)) ? Str::random(16) : $salt;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Perform a salted, SHA-1 hash on the value.
|
||||
// --------------------------------------------------------------
|
||||
$this->value = sha1($value.$this->salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for creating hash instances.
|
||||
*
|
||||
* @access public
|
||||
* @param string $value
|
||||
* @param string $salt
|
||||
* @return Hash
|
||||
*/
|
||||
public static function make($value, $salt = null)
|
||||
{
|
||||
return new self($value, $salt);
|
||||
}
|
||||
|
||||
}
|
275
system/html.php
Normal file
275
system/html.php
Normal file
@ -0,0 +1,275 @@
|
||||
<?php namespace System;
|
||||
|
||||
class HTML {
|
||||
|
||||
/**
|
||||
* Generate a JavaScript reference.
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function script($url)
|
||||
{
|
||||
return '<script type="text/javascript" src="'.trim(URL::to($url), '.js').'.js"></script>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a CSS reference.
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function style($url, $media = 'all')
|
||||
{
|
||||
return '<link href="'.trim(URL::to($url), '.css').'.css" rel="stylesheet" type="text/css" media="'.$media.'" />'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a HTML link.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $title
|
||||
* @param array $attributes
|
||||
* @param bool $https
|
||||
* @return string
|
||||
*/
|
||||
public static function link($url, $title, $attributes = array(), $https = false)
|
||||
{
|
||||
return '<a href="'.URL::to($url, $https).'"'.static::attributes($attributes).'>'.Str::entities($title).'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a HTTPS HTML link.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $title
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function secure_link($url, $title, $attributes)
|
||||
{
|
||||
return static::link($url, $title, $attributes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an HTML mailto link.
|
||||
*
|
||||
* @param string $email
|
||||
* @param string $title
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function mailto($email, $title = null, $attributes = array())
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Obfuscate the e-mail address.
|
||||
// -------------------------------------------------------
|
||||
$email = static::email($email);
|
||||
|
||||
// -------------------------------------------------------
|
||||
// If no title is specified, just use the e-mail address.
|
||||
// -------------------------------------------------------
|
||||
if (is_null($title))
|
||||
{
|
||||
$title = $email;
|
||||
}
|
||||
|
||||
return '<a href="mailto:'.$email.'"'.static::attributes($attributes).'>'.$title.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscate an e-mail address to prevent spam-bots from sniffing it.
|
||||
*
|
||||
* @param string $email
|
||||
* @return string
|
||||
*/
|
||||
public static function email($email)
|
||||
{
|
||||
return str_replace('@', '@', static::obfuscate($email));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an HTML image.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $alt
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function image($url, $alt = '', $attributes = array())
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Add the "alt" tag to the attributes.
|
||||
// -------------------------------------------------------
|
||||
$attributes['alt'] = Str::entities($alt);
|
||||
|
||||
return '<img src="'.URL::to($url).'"'.static::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate HTML breaks.
|
||||
*
|
||||
* @param int $count
|
||||
* @return string
|
||||
*/
|
||||
public static function breaks($count = 1)
|
||||
{
|
||||
return str_repeat('<br />', $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate non-breaking spaces.
|
||||
*
|
||||
* @param int $count
|
||||
* @return string
|
||||
*/
|
||||
public static function spaces($count = 1)
|
||||
{
|
||||
return str_repeat(' ', $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an ordered list.
|
||||
*
|
||||
* @param array $list
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function ol($list, $attributes = array())
|
||||
{
|
||||
return static::list_elements('ol', $list, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an un-ordered list.
|
||||
*
|
||||
* @param array $list
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function ul($list, $attributes = array())
|
||||
{
|
||||
return static::list_elements('ul', $list, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an ordered or un-ordered list.
|
||||
*
|
||||
* @param string $type
|
||||
* @param array $list
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
private static function list_elements($type, $list, $attributes)
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Verify the list is an array.
|
||||
// -------------------------------------------------------
|
||||
if ( ! is_array($list))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Initialize the output value.
|
||||
// -------------------------------------------------------
|
||||
$html = '';
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Add the list items.
|
||||
// -------------------------------------------------------
|
||||
foreach ($list as $key => $value)
|
||||
{
|
||||
$html .= '<li>'.Str::entities($value).'</li>';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Build the list opening tag.
|
||||
// -------------------------------------------------------
|
||||
$start = '<'.$type.static::attributes($attributes).'>';
|
||||
|
||||
return $start.$html.'</'.$type.'>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of HTML attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function attributes($attributes)
|
||||
{
|
||||
$html = array();
|
||||
|
||||
foreach ($attributes as $key => $value)
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// If the value is null, skip it.
|
||||
// -------------------------------------------------------
|
||||
if (is_null($value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Add the HTML attribute to the array of attributes.
|
||||
// -------------------------------------------------------
|
||||
$html[] = $key.'="'.Str::entities($value).'"';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Concatenate all of the attributes together.
|
||||
// -------------------------------------------------------
|
||||
if (count($html) > 0)
|
||||
{
|
||||
return ' '.implode(' ', $html);
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscate a string to prevent spam-bots from sniffing it.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function obfuscate($value)
|
||||
{
|
||||
$safe = '';
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Spin through the string letter by letter.
|
||||
// -------------------------------------------------------
|
||||
foreach (str_split($value) as $letter)
|
||||
{
|
||||
switch (rand(1, 3))
|
||||
{
|
||||
// -------------------------------------------------------
|
||||
// Convert the letter to its entity representation.
|
||||
// -------------------------------------------------------
|
||||
case 1:
|
||||
$safe .= '&#'.ord($letter).';';
|
||||
break;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Convert the letter to a Hex character code.
|
||||
// -------------------------------------------------------
|
||||
case 2:
|
||||
$safe .= '&#x'.dechex(ord($letter)).';';
|
||||
break;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// No encoding.
|
||||
// -------------------------------------------------------
|
||||
case 3:
|
||||
$safe .= $letter;
|
||||
}
|
||||
}
|
||||
|
||||
return $safe;
|
||||
}
|
||||
|
||||
}
|
230
system/inflector.php
Normal file
230
system/inflector.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Inflector {
|
||||
|
||||
/**
|
||||
* The words that have been converted to singular.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $singular_cache = array();
|
||||
|
||||
/**
|
||||
* The words that have been converted to plural.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $plural_cache = array();
|
||||
|
||||
/**
|
||||
* Plural word forms.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $plural = array(
|
||||
'/(quiz)$/i' => "$1zes",
|
||||
'/^(ox)$/i' => "$1en",
|
||||
'/([m|l])ouse$/i' => "$1ice",
|
||||
'/(matr|vert|ind)ix|ex$/i' => "$1ices",
|
||||
'/(x|ch|ss|sh)$/i' => "$1es",
|
||||
'/([^aeiouy]|qu)y$/i' => "$1ies",
|
||||
'/(hive)$/i' => "$1s",
|
||||
'/(?:([^f])fe|([lr])f)$/i' => "$1$2ves",
|
||||
'/(shea|lea|loa|thie)f$/i' => "$1ves",
|
||||
'/sis$/i' => "ses",
|
||||
'/([ti])um$/i' => "$1a",
|
||||
'/(tomat|potat|ech|her|vet)o$/i' => "$1oes",
|
||||
'/(bu)s$/i' => "$1ses",
|
||||
'/(alias)$/i' => "$1es",
|
||||
'/(octop)us$/i' => "$1i",
|
||||
'/(ax|test)is$/i' => "$1es",
|
||||
'/(us)$/i' => "$1es",
|
||||
'/s$/i' => "s",
|
||||
'/$/' => "s"
|
||||
);
|
||||
|
||||
/**
|
||||
* Singular word forms.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $singular = array(
|
||||
'/(quiz)zes$/i' => "$1",
|
||||
'/(matr)ices$/i' => "$1ix",
|
||||
'/(vert|ind)ices$/i' => "$1ex",
|
||||
'/^(ox)en$/i' => "$1",
|
||||
'/(alias)es$/i' => "$1",
|
||||
'/(octop|vir)i$/i' => "$1us",
|
||||
'/(cris|ax|test)es$/i' => "$1is",
|
||||
'/(shoe)s$/i' => "$1",
|
||||
'/(o)es$/i' => "$1",
|
||||
'/(bus)es$/i' => "$1",
|
||||
'/([m|l])ice$/i' => "$1ouse",
|
||||
'/(x|ch|ss|sh)es$/i' => "$1",
|
||||
'/(m)ovies$/i' => "$1ovie",
|
||||
'/(s)eries$/i' => "$1eries",
|
||||
'/([^aeiouy]|qu)ies$/i' => "$1y",
|
||||
'/([lr])ves$/i' => "$1f",
|
||||
'/(tive)s$/i' => "$1",
|
||||
'/(hive)s$/i' => "$1",
|
||||
'/(li|wi|kni)ves$/i' => "$1fe",
|
||||
'/(shea|loa|lea|thie)ves$/i' => "$1f",
|
||||
'/(^analy)ses$/i' => "$1sis",
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis",
|
||||
'/([ti])a$/i' => "$1um",
|
||||
'/(n)ews$/i' => "$1ews",
|
||||
'/(h|bl)ouses$/i' => "$1ouse",
|
||||
'/(corpse)s$/i' => "$1",
|
||||
'/(us)es$/i' => "$1",
|
||||
'/(us|ss)$/i' => "$1",
|
||||
'/s$/i' => "",
|
||||
);
|
||||
|
||||
/**
|
||||
* Irregular word forms.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $irregular = array(
|
||||
'move' => 'moves',
|
||||
'foot' => 'feet',
|
||||
'goose' => 'geese',
|
||||
'sex' => 'sexes',
|
||||
'child' => 'children',
|
||||
'man' => 'men',
|
||||
'tooth' => 'teeth',
|
||||
'person' => 'people',
|
||||
);
|
||||
|
||||
/**
|
||||
* Uncountable word forms.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $uncountable = array(
|
||||
'sheep',
|
||||
'fish',
|
||||
'deer',
|
||||
'series',
|
||||
'species',
|
||||
'money',
|
||||
'rice',
|
||||
'information',
|
||||
'equipment',
|
||||
);
|
||||
|
||||
/**
|
||||
* Convert a word to its plural form.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function plural($value)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Have we already converted this word?
|
||||
// -----------------------------------------------------
|
||||
if (array_key_exists($value, static::$plural_cache))
|
||||
{
|
||||
return static::$plural_cache[$value];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Are the singular and plural forms the same?
|
||||
// -----------------------------------------------------
|
||||
if (in_array(Str::lower($value), static::$uncountable))
|
||||
{
|
||||
return static::$plural_cache[$value] = $value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Is the plural form irregular?
|
||||
// -----------------------------------------------------
|
||||
foreach (static::$irregular as $pattern => $irregular)
|
||||
{
|
||||
$pattern = '/'.$pattern.'$/i';
|
||||
|
||||
if (preg_match($pattern, $value))
|
||||
{
|
||||
return static::$plural_cache[$value] = preg_replace($pattern, $irregular, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Check the plural forms for matches.
|
||||
// -----------------------------------------------------
|
||||
foreach (static::$plural as $pattern => $plural)
|
||||
{
|
||||
if (preg_match($pattern, $value))
|
||||
{
|
||||
return static::$plural_cache[$value] = preg_replace($pattern, $plural, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return static::$plural_cache[$value] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a word to its singular form.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function singular($value)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Have we already converted this word?
|
||||
// -----------------------------------------------------
|
||||
if (array_key_exists($value, static::$singular_cache))
|
||||
{
|
||||
return static::$singular_cache[$value];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Are the singular and plural forms the same?
|
||||
// -----------------------------------------------------
|
||||
if (in_array(Str::lower($value), static::$uncountable))
|
||||
{
|
||||
return static::$singular_cache[$value] = $value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Is the plural form irregular?
|
||||
// -----------------------------------------------------
|
||||
foreach (static::$irregular as $irregular => $pattern)
|
||||
{
|
||||
$pattern = '/'.$pattern.'$/i';
|
||||
|
||||
if (preg_match($pattern, $value))
|
||||
{
|
||||
return static::$singular_cache[$value] = preg_replace($pattern, $irregular, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Check the singular forms for matches.
|
||||
// -----------------------------------------------------
|
||||
foreach (static::$singular as $pattern => $singular)
|
||||
{
|
||||
if (preg_match($pattern, $value))
|
||||
{
|
||||
return static::$singular_cache[$value] = preg_replace($pattern, $singular, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return static::$singular_cache[$value] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plural form of a word if the count is greater than zero.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int $count
|
||||
* @return string
|
||||
*/
|
||||
public static function plural_if($value, $count)
|
||||
{
|
||||
return ($count > 1) ? static::plural($value) : $value;
|
||||
}
|
||||
|
||||
}
|
135
system/input.php
Normal file
135
system/input.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Input {
|
||||
|
||||
/**
|
||||
* The input data for the request.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $input;
|
||||
|
||||
/**
|
||||
* Determine if the input data contains an item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has($key)
|
||||
{
|
||||
return ( ! is_null(static::get($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the old input data contains an item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_old($key)
|
||||
{
|
||||
return ( ! is_null(static::old($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the input data.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return string
|
||||
*/
|
||||
public static function get($key = null, $default = null)
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// Hydrate the input data for the request.
|
||||
// -------------------------------------------------
|
||||
static::hydrate();
|
||||
|
||||
return static::from_array(static::$input, $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get input data from the previous request.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return string
|
||||
*/
|
||||
public static function old($key = null, $default = null)
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// Verify that sessions are enabled.
|
||||
// -------------------------------------------------
|
||||
if (Config::get('session.driver') == '')
|
||||
{
|
||||
throw new \Exception("Sessions must be enabled to retrieve old input data.");
|
||||
}
|
||||
|
||||
return static::from_array(Session::get('laravel_old_input', array()), $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from an array.
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return string
|
||||
*/
|
||||
private static function from_array($array, $key, $default)
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// If no key is given, return the entire array.
|
||||
// -------------------------------------------------
|
||||
if (is_null($key))
|
||||
{
|
||||
return $array;
|
||||
}
|
||||
|
||||
return (array_key_exists($key, $array)) ? $array[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate the input data for the request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function hydrate()
|
||||
{
|
||||
if (is_null(static::$input))
|
||||
{
|
||||
switch (Request::method())
|
||||
{
|
||||
case 'GET':
|
||||
static::$input =& $_GET;
|
||||
break;
|
||||
|
||||
case 'POST':
|
||||
static::$input =& $_POST;
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
case 'DELETE':
|
||||
// ----------------------------------------------------------------------
|
||||
// Typically, browsers do not support PUT and DELETE methods on HTML
|
||||
// forms. So, we simulate them using a hidden POST variable.
|
||||
//
|
||||
// If the request method is being "spoofed", we'll move the POST array
|
||||
// into the PUT / DELETE array.
|
||||
// ----------------------------------------------------------------------
|
||||
if (isset($_POST['request_method']) and ($_POST['request_method'] == 'PUT' or $_POST['request_method'] == 'DELETE'))
|
||||
{
|
||||
static::$input =& $_POST;
|
||||
}
|
||||
// ----------------------------------------------------------------------
|
||||
// If the request is a true PUT request, read the php://input file.
|
||||
// ----------------------------------------------------------------------
|
||||
else
|
||||
{
|
||||
parse_str(file_get_contents('php://input'), static::$input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
178
system/lang.php
Normal file
178
system/lang.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Lang {
|
||||
|
||||
/**
|
||||
* All of the loaded language files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $loaded = array();
|
||||
|
||||
/**
|
||||
* All of the loaded language lines.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $lines = array();
|
||||
|
||||
/**
|
||||
* The key of the line that is being requested.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* The place-holder replacements.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $replacements = array();
|
||||
|
||||
/**
|
||||
* Create a new Lang instance.
|
||||
*
|
||||
* @param string $line
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Lang instance for a language line.
|
||||
*
|
||||
* @param string $key
|
||||
* @return Lang
|
||||
*/
|
||||
public static function line($key)
|
||||
{
|
||||
return new static($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language line for a given language.
|
||||
*
|
||||
* @param string $language
|
||||
* @return string
|
||||
*/
|
||||
public function get($language = null)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// If no language was specified, use the default language.
|
||||
// --------------------------------------------------------------
|
||||
if (is_null($language))
|
||||
{
|
||||
$language = Config::get('application.language');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Extract the file and item from the key.
|
||||
// --------------------------------------------------------------
|
||||
list($file, $line) = $this->parse($this->key);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Load the language file.
|
||||
// --------------------------------------------------------------
|
||||
$this->load($file, $language);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Get the language line.
|
||||
// --------------------------------------------------------------
|
||||
if (array_key_exists($line, static::$lines[$language.$file]))
|
||||
{
|
||||
$line = static::$lines[$language.$file][$line];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception("Language line [$line] does not exist for language [$language]");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Make all place-holder replacements.
|
||||
// --------------------------------------------------------------
|
||||
foreach ($this->replacements as $key => $value)
|
||||
{
|
||||
$line = str_replace(':'.$key, $value, $line);
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a language key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
private function parse($key)
|
||||
{
|
||||
// ---------------------------------------------
|
||||
// Get the key segments.
|
||||
// ---------------------------------------------
|
||||
$segments = explode('.', $key);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Validate the key format.
|
||||
// ---------------------------------------------
|
||||
if (count($segments) < 2)
|
||||
{
|
||||
throw new \Exception("Invalid language key [$key].");
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// Return the file and item name.
|
||||
// ---------------------------------------------
|
||||
return array($segments[0], implode('.', array_slice($segments, 1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a language file.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $language
|
||||
* @return void
|
||||
*/
|
||||
private function load($file, $language)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Do not load the file if it has already been loaded.
|
||||
// --------------------------------------------------------------
|
||||
if (in_array($language.$file, static::$loaded))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Does the language file exist?
|
||||
// --------------------------------------------------------------
|
||||
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].");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Add the file to the array of loaded files.
|
||||
// --------------------------------------------------------------
|
||||
static::$loaded[] = $language.$file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the place-holder replacements.
|
||||
*
|
||||
* @param array $replacements
|
||||
* @return Lang
|
||||
*/
|
||||
public function replace($replacements)
|
||||
{
|
||||
$this->replacements = $replacements;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
50
system/loader.php
Normal file
50
system/loader.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This function is registered on the auto-loader stack by the front controller.
|
||||
*/
|
||||
return function($class) {
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Replace namespace slashes with directory slashes.
|
||||
// ----------------------------------------------------------
|
||||
$file = System\Str::lower(str_replace('\\', '/', $class));
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Should the class be aliased?
|
||||
// ----------------------------------------------------------
|
||||
if (array_key_exists($class, $aliases = System\Config::get('application.aliases')))
|
||||
{
|
||||
return class_alias($aliases[$class], $class);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Check for the class in the system directory.
|
||||
// ----------------------------------------------------------
|
||||
if (file_exists($path = BASE_PATH.$file.EXT))
|
||||
{
|
||||
require $path;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
// Check for the class in the models directory.
|
||||
// ----------------------------------------------------------
|
||||
elseif (file_exists($path = APP_PATH.'models/'.$file.EXT))
|
||||
{
|
||||
require $path;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
// Check for the class in the packages directory.
|
||||
// ----------------------------------------------------------
|
||||
elseif (file_exists($path = APP_PATH.'packages/'.$file.EXT))
|
||||
{
|
||||
require $path;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
// Check for the class in the application directory.
|
||||
// ----------------------------------------------------------
|
||||
elseif (file_exists($path = APP_PATH.$file.EXT))
|
||||
{
|
||||
require $path;
|
||||
}
|
||||
|
||||
};
|
102
system/log.php
Normal file
102
system/log.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Log {
|
||||
|
||||
/**
|
||||
* Write an info message to the log.
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function info($message)
|
||||
{
|
||||
static::write('Info', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a debug message to the log.
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function debug($message)
|
||||
{
|
||||
static::write('Debug', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an error message to the logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function error($message)
|
||||
{
|
||||
static::write('Error', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a message to the logs.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function write($type, $message)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Determine the yearly directory.
|
||||
// -----------------------------------------------------
|
||||
$directory = APP_PATH.'logs/'.date('Y');
|
||||
|
||||
if ( ! is_dir($directory))
|
||||
{
|
||||
static::make_directory($directory);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Determine the monthly directory.
|
||||
// -----------------------------------------------------
|
||||
$directory .= '/'.date('m');
|
||||
|
||||
if ( ! is_dir($directory))
|
||||
{
|
||||
static::make_directory($directory);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Determine the daily file.
|
||||
// -----------------------------------------------------
|
||||
$file = $directory.'/'.date('d').EXT;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Write the message to the log.
|
||||
// -----------------------------------------------------
|
||||
file_put_contents($file, date('Y-m-d H:i:s').' '.$type.' - '.$message.PHP_EOL, LOCK_EX | FILE_APPEND);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the log file permissions.
|
||||
// -----------------------------------------------------
|
||||
chmod($file, 0666);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a log directory.
|
||||
*
|
||||
* @param string $directory
|
||||
* @return void
|
||||
*/
|
||||
private static function make_directory($directory)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Create the directory.
|
||||
// -----------------------------------------------------
|
||||
mkdir($directory, 02777);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the directory permissions.
|
||||
// -----------------------------------------------------
|
||||
chmod($directory, 02777);
|
||||
}
|
||||
|
||||
}
|
56
system/memcached.php
Normal file
56
system/memcached.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Memcached {
|
||||
|
||||
/**
|
||||
* The Memcache instance.
|
||||
*
|
||||
* @var Memcache
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Get the singleton Memcache instance.
|
||||
*
|
||||
* @return Memcache
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (is_null(static::$instance))
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Verify that the Memcache extension is installed.
|
||||
// -----------------------------------------------------
|
||||
if ( ! class_exists('Memcache'))
|
||||
{
|
||||
throw new \Exception('Attempting to use Memcached, but the Memcached PHP extension is not installed on this server.');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Instantiate the Memcache class.
|
||||
// -----------------------------------------------------
|
||||
$memcache = new \Memcache;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Configure the Memcache servers.
|
||||
// -----------------------------------------------------
|
||||
foreach (Config::get('cache.servers') as $server)
|
||||
{
|
||||
$memcache->addServer($server['host'], $server['port'], true, $server['weight']);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Verify Memcache was configured successfully.
|
||||
// -----------------------------------------------------
|
||||
if ($memcache->getVersion() === false)
|
||||
{
|
||||
throw new \Exception('Memcached is configured. However, no connections could be made. Please verify your memcached configuration.');
|
||||
}
|
||||
|
||||
static::$instance = $memcache;
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
}
|
66
system/redirect.php
Normal file
66
system/redirect.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Redirect {
|
||||
|
||||
/**
|
||||
* Create a redirect response.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param int $status
|
||||
* @param bool $https
|
||||
* @return Response
|
||||
*/
|
||||
public static function to($url, $method = 'location', $status = 302, $https = false)
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// Prepare the URL.
|
||||
// -------------------------------------------------
|
||||
$url = URL::to($url, $https);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Return the redirect response.
|
||||
// -------------------------------------------------
|
||||
return ($method == 'refresh')
|
||||
? Response::make('', $status)->header('Refresh', '0;url='.$url)
|
||||
: Response::make('', $status)->header('Location', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a redirect response to a HTTPS URL.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param int $status
|
||||
* @return Response
|
||||
*/
|
||||
public static function to_secure($url, $method = 'location', $status = 302)
|
||||
{
|
||||
return static::to($url, $method, $status, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method to handle redirecting to routes.
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
// ----------------------------------------------------
|
||||
// Dynamically redirect to a secure route URL.
|
||||
// ----------------------------------------------------
|
||||
if (strpos($method, 'to_secure_') === 0)
|
||||
{
|
||||
return static::to(URL::to_route(substr($method, 10), $parameters, true));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Dynamically redirect a route URL.
|
||||
// ----------------------------------------------------
|
||||
if (strpos($method, 'to_') === 0)
|
||||
{
|
||||
return static::to(URL::to_route(substr($method, 3), $parameters));
|
||||
}
|
||||
|
||||
throw new \Exception("Method [$method] is not defined on the Redirect class.");
|
||||
}
|
||||
|
||||
}
|
136
system/request.php
Normal file
136
system/request.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Request {
|
||||
|
||||
/**
|
||||
* The request URI.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $uri;
|
||||
|
||||
/**
|
||||
* Get the request URI.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function uri()
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Have we already determined the URI?
|
||||
// --------------------------------------------------------------
|
||||
if ( ! is_null(static::$uri))
|
||||
{
|
||||
return static::$uri;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Use the PATH_INFO variable if it is available.
|
||||
// --------------------------------------------------------------
|
||||
if (isset($_SERVER['PATH_INFO']))
|
||||
{
|
||||
return static::$uri = static::tidy($_SERVER['PATH_INFO']);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// If the server REQUEST_URI variable is not available, bail out.
|
||||
// --------------------------------------------------------------
|
||||
if ( ! isset($_SERVER['REQUEST_URI']))
|
||||
{
|
||||
throw new \Exception('Unable to determine the request URI.');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Get the PHP_URL_PATH of the request URI.
|
||||
// --------------------------------------------------------------
|
||||
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Slice the application URL off of the URI.
|
||||
// --------------------------------------------------------------
|
||||
if (strpos($uri, $base_url = parse_url(Config::get('application.url'), PHP_URL_PATH)) === 0)
|
||||
{
|
||||
$uri = substr($uri, strlen($base_url));
|
||||
}
|
||||
|
||||
return static::$uri = static::tidy($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tidy up a URI for use by Laravel. For empty URIs, a forward
|
||||
* slash will be returned.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return string
|
||||
*/
|
||||
private static function tidy($uri)
|
||||
{
|
||||
return ($uri != '/') ? Str::lower(trim($uri, '/')) : '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request method.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function method()
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// The method can be spoofed using a POST variable. This allows
|
||||
// HTML forms to simulate PUT and DELETE methods.
|
||||
// --------------------------------------------------------------
|
||||
return (isset($_POST['request_method'])) ? $_POST['request_method'] : $_SERVER['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requestor's IP address.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ip()
|
||||
{
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
|
||||
{
|
||||
return $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
}
|
||||
elseif (isset($_SERVER['HTTP_CLIENT_IP']))
|
||||
{
|
||||
return $_SERVER['HTTP_CLIENT_IP'];
|
||||
}
|
||||
elseif (isset($_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
return $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the request is using HTTPS.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_secure()
|
||||
{
|
||||
return (static::protocol() == 'https');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 an AJAX request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_ajax()
|
||||
{
|
||||
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and Str::lower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
|
||||
}
|
||||
|
||||
}
|
252
system/response.php
Normal file
252
system/response.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Response {
|
||||
|
||||
/**
|
||||
* The content of the response.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $content;
|
||||
|
||||
/**
|
||||
* The HTTP status code.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* The response headers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $headers = array();
|
||||
|
||||
/**
|
||||
* HTTP status codes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $statuses = array(
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
207 => 'Multi-Status',
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
422 => 'Unprocessable Entity',
|
||||
423 => 'Locked',
|
||||
424 => 'Failed Dependency',
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
507 => 'Insufficient Storage',
|
||||
509 => 'Bandwidth Limit Exceeded'
|
||||
);
|
||||
|
||||
/**
|
||||
* Create a new response instance.
|
||||
*
|
||||
* @param mixed $content
|
||||
* @param int $status
|
||||
*/
|
||||
public function __construct($content, $status = 200)
|
||||
{
|
||||
$this->content = $content;
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for creating new response instances.
|
||||
*
|
||||
* @param string $content
|
||||
* @param int $status
|
||||
* @return Response
|
||||
*/
|
||||
public static function make($content, $status = 200)
|
||||
{
|
||||
return new static($content, $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for creating new view response instances.
|
||||
*
|
||||
* @param string $view
|
||||
* @param int $status
|
||||
* @return Response
|
||||
*/
|
||||
public static function view($view, $status = 200)
|
||||
{
|
||||
return static::make(View::make($view), $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the response to the browser.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// Set the content type if it has not been set.
|
||||
// -------------------------------------------------
|
||||
if ( ! array_key_exists('Content-Type', $this->headers))
|
||||
{
|
||||
$this->header('Content-Type', 'text/html; charset=utf-8');
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Send the headers to the browser.
|
||||
// -------------------------------------------------
|
||||
if ( ! headers_sent())
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// Send the HTTP protocol and status code.
|
||||
// -------------------------------------------------
|
||||
$protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
|
||||
|
||||
header($protocol.' '.$this->status.' '.$this->statuses[$this->status]);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Send the rest of the headers.
|
||||
// -------------------------------------------------
|
||||
foreach ($this->headers as $name => $value)
|
||||
{
|
||||
header($name.': '.$value, true);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Send the content of the response to the browser.
|
||||
// -------------------------------------------------
|
||||
echo (string) $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a header to the response.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return Response
|
||||
*/
|
||||
public function header($name, $value)
|
||||
{
|
||||
$this->headers[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the session flash data.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return Response
|
||||
*/
|
||||
public function with($key, $value)
|
||||
{
|
||||
if (Config::get('session.driver') != '')
|
||||
{
|
||||
Session::flash($key, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the response is a redirect.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_redirect()
|
||||
{
|
||||
return $this->status == 301 or $this->status == 302;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for getting response View data.
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
// ------------------------------------------------------
|
||||
// Attempt to get the data from the View.
|
||||
// ------------------------------------------------------
|
||||
if ($this->content instanceof View)
|
||||
{
|
||||
return $this->content->$key;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for setting response View data.
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
{
|
||||
// ------------------------------------------------------
|
||||
// Attempt to set the data on the View.
|
||||
// ------------------------------------------------------
|
||||
if ($this->content instanceof View)
|
||||
{
|
||||
$this->content->bind($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for handling dynamic method calls.
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
// ------------------------------------------------------
|
||||
// Attempt to the pass the method to the View instance.
|
||||
// ------------------------------------------------------
|
||||
if ($this->content instanceof View and method_exists($this->content, $method))
|
||||
{
|
||||
call_user_func_array(array($this->content, $method), $parameters);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \Exception("Method [$method] does not exist on the Response class.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the response.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->content;
|
||||
}
|
||||
|
||||
}
|
85
system/route.php
Normal file
85
system/route.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Route {
|
||||
|
||||
/**
|
||||
* The route callback or array.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $route;
|
||||
|
||||
/**
|
||||
* The parameters that will passed to the route function.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $parameters;
|
||||
|
||||
/**
|
||||
* Create a new Route instance.
|
||||
*
|
||||
* @param mixed $route
|
||||
* @param array $parameters
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($route, $parameters = array())
|
||||
{
|
||||
$this->route = $route;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the route function.
|
||||
*
|
||||
* @param mixed $route
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$response = null;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// If the route just has a callback, call it.
|
||||
// --------------------------------------------------------------
|
||||
if (is_callable($this->route))
|
||||
{
|
||||
$response = call_user_func_array($this->route, $this->parameters);
|
||||
}
|
||||
// --------------------------------------------------------------
|
||||
// The route value is an array. We'll need to evaluate it.
|
||||
// --------------------------------------------------------------
|
||||
elseif (is_array($this->route))
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Call the "before" route filters.
|
||||
// --------------------------------------------------------------
|
||||
$response = isset($this->route['before']) ? Filter::call($this->route['before']) : null;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Call the route callback.
|
||||
// --------------------------------------------------------------
|
||||
if (is_null($response) and isset($this->route['do']))
|
||||
{
|
||||
$response = call_user_func_array($this->route['do'], $this->parameters);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Make sure the response is a Response instance.
|
||||
// --------------------------------------------------------------
|
||||
$response = ( ! $response instanceof Response) ? new Response($response) : $response;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Call the "after" route filters.
|
||||
// --------------------------------------------------------------
|
||||
if (is_array($this->route) and isset($this->route['after']))
|
||||
{
|
||||
Filter::call($this->route['after'], array($response));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
148
system/router.php
Normal file
148
system/router.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Router {
|
||||
|
||||
/**
|
||||
* All of the loaded routes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $routes;
|
||||
|
||||
/**
|
||||
* The named routes that have been found so far.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $names = array();
|
||||
|
||||
/**
|
||||
* Search a set of routes for the route matching a method and URI.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $uri
|
||||
* @return Route
|
||||
*/
|
||||
public static function route($method, $uri)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Add a forward slash to the URI if necessary.
|
||||
// --------------------------------------------------------------
|
||||
$uri = ($uri != '/') ? '/'.$uri : $uri;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Load all of the application routes.
|
||||
// --------------------------------------------------------------
|
||||
static::$routes = require APP_PATH.'routes'.EXT;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Is there an exact match for the request?
|
||||
// --------------------------------------------------------------
|
||||
if (isset(static::$routes[$method.' '.$uri]))
|
||||
{
|
||||
return new Route(static::$routes[$method.' '.$uri]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// No exact match... check each route individually.
|
||||
// --------------------------------------------------------------
|
||||
foreach (static::$routes as $keys => $callback)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Only check routes that have multiple URIs or wildcards.
|
||||
// All other routes would have been caught by a literal match.
|
||||
// --------------------------------------------------------------
|
||||
if (strpos($keys, '(') !== false or strpos($keys, ',') !== false )
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Multiple routes can be assigned to a callback using commas.
|
||||
// --------------------------------------------------------------
|
||||
foreach (explode(', ', $keys) as $route)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Change wildcards into regular expressions.
|
||||
// --------------------------------------------------------------
|
||||
$route = str_replace(':num', '[0-9]+', str_replace(':any', '.+', $route));
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Test the route for a match.
|
||||
// --------------------------------------------------------------
|
||||
if (preg_match('#^'.$route.'$#', $method.' '.$uri))
|
||||
{
|
||||
return new Route($callback, static::parameters(explode('/', $uri), explode('/', $route)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a route by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public static function find($name)
|
||||
{
|
||||
// ----------------------------------------------------
|
||||
// Have we already looked up this named route?
|
||||
// ----------------------------------------------------
|
||||
if (array_key_exists($name, static::$names))
|
||||
{
|
||||
return static::$names[$name];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Instantiate the recursive array iterator.
|
||||
// ----------------------------------------------------
|
||||
$arrayIterator = new \RecursiveArrayIterator(static::$routes);
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Instantiate the recursive iterator iterator.
|
||||
// ----------------------------------------------------
|
||||
$recursiveIterator = new \RecursiveIteratorIterator($arrayIterator);
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Iterate through the routes searching for a route
|
||||
// name that matches the given name.
|
||||
// ----------------------------------------------------
|
||||
foreach ($recursiveIterator as $iterator)
|
||||
{
|
||||
$route = $recursiveIterator->getSubIterator();
|
||||
|
||||
if ($route['name'] == $name)
|
||||
{
|
||||
return static::$names[$name] = array($arrayIterator->key() => iterator_to_array($route));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parameters that should be passed to the route callback.
|
||||
*
|
||||
* @param array $uri_segments
|
||||
* @param array $route_segments
|
||||
* @return array
|
||||
*/
|
||||
private static function parameters($uri_segments, $route_segments)
|
||||
{
|
||||
$parameters = array();
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Spin through the route segments looking for parameters.
|
||||
// --------------------------------------------------------------
|
||||
for ($i = 0; $i < count($route_segments); $i++)
|
||||
{
|
||||
// --------------------------------------------------------------
|
||||
// Any segment wrapped in parentheses is a parameter.
|
||||
// --------------------------------------------------------------
|
||||
if (strpos($route_segments[$i], '(') === 0)
|
||||
{
|
||||
$parameters[] = $uri_segments[$i];
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
}
|
281
system/session.php
Normal file
281
system/session.php
Normal file
@ -0,0 +1,281 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Session {
|
||||
|
||||
/**
|
||||
* The active session driver.
|
||||
*
|
||||
* @var Session\Driver
|
||||
*/
|
||||
private static $driver;
|
||||
|
||||
/**
|
||||
* The session.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $session = array();
|
||||
|
||||
/**
|
||||
* Get the session driver instance.
|
||||
*
|
||||
* @return Session\Driver
|
||||
*/
|
||||
public static function driver()
|
||||
{
|
||||
if (is_null(static::$driver))
|
||||
{
|
||||
static::$driver = Session\Factory::make(Config::get('session.driver'));
|
||||
}
|
||||
|
||||
return static::$driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the session for the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function load()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// If a valid ID is present, load the session.
|
||||
// -----------------------------------------------------
|
||||
if ( ! is_null($id = Cookie::get('laravel_session')))
|
||||
{
|
||||
static::$session = static::driver()->load($id);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the session is invalid, start a new one.
|
||||
// -----------------------------------------------------
|
||||
if (is_null($id) or is_null(static::$session) or (time() - static::$session['last_activity']) > (Config::get('session.lifetime') * 60))
|
||||
{
|
||||
static::$session['id'] = Str::random(40);
|
||||
static::$session['data'] = array();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Generate a CSRF token if one does not exist.
|
||||
// -----------------------------------------------------
|
||||
if ( ! static::has('csrf_token'))
|
||||
{
|
||||
static::put('csrf_token', Str::random(16));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Set the last activity timestamp for the user.
|
||||
// -----------------------------------------------------
|
||||
static::$session['last_activity'] = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the session contains an item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has($key)
|
||||
{
|
||||
return array_key_exists($key, static::$session['data']) or
|
||||
array_key_exists(':old:'.$key, static::$session['data']) or
|
||||
array_key_exists(':new:'.$key, static::$session['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the session.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($key, $default = null)
|
||||
{
|
||||
if (static::has($key))
|
||||
{
|
||||
if (array_key_exists($key, static::$session['data']))
|
||||
{
|
||||
return static::$session['data'][$key];
|
||||
}
|
||||
// -----------------------------------------------------
|
||||
// Check the flash data for the item.
|
||||
// -----------------------------------------------------
|
||||
elseif (array_key_exists(':old:'.$key, static::$session['data']))
|
||||
{
|
||||
return static::$session['data'][':old:'.$key];
|
||||
}
|
||||
elseif (array_key_exists(':new:'.$key, static::$session['data']))
|
||||
{
|
||||
return static::$session['data'][':new:'.$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the session and delete it.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public static function once($key, $default = null)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Get the item from the session.
|
||||
// -----------------------------------------------------
|
||||
$value = static::get($key, $default);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Delete the item from the session.
|
||||
// -----------------------------------------------------
|
||||
static::forget($key);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an item to the session.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public static function put($key, $value)
|
||||
{
|
||||
static::$session['data'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a flash item to the session.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public static function flash($key, $value)
|
||||
{
|
||||
static::put(':new:'.$key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the session.
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public static function forget($key)
|
||||
{
|
||||
unset(static::$session['data'][$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function flush()
|
||||
{
|
||||
static::$session['data'] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the session ID.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function regenerate()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Delete the old session from storage.
|
||||
// -----------------------------------------------------
|
||||
static::driver()->delete(static::$session['id']);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Create a new session ID.
|
||||
// -----------------------------------------------------
|
||||
static::$session['id'] = Str::random(40);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function close()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Flash the old input into the session.
|
||||
// -----------------------------------------------------
|
||||
static::flash('laravel_old_input', Input::get());
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Age the session flash data.
|
||||
// -----------------------------------------------------
|
||||
static::age_flash();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Save the session to storage.
|
||||
// -----------------------------------------------------
|
||||
static::driver()->save(static::$session);
|
||||
|
||||
if ( ! headers_sent())
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Calculate the cookie lifetime.
|
||||
// -----------------------------------------------------
|
||||
$lifetime = (Config::get('session.expire_on_close')) ? 0 : Config::get('session.lifetime');
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Write the session cookie.
|
||||
// -----------------------------------------------------
|
||||
Cookie::put('laravel_session', static::$session['id'], $lifetime, Config::get('session.path'), Config::get('session.domain'), Config::get('session.https'));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Perform session garbage collection (2% chance).
|
||||
// -----------------------------------------------------
|
||||
if (mt_rand(1, 100) <= 2)
|
||||
{
|
||||
static::driver()->sweep(time() - (Config::get('session.lifetime') * 60));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Age the session flash data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function age_flash()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Expire all of the old flash data.
|
||||
// -----------------------------------------------------
|
||||
foreach (static::$session['data'] as $key => $value)
|
||||
{
|
||||
if (strpos($key, ':old:') === 0)
|
||||
{
|
||||
static::forget($key);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Age all of the new flash data.
|
||||
// -----------------------------------------------------
|
||||
foreach (static::$session['data'] as $key => $value)
|
||||
{
|
||||
if (strpos($key, ':new:') === 0)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Create an :old: flash item.
|
||||
// -----------------------------------------------------
|
||||
static::put(':old:'.substr($key, 5), $value);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Forget the :new: flash item.
|
||||
// -----------------------------------------------------
|
||||
static::forget($key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
37
system/session/driver.php
Normal file
37
system/session/driver.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php namespace System\Session;
|
||||
|
||||
interface Driver {
|
||||
|
||||
/**
|
||||
* Load a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return array
|
||||
*/
|
||||
public function load($id);
|
||||
|
||||
/**
|
||||
* Save a session.
|
||||
*
|
||||
* @param array $session
|
||||
* @return void
|
||||
*/
|
||||
public function save($session);
|
||||
|
||||
/**
|
||||
* Delete a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id);
|
||||
|
||||
/**
|
||||
* Delete all expired sessions.
|
||||
*
|
||||
* @param int $expiration
|
||||
* @return void
|
||||
*/
|
||||
public function sweep($expiration);
|
||||
|
||||
}
|
78
system/session/driver/db.php
Normal file
78
system/session/driver/db.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php namespace System\Session\Driver;
|
||||
|
||||
class DB implements \System\Session\Driver {
|
||||
|
||||
/**
|
||||
* Load a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return array
|
||||
*/
|
||||
public function load($id)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Find the session in the database.
|
||||
// -----------------------------------------------------
|
||||
$session = $this->query()->find($id);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the session was found, return it.
|
||||
// -----------------------------------------------------
|
||||
if ( ! is_null($session))
|
||||
{
|
||||
return array('id' => $session->id, 'last_activity' => $session->last_activity, 'data' => unserialize($session->data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a session.
|
||||
*
|
||||
* @param array $session
|
||||
* @return void
|
||||
*/
|
||||
public function save($session)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Delete the existing session row.
|
||||
// -----------------------------------------------------
|
||||
$this->delete($session['id']);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Insert a new session row.
|
||||
// -----------------------------------------------------
|
||||
$this->query()->insert(array('id' => $session['id'], 'last_activity' => $session['last_activity'], 'data' => serialize($session['data'])));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$this->query()->where('id', '=', $id)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all expired sessions.
|
||||
*
|
||||
* @param int $expiration
|
||||
* @return void
|
||||
*/
|
||||
public function sweep($expiration)
|
||||
{
|
||||
$this->query()->where('last_activity', '<', $expiration)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a session database query.
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
private function query()
|
||||
{
|
||||
return \System\DB::table(\System\Config::get('session.table'));
|
||||
}
|
||||
|
||||
}
|
64
system/session/driver/file.php
Normal file
64
system/session/driver/file.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php namespace System\Session\Driver;
|
||||
|
||||
class File implements \System\Session\Driver {
|
||||
|
||||
/**
|
||||
* Load a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return array
|
||||
*/
|
||||
public function load($id)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Look for the session on the file system.
|
||||
// -----------------------------------------------------
|
||||
if (file_exists($path = APP_PATH.'sessions/'.$id))
|
||||
{
|
||||
return unserialize(file_get_contents($path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a session.
|
||||
*
|
||||
* @param array $session
|
||||
* @return void
|
||||
*/
|
||||
public function save($session)
|
||||
{
|
||||
file_put_contents(APP_PATH.'sessions/'.$session['id'], serialize($session), LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
@unlink(APP_PATH.'sessions/'.$id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all expired sessions.
|
||||
*
|
||||
* @param int $expiration
|
||||
* @return void
|
||||
*/
|
||||
public function sweep($expiration)
|
||||
{
|
||||
foreach (glob(APP_PATH.'sessions/*') as $file)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// If the session file has expired, delete it.
|
||||
// -----------------------------------------------------
|
||||
if (filetype($file) == 'file' and filemtime($file) < $expiration)
|
||||
{
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
49
system/session/driver/memcached.php
Normal file
49
system/session/driver/memcached.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php namespace System\Session\Driver;
|
||||
|
||||
class Memcached implements \System\Session\Driver {
|
||||
|
||||
/**
|
||||
* Load a session by ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return array
|
||||
*/
|
||||
public function load($id)
|
||||
{
|
||||
return \System\Cache::driver('memcached')->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a session.
|
||||
*
|
||||
* @param array $session
|
||||
* @return void
|
||||
*/
|
||||
public function save($session)
|
||||
{
|
||||
\System\Cache::driver('memcached')->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('memcached')->forget($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all expired sessions.
|
||||
*
|
||||
* @param int $expiration
|
||||
* @return void
|
||||
*/
|
||||
public function sweep($expiration)
|
||||
{
|
||||
// Memcached sessions will expire automatically.
|
||||
}
|
||||
|
||||
}
|
29
system/session/factory.php
Normal file
29
system/session/factory.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php namespace System\Session;
|
||||
|
||||
class Factory {
|
||||
|
||||
/**
|
||||
* Create a session driver instance.
|
||||
*
|
||||
* @param string $driver
|
||||
* @return Driver
|
||||
*/
|
||||
public static function make($driver)
|
||||
{
|
||||
switch ($driver)
|
||||
{
|
||||
case 'file':
|
||||
return new Driver\File;
|
||||
|
||||
case 'db':
|
||||
return new Driver\DB;
|
||||
|
||||
case 'memcached':
|
||||
return new Driver\Memcached;
|
||||
|
||||
default:
|
||||
throw new \Exception("Session driver [$driver] is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
85
system/str.php
Normal file
85
system/str.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Str {
|
||||
|
||||
/**
|
||||
* The default encoding.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Convert HTML characters to entities.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function entities($value)
|
||||
{
|
||||
return htmlentities($value, ENT_QUOTES, static::$encoding, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to lowercase.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function lower($value)
|
||||
{
|
||||
return function_exists('mb_strtolower') ? mb_strtolower($value, static::$encoding) : strtolower($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to uppercase.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function upper($value)
|
||||
{
|
||||
return function_exists('mb_strtoupper') ? mb_strtoupper($value, static::$encoding) : strtoupper($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to title case (ucwords).
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function title($value)
|
||||
{
|
||||
return (function_exists('mb_convert_case')) ? mb_convert_case($value, MB_CASE_TITLE, static::$encoding) : ucwords(strtolower($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random alpha-numeric string.
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public static function random($length = 16)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Split the character pool into an array.
|
||||
// -----------------------------------------------------
|
||||
$pool = str_split('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 1);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Initialize the return value.
|
||||
// -----------------------------------------------------
|
||||
$value = '';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Build the random string.
|
||||
// -----------------------------------------------------
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
$value .= $pool[mt_rand(0, 61)];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
146
system/text.php
Normal file
146
system/text.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php namespace System;
|
||||
|
||||
class Text {
|
||||
|
||||
/**
|
||||
* Limit the words in a string. Word integrity will be preserved.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int $limit
|
||||
* @param string $end
|
||||
* @return string
|
||||
*/
|
||||
public static function words($value, $limit, $end = '…')
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// If the value is an empty string, bail out.
|
||||
// -----------------------------------------------------
|
||||
if (trim($value) == '')
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Limit the words in the string.
|
||||
// -----------------------------------------------------
|
||||
preg_match('/^\s*+(?:\S++\s*+){1,'.$limit.'}/', $value, $matches);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the string did not exceed the limit, we won't
|
||||
// need an ending character.
|
||||
// -----------------------------------------------------
|
||||
if (strlen($value) == strlen($matches[0]))
|
||||
{
|
||||
$end = '';
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Add the ending character to the string.
|
||||
// -----------------------------------------------------
|
||||
return rtrim($matches[0]).$end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the number of characters in a string. Word integrity will be preserved.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int $limit
|
||||
* @param string $end
|
||||
* @return string
|
||||
*/
|
||||
public static function characters($value, $limit, $end = '…')
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// If the value does not exceed the limit, bail out.
|
||||
// -----------------------------------------------------
|
||||
if (strlen($value) < $limit)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Replace new lines and whitespace in the string.
|
||||
// -----------------------------------------------------
|
||||
$value = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $value));
|
||||
|
||||
// -----------------------------------------------------
|
||||
// If the value does not exceed the limit, bail out.
|
||||
// -----------------------------------------------------
|
||||
if (strlen($value) <= $limit)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Initialize the output string.
|
||||
// -----------------------------------------------------
|
||||
$out = '';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// The string exceeds the character limit. Add each word
|
||||
// to the output individually until we reach the limit.
|
||||
// -----------------------------------------------------
|
||||
foreach (explode(' ', trim($value)) as $val)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Add the word to the output.
|
||||
// -----------------------------------------------------
|
||||
$out .= $val.' ';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Check the output length.
|
||||
// -----------------------------------------------------
|
||||
if (strlen($out) >= $limit)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Trim the output.
|
||||
// -----------------------------------------------------
|
||||
$out = trim($out);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Add the ending character to the string.
|
||||
// -----------------------------------------------------
|
||||
return (strlen($out) == strlen($value)) ? $out : $out.$end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Censor a string.
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $censored
|
||||
* @param string $replacement
|
||||
* @return string
|
||||
*/
|
||||
public static function censor($value, $censored, $replacement = '####')
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Pad the value with spaces.
|
||||
// -----------------------------------------------------
|
||||
$value = ' '.$value.' ';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Assume the word will be book-ended by the following.
|
||||
// -----------------------------------------------------
|
||||
$delim = '[-_\'\"`(){}<>\[\]|!?@#%&,.:;^~*+=\/ 0-9\n\r\t]';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Replace the censored words.
|
||||
// -----------------------------------------------------
|
||||
foreach ($censored as $word)
|
||||
{
|
||||
if ($replacement != '')
|
||||
{
|
||||
$value = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($word, '/')).")({$delim})/i", "\\1{$replacement}\\3", $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($word, '/')).")({$delim})/ie", "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", $value);
|
||||
}
|
||||
}
|
||||
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
}
|
132
system/url.php
Normal file
132
system/url.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php namespace System;
|
||||
|
||||
class URL {
|
||||
|
||||
/**
|
||||
* Generate an application URL.
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function to($url = '', $https = false)
|
||||
{
|
||||
// ----------------------------------------------------
|
||||
// Return the URL unchanged if it is already formed.
|
||||
// ----------------------------------------------------
|
||||
if (strpos($url, '://') !== false)
|
||||
{
|
||||
return $url;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Get the base URL of the application.
|
||||
// ----------------------------------------------------
|
||||
$base = Config::get('application.url');
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Does the URL need an HTTPS protocol?
|
||||
// ----------------------------------------------------
|
||||
if (strpos($base, 'http://') === 0 and $https)
|
||||
{
|
||||
$base = 'https://'.substr($base, 7);
|
||||
}
|
||||
|
||||
return rtrim($base, '/').'/'.ltrim($url, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an application URL with HTTPS.
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function to_secure($url = '')
|
||||
{
|
||||
return static::to($url, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a URL from a route name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
* @param bool $https
|
||||
* @return string
|
||||
*/
|
||||
public static function to_route($name, $parameters = array(), $https = false)
|
||||
{
|
||||
// ----------------------------------------------------
|
||||
// Does the named route exist?
|
||||
// ----------------------------------------------------
|
||||
if ( ! is_null($route = Router::find($name)))
|
||||
{
|
||||
$uris = explode(', ', key($route));
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Get the first URI assigned to the route.
|
||||
// ----------------------------------------------------
|
||||
$uri = substr($uris[0], strpos($uris[0], '/'));
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Replace any parameters in the URI.
|
||||
// ----------------------------------------------------
|
||||
foreach ($parameters as $parameter)
|
||||
{
|
||||
$uri = preg_replace('/\(\:any\)|\(\:num\)|\(.+\)/', $parameter, $uri, 1);
|
||||
}
|
||||
|
||||
return static::to($uri, $https);
|
||||
}
|
||||
|
||||
throw new \Exception("Error generating named route for route [$name]. Route is not defined.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a URL friendly "slug".
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $separator
|
||||
* @return string
|
||||
*/
|
||||
public static function slug($title, $separator = '-')
|
||||
{
|
||||
// ----------------------------------------------------
|
||||
// Remove all characters that are not the separator,
|
||||
// letters, numbers, or whitespace.
|
||||
// ----------------------------------------------------
|
||||
$title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', Str::lower($title));
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Replace all separator characters and whitespace by
|
||||
// a single separator
|
||||
// ----------------------------------------------------
|
||||
$title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
|
||||
|
||||
return trim($title, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for dynamically creating route URLs.
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
// ----------------------------------------------------
|
||||
// Dynamically create a secure route URL.
|
||||
// ----------------------------------------------------
|
||||
if (strpos($method, 'to_secure_') === 0)
|
||||
{
|
||||
return static::to_route(substr($method, 10), $parameters, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Dynamically create a route URL.
|
||||
// ----------------------------------------------------
|
||||
if (strpos($method, 'to_') === 0)
|
||||
{
|
||||
return static::to_route(substr($method, 3), $parameters);
|
||||
}
|
||||
|
||||
throw new \Exception("Method [$method] is not defined on the URL class.");
|
||||
}
|
||||
|
||||
}
|
191
system/view.php
Normal file
191
system/view.php
Normal file
@ -0,0 +1,191 @@
|
||||
<?php namespace System;
|
||||
|
||||
class View {
|
||||
|
||||
/**
|
||||
* The name of the view.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $view;
|
||||
|
||||
/**
|
||||
* The view data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = array();
|
||||
|
||||
/**
|
||||
* The content of the view.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* The name of last rendered view.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $last;
|
||||
|
||||
/**
|
||||
* Create a new view instance.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($view, $data = array())
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->data = $data;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the contents of the view from the file system.
|
||||
// -----------------------------------------------------
|
||||
$this->content = $this->load($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new view instance.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @return View
|
||||
*/
|
||||
public static function make($view, $data = array())
|
||||
{
|
||||
return new self($view, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the content of a view.
|
||||
*
|
||||
* @param string $view
|
||||
* @return string
|
||||
*/
|
||||
private function load($view)
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Is the view in the application directory?
|
||||
// -----------------------------------------------------
|
||||
if (file_exists($path = APP_PATH.'views/'.$view.EXT))
|
||||
{
|
||||
return file_get_contents($path);
|
||||
}
|
||||
// -----------------------------------------------------
|
||||
// Is the view in the system directory?
|
||||
// -----------------------------------------------------
|
||||
elseif (file_exists($path = SYS_PATH.'views/'.$view.EXT))
|
||||
{
|
||||
return file_get_contents($path);
|
||||
}
|
||||
// -----------------------------------------------------
|
||||
// Could not locate the view... bail out.
|
||||
// -----------------------------------------------------
|
||||
else
|
||||
{
|
||||
throw new \Exception("View [$view] doesn't exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a key / value pair to the view data.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return View
|
||||
*/
|
||||
public function bind($key, $value)
|
||||
{
|
||||
$this->data[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parsed content of the view.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// -----------------------------------------------------
|
||||
// Set the name of the last rendered view.
|
||||
// -----------------------------------------------------
|
||||
static::$last = $this->view;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the content of all of the sub-views.
|
||||
// -----------------------------------------------------
|
||||
foreach ($this->data as &$data)
|
||||
{
|
||||
if ($data instanceof View or $data instanceof Response)
|
||||
{
|
||||
$data = (string) $data;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Extract the view data into the local scope.
|
||||
// -----------------------------------------------------
|
||||
extract($this->data, EXTR_SKIP);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Start an output buffer to catch the content.
|
||||
// -----------------------------------------------------
|
||||
ob_start();
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Echo the content of the view.
|
||||
// -----------------------------------------------------
|
||||
echo eval('?>'.$this->content);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Get the contents of the output buffer.
|
||||
// -----------------------------------------------------
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for getting items from the view data.
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for setting items in the view data.
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
{
|
||||
$this->bind($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for determining if an item is in the view data.
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return array_key_exists($key, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Method for removing an item from the view data.
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parsed content of the View.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->get();
|
||||
}
|
||||
|
||||
}
|
78
system/views/error/exception.php
Normal file
78
system/views/error/exception.php
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Laravel - Error</title>
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=Ubuntu&subset=latin' rel='stylesheet' type='text/css'>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #fff;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
font-size: 18px;
|
||||
color: #3f3f3f;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
font-size: 45px;
|
||||
color: #6d6d6d;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #6d6d6d;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.content {
|
||||
padding: 10px 10px 10px 10px;
|
||||
background-color: #eee;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<h1><?php echo $severity; ?></h1>
|
||||
|
||||
<div class="content">
|
||||
<h3>Message:</h3>
|
||||
<?php echo $message; ?> in <strong><?php echo basename($file); ?></strong> on line <strong><?php echo $line; ?></strong>.
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h3>Stack Trace:</h3>
|
||||
|
||||
<pre><?php echo $trace; ?></pre>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h3>Context:</h3>
|
||||
|
||||
<?php if (count($contexts) > 0) { ?>
|
||||
|
||||
<?php foreach ($contexts as $num => $context) { ?>
|
||||
<pre><?php echo htmlentities($num.' '.$context); ?></pre>
|
||||
<?php } ?>
|
||||
|
||||
<?php } else { ?>
|
||||
Context unavailable.
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user