Skip to content

Instantly share code, notes, and snippets.

@scottpnelson
Created March 7, 2014 12:02
Show Gist options
  • Save scottpnelson/9410252 to your computer and use it in GitHub Desktop.
Save scottpnelson/9410252 to your computer and use it in GitHub Desktop.
This gist exceeds the recommended number of files (~10). To access all files, please clone this gist.
/bootstrap/compiled.php
/vendor
composer.phar
composer.lock
.env.local.php
.env.php
.DS_Store
Thumbs.db
<?php
return array(
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => true,
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => 'http://localhost',
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => 'YourSecretKey!!!',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => array(
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Cache\CacheServiceProvider',
'Illuminate\Session\CommandsServiceProvider',
'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
'Illuminate\Routing\ControllerServiceProvider',
'Illuminate\Cookie\CookieServiceProvider',
'Illuminate\Database\DatabaseServiceProvider',
'Illuminate\Encryption\EncryptionServiceProvider',
'Illuminate\Filesystem\FilesystemServiceProvider',
'Illuminate\Hashing\HashServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Illuminate\Log\LogServiceProvider',
'Illuminate\Mail\MailServiceProvider',
'Illuminate\Database\MigrationServiceProvider',
'Illuminate\Pagination\PaginationServiceProvider',
'Illuminate\Queue\QueueServiceProvider',
'Illuminate\Redis\RedisServiceProvider',
'Illuminate\Remote\RemoteServiceProvider',
'Illuminate\Auth\Reminders\ReminderServiceProvider',
'Illuminate\Database\SeedServiceProvider',
'Illuminate\Session\SessionServiceProvider',
'Illuminate\Translation\TranslationServiceProvider',
'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Workbench\WorkbenchServiceProvider',
),
/*
|--------------------------------------------------------------------------
| Service Provider Manifest
|--------------------------------------------------------------------------
|
| The service provider manifest is used by Laravel to lazy load service
| providers which are not needed for each request, as well to keep a
| list of all of the services. Here, you may set its storage spot.
|
*/
'manifest' => storage_path().'/meta',
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => array(
'App' => 'Illuminate\Support\Facades\App',
'Artisan' => 'Illuminate\Support\Facades\Artisan',
'Auth' => 'Illuminate\Support\Facades\Auth',
'Blade' => 'Illuminate\Support\Facades\Blade',
'Cache' => 'Illuminate\Support\Facades\Cache',
'ClassLoader' => 'Illuminate\Support\ClassLoader',
'Config' => 'Illuminate\Support\Facades\Config',
'Controller' => 'Illuminate\Routing\Controller',
'Cookie' => 'Illuminate\Support\Facades\Cookie',
'Crypt' => 'Illuminate\Support\Facades\Crypt',
'DB' => 'Illuminate\Support\Facades\DB',
'Eloquent' => 'Illuminate\Database\Eloquent\Model',
'Event' => 'Illuminate\Support\Facades\Event',
'File' => 'Illuminate\Support\Facades\File',
'Form' => 'Illuminate\Support\Facades\Form',
'Hash' => 'Illuminate\Support\Facades\Hash',
'HTML' => 'Illuminate\Support\Facades\HTML',
'Input' => 'Illuminate\Support\Facades\Input',
'Lang' => 'Illuminate\Support\Facades\Lang',
'Log' => 'Illuminate\Support\Facades\Log',
'Mail' => 'Illuminate\Support\Facades\Mail',
'Paginator' => 'Illuminate\Support\Facades\Paginator',
'Password' => 'Illuminate\Support\Facades\Password',
'Queue' => 'Illuminate\Support\Facades\Queue',
'Redirect' => 'Illuminate\Support\Facades\Redirect',
'Redis' => 'Illuminate\Support\Facades\Redis',
'Request' => 'Illuminate\Support\Facades\Request',
'Response' => 'Illuminate\Support\Facades\Response',
'Route' => 'Illuminate\Support\Facades\Route',
'Schema' => 'Illuminate\Support\Facades\Schema',
'Seeder' => 'Illuminate\Database\Seeder',
'Session' => 'Illuminate\Support\Facades\Session',
'SSH' => 'Illuminate\Support\Facades\SSH',
'Str' => 'Illuminate\Support\Str',
'URL' => 'Illuminate\Support\Facades\URL',
'Validator' => 'Illuminate\Support\Facades\Validator',
'View' => 'Illuminate\Support\Facades\View',
),
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Authentication Driver
|--------------------------------------------------------------------------
|
| This option controls the authentication driver that will be utilized.
| This driver manages the retrieval and authentication of the users
| attempting to get access to protected areas of your application.
|
| Supported: "database", "eloquent"
|
*/
'driver' => 'eloquent',
/*
|--------------------------------------------------------------------------
| Authentication Model
|--------------------------------------------------------------------------
|
| When using the "Eloquent" authentication driver, we need to know which
| Eloquent model should be used to retrieve your users. Of course, it
| is often just the "User" model but you may use whatever you like.
|
*/
'model' => 'User',
/*
|--------------------------------------------------------------------------
| Authentication Table
|--------------------------------------------------------------------------
|
| When using the "Database" authentication driver, we need to know which
| table should be used to retrieve your users. We have chosen a basic
| default value but you may easily change it to any table you like.
|
*/
'table' => 'users',
/*
|--------------------------------------------------------------------------
| Password Reminder Settings
|--------------------------------------------------------------------------
|
| Here you may set the settings for password reminders, including a view
| that should be used as your password reminder e-mail. You will also
| be able to set the name of the table that holds the reset tokens.
|
| The "expire" time is the number of minutes that the reminder should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Cache Driver
|--------------------------------------------------------------------------
|
| This option controls the default cache "driver" that will be used when
| using the Caching library. Of course, you may use other drivers any
| time you wish. This is the default when another is not specified.
|
| Supported: "file", "database", "apc", "memcached", "redis", "array"
|
*/
'driver' => 'file',
/*
|--------------------------------------------------------------------------
| File Cache Location
|--------------------------------------------------------------------------
|
| When using the "file" cache driver, we need a location where the cache
| files may be stored. A sensible default has been specified, but you
| are free to change it to any other place on disk that you desire.
|
*/
'path' => storage_path().'/cache',
/*
|--------------------------------------------------------------------------
| Database Cache Connection
|--------------------------------------------------------------------------
|
| When using the "database" cache driver you may specify the connection
| that should be used to store the cached items. When this option is
| null the default database connection will be utilized for cache.
|
*/
'connection' => null,
/*
|--------------------------------------------------------------------------
| Database Cache Table
|--------------------------------------------------------------------------
|
| When using the "database" cache driver we need to know the table that
| should be used to store the cached items. A default table name has
| been provided but you're free to change it however you deem fit.
|
*/
'table' => 'cache',
/*
|--------------------------------------------------------------------------
| Memcached Servers
|--------------------------------------------------------------------------
|
| Now you may specify an array of your Memcached servers that should be
| used when utilizing the Memcached cache driver. All of the servers
| should contain a value for "host", "port", and "weight" options.
|
*/
'memcached' => array(
array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),
),
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => 'laravel',
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Additional Compiled Classes
|--------------------------------------------------------------------------
|
| Here you may specify additional classes to include in the compiled file
| generated by the `artisan optimize` command. These should be classes
| that are included on basically every request into the application.
|
*/
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| PDO Fetch Style
|--------------------------------------------------------------------------
|
| By default, database results will be returned as instances of the PHP
| stdClass object; however, you may desire to retrieve records in an
| array format for simplicity. Here you can tweak the fetch style.
|
*/
'fetch' => PDO::FETCH_CLASS,
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => 'mysql',
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => array(
'sqlite' => array(
'driver' => 'sqlite',
'database' => __DIR__.'/../database/production.sqlite',
'prefix' => '',
),
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
'pgsql' => array(
'driver' => 'pgsql',
'host' => 'localhost',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
),
'sqlsrv' => array(
'driver' => 'sqlsrv',
'host' => 'localhost',
'database' => 'database',
'username' => 'root',
'password' => '',
'prefix' => '',
),
),
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => array(
'cluster' => false,
'default' => array(
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0,
),
),
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail"
|
*/
'driver' => 'smtp',
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Postmark mail service, which will provide reliable delivery.
|
*/
'host' => 'smtp.mailgun.org',
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to delivery e-mails to
| users of your application. Like the host we have set this value to
| stay compatible with the Postmark e-mail application by default.
|
*/
'port' => 587,
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => array('address' => null, 'name' => null),
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => 'tls',
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => null,
/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
'password' => null,
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
'pretend' => false,
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Queue Driver
|--------------------------------------------------------------------------
|
| The Laravel queue API supports a variety of back-ends via an unified
| API, giving you convenient access to each back-end using the same
| syntax for each one. Here you may set the default queue driver.
|
| Supported: "sync", "beanstalkd", "sqs", "iron"
|
*/
'default' => 'sync',
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
*/
'connections' => array(
'sync' => array(
'driver' => 'sync',
),
'beanstalkd' => array(
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'ttr' => 60,
),
'sqs' => array(
'driver' => 'sqs',
'key' => 'your-public-key',
'secret' => 'your-secret-key',
'queue' => 'your-queue-url',
'region' => 'us-east-1',
),
'iron' => array(
'driver' => 'iron',
'host' => 'mq-aws-us-east-1.iron.io',
'token' => 'your-token',
'project' => 'your-project-id',
'queue' => 'your-queue-name',
),
'redis' => array(
'driver' => 'redis',
'queue' => 'default',
),
),
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => array(
'database' => 'mysql', 'table' => 'failed_jobs',
),
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Remote Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify the default connection that will be used for SSH
| operations. This name should correspond to a connection name below
| in the server list. Each connection will be manually accessible.
|
*/
'default' => 'production',
/*
|--------------------------------------------------------------------------
| Remote Server Connections
|--------------------------------------------------------------------------
|
| These are the servers that will be accessible via the SSH task runner
| facilities of Laravel. This feature radically simplifies executing
| tasks on your servers, such as deploying out these applications.
|
*/
'connections' => array(
'production' => array(
'host' => '',
'username' => '',
'password' => '',
'key' => '',
'keyphrase' => '',
'root' => '/var/www',
),
),
/*
|--------------------------------------------------------------------------
| Remote Server Groups
|--------------------------------------------------------------------------
|
| Here you may list connections under a single group name, which allows
| you to easily access all of the servers at once using a short name
| that is extremely easy to remember, such as "web" or "database".
|
*/
'groups' => array(
'web' => array('production')
),
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => 'file',
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => 120,
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path().'/sessions',
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => null,
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => array(2, 100),
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => 'laravel_session',
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => null,
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
|
*/
'secure' => false,
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Cache Driver
|--------------------------------------------------------------------------
|
| This option controls the default cache "driver" that will be used when
| using the Caching library. Of course, you may use other drivers any
| time you wish. This is the default when another is not specified.
|
| Supported: "file", "database", "apc", "memcached", "redis", "array"
|
*/
'driver' => 'array',
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "native", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => 'array',
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => array(__DIR__.'/../views'),
/*
|--------------------------------------------------------------------------
| Pagination View
|--------------------------------------------------------------------------
|
| This view will be used to render the pagination link output, and can
| be easily customized here to show any view you like. A clean view
| compatible with Twitter's Bootstrap is given to you by default.
|
*/
'pagination' => 'pagination::slider-3',
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Workbench Author Name
|--------------------------------------------------------------------------
|
| When you create new packages via the Artisan "workbench" command your
| name is needed to generate the composer.json file for your package.
| You may specify it now so it is used for all of your workbenches.
|
*/
'name' => '',
/*
|--------------------------------------------------------------------------
| Workbench Author E-Mail Address
|--------------------------------------------------------------------------
|
| Like the option above, your e-mail address is used when generating new
| workbench packages. The e-mail is placed in your composer.json file
| automatically after the package is created by the workbench tool.
|
*/
'email' => '',
);
<?php
class BaseController extends Controller {
/**
* Setup the layout used by the controller.
*
* @return void
*/
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$this->layout = View::make($this->layout);
}
}
}
<?php
class HomeController extends BaseController {
/*
|--------------------------------------------------------------------------
| Default Home Controller
|--------------------------------------------------------------------------
|
| You may wish to use controllers instead of, or in addition to, Closure
| based routes. That's great! Here is an example controller method to
| get you started. To route to this controller, just add the route:
|
| Route::get('/', 'HomeController@showWelcome');
|
*/
public function showWelcome()
{
return View::make('hello');
}
}
<?php
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Eloquent::unguard();
// $this->call('UserTableSeeder');
}
}
<?php
/*
|--------------------------------------------------------------------------
| Application & Route Filters
|--------------------------------------------------------------------------
|
| Below you will find the "before" and "after" events for the application
| which may be used to do any work before or after a request into your
| application. Here you may also register your custom route filters.
|
*/
App::before(function($request)
{
//
});
App::after(function($request, $response)
{
//
});
/*
|--------------------------------------------------------------------------
| Authentication Filters
|--------------------------------------------------------------------------
|
| The following filters are used to verify that the user of the current
| session is logged into this application. The "basic" filter easily
| integrates HTTP Basic authentication for quick, simple checking.
|
*/
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::guest('login');
});
Route::filter('auth.basic', function()
{
return Auth::basic();
});
/*
|--------------------------------------------------------------------------
| Guest Filter
|--------------------------------------------------------------------------
|
| The "guest" filter is the counterpart of the authentication filters as
| it simply checks that the current user is not logged in. A redirect
| response will be issued if they are, which you may freely change.
|
*/
Route::filter('guest', function()
{
if (Auth::check()) return Redirect::to('/');
});
/*
|--------------------------------------------------------------------------
| CSRF Protection Filter
|--------------------------------------------------------------------------
|
| The CSRF filter is responsible for protecting your application against
| cross-site request forgery attacks. If this special token in a user
| session does not match the one given in this request, we'll bail.
|
*/
Route::filter('csrf', function()
{
if (Session::token() != Input::get('_token'))
{
throw new Illuminate\Session\TokenMismatchException;
}
});
<?php
return array(
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
"password" => "Passwords must be at least six characters and match the confirmation.",
"user" => "We can't find a user with that e-mail address.",
"token" => "This password reset token is invalid.",
"sent" => "Password reminder sent!",
);
<?php
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
"accepted" => "The :attribute must be accepted.",
"active_url" => "The :attribute is not a valid URL.",
"after" => "The :attribute must be a date after :date.",
"alpha" => "The :attribute may only contain letters.",
"alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.",
"alpha_num" => "The :attribute may only contain letters and numbers.",
"array" => "The :attribute must be an array.",
"before" => "The :attribute must be a date before :date.",
"between" => array(
"numeric" => "The :attribute must be between :min and :max.",
"file" => "The :attribute must be between :min and :max kilobytes.",
"string" => "The :attribute must be between :min and :max characters.",
"array" => "The :attribute must have between :min and :max items.",
),
"confirmed" => "The :attribute confirmation does not match.",
"date" => "The :attribute is not a valid date.",
"date_format" => "The :attribute does not match the format :format.",
"different" => "The :attribute and :other must be different.",
"digits" => "The :attribute must be :digits digits.",
"digits_between" => "The :attribute must be between :min and :max digits.",
"email" => "The :attribute must be a valid email address.",
"exists" => "The selected :attribute is invalid.",
"image" => "The :attribute must be an image.",
"in" => "The selected :attribute is invalid.",
"integer" => "The :attribute must be an integer.",
"ip" => "The :attribute must be a valid IP address.",
"max" => array(
"numeric" => "The :attribute may not be greater than :max.",
"file" => "The :attribute may not be greater than :max kilobytes.",
"string" => "The :attribute may not be greater than :max characters.",
"array" => "The :attribute may not have more than :max items.",
),
"mimes" => "The :attribute must be a file of type: :values.",
"min" => array(
"numeric" => "The :attribute must be at least :min.",
"file" => "The :attribute must be at least :min kilobytes.",
"string" => "The :attribute must be at least :min characters.",
"array" => "The :attribute must have at least :min items.",
),
"not_in" => "The selected :attribute is invalid.",
"numeric" => "The :attribute must be a number.",
"regex" => "The :attribute format is invalid.",
"required" => "The :attribute field is required.",
"required_if" => "The :attribute field is required when :other is :value.",
"required_with" => "The :attribute field is required when :values is present.",
"required_with_all" => "The :attribute field is required when :values is present.",
"required_without" => "The :attribute field is required when :values is not present.",
"required_without_all" => "The :attribute field is required when none of :values are present.",
"same" => "The :attribute and :other must match.",
"size" => array(
"numeric" => "The :attribute must be :size.",
"file" => "The :attribute must be :size kilobytes.",
"string" => "The :attribute must be :size characters.",
"array" => "The :attribute must contain :size items.",
),
"unique" => "The :attribute has already been taken.",
"url" => "The :attribute format is invalid.",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(
'attribute-name' => array(
'rule-name' => 'custom-message',
),
),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(),
);
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* @return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
Route::get('/', function()
{
return View::make('hello');
});
<?php
/*
|--------------------------------------------------------------------------
| Register The Artisan Commands
|--------------------------------------------------------------------------
|
| Each available Artisan command must be registered with the console so
| that it is available to be called. We'll register every command so
| the console gets access to each of the command object instances.
|
*/
<?php
/*
|--------------------------------------------------------------------------
| Register The Laravel Class Loader
|--------------------------------------------------------------------------
|
| In addition to using Composer, you may use the Laravel class loader to
| load your controllers and models. This is useful for keeping all of
| your classes in the "global" namespace without Composer updating.
|
*/
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
));
/*
|--------------------------------------------------------------------------
| Application Error Logger
|--------------------------------------------------------------------------
|
| Here we will configure the error logger setup for the application which
| is built on top of the wonderful Monolog library. By default we will
| build a basic log file setup which creates a single file for logs.
|
*/
Log::useFiles(storage_path().'/logs/laravel.log');
/*
|--------------------------------------------------------------------------
| Application Error Handler
|--------------------------------------------------------------------------
|
| Here you may handle any errors that occur in your application, including
| logging them or displaying custom views for specific errors. You may
| even register several error handlers to handle different types of
| exceptions. If nothing is returned, the default error view is
| shown, which includes a detailed stack trace during debug.
|
*/
App::error(function(Exception $exception, $code)
{
Log::error($exception);
});
/*
|--------------------------------------------------------------------------
| Maintenance Mode Handler
|--------------------------------------------------------------------------
|
| The "down" Artisan command gives you the ability to put an application
| into maintenance mode. Here, you will define what is displayed back
| to the user if maintenance mode is in effect for the application.
|
*/
App::down(function()
{
return Response::make("Be right back!", 503);
});
/*
|--------------------------------------------------------------------------
| Require The Filters File
|--------------------------------------------------------------------------
|
| Next we will load the filters file for the application. This gives us
| a nice separate location to store our route and application filter
| definitions instead of putting them all in the main routes file.
|
*/
require app_path().'/filters.php';
<?php
class ExampleTest extends TestCase {
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
}
}
<?php
class TestCase extends Illuminate\Foundation\Testing\TestCase {
/**
* Creates the application.
*
* @return \Symfony\Component\HttpKernel\HttpKernelInterface
*/
public function createApplication()
{
$unitTesting = true;
$testEnvironment = 'testing';
return require __DIR__.'/../../bootstrap/start.php';
}
}
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Password Reset</h2>
<div>
To reset your password, complete this form: {{ URL::to('password/reset', array($token)) }}.
</div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Laravel PHP Framework</title>
<style>
@import url(//fonts.googleapis.com/css?family=Lato:700);
body {
margin:0;
font-family:'Lato', sans-serif;
text-align:center;
color: #999;
}
.welcome {
width: 300px;
height: 200px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -100px;
}
a, a:visited {
text-decoration:none;
}
h1 {
font-size: 32px;
margin: 16px 0 0 0;
}
</style>
</head>
<body>
<div class="welcome">
<a href="http://laravel.com" title="Laravel PHP Framework"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIcAAACHCAYAAAA850oKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyNUVCMTdGOUJBNkExMUUyOTY3MkMyQjZGOTYyREVGMiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoyNUVCMTdGQUJBNkExMUUyOTY3MkMyQjZGOTYyREVGMiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjI1RUIxN0Y3QkE2QTExRTI5NjcyQzJCNkY5NjJERUYyIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjI1RUIxN0Y4QkE2QTExRTI5NjcyQzJCNkY5NjJERUYyIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+g6J7EAAAEL1JREFUeNrsXQmUFcUVrT8MKqJGjIKirIIQdlBcEISgIbhEjEYlLohGwYwL0eMSUKMeEsyBiCJBIrgcILjhwsG4YGIcHRCJggtuIAiKiYKKUeMumHvp96X9zPyu+tPV2697zjs9Z6Z//+p6d169evXqVU4Z4qtj+uyLy08hfSAdIS0g2yiHpOFryFrIq5CnIQ9vM/epJSYPyGkSohEuIyDnQNq7fk8tVkKmQKaBKJ/Vmxwgxmm4/BGyu+vbzOBdyGjIDJDkW2NygBS74DILcoTry8ziIcgwEOQDbXKAGO1weRTSxvVf5rEaMggEWRlIDiHGAkgz129lNcz0B0FW1EkOGUqedRajbC1Ib/8QU1FwwwxHjLIF9T4LBiK3FTnwy2G4HOX6qOywCfK5/Hw45NTvDSsSx1gF2cP1VWZBArwGeQnyik9WYyjZCA60xs9nQk6CdMPv/lcpHzzLESPTJODPa6DwTXV9CH9bg8vlIMlsOqeQB/OWg16qi3yWAQlMUClrJY4YycWnkBU2SVAnORgAcf2fGBJwkexlkVfk+maxELdtcuzj9FLeJChGjgmQU+RnBztkuAvyiPICjGuSRoK6kHdISZCLnB5DRw3kOJDhvSQ0Bnr+AS49OFWFdJefu8qfr4OM9hM3by3GivVwy/Lh4uw4iAESMLjZ1keAPBlaFfnYpWLlxn7PcsgDT8blr06foaIryPGSZSLsJP/93UTy1qBxCY/j7OcItHl+ITn4czXkEKfT0MCMq5EhkYBWvoMovquPEK1CbvMGSC+0+83CVdkuuDwPaeD0Ggo4fh+Kjn7ckAh7FZCA0gnSMKJ203HuW1s+x0RcLnB6DQ1vK2+t4sMAQjDeNEZ8g50T0O6bKmr55VXKS/5wCAe0AlM17ttbeWsaOyek3SO3IgcY/jEuFzudhooTYRlODbjnZsjSJDW6oo7fc2VuodNpqJgiy+K1Av+U3GcyVKaTySWHBEK4R2Wj02lo2JGhAhCkQRGCvI5LVdItBxv6Ai43Op2GioMhvy12A/p9pkpIvKki4O9XQNY7nYaKq2A9egfcQ+uxKtHkAIs/cs5p6GAwazYI0rhIv38i/sfXSbYcxCznnIYOJldNDPjHZCBqTKLJIc7pucqLuzuEhxGwHkcH3HMtZH6SLQcJwpD6X5w+Q8ctIMjuAf+Y3DKyLhZyoHF9NO+9HPKe02eo2BVym38jUS0EWS8E+TYOy3GDrP8HWY8Pg6ZhDiVhsPJiSsX6npvaJ8RBDmafn655/23KqxLjEC4m4B+0k4bl/lccPsc4SRrRcU6rnHMaOraT6e22Rfqe01ruRvskanI0VV7AS8c5fc45p1bADK6xAX3PwNjIqMlBjAJzdbcpkEgfOH2Gjouggx8HEOQOGd4jJQezjCZqWg+mko12ugwdnLXMBEGaBNx3vvJ2wUUa5zgSDRusO0eP2kEqEwQmB3EHvPLC619FSQ7iOhCkoYb12CRTsG+dPkNHYHKQ+H4XR02OjkHzbl8DGf+f5nRpBUWTgwSTIQ9GSQ6Cy8q7aT5jjHNOrWBHmd42CAgtDIe8EyU5uG3u9wbO6RinSyvoE+T4o//fV95uxU1RkYM4E6ztofkcJscucbq0giuhh/0DCPJP5VWZjowcm9ddNK2Hc07tgclBzD3dIYhEkEVRkYPoh0adqEmQxTK9dQgfOslB3ygvvP5RVOQgxku1QR1wfPzQ6dIKzoIehgQQZI3yiv9FRo6WkEs0rcf7zjm1iptBkD0CdDAHl+lRkYO4FI1qoXnvNOecWgOTg24tlhwk+I3ySktFQg4OK+MNnNNznR6tYXBQ/8pBOwyvfxkFOYihYGxfTYIwIeg2p0drCEwOgg5exOVCw+eukkkFQ/ctc/gSk+kn4/n76dS/xHOZI7JcJWfXeNbAHYkHQBdfBuhhLi51ObLUD49PqabgWW8XzqFN0BNyhvKCXkHWYz0axtS2Pzs9WgHreDCKHbT4Rn3RiuwpZKj2kaFoqQ1Ty0EwG3of2Q0XZD24LsDFuR5Ol1ZA3R0mEdJiemDxuM+CyFAfnyMPDhe/0/Q9uEu/yunQGrSSg6CHN0yJUSo5iPPQoA6aBFnknFMrYEyJ/gQjp41tfEGpVYuZDMSipronRzJyehxkJ6fTkvGW8ore0oF8AvKa7UrIpfgcfrBm5cM6N+J7mPc4yelYG8uFBCREDUs/Rj5m1ZMcTHLtInsqgshBK8XIaTen962wScIEJMKTtA5xlsSWgyAH1rcYPrcynKc0sta5aogvPUc6oNzB2MRi3zCxQJKG4yLDNrgcpLzjVX6ivF2QFfW1HASrD7aXDb86DWFZo1PLjAzso0W+YeKZoOBVBITgLjuG4rmKOwCyfVgOqR87STBmhOb9DNoMybhzuj7vK8gw8aJM6+MkA2c0rHXaVq7MUd1BLEVDGz6HPxizr6TL6zR0FC7XZ4gMa4QENTJEvBZ3g8THaylEoNRVB4RWo79NcijpmP460ytpOAvCdE4pGV72WYWawjWJmMhQIc7+YaJwVi7kpmseBBRU25RHhu5pkxzEUHTUXZovQ7ZWp4AIG2WWVeObVm5IQsNkb/OhItxju0stt3EKPEMVz+/lMsdw5e22s0aOtZCOkk+g83KslHxSwsjwucwk8sPEIrzPpwkhw15ChIFy3VPzo9XiDBdDE/EbtwvTIfWD2WJMKbxK834eHfYzcY7iwn+VVy0xP0wsARm+SggZfigWIW8dSj3ilVZ6tfKirHWBub8PQI63ZTmILyAd0MFvaXYAE1KujbDP3/VZBcoy2+ezGpCBs4dDxDIcJj5ELqTHU/nT1ZZz6/2Wcq041dQZc4B/bcNyKDFLrF91oub93BtzhkXndFWB87gyKeOXBJ/6CBkoByh7p3Ry2GCQa7aQIE+Gdf5JhPyzsk3dbViO70wZvvRJzU6id/14CN/Jd1nmswpPlLJUbZEMdPx6ilU4VGYUjSJuRhX6ZGpAOzl8LbVJjucl9rFJs+PuNLA2eXwtMwk6WwxDLww6ESkGQnT2OZBJOGyHkdne6KdlAe0eapMcxEg0YppmJ9LzZvCo2LY/zhqe9g0Ti3VnRhGSobVvakkL0SyB03Oegs1c4M+L3WSbHFxZbK+TUigdy9D6+AInqsYnS2TbX5LI0NTnQJIQbVU6EHhype0jylnjgxt8dVPkGVJvo7yEWA4TLyftaG851bm/b6jootIJ1l5/FP17b1yWg2CEcVBQEmxSIauXfX0zCp6VUqGyAcZ4utcVdqiMoAH00MdBDkwJGSqFAPlIJKd126psgs7xHVzKqG24tk0OloN6g9NLrgOgASsSSAYGmbr5HEgGoXZU5YM+MvRfYXNY4ZT1XQmsULjg459J8G83JcGHwDu381kGyq6qvEHd8eTs6rAsB8Pki8VxpHQPCOgwn6CrOJtRk6G5z4HktaVy8IM+FKsH0f/4oBTLwenoQt+08hn/AhWeQ9N8bMAzuNQ9xXZWlCTI9ldbFqw6Ov1rgQtvQ/LWvZjlMF2gWiZOZ/Mi91BpvUiskMmwvdqyYDVQviPndG0MrpCzvMPkQsuxUn0/1W1lCUpqrbykkWJglvUN9VkWlwWr/cWBHCikbOh0GwoYXufu/RdIDq7f14S1QIXnMXkn6PSFx/B9NQbP5JjYQ22JRPZTtWRLO4QGLmPsF7rphSLp+Vep4oEiOrOTgmL7vmc2Ecu2i9NbZLgl9EifFI0LqgmWjzrqPpNrLJc7fUWKX9kKA3MJPcin6A+LYLJiOV2cXocI57ehQ7b2LSj4NR3GtuIzcJcV09EmGTyT4d1RTmXRwdp0Twrbcvm9s5CCmdOFJwBwpsTEkyUGz71HeeUcHCyjMkQykGjdfbGGASq4qAg/8yflrWvogjkfRypfCr1DAi2HrFHkYw1UcKlrFEfDejxg8L3cm3uZU1+CyOFbo8gTokVI7WChki66WV6yKZgrvM2dCmMiR8RrFOeAHDcaEJXBttlOhRGRQ9Yo+qktq5c9VXRZT8w3bQeCfGzg43Ah8CCnRkvkkJLVeTIcpOJdo7gG5BhjYD32U97xpW6RzRI5kpTAy7A6M8bWGhDkVlxOd6oMH0lLlOX0dJzhZ1jG8hOnyuyTgzhZhgstwMqsw2WsU2V5kIP+g+mue4bhX3fqzD45iEOCzjMrsB5c5LvQqbM8yEGMlz0kugT5Gy7znUrLgxzMJjvb8DMXQL5xas0+OYgrZW+qrvXgoXfu8J8yIceuKuAs91pwtfKirQ4ZJwcxCtajlYH14ObgK5xqy4McDIz9wfAzTCl8zqk3++QgTANj3Hx1nlNvyaBT/0ia6kwYBcZAEK7Y3uH0rI2NEgpgqetm6L/Dk7bwFoSfo9FzdW+WOmNMCnIboGoHLWw1ZA7kvsJjUdJGDobIO+ucDOUjyJgSfJYsg/qmVb2bImtTtaIyZS/G+pgMjE02+MxEMZVtypwUi2WYnQNC/EfnA2mzHATrR7STKauu9TgGl/vLkBCsZnCXEOIt0w9XpvCFWSyeQ8UlBs7pXBDk78o7lSjrWCo+BAmxqj4PSqPl2GwMlHd0x2oD69FJeVWFGmSQEC/5fIjlYT20MqWdwfoc3E13vIH1eAUE4bpLVrZULhdC3G7r2LC0Wo48+qFjFhhYj51lartbSt+XlRlvFwthfVN52snBPba9TSoU4n05c5meMkLkfYglUX5xpUo3eDguz6idafAZZqvzsJleCX6vtXlCKK/4fyz/wLQcrBXaKMUE4Zy9vcnpCXhnFmZdmLD3eAdyr8QiFsVZr1V2Og6plM7dO8XkaK7MzpWjc/oUOmCWiv9kbOad3COEWBjncWJS453VBE+GHAFZQ8vB3e1HpXx4odXgZqh/G3RGM3FOoz4ZmyWs7hNCVMd5UrUU4uNe6FMgvyjoiwcqxbymnRxcWLsGMszAeqxD5zApaFIE7eP+33ky0/iHydqQJVJ0FwvBzeh1HT+6iJaDTt2zGZj3c4zeHx3/rEEnVcqMp5uF9vBUKWbEM3z9ENr1ZcyEaCFkICm6anykZ04+yCBKhwwQhON2X8NO4/01IX0/9/o+JLOMeXEfMSbJ2ccLITh86G44X4G2d8iTg1HD61U2cAJebI5hJ86sh3O6OWtKedHKebpHllkkBM+GOVwIcbTyosmmOB/vMTlPjkYSbNk9A+TgeksnvNwXFp1TzioekyHj/rjPtpdaJX3FsaSlaBJGaCDn+wI+eFZGrMdleLlxhh3MqstTAnwaOu+sJrRV1lRMpOgkhKAv0Sqkx56Gd9scVMwVsG9eBmYu+aktj0x/2/C/b6Z0th9MkuGZt3frJslYJgTjOkOlnT1DfvyDeMfv9F9Y9omRMSaItM0AQe7Ei/7SsOO5nH+uOG+sGHR7KUkyFgjBY8WOFUKwApONxPBVMtvbUCs5pCHtxHw2zQBBtI9MTxqgB5bfGiSOMisO2Ky7yuDhgMJjVHJ1NIwEmZ8BC/KC8o5M35gSQlAfB4qFOEFFc/YcLcbg2s7XyRVpKIeYGRnwQarw4lMTTop9ZOpJiXKdi0G64f5z3bTI4WMyGzwhxdPcDTI125AwQjT1OZa9I/56rgCPRp/MKHZTTvNFGAcZobw8iDRGUqeiI6oSQAhWXj5GCMFk56jzWRnLYarkreiPT4NuzpXwgvvKix0M+ZHylsyTng/CoFUvnlsWAyEaSH+dIsRoHNFXfyGO5qsyweC59UtNHvB/AQYAJxSvvrFB3mUAAAAASUVORK5CYII=" alt="Laravel PHP Framework"></a>
<h1>You have arrived.</h1>
</div>
</body>
</html>
#!/usr/bin/env php
<?php
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/bootstrap/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let's turn on the lights.
| This bootstrap the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight these users.
|
*/
$app = require_once __DIR__.'/bootstrap/start.php';
/*
|--------------------------------------------------------------------------
| Load The Artisan Console Application
|--------------------------------------------------------------------------
|
| We'll need to run the script to load and return the Artisan console
| application. We keep this in its own script so that we will load
| the console application independent of running commands which
| will allow us to fire commands from Routes when we want to.
|
*/
$app->setRequestForConsoleEnvironment();
$artisan = Illuminate\Console\Application::start($app);
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$status = $artisan->run();
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running. We will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$app->shutdown();
exit($status);
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Composer Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Include The Compiled Class File
|--------------------------------------------------------------------------
|
| To dramatically increase your application's performance, you may use a
| compiled class file which contains all of the classes commonly used
| by a request. The Artisan "optimize" is used to create this file.
|
*/
if (file_exists($compiled = __DIR__.'/compiled.php'))
{
require $compiled;
}
/*
|--------------------------------------------------------------------------
| Setup Patchwork UTF-8 Handling
|--------------------------------------------------------------------------
|
| The Patchwork library provides solid handling of UTF-8 strings as well
| as provides replacements for all mb_* and iconv type functions that
| are not available by default in PHP. We'll setup this stuff here.
|
*/
Patchwork\Utf8\Bootup::initMbstring();
/*
|--------------------------------------------------------------------------
| Register The Laravel Auto Loader
|--------------------------------------------------------------------------
|
| We register an auto-loader "behind" the Composer loader that can load
| model classes on the fly, even if the autoload files have not been
| regenerated for the application. We'll add it to the stack here.
|
*/
Illuminate\Support\ClassLoader::register();
/*
|--------------------------------------------------------------------------
| Register The Workbench Loaders
|--------------------------------------------------------------------------
|
| The Laravel workbench provides a convenient place to develop packages
| when working locally. However we will need to load in the Composer
| auto-load files for the packages so that these can be used here.
|
*/
if (is_dir($workbench = __DIR__.'/../workbench'))
{
Illuminate\Workbench\Starter::start($workbench);
}
<?php
return array(
/*
|--------------------------------------------------------------------------
| Application Path
|--------------------------------------------------------------------------
|
| Here we just defined the path to the application directory. Most likely
| you will never need to change this value as the default setup should
| work perfectly fine for the vast majority of all our applications.
|
*/
'app' => __DIR__.'/../app',
/*
|--------------------------------------------------------------------------
| Public Path
|--------------------------------------------------------------------------
|
| The public path contains the assets for your web application, such as
| your JavaScript and CSS files, and also contains the primary entry
| point for web requests into these applications from the outside.
|
*/
'public' => __DIR__.'/../public',
/*
|--------------------------------------------------------------------------
| Base Path
|--------------------------------------------------------------------------
|
| The base path is the root of the Laravel installation. Most likely you
| will not need to change this value. But, if for some wild reason it
| is necessary you will do so here, just proceed with some caution.
|
*/
'base' => __DIR__.'/..',
/*
|--------------------------------------------------------------------------
| Storage Path
|--------------------------------------------------------------------------
|
| The storage path is used by Laravel to store cached Blade views, logs
| and other pieces of information. You may modify the path here when
| you want to change the location of this directory for your apps.
|
*/
'storage' => __DIR__.'/../app/storage',
);
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application;
/*
|--------------------------------------------------------------------------
| Detect The Application Environment
|--------------------------------------------------------------------------
|
| Laravel takes a dead simple approach to your application environments
| so you can just specify a machine name for the host that matches a
| given environment, then we will automatically detect it for you.
|
*/
$env = $app->detectEnvironment(array(
'local' => array('your-machine-name'),
));
/*
|--------------------------------------------------------------------------
| Bind Paths
|--------------------------------------------------------------------------
|
| Here we are binding the paths configured in paths.php to the app. You
| should not be changing these here. If you need to change these you
| may do so within the paths.php file and they will be bound here.
|
*/
$app->bindInstallPaths(require __DIR__.'/paths.php');
/*
|--------------------------------------------------------------------------
| Load The Application
|--------------------------------------------------------------------------
|
| Here we will load this Illuminate application. We will keep this in a
| separate location so we can isolate the creation of an application
| from the actual running of the application with a given request.
|
*/
$framework = $app['path.base'].
'/vendor/laravel/framework/src';
require $framework.'/Illuminate/Foundation/start.php';
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"laravel/framework": "4.1.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
"scripts": {
"post-install-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-create-project-cmd": [
"php artisan key:generate"
]
},
"config": {
"preferred-install": "dist"
},
"minimum-stability": "stable"
}
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "e5c2dde8ee007bee03ec884a0359d5c2",
"packages": [
{
"name": "classpreloader/classpreloader",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/mtdowling/ClassPreloader.git",
"reference": "1a50f7945b725ff2c60f234e51407d1d6e7c77c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mtdowling/ClassPreloader/zipball/1a50f7945b725ff2c60f234e51407d1d6e7c77c5",
"reference": "1a50f7945b725ff2c60f234e51407d1d6e7c77c5",
"shasum": ""
},
"require": {
"nikic/php-parser": "*",
"php": ">=5.3.3",
"symfony/console": ">2.0",
"symfony/filesystem": ">2.0",
"symfony/finder": ">2.0"
},
"bin": [
"classpreloader.php"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.0-dev"
}
},
"autoload": {
"psr-0": {
"ClassPreloader": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
"keywords": [
"autoload",
"class",
"preload"
],
"time": "2013-06-24 22:58:34"
},
{
"name": "d11wtq/boris",
"version": "v1.0.8",
"source": {
"type": "git",
"url": "https://github.com/d11wtq/boris.git",
"reference": "125dd4e5752639af7678a22ea597115646d89c6e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/d11wtq/boris/zipball/125dd4e5752639af7678a22ea597115646d89c6e",
"reference": "125dd4e5752639af7678a22ea597115646d89c6e",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"suggest": {
"ext-pcntl": "*",
"ext-posix": "*",
"ext-readline": "*"
},
"bin": [
"bin/boris"
],
"type": "library",
"autoload": {
"psr-0": {
"Boris": "lib"
}
},
"notification-url": "https://packagist.org/downloads/",
"time": "2014-01-17 12:21:18"
},
{
"name": "filp/whoops",
"version": "1.0.10",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "91e3fd4b0812017ffbeb24add55330664e1ea32a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/91e3fd4b0812017ffbeb24add55330664e1ea32a",
"reference": "91e3fd4b0812017ffbeb24add55330664e1ea32a",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"mockery/mockery": "dev-master",
"silex/silex": "1.0.*@dev"
},
"type": "library",
"autoload": {
"psr-0": {
"Whoops": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Filipe Dobreira",
"homepage": "https://github.com/filp",
"role": "Developer"
}
],
"description": "php error handling for cool kids",
"homepage": "https://github.com/filp/whoops",
"keywords": [
"error",
"exception",
"handling",
"library",
"silex-provider",
"whoops",
"zf2"
],
"time": "2013-12-04 14:19:30"
},
{
"name": "ircmaxell/password-compat",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/ircmaxell/password_compat.git",
"reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/1fc1521b5e9794ea77e4eca30717be9635f1d4f4",
"reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4",
"shasum": ""
},
"type": "library",
"autoload": {
"files": [
"lib/password.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anthony Ferrara",
"email": "[email protected]",
"homepage": "http://blog.ircmaxell.com"
}
],
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
"homepage": "https://github.com/ircmaxell/password_compat",
"keywords": [
"hashing",
"password"
],
"time": "2013-04-30 19:58:08"
},
{
"name": "jeremeamia/SuperClosure",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/jeremeamia/super_closure.git",
"reference": "d05400085f7d4ae6f20ba30d36550836c0d061e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/d05400085f7d4ae6f20ba30d36550836c0d061e8",
"reference": "d05400085f7d4ae6f20ba30d36550836c0d061e8",
"shasum": ""
},
"require": {
"nikic/php-parser": "~0.9",
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~3.7"
},
"type": "library",
"autoload": {
"psr-0": {
"Jeremeamia\\SuperClosure": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jeremy Lindblom"
}
],
"description": "Doing interesting things with closures like serialization.",
"homepage": "https://github.com/jeremeamia/super_closure",
"keywords": [
"closure",
"function",
"parser",
"serializable",
"serialize",
"tokenizer"
],
"time": "2013-10-09 04:20:00"
},
{
"name": "laravel/framework",
"version": "v4.1.23",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "054c1a29aaf537c6c6ca7e7804375c671eddcaaf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/054c1a29aaf537c6c6ca7e7804375c671eddcaaf",
"reference": "054c1a29aaf537c6c6ca7e7804375c671eddcaaf",
"shasum": ""
},
"require": {
"classpreloader/classpreloader": "1.0.*",
"d11wtq/boris": "1.0.*",
"filp/whoops": "1.0.10",
"ircmaxell/password-compat": "1.0.*",
"jeremeamia/superclosure": "1.0.*",
"monolog/monolog": "1.*",
"nesbot/carbon": "1.*",
"patchwork/utf8": "1.1.*",
"php": ">=5.3.0",
"phpseclib/phpseclib": "0.3.*",
"predis/predis": "0.8.*",
"stack/builder": "1.0.*",
"swiftmailer/swiftmailer": "5.0.*",
"symfony/browser-kit": "2.4.*",
"symfony/console": "2.4.*",
"symfony/css-selector": "2.4.*",
"symfony/debug": "2.4.*",
"symfony/dom-crawler": "2.4.*",
"symfony/finder": "2.4.*",
"symfony/http-foundation": "2.4.*",
"symfony/http-kernel": "2.4.*",
"symfony/process": "2.4.*",
"symfony/routing": "2.4.*",
"symfony/translation": "2.4.*"
},
"replace": {
"illuminate/auth": "self.version",
"illuminate/cache": "self.version",
"illuminate/config": "self.version",
"illuminate/console": "self.version",
"illuminate/container": "self.version",
"illuminate/cookie": "self.version",
"illuminate/database": "self.version",
"illuminate/encryption": "self.version",
"illuminate/events": "self.version",
"illuminate/exception": "self.version",
"illuminate/filesystem": "self.version",
"illuminate/foundation": "self.version",
"illuminate/hashing": "self.version",
"illuminate/html": "self.version",
"illuminate/http": "self.version",
"illuminate/log": "self.version",
"illuminate/mail": "self.version",
"illuminate/pagination": "self.version",
"illuminate/queue": "self.version",
"illuminate/redis": "self.version",
"illuminate/routing": "self.version",
"illuminate/session": "self.version",
"illuminate/support": "self.version",
"illuminate/translation": "self.version",
"illuminate/validation": "self.version",
"illuminate/view": "self.version",
"illuminate/workbench": "self.version"
},
"require-dev": {
"aws/aws-sdk-php": "2.5.*",
"iron-io/iron_mq": "1.5.*",
"mockery/mockery": "0.9.*",
"pda/pheanstalk": "2.1.*",
"phpunit/phpunit": "3.7.*"
},
"suggest": {
"doctrine/dbal": "Allow renaming columns and dropping SQLite columns."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"autoload": {
"classmap": [
[
"src/Illuminate/Queue/IlluminateQueueClosure.php"
]
],
"files": [
"src/Illuminate/Support/helpers.php"
],
"psr-0": {
"Illuminate": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]",
"homepage": "https://github.com/taylorotwell",
"role": "Developer"
}
],
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"time": "2014-02-28 22:07:47"
},
{
"name": "monolog/monolog",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "6225b22de9dcf36546be3a0b2fa8e3d986153f57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/6225b22de9dcf36546be3a0b2fa8e3d986153f57",
"reference": "6225b22de9dcf36546be3a0b2fa8e3d986153f57",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"require-dev": {
"aws/aws-sdk-php": "~2.4.8",
"doctrine/couchdb": "dev-master",
"mlehner/gelf-php": "1.0.*",
"phpunit/phpunit": "~3.7.0",
"raven/raven": "0.5.*",
"ruflin/elastica": "0.90.*"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server",
"raven/raven": "Allow sending log messages to a Sentry server",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7.x-dev"
}
},
"autoload": {
"psr-0": {
"Monolog": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "[email protected]",
"homepage": "http://seld.be",
"role": "Developer"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "http://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"time": "2013-11-14 19:48:31"
},
{
"name": "nesbot/carbon",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "21c4cb4301969c7d85aee8a62eefdfa881413af0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/21c4cb4301969c7d85aee8a62eefdfa881413af0",
"reference": "21c4cb4301969c7d85aee8a62eefdfa881413af0",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"type": "library",
"autoload": {
"psr-0": {
"Carbon": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Brian Nesbitt",
"email": "[email protected]",
"homepage": "http://nesbot.com"
}
],
"description": "A simple API extension for DateTime.",
"homepage": "https://github.com/briannesbitt/Carbon",
"keywords": [
"date",
"datetime",
"time"
],
"time": "2014-01-07 05:10:44"
},
{
"name": "nikic/php-parser",
"version": "v0.9.4",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "1e5e280ae88a27effa2ae4aa2bd088494ed8594f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1e5e280ae88a27effa2ae4aa2bd088494ed8594f",
"reference": "1e5e280ae88a27effa2ae4aa2bd088494ed8594f",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.9-dev"
}
},
"autoload": {
"psr-0": {
"PHPParser": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
"keywords": [
"parser",
"php"
],
"time": "2013-08-25 17:11:40"
},
{
"name": "patchwork/utf8",
"version": "v1.1.20",
"source": {
"type": "git",
"url": "https://github.com/nicolas-grekas/Patchwork-UTF8.git",
"reference": "aea0de833cba7cf2c25239be71f2787edaee36d5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nicolas-grekas/Patchwork-UTF8/zipball/aea0de833cba7cf2c25239be71f2787edaee36d5",
"reference": "aea0de833cba7cf2c25239be71f2787edaee36d5",
"shasum": ""
},
"require": {
"lib-pcre": ">=7.3",
"php": ">=5.3.0"
},
"suggest": {
"ext-iconv": "Use iconv for best performance",
"ext-intl": "Use Intl for best performance",
"ext-mbstring": "Use Mbstring for best performance"
},
"type": "library",
"autoload": {
"psr-0": {
"Patchwork": "class/",
"Normalizer": "class/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"(Apache-2.0 or GPL-2.0)"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "[email protected]",
"role": "Developer"
}
],
"description": "Extensive, portable and performant handling of UTF-8 and grapheme clusters for PHP",
"homepage": "https://github.com/nicolas-grekas/Patchwork-UTF8",
"keywords": [
"i18n",
"unicode",
"utf-8",
"utf8"
],
"time": "2014-03-01 20:01:07"
},
{
"name": "phpseclib/phpseclib",
"version": "0.3.6",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "0ea31d9b65d49a8661e93bec19f44e989bd34c69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/0ea31d9b65d49a8661e93bec19f44e989bd34c69",
"reference": "0ea31d9b65d49a8661e93bec19f44e989bd34c69",
"shasum": ""
},
"require": {
"php": ">=5.0.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "1.*"
},
"suggest": {
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
"pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"Crypt": "phpseclib/",
"File": "phpseclib/",
"Math": "phpseclib/",
"Net": "phpseclib/",
"System": "phpseclib/"
},
"files": [
"phpseclib/Crypt/Random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"phpseclib/"
],
"license": [
"MIT"
],
"authors": [
{
"name": "Jim Wigginton",
"email": "[email protected]",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "[email protected]",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "[email protected]",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "[email protected]",
"role": "Developer"
}
],
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"homepage": "http://phpseclib.sourceforge.net",
"keywords": [
"BigInteger",
"aes",
"asn.1",
"asn1",
"blowfish",
"crypto",
"cryptography",
"encryption",
"rsa",
"security",
"sftp",
"signature",
"signing",
"ssh",
"twofish",
"x.509",
"x509"
],
"time": "2014-02-28 16:05:05"
},
{
"name": "predis/predis",
"version": "v0.8.5",
"source": {
"type": "git",
"url": "https://github.com/nrk/predis.git",
"reference": "5f2eea628eb465d866ad2771927d83769c8f956c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nrk/predis/zipball/5f2eea628eb465d866ad2771927d83769c8f956c",
"reference": "5f2eea628eb465d866ad2771927d83769c8f956c",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"suggest": {
"ext-curl": "Allows access to Webdis when paired with phpiredis",
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
},
"type": "library",
"autoload": {
"psr-0": {
"Predis": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniele Alessandri",
"email": "[email protected]",
"homepage": "http://clorophilla.net"
}
],
"description": "Flexible and feature-complete PHP client library for Redis",
"homepage": "http://github.com/nrk/predis",
"keywords": [
"nosql",
"predis",
"redis"
],
"time": "2014-01-16 14:10:29"
},
{
"name": "psr/log",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2012-12-21 11:40:51"
},
{
"name": "stack/builder",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/stackphp/builder.git",
"reference": "49ab90450d7f959943f3659a4bcb5965530117c2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/stackphp/builder/zipball/49ab90450d7f959943f3659a4bcb5965530117c2",
"reference": "49ab90450d7f959943f3659a4bcb5965530117c2",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"symfony/http-foundation": "~2.1",
"symfony/http-kernel": "~2.1"
},
"require-dev": {
"silex/silex": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-0": {
"Stack": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "[email protected]",
"homepage": "http://wiedler.ch/igor/"
}
],
"description": "Builder for stack middlewares based on HttpKernelInterface.",
"keywords": [
"stack"
],
"time": "2013-10-25 14:04:45"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.0.3",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "32edc3b0de0fdc1b10f5c4912e8677b3f411a230"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/32edc3b0de0fdc1b10f5c4912e8677b3f411a230",
"reference": "32edc3b0de0fdc1b10f5c4912e8677b3f411a230",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.1-dev"
}
},
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Chris Corbyn"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "http://swiftmailer.org",
"keywords": [
"mail",
"mailer"
],
"time": "2013-12-03 13:33:24"
},
{
"name": "symfony/browser-kit",
"version": "v2.4.2",
"target-dir": "Symfony/Component/BrowserKit",
"source": {
"type": "git",
"url": "https://github.com/symfony/BrowserKit.git",
"reference": "3898f9f9aafc853124c90a9d1a4f98c1034e627e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/BrowserKit/zipball/3898f9f9aafc853124c90a9d1a4f98c1034e627e",
"reference": "3898f9f9aafc853124c90a9d1a4f98c1034e627e",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/dom-crawler": "~2.0"
},
"require-dev": {
"symfony/css-selector": "~2.0",
"symfony/process": "~2.0"
},
"suggest": {
"symfony/process": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\BrowserKit\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony BrowserKit Component",
"homepage": "http://symfony.com",
"time": "2014-01-24 14:36:08"
},
{
"name": "symfony/console",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/940f217cbc3c8a33e5403e7c595495c4884400fe",
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/event-dispatcher": "~2.1"
},
"suggest": {
"symfony/event-dispatcher": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Console\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/css-selector",
"version": "v2.4.2",
"target-dir": "Symfony/Component/CssSelector",
"source": {
"type": "git",
"url": "https://github.com/symfony/CssSelector.git",
"reference": "ed1d61b2e23a0fd5dba0b20651258c4633d3e3a7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/CssSelector/zipball/ed1d61b2e23a0fd5dba0b20651258c4633d3e3a7",
"reference": "ed1d61b2e23a0fd5dba0b20651258c4633d3e3a7",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\CssSelector\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Jean-François Simon",
"email": "[email protected]"
}
],
"description": "Symfony CssSelector Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/debug",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Debug",
"source": {
"type": "git",
"url": "https://github.com/symfony/Debug.git",
"reference": "23b5f4fcad883679d9a6e1cbc568247fe606d8ee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Debug/zipball/23b5f4fcad883679d9a6e1cbc568247fe606d8ee",
"reference": "23b5f4fcad883679d9a6e1cbc568247fe606d8ee",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/http-foundation": "~2.1",
"symfony/http-kernel": "~2.1"
},
"suggest": {
"symfony/http-foundation": "",
"symfony/http-kernel": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Debug\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Debug Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/dom-crawler",
"version": "v2.4.2",
"target-dir": "Symfony/Component/DomCrawler",
"source": {
"type": "git",
"url": "https://github.com/symfony/DomCrawler.git",
"reference": "5962504de9b36d955d88b08c1434d420627c8c01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/DomCrawler/zipball/5962504de9b36d955d88b08c1434d420627c8c01",
"reference": "5962504de9b36d955d88b08c1434d420627c8c01",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/css-selector": "~2.0"
},
"suggest": {
"symfony/css-selector": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\DomCrawler\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.4.2",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "4708b8cd41984a5ba29fe7dd40716f7f761ac501"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/4708b8cd41984a5ba29fe7dd40716f7f761ac501",
"reference": "4708b8cd41984a5ba29fe7dd40716f7f761ac501",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/dependency-injection": "~2.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\EventDispatcher\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/filesystem",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
"reference": "7e65abb06d3b38f4be89266fe3fb4a759544e713"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/7e65abb06d3b38f4be89266fe3fb4a759544e713",
"reference": "7e65abb06d3b38f4be89266fe3fb4a759544e713",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Filesystem\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
"time": "2014-01-07 13:28:54"
},
{
"name": "symfony/finder",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
"url": "https://github.com/symfony/Finder.git",
"reference": "b6735d1fc16da13c4c7dddfe78366a4a098cf011"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Finder/zipball/b6735d1fc16da13c4c7dddfe78366a4a098cf011",
"reference": "b6735d1fc16da13c4c7dddfe78366a4a098cf011",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Finder\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
"homepage": "http://symfony.com",
"time": "2014-01-07 13:28:54"
},
{
"name": "symfony/http-foundation",
"version": "v2.4.2",
"target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
"reference": "cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129",
"reference": "cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"classmap": [
"Symfony/Component/HttpFoundation/Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 15:39:28"
},
{
"name": "symfony/http-kernel",
"version": "v2.4.2",
"target-dir": "Symfony/Component/HttpKernel",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpKernel.git",
"reference": "445d6eee0eab2a6cfab41b5dc43f1b86ec34d110"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/445d6eee0eab2a6cfab41b5dc43f1b86ec34d110",
"reference": "445d6eee0eab2a6cfab41b5dc43f1b86ec34d110",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"psr/log": "~1.0",
"symfony/debug": "~2.3",
"symfony/event-dispatcher": "~2.1",
"symfony/http-foundation": "~2.4"
},
"require-dev": {
"symfony/browser-kit": "~2.2",
"symfony/class-loader": "~2.1",
"symfony/config": "~2.0",
"symfony/console": "~2.2",
"symfony/dependency-injection": "~2.0",
"symfony/finder": "~2.0",
"symfony/process": "~2.0",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.2",
"symfony/templating": "~2.2"
},
"suggest": {
"symfony/browser-kit": "",
"symfony/class-loader": "",
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
"symfony/finder": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpKernel\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony HttpKernel Component",
"homepage": "http://symfony.com",
"time": "2014-02-12 19:27:03"
},
{
"name": "symfony/process",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process.git",
"reference": "c175448bac997556f8ab972908a4e14c7291fb03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Process/zipball/c175448bac997556f8ab972908a4e14c7291fb03",
"reference": "c175448bac997556f8ab972908a4e14c7291fb03",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Process\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/routing",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing.git",
"reference": "b2fdea8b60400bb84e4931d71101ebbb3a08c1eb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Routing/zipball/b2fdea8b60400bb84e4931d71101ebbb3a08c1eb",
"reference": "b2fdea8b60400bb84e4931d71101ebbb3a08c1eb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"psr/log": "~1.0",
"symfony/config": "~2.2",
"symfony/expression-language": "~2.4",
"symfony/yaml": "~2.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation loader",
"symfony/config": "For using the all-in-one router or any loader",
"symfony/expression-language": "For using expression matching",
"symfony/yaml": "For using the YAML loader"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Routing\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Routing Component",
"homepage": "http://symfony.com",
"keywords": [
"router",
"routing",
"uri",
"url"
],
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/translation",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Translation",
"source": {
"type": "git",
"url": "https://github.com/symfony/Translation.git",
"reference": "b00fd07417e493e08488e87bcebeb9681fc7323b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Translation/zipball/b00fd07417e493e08488e87bcebeb9681fc7323b",
"reference": "b00fd07417e493e08488e87bcebeb9681fc7323b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/config": "~2.0",
"symfony/yaml": "~2.2"
},
"suggest": {
"symfony/config": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Translation\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Translation Component",
"homepage": "http://symfony.com",
"time": "2014-02-03 17:15:33"
}
],
"packages-dev": [
],
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": [
],
"platform": [
],
"platform-dev": [
]
}

Contribution Guidelines

Please submit all issues and pull requests to the laravel/framework repository!

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Application Test Suite">
<directory>./app/tests/</directory>
</testsuite>
</testsuites>
</phpunit>
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <[email protected]>
*/
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/../bootstrap/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let's turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight these users.
|
*/
$app = require_once __DIR__.'/../bootstrap/start.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can simply call the run method,
| which will execute the request and send the response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have whipped up for them.
|
*/
$app->run();

Laravel PHP Framework

Latest Stable Version Total Downloads Build Status License

Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, and caching.

Laravel aims to make the development process a pleasing one for the developer without sacrificing application functionality. Happy developers make the best code. To this end, we've attempted to combine the very best of what we have seen in other web frameworks, including frameworks implemented in other languages, such as Ruby on Rails, ASP.NET MVC, and Sinatra.

Laravel is accessible, yet powerful, providing powerful tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked.

Official Documentation

Documentation for the entire framework can be found on the Laravel website.

Contributing To Laravel

All issues and pull requests should be filed on the laravel/framework repository.

License

The Laravel framework is open-sourced software licensed under the MIT license

<?php
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri = urldecode($uri);
$paths = require __DIR__.'/bootstrap/paths.php';
$requested = $paths['public'].$uri;
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' and file_exists($requested))
{
return false;
}
require_once $paths['public'].'/index.php';
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitb5e048f0ae9c30f4c9c6013e9dcd483d::getLoader();
#!/usr/bin/env sh
SRC_DIR="`pwd`"
cd "`dirname "$0"`"
cd "../d11wtq/boris/bin"
BIN_TARGET="`pwd`/boris"
cd "$SRC_DIR"
"$BIN_TARGET" "$@"
@ECHO OFF
SET BIN_TARGET=%~dp0/../d11wtq/boris/bin/boris
php "%BIN_TARGET%" %*
#!/usr/bin/env sh
SRC_DIR="`pwd`"
cd "`dirname "$0"`"
cd "../classpreloader/classpreloader"
BIN_TARGET="`pwd`/classpreloader.php"
cd "$SRC_DIR"
"$BIN_TARGET" "$@"
@ECHO OFF
SET BIN_TARGET=%~dp0/../classpreloader/classpreloader/classpreloader.php
php "%BIN_TARGET%" %*
#! /usr/bin/env php
<?php
if (file_exists($autoloadPath = __DIR__ . '/../../autoload.php')) {
require_once $autoloadPath;
} else {
require_once __DIR__ . '/vendor/autoload.php';
}
$application = new ClassPreloader\Application();
$application->run();
{
"name": "classpreloader/classpreloader",
"description":"Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
"keywords":["autoload","class","preload"],
"license":"MIT",
"require":{
"php": ">=5.3.3",
"symfony/console": ">2.0",
"symfony/filesystem": ">2.0",
"symfony/finder": ">2.0",
"nikic/php-parser": "*"
},
"minimum-stability": "beta",
"autoload": {
"psr-0": {
"ClassPreloader": "src/"
}
},
"bin": ["classpreloader.php"],
"extra": {
"branch-alias": {
"dev-master": "1.0.0-dev"
}
}
}

Copyright (c) 2013 Michael Dowling [email protected] and contributors

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.

Class Preloader for PHP

This tool is used to generate a single PHP script containing all of the classes required for a specific use case. Using a single compiled PHP script instead of relying on autoloading can help to improve the performance of specific use cases. For example, if your application executes the same bootstrap code on every request, then you could generate a preloader (the compiled output of this tool) to reduce the cost of autoloading the required classes over and over.

What it actually does

This tool listens for each file that is autoloaded, creates a list of files, traverses the parsed PHP file using PHPParser and any visitors of a Config object, wraps the code of each file in a namespace block if necessary, and writes the contents of every autoloaded file (in order) to a single PHP file.

Notice

This tool should only be used for specific use cases. There is a tradeoff between preloading classes and autoloading classes. The point at which it is no longer beneficial to generate a preloader is application specific. You'll need to perform your own benchmarks to determine if this tool will speed up your application.

Installation

Add the ClassPreloader as a dependency to your composer.json file:

{
    "require": {
        "classpreloader/classpreloader": "1.0.0"
    },
    "config": {
        "bin-dir": "bin"
    }
}

Using the tool

You use the bin/classpreloader.php compile command with a few command line flags to generate a preloader.

--config: A CSV containing a list of files to combine into a classmap, or the full path to a PHP script that returns an array of classes or a \ClassPreloader\Config object.

--output: The path to the file to store the compiled PHP code. If the directory does not exist, the tool will attempt to create it.

--fix_dir: (defaults to 1) Set to 0 to not replace "DIR" constants with the actual directory of the original file.

--fix_file: (defaults to 1) Set to 0 to not replace "FILE" constants with the actual location of the original file.

Writing a config file

Creating a PHP based configuration file is fairly simple. Just include the vendor/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php file and call the ClassLoader::getIncludes() method, passing a function as the only argument. This function should accept a ClassLoader object and register the passed in object's autoloader using $loader->register(). It is important to register the ClassLoader autoloader after all other autoloaders are registered.

An array or \ClassPreloader\Config must be returned from the config file. You can attach custom node visitors if you need to perform any sort of translation on each matching file before writing it to the output.

<?php
// Here's an example of creating a preloader for using Amazon DynamoDB and the
// AWS SDK for PHP 2.

require __DIR__ . '/src/ClassPreloader/ClassLoader.php';

use ClassPreloader\ClassLoader;

$config = ClassLoader::getIncludes(function(ClassLoader $loader) {
    require __DIR__ . '/vendor/autoload.php';
    $loader->register();
    $aws = Aws\Common\Aws::factory(array(
        'key'    => '***',
        'secret' => '***',
        'region' => 'us-east-1'
    ));
    $client = $aws->get('dynamodb');
    $client->listTables()->getAll();
});

// Add a regex filter that requires all classes to match the regex
// $config->addInclusiveFilter('/Foo/');

// Add a regex filter that requires that a class does not match the filter
// $config->addExclusiveFilter('/Foo/');

return $config;

You would then run the classpreloader.php script and pass in the full path to the above PHP script.

php bin/classpreloader.php compile --config="/path/to/the_example.php" --output="/tmp/preloader.php"

The above command will create a file in /tmp/preloader.php that contains every file that was autoloaded while running the snippet of code in the anonymous function. You would generate this file and include it in your production script.

Automating the process with Composer

You can automate the process of creating preloaders using Composer's script functionality. For example, if you wanted to automatically create a preloader each time the AWS SDK for PHP is installed, you could define a script like the following in your composer.json file:

{
    "require": {
        "classpreloader/classpreloader": "1.0.0"
    },
    "scripts": {
        "post-autoload-dump": "php bin/classpreloader.php compile --config=/path/to/the_example.php --output=/path/to/preload.php"
    },
    "config": {
        "bin-dir": "bin"
    }
}

Using the above composer.json file, each time the project's autoloader is recreated using the install or update command, the classpreloader.php file will be executed. This script would generate a preload.php containing the classes required to run the previously demonstrated "the_example.php" configuration file.

<?php
namespace ClassPreloader;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Console\Application as BaseApplication;
/**
* ClassPreloader application CLI
*/
class Application extends BaseApplication
{
public function __construct()
{
parent::__construct('ClassPreloader');
// Create a finder to find each non-abstract command in the filesystem
$finder = new Finder();
$finder->files()
->in(__DIR__ . '/Command')
->notName('Abstract*')
->name('*.php');
// Add each command to the CLI
foreach ($finder as $file) {
$filename = str_replace('\\', '/', $file->getRealpath());
$pos = strrpos($filename, '/ClassPreloader/') + strlen('/ClassPreloader/');
$class = __NAMESPACE__ . '\\'
. substr(str_replace('/', '\\', substr($filename, $pos)), 0, -4);
$this->add(new $class());
}
}
}
<?php
namespace ClassPreloader;
/**
* Maintains a list of classes using a sort of doubly-linked list
*/
class ClassList
{
/**
* @var ClassNode The head node of the list
*/
protected $head;
/**
* @var ClassNode The current node of the list
*/
protected $current;
public function __construct()
{
$this->clear();
}
/**
* Clear the contents of the list and reset the head node and current node
*/
public function clear()
{
$this->head = new ClassNode(null);
$this->current = $this->head;
}
/**
* Traverse to the next node in the list
*/
public function next()
{
if (isset($this->current->next)) {
$this->current = $this->current->next;
} else {
$this->current->next = new ClassNode(null, $this->current);
$this->current = $this->current->next;
}
}
/**
* Insert a value at the current position in the list. Any currently set
* value at this position will be pushed back in the list after the new
* value
*
* @param mixed $value Value to insert
*/
public function push($value)
{
if (!$this->current->value) {
$this->current->value = $value;
} else {
$temp = $this->current;
$this->current = new ClassNode($value, $temp->prev);
$this->current->next = $temp;
$temp->prev = $this->current;
if ($temp === $this->head) {
$this->head = $this->current;
} else {
$this->current->prev->next = $this->current;
}
}
}
/**
* Traverse the ClassList and return a list of classes
*
* @return array
*/
public function getClasses()
{
$classes = array();
$current = $this->head;
while ($current && $current->value) {
$classes[] = $current->value;
$current = $current->next;
}
return array_filter($classes);
}
}
<?php
namespace ClassPreloader;
require_once __DIR__ . '/ClassNode.php';
require_once __DIR__ . '/ClassList.php';
/**
* Creates an autoloader that intercepts and keeps track of each include in
* order that files must be included. This autoloader proxies to all other
* underlying autoloaders.
*/
class ClassLoader
{
/**
* @var ClassList List of loaded classes
*/
public $classList;
/**
* Create the dependency list
*/
public function __construct()
{
$this->classList = new ClassList();
}
/**
* Wrap a block of code in the autoloader and get a list of loaded classes
*
* @param \Callable $func Callable function
*
* @return Config
*/
public static function getIncludes($func)
{
$loader = new self();
call_user_func($func, $loader);
$loader->unregister();
$config = new Config();
foreach ($loader->getFilenames() as $file) {
$config->addFile($file);
}
return $config;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'), true, true);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True, if loaded
*/
public function loadClass($class)
{
foreach (spl_autoload_functions() as $func) {
if (is_array($func) && $func[0] === $this) {
continue;
}
$this->classList->push($class);
if (call_user_func($func, $class)) {
break;
}
}
$this->classList->next();
return true;
}
/**
* Get an array of loaded file names in order of loading
*
* @return array
*/
public function getFilenames()
{
$files = array();
foreach ($this->classList->getClasses() as $class) {
// Push interfaces before classes if not already loaded
$r = new \ReflectionClass($class);
foreach ($r->getInterfaces() as $inf) {
$name = $inf->getFileName();
if ($name && !in_array($name, $files)) {
$files[] = $name;
}
}
$files[] = $r->getFileName();
}
return $files;
}
}
<?php
namespace ClassPreloader;
/**
* A simple ClassNode that contains a value, previous, and next pointers
*/
class ClassNode
{
/**
* @var ClassNode|null Next node pointer
*/
public $next;
/**
* @var ClassNode|null Previous node pointer
*/
public $prev;
/**
* @var mixed Value of the ClassNode
*/
public $value;
/**
* Create a new ClassNode
*
* @param mixed $value Value of the class node
* @param ClassNode $prev Previous node pointer
*/
public function __construct($value = null, $prev = null)
{
$this->value = $value;
$this->prev = $prev;
}
}
<?php
namespace ClassPreloader\Command;
use ClassPreloader\Config;
use ClassPreloader\Parser\DirVisitor;
use ClassPreloader\Parser\NodeTraverser;
use ClassPreloader\Parser\FileVisitor;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
class PreCompileCommand extends Command
{
protected $input;
protected $output;
protected $printer;
protected $traverser;
protected $parser;
public function __construct()
{
parent::__construct();
$this->printer = new \PHPParser_PrettyPrinter_Zend();
$this->parser = new \PHPParser_Parser(new \PHPParser_Lexer());
}
/**
* {@inheritdoc}
*/
protected function configure()
{
parent::configure();
$this->setName('compile')
->setDescription('Compiles classes into a single file')
->addOption('config', null, InputOption::VALUE_REQUIRED, 'CSV of filenames to load, or the path to a PHP script that returns an array of file names')
->addOption('output', null, InputOption::VALUE_REQUIRED)
->addOption('fix_dir', null, InputOption::VALUE_REQUIRED, 'Convert __DIR__ constants to the original directory of a file', 1)
->addOption('fix_file', null, InputOption::VALUE_REQUIRED, 'Convert __FILE__ constants to the original path of a file', 1)
->addOption('strip_comments', null, InputOption::VALUE_REQUIRED, 'Set to 1 to strip comments from each source file', 0)
->setHelp(<<<EOF
The <info>%command.name%</info> command iterates over each script, normalizes
the file to be wrapped in namespaces, and combines each file into a single PHP
file.
EOF
);
}
/**
* Get the node traverser used by the command
*
* @return NodeTraverser
*/
protected function getTraverser()
{
if (!$this->traverser) {
$this->traverser = new NodeTraverser();
if ($this->input->getOption('fix_dir')) {
$this->traverser->addVisitor(new DirVisitor($file));
}
if ($this->input->getOption('fix_file')) {
$this->traverser->addVisitor(new FileVisitor($file));
}
}
return $this->traverser;
}
/**
* Get a pretty printed string of code from a file while applying visitors
*
* @param string $file Name of the file to get code from
* @param NodeTraverser $traverser Node traverser
*
* @return string
*/
protected function getCode($file)
{
if (!is_readable($file)) {
throw new \RuntimeException("Cannot open {$file} for reading");
}
if ($this->input->getOption('strip_comments')) {
$content = php_strip_whitespace($file);
} else {
$content = file_get_contents($file);
}
$stmts = $this->getTraverser()
->traverseFile($this->parser->parse($content), $file);
$pretty = $this->printer->prettyPrint($stmts);
// Remove the open PHP tag
if (substr($pretty, 6) == "<?php\n") {
$pretty = substr($pretty, 7);
}
// Add a wrapping namespace if needed
if (false === strpos($pretty, 'namespace ')) {
$pretty = "namespace {\n" . $pretty . "\n}\n";
}
return $pretty;
}
/**
* Validate the command options
*/
protected function validateCommand()
{
if (!$this->input->getOption('output')) {
throw new \InvalidArgumentException('An output option is required');
}
if (!$this->input->getOption('config')) {
throw new \InvalidArgumentException('A config option is required');
}
}
/**
* Get a list of files in order
*
* @param mixed $config Configuration option
*
* @return array
*/
protected function getFileList($config)
{
$this->output->writeln('> Loading configuration file');
$filesystem = new Filesystem();
if (strpos($config, ',')) {
return array_filter(explode(',', $config));
}
// Ensure absolute paths are resolved
if (!$filesystem->isAbsolutePath($config)) {
$config = getcwd() . '/' . $config;
}
// Ensure that the config file exists
if (!file_exists($config)) {
throw new \InvalidArgumentException(sprintf('Configuration file "%s" does not exist.', $config));
}
$result = require $config;
if ($result instanceof Config) {
foreach ($result->getVisitors() as $visitor) {
$this->getTraverser()->addVisitor($visitor);
}
return $result;
} elseif (is_array($result)) {
return $result;
}
throw new \InvalidArgumentException(
'Config must return an array of filenames or a Config object'
);
}
/**
* Prepare the output file and directory
*
* @param string $outputFile The full path to the output file
*/
protected function prepareOutput($outputFile)
{
$dir = dirname($outputFile);
if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
throw new \RuntimeException('Unable to create directory ' . $dir);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
$this->validateCommand();
$outputFile = $this->input->getOption('output');
$config = $this->input->getOption('config');
$files = $this->getFileList($config);
$output->writeLn('- Found ' . count($files) . ' files');
// Make sure that the output dir can be used or create it
$this->prepareOutput($outputFile);
if (!$handle = fopen($input->getOption('output'), 'w')) {
throw new \RuntimeException(
"Unable to open {$outputFile} for writing"
);
}
// Write the first line of the output
fwrite($handle, "<?php\n");
$output->writeln('> Compiling classes');
foreach ($files as $file) {
$this->output->writeln('- Writing ' . $file);
fwrite($handle, $this->getCode($file) . "\n");
}
fclose($handle);
$output->writeln("> Compiled loader written to {$outputFile}");
$output->writeln('- ' . (round(filesize($outputFile) / 1024)) . ' kb');
}
}
<?php
namespace ClassPreloader;
use Parser\AbstractNodeVisitor;
/**
* Class loader configuration object
*/
class Config implements \IteratorAggregate
{
/**
* @var array Array of AbstractNodeVisitor objects that visit nodes
*/
protected $visitors = array();
/**
* @var array Array of file names
*/
protected $filenames = array();
/**
* @var array Array of exclusive filters
*/
protected $exclusiveFilters = array();
/**
* @var array Array of inclusive filters
*/
protected $inclusiveFilters = array();
/**
* Set the filenames owned by the config
*
* @param array $filenames File name
*
* @return self
*/
public function addFile($filename)
{
$this->filenames[] = $filename;
return $this;
}
/**
* Get an array of file names that satisfy any added filters
*
* @return array
*/
public function getFilenames()
{
$filenames = array();
foreach ($this->filenames as $f) {
foreach ($this->inclusiveFilters as $filter) {
if (!preg_match($filter, $f)) {
continue 2;
}
}
foreach ($this->exclusiveFilters as $filter) {
if (preg_match($filter, $f)) {
continue 2;
}
}
$filenames[] = $f;
}
return $filenames;
}
/**
* Get an iterator for the filenames
*
* @return \ArrayIterator
*/
public function getIterator()
{
return new \ArrayIterator($this->getFilenames());
}
/**
* Add a filter used to filter out classes matching a specific pattern
*
* @param string $pattern Regular expression pattern
*
* @return self
*/
public function addExclusiveFilter($pattern)
{
$this->exclusiveFilters[] = $pattern;
return $this;
}
/**
* Add a filter used to grab only file names matching the pattern
*
* @param string $pattern Regular expression pattern
*
* @return self
*/
public function addInclusiveFilter($pattern)
{
$this->inclusiveFilters[] = $pattern;
return $this;
}
/**
* Add a visitor that will visit each node when traversing the node list
* of each file.
*
* @param AbstractNodeVisitor $visitor Node visitor
*
* @return self
*/
public function addVisitor(AbstractNodeVisitor $visitor)
{
$this->visitors[] = $visitor;
return $this;
}
/**
* Get an array of node visitors
*
* @return array
*/
public function getVisitors()
{
return $this->visitors;
}
}
<?php
namespace ClassPreloader\Parser;
/**
* Abstract node visitor used to track the filename
*/
abstract class AbstractNodeVisitor extends \PHPParser_NodeVisitorAbstract
{
/**
* @var string Current file being parsed
*/
protected $filename = '';
/**
* Set the full path to the current file being parsed
*
* @param string $filename Filename being parser
*
* @return self
*/
public function setFilename($filename)
{
$this->filename = $filename;
return $this;
}
/**
* Get the full path to the current file being parsed
*
* @return string
*/
public function getFilename()
{
return $this->filename;
}
/**
* Get the directory of the current file being parsed
*
* @return string
*/
public function getDir()
{
return dirname($this->getFilename());
}
}
<?php
namespace ClassPreloader\Parser;
/**
* Finds all references to __DIR__ and replaces them with the actual directory
*/
class DirVisitor extends AbstractNodeVisitor
{
public function enterNode(\PHPParser_Node $node)
{
if ($node instanceof \PHPParser_Node_Scalar_DirConst) {
return new \PHPParser_Node_Scalar_String($this->getDir());
}
}
}
<?php
namespace ClassPreloader\Parser;
/**
* Finds all references to __FILE__ and replaces them with the actual file path
*/
class FileVisitor extends AbstractNodeVisitor
{
public function enterNode(\PHPParser_Node $node)
{
if ($node instanceof \PHPParser_Node_Scalar_FileConst) {
return new \PHPParser_Node_Scalar_String($this->getFilename());
}
}
}
<?php
namespace ClassPreloader\Parser;
/**
* Allows a filename to be set when visiting
*/
class NodeTraverser extends \PHPParser_NodeTraverser
{
public function traverseFile(array $nodes, $filename)
{
// Set the correct state on each visitor
foreach ($this->visitors as $visitor) {
if ($visitor instanceof AbstractNodeVisitor) {
$visitor->setFilename($filename);
}
}
return $this->traverse($nodes);
}
}
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'BaseController' => $baseDir . '/app/controllers/BaseController.php',
'Boris\\Boris' => $vendorDir . '/d11wtq/boris/lib/Boris/Boris.php',
'Boris\\CLIOptionsHandler' => $vendorDir . '/d11wtq/boris/lib/Boris/CLIOptionsHandler.php',
'Boris\\ColoredInspector' => $vendorDir . '/d11wtq/boris/lib/Boris/ColoredInspector.php',
'Boris\\Config' => $vendorDir . '/d11wtq/boris/lib/Boris/Config.php',
'Boris\\DumpInspector' => $vendorDir . '/d11wtq/boris/lib/Boris/DumpInspector.php',
'Boris\\EvalWorker' => $vendorDir . '/d11wtq/boris/lib/Boris/EvalWorker.php',
'Boris\\ExportInspector' => $vendorDir . '/d11wtq/boris/lib/Boris/ExportInspector.php',
'Boris\\Inspector' => $vendorDir . '/d11wtq/boris/lib/Boris/Inspector.php',
'Boris\\ReadlineClient' => $vendorDir . '/d11wtq/boris/lib/Boris/ReadlineClient.php',
'Boris\\ShallowParser' => $vendorDir . '/d11wtq/boris/lib/Boris/ShallowParser.php',
'Carbon\\Carbon' => $vendorDir . '/nesbot/carbon/src/Carbon/Carbon.php',
'ClassPreloader\\Application' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Application.php',
'ClassPreloader\\ClassList' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/ClassList.php',
'ClassPreloader\\ClassLoader' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/ClassLoader.php',
'ClassPreloader\\ClassNode' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/ClassNode.php',
'ClassPreloader\\Command\\PreCompileCommand' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Command/PreCompileCommand.php',
'ClassPreloader\\Config' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Config.php',
'ClassPreloader\\Parser\\AbstractNodeVisitor' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Parser/AbstractNodeVisitor.php',
'ClassPreloader\\Parser\\DirVisitor' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Parser/DirVisitor.php',
'ClassPreloader\\Parser\\FileVisitor' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Parser/FileVisitor.php',
'ClassPreloader\\Parser\\NodeTraverser' => $vendorDir . '/classpreloader/classpreloader/src/ClassPreloader/Parser/NodeTraverser.php',
'Crypt_AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php',
'Crypt_Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php',
'Crypt_Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php',
'Crypt_DES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php',
'Crypt_Hash' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php',
'Crypt_RC2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php',
'Crypt_RC4' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php',
'Crypt_RSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php',
'Crypt_Rijndael' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php',
'Crypt_TripleDES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php',
'Crypt_Twofish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php',
'DatabaseSeeder' => $baseDir . '/app/database/seeds/DatabaseSeeder.php',
'File_ANSI' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ANSI.php',
'File_ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php',
'File_ASN1_Element' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php',
'File_X509' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/X509.php',
'HomeController' => $baseDir . '/app/controllers/HomeController.php',
'IlluminateQueueClosure' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/IlluminateQueueClosure.php',
'Illuminate\\Auth\\AuthManager' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/AuthManager.php',
'Illuminate\\Auth\\AuthServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php',
'Illuminate\\Auth\\Console\\ClearRemindersCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Console/ClearRemindersCommand.php',
'Illuminate\\Auth\\Console\\RemindersControllerCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Console/RemindersControllerCommand.php',
'Illuminate\\Auth\\Console\\RemindersTableCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Console/RemindersTableCommand.php',
'Illuminate\\Auth\\DatabaseUserProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/DatabaseUserProvider.php',
'Illuminate\\Auth\\EloquentUserProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php',
'Illuminate\\Auth\\GenericUser' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/GenericUser.php',
'Illuminate\\Auth\\Guard' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Guard.php',
'Illuminate\\Auth\\Reminders\\DatabaseReminderRepository' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Reminders/DatabaseReminderRepository.php',
'Illuminate\\Auth\\Reminders\\PasswordBroker' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Reminders/PasswordBroker.php',
'Illuminate\\Auth\\Reminders\\RemindableInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Reminders/RemindableInterface.php',
'Illuminate\\Auth\\Reminders\\ReminderRepositoryInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Reminders/ReminderRepositoryInterface.php',
'Illuminate\\Auth\\Reminders\\ReminderServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Reminders/ReminderServiceProvider.php',
'Illuminate\\Auth\\UserInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/UserInterface.php',
'Illuminate\\Auth\\UserProviderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/UserProviderInterface.php',
'Illuminate\\Cache\\ApcStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/ApcStore.php',
'Illuminate\\Cache\\ApcWrapper' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/ApcWrapper.php',
'Illuminate\\Cache\\ArrayStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/ArrayStore.php',
'Illuminate\\Cache\\CacheManager' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/CacheManager.php',
'Illuminate\\Cache\\CacheServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/CacheServiceProvider.php',
'Illuminate\\Cache\\Console\\ClearCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/Console/ClearCommand.php',
'Illuminate\\Cache\\DatabaseStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/DatabaseStore.php',
'Illuminate\\Cache\\FileStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/FileStore.php',
'Illuminate\\Cache\\MemcachedConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/MemcachedConnector.php',
'Illuminate\\Cache\\MemcachedStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/MemcachedStore.php',
'Illuminate\\Cache\\RedisStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/RedisStore.php',
'Illuminate\\Cache\\RedisTaggedCache' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/RedisTaggedCache.php',
'Illuminate\\Cache\\Repository' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/Repository.php',
'Illuminate\\Cache\\StoreInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/StoreInterface.php',
'Illuminate\\Cache\\TagSet' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/TagSet.php',
'Illuminate\\Cache\\TaggableStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/TaggableStore.php',
'Illuminate\\Cache\\TaggedCache' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/TaggedCache.php',
'Illuminate\\Cache\\WinCacheStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/WinCacheStore.php',
'Illuminate\\Cache\\XCacheStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/XCacheStore.php',
'Illuminate\\Config\\EnvironmentVariables' => $vendorDir . '/laravel/framework/src/Illuminate/Config/EnvironmentVariables.php',
'Illuminate\\Config\\EnvironmentVariablesLoaderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Config/EnvironmentVariablesLoaderInterface.php',
'Illuminate\\Config\\FileEnvironmentVariablesLoader' => $vendorDir . '/laravel/framework/src/Illuminate/Config/FileEnvironmentVariablesLoader.php',
'Illuminate\\Config\\FileLoader' => $vendorDir . '/laravel/framework/src/Illuminate/Config/FileLoader.php',
'Illuminate\\Config\\LoaderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Config/LoaderInterface.php',
'Illuminate\\Config\\Repository' => $vendorDir . '/laravel/framework/src/Illuminate/Config/Repository.php',
'Illuminate\\Console\\Application' => $vendorDir . '/laravel/framework/src/Illuminate/Console/Application.php',
'Illuminate\\Console\\Command' => $vendorDir . '/laravel/framework/src/Illuminate/Console/Command.php',
'Illuminate\\Container\\BindingResolutionException' => $vendorDir . '/laravel/framework/src/Illuminate/Container/Container.php',
'Illuminate\\Container\\Container' => $vendorDir . '/laravel/framework/src/Illuminate/Container/Container.php',
'Illuminate\\Cookie\\CookieJar' => $vendorDir . '/laravel/framework/src/Illuminate/Cookie/CookieJar.php',
'Illuminate\\Cookie\\CookieServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Cookie/CookieServiceProvider.php',
'Illuminate\\Cookie\\Guard' => $vendorDir . '/laravel/framework/src/Illuminate/Cookie/Guard.php',
'Illuminate\\Cookie\\Queue' => $vendorDir . '/laravel/framework/src/Illuminate/Cookie/Queue.php',
'Illuminate\\Database\\Capsule\\Manager' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Capsule/Manager.php',
'Illuminate\\Database\\Connection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connection.php',
'Illuminate\\Database\\ConnectionInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Database/ConnectionInterface.php',
'Illuminate\\Database\\ConnectionResolver' => $vendorDir . '/laravel/framework/src/Illuminate/Database/ConnectionResolver.php',
'Illuminate\\Database\\ConnectionResolverInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Database/ConnectionResolverInterface.php',
'Illuminate\\Database\\Connectors\\ConnectionFactory' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php',
'Illuminate\\Database\\Connectors\\Connector' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/Connector.php',
'Illuminate\\Database\\Connectors\\ConnectorInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/ConnectorInterface.php',
'Illuminate\\Database\\Connectors\\MySqlConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/MySqlConnector.php',
'Illuminate\\Database\\Connectors\\PostgresConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/PostgresConnector.php',
'Illuminate\\Database\\Connectors\\SQLiteConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/SQLiteConnector.php',
'Illuminate\\Database\\Connectors\\SqlServerConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Connectors/SqlServerConnector.php',
'Illuminate\\Database\\Console\\Migrations\\BaseCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/BaseCommand.php',
'Illuminate\\Database\\Console\\Migrations\\InstallCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/InstallCommand.php',
'Illuminate\\Database\\Console\\Migrations\\MigrateCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php',
'Illuminate\\Database\\Console\\Migrations\\MigrateMakeCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php',
'Illuminate\\Database\\Console\\Migrations\\RefreshCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/RefreshCommand.php',
'Illuminate\\Database\\Console\\Migrations\\ResetCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/ResetCommand.php',
'Illuminate\\Database\\Console\\Migrations\\RollbackCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/Migrations/RollbackCommand.php',
'Illuminate\\Database\\Console\\SeedCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Console/SeedCommand.php',
'Illuminate\\Database\\DatabaseManager' => $vendorDir . '/laravel/framework/src/Illuminate/Database/DatabaseManager.php',
'Illuminate\\Database\\DatabaseServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Database/DatabaseServiceProvider.php',
'Illuminate\\Database\\Eloquent\\Builder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php',
'Illuminate\\Database\\Eloquent\\Collection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Collection.php',
'Illuminate\\Database\\Eloquent\\MassAssignmentException' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/MassAssignmentException.php',
'Illuminate\\Database\\Eloquent\\Model' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Model.php',
'Illuminate\\Database\\Eloquent\\ModelNotFoundException' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/ModelNotFoundException.php',
'Illuminate\\Database\\Eloquent\\Relations\\BelongsTo' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php',
'Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php',
'Illuminate\\Database\\Eloquent\\Relations\\HasMany' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasMany.php',
'Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php',
'Illuminate\\Database\\Eloquent\\Relations\\HasOne' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOne.php',
'Illuminate\\Database\\Eloquent\\Relations\\HasOneOrMany' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php',
'Illuminate\\Database\\Eloquent\\Relations\\MorphMany' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphMany.php',
'Illuminate\\Database\\Eloquent\\Relations\\MorphOne' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphOne.php',
'Illuminate\\Database\\Eloquent\\Relations\\MorphOneOrMany' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php',
'Illuminate\\Database\\Eloquent\\Relations\\MorphPivot' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphPivot.php',
'Illuminate\\Database\\Eloquent\\Relations\\MorphToMany' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php',
'Illuminate\\Database\\Eloquent\\Relations\\Pivot' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Pivot.php',
'Illuminate\\Database\\Eloquent\\Relations\\Relation' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php',
'Illuminate\\Database\\Grammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Grammar.php',
'Illuminate\\Database\\MigrationServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Database/MigrationServiceProvider.php',
'Illuminate\\Database\\Migrations\\DatabaseMigrationRepository' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php',
'Illuminate\\Database\\Migrations\\Migration' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Migrations/Migration.php',
'Illuminate\\Database\\Migrations\\MigrationCreator' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Migrations/MigrationCreator.php',
'Illuminate\\Database\\Migrations\\MigrationRepositoryInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php',
'Illuminate\\Database\\Migrations\\Migrator' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php',
'Illuminate\\Database\\MySqlConnection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/MySqlConnection.php',
'Illuminate\\Database\\PostgresConnection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/PostgresConnection.php',
'Illuminate\\Database\\QueryException' => $vendorDir . '/laravel/framework/src/Illuminate/Database/QueryException.php',
'Illuminate\\Database\\Query\\Builder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Builder.php',
'Illuminate\\Database\\Query\\Expression' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Expression.php',
'Illuminate\\Database\\Query\\Grammars\\Grammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php',
'Illuminate\\Database\\Query\\Grammars\\MySqlGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php',
'Illuminate\\Database\\Query\\Grammars\\PostgresGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php',
'Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php',
'Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php',
'Illuminate\\Database\\Query\\JoinClause' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/JoinClause.php',
'Illuminate\\Database\\Query\\Processors\\MySqlProcessor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/MySqlProcessor.php',
'Illuminate\\Database\\Query\\Processors\\PostgresProcessor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/PostgresProcessor.php',
'Illuminate\\Database\\Query\\Processors\\Processor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/Processor.php',
'Illuminate\\Database\\Query\\Processors\\SQLiteProcessor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/SQLiteProcessor.php',
'Illuminate\\Database\\Query\\Processors\\SqlServerProcessor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/SqlServerProcessor.php',
'Illuminate\\Database\\SQLiteConnection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/SQLiteConnection.php',
'Illuminate\\Database\\Schema\\Blueprint' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php',
'Illuminate\\Database\\Schema\\Builder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Builder.php',
'Illuminate\\Database\\Schema\\Grammars\\Grammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Grammars/Grammar.php',
'Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php',
'Illuminate\\Database\\Schema\\Grammars\\PostgresGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php',
'Illuminate\\Database\\Schema\\Grammars\\SQLiteGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php',
'Illuminate\\Database\\Schema\\Grammars\\SqlServerGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php',
'Illuminate\\Database\\Schema\\MySqlBuilder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Schema/MySqlBuilder.php',
'Illuminate\\Database\\SeedServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Database/SeedServiceProvider.php',
'Illuminate\\Database\\Seeder' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Seeder.php',
'Illuminate\\Database\\SqlServerConnection' => $vendorDir . '/laravel/framework/src/Illuminate/Database/SqlServerConnection.php',
'Illuminate\\Encryption\\DecryptException' => $vendorDir . '/laravel/framework/src/Illuminate/Encryption/Encrypter.php',
'Illuminate\\Encryption\\Encrypter' => $vendorDir . '/laravel/framework/src/Illuminate/Encryption/Encrypter.php',
'Illuminate\\Encryption\\EncryptionServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Encryption/EncryptionServiceProvider.php',
'Illuminate\\Events\\Dispatcher' => $vendorDir . '/laravel/framework/src/Illuminate/Events/Dispatcher.php',
'Illuminate\\Events\\EventServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Events/EventServiceProvider.php',
'Illuminate\\Events\\Subscriber' => $vendorDir . '/laravel/framework/src/Illuminate/Events/Subscriber.php',
'Illuminate\\Exception\\ExceptionDisplayerInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Exception/ExceptionDisplayerInterface.php',
'Illuminate\\Exception\\ExceptionServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Exception/ExceptionServiceProvider.php',
'Illuminate\\Exception\\Handler' => $vendorDir . '/laravel/framework/src/Illuminate/Exception/Handler.php',
'Illuminate\\Exception\\PlainDisplayer' => $vendorDir . '/laravel/framework/src/Illuminate/Exception/PlainDisplayer.php',
'Illuminate\\Exception\\SymfonyDisplayer' => $vendorDir . '/laravel/framework/src/Illuminate/Exception/SymfonyDisplayer.php',
'Illuminate\\Exception\\WhoopsDisplayer' => $vendorDir . '/laravel/framework/src/Illuminate/Exception/WhoopsDisplayer.php',
'Illuminate\\Filesystem\\FileNotFoundException' => $vendorDir . '/laravel/framework/src/Illuminate/Filesystem/Filesystem.php',
'Illuminate\\Filesystem\\Filesystem' => $vendorDir . '/laravel/framework/src/Illuminate/Filesystem/Filesystem.php',
'Illuminate\\Filesystem\\FilesystemServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Filesystem/FilesystemServiceProvider.php',
'Illuminate\\Foundation\\AliasLoader' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/AliasLoader.php',
'Illuminate\\Foundation\\Application' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Application.php',
'Illuminate\\Foundation\\Artisan' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Artisan.php',
'Illuminate\\Foundation\\AssetPublisher' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/AssetPublisher.php',
'Illuminate\\Foundation\\Composer' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Composer.php',
'Illuminate\\Foundation\\ConfigPublisher' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/ConfigPublisher.php',
'Illuminate\\Foundation\\Console\\AssetPublishCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/AssetPublishCommand.php',
'Illuminate\\Foundation\\Console\\AutoloadCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/AutoloadCommand.php',
'Illuminate\\Foundation\\Console\\ChangesCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/ChangesCommand.php',
'Illuminate\\Foundation\\Console\\ClearCompiledCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/ClearCompiledCommand.php',
'Illuminate\\Foundation\\Console\\CommandMakeCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/CommandMakeCommand.php',
'Illuminate\\Foundation\\Console\\ConfigPublishCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/ConfigPublishCommand.php',
'Illuminate\\Foundation\\Console\\DownCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/DownCommand.php',
'Illuminate\\Foundation\\Console\\EnvironmentCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/EnvironmentCommand.php',
'Illuminate\\Foundation\\Console\\KeyGenerateCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/KeyGenerateCommand.php',
'Illuminate\\Foundation\\Console\\MigratePublishCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/MigratePublishCommand.php',
'Illuminate\\Foundation\\Console\\OptimizeCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/OptimizeCommand.php',
'Illuminate\\Foundation\\Console\\RoutesCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/RoutesCommand.php',
'Illuminate\\Foundation\\Console\\ServeCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/ServeCommand.php',
'Illuminate\\Foundation\\Console\\TailCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/TailCommand.php',
'Illuminate\\Foundation\\Console\\TinkerCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/TinkerCommand.php',
'Illuminate\\Foundation\\Console\\UpCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/UpCommand.php',
'Illuminate\\Foundation\\Console\\ViewPublishCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Console/ViewPublishCommand.php',
'Illuminate\\Foundation\\EnvironmentDetector' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/EnvironmentDetector.php',
'Illuminate\\Foundation\\MigrationPublisher' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/MigrationPublisher.php',
'Illuminate\\Foundation\\ProviderRepository' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php',
'Illuminate\\Foundation\\Providers\\ArtisanServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php',
'Illuminate\\Foundation\\Providers\\CommandCreatorServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/CommandCreatorServiceProvider.php',
'Illuminate\\Foundation\\Providers\\ComposerServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/ComposerServiceProvider.php',
'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/ConsoleSupportServiceProvider.php',
'Illuminate\\Foundation\\Providers\\KeyGeneratorServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/KeyGeneratorServiceProvider.php',
'Illuminate\\Foundation\\Providers\\MaintenanceServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/MaintenanceServiceProvider.php',
'Illuminate\\Foundation\\Providers\\OptimizeServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/OptimizeServiceProvider.php',
'Illuminate\\Foundation\\Providers\\PublisherServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/PublisherServiceProvider.php',
'Illuminate\\Foundation\\Providers\\RouteListServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/RouteListServiceProvider.php',
'Illuminate\\Foundation\\Providers\\ServerServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/ServerServiceProvider.php',
'Illuminate\\Foundation\\Providers\\TinkerServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Providers/TinkerServiceProvider.php',
'Illuminate\\Foundation\\Testing\\Client' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Testing/Client.php',
'Illuminate\\Foundation\\Testing\\TestCase' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php',
'Illuminate\\Foundation\\ViewPublisher' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/ViewPublisher.php',
'Illuminate\\Hashing\\BcryptHasher' => $vendorDir . '/laravel/framework/src/Illuminate/Hashing/BcryptHasher.php',
'Illuminate\\Hashing\\HashServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Hashing/HashServiceProvider.php',
'Illuminate\\Hashing\\HasherInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Hashing/HasherInterface.php',
'Illuminate\\Html\\FormBuilder' => $vendorDir . '/laravel/framework/src/Illuminate/Html/FormBuilder.php',
'Illuminate\\Html\\HtmlBuilder' => $vendorDir . '/laravel/framework/src/Illuminate/Html/HtmlBuilder.php',
'Illuminate\\Html\\HtmlServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Html/HtmlServiceProvider.php',
'Illuminate\\Http\\FrameGuard' => $vendorDir . '/laravel/framework/src/Illuminate/Http/FrameGuard.php',
'Illuminate\\Http\\JsonResponse' => $vendorDir . '/laravel/framework/src/Illuminate/Http/JsonResponse.php',
'Illuminate\\Http\\RedirectResponse' => $vendorDir . '/laravel/framework/src/Illuminate/Http/RedirectResponse.php',
'Illuminate\\Http\\Request' => $vendorDir . '/laravel/framework/src/Illuminate/Http/Request.php',
'Illuminate\\Http\\Response' => $vendorDir . '/laravel/framework/src/Illuminate/Http/Response.php',
'Illuminate\\Log\\LogServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Log/LogServiceProvider.php',
'Illuminate\\Log\\Writer' => $vendorDir . '/laravel/framework/src/Illuminate/Log/Writer.php',
'Illuminate\\Mail\\MailServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/MailServiceProvider.php',
'Illuminate\\Mail\\Mailer' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/Mailer.php',
'Illuminate\\Mail\\Message' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/Message.php',
'Illuminate\\Pagination\\BootstrapPresenter' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/BootstrapPresenter.php',
'Illuminate\\Pagination\\Environment' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/Environment.php',
'Illuminate\\Pagination\\PaginationServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/PaginationServiceProvider.php',
'Illuminate\\Pagination\\Paginator' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/Paginator.php',
'Illuminate\\Pagination\\Presenter' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/Presenter.php',
'Illuminate\\Queue\\BeanstalkdQueue' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/BeanstalkdQueue.php',
'Illuminate\\Queue\\Capsule\\Manager' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Capsule/Manager.php',
'Illuminate\\Queue\\Connectors\\BeanstalkdConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Connectors/BeanstalkdConnector.php',
'Illuminate\\Queue\\Connectors\\ConnectorInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Connectors/ConnectorInterface.php',
'Illuminate\\Queue\\Connectors\\IronConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Connectors/IronConnector.php',
'Illuminate\\Queue\\Connectors\\RedisConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Connectors/RedisConnector.php',
'Illuminate\\Queue\\Connectors\\SqsConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Connectors/SqsConnector.php',
'Illuminate\\Queue\\Connectors\\SyncConnector' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Connectors/SyncConnector.php',
'Illuminate\\Queue\\Console\\FailedTableCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/FailedTableCommand.php',
'Illuminate\\Queue\\Console\\FlushFailedCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/FlushFailedCommand.php',
'Illuminate\\Queue\\Console\\ForgetFailedCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/ForgetFailedCommand.php',
'Illuminate\\Queue\\Console\\ListFailedCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/ListFailedCommand.php',
'Illuminate\\Queue\\Console\\ListenCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/ListenCommand.php',
'Illuminate\\Queue\\Console\\RetryCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/RetryCommand.php',
'Illuminate\\Queue\\Console\\SubscribeCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/SubscribeCommand.php',
'Illuminate\\Queue\\Console\\WorkCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php',
'Illuminate\\Queue\\FailConsoleServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/FailConsoleServiceProvider.php',
'Illuminate\\Queue\\Failed\\DatabaseFailedJobProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Failed/DatabaseFailedJobProvider.php',
'Illuminate\\Queue\\Failed\\FailedJobProviderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Failed/FailedJobProviderInterface.php',
'Illuminate\\Queue\\IronQueue' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/IronQueue.php',
'Illuminate\\Queue\\Jobs\\BeanstalkdJob' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Jobs/BeanstalkdJob.php',
'Illuminate\\Queue\\Jobs\\IronJob' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Jobs/IronJob.php',
'Illuminate\\Queue\\Jobs\\Job' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Jobs/Job.php',
'Illuminate\\Queue\\Jobs\\RedisJob' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Jobs/RedisJob.php',
'Illuminate\\Queue\\Jobs\\SqsJob' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Jobs/SqsJob.php',
'Illuminate\\Queue\\Jobs\\SyncJob' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Jobs/SyncJob.php',
'Illuminate\\Queue\\Listener' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Listener.php',
'Illuminate\\Queue\\Queue' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Queue.php',
'Illuminate\\Queue\\QueueInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/QueueInterface.php',
'Illuminate\\Queue\\QueueManager' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/QueueManager.php',
'Illuminate\\Queue\\QueueServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/QueueServiceProvider.php',
'Illuminate\\Queue\\RedisQueue' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/RedisQueue.php',
'Illuminate\\Queue\\SqsQueue' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/SqsQueue.php',
'Illuminate\\Queue\\SyncQueue' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/SyncQueue.php',
'Illuminate\\Queue\\Worker' => $vendorDir . '/laravel/framework/src/Illuminate/Queue/Worker.php',
'Illuminate\\Redis\\Database' => $vendorDir . '/laravel/framework/src/Illuminate/Redis/Database.php',
'Illuminate\\Redis\\RedisServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Redis/RedisServiceProvider.php',
'Illuminate\\Remote\\Connection' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/Connection.php',
'Illuminate\\Remote\\ConnectionInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/ConnectionInterface.php',
'Illuminate\\Remote\\GatewayInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/GatewayInterface.php',
'Illuminate\\Remote\\MultiConnection' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/MultiConnection.php',
'Illuminate\\Remote\\RemoteManager' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/RemoteManager.php',
'Illuminate\\Remote\\RemoteServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/RemoteServiceProvider.php',
'Illuminate\\Remote\\SecLibGateway' => $vendorDir . '/laravel/framework/src/Illuminate/Remote/SecLibGateway.php',
'Illuminate\\Routing\\Console\\MakeControllerCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Console/MakeControllerCommand.php',
'Illuminate\\Routing\\Controller' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Controller.php',
'Illuminate\\Routing\\ControllerDispatcher' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php',
'Illuminate\\Routing\\ControllerInspector' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/ControllerInspector.php',
'Illuminate\\Routing\\ControllerServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/ControllerServiceProvider.php',
'Illuminate\\Routing\\Generators\\ControllerGenerator' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Generators/ControllerGenerator.php',
'Illuminate\\Routing\\Matching\\HostValidator' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Matching/HostValidator.php',
'Illuminate\\Routing\\Matching\\MethodValidator' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Matching/MethodValidator.php',
'Illuminate\\Routing\\Matching\\SchemeValidator' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Matching/SchemeValidator.php',
'Illuminate\\Routing\\Matching\\UriValidator' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Matching/UriValidator.php',
'Illuminate\\Routing\\Matching\\ValidatorInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Matching/ValidatorInterface.php',
'Illuminate\\Routing\\Redirector' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Redirector.php',
'Illuminate\\Routing\\Route' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Route.php',
'Illuminate\\Routing\\RouteCollection' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/RouteCollection.php',
'Illuminate\\Routing\\RouteFiltererInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/RouteFiltererInterface.php',
'Illuminate\\Routing\\Router' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/Router.php',
'Illuminate\\Routing\\RoutingServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/RoutingServiceProvider.php',
'Illuminate\\Routing\\UrlGenerator' => $vendorDir . '/laravel/framework/src/Illuminate/Routing/UrlGenerator.php',
'Illuminate\\Session\\CacheBasedSessionHandler' => $vendorDir . '/laravel/framework/src/Illuminate/Session/CacheBasedSessionHandler.php',
'Illuminate\\Session\\CommandsServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Session/CommandsServiceProvider.php',
'Illuminate\\Session\\Console\\SessionTableCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Session/Console/SessionTableCommand.php',
'Illuminate\\Session\\CookieSessionHandler' => $vendorDir . '/laravel/framework/src/Illuminate/Session/CookieSessionHandler.php',
'Illuminate\\Session\\FileSessionHandler' => $vendorDir . '/laravel/framework/src/Illuminate/Session/FileSessionHandler.php',
'Illuminate\\Session\\Middleware' => $vendorDir . '/laravel/framework/src/Illuminate/Session/Middleware.php',
'Illuminate\\Session\\SessionInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Session/SessionInterface.php',
'Illuminate\\Session\\SessionManager' => $vendorDir . '/laravel/framework/src/Illuminate/Session/SessionManager.php',
'Illuminate\\Session\\SessionServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Session/SessionServiceProvider.php',
'Illuminate\\Session\\Store' => $vendorDir . '/laravel/framework/src/Illuminate/Session/Store.php',
'Illuminate\\Session\\TokenMismatchException' => $vendorDir . '/laravel/framework/src/Illuminate/Session/TokenMismatchException.php',
'Illuminate\\Support\\ClassLoader' => $vendorDir . '/laravel/framework/src/Illuminate/Support/ClassLoader.php',
'Illuminate\\Support\\Collection' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Collection.php',
'Illuminate\\Support\\Contracts\\ArrayableInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Contracts/ArrayableInterface.php',
'Illuminate\\Support\\Contracts\\JsonableInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Contracts/JsonableInterface.php',
'Illuminate\\Support\\Contracts\\MessageProviderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Contracts/MessageProviderInterface.php',
'Illuminate\\Support\\Contracts\\RenderableInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Contracts/RenderableInterface.php',
'Illuminate\\Support\\Contracts\\ResponsePreparerInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Contracts/ResponsePreparerInterface.php',
'Illuminate\\Support\\Facades\\App' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/App.php',
'Illuminate\\Support\\Facades\\Artisan' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Artisan.php',
'Illuminate\\Support\\Facades\\Auth' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Auth.php',
'Illuminate\\Support\\Facades\\Blade' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Blade.php',
'Illuminate\\Support\\Facades\\Cache' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Cache.php',
'Illuminate\\Support\\Facades\\Config' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Config.php',
'Illuminate\\Support\\Facades\\Cookie' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Cookie.php',
'Illuminate\\Support\\Facades\\Crypt' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Crypt.php',
'Illuminate\\Support\\Facades\\DB' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/DB.php',
'Illuminate\\Support\\Facades\\Event' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Event.php',
'Illuminate\\Support\\Facades\\Facade' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Facade.php',
'Illuminate\\Support\\Facades\\File' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/File.php',
'Illuminate\\Support\\Facades\\Form' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Form.php',
'Illuminate\\Support\\Facades\\HTML' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/HTML.php',
'Illuminate\\Support\\Facades\\Hash' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Hash.php',
'Illuminate\\Support\\Facades\\Input' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Input.php',
'Illuminate\\Support\\Facades\\Lang' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Lang.php',
'Illuminate\\Support\\Facades\\Log' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Log.php',
'Illuminate\\Support\\Facades\\Mail' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Mail.php',
'Illuminate\\Support\\Facades\\Paginator' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Paginator.php',
'Illuminate\\Support\\Facades\\Password' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Password.php',
'Illuminate\\Support\\Facades\\Queue' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Queue.php',
'Illuminate\\Support\\Facades\\Redirect' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Redirect.php',
'Illuminate\\Support\\Facades\\Redis' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Redis.php',
'Illuminate\\Support\\Facades\\Request' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Request.php',
'Illuminate\\Support\\Facades\\Response' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Response.php',
'Illuminate\\Support\\Facades\\Route' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Route.php',
'Illuminate\\Support\\Facades\\SSH' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/SSH.php',
'Illuminate\\Support\\Facades\\Schema' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Schema.php',
'Illuminate\\Support\\Facades\\Session' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Session.php',
'Illuminate\\Support\\Facades\\URL' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/URL.php',
'Illuminate\\Support\\Facades\\Validator' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/Validator.php',
'Illuminate\\Support\\Facades\\View' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Facades/View.php',
'Illuminate\\Support\\Fluent' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Fluent.php',
'Illuminate\\Support\\Manager' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Manager.php',
'Illuminate\\Support\\MessageBag' => $vendorDir . '/laravel/framework/src/Illuminate/Support/MessageBag.php',
'Illuminate\\Support\\NamespacedItemResolver' => $vendorDir . '/laravel/framework/src/Illuminate/Support/NamespacedItemResolver.php',
'Illuminate\\Support\\Pluralizer' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Pluralizer.php',
'Illuminate\\Support\\SerializableClosure' => $vendorDir . '/laravel/framework/src/Illuminate/Support/SerializableClosure.php',
'Illuminate\\Support\\ServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Support/ServiceProvider.php',
'Illuminate\\Support\\Str' => $vendorDir . '/laravel/framework/src/Illuminate/Support/Str.php',
'Illuminate\\Translation\\FileLoader' => $vendorDir . '/laravel/framework/src/Illuminate/Translation/FileLoader.php',
'Illuminate\\Translation\\LoaderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Translation/LoaderInterface.php',
'Illuminate\\Translation\\TranslationServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Translation/TranslationServiceProvider.php',
'Illuminate\\Translation\\Translator' => $vendorDir . '/laravel/framework/src/Illuminate/Translation/Translator.php',
'Illuminate\\Validation\\DatabasePresenceVerifier' => $vendorDir . '/laravel/framework/src/Illuminate/Validation/DatabasePresenceVerifier.php',
'Illuminate\\Validation\\Factory' => $vendorDir . '/laravel/framework/src/Illuminate/Validation/Factory.php',
'Illuminate\\Validation\\PresenceVerifierInterface' => $vendorDir . '/laravel/framework/src/Illuminate/Validation/PresenceVerifierInterface.php',
'Illuminate\\Validation\\ValidationServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Validation/ValidationServiceProvider.php',
'Illuminate\\Validation\\Validator' => $vendorDir . '/laravel/framework/src/Illuminate/Validation/Validator.php',
'Illuminate\\View\\Compilers\\BladeCompiler' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php',
'Illuminate\\View\\Compilers\\Compiler' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/Compiler.php',
'Illuminate\\View\\Compilers\\CompilerInterface' => $vendorDir . '/laravel/framework/src/Illuminate/View/Compilers/CompilerInterface.php',
'Illuminate\\View\\Engines\\CompilerEngine' => $vendorDir . '/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php',
'Illuminate\\View\\Engines\\Engine' => $vendorDir . '/laravel/framework/src/Illuminate/View/Engines/Engine.php',
'Illuminate\\View\\Engines\\EngineInterface' => $vendorDir . '/laravel/framework/src/Illuminate/View/Engines/EngineInterface.php',
'Illuminate\\View\\Engines\\EngineResolver' => $vendorDir . '/laravel/framework/src/Illuminate/View/Engines/EngineResolver.php',
'Illuminate\\View\\Engines\\PhpEngine' => $vendorDir . '/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php',
'Illuminate\\View\\Environment' => $vendorDir . '/laravel/framework/src/Illuminate/View/Environment.php',
'Illuminate\\View\\FileViewFinder' => $vendorDir . '/laravel/framework/src/Illuminate/View/FileViewFinder.php',
'Illuminate\\View\\View' => $vendorDir . '/laravel/framework/src/Illuminate/View/View.php',
'Illuminate\\View\\ViewFinderInterface' => $vendorDir . '/laravel/framework/src/Illuminate/View/ViewFinderInterface.php',
'Illuminate\\View\\ViewServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/View/ViewServiceProvider.php',
'Illuminate\\Workbench\\Console\\WorkbenchMakeCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/Console/WorkbenchMakeCommand.php',
'Illuminate\\Workbench\\Package' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/Package.php',
'Illuminate\\Workbench\\PackageCreator' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/PackageCreator.php',
'Illuminate\\Workbench\\Starter' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/Starter.php',
'Illuminate\\Workbench\\WorkbenchServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/WorkbenchServiceProvider.php',
'Jeremeamia\\SuperClosure\\ClosureLocation' => $vendorDir . '/jeremeamia/SuperClosure/src/Jeremeamia/SuperClosure/ClosureLocation.php',
'Jeremeamia\\SuperClosure\\ClosureParser' => $vendorDir . '/jeremeamia/SuperClosure/src/Jeremeamia/SuperClosure/ClosureParser.php',
'Jeremeamia\\SuperClosure\\SerializableClosure' => $vendorDir . '/jeremeamia/SuperClosure/src/Jeremeamia/SuperClosure/SerializableClosure.php',
'Jeremeamia\\SuperClosure\\Visitor\\ClosureFinderVisitor' => $vendorDir . '/jeremeamia/SuperClosure/src/Jeremeamia/SuperClosure/Visitor/ClosureFinderVisitor.php',
'Jeremeamia\\SuperClosure\\Visitor\\MagicConstantVisitor' => $vendorDir . '/jeremeamia/SuperClosure/src/Jeremeamia/SuperClosure/Visitor/MagicConstantVisitor.php',
'Math_BigInteger' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php',
'Monolog\\ErrorHandler' => $vendorDir . '/monolog/monolog/src/Monolog/ErrorHandler.php',
'Monolog\\Formatter\\ChromePHPFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php',
'Monolog\\Formatter\\ElasticaFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php',
'Monolog\\Formatter\\FormatterInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php',
'Monolog\\Formatter\\GelfMessageFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php',
'Monolog\\Formatter\\JsonFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php',
'Monolog\\Formatter\\LineFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LineFormatter.php',
'Monolog\\Formatter\\LogstashFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php',
'Monolog\\Formatter\\NormalizerFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php',
'Monolog\\Formatter\\ScalarFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php',
'Monolog\\Formatter\\WildfireFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php',
'Monolog\\Handler\\AbstractHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractHandler.php',
'Monolog\\Handler\\AbstractProcessingHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php',
'Monolog\\Handler\\AbstractSyslogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php',
'Monolog\\Handler\\AmqpHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AmqpHandler.php',
'Monolog\\Handler\\BufferHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/BufferHandler.php',
'Monolog\\Handler\\ChromePHPHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php',
'Monolog\\Handler\\CouchDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php',
'Monolog\\Handler\\CubeHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/CubeHandler.php',
'Monolog\\Handler\\DoctrineCouchDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php',
'Monolog\\Handler\\DynamoDbHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php',
'Monolog\\Handler\\ElasticSearchHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php',
'Monolog\\Handler\\ErrorLogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php',
'Monolog\\Handler\\FingersCrossedHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php',
'Monolog\\Handler\\FingersCrossed\\ActivationStrategyInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php',
'Monolog\\Handler\\FingersCrossed\\ChannelLevelActivationStrategy' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php',
'Monolog\\Handler\\FingersCrossed\\ErrorLevelActivationStrategy' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php',
'Monolog\\Handler\\FirePHPHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php',
'Monolog\\Handler\\GelfHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/GelfHandler.php',
'Monolog\\Handler\\GroupHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/GroupHandler.php',
'Monolog\\Handler\\HandlerInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/HandlerInterface.php',
'Monolog\\Handler\\HipChatHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/HipChatHandler.php',
'Monolog\\Handler\\LogglyHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/LogglyHandler.php',
'Monolog\\Handler\\MailHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MailHandler.php',
'Monolog\\Handler\\MissingExtensionException' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php',
'Monolog\\Handler\\MongoDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php',
'Monolog\\Handler\\NativeMailerHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php',
'Monolog\\Handler\\NewRelicHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php',
'Monolog\\Handler\\NullHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NullHandler.php',
'Monolog\\Handler\\PushoverHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PushoverHandler.php',
'Monolog\\Handler\\RavenHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RavenHandler.php',
'Monolog\\Handler\\RedisHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RedisHandler.php',
'Monolog\\Handler\\RotatingFileHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php',
'Monolog\\Handler\\SocketHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SocketHandler.php',
'Monolog\\Handler\\StreamHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/StreamHandler.php',
'Monolog\\Handler\\SwiftMailerHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php',
'Monolog\\Handler\\SyslogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogHandler.php',
'Monolog\\Handler\\SyslogUdpHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php',
'Monolog\\Handler\\SyslogUdp\\UdpSocket' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php',
'Monolog\\Handler\\TestHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/TestHandler.php',
'Monolog\\Handler\\ZendMonitorHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php',
'Monolog\\Logger' => $vendorDir . '/monolog/monolog/src/Monolog/Logger.php',
'Monolog\\Processor\\IntrospectionProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php',
'Monolog\\Processor\\MemoryPeakUsageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php',
'Monolog\\Processor\\MemoryProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php',
'Monolog\\Processor\\MemoryUsageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php',
'Monolog\\Processor\\ProcessIdProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php',
'Monolog\\Processor\\PsrLogMessageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php',
'Monolog\\Processor\\UidProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/UidProcessor.php',
'Monolog\\Processor\\WebProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/WebProcessor.php',
'Net_SCP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SCP.php',
'Net_SFTP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php',
'Net_SFTP_Stream' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php',
'Net_SSH1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH1.php',
'Net_SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php',
'Normalizer' => $vendorDir . '/patchwork/utf8/class/Normalizer.php',
'PHPParser_Autoloader' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Autoloader.php',
'PHPParser_Builder' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder.php',
'PHPParser_BuilderAbstract' => $vendorDir . '/nikic/php-parser/lib/PHPParser/BuilderAbstract.php',
'PHPParser_BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PHPParser/BuilderFactory.php',
'PHPParser_Builder_Class' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder/Class.php',
'PHPParser_Builder_Function' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder/Function.php',
'PHPParser_Builder_Interface' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder/Interface.php',
'PHPParser_Builder_Method' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder/Method.php',
'PHPParser_Builder_Param' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder/Param.php',
'PHPParser_Builder_Property' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Builder/Property.php',
'PHPParser_Comment' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Comment.php',
'PHPParser_Comment_Doc' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Comment/Doc.php',
'PHPParser_Error' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Error.php',
'PHPParser_Lexer' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Lexer.php',
'PHPParser_Lexer_Emulative' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Lexer/Emulative.php',
'PHPParser_Node' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node.php',
'PHPParser_NodeAbstract' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeAbstract.php',
'PHPParser_NodeDumper' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeDumper.php',
'PHPParser_NodeTraverser' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeTraverser.php',
'PHPParser_NodeTraverserInterface' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeTraverserInterface.php',
'PHPParser_NodeVisitor' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeVisitor.php',
'PHPParser_NodeVisitorAbstract' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeVisitorAbstract.php',
'PHPParser_NodeVisitor_NameResolver' => $vendorDir . '/nikic/php-parser/lib/PHPParser/NodeVisitor/NameResolver.php',
'PHPParser_Node_Arg' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Arg.php',
'PHPParser_Node_Const' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Const.php',
'PHPParser_Node_Expr' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr.php',
'PHPParser_Node_Expr_Array' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Array.php',
'PHPParser_Node_Expr_ArrayDimFetch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ArrayDimFetch.php',
'PHPParser_Node_Expr_ArrayItem' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ArrayItem.php',
'PHPParser_Node_Expr_Assign' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Assign.php',
'PHPParser_Node_Expr_AssignBitwiseAnd' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignBitwiseAnd.php',
'PHPParser_Node_Expr_AssignBitwiseOr' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignBitwiseOr.php',
'PHPParser_Node_Expr_AssignBitwiseXor' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignBitwiseXor.php',
'PHPParser_Node_Expr_AssignConcat' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignConcat.php',
'PHPParser_Node_Expr_AssignDiv' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignDiv.php',
'PHPParser_Node_Expr_AssignMinus' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignMinus.php',
'PHPParser_Node_Expr_AssignMod' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignMod.php',
'PHPParser_Node_Expr_AssignMul' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignMul.php',
'PHPParser_Node_Expr_AssignPlus' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignPlus.php',
'PHPParser_Node_Expr_AssignRef' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignRef.php',
'PHPParser_Node_Expr_AssignShiftLeft' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignShiftLeft.php',
'PHPParser_Node_Expr_AssignShiftRight' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/AssignShiftRight.php',
'PHPParser_Node_Expr_BitwiseAnd' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BitwiseAnd.php',
'PHPParser_Node_Expr_BitwiseNot' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BitwiseNot.php',
'PHPParser_Node_Expr_BitwiseOr' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BitwiseOr.php',
'PHPParser_Node_Expr_BitwiseXor' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BitwiseXor.php',
'PHPParser_Node_Expr_BooleanAnd' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BooleanAnd.php',
'PHPParser_Node_Expr_BooleanNot' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BooleanNot.php',
'PHPParser_Node_Expr_BooleanOr' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/BooleanOr.php',
'PHPParser_Node_Expr_Cast' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast.php',
'PHPParser_Node_Expr_Cast_Array' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/Array.php',
'PHPParser_Node_Expr_Cast_Bool' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/Bool.php',
'PHPParser_Node_Expr_Cast_Double' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/Double.php',
'PHPParser_Node_Expr_Cast_Int' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/Int.php',
'PHPParser_Node_Expr_Cast_Object' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/Object.php',
'PHPParser_Node_Expr_Cast_String' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/String.php',
'PHPParser_Node_Expr_Cast_Unset' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Cast/Unset.php',
'PHPParser_Node_Expr_ClassConstFetch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ClassConstFetch.php',
'PHPParser_Node_Expr_Clone' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Clone.php',
'PHPParser_Node_Expr_Closure' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Closure.php',
'PHPParser_Node_Expr_ClosureUse' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ClosureUse.php',
'PHPParser_Node_Expr_Concat' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Concat.php',
'PHPParser_Node_Expr_ConstFetch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ConstFetch.php',
'PHPParser_Node_Expr_Div' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Div.php',
'PHPParser_Node_Expr_Empty' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Empty.php',
'PHPParser_Node_Expr_Equal' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Equal.php',
'PHPParser_Node_Expr_ErrorSuppress' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ErrorSuppress.php',
'PHPParser_Node_Expr_Eval' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Eval.php',
'PHPParser_Node_Expr_Exit' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Exit.php',
'PHPParser_Node_Expr_FuncCall' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/FuncCall.php',
'PHPParser_Node_Expr_Greater' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Greater.php',
'PHPParser_Node_Expr_GreaterOrEqual' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/GreaterOrEqual.php',
'PHPParser_Node_Expr_Identical' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Identical.php',
'PHPParser_Node_Expr_Include' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Include.php',
'PHPParser_Node_Expr_Instanceof' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Instanceof.php',
'PHPParser_Node_Expr_Isset' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Isset.php',
'PHPParser_Node_Expr_List' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/List.php',
'PHPParser_Node_Expr_LogicalAnd' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/LogicalAnd.php',
'PHPParser_Node_Expr_LogicalOr' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/LogicalOr.php',
'PHPParser_Node_Expr_LogicalXor' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/LogicalXor.php',
'PHPParser_Node_Expr_MethodCall' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/MethodCall.php',
'PHPParser_Node_Expr_Minus' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Minus.php',
'PHPParser_Node_Expr_Mod' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Mod.php',
'PHPParser_Node_Expr_Mul' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Mul.php',
'PHPParser_Node_Expr_New' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/New.php',
'PHPParser_Node_Expr_NotEqual' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/NotEqual.php',
'PHPParser_Node_Expr_NotIdentical' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/NotIdentical.php',
'PHPParser_Node_Expr_Plus' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Plus.php',
'PHPParser_Node_Expr_PostDec' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/PostDec.php',
'PHPParser_Node_Expr_PostInc' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/PostInc.php',
'PHPParser_Node_Expr_PreDec' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/PreDec.php',
'PHPParser_Node_Expr_PreInc' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/PreInc.php',
'PHPParser_Node_Expr_Print' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Print.php',
'PHPParser_Node_Expr_PropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/PropertyFetch.php',
'PHPParser_Node_Expr_ShellExec' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ShellExec.php',
'PHPParser_Node_Expr_ShiftLeft' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ShiftLeft.php',
'PHPParser_Node_Expr_ShiftRight' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/ShiftRight.php',
'PHPParser_Node_Expr_Smaller' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Smaller.php',
'PHPParser_Node_Expr_SmallerOrEqual' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/SmallerOrEqual.php',
'PHPParser_Node_Expr_StaticCall' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/StaticCall.php',
'PHPParser_Node_Expr_StaticPropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/StaticPropertyFetch.php',
'PHPParser_Node_Expr_Ternary' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Ternary.php',
'PHPParser_Node_Expr_UnaryMinus' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/UnaryMinus.php',
'PHPParser_Node_Expr_UnaryPlus' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/UnaryPlus.php',
'PHPParser_Node_Expr_Variable' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Variable.php',
'PHPParser_Node_Expr_Yield' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Expr/Yield.php',
'PHPParser_Node_Name' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Name.php',
'PHPParser_Node_Name_FullyQualified' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Name/FullyQualified.php',
'PHPParser_Node_Name_Relative' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Name/Relative.php',
'PHPParser_Node_Param' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Param.php',
'PHPParser_Node_Scalar' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar.php',
'PHPParser_Node_Scalar_ClassConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/ClassConst.php',
'PHPParser_Node_Scalar_DNumber' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/DNumber.php',
'PHPParser_Node_Scalar_DirConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/DirConst.php',
'PHPParser_Node_Scalar_Encapsed' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/Encapsed.php',
'PHPParser_Node_Scalar_FileConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/FileConst.php',
'PHPParser_Node_Scalar_FuncConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/FuncConst.php',
'PHPParser_Node_Scalar_LNumber' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/LNumber.php',
'PHPParser_Node_Scalar_LineConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/LineConst.php',
'PHPParser_Node_Scalar_MethodConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/MethodConst.php',
'PHPParser_Node_Scalar_NSConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/NSConst.php',
'PHPParser_Node_Scalar_String' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/String.php',
'PHPParser_Node_Scalar_TraitConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Scalar/TraitConst.php',
'PHPParser_Node_Stmt' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt.php',
'PHPParser_Node_Stmt_Break' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Break.php',
'PHPParser_Node_Stmt_Case' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Case.php',
'PHPParser_Node_Stmt_Catch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Catch.php',
'PHPParser_Node_Stmt_Class' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Class.php',
'PHPParser_Node_Stmt_ClassConst' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/ClassConst.php',
'PHPParser_Node_Stmt_ClassMethod' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/ClassMethod.php',
'PHPParser_Node_Stmt_Const' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Const.php',
'PHPParser_Node_Stmt_Continue' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Continue.php',
'PHPParser_Node_Stmt_Declare' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Declare.php',
'PHPParser_Node_Stmt_DeclareDeclare' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/DeclareDeclare.php',
'PHPParser_Node_Stmt_Do' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Do.php',
'PHPParser_Node_Stmt_Echo' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Echo.php',
'PHPParser_Node_Stmt_Else' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Else.php',
'PHPParser_Node_Stmt_ElseIf' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/ElseIf.php',
'PHPParser_Node_Stmt_For' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/For.php',
'PHPParser_Node_Stmt_Foreach' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Foreach.php',
'PHPParser_Node_Stmt_Function' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Function.php',
'PHPParser_Node_Stmt_Global' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Global.php',
'PHPParser_Node_Stmt_Goto' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Goto.php',
'PHPParser_Node_Stmt_HaltCompiler' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/HaltCompiler.php',
'PHPParser_Node_Stmt_If' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/If.php',
'PHPParser_Node_Stmt_InlineHTML' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/InlineHTML.php',
'PHPParser_Node_Stmt_Interface' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Interface.php',
'PHPParser_Node_Stmt_Label' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Label.php',
'PHPParser_Node_Stmt_Namespace' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Namespace.php',
'PHPParser_Node_Stmt_Property' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Property.php',
'PHPParser_Node_Stmt_PropertyProperty' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/PropertyProperty.php',
'PHPParser_Node_Stmt_Return' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Return.php',
'PHPParser_Node_Stmt_Static' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Static.php',
'PHPParser_Node_Stmt_StaticVar' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/StaticVar.php',
'PHPParser_Node_Stmt_Switch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Switch.php',
'PHPParser_Node_Stmt_Throw' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Throw.php',
'PHPParser_Node_Stmt_Trait' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Trait.php',
'PHPParser_Node_Stmt_TraitUse' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/TraitUse.php',
'PHPParser_Node_Stmt_TraitUseAdaptation' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/TraitUseAdaptation.php',
'PHPParser_Node_Stmt_TraitUseAdaptation_Alias' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/TraitUseAdaptation/Alias.php',
'PHPParser_Node_Stmt_TraitUseAdaptation_Precedence' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
'PHPParser_Node_Stmt_TryCatch' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/TryCatch.php',
'PHPParser_Node_Stmt_Unset' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Unset.php',
'PHPParser_Node_Stmt_Use' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/Use.php',
'PHPParser_Node_Stmt_UseUse' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/UseUse.php',
'PHPParser_Node_Stmt_While' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Node/Stmt/While.php',
'PHPParser_Parser' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Parser.php',
'PHPParser_PrettyPrinterAbstract' => $vendorDir . '/nikic/php-parser/lib/PHPParser/PrettyPrinterAbstract.php',
'PHPParser_PrettyPrinter_Default' => $vendorDir . '/nikic/php-parser/lib/PHPParser/PrettyPrinter/Default.php',
'PHPParser_PrettyPrinter_Zend' => $vendorDir . '/nikic/php-parser/lib/PHPParser/PrettyPrinter/Zend.php',
'PHPParser_Serializer' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Serializer.php',
'PHPParser_Serializer_XML' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Serializer/XML.php',
'PHPParser_Template' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Template.php',
'PHPParser_TemplateLoader' => $vendorDir . '/nikic/php-parser/lib/PHPParser/TemplateLoader.php',
'PHPParser_Unserializer' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Unserializer.php',
'PHPParser_Unserializer_XML' => $vendorDir . '/nikic/php-parser/lib/PHPParser/Unserializer/XML.php',
'Patchwork\\PHP\\Shim\\Iconv' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Iconv.php',
'Patchwork\\PHP\\Shim\\Intl' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Intl.php',
'Patchwork\\PHP\\Shim\\Mbstring' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Mbstring.php',
'Patchwork\\PHP\\Shim\\Normalizer' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Normalizer.php',
'Patchwork\\PHP\\Shim\\Xml' => $vendorDir . '/patchwork/utf8/class/Patchwork/PHP/Shim/Xml.php',
'Patchwork\\TurkishUtf8' => $vendorDir . '/patchwork/utf8/class/Patchwork/TurkishUtf8.php',
'Patchwork\\Utf8' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8.php',
'Patchwork\\Utf8\\Bootup' => $vendorDir . '/patchwork/utf8/class/Patchwork/Utf8/Bootup.php',
'Predis\\Autoloader' => $vendorDir . '/predis/predis/lib/Predis/Autoloader.php',
'Predis\\BasicClientInterface' => $vendorDir . '/predis/predis/lib/Predis/BasicClientInterface.php',
'Predis\\Client' => $vendorDir . '/predis/predis/lib/Predis/Client.php',
'Predis\\ClientException' => $vendorDir . '/predis/predis/lib/Predis/ClientException.php',
'Predis\\ClientInterface' => $vendorDir . '/predis/predis/lib/Predis/ClientInterface.php',
'Predis\\Cluster\\CommandHashStrategyInterface' => $vendorDir . '/predis/predis/lib/Predis/Cluster/CommandHashStrategyInterface.php',
'Predis\\Cluster\\Distribution\\DistributionStrategyInterface' => $vendorDir . '/predis/predis/lib/Predis/Cluster/Distribution/DistributionStrategyInterface.php',
'Predis\\Cluster\\Distribution\\EmptyRingException' => $vendorDir . '/predis/predis/lib/Predis/Cluster/Distribution/EmptyRingException.php',
'Predis\\Cluster\\Distribution\\HashRing' => $vendorDir . '/predis/predis/lib/Predis/Cluster/Distribution/HashRing.php',
'Predis\\Cluster\\Distribution\\KetamaPureRing' => $vendorDir . '/predis/predis/lib/Predis/Cluster/Distribution/KetamaPureRing.php',
'Predis\\Cluster\\Hash\\CRC16HashGenerator' => $vendorDir . '/predis/predis/lib/Predis/Cluster/Hash/CRC16HashGenerator.php',
'Predis\\Cluster\\Hash\\HashGeneratorInterface' => $vendorDir . '/predis/predis/lib/Predis/Cluster/Hash/HashGeneratorInterface.php',
'Predis\\Cluster\\PredisClusterHashStrategy' => $vendorDir . '/predis/predis/lib/Predis/Cluster/PredisClusterHashStrategy.php',
'Predis\\Cluster\\RedisClusterHashStrategy' => $vendorDir . '/predis/predis/lib/Predis/Cluster/RedisClusterHashStrategy.php',
'Predis\\Collection\\Iterator\\CursorBasedIterator' => $vendorDir . '/predis/predis/lib/Predis/Collection/Iterator/CursorBasedIterator.php',
'Predis\\Collection\\Iterator\\HashKey' => $vendorDir . '/predis/predis/lib/Predis/Collection/Iterator/HashKey.php',
'Predis\\Collection\\Iterator\\Keyspace' => $vendorDir . '/predis/predis/lib/Predis/Collection/Iterator/Keyspace.php',
'Predis\\Collection\\Iterator\\ListKey' => $vendorDir . '/predis/predis/lib/Predis/Collection/Iterator/ListKey.php',
'Predis\\Collection\\Iterator\\SetKey' => $vendorDir . '/predis/predis/lib/Predis/Collection/Iterator/SetKey.php',
'Predis\\Collection\\Iterator\\SortedSetKey' => $vendorDir . '/predis/predis/lib/Predis/Collection/Iterator/SortedSetKey.php',
'Predis\\Command\\AbstractCommand' => $vendorDir . '/predis/predis/lib/Predis/Command/AbstractCommand.php',
'Predis\\Command\\CommandInterface' => $vendorDir . '/predis/predis/lib/Predis/Command/CommandInterface.php',
'Predis\\Command\\ConnectionAuth' => $vendorDir . '/predis/predis/lib/Predis/Command/ConnectionAuth.php',
'Predis\\Command\\ConnectionEcho' => $vendorDir . '/predis/predis/lib/Predis/Command/ConnectionEcho.php',
'Predis\\Command\\ConnectionPing' => $vendorDir . '/predis/predis/lib/Predis/Command/ConnectionPing.php',
'Predis\\Command\\ConnectionQuit' => $vendorDir . '/predis/predis/lib/Predis/Command/ConnectionQuit.php',
'Predis\\Command\\ConnectionSelect' => $vendorDir . '/predis/predis/lib/Predis/Command/ConnectionSelect.php',
'Predis\\Command\\HashDelete' => $vendorDir . '/predis/predis/lib/Predis/Command/HashDelete.php',
'Predis\\Command\\HashExists' => $vendorDir . '/predis/predis/lib/Predis/Command/HashExists.php',
'Predis\\Command\\HashGet' => $vendorDir . '/predis/predis/lib/Predis/Command/HashGet.php',
'Predis\\Command\\HashGetAll' => $vendorDir . '/predis/predis/lib/Predis/Command/HashGetAll.php',
'Predis\\Command\\HashGetMultiple' => $vendorDir . '/predis/predis/lib/Predis/Command/HashGetMultiple.php',
'Predis\\Command\\HashIncrementBy' => $vendorDir . '/predis/predis/lib/Predis/Command/HashIncrementBy.php',
'Predis\\Command\\HashIncrementByFloat' => $vendorDir . '/predis/predis/lib/Predis/Command/HashIncrementByFloat.php',
'Predis\\Command\\HashKeys' => $vendorDir . '/predis/predis/lib/Predis/Command/HashKeys.php',
'Predis\\Command\\HashLength' => $vendorDir . '/predis/predis/lib/Predis/Command/HashLength.php',
'Predis\\Command\\HashScan' => $vendorDir . '/predis/predis/lib/Predis/Command/HashScan.php',
'Predis\\Command\\HashSet' => $vendorDir . '/predis/predis/lib/Predis/Command/HashSet.php',
'Predis\\Command\\HashSetMultiple' => $vendorDir . '/predis/predis/lib/Predis/Command/HashSetMultiple.php',
'Predis\\Command\\HashSetPreserve' => $vendorDir . '/predis/predis/lib/Predis/Command/HashSetPreserve.php',
'Predis\\Command\\HashValues' => $vendorDir . '/predis/predis/lib/Predis/Command/HashValues.php',
'Predis\\Command\\KeyDelete' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyDelete.php',
'Predis\\Command\\KeyDump' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyDump.php',
'Predis\\Command\\KeyExists' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyExists.php',
'Predis\\Command\\KeyExpire' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyExpire.php',
'Predis\\Command\\KeyExpireAt' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyExpireAt.php',
'Predis\\Command\\KeyKeys' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyKeys.php',
'Predis\\Command\\KeyKeysV12x' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyKeysV12x.php',
'Predis\\Command\\KeyMove' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyMove.php',
'Predis\\Command\\KeyPersist' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyPersist.php',
'Predis\\Command\\KeyPreciseExpire' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyPreciseExpire.php',
'Predis\\Command\\KeyPreciseExpireAt' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyPreciseExpireAt.php',
'Predis\\Command\\KeyPreciseTimeToLive' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyPreciseTimeToLive.php',
'Predis\\Command\\KeyRandom' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyRandom.php',
'Predis\\Command\\KeyRename' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyRename.php',
'Predis\\Command\\KeyRenamePreserve' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyRenamePreserve.php',
'Predis\\Command\\KeyRestore' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyRestore.php',
'Predis\\Command\\KeyScan' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyScan.php',
'Predis\\Command\\KeySort' => $vendorDir . '/predis/predis/lib/Predis/Command/KeySort.php',
'Predis\\Command\\KeyTimeToLive' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyTimeToLive.php',
'Predis\\Command\\KeyType' => $vendorDir . '/predis/predis/lib/Predis/Command/KeyType.php',
'Predis\\Command\\ListIndex' => $vendorDir . '/predis/predis/lib/Predis/Command/ListIndex.php',
'Predis\\Command\\ListInsert' => $vendorDir . '/predis/predis/lib/Predis/Command/ListInsert.php',
'Predis\\Command\\ListLength' => $vendorDir . '/predis/predis/lib/Predis/Command/ListLength.php',
'Predis\\Command\\ListPopFirst' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPopFirst.php',
'Predis\\Command\\ListPopFirstBlocking' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPopFirstBlocking.php',
'Predis\\Command\\ListPopLast' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPopLast.php',
'Predis\\Command\\ListPopLastBlocking' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPopLastBlocking.php',
'Predis\\Command\\ListPopLastPushHead' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPopLastPushHead.php',
'Predis\\Command\\ListPopLastPushHeadBlocking' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPopLastPushHeadBlocking.php',
'Predis\\Command\\ListPushHead' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPushHead.php',
'Predis\\Command\\ListPushHeadX' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPushHeadX.php',
'Predis\\Command\\ListPushTail' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPushTail.php',
'Predis\\Command\\ListPushTailX' => $vendorDir . '/predis/predis/lib/Predis/Command/ListPushTailX.php',
'Predis\\Command\\ListRange' => $vendorDir . '/predis/predis/lib/Predis/Command/ListRange.php',
'Predis\\Command\\ListRemove' => $vendorDir . '/predis/predis/lib/Predis/Command/ListRemove.php',
'Predis\\Command\\ListSet' => $vendorDir . '/predis/predis/lib/Predis/Command/ListSet.php',
'Predis\\Command\\ListTrim' => $vendorDir . '/predis/predis/lib/Predis/Command/ListTrim.php',
'Predis\\Command\\PrefixHelpers' => $vendorDir . '/predis/predis/lib/Predis/Command/PrefixHelpers.php',
'Predis\\Command\\PrefixableCommand' => $vendorDir . '/predis/predis/lib/Predis/Command/PrefixableCommand.php',
'Predis\\Command\\PrefixableCommandInterface' => $vendorDir . '/predis/predis/lib/Predis/Command/PrefixableCommandInterface.php',
'Predis\\Command\\Processor\\CommandProcessingInterface' => $vendorDir . '/predis/predis/lib/Predis/Command/Processor/CommandProcessingInterface.php',
'Predis\\Command\\Processor\\CommandProcessorChainInterface' => $vendorDir . '/predis/predis/lib/Predis/Command/Processor/CommandProcessorChainInterface.php',
'Predis\\Command\\Processor\\CommandProcessorInterface' => $vendorDir . '/predis/predis/lib/Predis/Command/Processor/CommandProcessorInterface.php',
'Predis\\Command\\Processor\\KeyPrefixProcessor' => $vendorDir . '/predis/predis/lib/Predis/Command/Processor/KeyPrefixProcessor.php',
'Predis\\Command\\Processor\\ProcessorChain' => $vendorDir . '/predis/predis/lib/Predis/Command/Processor/ProcessorChain.php',
'Predis\\Command\\PubSubPublish' => $vendorDir . '/predis/predis/lib/Predis/Command/PubSubPublish.php',
'Predis\\Command\\PubSubSubscribe' => $vendorDir . '/predis/predis/lib/Predis/Command/PubSubSubscribe.php',
'Predis\\Command\\PubSubSubscribeByPattern' => $vendorDir . '/predis/predis/lib/Predis/Command/PubSubSubscribeByPattern.php',
'Predis\\Command\\PubSubUnsubscribe' => $vendorDir . '/predis/predis/lib/Predis/Command/PubSubUnsubscribe.php',
'Predis\\Command\\PubSubUnsubscribeByPattern' => $vendorDir . '/predis/predis/lib/Predis/Command/PubSubUnsubscribeByPattern.php',
'Predis\\Command\\RawCommand' => $vendorDir . '/predis/predis/lib/Predis/Command/RawCommand.php',
'Predis\\Command\\ScriptedCommand' => $vendorDir . '/predis/predis/lib/Predis/Command/ScriptedCommand.php',
'Predis\\Command\\ServerBackgroundRewriteAOF' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerBackgroundRewriteAOF.php',
'Predis\\Command\\ServerBackgroundSave' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerBackgroundSave.php',
'Predis\\Command\\ServerClient' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerClient.php',
'Predis\\Command\\ServerConfig' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerConfig.php',
'Predis\\Command\\ServerDatabaseSize' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerDatabaseSize.php',
'Predis\\Command\\ServerEval' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerEval.php',
'Predis\\Command\\ServerEvalSHA' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerEvalSHA.php',
'Predis\\Command\\ServerFlushAll' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerFlushAll.php',
'Predis\\Command\\ServerFlushDatabase' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerFlushDatabase.php',
'Predis\\Command\\ServerInfo' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerInfo.php',
'Predis\\Command\\ServerInfoV26x' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerInfoV26x.php',
'Predis\\Command\\ServerLastSave' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerLastSave.php',
'Predis\\Command\\ServerMonitor' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerMonitor.php',
'Predis\\Command\\ServerObject' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerObject.php',
'Predis\\Command\\ServerSave' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerSave.php',
'Predis\\Command\\ServerScript' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerScript.php',
'Predis\\Command\\ServerShutdown' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerShutdown.php',
'Predis\\Command\\ServerSlaveOf' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerSlaveOf.php',
'Predis\\Command\\ServerSlowlog' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerSlowlog.php',
'Predis\\Command\\ServerTime' => $vendorDir . '/predis/predis/lib/Predis/Command/ServerTime.php',
'Predis\\Command\\SetAdd' => $vendorDir . '/predis/predis/lib/Predis/Command/SetAdd.php',
'Predis\\Command\\SetCardinality' => $vendorDir . '/predis/predis/lib/Predis/Command/SetCardinality.php',
'Predis\\Command\\SetDifference' => $vendorDir . '/predis/predis/lib/Predis/Command/SetDifference.php',
'Predis\\Command\\SetDifferenceStore' => $vendorDir . '/predis/predis/lib/Predis/Command/SetDifferenceStore.php',
'Predis\\Command\\SetIntersection' => $vendorDir . '/predis/predis/lib/Predis/Command/SetIntersection.php',
'Predis\\Command\\SetIntersectionStore' => $vendorDir . '/predis/predis/lib/Predis/Command/SetIntersectionStore.php',
'Predis\\Command\\SetIsMember' => $vendorDir . '/predis/predis/lib/Predis/Command/SetIsMember.php',
'Predis\\Command\\SetMembers' => $vendorDir . '/predis/predis/lib/Predis/Command/SetMembers.php',
'Predis\\Command\\SetMove' => $vendorDir . '/predis/predis/lib/Predis/Command/SetMove.php',
'Predis\\Command\\SetPop' => $vendorDir . '/predis/predis/lib/Predis/Command/SetPop.php',
'Predis\\Command\\SetRandomMember' => $vendorDir . '/predis/predis/lib/Predis/Command/SetRandomMember.php',
'Predis\\Command\\SetRemove' => $vendorDir . '/predis/predis/lib/Predis/Command/SetRemove.php',
'Predis\\Command\\SetScan' => $vendorDir . '/predis/predis/lib/Predis/Command/SetScan.php',
'Predis\\Command\\SetUnion' => $vendorDir . '/predis/predis/lib/Predis/Command/SetUnion.php',
'Predis\\Command\\SetUnionStore' => $vendorDir . '/predis/predis/lib/Predis/Command/SetUnionStore.php',
'Predis\\Command\\StringAppend' => $vendorDir . '/predis/predis/lib/Predis/Command/StringAppend.php',
'Predis\\Command\\StringBitCount' => $vendorDir . '/predis/predis/lib/Predis/Command/StringBitCount.php',
'Predis\\Command\\StringBitOp' => $vendorDir . '/predis/predis/lib/Predis/Command/StringBitOp.php',
'Predis\\Command\\StringDecrement' => $vendorDir . '/predis/predis/lib/Predis/Command/StringDecrement.php',
'Predis\\Command\\StringDecrementBy' => $vendorDir . '/predis/predis/lib/Predis/Command/StringDecrementBy.php',
'Predis\\Command\\StringGet' => $vendorDir . '/predis/predis/lib/Predis/Command/StringGet.php',
'Predis\\Command\\StringGetBit' => $vendorDir . '/predis/predis/lib/Predis/Command/StringGetBit.php',
'Predis\\Command\\StringGetMultiple' => $vendorDir . '/predis/predis/lib/Predis/Command/StringGetMultiple.php',
'Predis\\Command\\StringGetRange' => $vendorDir . '/predis/predis/lib/Predis/Command/StringGetRange.php',
'Predis\\Command\\StringGetSet' => $vendorDir . '/predis/predis/lib/Predis/Command/StringGetSet.php',
'Predis\\Command\\StringIncrement' => $vendorDir . '/predis/predis/lib/Predis/Command/StringIncrement.php',
'Predis\\Command\\StringIncrementBy' => $vendorDir . '/predis/predis/lib/Predis/Command/StringIncrementBy.php',
'Predis\\Command\\StringIncrementByFloat' => $vendorDir . '/predis/predis/lib/Predis/Command/StringIncrementByFloat.php',
'Predis\\Command\\StringPreciseSetExpire' => $vendorDir . '/predis/predis/lib/Predis/Command/StringPreciseSetExpire.php',
'Predis\\Command\\StringSet' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSet.php',
'Predis\\Command\\StringSetBit' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSetBit.php',
'Predis\\Command\\StringSetExpire' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSetExpire.php',
'Predis\\Command\\StringSetMultiple' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSetMultiple.php',
'Predis\\Command\\StringSetMultiplePreserve' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSetMultiplePreserve.php',
'Predis\\Command\\StringSetPreserve' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSetPreserve.php',
'Predis\\Command\\StringSetRange' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSetRange.php',
'Predis\\Command\\StringStrlen' => $vendorDir . '/predis/predis/lib/Predis/Command/StringStrlen.php',
'Predis\\Command\\StringSubstr' => $vendorDir . '/predis/predis/lib/Predis/Command/StringSubstr.php',
'Predis\\Command\\TransactionDiscard' => $vendorDir . '/predis/predis/lib/Predis/Command/TransactionDiscard.php',
'Predis\\Command\\TransactionExec' => $vendorDir . '/predis/predis/lib/Predis/Command/TransactionExec.php',
'Predis\\Command\\TransactionMulti' => $vendorDir . '/predis/predis/lib/Predis/Command/TransactionMulti.php',
'Predis\\Command\\TransactionUnwatch' => $vendorDir . '/predis/predis/lib/Predis/Command/TransactionUnwatch.php',
'Predis\\Command\\TransactionWatch' => $vendorDir . '/predis/predis/lib/Predis/Command/TransactionWatch.php',
'Predis\\Command\\ZSetAdd' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetAdd.php',
'Predis\\Command\\ZSetCardinality' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetCardinality.php',
'Predis\\Command\\ZSetCount' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetCount.php',
'Predis\\Command\\ZSetIncrementBy' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetIncrementBy.php',
'Predis\\Command\\ZSetIntersectionStore' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetIntersectionStore.php',
'Predis\\Command\\ZSetRange' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetRange.php',
'Predis\\Command\\ZSetRangeByScore' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetRangeByScore.php',
'Predis\\Command\\ZSetRank' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetRank.php',
'Predis\\Command\\ZSetRemove' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetRemove.php',
'Predis\\Command\\ZSetRemoveRangeByRank' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetRemoveRangeByRank.php',
'Predis\\Command\\ZSetRemoveRangeByScore' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetRemoveRangeByScore.php',
'Predis\\Command\\ZSetReverseRange' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetReverseRange.php',
'Predis\\Command\\ZSetReverseRangeByScore' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetReverseRangeByScore.php',
'Predis\\Command\\ZSetReverseRank' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetReverseRank.php',
'Predis\\Command\\ZSetScan' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetScan.php',
'Predis\\Command\\ZSetScore' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetScore.php',
'Predis\\Command\\ZSetUnionStore' => $vendorDir . '/predis/predis/lib/Predis/Command/ZSetUnionStore.php',
'Predis\\CommunicationException' => $vendorDir . '/predis/predis/lib/Predis/CommunicationException.php',
'Predis\\Connection\\AbstractConnection' => $vendorDir . '/predis/predis/lib/Predis/Connection/AbstractConnection.php',
'Predis\\Connection\\AggregatedConnectionInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/AggregatedConnectionInterface.php',
'Predis\\Connection\\ClusterConnectionInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/ClusterConnectionInterface.php',
'Predis\\Connection\\ComposableConnectionInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/ComposableConnectionInterface.php',
'Predis\\Connection\\ComposableStreamConnection' => $vendorDir . '/predis/predis/lib/Predis/Connection/ComposableStreamConnection.php',
'Predis\\Connection\\ConnectionException' => $vendorDir . '/predis/predis/lib/Predis/Connection/ConnectionException.php',
'Predis\\Connection\\ConnectionFactory' => $vendorDir . '/predis/predis/lib/Predis/Connection/ConnectionFactory.php',
'Predis\\Connection\\ConnectionFactoryInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/ConnectionFactoryInterface.php',
'Predis\\Connection\\ConnectionInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/ConnectionInterface.php',
'Predis\\Connection\\ConnectionParameters' => $vendorDir . '/predis/predis/lib/Predis/Connection/ConnectionParameters.php',
'Predis\\Connection\\ConnectionParametersInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/ConnectionParametersInterface.php',
'Predis\\Connection\\MasterSlaveReplication' => $vendorDir . '/predis/predis/lib/Predis/Connection/MasterSlaveReplication.php',
'Predis\\Connection\\PhpiredisConnection' => $vendorDir . '/predis/predis/lib/Predis/Connection/PhpiredisConnection.php',
'Predis\\Connection\\PhpiredisStreamConnection' => $vendorDir . '/predis/predis/lib/Predis/Connection/PhpiredisStreamConnection.php',
'Predis\\Connection\\PredisCluster' => $vendorDir . '/predis/predis/lib/Predis/Connection/PredisCluster.php',
'Predis\\Connection\\RedisCluster' => $vendorDir . '/predis/predis/lib/Predis/Connection/RedisCluster.php',
'Predis\\Connection\\ReplicationConnectionInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/ReplicationConnectionInterface.php',
'Predis\\Connection\\SingleConnectionInterface' => $vendorDir . '/predis/predis/lib/Predis/Connection/SingleConnectionInterface.php',
'Predis\\Connection\\StreamConnection' => $vendorDir . '/predis/predis/lib/Predis/Connection/StreamConnection.php',
'Predis\\Connection\\WebdisConnection' => $vendorDir . '/predis/predis/lib/Predis/Connection/WebdisConnection.php',
'Predis\\ExecutableContextInterface' => $vendorDir . '/predis/predis/lib/Predis/ExecutableContextInterface.php',
'Predis\\Helpers' => $vendorDir . '/predis/predis/lib/Predis/Helpers.php',
'Predis\\Iterator\\MultiBulkResponse' => $vendorDir . '/predis/predis/lib/Predis/Iterator/MultiBulkResponse.php',
'Predis\\Iterator\\MultiBulkResponseSimple' => $vendorDir . '/predis/predis/lib/Predis/Iterator/MultiBulkResponseSimple.php',
'Predis\\Iterator\\MultiBulkResponseTuple' => $vendorDir . '/predis/predis/lib/Predis/Iterator/MultiBulkResponseTuple.php',
'Predis\\Monitor\\MonitorContext' => $vendorDir . '/predis/predis/lib/Predis/Monitor/MonitorContext.php',
'Predis\\NotSupportedException' => $vendorDir . '/predis/predis/lib/Predis/NotSupportedException.php',
'Predis\\Option\\AbstractOption' => $vendorDir . '/predis/predis/lib/Predis/Option/AbstractOption.php',
'Predis\\Option\\ClientCluster' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientCluster.php',
'Predis\\Option\\ClientConnectionFactory' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientConnectionFactory.php',
'Predis\\Option\\ClientExceptions' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientExceptions.php',
'Predis\\Option\\ClientOptions' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientOptions.php',
'Predis\\Option\\ClientOptionsInterface' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientOptionsInterface.php',
'Predis\\Option\\ClientPrefix' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientPrefix.php',
'Predis\\Option\\ClientProfile' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientProfile.php',
'Predis\\Option\\ClientReplication' => $vendorDir . '/predis/predis/lib/Predis/Option/ClientReplication.php',
'Predis\\Option\\CustomOption' => $vendorDir . '/predis/predis/lib/Predis/Option/CustomOption.php',
'Predis\\Option\\OptionInterface' => $vendorDir . '/predis/predis/lib/Predis/Option/OptionInterface.php',
'Predis\\Pipeline\\FireAndForgetExecutor' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/FireAndForgetExecutor.php',
'Predis\\Pipeline\\MultiExecExecutor' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/MultiExecExecutor.php',
'Predis\\Pipeline\\PipelineContext' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/PipelineContext.php',
'Predis\\Pipeline\\PipelineExecutorInterface' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/PipelineExecutorInterface.php',
'Predis\\Pipeline\\SafeClusterExecutor' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/SafeClusterExecutor.php',
'Predis\\Pipeline\\SafeExecutor' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/SafeExecutor.php',
'Predis\\Pipeline\\StandardExecutor' => $vendorDir . '/predis/predis/lib/Predis/Pipeline/StandardExecutor.php',
'Predis\\PredisException' => $vendorDir . '/predis/predis/lib/Predis/PredisException.php',
'Predis\\Profile\\ServerProfile' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerProfile.php',
'Predis\\Profile\\ServerProfileInterface' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerProfileInterface.php',
'Predis\\Profile\\ServerVersion12' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersion12.php',
'Predis\\Profile\\ServerVersion20' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersion20.php',
'Predis\\Profile\\ServerVersion22' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersion22.php',
'Predis\\Profile\\ServerVersion24' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersion24.php',
'Predis\\Profile\\ServerVersion26' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersion26.php',
'Predis\\Profile\\ServerVersion28' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersion28.php',
'Predis\\Profile\\ServerVersionNext' => $vendorDir . '/predis/predis/lib/Predis/Profile/ServerVersionNext.php',
'Predis\\Protocol\\CommandSerializerInterface' => $vendorDir . '/predis/predis/lib/Predis/Protocol/CommandSerializerInterface.php',
'Predis\\Protocol\\ComposableProtocolInterface' => $vendorDir . '/predis/predis/lib/Predis/Protocol/ComposableProtocolInterface.php',
'Predis\\Protocol\\ProtocolException' => $vendorDir . '/predis/predis/lib/Predis/Protocol/ProtocolException.php',
'Predis\\Protocol\\ProtocolInterface' => $vendorDir . '/predis/predis/lib/Predis/Protocol/ProtocolInterface.php',
'Predis\\Protocol\\ResponseHandlerInterface' => $vendorDir . '/predis/predis/lib/Predis/Protocol/ResponseHandlerInterface.php',
'Predis\\Protocol\\ResponseReaderInterface' => $vendorDir . '/predis/predis/lib/Predis/Protocol/ResponseReaderInterface.php',
'Predis\\Protocol\\Text\\ComposableTextProtocol' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ComposableTextProtocol.php',
'Predis\\Protocol\\Text\\ResponseBulkHandler' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ResponseBulkHandler.php',
'Predis\\Protocol\\Text\\ResponseErrorHandler' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ResponseErrorHandler.php',
'Predis\\Protocol\\Text\\ResponseIntegerHandler' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ResponseIntegerHandler.php',
'Predis\\Protocol\\Text\\ResponseMultiBulkHandler' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ResponseMultiBulkHandler.php',
'Predis\\Protocol\\Text\\ResponseMultiBulkStreamHandler' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ResponseMultiBulkStreamHandler.php',
'Predis\\Protocol\\Text\\ResponseStatusHandler' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/ResponseStatusHandler.php',
'Predis\\Protocol\\Text\\TextCommandSerializer' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/TextCommandSerializer.php',
'Predis\\Protocol\\Text\\TextProtocol' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/TextProtocol.php',
'Predis\\Protocol\\Text\\TextResponseReader' => $vendorDir . '/predis/predis/lib/Predis/Protocol/Text/TextResponseReader.php',
'Predis\\PubSub\\AbstractPubSubContext' => $vendorDir . '/predis/predis/lib/Predis/PubSub/AbstractPubSubContext.php',
'Predis\\PubSub\\DispatcherLoop' => $vendorDir . '/predis/predis/lib/Predis/PubSub/DispatcherLoop.php',
'Predis\\PubSub\\PubSubContext' => $vendorDir . '/predis/predis/lib/Predis/PubSub/PubSubContext.php',
'Predis\\Replication\\ReplicationStrategy' => $vendorDir . '/predis/predis/lib/Predis/Replication/ReplicationStrategy.php',
'Predis\\ResponseError' => $vendorDir . '/predis/predis/lib/Predis/ResponseError.php',
'Predis\\ResponseErrorInterface' => $vendorDir . '/predis/predis/lib/Predis/ResponseErrorInterface.php',
'Predis\\ResponseObjectInterface' => $vendorDir . '/predis/predis/lib/Predis/ResponseObjectInterface.php',
'Predis\\ResponseQueued' => $vendorDir . '/predis/predis/lib/Predis/ResponseQueued.php',
'Predis\\ServerException' => $vendorDir . '/predis/predis/lib/Predis/ServerException.php',
'Predis\\Session\\SessionHandler' => $vendorDir . '/predis/predis/lib/Predis/Session/SessionHandler.php',
'Predis\\Transaction\\AbortedMultiExecException' => $vendorDir . '/predis/predis/lib/Predis/Transaction/AbortedMultiExecException.php',
'Predis\\Transaction\\MultiExecContext' => $vendorDir . '/predis/predis/lib/Predis/Transaction/MultiExecContext.php',
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php',
'Stack\\Builder' => $vendorDir . '/stack/builder/src/Stack/Builder.php',
'Stack\\StackedHttpKernel' => $vendorDir . '/stack/builder/src/Stack/StackedHttpKernel.php',
'Symfony\\Component\\BrowserKit\\Client' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php',
'Symfony\\Component\\BrowserKit\\Cookie' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/Cookie.php',
'Symfony\\Component\\BrowserKit\\CookieJar' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/CookieJar.php',
'Symfony\\Component\\BrowserKit\\History' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/History.php',
'Symfony\\Component\\BrowserKit\\Request' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/Request.php',
'Symfony\\Component\\BrowserKit\\Response' => $vendorDir . '/symfony/browser-kit/Symfony/Component/BrowserKit/Response.php',
'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Symfony/Component/Console/Application.php',
'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Symfony/Component/Console/Command/Command.php',
'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Symfony/Component/Console/Command/HelpCommand.php',
'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Symfony/Component/Console/Command/ListCommand.php',
'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/Symfony/Component/Console/ConsoleEvents.php',
'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php',
'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php',
'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php',
'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php',
'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php',
'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php',
'Symfony\\Component\\Console\\Helper\\DialogHelper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php',
'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/Helper.php',
'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php',
'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/HelperSet.php',
'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php',
'Symfony\\Component\\Console\\Helper\\ProgressHelper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php',
'Symfony\\Component\\Console\\Helper\\TableHelper' => $vendorDir . '/symfony/console/Symfony/Component/Console/Helper/TableHelper.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/ArgvInput.php',
'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/ArrayInput.php',
'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/Input.php',
'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/InputArgument.php',
'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php',
'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/InputDefinition.php',
'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/InputInterface.php',
'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/InputOption.php',
'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Input/StringInput.php',
'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php',
'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/NullOutput.php',
'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/Output.php',
'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/OutputInterface.php',
'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Symfony/Component/Console/Output/StreamOutput.php',
'Symfony\\Component\\Console\\Shell' => $vendorDir . '/symfony/console/Symfony/Component/Console/Shell.php',
'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php',
'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tester/CommandTester.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\ObjectsProvider' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorApplication1' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorApplication2' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorCommand1' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorCommand2' => $vendorDir . '/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php',
'Symfony\\Component\\CssSelector\\CssSelector' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/CssSelector.php',
'Symfony\\Component\\CssSelector\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Exception/ExceptionInterface.php',
'Symfony\\Component\\CssSelector\\Exception\\ExpressionErrorException' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Exception/ExpressionErrorException.php',
'Symfony\\Component\\CssSelector\\Exception\\InternalErrorException' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Exception/InternalErrorException.php',
'Symfony\\Component\\CssSelector\\Exception\\ParseException' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Exception/ParseException.php',
'Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Exception/SyntaxErrorException.php',
'Symfony\\Component\\CssSelector\\Node\\AbstractNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/AbstractNode.php',
'Symfony\\Component\\CssSelector\\Node\\AttributeNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/AttributeNode.php',
'Symfony\\Component\\CssSelector\\Node\\ClassNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/ClassNode.php',
'Symfony\\Component\\CssSelector\\Node\\CombinedSelectorNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php',
'Symfony\\Component\\CssSelector\\Node\\ElementNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/ElementNode.php',
'Symfony\\Component\\CssSelector\\Node\\FunctionNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/FunctionNode.php',
'Symfony\\Component\\CssSelector\\Node\\HashNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/HashNode.php',
'Symfony\\Component\\CssSelector\\Node\\NegationNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/NegationNode.php',
'Symfony\\Component\\CssSelector\\Node\\NodeInterface' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/NodeInterface.php',
'Symfony\\Component\\CssSelector\\Node\\PseudoNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/PseudoNode.php',
'Symfony\\Component\\CssSelector\\Node\\SelectorNode' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/SelectorNode.php',
'Symfony\\Component\\CssSelector\\Node\\Specificity' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Node/Specificity.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\CommentHandler' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/CommentHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\HandlerInterface' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/HandlerInterface.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\HashHandler' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/HashHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\IdentifierHandler' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/IdentifierHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\NumberHandler' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/NumberHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\StringHandler' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/StringHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\WhitespaceHandler' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Handler/WhitespaceHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Parser' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Parser.php',
'Symfony\\Component\\CssSelector\\Parser\\ParserInterface' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/ParserInterface.php',
'Symfony\\Component\\CssSelector\\Parser\\Reader' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Reader.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ClassParser' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Shortcut/ClassParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ElementParser' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Shortcut/ElementParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\EmptyStringParser' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Shortcut/EmptyStringParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\HashParser' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Shortcut/HashParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Token' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Token.php',
'Symfony\\Component\\CssSelector\\Parser\\TokenStream' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/TokenStream.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\Tokenizer' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Tokenizer/Tokenizer.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerEscaping' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Tokenizer/TokenizerEscaping.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerPatterns' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/Parser/Tokenizer/TokenizerPatterns.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\AbstractExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/AbstractExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\AttributeMatchingExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/AttributeMatchingExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\CombinationExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/CombinationExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/ExtensionInterface.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\FunctionExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\HtmlExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/HtmlExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\NodeExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/NodeExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\PseudoClassExtension' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Extension/PseudoClassExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Translator' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/Translator.php',
'Symfony\\Component\\CssSelector\\XPath\\TranslatorInterface' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/TranslatorInterface.php',
'Symfony\\Component\\CssSelector\\XPath\\XPathExpr' => $vendorDir . '/symfony/css-selector/Symfony/Component/CssSelector/XPath/XPathExpr.php',
'Symfony\\Component\\Debug\\Debug' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Debug.php',
'Symfony\\Component\\Debug\\DebugClassLoader' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/DebugClassLoader.php',
'Symfony\\Component\\Debug\\ErrorHandler' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/ErrorHandler.php',
'Symfony\\Component\\Debug\\ExceptionHandler' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/ExceptionHandler.php',
'Symfony\\Component\\Debug\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Exception/ClassNotFoundException.php',
'Symfony\\Component\\Debug\\Exception\\ContextErrorException' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Exception/ContextErrorException.php',
'Symfony\\Component\\Debug\\Exception\\DummyException' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Exception/DummyException.php',
'Symfony\\Component\\Debug\\Exception\\FatalErrorException' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Exception/FatalErrorException.php',
'Symfony\\Component\\Debug\\Exception\\FlattenException' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Exception/FlattenException.php',
'Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Exception/UndefinedFunctionException.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\FatalErrorHandlerInterface' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/FatalErrorHandler/FatalErrorHandlerInterface.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php',
'Symfony\\Component\\Debug\\Tests\\Fixtures\\RequiredTwice' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Tests/Fixtures/RequiredTwice.php',
'Symfony\\Component\\Debug\\Tests\\MockExceptionHandler' => $vendorDir . '/symfony/debug/Symfony/Component/Debug/Tests/MockExceptionHandler.php',
'Symfony\\Component\\DomCrawler\\Crawler' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Crawler.php',
'Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/ChoiceFormField.php',
'Symfony\\Component\\DomCrawler\\Field\\FileFormField' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/FileFormField.php',
'Symfony\\Component\\DomCrawler\\Field\\FormField' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/FormField.php',
'Symfony\\Component\\DomCrawler\\Field\\InputFormField' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/InputFormField.php',
'Symfony\\Component\\DomCrawler\\Field\\TextareaFormField' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/TextareaFormField.php',
'Symfony\\Component\\DomCrawler\\Form' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php',
'Symfony\\Component\\DomCrawler\\FormFieldRegistry' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/FormFieldRegistry.php',
'Symfony\\Component\\DomCrawler\\Link' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Link.php',
'Symfony\\Component\\DomCrawler\\Tests\\Field\\FormFieldTestCase' => $vendorDir . '/symfony/dom-crawler/Symfony/Component/DomCrawler/Tests/Field/FormFieldTestCase.php',
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php',
'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Event.php',
'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventDispatcherInterface.php',
'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventSubscriberInterface.php',
'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/GenericEvent.php',
'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php',
'Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php',
'Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/filesystem/Symfony/Component/Filesystem/Exception/FileNotFoundException.php',
'Symfony\\Component\\Filesystem\\Exception\\IOException' => $vendorDir . '/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php',
'Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => $vendorDir . '/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOExceptionInterface.php',
'Symfony\\Component\\Filesystem\\Filesystem' => $vendorDir . '/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php',
'Symfony\\Component\\Filesystem\\Tests\\FilesystemTestCase' => $vendorDir . '/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php',
'Symfony\\Component\\Finder\\Adapter\\AbstractAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php',
'Symfony\\Component\\Finder\\Adapter\\AbstractFindAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php',
'Symfony\\Component\\Finder\\Adapter\\AdapterInterface' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php',
'Symfony\\Component\\Finder\\Adapter\\BsdFindAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php',
'Symfony\\Component\\Finder\\Adapter\\GnuFindAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php',
'Symfony\\Component\\Finder\\Adapter\\PhpAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php',
'Symfony\\Component\\Finder\\Comparator\\Comparator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php',
'Symfony\\Component\\Finder\\Comparator\\DateComparator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php',
'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php',
'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php',
'Symfony\\Component\\Finder\\Exception\\AdapterFailureException' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php',
'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php',
'Symfony\\Component\\Finder\\Exception\\OperationNotPermitedException' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php',
'Symfony\\Component\\Finder\\Exception\\ShellCommandFailureException' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php',
'Symfony\\Component\\Finder\\Expression\\Expression' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Expression/Expression.php',
'Symfony\\Component\\Finder\\Expression\\Glob' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Expression/Glob.php',
'Symfony\\Component\\Finder\\Expression\\Regex' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Expression/Regex.php',
'Symfony\\Component\\Finder\\Expression\\ValueInterface' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php',
'Symfony\\Component\\Finder\\Finder' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Finder.php',
'Symfony\\Component\\Finder\\Glob' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Glob.php',
'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\FilePathsIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php',
'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php',
'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php',
'Symfony\\Component\\Finder\\Shell\\Command' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Shell/Command.php',
'Symfony\\Component\\Finder\\Shell\\Shell' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Shell/Shell.php',
'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/SplFileInfo.php',
'Symfony\\Component\\Finder\\Tests\\FakeAdapter\\DummyAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php',
'Symfony\\Component\\Finder\\Tests\\FakeAdapter\\FailingAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php',
'Symfony\\Component\\Finder\\Tests\\FakeAdapter\\NamedAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php',
'Symfony\\Component\\Finder\\Tests\\FakeAdapter\\UnsupportedAdapter' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php',
'Symfony\\Component\\Finder\\Tests\\Iterator\\Iterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php',
'Symfony\\Component\\Finder\\Tests\\Iterator\\IteratorTestCase' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php',
'Symfony\\Component\\Finder\\Tests\\Iterator\\MockFileListIterator' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php',
'Symfony\\Component\\Finder\\Tests\\Iterator\\MockSplFileInfo' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php',
'Symfony\\Component\\Finder\\Tests\\Iterator\\RealIteratorTestCase' => $vendorDir . '/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php',
'Symfony\\Component\\HttpFoundation\\AcceptHeader' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/AcceptHeader.php',
'Symfony\\Component\\HttpFoundation\\AcceptHeaderItem' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/AcceptHeaderItem.php',
'Symfony\\Component\\HttpFoundation\\ApacheRequest' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/ApacheRequest.php',
'Symfony\\Component\\HttpFoundation\\BinaryFileResponse' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/BinaryFileResponse.php',
'Symfony\\Component\\HttpFoundation\\Cookie' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Cookie.php',
'Symfony\\Component\\HttpFoundation\\ExpressionRequestMatcher' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/ExpressionRequestMatcher.php',
'Symfony\\Component\\HttpFoundation\\FileBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/FileBag.php',
'Symfony\\Component\\HttpFoundation\\File\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php',
'Symfony\\Component\\HttpFoundation\\File\\Exception\\FileException' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/FileException.php',
'Symfony\\Component\\HttpFoundation\\File\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php',
'Symfony\\Component\\HttpFoundation\\File\\Exception\\UnexpectedTypeException' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/UnexpectedTypeException.php',
'Symfony\\Component\\HttpFoundation\\File\\Exception\\UploadException' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/UploadException.php',
'Symfony\\Component\\HttpFoundation\\File\\File' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/File.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\ExtensionGuesser' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesser.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\ExtensionGuesserInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesserInterface.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\FileBinaryMimeTypeGuesser' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\FileinfoMimeTypeGuesser' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\MimeTypeExtensionGuesser' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\MimeTypeGuesser' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php',
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\MimeTypeGuesserInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php',
'Symfony\\Component\\HttpFoundation\\File\\UploadedFile' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/File/UploadedFile.php',
'Symfony\\Component\\HttpFoundation\\HeaderBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/HeaderBag.php',
'Symfony\\Component\\HttpFoundation\\IpUtils' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/IpUtils.php',
'Symfony\\Component\\HttpFoundation\\JsonResponse' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/JsonResponse.php',
'Symfony\\Component\\HttpFoundation\\ParameterBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/ParameterBag.php',
'Symfony\\Component\\HttpFoundation\\RedirectResponse' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/RedirectResponse.php',
'Symfony\\Component\\HttpFoundation\\Request' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php',
'Symfony\\Component\\HttpFoundation\\RequestMatcher' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcher.php',
'Symfony\\Component\\HttpFoundation\\RequestMatcherInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcherInterface.php',
'Symfony\\Component\\HttpFoundation\\RequestStack' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestStack.php',
'Symfony\\Component\\HttpFoundation\\Response' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Response.php',
'Symfony\\Component\\HttpFoundation\\ResponseHeaderBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/ResponseHeaderBag.php',
'Symfony\\Component\\HttpFoundation\\ServerBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/ServerBag.php',
'Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php',
'Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBagInterface.php',
'Symfony\\Component\\HttpFoundation\\Session\\Attribute\\NamespacedAttributeBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php',
'Symfony\\Component\\HttpFoundation\\Session\\Flash\\AutoExpireFlashBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php',
'Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php',
'Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php',
'Symfony\\Component\\HttpFoundation\\Session\\Session' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Session.php',
'Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/SessionBagInterface.php',
'Symfony\\Component\\HttpFoundation\\Session\\SessionInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/SessionInterface.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcacheSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MongoDbSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NullSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\WriteCheckSessionHandler' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/WriteCheckSessionHandler.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\MetadataBag' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/MetadataBag.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileSessionStorage' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\PhpBridgeSessionStorage' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/PhpBridgeSessionStorage.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\AbstractProxy' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Proxy/AbstractProxy.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\NativeProxy' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Proxy/NativeProxy.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\SessionHandlerProxy' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php',
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/StreamedResponse.php',
'Symfony\\Component\\HttpFoundation\\Tests\\ResponseTestCase' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/ResponseTestCase.php',
'Symfony\\Component\\HttpKernel\\Bundle\\Bundle' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/Bundle.php',
'Symfony\\Component\\HttpKernel\\Bundle\\BundleInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/BundleInterface.php',
'Symfony\\Component\\HttpKernel\\CacheClearer\\CacheClearerInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php',
'Symfony\\Component\\HttpKernel\\CacheClearer\\ChainCacheClearer' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php',
'Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmer' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php',
'Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmerAggregate' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php',
'Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmerInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerInterface.php',
'Symfony\\Component\\HttpKernel\\CacheWarmer\\WarmableInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/WarmableInterface.php',
'Symfony\\Component\\HttpKernel\\Client' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php',
'Symfony\\Component\\HttpKernel\\Config\\FileLocator' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Config/FileLocator.php',
'Symfony\\Component\\HttpKernel\\Controller\\ControllerReference' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.php',
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php',
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php',
'Symfony\\Component\\HttpKernel\\Controller\\TraceableControllerResolver' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/TraceableControllerResolver.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\ConfigDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\DataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\DataCollectorInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\EventDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\ExceptionDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\LateDataCollectorInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LateDataCollectorInterface.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\LoggerDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\MemoryDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\RequestDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\RouterDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RouterDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\TimeDataCollector' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php',
'Symfony\\Component\\HttpKernel\\DataCollector\\Util\\ValueExporter' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/Util/ValueExporter.php',
'Symfony\\Component\\HttpKernel\\Debug\\ErrorHandler' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php',
'Symfony\\Component\\HttpKernel\\Debug\\ExceptionHandler' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php',
'Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php',
'Symfony\\Component\\HttpKernel\\DependencyInjection\\AddClassesToCachePass' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php',
'Symfony\\Component\\HttpKernel\\DependencyInjection\\ConfigurableExtension' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ConfigurableExtension.php',
'Symfony\\Component\\HttpKernel\\DependencyInjection\\ContainerAwareHttpKernel' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php',
'Symfony\\Component\\HttpKernel\\DependencyInjection\\Extension' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php',
'Symfony\\Component\\HttpKernel\\DependencyInjection\\MergeExtensionConfigurationPass' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php',
'Symfony\\Component\\HttpKernel\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/RegisterListenersPass.php',
'Symfony\\Component\\HttpKernel\\EventListener\\ErrorsLoggerListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ErrorsLoggerListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\EsiListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/EsiListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\ExceptionListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\FragmentListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/FragmentListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\LocaleListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/LocaleListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\ProfilerListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ResponseListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\SessionListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/SessionListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\StreamedResponseListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/StreamedResponseListener.php',
'Symfony\\Component\\HttpKernel\\EventListener\\TestSessionListener' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/TestSessionListener.php',
'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterControllerEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterResponseEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\FinishRequestEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FinishRequestEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseForControllerResultEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\KernelEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/KernelEvent.php',
'Symfony\\Component\\HttpKernel\\Event\\PostResponseEvent' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Event/PostResponseEvent.php',
'Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/AccessDeniedHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/BadRequestHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\ConflictHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/ConflictHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\FatalErrorException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php',
'Symfony\\Component\\HttpKernel\\Exception\\FlattenException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php',
'Symfony\\Component\\HttpKernel\\Exception\\GoneHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/GoneHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\HttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpExceptionInterface.php',
'Symfony\\Component\\HttpKernel\\Exception\\LengthRequiredHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/LengthRequiredHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/MethodNotAllowedHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\NotAcceptableHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotAcceptableHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotFoundHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\PreconditionFailedHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/PreconditionFailedHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\PreconditionRequiredHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/PreconditionRequiredHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\ServiceUnavailableHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/ServiceUnavailableHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\TooManyRequestsHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/TooManyRequestsHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/UnauthorizedHttpException.php',
'Symfony\\Component\\HttpKernel\\Exception\\UnsupportedMediaTypeHttpException' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/UnsupportedMediaTypeHttpException.php',
'Symfony\\Component\\HttpKernel\\Fragment\\EsiFragmentRenderer' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/EsiFragmentRenderer.php',
'Symfony\\Component\\HttpKernel\\Fragment\\FragmentHandler' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php',
'Symfony\\Component\\HttpKernel\\Fragment\\FragmentRendererInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/FragmentRendererInterface.php',
'Symfony\\Component\\HttpKernel\\Fragment\\HIncludeFragmentRenderer' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php',
'Symfony\\Component\\HttpKernel\\Fragment\\InlineFragmentRenderer' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php',
'Symfony\\Component\\HttpKernel\\Fragment\\RoutableFragmentRenderer' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php',
'Symfony\\Component\\HttpKernel\\HttpCache\\Esi' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Esi.php',
'Symfony\\Component\\HttpKernel\\HttpCache\\EsiResponseCacheStrategy' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategy.php',
'Symfony\\Component\\HttpKernel\\HttpCache\\EsiResponseCacheStrategyInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategyInterface.php',
'Symfony\\Component\\HttpKernel\\HttpCache\\HttpCache' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/HttpCache.php',
'Symfony\\Component\\HttpKernel\\HttpCache\\Store' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Store.php',
'Symfony\\Component\\HttpKernel\\HttpCache\\StoreInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/StoreInterface.php',
'Symfony\\Component\\HttpKernel\\HttpKernel' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php',
'Symfony\\Component\\HttpKernel\\HttpKernelInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernelInterface.php',
'Symfony\\Component\\HttpKernel\\Kernel' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php',
'Symfony\\Component\\HttpKernel\\KernelEvents' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/KernelEvents.php',
'Symfony\\Component\\HttpKernel\\KernelInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/KernelInterface.php',
'Symfony\\Component\\HttpKernel\\Log\\DebugLoggerInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Log/DebugLoggerInterface.php',
'Symfony\\Component\\HttpKernel\\Log\\LoggerInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php',
'Symfony\\Component\\HttpKernel\\Log\\NullLogger' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php',
'Symfony\\Component\\HttpKernel\\Profiler\\BaseMemcacheProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\FileProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\MemcacheProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcacheProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\MemcachedProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcachedProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\MongoDbProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\MysqlProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\PdoProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\Profile' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profile.php',
'Symfony\\Component\\HttpKernel\\Profiler\\Profiler' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php',
'Symfony\\Component\\HttpKernel\\Profiler\\ProfilerStorageInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php',
'Symfony\\Component\\HttpKernel\\Profiler\\RedisProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\Profiler\\SqliteProfilerStorage' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php',
'Symfony\\Component\\HttpKernel\\TerminableInterface' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/TerminableInterface.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionAbsentBundle\\ExtensionAbsentBundle' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionAbsentBundle/ExtensionAbsentBundle.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionLoadedBundle\\DependencyInjection\\ExtensionLoadedExtension' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionLoadedBundle/DependencyInjection/ExtensionLoadedExtension.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionLoadedBundle\\ExtensionLoadedBundle' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionLoadedBundle/ExtensionLoadedBundle.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionPresentBundle\\Command\\BarCommand' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/Command/BarCommand.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionPresentBundle\\Command\\FooCommand' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/Command/FooCommand.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionPresentBundle\\DependencyInjection\\ExtensionPresentExtension' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/DependencyInjection/ExtensionPresentExtension.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\ExtensionPresentBundle\\ExtensionPresentBundle' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/ExtensionPresentBundle.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\FooBarBundle' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/FooBarBundle.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\KernelForOverrideName' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/KernelForOverrideName.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\TestClient' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/TestClient.php',
'Symfony\\Component\\HttpKernel\\Tests\\Fixtures\\TestEventDispatcher' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php',
'Symfony\\Component\\HttpKernel\\Tests\\HttpCache\\HttpCacheTestCase' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTestCase.php',
'Symfony\\Component\\HttpKernel\\Tests\\HttpCache\\TestHttpKernel' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php',
'Symfony\\Component\\HttpKernel\\Tests\\HttpCache\\TestMultipleHttpKernel' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php',
'Symfony\\Component\\HttpKernel\\Tests\\Logger' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Logger.php',
'Symfony\\Component\\HttpKernel\\Tests\\Profiler\\Mock\\MemcacheMock' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/Mock/MemcacheMock.php',
'Symfony\\Component\\HttpKernel\\Tests\\Profiler\\Mock\\MemcachedMock' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/Mock/MemcachedMock.php',
'Symfony\\Component\\HttpKernel\\Tests\\Profiler\\Mock\\RedisMock' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/Mock/RedisMock.php',
'Symfony\\Component\\HttpKernel\\Tests\\TestHttpKernel' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/TestHttpKernel.php',
'Symfony\\Component\\HttpKernel\\UriSigner' => $vendorDir . '/symfony/http-kernel/Symfony/Component/HttpKernel/UriSigner.php',
'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php',
'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Symfony/Component/Process/Exception/InvalidArgumentException.php',
'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Symfony/Component/Process/Exception/LogicException.php',
'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php',
'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Symfony/Component/Process/Exception/ProcessTimedOutException.php',
'Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php',
'Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/Symfony/Component/Process/ExecutableFinder.php',
'Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/Symfony/Component/Process/PhpExecutableFinder.php',
'Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/Symfony/Component/Process/PhpProcess.php',
'Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Symfony/Component/Process/Process.php',
'Symfony\\Component\\Process\\ProcessBuilder' => $vendorDir . '/symfony/process/Symfony/Component/Process/ProcessBuilder.php',
'Symfony\\Component\\Process\\ProcessPipes' => $vendorDir . '/symfony/process/Symfony/Component/Process/ProcessPipes.php',
'Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/Symfony/Component/Process/ProcessUtils.php',
'Symfony\\Component\\Process\\Tests\\ProcessInSigchildEnvironment' => $vendorDir . '/symfony/process/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php',
'Symfony\\Component\\Routing\\Annotation\\Route' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Annotation/Route.php',
'Symfony\\Component\\Routing\\CompiledRoute' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/CompiledRoute.php',
'Symfony\\Component\\Routing\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php',
'Symfony\\Component\\Routing\\Exception\\InvalidParameterException' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php',
'Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php',
'Symfony\\Component\\Routing\\Exception\\MissingMandatoryParametersException' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php',
'Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php',
'Symfony\\Component\\Routing\\Exception\\RouteNotFoundException' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php',
'Symfony\\Component\\Routing\\Generator\\ConfigurableRequirementsInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Generator/ConfigurableRequirementsInterface.php',
'Symfony\\Component\\Routing\\Generator\\Dumper\\GeneratorDumper' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php',
'Symfony\\Component\\Routing\\Generator\\Dumper\\GeneratorDumperInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php',
'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php',
'Symfony\\Component\\Routing\\Generator\\UrlGenerator' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php',
'Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php',
'Symfony\\Component\\Routing\\Loader\\AnnotationClassLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php',
'Symfony\\Component\\Routing\\Loader\\AnnotationDirectoryLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php',
'Symfony\\Component\\Routing\\Loader\\AnnotationFileLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php',
'Symfony\\Component\\Routing\\Loader\\ClosureLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php',
'Symfony\\Component\\Routing\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php',
'Symfony\\Component\\Routing\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php',
'Symfony\\Component\\Routing\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php',
'Symfony\\Component\\Routing\\Matcher\\ApacheUrlMatcher' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\ApacheMatcherDumper' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperCollection' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperPrefixCollection' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/DumperPrefixCollection.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperRoute' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/DumperRoute.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\MatcherDumper' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\MatcherDumperInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php',
'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php',
'Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcher' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php',
'Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php',
'Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php',
'Symfony\\Component\\Routing\\Matcher\\TraceableUrlMatcher' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php',
'Symfony\\Component\\Routing\\Matcher\\UrlMatcher' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php',
'Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php',
'Symfony\\Component\\Routing\\RequestContext' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/RequestContext.php',
'Symfony\\Component\\Routing\\RequestContextAwareInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php',
'Symfony\\Component\\Routing\\Route' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Route.php',
'Symfony\\Component\\Routing\\RouteCollection' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/RouteCollection.php',
'Symfony\\Component\\Routing\\RouteCompiler' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/RouteCompiler.php',
'Symfony\\Component\\Routing\\RouteCompilerInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php',
'Symfony\\Component\\Routing\\Router' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Router.php',
'Symfony\\Component\\Routing\\RouterInterface' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/RouterInterface.php',
'Symfony\\Component\\Routing\\Tests\\Fixtures\\AnnotatedClasses\\AbstractClass' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php',
'Symfony\\Component\\Routing\\Tests\\Fixtures\\AnnotatedClasses\\BarClass' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/BarClass.php',
'Symfony\\Component\\Routing\\Tests\\Fixtures\\AnnotatedClasses\\FooClass' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooClass.php',
'Symfony\\Component\\Routing\\Tests\\Fixtures\\CustomXmlFileLoader' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/CustomXmlFileLoader.php',
'Symfony\\Component\\Routing\\Tests\\Fixtures\\RedirectableUrlMatcher' => $vendorDir . '/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/RedirectableUrlMatcher.php',
'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Catalogue/AbstractOperation.php',
'Symfony\\Component\\Translation\\Catalogue\\DiffOperation' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Catalogue/DiffOperation.php',
'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Catalogue/MergeOperation.php',
'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Catalogue/OperationInterface.php',
'Symfony\\Component\\Translation\\Dumper\\CsvFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/CsvFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\DumperInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/DumperInterface.php',
'Symfony\\Component\\Translation\\Dumper\\FileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/FileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\IcuResFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/IcuResFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\IniFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/IniFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\JsonFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/JsonFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\MoFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/MoFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\PhpFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/PhpFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\PoFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/PoFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\QtFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/QtFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\XliffFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/XliffFileDumper.php',
'Symfony\\Component\\Translation\\Dumper\\YamlFileDumper' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Dumper/YamlFileDumper.php',
'Symfony\\Component\\Translation\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Exception/ExceptionInterface.php',
'Symfony\\Component\\Translation\\Exception\\InvalidResourceException' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Exception/InvalidResourceException.php',
'Symfony\\Component\\Translation\\Exception\\NotFoundResourceException' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Exception/NotFoundResourceException.php',
'Symfony\\Component\\Translation\\Extractor\\ChainExtractor' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Extractor/ChainExtractor.php',
'Symfony\\Component\\Translation\\Extractor\\ExtractorInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Extractor/ExtractorInterface.php',
'Symfony\\Component\\Translation\\IdentityTranslator' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/IdentityTranslator.php',
'Symfony\\Component\\Translation\\Interval' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Interval.php',
'Symfony\\Component\\Translation\\Loader\\ArrayLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/ArrayLoader.php',
'Symfony\\Component\\Translation\\Loader\\CsvFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/CsvFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\IcuDatFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/IcuDatFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\IcuResFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/IcuResFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\IniFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/IniFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\JsonFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/JsonFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\LoaderInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/LoaderInterface.php',
'Symfony\\Component\\Translation\\Loader\\MoFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/MoFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/PhpFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\PoFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/PoFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\QtFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/QtFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\XliffFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/XliffFileLoader.php',
'Symfony\\Component\\Translation\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Loader/YamlFileLoader.php',
'Symfony\\Component\\Translation\\MessageCatalogue' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/MessageCatalogue.php',
'Symfony\\Component\\Translation\\MessageCatalogueInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/MessageCatalogueInterface.php',
'Symfony\\Component\\Translation\\MessageSelector' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/MessageSelector.php',
'Symfony\\Component\\Translation\\MetadataAwareInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/MetadataAwareInterface.php',
'Symfony\\Component\\Translation\\PluralizationRules' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/PluralizationRules.php',
'Symfony\\Component\\Translation\\Tests\\Loader\\LocalizedTestCase' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php',
'Symfony\\Component\\Translation\\Translator' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Translator.php',
'Symfony\\Component\\Translation\\TranslatorInterface' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php',
'Symfony\\Component\\Translation\\Writer\\TranslationWriter' => $vendorDir . '/symfony/translation/Symfony/Component/Translation/Writer/TranslationWriter.php',
'System_SSH_Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH_Agent.php',
'System_SSH_Agent_Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH_Agent.php',
'TestCase' => $baseDir . '/app/tests/TestCase.php',
'User' => $baseDir . '/app/models/User.php',
'Whoops\\Exception\\ErrorException' => $vendorDir . '/filp/whoops/src/Whoops/Exception/ErrorException.php',
'Whoops\\Exception\\Frame' => $vendorDir . '/filp/whoops/src/Whoops/Exception/Frame.php',
'Whoops\\Exception\\FrameCollection' => $vendorDir . '/filp/whoops/src/Whoops/Exception/FrameCollection.php',
'Whoops\\Exception\\Inspector' => $vendorDir . '/filp/whoops/src/Whoops/Exception/Inspector.php',
'Whoops\\Handler\\CallbackHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/CallbackHandler.php',
'Whoops\\Handler\\Handler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/Handler.php',
'Whoops\\Handler\\HandlerInterface' => $vendorDir . '/filp/whoops/src/Whoops/Handler/HandlerInterface.php',
'Whoops\\Handler\\JsonResponseHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/JsonResponseHandler.php',
'Whoops\\Handler\\PrettyPageHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/PrettyPageHandler.php',
'Whoops\\Handler\\XmlResponseHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/XmlResponseHandler.php',
'Whoops\\Module' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Zend/Module.php',
'Whoops\\Provider\\Phalcon\\WhoopsServiceProvider' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Phalcon/WhoopsServiceProvider.php',
'Whoops\\Provider\\Silex\\WhoopsServiceProvider' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Silex/WhoopsServiceProvider.php',
'Whoops\\Provider\\Zend\\ExceptionStrategy' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Zend/ExceptionStrategy.php',
'Whoops\\Provider\\Zend\\RouteNotFoundStrategy' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Zend/RouteNotFoundStrategy.php',
'Whoops\\Run' => $vendorDir . '/filp/whoops/src/Whoops/Run.php',
);
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
$vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php',
$vendorDir . '/ircmaxell/password-compat/lib/password.php',
$vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
);
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Whoops' => array($vendorDir . '/filp/whoops/src'),
'System' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\DomCrawler\\' => array($vendorDir . '/symfony/dom-crawler'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Symfony\\Component\\BrowserKit\\' => array($vendorDir . '/symfony/browser-kit'),
'Stack' => array($vendorDir . '/stack/builder/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
'Predis' => array($vendorDir . '/predis/predis/lib'),
'Patchwork' => array($vendorDir . '/patchwork/utf8/class'),
'PHPParser' => array($vendorDir . '/nikic/php-parser/lib'),
'Normalizer' => array($vendorDir . '/patchwork/utf8/class'),
'Net' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'Monolog' => array($vendorDir . '/monolog/monolog/src'),
'Math' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'Jeremeamia\\SuperClosure' => array($vendorDir . '/jeremeamia/SuperClosure/src'),
'Illuminate' => array($vendorDir . '/laravel/framework/src'),
'File' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'Crypt' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'ClassPreloader' => array($vendorDir . '/classpreloader/classpreloader/src'),
'Carbon' => array($vendorDir . '/nesbot/carbon/src'),
'Boris' => array($vendorDir . '/d11wtq/boris/lib'),
);
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitb5e048f0ae9c30f4c9c6013e9dcd483d
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitb5e048f0ae9c30f4c9c6013e9dcd483d', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitb5e048f0ae9c30f4c9c6013e9dcd483d', 'loadClassLoader'));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
$includePaths = require __DIR__ . '/include_paths.php';
array_push($includePaths, get_include_path());
set_include_path(join(PATH_SEPARATOR, $includePaths));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
$loader->register(true);
$includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $file) {
composerRequireb5e048f0ae9c30f4c9c6013e9dcd483d($file);
}
return $loader;
}
}
function composerRequireb5e048f0ae9c30f4c9c6013e9dcd483d($file)
{
require $file;
}
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <[email protected]>
* Jordi Boggiano <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0 class loader
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <[email protected]>
* @author Jordi Boggiano <[email protected]>
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
public function getPrefixes()
{
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-0 base directories
* @param bool $prepend Whether to prepend the directories
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*/
public function setPsr4($prefix, $paths) {
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
if ('\\' == $class[0]) {
$class = substr($class, 1);
}
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . '.php';
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
// Remember that this class does not exist.
return $this->classMap[$class] = false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}
<?php
// include_paths.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/phpseclib/phpseclib/phpseclib',
);
[
{
"name": "symfony/translation",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Translation",
"source": {
"type": "git",
"url": "https://github.com/symfony/Translation.git",
"reference": "b00fd07417e493e08488e87bcebeb9681fc7323b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Translation/zipball/b00fd07417e493e08488e87bcebeb9681fc7323b",
"reference": "b00fd07417e493e08488e87bcebeb9681fc7323b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/config": "~2.0",
"symfony/yaml": "~2.2"
},
"suggest": {
"symfony/config": "",
"symfony/yaml": ""
},
"time": "2014-02-03 17:15:33",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Translation\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Translation Component",
"homepage": "http://symfony.com"
},
{
"name": "psr/log",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"shasum": ""
},
"time": "2012-12-21 11:40:51",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
]
},
{
"name": "symfony/routing",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing.git",
"reference": "b2fdea8b60400bb84e4931d71101ebbb3a08c1eb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Routing/zipball/b2fdea8b60400bb84e4931d71101ebbb3a08c1eb",
"reference": "b2fdea8b60400bb84e4931d71101ebbb3a08c1eb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"psr/log": "~1.0",
"symfony/config": "~2.2",
"symfony/expression-language": "~2.4",
"symfony/yaml": "~2.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation loader",
"symfony/config": "For using the all-in-one router or any loader",
"symfony/expression-language": "For using expression matching",
"symfony/yaml": "For using the YAML loader"
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Routing\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Routing Component",
"homepage": "http://symfony.com",
"keywords": [
"router",
"routing",
"uri",
"url"
]
},
{
"name": "symfony/process",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process.git",
"reference": "c175448bac997556f8ab972908a4e14c7291fb03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Process/zipball/c175448bac997556f8ab972908a4e14c7291fb03",
"reference": "c175448bac997556f8ab972908a4e14c7291fb03",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Process\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/finder",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
"url": "https://github.com/symfony/Finder.git",
"reference": "b6735d1fc16da13c4c7dddfe78366a4a098cf011"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Finder/zipball/b6735d1fc16da13c4c7dddfe78366a4a098cf011",
"reference": "b6735d1fc16da13c4c7dddfe78366a4a098cf011",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-01-07 13:28:54",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Finder\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/console",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/940f217cbc3c8a33e5403e7c595495c4884400fe",
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/event-dispatcher": "~2.1"
},
"suggest": {
"symfony/event-dispatcher": ""
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Console\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/filesystem",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
"reference": "7e65abb06d3b38f4be89266fe3fb4a759544e713"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/7e65abb06d3b38f4be89266fe3fb4a759544e713",
"reference": "7e65abb06d3b38f4be89266fe3fb4a759544e713",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-01-07 13:28:54",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Filesystem\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/debug",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/Debug",
"source": {
"type": "git",
"url": "https://github.com/symfony/Debug.git",
"reference": "23b5f4fcad883679d9a6e1cbc568247fe606d8ee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Debug/zipball/23b5f4fcad883679d9a6e1cbc568247fe606d8ee",
"reference": "23b5f4fcad883679d9a6e1cbc568247fe606d8ee",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/http-foundation": "~2.1",
"symfony/http-kernel": "~2.1"
},
"suggest": {
"symfony/http-foundation": "",
"symfony/http-kernel": ""
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Debug\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Debug Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/http-foundation",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
"reference": "cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129",
"reference": "cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-02-11 15:39:28",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"classmap": [
"Symfony/Component/HttpFoundation/Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "4708b8cd41984a5ba29fe7dd40716f7f761ac501"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/4708b8cd41984a5ba29fe7dd40716f7f761ac501",
"reference": "4708b8cd41984a5ba29fe7dd40716f7f761ac501",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/dependency-injection": "~2.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\EventDispatcher\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/http-kernel",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/HttpKernel",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpKernel.git",
"reference": "445d6eee0eab2a6cfab41b5dc43f1b86ec34d110"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/445d6eee0eab2a6cfab41b5dc43f1b86ec34d110",
"reference": "445d6eee0eab2a6cfab41b5dc43f1b86ec34d110",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"psr/log": "~1.0",
"symfony/debug": "~2.3",
"symfony/event-dispatcher": "~2.1",
"symfony/http-foundation": "~2.4"
},
"require-dev": {
"symfony/browser-kit": "~2.2",
"symfony/class-loader": "~2.1",
"symfony/config": "~2.0",
"symfony/console": "~2.2",
"symfony/dependency-injection": "~2.0",
"symfony/finder": "~2.0",
"symfony/process": "~2.0",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.2",
"symfony/templating": "~2.2"
},
"suggest": {
"symfony/browser-kit": "",
"symfony/class-loader": "",
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
"symfony/finder": ""
},
"time": "2014-02-12 19:27:03",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpKernel\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony HttpKernel Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/dom-crawler",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/DomCrawler",
"source": {
"type": "git",
"url": "https://github.com/symfony/DomCrawler.git",
"reference": "5962504de9b36d955d88b08c1434d420627c8c01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/DomCrawler/zipball/5962504de9b36d955d88b08c1434d420627c8c01",
"reference": "5962504de9b36d955d88b08c1434d420627c8c01",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/css-selector": "~2.0"
},
"suggest": {
"symfony/css-selector": ""
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\DomCrawler\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/css-selector",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/CssSelector",
"source": {
"type": "git",
"url": "https://github.com/symfony/CssSelector.git",
"reference": "ed1d61b2e23a0fd5dba0b20651258c4633d3e3a7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/CssSelector/zipball/ed1d61b2e23a0fd5dba0b20651258c4633d3e3a7",
"reference": "ed1d61b2e23a0fd5dba0b20651258c4633d3e3a7",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-02-11 13:52:09",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\CssSelector\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Jean-François Simon",
"email": "[email protected]"
}
],
"description": "Symfony CssSelector Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/browser-kit",
"version": "v2.4.2",
"version_normalized": "2.4.2.0",
"target-dir": "Symfony/Component/BrowserKit",
"source": {
"type": "git",
"url": "https://github.com/symfony/BrowserKit.git",
"reference": "3898f9f9aafc853124c90a9d1a4f98c1034e627e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/BrowserKit/zipball/3898f9f9aafc853124c90a9d1a4f98c1034e627e",
"reference": "3898f9f9aafc853124c90a9d1a4f98c1034e627e",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/dom-crawler": "~2.0"
},
"require-dev": {
"symfony/css-selector": "~2.0",
"symfony/process": "~2.0"
},
"suggest": {
"symfony/process": ""
},
"time": "2014-01-24 14:36:08",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\BrowserKit\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony BrowserKit Component",
"homepage": "http://symfony.com"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.0.3",
"version_normalized": "5.0.3.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "32edc3b0de0fdc1b10f5c4912e8677b3f411a230"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/32edc3b0de0fdc1b10f5c4912e8677b3f411a230",
"reference": "32edc3b0de0fdc1b10f5c4912e8677b3f411a230",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"time": "2013-12-03 13:33:24",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Chris Corbyn"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "http://swiftmailer.org",
"keywords": [
"mail",
"mailer"
]
},
{
"name": "stack/builder",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/stackphp/builder.git",
"reference": "49ab90450d7f959943f3659a4bcb5965530117c2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/stackphp/builder/zipball/49ab90450d7f959943f3659a4bcb5965530117c2",
"reference": "49ab90450d7f959943f3659a4bcb5965530117c2",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"symfony/http-foundation": "~2.1",
"symfony/http-kernel": "~2.1"
},
"require-dev": {
"silex/silex": "~1.0"
},
"time": "2013-10-25 14:04:45",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Stack": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "[email protected]",
"homepage": "http://wiedler.ch/igor/"
}
],
"description": "Builder for stack middlewares based on HttpKernelInterface.",
"keywords": [
"stack"
]
},
{
"name": "predis/predis",
"version": "v0.8.5",
"version_normalized": "0.8.5.0",
"source": {
"type": "git",
"url": "https://github.com/nrk/predis.git",
"reference": "5f2eea628eb465d866ad2771927d83769c8f956c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nrk/predis/zipball/5f2eea628eb465d866ad2771927d83769c8f956c",
"reference": "5f2eea628eb465d866ad2771927d83769c8f956c",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"suggest": {
"ext-curl": "Allows access to Webdis when paired with phpiredis",
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
},
"time": "2014-01-16 14:10:29",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Predis": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniele Alessandri",
"email": "[email protected]",
"homepage": "http://clorophilla.net"
}
],
"description": "Flexible and feature-complete PHP client library for Redis",
"homepage": "http://github.com/nrk/predis",
"keywords": [
"nosql",
"predis",
"redis"
]
},
{
"name": "phpseclib/phpseclib",
"version": "0.3.6",
"version_normalized": "0.3.6.0",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "0ea31d9b65d49a8661e93bec19f44e989bd34c69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/0ea31d9b65d49a8661e93bec19f44e989bd34c69",
"reference": "0ea31d9b65d49a8661e93bec19f44e989bd34c69",
"shasum": ""
},
"require": {
"php": ">=5.0.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "1.*"
},
"suggest": {
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
"pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
},
"time": "2014-02-28 16:05:05",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Crypt": "phpseclib/",
"File": "phpseclib/",
"Math": "phpseclib/",
"Net": "phpseclib/",
"System": "phpseclib/"
},
"files": [
"phpseclib/Crypt/Random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"phpseclib/"
],
"license": [
"MIT"
],
"authors": [
{
"name": "Jim Wigginton",
"email": "[email protected]",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "[email protected]",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "[email protected]",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "[email protected]",
"role": "Developer"
}
],
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"homepage": "http://phpseclib.sourceforge.net",
"keywords": [
"BigInteger",
"aes",
"asn.1",
"asn1",
"blowfish",
"crypto",
"cryptography",
"encryption",
"rsa",
"security",
"sftp",
"signature",
"signing",
"ssh",
"twofish",
"x.509",
"x509"
]
},
{
"name": "patchwork/utf8",
"version": "v1.1.20",
"version_normalized": "1.1.20.0",
"source": {
"type": "git",
"url": "https://github.com/nicolas-grekas/Patchwork-UTF8.git",
"reference": "aea0de833cba7cf2c25239be71f2787edaee36d5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nicolas-grekas/Patchwork-UTF8/zipball/aea0de833cba7cf2c25239be71f2787edaee36d5",
"reference": "aea0de833cba7cf2c25239be71f2787edaee36d5",
"shasum": ""
},
"require": {
"lib-pcre": ">=7.3",
"php": ">=5.3.0"
},
"suggest": {
"ext-iconv": "Use iconv for best performance",
"ext-intl": "Use Intl for best performance",
"ext-mbstring": "Use Mbstring for best performance"
},
"time": "2014-03-01 20:01:07",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Patchwork": "class/",
"Normalizer": "class/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"(Apache-2.0 or GPL-2.0)"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "[email protected]",
"role": "Developer"
}
],
"description": "Extensive, portable and performant handling of UTF-8 and grapheme clusters for PHP",
"homepage": "https://github.com/nicolas-grekas/Patchwork-UTF8",
"keywords": [
"i18n",
"unicode",
"utf-8",
"utf8"
]
},
{
"name": "nesbot/carbon",
"version": "1.8.0",
"version_normalized": "1.8.0.0",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "21c4cb4301969c7d85aee8a62eefdfa881413af0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/21c4cb4301969c7d85aee8a62eefdfa881413af0",
"reference": "21c4cb4301969c7d85aee8a62eefdfa881413af0",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"time": "2014-01-07 05:10:44",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Carbon": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Brian Nesbitt",
"email": "[email protected]",
"homepage": "http://nesbot.com"
}
],
"description": "A simple API extension for DateTime.",
"homepage": "https://github.com/briannesbitt/Carbon",
"keywords": [
"date",
"datetime",
"time"
]
},
{
"name": "monolog/monolog",
"version": "1.7.0",
"version_normalized": "1.7.0.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "6225b22de9dcf36546be3a0b2fa8e3d986153f57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/6225b22de9dcf36546be3a0b2fa8e3d986153f57",
"reference": "6225b22de9dcf36546be3a0b2fa8e3d986153f57",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"require-dev": {
"aws/aws-sdk-php": "~2.4.8",
"doctrine/couchdb": "dev-master",
"mlehner/gelf-php": "1.0.*",
"phpunit/phpunit": "~3.7.0",
"raven/raven": "0.5.*",
"ruflin/elastica": "0.90.*"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server",
"raven/raven": "Allow sending log messages to a Sentry server",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"time": "2013-11-14 19:48:31",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Monolog": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "[email protected]",
"homepage": "http://seld.be",
"role": "Developer"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "http://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
]
},
{
"name": "nikic/php-parser",
"version": "v0.9.4",
"version_normalized": "0.9.4.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "1e5e280ae88a27effa2ae4aa2bd088494ed8594f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1e5e280ae88a27effa2ae4aa2bd088494ed8594f",
"reference": "1e5e280ae88a27effa2ae4aa2bd088494ed8594f",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"time": "2013-08-25 17:11:40",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.9-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"PHPParser": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
"keywords": [
"parser",
"php"
]
},
{
"name": "jeremeamia/SuperClosure",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/jeremeamia/super_closure.git",
"reference": "d05400085f7d4ae6f20ba30d36550836c0d061e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/d05400085f7d4ae6f20ba30d36550836c0d061e8",
"reference": "d05400085f7d4ae6f20ba30d36550836c0d061e8",
"shasum": ""
},
"require": {
"nikic/php-parser": "~0.9",
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~3.7"
},
"time": "2013-10-09 04:20:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Jeremeamia\\SuperClosure": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jeremy Lindblom"
}
],
"description": "Doing interesting things with closures like serialization.",
"homepage": "https://github.com/jeremeamia/super_closure",
"keywords": [
"closure",
"function",
"parser",
"serializable",
"serialize",
"tokenizer"
]
},
{
"name": "ircmaxell/password-compat",
"version": "1.0.3",
"version_normalized": "1.0.3.0",
"source": {
"type": "git",
"url": "https://github.com/ircmaxell/password_compat.git",
"reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/1fc1521b5e9794ea77e4eca30717be9635f1d4f4",
"reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4",
"shasum": ""
},
"time": "2013-04-30 19:58:08",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"lib/password.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anthony Ferrara",
"email": "[email protected]",
"homepage": "http://blog.ircmaxell.com"
}
],
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
"homepage": "https://github.com/ircmaxell/password_compat",
"keywords": [
"hashing",
"password"
]
},
{
"name": "d11wtq/boris",
"version": "v1.0.8",
"version_normalized": "1.0.8.0",
"source": {
"type": "git",
"url": "https://github.com/d11wtq/boris.git",
"reference": "125dd4e5752639af7678a22ea597115646d89c6e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/d11wtq/boris/zipball/125dd4e5752639af7678a22ea597115646d89c6e",
"reference": "125dd4e5752639af7678a22ea597115646d89c6e",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"suggest": {
"ext-pcntl": "*",
"ext-posix": "*",
"ext-readline": "*"
},
"time": "2014-01-17 12:21:18",
"bin": [
"bin/boris"
],
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Boris": "lib"
}
},
"notification-url": "https://packagist.org/downloads/"
},
{
"name": "classpreloader/classpreloader",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/mtdowling/ClassPreloader.git",
"reference": "1a50f7945b725ff2c60f234e51407d1d6e7c77c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mtdowling/ClassPreloader/zipball/1a50f7945b725ff2c60f234e51407d1d6e7c77c5",
"reference": "1a50f7945b725ff2c60f234e51407d1d6e7c77c5",
"shasum": ""
},
"require": {
"nikic/php-parser": "*",
"php": ">=5.3.3",
"symfony/console": ">2.0",
"symfony/filesystem": ">2.0",
"symfony/finder": ">2.0"
},
"time": "2013-06-24 22:58:34",
"bin": [
"classpreloader.php"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.0-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"ClassPreloader": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
"keywords": [
"autoload",
"class",
"preload"
]
},
{
"name": "laravel/framework",
"version": "v4.1.23",
"version_normalized": "4.1.23.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "054c1a29aaf537c6c6ca7e7804375c671eddcaaf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/054c1a29aaf537c6c6ca7e7804375c671eddcaaf",
"reference": "054c1a29aaf537c6c6ca7e7804375c671eddcaaf",
"shasum": ""
},
"require": {
"classpreloader/classpreloader": "1.0.*",
"d11wtq/boris": "1.0.*",
"filp/whoops": "1.0.10",
"ircmaxell/password-compat": "1.0.*",
"jeremeamia/superclosure": "1.0.*",
"monolog/monolog": "1.*",
"nesbot/carbon": "1.*",
"patchwork/utf8": "1.1.*",
"php": ">=5.3.0",
"phpseclib/phpseclib": "0.3.*",
"predis/predis": "0.8.*",
"stack/builder": "1.0.*",
"swiftmailer/swiftmailer": "5.0.*",
"symfony/browser-kit": "2.4.*",
"symfony/console": "2.4.*",
"symfony/css-selector": "2.4.*",
"symfony/debug": "2.4.*",
"symfony/dom-crawler": "2.4.*",
"symfony/finder": "2.4.*",
"symfony/http-foundation": "2.4.*",
"symfony/http-kernel": "2.4.*",
"symfony/process": "2.4.*",
"symfony/routing": "2.4.*",
"symfony/translation": "2.4.*"
},
"replace": {
"illuminate/auth": "self.version",
"illuminate/cache": "self.version",
"illuminate/config": "self.version",
"illuminate/console": "self.version",
"illuminate/container": "self.version",
"illuminate/cookie": "self.version",
"illuminate/database": "self.version",
"illuminate/encryption": "self.version",
"illuminate/events": "self.version",
"illuminate/exception": "self.version",
"illuminate/filesystem": "self.version",
"illuminate/foundation": "self.version",
"illuminate/hashing": "self.version",
"illuminate/html": "self.version",
"illuminate/http": "self.version",
"illuminate/log": "self.version",
"illuminate/mail": "self.version",
"illuminate/pagination": "self.version",
"illuminate/queue": "self.version",
"illuminate/redis": "self.version",
"illuminate/routing": "self.version",
"illuminate/session": "self.version",
"illuminate/support": "self.version",
"illuminate/translation": "self.version",
"illuminate/validation": "self.version",
"illuminate/view": "self.version",
"illuminate/workbench": "self.version"
},
"require-dev": {
"aws/aws-sdk-php": "2.5.*",
"iron-io/iron_mq": "1.5.*",
"mockery/mockery": "0.9.*",
"pda/pheanstalk": "2.1.*",
"phpunit/phpunit": "3.7.*"
},
"suggest": {
"doctrine/dbal": "Allow renaming columns and dropping SQLite columns."
},
"time": "2014-02-28 22:07:47",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"classmap": [
[
"src/Illuminate/Queue/IlluminateQueueClosure.php"
]
],
"files": [
"src/Illuminate/Support/helpers.php"
],
"psr-0": {
"Illuminate": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]",
"homepage": "https://github.com/taylorotwell",
"role": "Developer"
}
],
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
]
},
{
"name": "filp/whoops",
"version": "1.0.10",
"version_normalized": "1.0.10.0",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "91e3fd4b0812017ffbeb24add55330664e1ea32a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/91e3fd4b0812017ffbeb24add55330664e1ea32a",
"reference": "91e3fd4b0812017ffbeb24add55330664e1ea32a",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"mockery/mockery": "dev-master",
"silex/silex": "1.0.*@dev"
},
"time": "2013-12-04 14:19:30",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Whoops": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Filipe Dobreira",
"homepage": "https://github.com/filp",
"role": "Developer"
}
],
"description": "php error handling for cool kids",
"homepage": "https://github.com/filp/whoops",
"keywords": [
"error",
"exception",
"handling",
"library",
"silex-provider",
"whoops",
"zf2"
]
}
]
#!/usr/bin/env php
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
require_once __DIR__.'/../lib/autoload.php';
$boris = new \Boris\Boris();
$config = new \Boris\Config();
$config->apply($boris);
$options = new \Boris\CLIOptionsHandler();
$options->handle($boris);
$boris->start();
{
"files": ["LICENSE"],
"finder": [
{
"name": "*.php",
"exclude": [
"tests"
],
"in": "lib"
}
],
"git-version": "git_tag",
"main": "bin/boris",
"output": "boris.phar",
"stub": true
}
{
"name": "d11wtq/boris",
"require": {
"php": ">=5.3.0"
},
"suggest": {
"ext-readline": "*",
"ext-pcntl": "*",
"ext-posix": "*"
},
"autoload": {
"psr-0": {"Boris": "lib"}
},
"bin": ["bin/boris"]
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
/**
* Custom autoloader for non-composer installations.
*/
spl_autoload_register(function($class) {
if ($class[0] == '\\') {
$class = substr($class, 1);
}
$path = sprintf('%s/%s.php', __DIR__, implode('/', explode('\\', $class)));
if (is_file($path)) {
require_once($path);
}
});
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Boris is a tiny REPL for PHP.
*/
class Boris {
const VERSION = "1.0.8";
private $_prompt;
private $_historyFile;
private $_exports = array();
private $_startHooks = array();
private $_failureHooks = array();
private $_inspector;
/**
* Create a new REPL, which consists of an evaluation worker and a readline client.
*
* @param string $prompt, optional
* @param string $historyFile, optional
*/
public function __construct($prompt = 'boris> ', $historyFile = null) {
$this->setPrompt($prompt);
$this->_historyFile = $historyFile
? $historyFile
: sprintf('%s/.boris_history', getenv('HOME'))
;
$this->_inspector = new ColoredInspector();
}
/**
* Add a new hook to run in the context of the REPL when it starts.
*
* @param mixed $hook
*
* The hook is either a string of PHP code to eval(), or a Closure accepting
* the EvalWorker object as its first argument and the array of defined
* local variables in the second argument.
*
* If the hook is a callback and needs to set any local variables in the
* REPL's scope, it should invoke $worker->setLocal($var_name, $value) to
* do so.
*
* Hooks are guaranteed to run in the order they were added and the state
* set by each hook is available to the next hook (either through global
* resources, such as classes and interfaces, or through the 2nd parameter
* of the callback, if any local variables were set.
*
* @example Contrived example where one hook sets the date and another
* prints it in the REPL.
*
* $boris->onStart(function($worker, $vars){
* $worker->setLocal('date', date('Y-m-d'));
* });
*
* $boris->onStart('echo "The date is $date\n";');
*/
public function onStart($hook) {
$this->_startHooks[] = $hook;
}
/**
* Add a new hook to run in the context of the REPL when a fatal error occurs.
*
* @param mixed $hook
*
* The hook is either a string of PHP code to eval(), or a Closure accepting
* the EvalWorker object as its first argument and the array of defined
* local variables in the second argument.
*
* If the hook is a callback and needs to set any local variables in the
* REPL's scope, it should invoke $worker->setLocal($var_name, $value) to
* do so.
*
* Hooks are guaranteed to run in the order they were added and the state
* set by each hook is available to the next hook (either through global
* resources, such as classes and interfaces, or through the 2nd parameter
* of the callback, if any local variables were set.
*
* @example An example if your project requires some database connection cleanup:
*
* $boris->onFailure(function($worker, $vars){
* DB::reset();
* });
*/
public function onFailure($hook){
$this->_failureHooks[] = $hook;
}
/**
* Set a local variable, or many local variables.
*
* @example Setting a single variable
* $boris->setLocal('user', $bob);
*
* @example Setting many variables at once
* $boris->setLocal(array('user' => $bob, 'appContext' => $appContext));
*
* This method can safely be invoked repeatedly.
*
* @param array|string $local
* @param mixed $value, optional
*/
public function setLocal($local, $value = null) {
if (!is_array($local)) {
$local = array($local => $value);
}
$this->_exports = array_merge($this->_exports, $local);
}
/**
* Sets the Boris prompt text
*
* @param string $prompt
*/
public function setPrompt($prompt) {
$this->_prompt = $prompt;
}
/**
* Set an Inspector object for Boris to output return values with.
*
* @param object $inspector any object the responds to inspect($v)
*/
public function setInspector($inspector) {
$this->_inspector = $inspector;
}
/**
* Start the REPL (display the readline prompt).
*
* This method never returns.
*/
public function start() {
declare(ticks = 1);
pcntl_signal(SIGINT, SIG_IGN, true);
if (!$pipes = stream_socket_pair(
STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP)) {
throw new \RuntimeException('Failed to create socket pair');
}
$pid = pcntl_fork();
if ($pid > 0) {
if (function_exists('setproctitle')) {
setproctitle('boris (master)');
}
fclose($pipes[0]);
$client = new ReadlineClient($pipes[1]);
$client->start($this->_prompt, $this->_historyFile);
} elseif ($pid < 0) {
throw new \RuntimeException('Failed to fork child process');
} else {
if (function_exists('setproctitle')) {
setproctitle('boris (worker)');
}
fclose($pipes[1]);
$worker = new EvalWorker($pipes[0]);
$worker->setLocal($this->_exports);
$worker->setStartHooks($this->_startHooks);
$worker->setFailureHooks($this->_failureHooks);
$worker->setInspector($this->_inspector);
$worker->start();
}
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Processes available command line flags.
*/
class CLIOptionsHandler {
/**
* Accept the REPL object and perform any setup necessary from the CLI flags.
*
* @param Boris $boris
*/
public function handle($boris) {
$args = getopt('hvr:', array('help', 'version', 'require:'));
foreach ($args as $option => $value) {
switch ($option) {
/*
* Sets files to load at startup, may be used multiple times,
* i.e: boris -r test.php,foo/bar.php -r ba/foo.php --require hey.php
*/
case 'r':
case 'require':
$this->_handleRequire($boris, $value);
break;
/*
* Show Usage info
*/
case 'h':
case 'help':
$this->_handleUsageInfo();
break;
/*
* Show version
*/
case 'v':
case 'version':
$this->_handleVersion();
break;
}
}
}
// -- Private Methods
private function _handleRequire($boris, $paths) {
$require = array_reduce(
(array) $paths,
function($acc, $v) { return array_merge($acc, explode(',', $v)); },
array()
);
$boris->onStart(function($worker, $scope) use($require) {
foreach($require as $path) {
require $path;
}
$worker->setLocal(get_defined_vars());
});
}
private function _handleUsageInfo() {
echo <<<USAGE
Usage: boris [options]
boris is a tiny REPL for PHP
Options:
-h, --help show this help message and exit
-r, --require a comma-separated list of files to require on startup
-v, --version show Boris version
USAGE;
exit(0);
}
private function _handleVersion() {
printf("Boris %s\n", Boris::VERSION);
exit(0);
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
/**
* @author Rob Morris <[email protected]>
* @author Chris Corbyn <[email protected]>
*
* Copyright © 2013 Rob Morris.
*/
namespace Boris;
/**
* Identifies data types in data structures and syntax highlights them.
*/
class ColoredInspector implements Inspector {
static $TERM_COLORS = array(
'black' => "\033[0;30m",
'white' => "\033[1;37m",
'none' => "\033[1;30m",
'dark_grey' => "\033[1;30m",
'light_grey' => "\033[0;37m",
'dark_red' => "\033[0;31m",
'light_red' => "\033[1;31m",
'dark_green' => "\033[0;32m",
'light_green' => "\033[1;32m",
'dark_yellow' => "\033[0;33m",
'light_yellow' => "\033[1;33m",
'dark_blue' => "\033[0;34m",
'light_blue' => "\033[1;34m",
'dark_purple' => "\033[0;35m",
'light_purple' => "\033[1;35m",
'dark_cyan' => "\033[0;36m",
'light_cyan' => "\033[1;36m",
);
private $_fallback;
private $_colorMap = array();
/**
* Initialize a new ColoredInspector, using $colorMap.
*
* The colors should be an associative array with the keys:
*
* - 'integer'
* - 'float'
* - 'keyword'
* - 'string'
* - 'boolean'
* - 'default'
*
* And the values, one of the following colors:
*
* - 'none'
* - 'black'
* - 'white'
* - 'dark_grey'
* - 'light_grey'
* - 'dark_red'
* - 'light_red'
* - 'dark_green'
* - 'light_green'
* - 'dark_yellow'
* - 'light_yellow'
* - 'dark_blue'
* - 'light_blue'
* - 'dark_purple'
* - 'light_purple'
* - 'dark_cyan'
* - 'light_cyan'
*
* An empty $colorMap array effectively means 'none' for all types.
*
* @param array $colorMap
*/
public function __construct($colorMap = null) {
$this->_fallback = new DumpInspector();
if (isset($colorMap)) {
$this->_colorMap = $colorMap;
} else {
$this->_colorMap = $this->_defaultColorMap();
}
}
public function inspect($variable) {
return preg_replace(
'/^/m',
$this->_colorize('comment', '// '),
$this->_dump($variable)
);
}
/**
* Returns an associative array of an object's properties.
*
* This method is public so that subclasses may override it.
*
* @param object $value
* @return array
* */
public function objectVars($value) {
return get_object_vars($value);
}
// -- Private Methods
public function _dump($value) {
$tests = array(
'is_null' => '_dumpNull',
'is_string' => '_dumpString',
'is_bool' => '_dumpBoolean',
'is_integer' => '_dumpInteger',
'is_float' => '_dumpFloat',
'is_array' => '_dumpArray',
'is_object' => '_dumpObject'
);
foreach ($tests as $predicate => $outputMethod) {
if (call_user_func($predicate, $value))
return call_user_func(array($this, $outputMethod), $value);
}
return $this->_fallback->inspect($value);
}
private function _dumpNull($value) {
return $this->_colorize('keyword', 'NULL');
}
private function _dumpString($value) {
return $this->_colorize('string', var_export($value, true));
}
private function _dumpBoolean($value) {
return $this->_colorize('bool', var_export($value, true));
}
private function _dumpInteger($value) {
return $this->_colorize('integer', var_export($value, true));
}
private function _dumpFloat($value) {
return $this->_colorize('float', var_export($value, true));
}
private function _dumpArray($value) {
return $this->_dumpStructure('array', $value);
}
private function _dumpObject($value) {
return $this->_dumpStructure(
sprintf('object(%s)', get_class($value)),
$this->objectVars($value)
);
}
private function _dumpStructure($type, $value) {
return $this->_astToString($this->_buildAst($type, $value));
}
public function _buildAst($type, $value, $seen = array()) {
// FIXME: Improve this AST so it doesn't require access to dump() or colorize()
if ($this->_isSeen($value, $seen)) {
return $this->_colorize('default', '*** RECURSION ***');
} else {
$nextSeen = array_merge($seen, array($value));
}
if (is_object($value)) {
$vars = $this->objectVars($value);
} else {
$vars = $value;
}
$self = $this;
return array(
'name' => $this->_colorize('keyword', $type),
'children' => empty($vars) ? array() : array_combine(
array_map(array($this, '_dump'), array_keys($vars)),
array_map(
function($v) use($self, $nextSeen) {
if (is_object($v)) {
return $self->_buildAst(
sprintf('object(%s)', get_class($v)),
$v,
$nextSeen
);
} elseif (is_array($v)) {
return $self->_buildAst('array', $v, $nextSeen);
} else {
return $self->_dump($v);
}
},
array_values($vars)
)
)
);
}
public function _astToString($node, $indent = 0) {
$children = $node['children'];
$self = $this;
return implode(
"\n",
array(
sprintf('%s(', $node['name']),
implode(
",\n",
array_map(
function($k) use($self, $children, $indent) {
if (is_array($children[$k])) {
return sprintf(
'%s%s => %s',
str_repeat(' ', ($indent + 1) * 2),
$k,
$self->_astToString($children[$k], $indent + 1)
);
} else {
return sprintf(
'%s%s => %s',
str_repeat(' ', ($indent + 1) * 2),
$k,
$children[$k]
);
}
},
array_keys($children)
)
),
sprintf('%s)', str_repeat(' ', $indent * 2))
)
);
}
private function _defaultColorMap() {
return array(
'integer' => 'light_green',
'float' => 'light_yellow',
'string' => 'light_red',
'bool' => 'light_purple',
'keyword' => 'light_cyan',
'comment' => 'dark_grey',
'default' => 'none'
);
}
private function _colorize($type, $value) {
if (!empty($this->_colorMap[$type])) {
$colorName = $this->_colorMap[$type];
} else {
$colorName = $this->_colorMap['default'];
}
return sprintf(
"%s%s\033[0m",
static::$TERM_COLORS[$colorName],
$value
);
}
private function _isSeen($value, $seen) {
foreach ($seen as $v) {
if ($v === $value)
return true;
}
return false;
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Config handles loading configuration files for boris
*/
class Config {
private $_searchPaths;
private $_cascade = false;
private $_files = array();
/**
* Create a new Config instance, optionally with an array
* of paths to search for configuration files.
*
* Additionally, if the second, optional boolean argument is
* true, all existing configuration files will be loaded, and
* effectively merged.
*
* @param array $searchPaths
* @param bool $cascade
*/
public function __construct($searchPaths = null, $cascade = false) {
if (is_null($searchPaths)) {
$searchPaths = array();
if ($userHome = getenv('HOME')) {
$searchPaths[] = "{$userHome}/.borisrc";
}
$searchPaths[] = getcwd() . '/.borisrc';
}
$this->_cascade = $cascade;
$this->_searchPaths = $searchPaths;
}
/**
* Searches for configuration files in the available
* search paths, and applies them to the provided
* boris instance.
*
* Returns true if any configuration files were found.
*
* @param Boris\Boris $boris
* @return bool
*/
public function apply(Boris $boris) {
$applied = false;
foreach($this->_searchPaths as $path) {
if (is_readable($path)) {
$this->_loadInIsolation($path, $boris);
$applied = true;
$this->_files[] = $path;
if (!$this->_cascade) {
break;
}
}
}
return $applied;
}
/**
* Returns an array of files that were loaded
* for this Config
*
* @return array
*/
public function loadedFiles() {
return $this->_files;
}
// -- Private Methods
private function _loadInIsolation($path, $boris) {
require $path;
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Passes values through var_dump() to inspect them.
*/
class DumpInspector implements Inspector {
public function inspect($variable) {
ob_start();
var_dump($variable);
return sprintf(" → %s", trim(ob_get_clean()));
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* EvalWorker is responsible for evaluating PHP expressions in forked processes.
*/
class EvalWorker {
const ABNORMAL_EXIT = 255;
const DONE = "\0";
const EXITED = "\1";
const FAILED = "\2";
const READY = "\3";
private $_socket;
private $_exports = array();
private $_startHooks = array();
private $_failureHooks = array();
private $_ppid;
private $_pid;
private $_cancelled;
private $_inspector;
private $_exceptionHandler;
/**
* Create a new worker using the given socket for communication.
*
* @param resource $socket
*/
public function __construct($socket) {
$this->_socket = $socket;
$this->_inspector = new DumpInspector();
stream_set_blocking($socket, 0);
}
/**
* Set local variables to be placed in the workers's scope.
*
* @param array|string $local
* @param mixed $value, if $local is a string
*/
public function setLocal($local, $value = null) {
if (!is_array($local)) {
$local = array($local => $value);
}
$this->_exports = array_merge($this->_exports, $local);
}
/**
* Set hooks to run inside the worker before it starts looping.
*
* @param array $hooks
*/
public function setStartHooks($hooks) {
$this->_startHooks = $hooks;
}
/**
* Set hooks to run inside the worker after a fatal error is caught.
*
* @param array $hooks
*/
public function setFailureHooks($hooks) {
$this->_failureHooks = $hooks;
}
/**
* Set an Inspector object for Boris to output return values with.
*
* @param object $inspector any object the responds to inspect($v)
*/
public function setInspector($inspector) {
$this->_inspector = $inspector;
}
/**
* Start the worker.
*
* This method never returns.
*/
public function start() {
$__scope = $this->_runHooks($this->_startHooks);
extract($__scope);
$this->_write($this->_socket, self::READY);
/* Note the naming of the local variables due to shared scope with the user here */
for (;;) {
declare(ticks = 1);
// don't exit on ctrl-c
pcntl_signal(SIGINT, SIG_IGN, true);
$this->_cancelled = false;
$__input = $this->_transform($this->_read($this->_socket));
if ($__input === null) {
continue;
}
$__response = self::DONE;
$this->_ppid = posix_getpid();
$this->_pid = pcntl_fork();
if ($this->_pid < 0) {
throw new \RuntimeException('Failed to fork child labourer');
} elseif ($this->_pid > 0) {
// kill the child on ctrl-c
pcntl_signal(SIGINT, array($this, 'cancelOperation'), true);
pcntl_waitpid($this->_pid, $__status);
if (!$this->_cancelled && $__status != (self::ABNORMAL_EXIT << 8)) {
$__response = self::EXITED;
} else {
$this->_runHooks($this->_failureHooks);
$__response = self::FAILED;
}
} else {
// user exception handlers normally cause a clean exit, so Boris will exit too
if (!$this->_exceptionHandler =
set_exception_handler(array($this, 'delegateExceptionHandler'))) {
restore_exception_handler();
}
// undo ctrl-c signal handling ready for user code execution
pcntl_signal(SIGINT, SIG_DFL, true);
$__pid = posix_getpid();
$__result = eval($__input);
if (posix_getpid() != $__pid) {
// whatever the user entered caused a forked child
// (totally valid, but we don't want that child to loop and wait for input)
exit(0);
}
if (preg_match('/\s*return\b/i', $__input)) {
fwrite(STDOUT, sprintf("%s\n", $this->_inspector->inspect($__result)));
}
$this->_expungeOldWorker();
}
$this->_write($this->_socket, $__response);
if ($__response == self::EXITED) {
exit(0);
}
}
}
/**
* While a child process is running, terminate it immediately.
*/
public function cancelOperation() {
printf("Cancelling...\n");
$this->_cancelled = true;
posix_kill($this->_pid, SIGKILL);
pcntl_signal_dispatch();
}
/**
* If any user-defined exception handler is present, call it, but be sure to exit correctly.
*/
public function delegateExceptionHandler($ex) {
call_user_func($this->_exceptionHandler, $ex);
exit(self::ABNORMAL_EXIT);
}
// -- Private Methods
private function _runHooks($hooks) {
extract($this->_exports);
foreach ($hooks as $__hook) {
if (is_string($__hook)) {
eval($__hook);
} elseif (is_callable($__hook)) {
call_user_func($__hook, $this, get_defined_vars());
} else {
throw new \RuntimeException(
sprintf(
'Hooks must be closures or strings of PHP code. Got [%s].',
gettype($__hook)
)
);
}
// hooks may set locals
extract($this->_exports);
}
return get_defined_vars();
}
private function _expungeOldWorker() {
posix_kill($this->_ppid, SIGTERM);
pcntl_signal_dispatch();
}
private function _write($socket, $data) {
if (!fwrite($socket, $data)) {
throw new \RuntimeException('Socket error: failed to write data');
}
}
private function _read($socket)
{
$read = array($socket);
$except = array($socket);
if ($this->_select($read, $except) > 0) {
if ($read) {
return stream_get_contents($read[0]);
} else if ($except) {
throw new \UnexpectedValueException("Socket error: closed");
}
}
}
private function _select(&$read, &$except) {
$write = null;
set_error_handler(function(){return true;}, E_WARNING);
$result = stream_select($read, $write, $except, 10);
restore_error_handler();
return $result;
}
private function _transform($input) {
if ($input === null) {
return null;
}
$transforms = array(
'exit' => 'exit(0)'
);
foreach ($transforms as $from => $to) {
$input = preg_replace('/^\s*' . preg_quote($from, '/') . '\s*;?\s*$/', $to . ';', $input);
}
return $input;
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Passes values through var_export() to inspect them.
*/
class ExportInspector implements Inspector {
public function inspect($variable) {
return sprintf(" → %s", var_export($variable, true));
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Something that is capable of returning a useful representation of a variable.
*/
interface Inspector {
/**
* Return a debug-friendly string representation of $variable.
*
* @param mixed $variable
*
* @return string
*/
public function inspect($variable);
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* The Readline client is what the user spends their time entering text into.
*
* Input is collected and sent to {@link \Boris\EvalWorker} for processing.
*/
class ReadlineClient {
private $_socket;
private $_prompt;
private $_historyFile;
private $_clear = false;
/**
* Create a new ReadlineClient using $socket for communication.
*
* @param resource $socket
*/
public function __construct($socket) {
$this->_socket = $socket;
}
/**
* Start the client with an prompt and readline history path.
*
* This method never returns.
*
* @param string $prompt
* @param string $historyFile
*/
public function start($prompt, $historyFile) {
readline_read_history($historyFile);
declare(ticks = 1);
pcntl_signal(SIGCHLD, SIG_IGN);
pcntl_signal(SIGINT, array($this, 'clear'), true);
// wait for the worker to finish executing hooks
if (fread($this->_socket, 1) != EvalWorker::READY) {
throw new \RuntimeException('EvalWorker failed to start');
}
$parser = new ShallowParser();
$buf = '';
$lineno = 1;
for (;;) {
$this->_clear = false;
$line = readline(
sprintf(
'[%d] %s',
$lineno,
($buf == ''
? $prompt
: str_pad('*> ', strlen($prompt), ' ', STR_PAD_LEFT))
)
);
if ($this->_clear) {
$buf = '';
continue;
}
if (false === $line) {
$buf = 'exit(0);'; // ctrl-d acts like exit
}
if (strlen($line) > 0) {
readline_add_history($line);
}
$buf .= sprintf("%s\n", $line);
if ($statements = $parser->statements($buf)) {
++$lineno;
$buf = '';
foreach ($statements as $stmt) {
if (false === $written = fwrite($this->_socket, $stmt)) {
throw new \RuntimeException('Socket error: failed to write data');
}
if ($written > 0) {
$status = fread($this->_socket, 1);
if ($status == EvalWorker::EXITED) {
readline_write_history($historyFile);
echo "\n";
exit(0);
} elseif ($status == EvalWorker::FAILED) {
break;
}
}
}
}
}
}
/**
* Clear the input buffer.
*/
public function clear() {
// FIXME: I'd love to have this send \r to readline so it puts the user on a blank line
$this->_clear = true;
}
}
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* The ShallowParser takes whatever is currently buffered and chunks it into individual statements.
*/
class ShallowParser {
private $_pairs = array(
'(' => ')',
'{' => '}',
'[' => ']',
'"' => '"',
"'" => "'",
'//' => "\n",
'#' => "\n",
'/*' => '*/',
'<<<' => '_heredoc_special_case_'
);
private $_initials;
public function __construct() {
$this->_initials = '/^(' . implode('|', array_map(array($this, 'quote'), array_keys($this->_pairs))) . ')/';
}
/**
* Break the $buffer into chunks, with one for each highest-level construct possible.
*
* If the buffer is incomplete, returns an empty array.
*
* @param string $buffer
*
* @return array
*/
public function statements($buffer) {
$result = $this->_createResult($buffer);
while (strlen($result->buffer) > 0) {
$this->_resetResult($result);
if ($result->state == '<<<') {
if (!$this->_initializeHeredoc($result)) {
continue;
}
}
$rules = array('_scanEscapedChar', '_scanRegion', '_scanStateEntrant', '_scanWsp', '_scanChar');
foreach ($rules as $method) {
if ($this->$method($result)) {
break;
}
}
if ($result->stop) {
break;
}
}
if (!empty($result->statements) && trim($result->stmt) === '' && strlen($result->buffer) == 0) {
$this->_combineStatements($result);
$this->_prepareForDebug($result);
return $result->statements;
}
}
public function quote($token) {
return preg_quote($token, '/');
}
// -- Private Methods
private function _createResult($buffer) {
$result = new \stdClass();
$result->buffer = $buffer;
$result->stmt = '';
$result->state = null;
$result->states = array();
$result->statements = array();
$result->stop = false;
return $result;
}
private function _resetResult($result) {
$result->stop = false;
$result->state = end($result->states);
$result->terminator = $result->state
? '/^(.*?' . preg_quote($this->_pairs[$result->state], '/') . ')/s'
: null
;
}
private function _combineStatements($result) {
$combined = array();
foreach ($result->statements as $scope) {
if (trim($scope) == ';' || substr(trim($scope), -1) != ';') {
$combined[] = ((string) array_pop($combined)) . $scope;
} else {
$combined[] = $scope;
}
}
$result->statements = $combined;
}
private function _prepareForDebug($result) {
$result->statements []= $this->_prepareDebugStmt(array_pop($result->statements));
}
private function _initializeHeredoc($result) {
if (preg_match('/^([\'"]?)([a-z_][a-z0-9_]*)\\1/i', $result->buffer, $match)) {
$docId = $match[2];
$result->stmt .= $match[0];
$result->buffer = substr($result->buffer, strlen($match[0]));
$result->terminator = '/^(.*?\n' . $docId . ');?\n/s';
return true;
} else {
return false;
}
}
private function _scanWsp($result) {
if (preg_match('/^\s+/', $result->buffer, $match)) {
if (!empty($result->statements) && $result->stmt === '') {
$result->statements[] = array_pop($result->statements) . $match[0];
} else {
$result->stmt .= $match[0];
}
$result->buffer = substr($result->buffer, strlen($match[0]));
return true;
} else {
return false;
}
}
private function _scanEscapedChar($result) {
if (($result->state == '"' || $result->state == "'")
&& preg_match('/^[^' . $result->state . ']*?\\\\./s', $result->buffer, $match)) {
$result->stmt .= $match[0];
$result->buffer = substr($result->buffer, strlen($match[0]));
return true;
} else {
return false;
}
}
private function _scanRegion($result) {
if (in_array($result->state, array('"', "'", '<<<', '//', '#', '/*'))) {
if (preg_match($result->terminator, $result->buffer, $match)) {
$result->stmt .= $match[1];
$result->buffer = substr($result->buffer, strlen($match[1]));
array_pop($result->states);
} else {
$result->stop = true;
}
return true;
} else {
return false;
}
}
private function _scanStateEntrant($result) {
if (preg_match($this->_initials, $result->buffer, $match)) {
$result->stmt .= $match[0];
$result->buffer = substr($result->buffer, strlen($match[0]));
$result->states[] = $match[0];
return true;
} else {
return false;
}
}
private function _scanChar($result) {
$chr = substr($result->buffer, 0, 1);
$result->stmt .= $chr;
$result->buffer = substr($result->buffer, 1);
if ($result->state && $chr == $this->_pairs[$result->state]) {
array_pop($result->states);
}
if (empty($result->states) && ($chr == ';' || $chr == '}')) {
if (!$this->_isLambda($result->stmt) || $chr == ';') {
$result->statements[] = $result->stmt;
$result->stmt = '';
}
}
return true;
}
private function _isLambda($input) {
return preg_match(
'/^([^=]*?=\s*)?function\s*\([^\)]*\)\s*(use\s*\([^\)]*\)\s*)?\s*\{.*\}\s*;?$/is',
trim($input)
);
}
private function _isReturnable($input) {
$input = trim($input);
if (substr($input, -1) == ';' && substr($input, 0, 1) != '{') {
return $this->_isLambda($input) || !preg_match(
'/^(' .
'echo|print|exit|die|goto|global|include|include_once|require|require_once|list|' .
'return|do|for|foreach|while|if|function|namespace|class|interface|abstract|switch|' .
'declare|throw|try|unset' .
')\b/i',
$input
);
} else {
return false;
}
}
private function _prepareDebugStmt($input) {
if ($this->_isReturnable($input) && !preg_match('/^\s*return/i', $input)) {
$input = sprintf('return %s', $input);
}
return $input;
}
}
Copyright (c) 2011 Chris Corbyn
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.

Boris: A tiny little, but robust REPL for PHP

Demo

Python has one. Ruby has one. Clojure has one. Now PHP has one too. Boris is PHP's missing REPL (read-eval-print loop), allowing developers to experiment with PHP code in the terminal in an interactive manner. If you make a mistake, it doesn't matter, Boris will report the error and stand to attention for further input.

Everything you enter into Boris is evaluated and the result inspected so you can understand what is happening. State is maintained between inputs, allowing you to gradually build up a solution to a problem.

Why?

I'm in the process of transitioning away from PHP to Ruby. I have come to find PHP's lack of a real REPL to be frustrating and was not able to find an existing implementation that was complete. Boris weighs in at a few hundred lines of fairly straightforward code.

Installation

1. As a pre-built phar file

Boris is available for download as a Phar archive:

Simply download it and run it.

curl -O https://github.com/d11wtq/boris/releases/download/v1.0.8/boris.phar
chmod +x boris.phar
./boris.phar

2. Via packagist

For use with composer.

3. Directly from this repo

This is great if you want to stay really up-to-date. I don't commit unstable code to master, ever.

git clone git://github.com/d11wtq/boris.git
cd boris
./bin/boris

4. Build your own phar

You can also build a PHAR file using Box:

box build

This will create a boris.phar file. Feel free to move it into your bin directory:

chmod +x boris.phar
mv boris.phar /usr/local/bin/boris

Pro Tip

Add boris to your $PATH for easy access.

Usage

When Boris starts, you will be at the boris> prompt. PHP code you enter at this prompt is evaluated. If an expression spans multiple lines, Boris will collect the input and then evaluate the expression when it is complete. Press CTRL-C to clear a multi-line input buffer if you make a mistake. The output is dumped with var_dump() by default.

boris> $x = 1;
int(1)
boris> $y = 2;
int(2)
boris> "x + y = " . ($x + $y);
string(9) "x + y = 3"
boris> exit;

You can also use CTRL-D to exit the REPL.

Cancelling long-running operations

Long-running operations, such as infinite loops, may be cancelled at any time without quitting the REPL, by using CTRL-C while the operation is running.

boris> for ($i = 0; ; ++$i) {
    *>   if ($i % 2 == 0) printf("Tick\n");
    *>   else             printf("Tock\n");
    *>   sleep(1);
    *> }
Tick
Tock
Tick
Tock
Tick
Tock
Tick
^CCancelling...
boris>

Using Boris with your application loaded

You can also use Boris as part of a larger project (e.g. with your application environment loaded).

require_once 'lib/autoload.php';

$boris = new \Boris\Boris('myapp> ');
$boris->start();

The constructor parameter is optional and changes the prompt.

If you want to pass local variables straight into Boris (e.g. parts of your application), you can do that too (thanks to @dhotston):

$boris = new \Boris\Boris('myapp> ');
$boris->setLocal(array('appContext' => $appContext));
$boris->start();

In the above example, $appContext will be present inside the REPL.

Using start hooks

It is possible to add callbacks to Boris that are executed inside the REPL before it begins looping. Any number of hooks can be added, and they will be executed in order. Any variables set or exported by the hook will become visible from inside the REPL and consequently, to subsequent hooks that are run.

There are two ways to specify hooks: as arbitrary strings of PHP code to evaluate, or as callbacks given as closures. Both approaches allow you access to the scope, though you need to do slightly more work with the callback approach.

// this will simply be evaluated in the REPL scope
// the variables $foo and $bar will be visible inside the REPL
$boris->onStart('$foo = 42; $bar = 2; echo "Hello Boris!\n";');

// this will be passed the REPL and it's scope as arguments
// any changes to the scope can be expressed by invoking the usual
// methods on the REPL
$boris->onStart(function($worker, $scope){
  extract($scope); // we could also just access specific vars by key

  echo '$foo * $bar = ' . ($foo * $bar) . "\n";

  $worker->setLocal('name', 'Chris');
});

Above we added two hooks. The first just gets passed to eval() and leaves $foo and $bar in scope. The second uses the callback style and reads its variables from the $scope parameter, then sets variables into the REPL with setLocal().

User configuration files

If you have, things you always want to do when Boris starts, such as load useful utility functions, change the prompt or set local variable, you may create a ~/.borisrc file, which will be loaded whenever Boris starts up.

The contents of this file are just arbitrary PHP code. You are not inside the REPL itself in this file, but you have access to $boris, which is the REPL object. Here's an example ~/.borisrc that sets the prompt.

<?php

/* File: ~/.borisrc */

$boris->setPrompt('prompty> ');

Boris will also look under your current working directory for this file. If it finds one on both locations, they will both be loaded by default (not that this is customizable at the code level). If you need to execute code in the REPL itself, use hooks as documented above.

Thanks to @filp for this feature!

Customizing the output

After each expression you enter, Boris passes it through an Inspector to get a representation that is useful for debugging. The default is does some nice highlighting of the data types in the value, to make it easier to read at a glance, but you can change this behaviour.

Any object that has an inspect($variable) method may be used for this purpose.

$boris->setInspector(new BlinkInspector());

Boris comes with three alternatives out of the box:

  • \Boris\ColoredInspector, which does data-type highlighting and is the default
  • \Boris\DumpInspector, which uses a simple, but effective var_dump()
  • \Boris\ExportInspector, which uses var_export()

Note that you can change this from inside the REPL too:

boris> $this->setInspector(new \Boris\ExportInspector());
-> NULL
boris> "Test";
-> 'Test'

To further customize object output within \Boris\ColoredInspector, you may subclass and override the objectVars($value) method:

class MyInspector extends \Boris\ColoredInspector {
    public function objectVars($value) {
        if ($value instanceof User) {
            return array('user_id' => $value->getUserId());
        }

        return parent::objectVars($value);
    }
}

This overrides the default behavior of simply calling get_object_vars() on the object, allowing you to display properties that may be otherwise obfuscated behind magic methods or property visibility.

Boris doesn't display exceptions or errors when running in my app?

Boris honours your environment. If your application has error handlers installed, they will mask the error. Likewise, if an exception handler is installed, you won't see a backtrace (unless your exception handler displays it).

Since Boris is much more useful when you can see errors in the console, the best thing to do is to disable any exception/error handlers when your application is running inside of Boris.

What about PHP's interactive mode?

PHP's interactive mode does not print the result of evaluating expressions and more importantly, it exits if you type something that produces a fatal error, such as invoking a function/method that does not exist, or an uncaught exception. Boris is designed to be robust, like other REPLs, so you can experiment with things that you know may error, without losing everything.

Architecture Overview

This section of the README only applies to those curious enough to read the code. Boris is quite different to other PHP REPLs, because it deals with fatal errors (not Exceptions, fatal errors) in a special way.

Boris will only work on POSIX systems (Linux and Mac OS). This is primarily because it depends on the ability to fork, but also because it plays with signals a lot too.

Boris is made up of two parts:

  1. A REPL worker process, which receives expressions to evaluate and print
  2. A readline client, which simply takes your input, sends it to the worker and then loops

If all errors in PHP were exceptions, building a REPL would be simple. This is not the case, however. Some PHP errors are truly fatal and cannot be caught. In order to prevent such fatal errors from killing the REPL, the worker looks something like this:

for(;;) {
  $input = accept_some_input();
  if (fork_child()) {
    wait_for_child();
  } else { // inside child
    var_dump(eval($input));
    kill_parent();
  }
}

The child is forked with all current variables and resources. It evaluates the input then kills the parent, then the loop continues inside the child, waiting for the next input.

While the child is evaluating the input, the parent waits. The parent is expecting the worst—that the child will die abnormally—at which point the parent continues waiting for input and does not terminate. The state remains unchanged.

After each expression is evaluated, the worker reports back to the main process with a status code of 0 (keep running) or 1 (terminate).

The main process (readline) of Boris is much more straightforward. It takes your input, performs a (very) shallow parse on it, in order to decide if it needs to wait for further input, or evaluate the input (one statement at a time) it has received. If the worker reports back with a status code of 1, the process terminates, otherwise the next iteration of the loop is entered.

Will it work with...?

Boris depends on the following PHP features:

  • PHP >= 5.3
  • The Readline functions
  • The PCNTL functions
  • The POSIX functions

There's no chance it can work on Windows, due to the dependency on POSIX features (the code is almost entirely dependant on POSIX).

Copyright & Licensing

Boris is written and maintained by Chris Corbyn (@d11wtq). You can use the code as you see fit. See the LICENSE file for details.

vendor/*
report/*
phpunit.xml
composer.lock
language: php
php:
- 5.4
- 5.3
before_script:
- composer install --dev
{
"name": "filp/whoops",
"license": "MIT",
"description": "php error handling for cool kids",
"keywords": ["library", "error", "handling", "exception", "silex-provider", "whoops", "zf2"],
"homepage": "https://github.com/filp/whoops",
"authors": [
{
"name": "Filipe Dobreira",
"homepage": "https://github.com/filp",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"mockery/mockery": "dev-master",
"silex/silex": "1.0.*@dev"
},
"autoload": {
"psr-0": {
"Whoops": "src/"
}
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*
* Run this example file with the PHP 5.4 web server with:
*
* $ cd project_dir
* $ php -S localhost:8080
*
* and access localhost:8080/examples/example-ajax-only.php through your browser
*
* Or just run it through apache/nginx/what-have-yous as usual.
*/
namespace Whoops\Example;
use Whoops\Run;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Handler\JsonResponseHandler;
use RuntimeException;
require __DIR__ . '/../vendor/autoload.php';
$run = new Run;
// We want the error page to be shown by default, if this is a
// regular request, so that's the first thing to go into the stack:
$run->pushHandler(new PrettyPageHandler);
// Now, we want a second handler that will run before the error page,
// and immediately return an error message in JSON format, if something
// goes awry.
$jsonHandler = new JsonResponseHandler;
// Make sure it only triggers for AJAX requests:
$jsonHandler->onlyForAjaxRequests(true);
// You can also tell JsonResponseHandler to give you a full stack trace:
// $jsonHandler->addTraceToOutput(true);
// And push it into the stack:
$run->pushHandler($jsonHandler);
// That's it! Register Whoops and throw a dummy exception:
$run->register();
throw new RuntimeException("Oh fudge napkins!");
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*
* NOTE: Requires silex/silex, can be installed with composer
* within this project using the --dev flag:
*
* $ composer install --dev
*
* Run this example file with the PHP 5.4 web server with:
*
* $ cd project_dir
* $ php -S localhost:8080
*
* and access localhost:8080/examples/example-silex.php through your browser
*
* Or just run it through apache/nginx/what-have-yous as usual.
*/
require __DIR__ . '/../vendor/autoload.php';
use Whoops\Provider\Silex\WhoopsServiceProvider;
use Silex\Application;
$app = new Application;
$app['debug'] = true;
if($app['debug']) {
$app->register(new WhoopsServiceProvider);
}
$app->get('/', function() use($app) {
throw new RuntimeException("Oh no!");
});
$app->run();
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*
* Run this example file with the PHP 5.4 web server with:
*
* $ cd project_dir
* $ php -S localhost:8080
*
* and access localhost:8080/examples/example.php through your browser
*
* Or just run it through apache/nginx/what-have-yous as usual.
*/
namespace Whoops\Example;
use Whoops\Run;
use Whoops\Handler\PrettyPageHandler;
use Exception as BaseException;
require __DIR__ . '/../vendor/autoload.php';
class Exception extends BaseException {}
$run = new Run;
$handler = new PrettyPageHandler;
// Add a custom table to the layout:
$handler->addDataTable('Ice-cream I like', array(
'Chocolate' => 'yes',
'Coffee & chocolate' => 'a lot',
'Strawberry & chocolate' => 'it\'s alright',
'Vanilla' => 'ew'
));
$run->pushHandler($handler);
// Example: tag all frames inside a function with their function name
$run->pushHandler(function($exception, $inspector, $run) {
$inspector->getFrames()->map(function($frame) {
if($function = $frame->getFunction()) {
$frame->addComment("This frame is within function '$function'", 'cpt-obvious');
}
return $frame;
});
});
$run->register();
function fooBar() {
throw new Exception("Something broke!");
}
function bar()
{
fooBar();
}
bar();

#The MIT License

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.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Whoops Tests Suite">
<directory>tests/Whoops/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/Whoops/</directory>
</whitelist>
</filter>
</phpunit>

whoops

php errors for cool kids

Build Status Total Downloads Latest Stable Version


Whoops!

whoops is an error handler base/framework for PHP. Out-of-the-box, it provides a pretty error interface that helps you debug your web projects, but at heart it's a simple yet powerful stacked error handling system.

(current) Features

  • Flexible, stack-based error handling
  • Stand-alone library with (currently) no required dependencies
  • Simple API for dealing with exceptions, trace frames & their data
  • Includes a pretty rad error page for your webapp projects
  • NEW Includes the ability to open referenced files directly in your editor and IDE
  • Includes a Silex Service Provider for painless integration with Silex
  • Includes a Phalcon Service Provider for painless integration with Phalcon
  • Includes a Module for equally painless integration with Zend Framework 2
  • Easy to extend and integrate with existing libraries
  • Clean, well-structured & tested code-base (well, except pretty-template.php, for now...)

Installing

  • Install Composer and place the executable somewhere in your $PATH (for the rest of this README, I'll reference it as just composer)

  • Add filp/whoops to your project's composer.json file:

{
    "require": {
        "filp/whoops": "1.*"
    }
}
  • Install/update your dependencies
$ cd my_project
$ composer install

And you're good to go! Have a look at the example files in examples/ to get a feel for how things work. I promise it's really simple!

API Documentation

Initial API documentation of the whoops library is available here: https://github.com/filp/whoops/wiki/API-Documentation

Usage

Integrating with Silex

whoops comes packaged with a Silex Service Provider: Whoops\Provider\Silex\WhoopsServiceProvider. Using it in your existing Silex project is easy:

require 'vendor/autoload.php';

use Silex\Application;

// ... some awesome code here ...

if($app['debug']) {
    $app->register(new Whoops\Provider\Silex\WhoopsServiceProvider);
}

// ...

$app->run();

And that's about it. By default, you'll get the pretty error pages if something goes awry in your development environment, but you also have full access to the whoops library, obviously. For example, adding a new handler into your app is as simple as extending whoops:

$app['whoops'] = $app->extend('whoops', function($whoops) {
    $whoops->pushHandler(new DeleteWholeProjectHandler);
    return $whoops;
});

Integrating with Phalcon

whoops comes packaged with a Phalcon Service Provider: Whoops\Provider\Phalcon\WhoopsServiceProvider. Using it in your existing Phalcon project is easy. The provider uses the default Phalcon DI unless you pass a DI instance into the constructor.

new Whoops\Provider\Phalcon\WhoopsServiceProvider;

// --- or ---

$di = Phalcon\DI\FactoryDefault;
new Whoops\Provider\Phalcon\WhoopsServiceProvider($di);

Integrating with Laravel 4/Illuminate

If you're using Laravel 4, as of this commit to laravel/framework, you're already using Whoops! Yay!

Integrating with Laravel 3

User @hugomrdias contributed a simple guide/example to help you integrate whoops with Laravel 3's IoC container, available at:

https://gist.github.com/hugomrdias/5169713#file-start-php

Integrating with Zend Framework 2

User @zsilbi contributed a provider for ZF2 integration, available in the following location:

https://github.com/filp/whoops/tree/master/src/Whoops/Provider/Zend

Instructions:

  • Add Whoops as a module to you app (/vendor/Whoops)
  • Whoops must be the first module:
'modules' => array(
        'Whoops',
        'Application'
   )
  • Move Module.php from /Whoops/Provider/Zend/Module.php to /Whoops/Module.php
  • Use optional configurations in your controller config:
return array(
    'view_manager' => array(
        'display_not_found_reason' => true,
        'display_exceptions' => true,
        'json_exceptions' => array(
            'display' => true,
            'ajax_only' => true,
            'show_trace' => true
        )
    ),
);
  • NOTE: ob_clean(); is used to remove previous output, so you may use ob_start(); at the beginning of your app (index.php)

Opening referenced files with your favorite editor or IDE

When using the pretty error page feature, whoops comes with the ability to open referenced files directly in your IDE or editor.

<?php

use Whoops\Handler\PrettyPageHandler;

$handler = new PrettyPageHandler;
$handler->setEditor('sublime');

The following editors are currently supported by default.

  • sublime - Sublime Text 2
  • emacs - Emacs
  • textmate - Textmate
  • macvim - MacVim
  • xdebug - xdebug (uses xdebug.file_link_format)

Adding your own editor is simple:

$handler->setEditor(function($file, $line) {
    return "whatever://open?file=$file&line=$line";
});

You can add PhpStorm support with PhpStormOpener (Mac OS X only):

$handler->setEditor(
    function ($file, $line) {
        // if your development server is not local it's good to map remote files to local
        $translations = array('^' . __DIR__ => '~/Development/PhpStormOpener'); // change to your path
        
        foreach ($translations as $from => $to) {
            $file = preg_replace('#' . $from . '#', $to, $file, 1);
        }

        return "pstorm://$file:$line";
    }
);

Available Handlers

whoops currently ships with the following built-in handlers, available in the Whoops\Handler namespace:

  • PrettyPageHandler - Shows a pretty error page when something goes pants-up
  • CallbackHandler - Wraps a closure or other callable as a handler. You do not need to use this handler explicitly, whoops will automatically wrap any closure or callable you pass to Whoops\Run::pushHandler
  • JsonResponseHandler - Captures exceptions and returns information on them as a JSON string. Can be used to, for example, play nice with AJAX requests.

Contributing

If you want to give me some feedback or make a suggestion, send me a message through twitter: @imfilp

If you want to get your hands dirty, great! Here's a couple of steps/guidelines:

  • Fork/clone this repo, and update dev dependencies using Composer
$ git clone [email protected]:filp/whoops.git
$ cd whoops
$ composer install --dev
  • Create a new branch for your feature or fix
$ git checkout -b feature/flames-on-the-side
  • Add your changes & tests for those changes (in tests/).
  • Remember to stick to the existing code style as best as possible. When in doubt, follow PSR-2.
  • Send me a pull request!

If you don't want to go through all this, but still found something wrong or missing, please let me know, and/or open a new issue report so that I or others may take care of it.

Authors

This library was primarily developed by Filipe Dobreira.

A lot of awesome fixes and enhancements were also sent in by contributors, which you can find in this page right here.

Bitdeli Badge

<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use ErrorException as BaseErrorException;
/**
* Wraps ErrorException; mostly used for typing (at least now)
* to easily cleanup the stack trace of redundant info.
*/
class ErrorException extends BaseErrorException {}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use InvalidArgumentException;
use Serializable;
class Frame implements Serializable
{
/**
* @var array
*/
protected $frame;
/**
* @var string
*/
protected $fileContentsCache;
/**
* @var array[]
*/
protected $comments = array();
/**
* @param array[]
*/
public function __construct(array $frame)
{
$this->frame = $frame;
}
/**
* @param bool $shortened
* @return string|null
*/
public function getFile($shortened = false)
{
if(empty($this->frame['file'])) {
return null;
}
$file = $this->frame['file'];
// Check if this frame occurred within an eval().
// @todo: This can be made more reliable by checking if we've entered
// eval() in a previous trace, but will need some more work on the upper
// trace collector(s).
if(preg_match('/^(.*)\((\d+)\) : eval\(\)\'d code$/', $file, $matches)) {
$file = $this->frame['file'] = $matches[1];
$this->frame['line'] = (int) $matches[2];
}
if($shortened && is_string($file)) {
// Replace the part of the path that all frames have in common, and add 'soft hyphens' for smoother line-breaks.
$dirname = dirname(dirname(dirname(dirname(dirname(dirname(__DIR__))))));
$file = str_replace($dirname, "", $file);
$file = str_replace("/", "/&shy;", $file);
}
return $file;
}
/**
* @return int|null
*/
public function getLine()
{
return isset($this->frame['line']) ? $this->frame['line'] : null;
}
/**
* @return string|null
*/
public function getClass()
{
return isset($this->frame['class']) ? $this->frame['class'] : null;
}
/**
* @return string|null
*/
public function getFunction()
{
return isset($this->frame['function']) ? $this->frame['function'] : null;
}
/**
* @return array
*/
public function getArgs()
{
return isset($this->frame['args']) ? (array) $this->frame['args'] : array();
}
/**
* Returns the full contents of the file for this frame,
* if it's known.
* @return string|null
*/
public function getFileContents()
{
if($this->fileContentsCache === null && $filePath = $this->getFile()) {
// Return null if the file doesn't actually exist - this may
// happen in cases where the filename is provided as, for
// example, 'Unknown'
if(!is_file($filePath)) {
return null;
}
$this->fileContentsCache = file_get_contents($filePath);
}
return $this->fileContentsCache;
}
/**
* Adds a comment to this frame, that can be received and
* used by other handlers. For example, the PrettyPage handler
* can attach these comments under the code for each frame.
*
* An interesting use for this would be, for example, code analysis
* & annotations.
*
* @param string $comment
* @param string $context Optional string identifying the origin of the comment
*/
public function addComment($comment, $context = 'global')
{
$this->comments[] = array(
'comment' => $comment,
'context' => $context
);
}
/**
* Returns all comments for this frame. Optionally allows
* a filter to only retrieve comments from a specific
* context.
*
* @param string $filter
* @return array[]
*/
public function getComments($filter = null)
{
$comments = $this->comments;
if($filter !== null) {
$comments = array_filter($comments, function($c) use($filter) {
return $c['context'] == $filter;
});
}
return $comments;
}
/**
* Returns the array containing the raw frame data from which
* this Frame object was built
*
* @return array
*/
public function getRawFrame()
{
return $this->frame;
}
/**
* Returns the contents of the file for this frame as an
* array of lines, and optionally as a clamped range of lines.
*
* NOTE: lines are 0-indexed
*
* @example
* Get all lines for this file
* $frame->getFileLines(); // => array( 0 => '<?php', 1 => '...', ...)
* @example
* Get one line for this file, starting at line 10 (zero-indexed, remember!)
* $frame->getFileLines(9, 1); // array( 10 => '...', 11 => '...')
*
* @throws InvalidArgumentException if $length is less than or equal to 0
* @param int $start
* @param int $length
* @return string[]|null
*/
public function getFileLines($start = 0, $length = null)
{
if(null !== ($contents = $this->getFileContents())) {
$lines = explode("\n", $contents);
// Get a subset of lines from $start to $end
if($length !== null)
{
$start = (int) $start;
$length = (int) $length;
if ($start < 0) {
$start = 0;
}
if($length <= 0) {
throw new InvalidArgumentException(
"\$length($length) cannot be lower or equal to 0"
);
}
$lines = array_slice($lines, $start, $length, true);
}
return $lines;
}
}
/**
* Implements the Serializable interface, with special
* steps to also save the existing comments.
*
* @see Serializable::serialize
* @return string
*/
public function serialize()
{
$frame = $this->frame;
if(!empty($this->comments)) {
$frame['_comments'] = $this->comments;
}
return serialize($frame);
}
/**
* Unserializes the frame data, while also preserving
* any existing comment data.
*
* @see Serializable::unserialize
* @param string $serializedFrame
*/
public function unserialize($serializedFrame)
{
$frame = unserialize($serializedFrame);
if(!empty($frame['_comments'])) {
$this->comments = $frame['_comments'];
unset($frame['_comments']);
}
$this->frame = $frame;
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use Whoops\Exception\Frame;
use UnexpectedValueException;
use IteratorAggregate;
use ArrayIterator;
use Serializable;
use Countable;
/**
* Exposes a fluent interface for dealing with an ordered list
* of stack-trace frames.
*/
class FrameCollection implements IteratorAggregate, Serializable, Countable
{
/**
* @var array[]
*/
private $frames;
/**
* @param array $frames
*/
public function __construct(array $frames)
{
$this->frames = array_map(function($frame) {
return new Frame($frame);
}, $frames);
}
/**
* Filters frames using a callable, returns the same FrameCollection
*
* @param callable $callable
* @return FrameCollection
*/
public function filter($callable)
{
$this->frames = array_filter($this->frames, $callable);
return $this;
}
/**
* Map the collection of frames
*
* @param callable $callable
* @return FrameCollection
*/
public function map($callable)
{
// Contain the map within a higher-order callable
// that enforces type-correctness for the $callable
$this->frames = array_map(function($frame) use($callable) {
$frame = call_user_func($callable, $frame);
if(!$frame instanceof Frame) {
throw new UnexpectedValueException(
"Callable to " . __METHOD__ . " must return a Frame object"
);
}
return $frame;
}, $this->frames);
return $this;
}
/**
* Returns an array with all frames, does not affect
* the internal array.
*
* @todo If this gets any more complex than this,
* have getIterator use this method.
* @see FrameCollection::getIterator
* @return array
*/
public function getArray()
{
return $this->frames;
}
/**
* @see IteratorAggregate::getIterator
* @return ArrayIterator
*/
public function getIterator()
{
return new ArrayIterator($this->frames);
}
/**
* @see Countable::count
* @return int
*/
public function count()
{
return count($this->frames);
}
/**
* @see Serializable::serialize
* @return string
*/
public function serialize()
{
return serialize($this->frames);
}
/**
* @see Serializable::unserialize
* @param string $serializedFrames
*/
public function unserialize($serializedFrames)
{
$this->frames = unserialize($serializedFrames);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use Whoops\Exception\FrameCollection;
use Whoops\Exception\ErrorException;
use Exception;
class Inspector
{
/**
* @var Exception
*/
private $exception;
/**
* @var FrameCollection
*/
private $frames;
/**
* @param Exception $exception The exception to inspect
*/
public function __construct(Exception $exception)
{
$this->exception = $exception;
}
/**
* @return Exception
*/
public function getException()
{
return $this->exception;
}
/**
* @return string
*/
public function getExceptionName()
{
return get_class($this->exception);
}
/**
* @return string
*/
public function getExceptionMessage()
{
return $this->exception->getMessage();
}
/**
* Returns an iterator for the inspected exception's
* frames.
* @return FrameCollection
*/
public function getFrames()
{
if($this->frames === null) {
$frames = $this->exception->getTrace();
// If we're handling an ErrorException thrown by Whoops,
// get rid of the last frame, which matches the handleError method,
// and do not add the current exception to trace. We ensure that
// the next frame does have a filename / linenumber, though.
if($this->exception instanceof ErrorException && empty($frames[1]['line'])) {
$frames = array($this->getFrameFromError($this->exception));
} else {
$firstFrame = $this->getFrameFromException($this->exception);
array_unshift($frames, $firstFrame);
}
$this->frames = new FrameCollection($frames);
}
return $this->frames;
}
/**
* Given an exception, generates an array in the format
* generated by Exception::getTrace()
* @param Exception $exception
* @return array
*/
protected function getFrameFromException(Exception $exception)
{
return array(
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'class' => get_class($exception),
'args' => array(
$exception->getMessage()
)
);
}
/**
* Given an error, generates an array in the format
* generated by ErrorException
* @param ErrorException $exception
* @return array
*/
protected function getFrameFromError(ErrorException $exception)
{
return array(
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'class' => null,
'args' => array()
);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\Handler\Handler;
use InvalidArgumentException;
/**
* Wrapper for Closures passed as handlers. Can be used
* directly, or will be instantiated automagically by Whoops\Run
* if passed to Run::pushHandler
*/
class CallbackHandler extends Handler
{
/**
* @var callable
*/
protected $callable;
/**
* @throws InvalidArgumentException If argument is not callable
* @param callable $callable
*/
public function __construct($callable)
{
if(!is_callable($callable)) {
throw new InvalidArgumentException(
'Argument to ' . __METHOD__ . ' must be valid callable'
);
}
$this->callable = $callable;
}
/**
* @return int|null
*/
public function handle()
{
$exception = $this->getException();
$inspector = $this->getInspector();
$run = $this->getRun();
return call_user_func($this->callable, $exception, $inspector, $run);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\Handler\HandlerInterface;
use Whoops\Exception\Inspector;
use Whoops\Run;
use Exception;
/**
* Abstract implementation of a Handler.
*/
abstract class Handler implements HandlerInterface
{
/**
* Return constants that can be returned from Handler::handle
* to message the handler walker.
*/
const DONE = 0x10; // returning this is optional, only exists for
// semantic purposes
const LAST_HANDLER = 0x20;
const QUIT = 0x30;
/**
* @var Run
*/
private $run;
/**
* @var Inspector $inspector
*/
private $inspector;
/**
* @var Exception $exception
*/
private $exception;
/**
* @param Run $run
*/
public function setRun(Run $run)
{
$this->run = $run;
}
/**
* @return Run
*/
protected function getRun()
{
return $this->run;
}
/**
* @param Inspector $inspector
*/
public function setInspector(Inspector $inspector)
{
$this->inspector = $inspector;
}
/**
* @return Inspector
*/
protected function getInspector()
{
return $this->inspector;
}
/**
* @param Exception $exception
*/
public function setException(Exception $exception)
{
$this->exception = $exception;
}
/**
* @return Exception
*/
protected function getException()
{
return $this->exception;
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\Exception\Inspector;
use Whoops\Run;
use Exception;
interface HandlerInterface
{
/**
* @return int|null A handler may return nothing, or a Handler::HANDLE_* constant
*/
public function handle();
/**
* @param Run $run
*/
public function setRun(Run $run);
/**
* @param Exception $exception
*/
public function setException(Exception $exception);
/**
* @param Inspector $inspector
*/
public function setInspector(Inspector $inspector);
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\Handler\Handler;
use Whoops\Exception\Frame;
/**
* Catches an exception and converts it to a JSON
* response. Additionally can also return exception
* frames for consumption by an API.
*/
class JsonResponseHandler extends Handler
{
/**
* @var bool
*/
private $returnFrames = false;
/**
* @var bool
*/
private $onlyForAjaxRequests = false;
/**
* @param bool|null $returnFrames
* @return null|bool
*/
public function addTraceToOutput($returnFrames = null)
{
if(func_num_args() == 0) {
return $this->returnFrames;
}
$this->returnFrames = (bool) $returnFrames;
}
/**
* @param bool|null $onlyForAjaxRequests
* @return null|bool
*/
public function onlyForAjaxRequests($onlyForAjaxRequests = null)
{
if(func_num_args() == 0) {
return $this->onlyForAjaxRequests;
}
$this->onlyForAjaxRequests = (bool) $onlyForAjaxRequests;
}
/**
* Check, if possible, that this execution was triggered by an AJAX request.
*
* @return bool
*/
private function isAjaxRequest()
{
return (
!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
;
}
/**
* @return int
*/
public function handle()
{
if($this->onlyForAjaxRequests() && !$this->isAjaxRequest()) {
return Handler::DONE;
}
$exception = $this->getException();
$response = array(
'error' => array(
'type' => get_class($exception),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine()
)
);
if($this->addTraceToOutput()) {
$inspector = $this->getInspector();
$frames = $inspector->getFrames();
$frameData = array();
foreach($frames as $frame) {
/** @var Frame $frame */
$frameData[] = array(
'file' => $frame->getFile(),
'line' => $frame->getLine(),
'function' => $frame->getFunction(),
'class' => $frame->getClass(),
'args' => $frame->getArgs()
);
}
$response['error']['trace'] = $frameData;
}
echo json_encode($response);
return Handler::QUIT;
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\Handler\Handler;
use InvalidArgumentException;
class PrettyPageHandler extends Handler
{
/**
* @var string
*/
private $resourcesPath;
/**
* @var array[]
*/
private $extraTables = array();
/**
* @var string
*/
private $pageTitle = 'Whoops! There was an error.';
/**
* A string identifier for a known IDE/text editor, or a closure
* that resolves a string that can be used to open a given file
* in an editor. If the string contains the special substrings
* %file or %line, they will be replaced with the correct data.
*
* @example
* "txmt://open?url=%file&line=%line"
* @var mixed $editor
*/
protected $editor;
/**
* A list of known editor strings
* @var array
*/
protected $editors = array(
'sublime' => 'subl://open?url=file://%file&line=%line',
'textmate' => 'txmt://open?url=file://%file&line=%line',
'emacs' => 'emacs://open?url=file://%file&line=%line',
'macvim' => 'mvim://open/?url=file://%file&line=%line'
);
/**
* Constructor.
*/
public function __construct()
{
if (ini_get('xdebug.file_link_format') || extension_loaded('xdebug')) {
// Register editor using xdebug's file_link_format option.
$this->editors['xdebug'] = function($file, $line) {
return str_replace(array('%f', '%l'), array($file, $line), ini_get('xdebug.file_link_format'));
};
}
}
/**
* @return int|null
*/
public function handle()
{
// Check conditions for outputting HTML:
// @todo: make this more robust
if(php_sapi_name() === 'cli' && !isset($_ENV['whoops-test'])) {
return Handler::DONE;
}
// Get the 'pretty-template.php' template file
// @todo: this can be made more dynamic &&|| cleaned-up
if(!($resources = $this->getResourcesPath())) {
$resources = __DIR__ . '/../Resources';
}
$templateFile = "$resources/pretty-template.php";
// @todo: Make this more reliable,
// possibly by adding methods to append CSS & JS to the page
$cssFile = "$resources/pretty-page.css";
// Prepare the $v global variable that will pass relevant
// information to the template
$inspector = $this->getInspector();
$frames = $inspector->getFrames();
$v = (object) array(
'title' => $this->getPageTitle(),
'name' => explode('\\', $inspector->getExceptionName()),
'message' => $inspector->getException()->getMessage(),
'frames' => $frames,
'hasFrames' => !!count($frames),
'handler' => $this,
'handlers' => $this->getRun()->getHandlers(),
'pageStyle' => file_get_contents($cssFile),
'tables' => array(
'Server/Request Data' => $_SERVER,
'GET Data' => $_GET,
'POST Data' => $_POST,
'Files' => $_FILES,
'Cookies' => $_COOKIE,
'Session' => isset($_SESSION) ? $_SESSION: array(),
'Environment Variables' => $_ENV
)
);
$extraTables = array_map(function($table) {
return $table instanceof \Closure ? $table() : $table;
}, $this->getDataTables());
// Add extra entries list of data tables:
$v->tables = array_merge($extraTables, $v->tables);
call_user_func(function() use($templateFile, $v) {
// $e -> cleanup output, optionally preserving URIs as anchors:
$e = function($_, $allowLinks = false) {
$escaped = htmlspecialchars($_, ENT_QUOTES, 'UTF-8');
// convert URIs to clickable anchor elements:
if($allowLinks) {
$escaped = preg_replace(
'@([A-z]+?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@',
"<a href=\"$1\" target=\"_blank\">$1</a>", $escaped
);
}
return $escaped;
};
// $slug -> sluggify string (i.e: Hello world! -> hello-world)
$slug = function($_) {
$_ = str_replace(" ", "-", $_);
$_ = preg_replace('/[^\w\d\-\_]/i', '', $_);
return strtolower($_);
};
require $templateFile;
});
return Handler::QUIT;
}
/**
* Adds an entry to the list of tables displayed in the template.
* The expected data is a simple associative array. Any nested arrays
* will be flattened with print_r
* @param string $label
* @param array $data
*/
public function addDataTable($label, array $data)
{
$this->extraTables[$label] = $data;
}
/**
* Lazily adds an entry to the list of tables displayed in the table.
* The supplied callback argument will be called when the error is rendered,
* it should produce a simple associative array. Any nested arrays will
* be flattened with print_r.
*
* @throws InvalidArgumentException If $callback is not callable
* @param string $label
* @param callable $callback Callable returning an associative array
*/
public function addDataTableCallback($label, /* callable */ $callback)
{
if (!is_callable($callback)) {
throw new InvalidArgumentException('Expecting callback argument to be callable');
}
$this->extraTables[$label] = function() use ($callback) {
try {
$result = call_user_func($callback);
// Only return the result if it can be iterated over by foreach().
return is_array($result) || $result instanceof \Traversable ? $result : array();
} catch (\Exception $e) {
// Don't allow failure to break the rendering of the original exception.
return array();
}
};
}
/**
* Returns all the extra data tables registered with this handler.
* Optionally accepts a 'label' parameter, to only return the data
* table under that label.
* @param string|null $label
* @return array[]
*/
public function getDataTables($label = null)
{
if($label !== null) {
return isset($this->extraTables[$label]) ?
$this->extraTables[$label] : array();
}
return $this->extraTables;
}
/**
* Adds an editor resolver, identified by a string
* name, and that may be a string path, or a callable
* resolver. If the callable returns a string, it will
* be set as the file reference's href attribute.
*
* @example
* $run->addEditor('macvim', "mvim://open?url=file://%file&line=%line")
* @example
* $run->addEditor('remove-it', function($file, $line) {
* unlink($file);
* return "http://stackoverflow.com";
* });
* @param string $identifier
* @param string $resolver
*/
public function addEditor($identifier, $resolver)
{
$this->editors[$identifier] = $resolver;
}
/**
* Set the editor to use to open referenced files, by a string
* identifier, or a callable that will be executed for every
* file reference, with a $file and $line argument, and should
* return a string.
*
* @example
* $run->setEditor(function($file, $line) { return "file:///{$file}"; });
* @example
* $run->setEditor('sublime');
*
* @throws InvalidArgumentException If invalid argument identifier provided
* @param string|callable $editor
*/
public function setEditor($editor)
{
if(!is_callable($editor) && !isset($this->editors[$editor])) {
throw new InvalidArgumentException(
"Unknown editor identifier: $editor. Known editors:" .
implode(",", array_keys($this->editors))
);
}
$this->editor = $editor;
}
/**
* Given a string file path, and an integer file line,
* executes the editor resolver and returns, if available,
* a string that may be used as the href property for that
* file reference.
*
* @throws InvalidArgumentException If editor resolver does not return a string
* @param string $filePath
* @param int $line
* @return string|bool
*/
public function getEditorHref($filePath, $line)
{
if($this->editor === null) {
return false;
}
$editor = $this->editor;
if(is_string($editor)) {
$editor = $this->editors[$editor];
}
if(is_callable($editor)) {
$editor = call_user_func($editor, $filePath, $line);
}
// Check that the editor is a string, and replace the
// %line and %file placeholders:
if(!is_string($editor)) {
throw new InvalidArgumentException(
__METHOD__ . " should always resolve to a string; got something else instead"
);
}
$editor = str_replace("%line", rawurlencode($line), $editor);
$editor = str_replace("%file", rawurlencode($filePath), $editor);
return $editor;
}
/**
* @var string
*/
public function setPageTitle($title)
{
$this->pageTitle = (string) $title;
}
/**
* @return string
*/
public function getPageTitle()
{
return $this->pageTitle;
}
/**
* @return string
*/
public function getResourcesPath()
{
return $this->resourcesPath;
}
/**
* @throws InvalidArgumentException If argument is not a valid directory
* @param string $resourcesPath
*/
public function setResourcesPath($resourcesPath)
{
if(!is_dir($resourcesPath)) {
throw new InvalidArgumentException(
"$resourcesPath is not a valid directory"
);
}
$this->resourcesPath = $resourcesPath;
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use SimpleXMLElement;
use Whoops\Exception\Frame;
use Whoops\Handler\Handler;
/**
* Catches an exception and converts it to an XML
* response. Additionally can also return exception
* frames for consumption by an API.
*/
class XmlResponseHandler extends Handler
{
/**
* @var bool
*/
private $returnFrames = false;
/**
* @param bool|null $returnFrames
* @return null|bool
*/
public function addTraceToOutput($returnFrames = null)
{
if(func_num_args() == 0) {
return $this->returnFrames;
}
$this->returnFrames = (bool) $returnFrames;
}
/**
* @return int
*/
public function handle()
{
$exception = $this->getException();
$response = array(
'error' => array(
'type' => get_class($exception),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine()
)
);
if($this->addTraceToOutput()) {
$inspector = $this->getInspector();
$frames = $inspector->getFrames();
$frameData = array();
foreach($frames as $frame) {
/** @var Frame $frame */
$frameData[] = array(
'file' => $frame->getFile(),
'line' => $frame->getLine(),
'function' => $frame->getFunction(),
'class' => $frame->getClass(),
'args' => $frame->getArgs()
);
}
$response['error']['trace'] = array_flip($frameData);
}
echo $this->toXml($response);
return Handler::QUIT;
}
/**
* @param SimpleXMLElement $node Node to append data to, will be modified in place
* @param array|Traversable $data
* @return SimpleXMLElement The modified node, for chaining
*/
private static function addDataToNode(\SimpleXMLElement $node, $data)
{
assert('is_array($data) || $node instanceof Traversable');
foreach($data as $key => $value)
{
if (is_numeric($key))
{
// Convert the key to a valid string
$key = "unknownNode_". (string) $key;
}
// Delete any char not allowed in XML element names
$key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);
if (is_array($value))
{
$child = $node->addChild($key);
self::addDataToNode($child, $value);
}
else
{
$value = str_replace('&', '&amp;', print_r($value, true));
$node->addChild($key, $value);
}
}
return $node;
}
/**
* The main function for converting to an XML document.
*
* @param array|Traversable $data
* @return string XML
*/
private static function toXml($data)
{
assert('is_array($data) || $node instanceof Traversable');
// turn off compatibility mode as simple xml throws a wobbly if you don't.
$compatibilityMode = ini_get('zend.ze1_compatibility_mode');
if ($compatibilityMode) {
ini_set('zend.ze1_compatibility_mode', 0);
}
$node = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><root />");
$xml = self::addDataToNode($node, $data)->asXML();
if ($compatibilityMode) {
ini_set('zend.ze1_compatibility_mode', $compatibilityMode);
}
return $xml;
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Provider\Phalcon;
use Whoops\Run;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Handler\JsonResponseHandler;
use Phalcon\DI;
use Phalcon\DI\Exception;
class WhoopsServiceProvider
{
/**
* @param DI $di
*/
public function __construct(DI $di = null)
{
if (!$di) {
$di = DI::getDefault();
}
// There's only ever going to be one error page...right?
$di->setShared('whoops.pretty_page_handler', function() {
return new PrettyPageHandler;
});
// There's only ever going to be one error page...right?
$di->setShared('whoops.json_response_handler', function() {
$jsonHandler = new JsonResponseHandler;
$jsonHandler->onlyForAjaxRequests(true);
return $jsonHandler;
});
// Retrieves info on the Phalcon environment and ships it off
// to the PrettyPageHandler's data tables:
// This works by adding a new handler to the stack that runs
// before the error page, retrieving the shared page handler
// instance, and working with it to add new data tables
$phalcon_info_handler = function() use($di) {
try {
$request = $di['request'];
} catch (Exception $e) {
// This error occurred too early in the application's life
// and the request instance is not yet available.
return;
}
// Request info:
$di['whoops.pretty_page_handler']->addDataTable('Phalcon Application (Request)', array(
'URI' => $request->getScheme().'://'.$request->getServer('HTTP_HOST').$request->getServer('REQUEST_URI'),
'Request URI' => $request->getServer('REQUEST_URI'),
'Path Info' => $request->getServer('PATH_INFO'),
'Query String'=> $request->getServer('QUERY_STRING') ?: '<none>',
'HTTP Method' => $request->getMethod(),
'Script Name' => $request->getServer('SCRIPT_NAME'),
//'Base Path' => $request->getBasePath(),
//'Base URL' => $request->getBaseUrl(),
'Scheme' => $request->getScheme(),
'Port' => $request->getServer('SERVER_PORT'),
'Host' => $request->getServerName(),
));
};
$di->setShared('whoops', function() use($di, $phalcon_info_handler) {
$run = new Run;
$run->pushHandler($di['whoops.pretty_page_handler']);
$run->pushHandler($phalcon_info_handler);
$run->pushHandler($di['whoops.json_response_handler']);
return $run;
});
$di['whoops']->register();
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Provider\Silex;
use Whoops\Run;
use Whoops\Handler\PrettyPageHandler;
use Silex\ServiceProviderInterface;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use RuntimeException;
class WhoopsServiceProvider implements ServiceProviderInterface
{
/**
* @param Application $app
*/
public function register(Application $app)
{
// There's only ever going to be one error page...right?
$app['whoops.error_page_handler'] = $app->share(function() {
return new PrettyPageHandler;
});
// Retrieves info on the Silex environment and ships it off
// to the PrettyPageHandler's data tables:
// This works by adding a new handler to the stack that runs
// before the error page, retrieving the shared page handler
// instance, and working with it to add new data tables
$app['whoops.silex_info_handler'] = $app->protect(function() use($app) {
try {
/** @var Request $request */
$request = $app['request'];
} catch (RuntimeException $e) {
// This error occurred too early in the application's life
// and the request instance is not yet available.
return;
}
/** @var PrettyPageHandler $errorPageHandler */
$errorPageHandler = $app["whoops.error_page_handler"];
// General application info:
$errorPageHandler->addDataTable('Silex Application', array(
'Charset' => $app['charset'],
'Locale' => $app['locale'],
'Route Class' => $app['route_class'],
'Dispatcher Class' => $app['dispatcher_class'],
'Application Class'=> get_class($app)
));
// Request info:
$errorPageHandler->addDataTable('Silex Application (Request)', array(
'URI' => $request->getUri(),
'Request URI' => $request->getRequestUri(),
'Path Info' => $request->getPathInfo(),
'Query String'=> $request->getQueryString() ?: '<none>',
'HTTP Method' => $request->getMethod(),
'Script Name' => $request->getScriptName(),
'Base Path' => $request->getBasePath(),
'Base URL' => $request->getBaseUrl(),
'Scheme' => $request->getScheme(),
'Port' => $request->getPort(),
'Host' => $request->getHost(),
));
});
$app['whoops'] = $app->share(function() use($app) {
$run = new Run;
$run->pushHandler($app['whoops.error_page_handler']);
$run->pushHandler($app['whoops.silex_info_handler']);
return $run;
});
$app->error(array($app['whoops'], Run::EXCEPTION_HANDLER));
$app['whoops']->register();
}
/**
* @see Silex\ServiceProviderInterface::boot
*/
public function boot(Application $app) {}
}
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <[email protected]>
*/
namespace Whoops\Provider\Zend;
use Whoops\Run;
use Zend\Mvc\View\Http\ExceptionStrategy as BaseExceptionStrategy;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Application;
class ExceptionStrategy extends BaseExceptionStrategy {
protected $run;
public function __construct(Run $run) {
$this->run = $run;
return $this;
}
public function prepareExceptionViewModel(MvcEvent $event) {
// Do nothing if no error in the event
$error = $event->getError();
if (empty($error)) {
return;
}
// Do nothing if the result is a response object
$result = $event->getResult();
if ($result instanceof Response) {
return;
}
switch ($error) {
case Application::ERROR_CONTROLLER_NOT_FOUND:
case Application::ERROR_CONTROLLER_INVALID:
case Application::ERROR_ROUTER_NO_MATCH:
// Specifically not handling these
return;
case Application::ERROR_EXCEPTION:
default:
$exception = $event->getParam('exception');
if($exception) {
$response = $event->getResponse();
if (!$response || $response->getStatusCode() === 200) {
header('HTTP/1.0 500 Internal Server Error', true, 500);
}
ob_clean();
$this->run->handleException($event->getParam('exception'));
}
break;
}
}
}
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <[email protected]>
*
* Example controller configuration
*/
return array(
'view_manager' => array(
'editor' => 'sublime',
'display_not_found_reason' => true,
'display_exceptions' => true,
'json_exceptions' => array(
'display' => true,
'ajax_only' => true,
'show_trace' => true
)
),
);
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <[email protected]>
*
* The Whoops directory should be added as a module to ZF2 (/vendor/Whoops)
*
* Whoops must be added as the first module
* For example:
* 'modules' => array(
* 'Whoops',
* 'Application',
* ),
*
* This file should be moved next to Whoops/Run.php (/vendor/Whoops/Module.php)
*
*/
namespace Whoops;
use Whoops\Run;
use Whoops\Provider\Zend\ExceptionStrategy;
use Whoops\Provider\Zend\RouteNotFoundStrategy;
use Whoops\Handler\JsonResponseHandler;
use Whoops\Handler\PrettyPageHandler;
use Zend\EventManager\EventInterface;
use Zend\Console\Request as ConsoleRequest;
class Module
{
protected $run;
public function onBootstrap(EventInterface $event)
{
$prettyPageHandler = new PrettyPageHandler();
// Set editor
$config = $event->getApplication()->getServiceManager()->get('Config');
if (isset($config['view_manager']['editor'])) {
$prettyPageHandler->setEditor($config['view_manager']['editor']);
}
$this->run = new Run();
$this->run->register();
$this->run->pushHandler($prettyPageHandler);
$this->attachListeners($event);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
private function attachListeners(EventInterface $event)
{
$request = $event->getRequest();
$application = $event->getApplication();
$services = $application->getServiceManager();
$events = $application->getEventManager();
$config = $services->get('Config');
//Display exceptions based on configuration and console mode
if ($request instanceof ConsoleRequest || empty($config['view_manager']['display_exceptions']))
return;
$jsonHandler = new JsonResponseHandler();
if (!empty($config['view_manager']['json_exceptions']['show_trace'])) {
//Add trace to the JSON output
$jsonHandler->addTraceToOutput(true);
}
if (!empty($config['view_manager']['json_exceptions']['ajax_only'])) {
//Only return JSON response for AJAX requests
$jsonHandler->onlyForAjaxRequests(true);
}
if (!empty($config['view_manager']['json_exceptions']['display'])) {
//Turn on JSON handler
$this->run->pushHandler($jsonHandler);
}
//Attach the Whoops ExceptionStrategy
$exceptionStrategy = new ExceptionStrategy($this->run);
$exceptionStrategy->attach($events);
//Attach the Whoops RouteNotFoundStrategy
$routeNotFoundStrategy = new RouteNotFoundStrategy($this->run);
$routeNotFoundStrategy->attach($events);
//Detach default ExceptionStrategy
$services->get('Zend\Mvc\View\Http\ExceptionStrategy')->detach($events);
//Detach default RouteNotFoundStrategy
$services->get('Zend\Mvc\View\Http\RouteNotFoundStrategy')->detach($events);
}
}
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <[email protected]>
*/
namespace Whoops\Provider\Zend;
use Whoops\Run;
use Zend\Mvc\View\Http\RouteNotFoundStrategy as BaseRouteNotFoundStrategy;
use Zend\Mvc\MvcEvent;
use Zend\Stdlib\ResponseInterface as Response;
use Zend\View\Model\ViewModel;
class RouteNotFoundStrategy extends BaseRouteNotFoundStrategy {
protected $run;
public function __construct(Run $run) {
$this->run = $run;
}
public function prepareNotFoundViewModel(MvcEvent $e) {
$vars = $e->getResult();
if ($vars instanceof Response) {
// Already have a response as the result
return;
}
$response = $e->getResponse();
if ($response->getStatusCode() != 404) {
// Only handle 404 responses
return;
}
if (!$vars instanceof ViewModel) {
$model = new ViewModel();
if (is_string($vars)) {
$model->setVariable('message', $vars);
} else {
$model->setVariable('message', 'Page not found.');
}
} else {
$model = $vars;
if ($model->getVariable('message') === null) {
$model->setVariable('message', 'Page not found.');
}
}
// If displaying reasons, inject the reason
$this->injectNotFoundReason($model, $e);
// If displaying exceptions, inject
$this->injectException($model, $e);
// Inject controller if we're displaying either the reason or the exception
$this->injectController($model, $e);
ob_clean();
throw new \Exception($model->getVariable('message') . ' ' . $model->getVariable('reason'));
}
}
.cf:before, .cf:after {content: " ";display: table;} .cf:after {clear: both;} .cf {*zoom: 1;}
body {
font: 14px helvetica, arial, sans-serif;
color: #2B2B2B;
background-color: #D4D4D4;
padding:0;
margin: 0;
max-height: 100%;
}
a {
text-decoration: none;
}
.container{
height: 100%;
width: 100%;
position: fixed;
margin: 0;
padding: 0;
left: 0;
top: 0;
}
.branding {
position: absolute;
top: 10px;
right: 20px;
color: #777777;
font-size: 10px;
z-index: 100;
}
.branding a {
color: #CD3F3F;
}
header {
padding: 30px 20px;
color: white;
background: #272727;
box-sizing: border-box;
border-left: 5px solid #CD3F3F;
}
.exc-title {
margin: 0;
color: #616161;
text-shadow: 0 1px 2px rgba(0, 0, 0, .1);
}
.exc-title-primary { color: #CD3F3F; }
.exc-message {
font-size: 32px;
margin: 5px 0;
word-wrap: break-word;
}
.stack-container {
height: 100%;
position: relative;
}
.details-container {
height: 100%;
overflow: auto;
float: right;
width: 70%;
background: #DADADA;
}
.details {
padding: 10px;
padding-left: 5px;
border-left: 5px solid rgba(0, 0, 0, .1);
}
.frames-container {
height: 100%;
overflow: auto;
float: left;
width: 30%;
background: #FFF;
}
.frame {
padding: 14px;
background: #F3F3F3;
border-right: 1px solid rgba(0, 0, 0, .2);
cursor: pointer;
}
.frame.active {
background-color: #4288CE;
color: #F3F3F3;
box-shadow: inset -2px 0 0 rgba(255, 255, 255, .1);
text-shadow: 0 1px 0 rgba(0, 0, 0, .2);
}
.frame:not(.active):hover {
background: #BEE9EA;
}
.frame-class, .frame-function, .frame-index {
font-weight: bold;
}
.frame-index {
font-size: 11px;
color: #BDBDBD;
}
.frame-class {
color: #4288CE;
}
.active .frame-class {
color: #BEE9EA;
}
.frame-file {
font-family: consolas, monospace;
word-wrap:break-word;
}
.frame-file .editor-link {
color: #272727;
}
.frame-line {
font-weight: bold;
color: #4288CE;
}
.active .frame-line { color: #BEE9EA; }
.frame-line:before {
content: ":";
}
.frame-code {
padding: 10px;
padding-left: 5px;
background: #BDBDBD;
display: none;
border-left: 5px solid #4288CE;
}
.frame-code.active {
display: block;
}
.frame-code .frame-file {
background: #C6C6C6;
color: #525252;
text-shadow: 0 1px 0 #E7E7E7;
padding: 10px 10px 5px 10px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
border: 1px solid rgba(0, 0, 0, .1);
border-bottom: none;
box-shadow: inset 0 1px 0 #DADADA;
}
.code-block {
padding: 10px;
margin: 0;
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
}
.linenums {
margin: 0;
margin-left: 10px;
}
.frame-comments {
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
border: 1px solid rgba(0, 0, 0, .2);
border-top: none;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
padding: 5px;
font-size: 12px;
background: #404040;
}
.frame-comments.empty {
padding: 8px 15px;
}
.frame-comments.empty:before {
content: "No comments for this stack frame.";
font-style: italic;
color: #828282;
}
.frame-comment {
padding: 10px;
color: #D2D2D2;
}
.frame-comment a {
color: #BEE9EA;
font-weight: bold;
text-decoration: none;
}
.frame-comment a:hover {
color: #4bb1b1;
}
.frame-comment:not(:last-child) {
border-bottom: 1px dotted rgba(0, 0, 0, .3);
}
.frame-comment-context {
font-size: 10px;
font-weight: bold;
color: #86D2B6;
}
.data-table-container label {
font-size: 16px;
font-weight: bold;
color: #4288CE;
margin: 10px 0;
padding: 10px 0;
display: block;
margin-bottom: 5px;
padding-bottom: 5px;
border-bottom: 1px dotted rgba(0, 0, 0, .2);
}
.data-table {
width: 100%;
margin: 10px 0;
}
.data-table tbody {
font: 13px consolas, monospace;
}
.data-table thead {
display: none;
}
.data-table tr {
padding: 5px 0;
}
.data-table td:first-child {
width: 20%;
min-width: 130px;
overflow: hidden;
font-weight: bold;
color: #463C54;
padding-right: 5px;
}
.data-table td:last-child {
width: 80%;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
.data-table .empty {
color: rgba(0, 0, 0, .3);
font-style: italic;
}
.handler {
padding: 10px;
font: 14px monospace;
}
.handler.active {
color: #BBBBBB;
background: #989898;
font-weight: bold;
}
/* prettify code style
Uses the Doxy theme as a base */
pre .str, code .str { color: #BCD42A; } /* string */
pre .kwd, code .kwd { color: #4bb1b1; font-weight: bold; } /* keyword*/
pre .com, code .com { color: #888; font-weight: bold; } /* comment */
pre .typ, code .typ { color: #ef7c61; } /* type */
pre .lit, code .lit { color: #BCD42A; } /* literal */
pre .pun, code .pun { color: #fff; font-weight: bold; } /* punctuation */
pre .pln, code .pln { color: #e9e4e5; } /* plaintext */
pre .tag, code .tag { color: #4bb1b1; } /* html/xml tag */
pre .htm, code .htm { color: #dda0dd; } /* html tag */
pre .xsl, code .xsl { color: #d0a0d0; } /* xslt tag */
pre .atn, code .atn { color: #ef7c61; font-weight: normal;} /* html/xml attribute name */
pre .atv, code .atv { color: #bcd42a; } /* html/xml attribute value */
pre .dec, code .dec { color: #606; } /* decimal */
pre.prettyprint, code.prettyprint {
font-family: 'Source Code Pro', Monaco, Consolas, "Lucida Console", monospace;;
background: #333;
color: #e9e4e5;
}
pre.prettyprint {
white-space: pre-wrap;
}
pre.prettyprint a, code.prettyprint a {
text-decoration:none;
}
.linenums li {
color: #A5A5A5;
}
.linenums li.current{
background: rgba(255, 100, 100, .07);
padding-top: 4px;
padding-left: 1px;
}
.linenums li.current.active {
background: rgba(255, 100, 100, .17);
}
<?php
/**
* Template file for Whoops's pretty error output.
* Check the $v global variable (stdClass) for what's available
* to work with.
* @var stdClass $v
* @var callable $e
* @var callable $slug
*/
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo $e($v->title) ?></title>
<style><?php echo $v->pageStyle ?></style>
</head>
<body>
<div class="container">
<div class="stack-container">
<div class="frames-container cf <?php echo (!$v->hasFrames ? 'empty' : '') ?>">
<?php /* List file names & line numbers for all stack frames;
clicking these links/buttons will display the code view
for that particular frame */ ?>
<?php foreach($v->frames as $i => $frame): ?>
<?php /** @var \Whoops\Exception\Frame $frame */ ?>
<div class="frame <?php echo ($i == 0 ? 'active' : '') ?>" id="frame-line-<?php echo $i ?>">
<div class="frame-method-info">
<span class="frame-index"><?php echo (count($v->frames) - $i - 1) ?>.</span>
<span class="frame-class"><?php echo $e($frame->getClass() ?: '') ?></span>
<span class="frame-function"><?php echo $e($frame->getFunction() ?: '') ?></span>
</div>
<span class="frame-file">
<?php echo ($frame->getFile(true) ?: '<#unknown>') ?><!--
--><span class="frame-line"><?php echo (int) $frame->getLine() ?></span>
</span>
</div>
<?php endforeach ?>
</div>
<div class="details-container cf">
<header>
<div class="exception">
<h3 class="exc-title">
<?php foreach($v->name as $i => $nameSection): ?>
<?php if($i == count($v->name) - 1): ?>
<span class="exc-title-primary"><?php echo $e($nameSection) ?></span>
<?php else: ?>
<?php echo $e($nameSection) . ' \\' ?>
<?php endif ?>
<?php endforeach ?>
</h3>
<p class="exc-message">
<?php echo $e($v->message) ?>
</p>
</div>
</header>
<?php /* Display a code block for all frames in the stack.
* @todo: This should PROBABLY be done on-demand, lest
* we get 200 frames to process. */ ?>
<div class="frame-code-container <?php echo (!$v->hasFrames ? 'empty' : '') ?>">
<?php foreach($v->frames as $i => $frame): ?>
<?php /** @var \Whoops\Exception\Frame $frame */ ?>
<?php $line = $frame->getLine(); ?>
<div class="frame-code <?php echo ($i == 0 ) ? 'active' : '' ?>" id="frame-code-<?php echo $i ?>">
<div class="frame-file">
<?php $filePath = $frame->getFile(); ?>
<?php if($filePath && $editorHref = $v->handler->getEditorHref($filePath, (int) $line)): ?>
Open:
<a href="<?php echo $editorHref ?>" class="editor-link">
<strong><?php echo $e($filePath ?: '<#unknown>') ?></strong>
</a>
<?php else: ?>
<strong><?php echo $e($filePath ?: '<#unknown>') ?></strong>
<?php endif ?>
</div>
<?php
// Do nothing if there's no line to work off
if($line !== null):
// the $line is 1-indexed, we nab -1 where needed to account for this
$range = $frame->getFileLines($line - 8, 10);
$range = array_map(function($line){ return empty($line) ? ' ' : $line;}, $range);
$start = key($range) + 1;
$code = join("\n", $range);
?>
<pre class="code-block prettyprint linenums:<?php echo $start ?>"><?php echo $e($code) ?></pre>
<?php endif ?>
<?php
// Append comments for this frame */
$comments = $frame->getComments();
?>
<div class="frame-comments <?php echo empty($comments) ? 'empty' : '' ?>">
<?php foreach($comments as $commentNo => $comment): ?>
<?php
extract($comment)
/**
* @var string $context
* @var string $comment
*/
?>
<div class="frame-comment" id="comment-<?php echo $i . '-' . $commentNo ?>">
<span class="frame-comment-context"><?php echo $e($context) ?></span>
<?php echo $e($comment, true) ?>
</div>
<?php endforeach ?>
</div>
</div>
<?php endforeach ?>
</div>
<?php /* List data-table values, i.e: $_SERVER, $_GET, .... */ ?>
<div class="details">
<div class="data-table-container" id="data-tables">
<?php foreach($v->tables as $label => $data): ?>
<div class="data-table" id="sg-<?php echo $e($slug($label)) ?>">
<label><?php echo $e($label) ?></label>
<?php if(!empty($data)): ?>
<table class="data-table">
<thead>
<tr>
<td class="data-table-k">Key</td>
<td class="data-table-v">Value</td>
</tr>
</thead>
<?php foreach($data as $k => $value): ?>
<tr>
<td><?php echo $e($k) ?></td>
<td><?php echo $e(print_r($value, true)) ?></td>
</tr>
<?php endforeach ?>
</table>
<?php else: ?>
<span class="empty">empty</span>
<?php endif ?>
</div>
<?php endforeach ?>
</div>
<?php /* List registered handlers, in order of first to last registered */ ?>
<div class="data-table-container" id="handlers">
<label>Registered Handlers</label>
<?php foreach($v->handlers as $i => $handler): ?>
<div class="handler <?php echo ($handler === $v->handler) ? 'active' : ''?>">
<?php echo $i ?>. <?php echo $e(get_class($handler)) ?>
</div>
<?php endforeach ?>
</div>
</div> <!-- .details -->
</div>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/prettify/r224/prettify.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
prettyPrint();
var $frameLines = $('[id^="frame-line-"]');
var $activeLine = $('.frames-container .active');
var $activeFrame = $('.active[id^="frame-code-"]').show();
var $container = $('.details-container');
var headerHeight = $('header').css('height');
var highlightCurrentLine = function() {
// Highlight the active and neighboring lines for this frame:
var activeLineNumber = +($activeLine.find('.frame-line').text());
var $lines = $activeFrame.find('.linenums li');
var firstLine = +($lines.first().val());
$($lines[activeLineNumber - firstLine - 1]).addClass('current');
$($lines[activeLineNumber - firstLine]).addClass('current active');
$($lines[activeLineNumber - firstLine + 1]).addClass('current');
};
// Highlight the active for the first frame:
highlightCurrentLine();
$frameLines.click(function() {
var $this = $(this);
var id = /frame\-line\-([\d]*)/.exec($this.attr('id'))[1];
var $codeFrame = $('#frame-code-' + id);
if($codeFrame) {
$activeLine.removeClass('active');
$activeFrame.removeClass('active');
$this.addClass('active');
$codeFrame.addClass('active');
$activeLine = $this;
$activeFrame = $codeFrame;
highlightCurrentLine();
$container.animate({ scrollTop: headerHeight }, "fast");
}
});
});
</script>
</body>
</html>
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops;
use Whoops\Handler\HandlerInterface;
use Whoops\Handler\Handler;
use Whoops\Handler\CallbackHandler;
use Whoops\Exception\Inspector;
use Whoops\Exception\ErrorException;
use InvalidArgumentException;
use Exception;
class Run
{
const EXCEPTION_HANDLER = "handleException";
const ERROR_HANDLER = "handleError";
const SHUTDOWN_HANDLER = "handleShutdown";
protected $isRegistered;
protected $allowQuit = true;
protected $sendOutput = true;
protected $sendHttpCode = 500;
/**
* @var HandlerInterface[]
*/
protected $handlerStack = array();
protected $silencedPatterns = array();
/**
* Pushes a handler to the end of the stack
*
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
* @param Callable|HandlerInterface $handler
* @return Run
*/
public function pushHandler($handler)
{
if(is_callable($handler)) {
$handler = new CallbackHandler($handler);
}
if(!$handler instanceof HandlerInterface) {
throw new InvalidArgumentException(
"Argument to " . __METHOD__ . " must be a callable, or instance of"
. "Whoops\\Handler\\HandlerInterface"
);
}
$this->handlerStack[] = $handler;
return $this;
}
/**
* Removes the last handler in the stack and returns it.
* Returns null if there"s nothing else to pop.
* @return null|HandlerInterface
*/
public function popHandler()
{
return array_pop($this->handlerStack);
}
/**
* Returns an array with all handlers, in the
* order they were added to the stack.
* @return array
*/
public function getHandlers()
{
return $this->handlerStack;
}
/**
* Clears all handlers in the handlerStack, including
* the default PrettyPage handler.
* @return Run
*/
public function clearHandlers()
{
$this->handlerStack = array();
return $this;
}
/**
* @param Exception $exception
* @return Inspector
*/
protected function getInspector(Exception $exception)
{
return new Inspector($exception);
}
/**
* Registers this instance as an error handler.
* @return Run
*/
public function register()
{
if(!$this->isRegistered) {
// Workaround PHP bug 42098
// https://bugs.php.net/bug.php?id=42098
class_exists("\\Whoops\\Exception\\ErrorException");
class_exists("\\Whoops\\Exception\\FrameCollection");
class_exists("\\Whoops\\Exception\\Frame");
class_exists("\\Whoops\\Exception\\Inspector");
set_error_handler(array($this, self::ERROR_HANDLER));
set_exception_handler(array($this, self::EXCEPTION_HANDLER));
register_shutdown_function(array($this, self::SHUTDOWN_HANDLER));
$this->isRegistered = true;
}
return $this;
}
/**
* Unregisters all handlers registered by this Whoops\Run instance
* @return Run
*/
public function unregister()
{
if($this->isRegistered) {
restore_exception_handler();
restore_error_handler();
$this->isRegistered = false;
}
return $this;
}
/**
* Should Whoops allow Handlers to force the script to quit?
* @param bool|int $exit
* @return bool
*/
public function allowQuit($exit = null)
{
if(func_num_args() == 0) {
return $this->allowQuit;
}
return $this->allowQuit = (bool) $exit;
}
/**
* Silence particular errors in particular files
* @param array|string $patterns List or a single regex pattern to match
* @param integer $levels Defaults to E_STRICT | E_DEPRECATED
* @return \Whoops\Run
*/
public function silenceErrorsInPaths($patterns, $levels = 10240)
{
$this->silencedPatterns = array_merge(
$this->silencedPatterns,
array_map(
function ($pattern) use ($levels) {
return array(
"pattern" => $pattern,
"levels" => $levels,
);
},
(array) $patterns
)
);
return $this;
}
/*
* Should Whoops send HTTP error code to the browser if possible?
* Whoops will by default send HTTP code 500, but you may wish to
* use 502, 503, or another 5xx family code.
*
* @param bool|int $code
* @return bool
*/
public function sendHttpCode($code = null)
{
if(func_num_args() == 0) {
return $this->sendHttpCode;
}
if(!$code) {
return $this->sendHttpCode = false;
}
if($code === true) {
$code = 500;
}
if ($code < 400 || 600 <= $code) {
throw new InvalidArgumentException(
"Invalid status code '$code', must be 4xx or 5xx"
);
}
return $this->sendHttpCode = $code;
}
/**
* Should Whoops push output directly to the client?
* If this is false, output will be returned by handleException
* @param bool|int $send
* @return bool
*/
public function writeToOutput($send = null)
{
if(func_num_args() == 0) {
return $this->sendOutput;
}
return $this->sendOutput = (bool) $send;
}
/**
* Handles an exception, ultimately generating a Whoops error
* page.
*
* @param Exception $exception
* @return string Output generated by handlers
*/
public function handleException(Exception $exception)
{
// Walk the registered handlers in the reverse order
// they were registered, and pass off the exception
$inspector = $this->getInspector($exception);
// Capture output produced while handling the exception,
// we might want to send it straight away to the client,
// or return it silently.
ob_start();
// Just in case there are no handlers:
$handlerResponse = null;
for($i = count($this->handlerStack) - 1; $i >= 0; $i--) {
$handler = $this->handlerStack[$i];
$handler->setRun($this);
$handler->setInspector($inspector);
$handler->setException($exception);
$handlerResponse = $handler->handle($exception);
if(in_array($handlerResponse, array(Handler::LAST_HANDLER, Handler::QUIT))) {
// The Handler has handled the exception in some way, and
// wishes to quit execution (Handler::QUIT), or skip any
// other handlers (Handler::LAST_HANDLER). If $this->allowQuit
// is false, Handler::QUIT behaves like Handler::LAST_HANDLER
break;
}
}
$output = ob_get_clean();
// If we're allowed to, send output generated by handlers directly
// to the output, otherwise, and if the script doesn't quit, return
// it so that it may be used by the caller
if($this->writeToOutput()) {
// @todo Might be able to clean this up a bit better
// If we're going to quit execution, cleanup all other output
// buffers before sending our own output:
if($handlerResponse == Handler::QUIT && $this->allowQuit()) {
while (ob_get_level() > 0) ob_end_clean();
}
if($this->sendHttpCode() && isset($_SERVER["REQUEST_URI"]) && !headers_sent()) {
$httpCode = $this->sendHttpCode();
if (function_exists('http_response_code')) {
http_response_code($httpCode);
} else {
// http_response_code is added in 5.4.
// For compatibility with 5.3 we use the third argument in header call
// First argument must be a real header.
// If it is empty, PHP will ignore the third argument.
// If it is invalid, such as a single space, Apache will handle it well,
// but the PHP development server will hang.
// Setting a full status line would require us to hardcode
// string values for all different status code, and detect the protocol.
// which is an extra error-prone complexity.
header('X-Ignore-This: 1', true, $httpCode);
}
}
echo $output;
}
// Handlers are done! Check if we got here because of Handler::QUIT
// ($handlerResponse will be the response from the last queried handler)
// and if so, try to quit execution.
if($handlerResponse == Handler::QUIT && $this->allowQuit()) {
exit;
}
return $output;
}
/**
* Converts generic PHP errors to \ErrorException
* instances, before passing them off to be handled.
*
* This method MUST be compatible with set_error_handler.
*
* @param int $level
* @param string $message
* @param string $file
* @param int $line
*
* @return bool
*/
public function handleError($level, $message, $file = null, $line = null)
{
if ($level & error_reporting()) {
foreach ($this->silencedPatterns as $entry) {
$pathMatches = (bool) preg_match($entry["pattern"], $file);
$levelMatches = $level & $entry["levels"];
if ($pathMatches && $levelMatches) {
// Ignore the error, abort handling
return true;
}
}
$exception = new ErrorException($message, $level, 0, $file, $line);
if ($this->canThrowExceptions) {
throw $exception;
} else {
$this->handleException($exception);
}
}
}
/**
* Special case to deal with Fatal errors and the like.
*/
public function handleShutdown()
{
// If we reached this step, we are in shutdown handler.
// An exception thrown in a shutdown handler will not be propagated
// to the exception handler. Pass that information along.
$this->canThrowExceptions = false;
$error = error_get_last();
if ($error && $this->isLevelFatal($error['type'])) {
// If there was a fatal error,
// it was not handled in handleError yet.
$this->handleError(
$error['type'],
$error['message'],
$error['file'],
$error['line']
);
}
}
/**
* In certain scenarios, like in shutdown handler, we can not throw exceptions
* @var boolean
*/
private $canThrowExceptions = true;
private static function isLevelFatal($level)
{
return in_array(
$level,
array(
E_ERROR,
E_PARSE,
E_CORE_ERROR,
E_CORE_WARNING,
E_COMPILE_ERROR,
E_COMPILE_WARNING
)
);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*
* Bootstraper for PHPUnit tests.
*/
error_reporting(E_ALL | E_STRICT);
$_ENV['whoops-test'] = true;
$loader = require_once __DIR__ . '/../vendor/autoload.php';
$loader->add('Whoops\\', __DIR__);
<?php
// Line 2
// Line 3
// Line 4
// Line 5
// Line 6
// Line 7
// Line 8
// Line 9
// Line 10
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use Whoops\Exception\FrameCollection;
use Whoops\TestCase;
use Mockery as m;
class FrameCollectionTest extends TestCase
{
/**
* Stupid little counter for tagging frames
* with a unique but predictable id
* @var int
*/
private $frameIdCounter = 0;
/**
* @return array
*/
public function getFrameData()
{
$id = ++$this->frameIdCounter;
return array(
'file' => __DIR__ . '/../../fixtures/frame.lines-test.php',
'line' => $id,
'function' => 'test-' . $id,
'class' => 'MyClass',
'args' => array(true, 'hello')
);
}
/**
* @param int $total
* @return array
*/
public function getFrameDataList($total)
{
$total = max((int) $total, 1);
$self = $this;
$frames = array_map(function() use($self) {
return $self->getFrameData();
}, range(1, $total));
return $frames;
}
/**
* @param array $frames
* @return Whoops\Exception\FrameCollection
*/
private function getFrameCollectionInstance($frames = null)
{
if($frames === null) {
$frames = $this->getFrameDataList(10);
}
return new FrameCollection($frames);
}
/**
* @covers Whoops\Exception\FrameCollection::filter
* @covers Whoops\Exception\FrameCollection::count
*/
public function testFilterFrames()
{
$frames = $this->getFrameCollectionInstance();
// Filter out all frames with a line number under 6
$frames->filter(function($frame) {
return $frame->getLine() <= 5;
});
$this->assertCount(5, $frames);
}
/**
* @covers Whoops\Exception\FrameCollection::map
*/
public function testMapFrames()
{
$frames = $this->getFrameCollectionInstance();
// Filter out all frames with a line number under 6
$frames->map(function($frame) {
$frame->addComment("This is cool", "test");
return $frame;
});
$this->assertCount(10, $frames);
}
/**
* @covers Whoops\Exception\FrameCollection::map
* @expectedException UnexpectedValueException
*/
public function testMapFramesEnforceType()
{
$frames = $this->getFrameCollectionInstance();
// Filter out all frames with a line number under 6
$frames->map(function($frame) {
return "bajango";
});
}
/**
* @covers Whoops\Exception\FrameCollection::getArray
*/
public function testGetArray()
{
$frames = $this->getFrameCollectionInstance();
$frames = $frames->getArray();
$this->assertCount(10, $frames);
foreach($frames as $frame) {
$this->assertInstanceOf('Whoops\\Exception\\Frame', $frame);
}
}
/**
* @covers Whoops\Exception\FrameCollection::getIterator
*/
public function testCollectionIsIterable()
{
$frames = $this->getFrameCollectionInstance();
foreach($frames as $frame) {
$this->assertInstanceOf('Whoops\\Exception\\Frame', $frame);
}
}
/**
* @covers Whoops\Exception\FrameCollection::serialize
* @covers Whoops\Exception\FrameCollection::unserialize
*/
public function testCollectionIsSerializable()
{
$frames = $this->getFrameCollectionInstance();
$serializedFrames = serialize($frames);
$newFrames = unserialize($serializedFrames);
foreach($newFrames as $frame) {
$this->assertInstanceOf('Whoops\\Exception\\Frame', $frame);
}
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use Whoops\Exception\Frame;
use Whoops\TestCase;
use Mockery as m;
class FrameTest extends TestCase
{
/**
* @return array
*/
private function getFrameData()
{
return array(
'file' => __DIR__ . '/../../fixtures/frame.lines-test.php',
'line' => 0,
'function' => 'test',
'class' => 'MyClass',
'args' => array(true, 'hello')
);
}
/**
* @param array $data
* @return Frame
*/
private function getFrameInstance($data = null)
{
if($data === null) {
$data = $this->getFrameData();
}
return new Frame($data);
}
/**
* @covers Whoops\Exception\Frame::getFile
*/
public function testGetFile()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$this->assertEquals($frame->getFile(), $data['file']);
}
/**
* @covers Whoops\Exception\Frame::getLine
*/
public function testGetLine()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$this->assertEquals($frame->getLine(), $data['line']);
}
/**
* @covers Whoops\Exception\Frame::getClass
*/
public function testGetClass()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$this->assertEquals($frame->getClass(), $data['class']);
}
/**
* @covers Whoops\Exception\Frame::getFunction
*/
public function testGetFunction()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$this->assertEquals($frame->getFunction(), $data['function']);
}
/**
* @covers Whoops\Exception\Frame::getArgs
*/
public function testGetArgs()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$this->assertEquals($frame->getArgs(), $data['args']);
}
/**
* @covers Whoops\Exception\Frame::getFileContents
*/
public function testGetFileContents()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$this->assertEquals($frame->getFileContents(), file_get_contents($data['file']));
}
/**
* @covers Whoops\Exception\Frame::getFileLines
*/
public function testGetFileLines()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$lines = explode("\n", $frame->getFileContents());
$this->assertEquals($frame->getFileLines(), $lines);
}
/**
* @covers Whoops\Exception\Frame::getFileLines
*/
public function testGetFileLinesRange()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance($data);
$lines = $frame->getFileLines(0, 3);
$this->assertEquals($lines[0], '<?php');
$this->assertEquals($lines[1], '// Line 2');
$this->assertEquals($lines[2], '// Line 3');
}
/**
* @covers Whoops\Exception\Frame::addComment
* @covers Whoops\Exception\Frame::getComments
*/
public function testGetComments()
{
$frame = $this->getFrameInstance();
$testComments = array(
'Dang, yo!',
'Errthangs broken!',
'Dayumm!'
);
$frame->addComment($testComments[0]);
$frame->addComment($testComments[1]);
$frame->addComment($testComments[2]);
$comments = $frame->getComments();
$this->assertCount(3, $comments);
$this->assertEquals($comments[0]['comment'], $testComments[0]);
$this->assertEquals($comments[1]['comment'], $testComments[1]);
$this->assertEquals($comments[2]['comment'], $testComments[2]);
}
/**
* @covers Whoops\Exception\Frame::addComment
* @covers Whoops\Exception\Frame::getComments
*/
public function testGetFilteredComments()
{
$frame = $this->getFrameInstance();
$testComments = array(
array('Dang, yo!', 'test'),
array('Errthangs broken!', 'test'),
'Dayumm!'
);
$frame->addComment($testComments[0][0], $testComments[0][1]);
$frame->addComment($testComments[1][0], $testComments[1][1]);
$frame->addComment($testComments[2][0], $testComments[2][1]);
$comments = $frame->getComments('test');
$this->assertCount(2, $comments);
$this->assertEquals($comments[0]['comment'], $testComments[0][0]);
$this->assertEquals($comments[1]['comment'], $testComments[1][0]);
}
/**
* @covers Whoops\Exception\Frame::serialize
* @covers Whoops\Exception\Frame::unserialize
*/
public function testFrameIsSerializable()
{
$data = $this->getFrameData();
$frame = $this->getFrameInstance();
$commentText = "Gee I hope this works";
$commentContext = "test";
$frame->addComment($commentText, $commentContext);
$serializedFrame = serialize($frame);
$newFrame = unserialize($serializedFrame);
$this->assertInstanceOf('Whoops\\Exception\\Frame', $newFrame);
$this->assertEquals($newFrame->getFile(), $data['file']);
$this->assertEquals($newFrame->getLine(), $data['line']);
$comments = $newFrame->getComments();
$this->assertCount(1, $comments);
$this->assertEquals($comments[0]["comment"], $commentText);
$this->assertEquals($comments[0]["context"], $commentContext);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use Whoops\Exception\Inspector;
use Whoops\TestCase;
use RuntimeException;
use Exception;
use Mockery as m;
class InspectorTest extends TestCase
{
/**
* @param string $message
* @return Exception
*/
protected function getException($message = null)
{
return m::mock('Exception', array($message));
}
/**
* @param Exception $exception|null
* @return Whoops\Exception\Inspector
*/
protected function getInspectorInstance(Exception $exception = null)
{
return new Inspector($exception);
}
/**
* @covers Whoops\Exception\Inspector::getExceptionName
*/
public function testReturnsCorrectExceptionName()
{
$exception = $this->getException();
$inspector = $this->getInspectorInstance($exception);
$this->assertEquals(get_class($exception), $inspector->getExceptionName());
}
/**
* @covers Whoops\Exception\Inspector::__construct
* @covers Whoops\Exception\Inspector::getException
*/
public function testExceptionIsStoredAndReturned()
{
$exception = $this->getException();
$inspector = $this->getInspectorInstance($exception);
$this->assertSame($exception, $inspector->getException());
}
/**
* @covers Whoops\Exception\Inspector::getFrames
*/
public function testGetFramesReturnsCollection()
{
$exception = $this->getException();
$inspector = $this->getInspectorInstance($exception);
$this->assertInstanceOf('Whoops\\Exception\\FrameCollection', $inspector->getFrames());
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\TestCase;
use Whoops\Handler\JsonResponseHandler;
use RuntimeException;
class JsonResponseHandlerTest extends TestCase
{
/**
* @return Whoops\Handler\JsonResponseHandler
*/
private function getHandler()
{
return new JsonResponseHandler;
}
/**
* @return RuntimeException
*/
public function getException($message = 'test message')
{
return new RuntimeException($message);
}
/**
* @param bool $withTrace
* @return array
*/
private function getJsonResponseFromHandler($withTrace = false)
{
$handler = $this->getHandler();
$handler->addTraceToOutput($withTrace);
$run = $this->getRunInstance();
$run->pushHandler($handler);
$run->register();
$exception = $this->getException();
ob_start();
$run->handleException($exception);
$json = json_decode(ob_get_clean(), true);
// Check that the json response is parse-able:
$this->assertEquals(json_last_error(), JSON_ERROR_NONE);
return $json;
}
/**
* @covers Whoops\Handler\JsonResponseHandler::addTraceToOutput
* @covers Whoops\Handler\JsonResponseHandler::handle
*/
public function testReturnsWithoutFrames()
{
$json = $this->getJsonResponseFromHandler($withTrace = false);
// Check that the response has the expected keys:
$this->assertArrayHasKey('error', $json);
$this->assertArrayHasKey('type', $json['error']);
$this->assertArrayHasKey('file', $json['error']);
$this->assertArrayHasKey('line', $json['error']);
// Check the field values:
$this->assertEquals($json['error']['file'], __FILE__);
$this->assertEquals($json['error']['message'], 'test message');
$this->assertEquals($json['error']['type'], get_class($this->getException()));
// Check that the trace is NOT returned:
$this->assertArrayNotHasKey('trace', $json['error']);
}
/**
* @covers Whoops\Handler\JsonResponseHandler::addTraceToOutput
* @covers Whoops\Handler\JsonResponseHandler::handle
*/
public function testReturnsWithFrames()
{
$json = $this->getJsonResponseFromHandler($withTrace = true);
// Check that the trace is returned:
$this->assertArrayHasKey('trace', $json['error']);
// Check that a random frame has the expected fields
$traceFrame = reset($json['error']['trace']);
$this->assertArrayHasKey('file', $traceFrame);
$this->assertArrayHasKey('line', $traceFrame);
$this->assertArrayHasKey('function', $traceFrame);
$this->assertArrayHasKey('class', $traceFrame);
$this->assertArrayHasKey('args', $traceFrame);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\TestCase;
use Whoops\Handler\PrettyPageHandler;
use RuntimeException;
use InvalidArgumentException;
class PrettyPageHandlerTest extends TestCase
{
/**
* @return Whoops\Handler\JsonResponseHandler
*/
private function getHandler()
{
return new PrettyPageHandler;
}
/**
* @return RuntimeException
*/
public function getException()
{
return new RuntimeException;
}
/**
* Test that PrettyPageHandle handles the template without
* any errors.
* @covers Whoops\Handler\PrettyPageHandler::handle
*/
public function testHandleWithoutErrors()
{
$run = $this->getRunInstance();
$handler = $this->getHandler();
$run->pushHandler($handler);
ob_start();
$run->handleException($this->getException());
ob_get_clean();
// Reached the end without errors
$this->assertTrue(true);
}
/**
* @covers Whoops\Handler\PrettyPageHandler::setPageTitle
* @covers Whoops\Handler\PrettyPageHandler::getPageTitle
*/
public function testGetSetPageTitle()
{
$title = 'My Cool Error Handler';
$handler = $this->getHandler();
$handler->setPageTitle($title);
$this->assertEquals($title, $handler->getPagetitle());
}
/**
* @covers Whoops\Handler\PrettyPageHandler::setResourcesPath
* @covers Whoops\Handler\PrettyPageHandler::getResourcesPath
*/
public function testGetSetResourcesPath()
{
$path = __DIR__; // guaranteed to be valid!
$handler = $this->getHandler();
$handler->setResourcesPath($path);
$this->assertEquals($path, $handler->getResourcesPath());
}
/**
* @covers Whoops\Handler\PrettyPageHandler::setResourcesPath
* @expectedException InvalidArgumentException
*/
public function testSetInvalidResourcesPath()
{
$path = __DIR__ . '/ZIMBABWE'; // guaranteed to be invalid!
$this->getHandler()->setResourcesPath($path);
}
/**
* @covers Whoops\Handler\PrettyPageHandler::getDataTables
* @covers Whoops\Handler\PrettyPageHandler::addDataTable
*/
public function testGetSetDataTables()
{
$handler = $this->getHandler();
// should have no tables by default:
$this->assertEmpty($handler->getDataTables());
$tableOne = array(
'ice' => 'cream',
'ice-ice' => 'baby'
);
$tableTwo = array(
'dolan' =>'pls',
'time' => time()
);
$handler->addDataTable('table 1', $tableOne);
$handler->addDataTable('table 2', $tableTwo);
// should contain both tables:
$tables = $handler->getDataTables();
$this->assertCount(2, $tables);
$this->assertEquals($tableOne, $tables['table 1']);
$this->assertEquals($tableTwo, $tables['table 2']);
// should contain only table 1
$this->assertEquals($tableOne, $handler->getDataTables('table 1'));
// should return an empty table:
$this->assertEmpty($handler->getDataTables('ZIMBABWE!'));
}
/**
* @covers Whoops\Handler\PrettyPageHandler::getDataTables
* @covers Whoops\Handler\PrettyPageHandler::addDataTableCallback
*/
public function testSetCallbackDataTables()
{
$handler = $this->getHandler();
$this->assertEmpty($handler->getDataTables());
$table1 = function() {
return array(
'hammer' => 'time',
'foo' => 'bar',
);
};
$expected1 = array('hammer' => 'time', 'foo' => 'bar');
$table2 = function() use ($expected1) {
return array(
'another' => 'table',
'this' => $expected1,
);
};
$expected2 = array('another' => 'table', 'this' => $expected1);
$table3 = create_function('', 'return array("oh my" => "how times have changed!");');
$expected3 = array('oh my' => 'how times have changed!');
// Sanity check, make sure expected values really are correct.
$this->assertSame($expected1, $table1());
$this->assertSame($expected2, $table2());
$this->assertSame($expected3, $table3());
$handler->addDataTableCallback('table1', $table1);
$handler->addDataTableCallback('table2', $table2);
$handler->addDataTableCallback('table3', $table3);
$tables = $handler->getDataTables();
$this->assertCount(3, $tables);
// Supplied callable is wrapped in a closure
$this->assertInstanceOf('Closure', $tables['table1']);
$this->assertInstanceOf('Closure', $tables['table2']);
$this->assertInstanceOf('Closure', $tables['table3']);
// Run each wrapped callable and check results against expected output.
$this->assertEquals($expected1, $tables['table1']());
$this->assertEquals($expected2, $tables['table2']());
$this->assertEquals($expected3, $tables['table3']());
$this->assertSame($tables['table1'], $handler->getDataTables('table1'));
$this->assertSame($expected1, call_user_func($handler->getDataTables('table1')));
}
/**
* @covers Whoops\Handler\PrettyPageHandler::setEditor
* @covers Whoops\Handler\PrettyPageHandler::getEditorHref
*/
public function testSetEditorSimple()
{
$handler = $this->getHandler();
$handler->setEditor('sublime');
$this->assertEquals(
$handler->getEditorHref('/foo/bar.php', 10),
'subl://open?url=file://%2Ffoo%2Fbar.php&line=10'
);
$this->assertEquals(
$handler->getEditorHref('/foo/with space?.php', 2324),
'subl://open?url=file://%2Ffoo%2Fwith%20space%3F.php&line=2324'
);
$this->assertEquals(
$handler->getEditorHref('/foo/bar/with-dash.php', 0),
'subl://open?url=file://%2Ffoo%2Fbar%2Fwith-dash.php&line=0'
);
}
/**
* @covers Whoops\Handler\PrettyPageHandler::setEditor
* @covers Whoops\Handler\PrettyPageHandler::getEditorHref
*/
public function testSetEditorCallable()
{
$handler = $this->getHandler();
$handler->setEditor(function($file, $line) {
$file = rawurlencode($file);
$line = rawurlencode($line);
return "http://google.com/search/?q=$file:$line";
});
$this->assertEquals(
$handler->getEditorHref('/foo/bar.php', 10),
'http://google.com/search/?q=%2Ffoo%2Fbar.php:10'
);
}
/**
* @covers Whoops\Handler\PrettyPageHandler::setEditor
* @covers Whoops\Handler\PrettyPageHandler::addEditor
* @covers Whoops\Handler\PrettyPageHandler::getEditorHref
*/
public function testAddEditor()
{
$handler = $this->getHandler();
$handler->addEditor('test-editor', function($file, $line) {
return "cool beans $file:$line";
});
$handler->setEditor('test-editor');
$this->assertEquals(
$handler->getEditorHref('hello', 20),
'cool beans hello:20'
);
}
public function testEditorXdebug()
{
$originalValue = ini_get('xdebug.file_link_format');
ini_set('xdebug.file_link_format', '%f:%l');
$handler = $this->getHandler();
$handler->setEditor('xdebug');
$this->assertEquals(
'/foo/bar.php:10',
$handler->getEditorHref('/foo/bar.php', 10)
);
ini_set('xdebug.file_link_format', 'subl://open?url=%f&line=%l');
// xdebug doesn't do any URL encoded, matching that behaviour.
$this->assertEquals(
'subl://open?url=/foo/with space?.php&line=2324',
$handler->getEditorHref('/foo/with space?.php', 2324)
);
ini_set('xdebug.file_link_format', $originalValue);
}
}
<?php
/**
* Whoops - php errors for cool kids
*/
namespace Whoops\Handler;
use Whoops\TestCase;
use Whoops\Handler\XmlResponseHandler;
use RuntimeException;
class XmlResponseHandlerTest extends TestCase
{
public function testSimpleValid()
{
$handler = new XmlResponseHandler;
$run = $this->getRunInstance();
$run->pushHandler($handler);
$run->register();
ob_start();
$run->handleException($this->getException());
$data = ob_get_clean();
$this->assertTrue($this->isValidXml($data));
return simplexml_load_string($data);
}
/**
* @depends testSimpleValid
*/
public function testSimpleValidFile(\SimpleXMLElement $xml)
{
$this->checkField($xml, 'file', $this->getException()->getFile());
}
/**
* @depends testSimpleValid
*/
public function testSimpleValidLine(\SimpleXMLElement $xml)
{
$this->checkField($xml, 'line', (string) $this->getException()->getLine());
}
/**
* @depends testSimpleValid
*/
public function testSimpleValidType(\SimpleXMLElement $xml)
{
$this->checkField($xml, 'type', get_class($this->getException()));
}
/**
* Helper for testSimpleValid*
*/
private function checkField(\SimpleXMLElement $xml, $field, $value)
{
$list = $xml->xpath('/root/error/'.$field);
$this->assertArrayHasKey(0, $list);
$this->assertSame($value, (string) $list[0]);
}
private function getException()
{
return new RuntimeException;
}
/**
* See if passed string is a valid XML document
* @param string $data
* @return boolean
*/
private function isValidXml($data)
{
$prev = libxml_use_internal_errors(true);
$xml = simplexml_load_string($data);
libxml_use_internal_errors($prev);
return $xml !== false;
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops;
use Whoops\TestCase;
use Whoops\Run;
use Whoops\Handler\Handler;
use ArrayObject;
use Mockery as m;
use InvalidArgumentException;
use RuntimeException;
use Exception;
class RunTest extends TestCase
{
/**
* @param string $message
* @return Exception
*/
protected function getException($message = null)
{
return m::mock('Exception', array($message));
}
/**
* @return Handler
*/
protected function getHandler()
{
return m::mock('Whoops\\Handler\\Handler')
->shouldReceive('setRun')
->andReturn(null)
->mock()
->shouldReceive('setInspector')
->andReturn(null)
->mock()
->shouldReceive('setException')
->andReturn(null)
->mock()
;
}
/**
* @covers Whoops\Run::clearHandlers
*/
public function testClearHandlers()
{
$run = $this->getRunInstance();
$run->clearHandlers();
$handlers = $run->getHandlers();
$this->assertEmpty($handlers);
}
/**
* @covers Whoops\Run::pushHandler
*/
public function testPushHandler()
{
$run = $this->getRunInstance();
$run->clearHandlers();
$handlerOne = $this->getHandler();
$handlerTwo = $this->getHandler();
$run->pushHandler($handlerOne);
$run->pushHandler($handlerTwo);
$handlers = $run->getHandlers();
$this->assertCount(2, $handlers);
$this->assertContains($handlerOne, $handlers);
$this->assertContains($handlerTwo, $handlers);
}
/**
* @expectedException InvalidArgumentException
* @covers Whoops\Run::pushHandler
*/
public function testPushInvalidHandler()
{
$run = $this->getRunInstance();
$run->pushHandler($banana = 'actually turnip');
}
/**
* @covers Whoops\Run::pushHandler
*/
public function testPushClosureBecomesHandler()
{
$run = $this->getRunInstance();
$run->pushHandler(function() {});
$this->assertInstanceOf('Whoops\\Handler\\CallbackHandler', $run->popHandler());
}
/**
* @covers Whoops\Run::popHandler
* @covers Whoops\Run::getHandlers
*/
public function testPopHandler()
{
$run = $this->getRunInstance();
$handlerOne = $this->getHandler();
$handlerTwo = $this->getHandler();
$handlerThree = $this->getHandler();
$run->pushHandler($handlerOne);
$run->pushHandler($handlerTwo);
$run->pushHandler($handlerThree);
$this->assertSame($handlerThree, $run->popHandler());
$this->assertSame($handlerTwo, $run->popHandler());
$this->assertSame($handlerOne, $run->popHandler());
// Should return null if there's nothing else in
// the stack
$this->assertNull($run->popHandler());
// Should be empty since we popped everything off
// the stack:
$this->assertEmpty($run->getHandlers());
}
/**
* @covers Whoops\Run::register
*/
public function testRegisterHandler()
{
// It is impossible to test the Run::register method using phpunit,
// as given how every test is always inside a giant try/catch block,
// any thrown exception will never hit a global exception handler.
// On the other hand, there is not much need in testing
// a call to a native PHP function.
$this->assertTrue(true);
}
/**
* @covers Whoops\Run::unregister
* @expectedException Exception
*/
public function testUnregisterHandler()
{
$run = $this->getRunInstance();
$run->register();
$handler = $this->getHandler();
$run->pushHandler($handler);
$run->unregister();
throw $this->getException("I'm not supposed to be caught!");
}
/**
* @covers Whoops\Run::pushHandler
* @covers Whoops\Run::getHandlers
*/
public function testHandlerHoldsOrder()
{
$run = $this->getRunInstance();
$handlerOne = $this->getHandler();
$handlerTwo = $this->getHandler();
$handlerThree = $this->getHandler();
$handlerFour = $this->getHandler();
$run->pushHandler($handlerOne);
$run->pushHandler($handlerTwo);
$run->pushHandler($handlerThree);
$run->pushHandler($handlerFour);
$handlers = $run->getHandlers();
$this->assertSame($handlers[0], $handlerOne);
$this->assertSame($handlers[1], $handlerTwo);
$this->assertSame($handlers[2], $handlerThree);
$this->assertSame($handlers[3], $handlerFour);
}
/**
* @todo possibly split this up a bit and move
* some of this test to Handler unit tests?
* @covers Whoops\Run::handleException
*/
public function testHandlersGonnaHandle()
{
$run = $this->getRunInstance();
$exception = $this->getException();
$order = new ArrayObject;
$handlerOne = $this->getHandler();
$handlerTwo = $this->getHandler();
$handlerThree = $this->getHandler();
$handlerOne->shouldReceive('handle')
->andReturnUsing(function() use($order) { $order[] = 1; });
$handlerTwo->shouldReceive('handle')
->andReturnUsing(function() use($order) { $order[] = 2; });
$handlerThree->shouldReceive('handle')
->andReturnUsing(function() use($order) { $order[] = 3; });
$run->pushHandler($handlerOne);
$run->pushHandler($handlerTwo);
$run->pushHandler($handlerThree);
// Get an exception to be handled, and verify that the handlers
// are given the handler, and in the inverse order they were
// registered.
$run->handleException($exception);
$this->assertEquals((array) $order, array(3, 2, 1));
}
/**
* @covers Whoops\Run::handleException
*/
public function testLastHandler()
{
$run = $this->getRunInstance();
$handlerOne = $this->getHandler();
$handlerTwo = $this->getHandler();
$run->pushHandler($handlerOne);
$run->pushHandler($handlerTwo);
$test = $this;
$handlerOne
->shouldReceive('handle')
->andReturnUsing(function () use($test) {
$test->fail('$handlerOne should not be called');
})
;
$handlerTwo
->shouldReceive('handle')
->andReturn(Handler::LAST_HANDLER)
;
$run->handleException($this->getException());
// Reached the end without errors
$this->assertTrue(true);
}
/**
* Test error suppression using @ operator.
*/
public function testErrorSuppression()
{
$run = $this->getRunInstance();
$run->register();
$handler = $this->getHandler();
$run->pushHandler($handler);
$test = $this;
$handler
->shouldReceive('handle')
->andReturnUsing(function () use($test) {
$test->fail('$handler should not be called, error not suppressed');
})
;
@trigger_error("Test error suppression");
// Reached the end without errors
$this->assertTrue(true);
}
public function testErrorCatching()
{
$run = $this->getRunInstance();
$run->register();
$handler = $this->getHandler();
$run->pushHandler($handler);
$test = $this;
$handler
->shouldReceive('handle')
->andReturnUsing(function () use($test) {
$test->fail('$handler should not be called error should be caught');
})
;
try {
trigger_error(E_USER_NOTICE, 'foo');
$this->fail('Should not continue after error thrown');
} catch (\ErrorException $e) {
// Do nothing
$this->assertTrue(true);
return;
}
$this->fail('Should not continue here, should have been caught.');
}
/**
* Test to make sure that error_reporting is respected.
*/
public function testErrorReporting()
{
$run = $this->getRunInstance();
$run->register();
$handler = $this->getHandler();
$run->pushHandler($handler);
$test = $this;
$handler
->shouldReceive('handle')
->andReturnUsing(function () use($test) {
$test->fail('$handler should not be called, error_reporting not respected');
})
;
$oldLevel = error_reporting(E_ALL ^ E_USER_NOTICE);
trigger_error("Test error reporting", E_USER_NOTICE);
error_reporting($oldLevel);
// Reached the end without errors
$this->assertTrue(true);
}
/**
* @covers Whoops\Run::silenceErrorsInPaths
*/
public function testSilenceErrorsInPaths()
{
$run = $this->getRunInstance();
$run->register();
$handler = $this->getHandler();
$run->pushHandler($handler);
$test = $this;
$handler
->shouldReceive('handle')
->andReturnUsing(function () use($test) {
$test->fail('$handler should not be called, silenceErrorsInPaths not respected');
})
;
$run->silenceErrorsInPaths('@^'.preg_quote(__FILE__).'$@', E_USER_NOTICE);
trigger_error('Test', E_USER_NOTICE);
$this->assertTrue(true);
}
/**
* @covers Whoops\Run::handleException
* @covers Whoops\Run::writeToOutput
*/
public function testOutputIsSent()
{
$run = $this->getRunInstance();
$run->pushHandler(function() {
echo "hello there";
});
ob_start();
$run->handleException(new RuntimeException);
$this->assertEquals("hello there", ob_get_clean());
}
/**
* @covers Whoops\Run::handleException
* @covers Whoops\Run::writeToOutput
*/
public function testOutputIsNotSent()
{
$run = $this->getRunInstance();
$run->writeToOutput(false);
$run->pushHandler(function() {
echo "hello there";
});
ob_start();
$this->assertEquals("hello there", $run->handleException(new RuntimeException));
$this->assertEquals("", ob_get_clean());
}
/**
* @covers Whoops\Run::sendHttpCode
*/
public function testSendHttpCode()
{
$run = $this->getRunInstance();
$run->sendHttpCode(true);
$this->assertEquals(500, $run->sendHttpCode());
}
/**
* @covers Whoops\Run::sendHttpCode
* @expectedException InvalidArgumentException
*/
public function testSendHttpCodeWrongCode()
{
$this->getRunInstance()->sendHttpCode(1337);
}
}
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops;
use Whoops\Run;
class TestCase extends \PHPUnit_Framework_TestCase
{
/**
* @return Run
*/
protected function getRunInstance()
{
$run = new Run;
$run->allowQuit(false);
return $run;
}
}
language: php
php:
- 5.5
- 5.4
- 5.3
script: phpunit --configuration phpunit.xml.dist
{
"name": "ircmaxell/password-compat",
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
"version": "1.0.3",
"keywords": ["password", "hashing"],
"homepage": "https://github.com/ircmaxell/password_compat",
"license": "MIT",
"authors": [
{
"name": "Anthony Ferrara",
"email": "[email protected]",
"homepage": "http://blog.ircmaxell.com"
}
],
"autoload": {
"files": ["lib/password.php"]
}
}
<?php
/**
* A Compatibility library with PHP 5.5's simplified password hashing API.
*
* @author Anthony Ferrara <[email protected]>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @copyright 2012 The Authors
*/
if (!defined('PASSWORD_BCRYPT')) {
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
/**
* Hash the password using the specified algorithm
*
* @param string $password The password to hash
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
* @param array $options The options for the algorithm to use
*
* @return string|false The hashed password, or false on error.
*/
function password_hash($password, $algo, array $options = array()) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
return null;
}
if (!is_string($password)) {
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
return null;
}
if (!is_int($algo)) {
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
return null;
}
switch ($algo) {
case PASSWORD_BCRYPT:
// Note that this is a C constant, but not exposed to PHP, so we don't define it here.
$cost = 10;
if (isset($options['cost'])) {
$cost = $options['cost'];
if ($cost < 4 || $cost > 31) {
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
return null;
}
}
// The length of salt to generate
$raw_salt_len = 16;
// The length required in the final serialization
$required_salt_len = 22;
$hash_format = sprintf("$2y$%02d$", $cost);
break;
default:
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
return null;
}
if (isset($options['salt'])) {
switch (gettype($options['salt'])) {
case 'NULL':
case 'boolean':
case 'integer':
case 'double':
case 'string':
$salt = (string) $options['salt'];
break;
case 'object':
if (method_exists($options['salt'], '__tostring')) {
$salt = (string) $options['salt'];
break;
}
case 'array':
case 'resource':
default:
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
return null;
}
if (strlen($salt) < $required_salt_len) {
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", strlen($salt), $required_salt_len), E_USER_WARNING);
return null;
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
$salt = str_replace('+', '.', base64_encode($salt));
}
} else {
$buffer = '';
$buffer_valid = false;
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && is_readable('/dev/urandom')) {
$f = fopen('/dev/urandom', 'r');
$read = strlen($buffer);
while ($read < $raw_salt_len) {
$buffer .= fread($f, $raw_salt_len - $read);
$read = strlen($buffer);
}
fclose($f);
if ($read >= $raw_salt_len) {
$buffer_valid = true;
}
}
if (!$buffer_valid || strlen($buffer) < $raw_salt_len) {
$bl = strlen($buffer);
for ($i = 0; $i < $raw_salt_len; $i++) {
if ($i < $bl) {
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
} else {
$buffer .= chr(mt_rand(0, 255));
}
}
}
$salt = str_replace('+', '.', base64_encode($buffer));
}
$salt = substr($salt, 0, $required_salt_len);
$hash = $hash_format . $salt;
$ret = crypt($password, $hash);
if (!is_string($ret) || strlen($ret) <= 13) {
return false;
}
return $ret;
}
/**
* Get information about the password hash. Returns an array of the information
* that was used to generate the password hash.
*
* array(
* 'algo' => 1,
* 'algoName' => 'bcrypt',
* 'options' => array(
* 'cost' => 10,
* ),
* )
*
* @param string $hash The password hash to extract info from
*
* @return array The array of information about the hash.
*/
function password_get_info($hash) {
$return = array(
'algo' => 0,
'algoName' => 'unknown',
'options' => array(),
);
if (substr($hash, 0, 4) == '$2y$' && strlen($hash) == 60) {
$return['algo'] = PASSWORD_BCRYPT;
$return['algoName'] = 'bcrypt';
list($cost) = sscanf($hash, "$2y$%d$");
$return['options']['cost'] = $cost;
}
return $return;
}
/**
* Determine if the password hash needs to be rehashed according to the options provided
*
* If the answer is true, after validating the password using password_verify, rehash it.
*
* @param string $hash The hash to test
* @param int $algo The algorithm used for new password hashes
* @param array $options The options array passed to password_hash
*
* @return boolean True if the password needs to be rehashed.
*/
function password_needs_rehash($hash, $algo, array $options = array()) {
$info = password_get_info($hash);
if ($info['algo'] != $algo) {
return true;
}
switch ($algo) {
case PASSWORD_BCRYPT:
$cost = isset($options['cost']) ? $options['cost'] : 10;
if ($cost != $info['options']['cost']) {
return true;
}
break;
}
return false;
}
/**
* Verify a password against a hash using a timing attack resistant approach
*
* @param string $password The password to verify
* @param string $hash The hash to verify against
*
* @return boolean If the password matches the hash
*/
function password_verify($password, $hash) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
return false;
}
$ret = crypt($password, $hash);
if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) {
return false;
}
$status = 0;
for ($i = 0; $i < strlen($ret); $i++) {
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
}

Copyright (c) 2012 Anthony Ferrara

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.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="true"
backupStaticAttributes="false"
bootstrap="lib/password.php"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
mapTestClassNameToCoveredClassName="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
strict="false"
verbose="false">
<testsuites>
<testsuite name="Unit">
<directory>test/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">lib/</directory>
</whitelist>
</filter>
</phpunit>

password_compat

Build Status

This library is intended to provide forward compatibility with the password_* functions being worked on for PHP 5.5.

See the RFC for more detailed information.

Requirements

This library requires PHP >= 5.3.7 OR a version that has the $2y fix backported into it (such as Debian provides).

The runtime checks have been removed due to this version issue. To see if password_compat is available for your system, run the included version-test.php. If it outputs "Pass", you can safely use the library. If not, you cannot.

If you attempt to use password-compat on an unsupported version, attempts to create or verify hashes will return false. You have been warned!

The reason for this is that PHP prior to 5.3.7 contains a security issue with its BCRYPT implementation. Therefore, it's highly recommended that you upgrade to a newer version of PHP prior to using this layer.

Installation

To install, simply require the password.php file under lib.

You can also install it via Composer by using the Packagist archive.

Usage

Creating Password Hashes

To create a password hash from a password, simply use the password_hash function.

$hash = password_hash($password, PASSWORD_BCRYPT);

Note that the algorithm that we chose is PASSWORD_BCRYPT. That's the current strongest algorithm supported. This is the BCRYPT crypt algorithm. It produces a 60 character hash as the result.

BCRYPT also allows for you to define a cost parameter in the options array. This allows for you to change the CPU cost of the algorithm:

$hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 10]);

That's the same as the default. The cost can range from 4 to 31. I would suggest that you use the highest cost that you can, while keeping response time reasonable (I target between 0.1 and 0.5 seconds for a hash, depending on use-case).

Another algorithm name is supported:

PASSWORD_DEFAULT

This will use the strongest algorithm available to PHP at the current time. Presently, this is the same as specifying PASSWORD_BCRYPT. But in future versions of PHP, it may be updated to use a stronger algorithm if one is introduced. It can also be changed if a problem is identified with the BCRYPT algorithm. Note that if you use this option, you are strongly encouraged to store it in a VARCHAR(255) column to avoid truncation issues if a future algorithm increases the length of the generated hash.

It is very important that you should check the return value of password_hash prior to storing it, because a false may be returned if it encountered an error.

Verifying Password Hashes

To verify a hash created by password_hash, simply call:

if (password_verify($password, $hash)) {
	/* Valid */
} else {
	/* Invalid */
}

That's all there is to it.

Rehashing Passwords

From time to time you may update your hashing parameters (algorithm, cost, etc). So a function to determine if rehashing is necessary is available:

if (password_verify($password, $hash)) {
	if (password_needs_rehash($hash, $algorithm, $options)) {
		$hash = password_hash($password, $algorithm, $options);
		/* Store new hash in db */
	}
}
<?php
class PasswordGetInfoTest extends PHPUnit_Framework_TestCase {
public static function provideInfo() {
return array(
array('foo', array('algo' => 0, 'algoName' => 'unknown', 'options' => array())),
array('$2y$', array('algo' => 0, 'algoName' => 'unknown', 'options' => array())),
array('$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi', array('algo' => PASSWORD_BCRYPT, 'algoName' => 'bcrypt', 'options' => array('cost' => 7))),
array('$2y$10$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi', array('algo' => PASSWORD_BCRYPT, 'algoName' => 'bcrypt', 'options' => array('cost' => 10))),
);
}
public function testFuncExists() {
$this->assertTrue(function_exists('password_get_info'));
}
/**
* @dataProvider provideInfo
*/
public function testInfo($hash, $info) {
$this->assertEquals($info, password_get_info($hash));
}
}
<?php
class PasswordHashTest extends PHPUnit_Framework_TestCase {
public function testFuncExists() {
$this->assertTrue(function_exists('password_hash'));
}
public function testStringLength() {
$this->assertEquals(60, strlen(password_hash('foo', PASSWORD_BCRYPT)));
}
public function testHash() {
$hash = password_hash('foo', PASSWORD_BCRYPT);
$this->assertEquals($hash, crypt('foo', $hash));
}
public function testKnownSalt() {
$hash = password_hash("rasmuslerdorf", PASSWORD_BCRYPT, array("cost" => 7, "salt" => "usesomesillystringforsalt"));
$this->assertEquals('$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi', $hash);
}
public function testRawSalt() {
$hash = password_hash("test", PASSWORD_BCRYPT, array("salt" => "123456789012345678901" . chr(0)));
$this->assertEquals('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', $hash);
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidAlgo() {
password_hash('foo', array());
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidAlgo2() {
password_hash('foo', 2);
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidPassword() {
password_hash(array(), 1);
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidSalt() {
password_hash('foo', PASSWORD_BCRYPT, array('salt' => array()));
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidBcryptCostLow() {
password_hash('foo', PASSWORD_BCRYPT, array('cost' => 3));
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidBcryptCostHigh() {
password_hash('foo', PASSWORD_BCRYPT, array('cost' => 32));
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidBcryptCostInvalid() {
password_hash('foo', PASSWORD_BCRYPT, array('cost' => 'foo'));
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInvalidBcryptSaltShort() {
password_hash('foo', PASSWORD_BCRYPT, array('salt' => 'abc'));
}
}
<?php
class PasswordNeedsRehashTest extends PHPUnit_Framework_TestCase {
public static function provideCases() {
return array(
array('foo', 0, array(), false),
array('foo', 1, array(), true),
array('$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi', PASSWORD_BCRYPT, array(), true),
array('$2y$07$usesomesillystringfore2udlvp1ii2e./u9c8sbjqp8i90dh6hi', PASSWORD_BCRYPT, array('cost' => 7), false),
array('$2y$07$usesomesillystringfore2udlvp1ii2e./u9c8sbjqp8i90dh6hi', PASSWORD_BCRYPT, array('cost' => 5), true),
);
}
public function testFuncExists() {
$this->assertTrue(function_exists('password_needs_rehash'));
}
/**
* @dataProvider provideCases
*/
public function testCases($hash, $algo, $options, $valid) {
$this->assertEquals($valid, password_needs_rehash($hash, $algo, $options));
}
}
<?php
class PasswordVerifyTest extends PHPUnit_Framework_TestCase {
public function testFuncExists() {
$this->assertTrue(function_exists('password_verify'));
}
public function testFailedType() {
$this->assertFalse(password_verify(123, 123));
}
public function testSaltOnly() {
$this->assertFalse(password_verify('foo', '$2a$07$usesomesillystringforsalt$'));
}
public function testInvalidPassword() {
$this->assertFalse(password_verify('rasmusler', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi'));
}
public function testValidPassword() {
$this->assertTrue(password_verify('rasmuslerdorf', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi'));
}
public function testInValidHash() {
$this->assertFalse(password_verify('rasmuslerdorf', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hj'));
}
}
<?php
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;
echo "Test for functionality of compat library: " . ($pass ? "Pass" : "Fail");
echo "\n";
.idea/*
vendor/*
build/*
.DS_Store
cache.properties
phpunit.xml
composer.phar
composer.lock
language: php
php:
- 5.3
- 5.4
before_script:
- composer install --dev
- cp phpunit.xml.dist phpunit.xml
script: phpunit --coverage-text
{
"name": "jeremeamia/SuperClosure",
"type": "library",
"description": "Doing interesting things with closures like serialization.",
"keywords": ["closure", "serialize", "serializable", "function", "parser", "tokenizer"],
"homepage": "https://github.com/jeremeamia/super_closure",
"license": "MIT",
"authors": [
{
"name": "Jeremy Lindblom"
}
],
"require": {
"php": ">=5.3.3",
"nikic/php-parser": "~0.9"
},
"require-dev": {
"phpunit/phpunit": "~3.7"
},
"autoload": {
"psr-0": { "Jeremeamia\\SuperClosure": "src/" }
}
}
<?php
if (version_compare(PHP_VERSION, '5.4', '<=')) {
throw new \RuntimeException('PHP 5.4+ is required for this example.');
}
require __DIR__ . '/../vendor/autoload.php';
use Jeremeamia\SuperClosure\SerializableClosure;
$factorial = new SerializableClosure(function ($n) use (&$factorial) {
return ($n <= 1) ? 1 : $n * $factorial($n - 1);
});
echo $factorial(5) . PHP_EOL;
//> 120
$serialized = serialize($factorial);
$unserialized = unserialize($serialized);
echo $unserialized(5) . PHP_EOL;
//> 120
<?php
require __DIR__ . '/../vendor/autoload.php';
use Jeremeamia\SuperClosure\SerializableClosure;
$greeting = 'Hello';
$helloWorld = new SerializableClosure(function ($name = 'World') use ($greeting) {
echo "{$greeting}, {$name}!\n";
});
$helloWorld();
//> Hello, World!
$helloWorld('Jeremy');
//> Hello, Jeremy!
$serialized = serialize($helloWorld);
$unserialized = unserialize($serialized);
$unserialized();
//> Hello, World!
$unserialized('Jeremy');
//> Hello, Jeremy!

MIT License

Copyright (c) 2010-2013 Jeremy Lindblom

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.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="./tests/bootstrap.php"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
>
<testsuites>
<testsuite name="SuperClosure">
<directory>./tests/Jeremeamia/SuperClosure/Test</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src/Jeremeamia/SuperClosure</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="./build/artifacts/coverage"
yui="true" highlight="false" charset="UTF-8"
lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="./build/artifacts/coverage.xml"/>
<log type="junit" target="./build/artifacts/log.xml" logIncompleteSkipped="false"/>
<log type="testdox-html" target="./build/artifacts/testdox.html"/>
</logging>
</phpunit>

PHP Super Closure

Latest Stable Version Total Downloads Build Status

Have you ever seen this?

Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'

It's true! If you try to serialize a Closure, PHP will throw an exception and tell you that it is not allowed. But even though it is not "allowed" by PHP, the Super Closure library (jeremeamia/superclosure on Packagist) makes it possible.

I'm not joking, you really can serialize a PHP closure!

<?php

require 'vendor/autoload.php';

use Jeremeamia\SuperClosure\SerializableClosure;

$greeting = 'Hello';
$helloWorld = new SerializableClosure(function ($name = 'World') use ($greeting) {
    echo "{$greeting}, {$name}!\n";
});

$helloWorld();
//> Hello, World!
$helloWorld('Jeremy');
//> Hello, Jeremy!

$serialized = serialize($helloWorld);
$unserialized = unserialize($serialized);

$unserialized();
//> Hello, World!
$unserialized('Jeremy');
//> Hello, Jeremy!

Yep, pretty cool huh?

Tell Me More!

It all started way back in the beginning of 2010 when PHP 5.3 was starting to gain traction. I wrote a blog post called Extending PHP 5.3 Closures with Serialization and Reflection on my former employers' blog, HTMList, showing how it can be done. Since then I've made a few iterations on the code, and this most recent iteration brings with it a generally more robust solution that takes advantage of the fabulous nikic/php-parser library.

Features

  • Grants the ability to serialize closures
  • Handles closures with used/inherited/imported variables
  • Handles closures that use other closures
  • Handles closures that reference class names in the parameters or body
  • Handles recursive closures (PHP 5.4+ only)
  • Allows you to get the code of a closure
  • Allows you to get the names and values of variables used by a closure
  • Allows you to get an Abstract Syntax Tree (AST) representing the code of a closure
  • Replaces magic constants with their expected values so that the closure behaves as expected after unserialization
  • Uses an accurate parsing method of a context-free grammar via the nikic/php-parser library
  • PSR-0 compliant and installable via Composer

Caveats

  1. For any variables used by reference (e.g., function () use (&$vars, &$like, &$these) {…}), the references are not maintained after serialization/unserialization. The only exception is when (in PHP 5.4+ only) the used variable is a reference to the SerializableClosure object being serialized, which is the case with a recursive function. For some reason — that I actually don't quite understand — this works.
  2. If you have two closures defined on a single line (you shouldn't do this anyway), you will not be able to serialize either one since it is ambiguous which closure's code should be parsed.
  3. Because the technique to acquire the code and context of the closure requires reflection and full AST-style parsing, the performance of serializing a closure is likely not good.
  4. Warning: Both eval() and extract() are required to unserialize the closure. These functions are considered dangerous by many, so you will have to evaluate whether or not you actual want to be using this library if these functions concern you. These functions must be used to make this technique work.

Installation

To install the Super Closure library in your project using Composer, first add the following to your composer.json config file.

{
    "require": {
        "jeremeamia/superclosure": "~1.0"
    }
}

Then run Composer's install or update commands to complete installation. Please visit the Composer homepage for more information about how to use Composer.

Why Would I Need To Serialize Closures?

Well, since you are here looking at this README, you may already have a use case in mind. Even though this concept began as an experiment, there have been some use cases that have come up in the wild.

For example, in a video about Laravel 4 and IronMQ by UserScape, at about the 7:50 mark they show how you can push a closure onto a queue as a job so that it can be executed by a worker. This is nice because you do not have to create a whole class for a job that might be really simple. The closure serialization is done by a class in the Laravel 4 framework that is based on one of my older versions of SuperClosure.

Essentially this library let's you create closures in one process and use them in another. It would even be possible to provide closures (or algorithms) as a service through an API.

Who Is Using Super Closure?

  • Laravel 4 - Serializes a closure to potentially push onto a job queue.
  • HTTP Mock for PHP - Serialize a closure to send to remote server within a test workflow.
  • Jumper - Serialize a closure to run on remote host via SSH.
  • nicmart/Benchmark - Uses the ClosureParser to display a benchmarked Closure's code.
  • Please let me know if and how your project uses Super Closure.
<?php
namespace Jeremeamia\SuperClosure;
/**
* Simple object for storing the location information of a closure (e.g., file, class, etc.)
*
* @copyright Jeremy Lindblom 2010-2013
*/
class ClosureLocation
{
/** @var string */
protected $closureScopeClass;
/** @var string */
public $class;
/** @var string */
public $directory;
/** @var string */
public $file;
/** @var string */
public $function;
/** @var string */
public $line;
/** @var string */
public $method;
/** @var string */
public $namespace;
/** @var string */
public $trait;
/**
* Creates a ClosureLocation and seeds it with all the data that can be gleaned from the closure's reflection
*
* @param \ReflectionFunction $reflection The reflection of the closure that this ClosureLocation should represent
*
* @return ClosureLocation
*/
public static function fromReflection(\ReflectionFunction $reflection)
{
$location = new self;
$location->directory = dirname($reflection->getFileName());
$location->file = $reflection->getFileName();
$location->function = $reflection->getName();
$location->line = $reflection->getStartLine();
// @codeCoverageIgnoreStart
if (version_compare(PHP_VERSION, '5.4', '>=')) {
$closureScopeClass = $reflection->getClosureScopeClass();
$location->closureScopeClass = $closureScopeClass ? $closureScopeClass->getName() : null;
}
// @codeCoverageIgnoreEnd
return $location;
}
public function finalize()
{
if ($this->class || $this->trait) {
$class = $this->class ?: $this->trait;
$this->method = "{$class}::{$this->function}";
}
if (!$this->class && $this->trait) {
$this->class = $this->closureScopeClass;
}
}
}
<?php
namespace Jeremeamia\SuperClosure;
use Jeremeamia\SuperClosure\Visitor\ClosureFinderVisitor;
use Jeremeamia\SuperClosure\Visitor\MagicConstantVisitor;
/**
* Parses a closure from its reflection such that the code and used (closed upon) variables are accessible. The
* ClosureParser uses the fabulous nikic/php-parser library which creates abstract syntax trees (AST) of the code.
*
* @copyright Jeremy Lindblom 2010-2013
*/
class ClosureParser
{
/**
* @var array
*/
protected static $cache = array();
/**
* @var \ReflectionFunction The reflection of the closure being parsed
*/
protected $reflection;
/**
* @var \PHPParser_Node An abstract syntax tree defining the code of the closure
*/
protected $abstractSyntaxTree;
/**
* @var array The variables used (closed upon) by the closure and their values
*/
protected $usedVariables;
/**
* @var string The closure's code
*/
protected $code;
/**
* Creates a ClosureParser for the provided closure
*
* @param \Closure $closure
*
* @return ClosureParser
*/
public static function fromClosure(\Closure $closure)
{
return new self(new \ReflectionFunction($closure));
}
/**
* Clears the internal cache of file ASTs.
*
* ASTs are stored for any file that is parsed to speed up multiple
* parsings of the same file. If you are worried about the memory consumption of files the ClosureParser has already
* parsed, you can call this function to clear the cache. The cache is not persistent and stores ASTs from the
* current process
*/
public static function clearCache()
{
self::$cache = array();
}
/**
* @param \ReflectionFunction $reflection
*
* @throws \InvalidArgumentException
*/
public function __construct(\ReflectionFunction $reflection)
{
if (!$reflection->isClosure()) {
throw new \InvalidArgumentException('You must provide the reflection of a closure.');
}
$this->reflection = $reflection;
}
/**
* Returns the reflection of the closure
*
* @return \ReflectionFunction
*/
public function getReflection()
{
return $this->reflection;
}
/**
* Returns the abstract syntax tree (AST) of the closure's code. Class names are resolved to their fully-qualified
* class names (FQCN) and magic constants are resolved to their values as they would be in the context of the
* closure.
*
* @return \PHPParser_Node_Expr_Closure
* @throws \InvalidArgumentException
*/
public function getClosureAbstractSyntaxTree()
{
if (!$this->abstractSyntaxTree) {
try {
// Parse the code from the file containing the closure and create an AST with FQCN resolved
$fileAst = $this->getFileAbstractSyntaxTree();
$closureFinder = new ClosureFinderVisitor($this->reflection);
$fileTraverser = new \PHPParser_NodeTraverser();
$fileTraverser->addVisitor(new \PHPParser_NodeVisitor_NameResolver);
$fileTraverser->addVisitor($closureFinder);
$fileTraverser->traverse($fileAst);
} catch (\PHPParser_Error $e) {
// @codeCoverageIgnoreStart
throw new \InvalidArgumentException('There was an error parsing the file containing the closure.');
// @codeCoverageIgnoreEnd
}
// Find the first closure defined in the AST that is on the line where the closure is located
$closureAst = $closureFinder->getClosureNode();
if (!$closureAst) {
// @codeCoverageIgnoreStart
throw new \InvalidArgumentException('The closure was not found within the abstract syntax tree.');
// @codeCoverageIgnoreEnd
}
// Resolve additional nodes by making a second pass through just the closure's nodes
$closureTraverser = new \PHPParser_NodeTraverser();
$closureTraverser->addVisitor(new MagicConstantVisitor($closureFinder->getLocation()));
$closureAst = $closureTraverser->traverse(array($closureAst));
$this->abstractSyntaxTree = $closureAst[0];
}
return $this->abstractSyntaxTree;
}
/**
* Returns the variables that in the "use" clause of the closure definition. These are referred to as the "used
* variables", "static variables", or "closed upon variables", "context" of the closure.
*
* @return array
*/
public function getUsedVariables()
{
if (!$this->usedVariables) {
// Get the variable names defined in the AST
$usedVarNames = array_map(function ($usedVar) {
return $usedVar->var;
}, $this->getClosureAbstractSyntaxTree()->uses);
// Get the variable names and values using reflection
$usedVarValues = $this->reflection->getStaticVariables();
// Combine the two arrays to create a canonical hash of variable names and values
$this->usedVariables = array();
foreach ($usedVarNames as $name) {
if (isset($usedVarValues[$name])) {
$this->usedVariables[$name] = $usedVarValues[$name];
}
}
}
return $this->usedVariables;
}
/**
* Returns the formatted code of the closure
*
* @return string
*/
public function getCode()
{
if (!$this->code) {
// Use the pretty printer to print the closure code from the AST
$printer = new \PHPParser_PrettyPrinter_Default();
$this->code = $printer->prettyPrint(array($this->getClosureAbstractSyntaxTree()));
}
return $this->code;
}
/**
* Loads the PHP file and produces an abstract syntax tree (AST) of the code. This is stored in an internal cache by
* the filename for memoization within the same process
*
* @return array
*/
protected function getFileAbstractSyntaxTree()
{
$filename = $this->reflection->getFileName();
if (!isset(self::$cache[$filename])) {
$parser = new \PHPParser_Parser(new \PHPParser_Lexer_Emulative);
self::$cache[$filename] = $parser->parse(file_get_contents($filename));
}
return self::$cache[$filename];
}
}
<?php
namespace Jeremeamia\SuperClosure;
/**
* This class allows you to do the impossible - serialize closures! With the combined power of the nikic/php-parser
* library, the Reflection API, and infamous eval, you can serialize a closure, unserialize it in a different PHP
* process, and execute it. It's almost as cool as time travel!
*
* @copyright Jeremy Lindblom 2010-2013
*/
class SerializableClosure implements \Serializable
{
/**
* @var \Closure The closure being made serializable
*/
protected $closure;
/**
* @var \ReflectionFunction The reflected closure
*/
protected $reflection;
/**
* @var array The calculated state to serialize
*/
protected $state;
/**
* @param \Closure $closure
*/
public function __construct(\Closure $closure)
{
$this->closure = $closure;
}
/**
* @return \ReflectionFunction
*/
public function getReflection()
{
if (!$this->reflection) {
$this->reflection = new \ReflectionFunction($this->closure);
}
return $this->reflection;
}
/**
* @return \Closure
*/
public function getClosure()
{
return $this->closure;
}
/**
* Invokes the original closure
*
* @return mixed
*/
public function __invoke()
{
return $this->getReflection()->invokeArgs(func_get_args());
}
/**
* Serialize the code and of context of the closure
*
* @return string
*/
public function serialize()
{
if (!$this->state) {
$this->createState();
}
return serialize($this->state);
}
/**
* Unserializes the closure data and recreates the closure. Attempts to recreate the closure's context as well by
* extracting the used variables into the scope. Variables names in this method are surrounded with underlines in
* order to prevent collisions with the variables in the context. NOTE: There be dragons here! Both `eval` and
* `extract` are used in this method
*
* @param string $__serialized__
*/
public function unserialize($__serialized__)
{
// Unserialize the data we need to reconstruct the SuperClosure
$this->state = unserialize($__serialized__);
list($__code__, $__context__) = $this->state;
// Simulate the original context the Closure was created in
extract($__context__);
// Evaluate the code to recreate the Closure
eval("\$this->closure = {$__code__};");
}
/**
* Uses the closure parser to fetch the closure's code and context
*/
protected function createState()
{
$parser = new ClosureParser($this->getReflection());
$this->state = array($parser->getCode());
// Add the used variables (context) to the state, but wrap all closures with SerializableClosure
$this->state[] = array_map(function ($var) {
return ($var instanceof \Closure) ? new self($var) : $var;
}, $parser->getUsedVariables());
}
}
<?php
namespace Jeremeamia\SuperClosure\Visitor;
use Jeremeamia\SuperClosure\ClosureLocation;
/**
* This is a visitor that extends the nikic/php-parser library and looks for a closure node and its location
*
* @copyright Jeremy Lindblom 2010-2013
*/
class ClosureFinderVisitor extends \PHPParser_NodeVisitorAbstract
{
/**
* @var \ReflectionFunction
*/
protected $reflection;
/**
* @var \PHPParser_Node_Expr_Closure
*/
protected $closureNode;
/**
* @var ClosureLocation
*/
protected $location;
/**
* @param \ReflectionFunction $reflection
*/
public function __construct(\ReflectionFunction $reflection)
{
$this->reflection = $reflection;
$this->location = new ClosureLocation;
}
public function beforeTraverse(array $nodes)
{
$this->location = ClosureLocation::fromReflection($this->reflection);
}
public function afterTraverse(array $nodes)
{
$this->location->finalize();
}
public function enterNode(\PHPParser_Node $node)
{
// Determine information about the closure's location
if (!$this->closureNode) {
if ($node instanceof \PHPParser_Node_Stmt_Namespace) {
$this->location->namespace = is_array($node->name->parts) ? implode('\\', $node->name->parts) : null;
}
if ($node instanceof \PHPParser_Node_Stmt_Trait) {
$this->location->trait = $this->location->namespace . '\\' . $node->name;
$this->location->class = null;
}
elseif ($node instanceof \PHPParser_Node_Stmt_Class) {
$this->location->class = $this->location->namespace . '\\' . $node->name;
$this->location->trait = null;
}
}
// Locate the node of the closure
if ($node instanceof \PHPParser_Node_Expr_Closure) {
if ($node->getAttribute('startLine') == $this->reflection->getStartLine()) {
if ($this->closureNode) {
throw new \RuntimeException('Two closures were declared on the same line of code. Cannot determine '
. 'which closure was the intended target.');
} else {
$this->closureNode = $node;
}
}
}
}
public function leaveNode(\PHPParser_Node $node)
{
// Determine information about the closure's location
if (!$this->closureNode) {
if ($node instanceof \PHPParser_Node_Stmt_Namespace) {
$this->location->namespace = null;
}
if ($node instanceof \PHPParser_Node_Stmt_Trait) {
$this->location->trait = null;
}
elseif ($node instanceof \PHPParser_Node_Stmt_Class) {
$this->location->class = null;
}
}
}
/**
* @return \PHPParser_Node_Expr_Closure
*/
public function getClosureNode()
{
return $this->closureNode;
}
/**
* @return ClosureLocation
*/
public function getLocation()
{
return $this->location;
}
}
<?php
namespace Jeremeamia\SuperClosure\Visitor;
use Jeremeamia\SuperClosure\ClosureLocation;
use PHPParser_Node_Scalar_LNumber as NumberNode;
use PHPParser_Node_Scalar_String as StringNode;
/**
* This is a visitor that resolves magic constants (e.g., __FILE__) to their intended values within a closure's AST
*
* @copyright Jeremy Lindblom 2010-2013
*/
class MagicConstantVisitor extends \PHPParser_NodeVisitorAbstract
{
/**
* @var ClosureLocation
*/
protected $location;
/**
* @param ClosureLocation $location
*/
public function __construct(ClosureLocation $location)
{
$this->location = $location;
}
public function leaveNode(\PHPParser_Node $node)
{
switch ($node->getType()) {
case 'Scalar_LineConst' :
return new NumberNode($node->getAttribute('startLine'));
case 'Scalar_FileConst' :
return new StringNode($this->location->file);
case 'Scalar_DirConst' :
return new StringNode($this->location->directory);
case 'Scalar_FuncConst' :
return new StringNode($this->location->function);
case 'Scalar_NSConst' :
return new StringNode($this->location->namespace);
case 'Scalar_ClassConst' :
return new StringNode($this->location->class);
case 'Scalar_MethodConst' :
return new StringNode($this->location->method);
case 'Scalar_TraitConst' :
return new StringNode($this->location->trait);
}
}
}
<?php
date_default_timezone_set('America/Los_Angeles');
require __DIR__ . '/../vendor/autoload.php';
<?php
namespace Jeremeamia\SuperClosure\Test;
use Jeremeamia\SuperClosure\ClosureLocation;
class ClosureLocationTest extends \PHPUnit_Framework_TestCase
{
public function testCanCreateClosureLocationFromClosureReflection()
{
$reflection = new \ReflectionFunction(function () {});
$location = ClosureLocation::fromReflection($reflection);
$setProperties = array_filter(get_object_vars($location));
$this->assertEquals(array('directory', 'file', 'function', 'line'), array_keys($setProperties));
}
public function testCanFinalizeLocation()
{
$location = new ClosureLocation();
$location->function = '[function]';
$location->trait = '[trait]';
$r = new \ReflectionObject($location);
$p = $r->getProperty('closureScopeClass');
$p->setAccessible(true);
$p->setValue($location, '[class]');
$location->finalize();
$this->assertEquals('[trait]::[function]', $location->method);
$this->assertEquals('[class]', $location->class);
}
}
<?php
namespace Jeremeamia\SuperClosure\Test;
use Jeremeamia\SuperClosure\ClosureParser;
class ClosureParserTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::__construct
* @covers \Jeremeamia\SuperClosure\ClosureParser::getReflection
*/
public function testCanGetReflectionBackFromParser()
{
$closure = function () {};
$reflection = new \ReflectionFunction($closure);
$parser = new ClosureParser($reflection);
$this->assertSame($reflection, $parser->getReflection());
}
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::fromClosure
*/
public function testCanUseFactoryMethodToCreateParser()
{
$parser = ClosureParser::fromClosure(function () {});
$this->assertInstanceOf('Jeremeamia\SuperClosure\ClosureParser', $parser);
}
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::__construct
*/
public function testRaisesErrorWhenNonClosureIsProvided()
{
$this->setExpectedException('InvalidArgumentException');
$reflection = new \ReflectionFunction('strpos');
$parser = new ClosureParser($reflection);
}
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::getCode
*/
public function testCanGetCodeFromParser()
{
$closure = function () {};
$expectedCode = "function () {\n \n};";
$parser = new ClosureParser(new \ReflectionFunction($closure));
$actualCode = $parser->getCode();
$this->assertEquals($expectedCode, $actualCode);
}
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::getUsedVariables
*/
public function testCanGetUsedVariablesFromParser()
{
$foo = 1;
$bar = 2;
$closure = function () use ($foo, $bar) {};
$expectedVars = array('foo' => 1, 'bar' => 2);
$parser = new ClosureParser(new \ReflectionFunction($closure));
$actualVars = $parser->getUsedVariables();
$this->assertEquals($expectedVars, $actualVars);
}
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::clearCache
*/
public function testCanClearCache()
{
$parserClass = 'Jeremeamia\SuperClosure\ClosureParser';
$p = new \ReflectionProperty($parserClass, 'cache');
$p->setAccessible(true);
$p->setValue(null, array('foo' => 'bar'));
$this->assertEquals(array('foo' => 'bar'), $this->readAttribute($parserClass, 'cache'));
ClosureParser::clearCache();
$this->assertEquals(array(), $this->readAttribute($parserClass, 'cache'));
}
/**
* @covers \Jeremeamia\SuperClosure\ClosureParser::getClosureAbstractSyntaxTree
* @covers \Jeremeamia\SuperClosure\ClosureParser::getFileAbstractSyntaxTree
*/
public function testCanGetClosureAst()
{
$closure = function () {};
$parser = new ClosureParser(new \ReflectionFunction($closure));
$ast = $parser->getClosureAbstractSyntaxTree();
$this->assertInstanceOf('PHPParser_Node_Expr_Closure', $ast);
}
}
<?php
namespace Jeremeamia\SuperClosure\Test;
use Jeremeamia\SuperClosure\SerializableClosure;
/**
* @covers \Jeremeamia\SuperClosure\SerializableClosure
*/
class SerializableClosureTest extends \PHPUnit_Framework_TestCase
{
/**
* @var SerializableClosure
*/
public $serializableClosure;
/**
* @var \Closure
*/
public $originalClosure;
public function setup()
{
$base = 2;
$exp = function ($power) use ($base) {
return (int) pow($base, $power);
};
$this->originalClosure = $exp;
$this->serializableClosure = new SerializableClosure($exp);
}
public function testClosureProxiesToTheOriginalClosureWhenInvoked()
{
$this->assertInstanceOf('\Closure', $this->serializableClosure->getClosure());
$this->assertSame($this->originalClosure, $this->serializableClosure->getClosure());
$this->assertEquals(
call_user_func($this->originalClosure, 4),
call_user_func($this->serializableClosure, 4)
);
}
public function testClosureBehavesTheSameAfterSerializationProcess()
{
$originalReturnValue = call_user_func($this->serializableClosure, 4);
$serializedClosure = serialize($this->serializableClosure);
$unserializedClosure = unserialize($serializedClosure);
$finalReturnValue = call_user_func($unserializedClosure, 4);
$this->assertEquals($originalReturnValue, $finalReturnValue);
}
public function testCanSerializeRecursiveClosure()
{
if (version_compare(PHP_VERSION, '5.4', '<')) {
$this->markTestSkipped('Requires version 5.4+ of PHP');
}
$factorial = new SerializableClosure(function ($n) use (&$factorial) {
return ($n <= 1) ? 1 : $n * $factorial($n - 1);
});
$this->assertEquals(120, call_user_func($factorial, 5));
}
public function testCanSerializeMultipleTimes()
{
$result = call_user_func($this->serializableClosure, 5);
$this->assertEquals(32, $result);
$serializedOnce = unserialize(serialize($this->serializableClosure));
$this->assertEquals(32, call_user_func($serializedOnce, 5));
$internalState = $this->readAttribute($serializedOnce, 'state');
$this->assertCount(2, $internalState);
$serializedAgain = unserialize(serialize($this->serializableClosure));
$this->assertEquals(32, call_user_func($serializedAgain, 5));
$this->assertEquals($internalState, $this->readAttribute($serializedAgain, 'state'));
$serializedTwice = unserialize(serialize($serializedOnce));
$this->assertEquals(32, call_user_func($serializedTwice, 5));
$this->assertEquals($internalState, $this->readAttribute($serializedTwice, 'state'));
}
/**
* CAVEAT #1: Serializing a closure will sever relationships with things passed by reference
*/
public function testDoesNotMaintainsReferencesEvenWhenVariablesAreStillInScope()
{
$num = 0;
$inc = new SerializableClosure(function () use (&$num) {
$num++;
});
$inc();
$inc();
$this->assertEquals(2, $num, '$num should be incremented twice because by reference');
$newInc = unserialize(serialize($inc));
/** @var $newInc \Closure */
$newInc();
$this->assertEquals(2, $num, '$num should not be incremented again because the reference is lost');
}
/**
* CAVEAT #2: You can't serialize a closure if there are two closures declared on one line
*/
public function testCannotDetermineWhichClosureToUseIfTwoDeclaredOnTheSameLine()
{
$this->setExpectedException('Exception');
$add = function ($a, $b) {return $a + $b;}; $sub = function ($a, $b) {return $a - $b;};
$serialized = serialize(new SerializableClosure($sub));
}
}
<?php
namespace Jeremeamia\SuperClosure\Test\Visitor;
use Jeremeamia\SuperClosure\Visitor\ClosureFinderVisitor;
/**
* @covers Jeremeamia\SuperClosure\Visitor\ClosureFinderVisitor
*/
class ClosureFinderVisitorTest extends \PHPUnit_Framework_TestCase
{
public function testClosureNodeIsDiscoveredByVisitor()
{
$closure = function () {}; // Take the line number here and set it as the "startLine"
$reflectedClosure = new \ReflectionFunction($closure);
$closureFinder = new ClosureFinderVisitor($reflectedClosure);
$closureNode = new \PHPParser_Node_Expr_Closure(array(), array('startLine' => 14));
$closureFinder->enterNode($closureNode);
$this->assertSame($closureNode, $closureFinder->getClosureNode());
}
public function testClosureNodeIsAmbiguousIfMultipleClosuresOnLine()
{
$this->setExpectedException('RuntimeException');
$closure = function () {}; function () {}; // Take the line number here and set it as the "startLine"
$closureFinder = new ClosureFinderVisitor(new \ReflectionFunction($closure));
$closureFinder->enterNode(new \PHPParser_Node_Expr_Closure(array(), array('startLine' => 27)));
$closureFinder->enterNode(new \PHPParser_Node_Expr_Closure(array(), array('startLine' => 27)));
}
public function testCalculatesClosureLocation()
{
$closure = function () {}; // Take the line number here and set it as the "startLine"
$closureFinder = new ClosureFinderVisitor(new \ReflectionFunction($closure));
$closureFinder->beforeTraverse(array());
$node = new \PHPParser_Node_Stmt_Namespace(new \PHPParser_Node_Name(array('Foo', 'Bar')));
$closureFinder->enterNode($node);
$closureFinder->leaveNode($node);
$node = new \PHPParser_Node_Stmt_Trait('Fizz');
$closureFinder->enterNode($node);
$closureFinder->leaveNode($node);
$node = new \PHPParser_Node_Stmt_Class('Buzz');
$closureFinder->enterNode($node);
$closureFinder->leaveNode($node);
$closureFinder->afterTraverse(array());
$setProperties = array_filter(get_object_vars($closureFinder->getLocation()));
$this->assertEquals(array('directory', 'file', 'function', 'line'), array_keys($setProperties));
}
}
<?php
namespace Jeremeamia\SuperClosure\Test\Visitor;
use Jeremeamia\SuperClosure\Visitor\MagicConstantVisitor;
use Jeremeamia\SuperClosure\ClosureLocation;
/**
* @covers Jeremeamia\SuperClosure\Visitor\MagicConstantVisitor
*/
class MagicConstantVisitorTest extends \PHPUnit_Framework_TestCase
{
public function testDataFromClosureLocationGetsUsed()
{
$location = new ClosureLocation();
$location->class = '[class]';
$location->directory = '[directory]';
$location->file = '[file]';
$location->function = '[function]';
$location->line = '[line]';
$location->method = '[method]';
$location->namespace = '[namespace]';
$location->trait = '[trait]';
$nodes = array(
'PHPParser_Node_Scalar_LineConst' => 'PHPParser_Node_Scalar_LNumber',
'PHPParser_Node_Scalar_FileConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_DirConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_FuncConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_NSConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_ClassConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_MethodConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_TraitConst' => 'PHPParser_Node_Scalar_String',
'PHPParser_Node_Scalar_String' => 'PHPParser_Node_Scalar_String',
);
$visitor = new MagicConstantVisitor($location);
foreach ($nodes as $originalNodeName => $resultNodeName) {
$mockNode = $this->getMockBuilder($originalNodeName)
->disableOriginalConstructor()
->setMethods(array('getType', 'getAttribute'))
->getMock();
$mockNode->expects($this->any())
->method('getAttribute')
->will($this->returnValue(1));
$mockNode->expects($this->any())
->method('getType')
->will($this->returnValue(substr($originalNodeName, 15)));
$resultNode = $visitor->leaveNode($mockNode) ?: $mockNode;
$this->assertInstanceOf($resultNodeName, $resultNode);
}
}
}
/build export-ignore
/tests export-ignore
/vendor
composer.phar
composer.lock
.DS_Store
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
before_script:
- composer self-update
- composer install --prefer-source --no-interaction --dev
script: phpunit -d memory_limit=1024M
matrix:
allow_failures:
- php: 5.6
- php: hhvm
fast_finish: true
{
"name": "laravel/framework",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.0",
"classpreloader/classpreloader": "1.0.*",
"d11wtq/boris": "1.0.*",
"ircmaxell/password-compat": "1.0.*",
"filp/whoops": "1.0.10",
"jeremeamia/superclosure": "1.0.*",
"monolog/monolog": "1.*",
"nesbot/carbon": "1.*",
"patchwork/utf8": "1.1.*",
"phpseclib/phpseclib": "0.3.*",
"predis/predis": "0.8.*",
"stack/builder": "1.0.*",
"swiftmailer/swiftmailer": "5.0.*",
"symfony/browser-kit": "2.4.*",
"symfony/console": "2.4.*",
"symfony/css-selector": "2.4.*",
"symfony/debug": "2.4.*",
"symfony/dom-crawler": "2.4.*",
"symfony/finder": "2.4.*",
"symfony/http-foundation": "2.4.*",
"symfony/http-kernel": "2.4.*",
"symfony/process": "2.4.*",
"symfony/routing": "2.4.*",
"symfony/translation": "2.4.*"
},
"replace": {
"illuminate/auth": "self.version",
"illuminate/cache": "self.version",
"illuminate/config": "self.version",
"illuminate/console": "self.version",
"illuminate/container": "self.version",
"illuminate/cookie": "self.version",
"illuminate/database": "self.version",
"illuminate/encryption": "self.version",
"illuminate/events": "self.version",
"illuminate/exception": "self.version",
"illuminate/filesystem": "self.version",
"illuminate/foundation": "self.version",
"illuminate/hashing": "self.version",
"illuminate/http": "self.version",
"illuminate/html": "self.version",
"illuminate/log": "self.version",
"illuminate/mail": "self.version",
"illuminate/pagination": "self.version",
"illuminate/queue": "self.version",
"illuminate/redis": "self.version",
"illuminate/routing": "self.version",
"illuminate/session": "self.version",
"illuminate/support": "self.version",
"illuminate/translation": "self.version",
"illuminate/validation": "self.version",
"illuminate/view": "self.version",
"illuminate/workbench": "self.version"
},
"require-dev": {
"aws/aws-sdk-php": "2.5.*",
"iron-io/iron_mq": "1.5.*",
"pda/pheanstalk": "2.1.*",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"classmap": [
["src/Illuminate/Queue/IlluminateQueueClosure.php"]
],
"files": [
"src/Illuminate/Support/helpers.php"
],
"psr-0": {
"Illuminate": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"suggest": {
"doctrine/dbal": "Allow renaming columns and dropping SQLite columns."
},
"minimum-stability": "dev"
}

Laravel Contribution Guide

This page contains guidelines for contributing to the Laravel framework. Please review these guidelines before submitting any pull requests to the framework.

Which Branch?

ALL bug fixes should be made to the 4.x branch which they belong. Bug fixes should never be sent to the master branch unless they fix features that exist only in the upcoming release.

Pull Requests

The pull request process differs for new features and bugs. Before sending a pull request for a new feature, you should first create an issue with [Proposal] in the title. The proposal should describe the new feature, as well as implementation ideas. The proposal will then be reviewed and either approved or denied. Once a proposal is approved, a pull request may be created implementing the new feature. Pull requests which do not follow this guideline will be closed immediately.

Pull requests for bugs may be sent without creating any proposal issue. If you believe that you know of a solution for a bug that has been filed on Github, please leave a comment detailing your proposed fix.

Feature Requests

If you have an idea for a new feature you would like to see added to Laravel, you may create an issue on Github with [Request] in the title. The feature request will then be reviewed by a core contributor.

Coding Guidelines

Laravel follows the PSR-0 and PSR-1 coding standards. In addition to these standards, below is a list of other coding standards that should be followed:

  • Namespace declarations should be on the same line as <?php.
  • Class opening { should be on the same line as the class name.
  • Function and control structure opening { should be on a separate line.
  • Interface names are suffixed with Interface (FooInterface)
The MIT License (MIT)
Copyright (c) <Taylor Otwell>
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.
<?php
/*
|--------------------------------------------------------------------------
| Register The Composer Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Set The Default Timezone
|--------------------------------------------------------------------------
|
| Here we will set the default timezone for PHP. PHP is notoriously mean
| if the timezone is not explicitly set. This will be used by each of
| the PHP date and date-time functions throughout the application.
|
*/
date_default_timezone_set('UTC');
Carbon\Carbon::setTestNow(Carbon\Carbon::now());
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="phpunit.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Laravel Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">src</directory>
<exclude>
<directory suffix=".php">vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

Laravel Framework (Kernel)

Latest Stable Version Total Downloads Build Status Dependency Status

Note: This repository contains the core code of the Laravel framework. If you want to build an application using Laravel 4, visit the main Laravel repository.

Laravel PHP Framework

Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, and caching.

Laravel aims to make the development process a pleasing one for the developer without sacrificing application functionality. Happy developers make the best code. To this end, we've attempted to combine the very best of what we have seen in other web frameworks, including frameworks implemented in other languages, such as Ruby on Rails, ASP.NET MVC, and Sinatra.

Laravel is accessible, yet powerful, providing powerful tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked.

Official Documentation

Documentation for the entire framework can be found on the Laravel website.

Contributing

Thank you for considering contributing to the Laravel framework. If you are submitting a bug-fix, or an enhancement that is not a breaking change, submit your pull request to the branch corresponding to the latest stable release of the framework, such as the 4.1 branch. If you are submitting a breaking change or an entirely new component, submit your pull request to the master branch.

License

The Laravel framework is open-sourced software licensed under the MIT license

<?php namespace Illuminate\Auth;
use Illuminate\Support\Manager;
class AuthManager extends Manager {
/**
* Create a new driver instance.
*
* @param string $driver
* @return mixed
*/
protected function createDriver($driver)
{
$guard = parent::createDriver($driver);
// When using the remember me functionality of the authentication services we
// will need to be set the encryption instance of the guard, which allows
// secure, encrypted cookie values to get generated for those cookies.
$guard->setCookieJar($this->app['cookie']);
$guard->setDispatcher($this->app['events']);
return $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
}
/**
* Call a custom driver creator.
*
* @param string $driver
* @return mixed
*/
protected function callCustomCreator($driver)
{
$custom = parent::callCustomCreator($driver);
if ($custom instanceof Guard) return $custom;
return new Guard($custom, $this->app['session.store']);
}
/**
* Create an instance of the database driver.
*
* @return \Illuminate\Auth\Guard
*/
public function createDatabaseDriver()
{
$provider = $this->createDatabaseProvider();
return new Guard($provider, $this->app['session.store']);
}
/**
* Create an instance of the database user provider.
*
* @return \Illuminate\Auth\DatabaseUserProvider
*/
protected function createDatabaseProvider()
{
$connection = $this->app['db']->connection();
// When using the basic database user provider, we need to inject the table we
// want to use, since this is not an Eloquent model we will have no way to
// know without telling the provider, so we'll inject the config value.
$table = $this->app['config']['auth.table'];
return new DatabaseUserProvider($connection, $this->app['hash'], $table);
}
/**
* Create an instance of the Eloquent driver.
*
* @return \Illuminate\Auth\Guard
*/
public function createEloquentDriver()
{
$provider = $this->createEloquentProvider();
return new Guard($provider, $this->app['session.store']);
}
/**
* Create an instance of the Eloquent user provider.
*
* @return \Illuminate\Auth\EloquentUserProvider
*/
protected function createEloquentProvider()
{
$model = $this->app['config']['auth.model'];
return new EloquentUserProvider($this->app['hash'], $model);
}
/**
* Get the default authentication driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['auth.driver'];
}
/**
* Set the default authentication driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['auth.driver'] = $name;
}
}
<?php namespace Illuminate\Auth;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bindShared('auth', function($app)
{
// Once the authentication service has actually been requested by the developer
// we will set a variable in the application indicating such. This helps us
// know that we need to set any queued cookies in the after event later.
$app['auth.loaded'] = true;
return new AuthManager($app);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('auth');
}
}
{
"name": "illuminate/auth",
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/cookie": "4.1.*",
"illuminate/encryption": "4.1.*",
"illuminate/events": "4.1.*",
"illuminate/hashing": "4.1.*",
"illuminate/http": "4.1.*",
"illuminate/session": "4.1.*",
"illuminate/support": "4.1.*",
"nesbot/carbon": "1.*"
},
"require-dev": {
"illuminate/console": "4.1.*",
"illuminate/routing": "4.1.*",
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {"Illuminate\\Auth": ""}
},
"target-dir": "Illuminate/Auth",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"minimum-stability": "dev"
}
<?php namespace Illuminate\Auth\Console;
use Illuminate\Console\Command;
class ClearRemindersCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'auth:clear-reminders';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush expired reminders.';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['auth.reminder.repository']->deleteExpired();
$this->info('Expired reminders cleared!');
}
}
<?php namespace Illuminate\Auth\Console;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
class RemindersControllerCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'auth:reminders-controller';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a stub password reminder controller';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new reminder table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files)
{
parent::__construct();
$this->files = $files;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$destination = $this->laravel['path'].'/controllers/RemindersController.php';
if ( ! $this->files->exists($destination))
{
$this->files->copy(__DIR__.'/stubs/controller.stub', $destination);
$this->info('Password reminders controller created successfully!');
$this->comment("Route: Route::controller('password', 'RemindersController');");
}
else
{
$this->error('Password reminders controller already exists!');
}
}
}
<?php namespace Illuminate\Auth\Console;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
class RemindersTableCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'auth:reminders-table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the password reminders table';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new reminder table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files)
{
parent::__construct();
$this->files = $files;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$fullPath = $this->createBaseMigration();
$this->files->put($fullPath, $this->getMigrationStub());
$this->info('Migration created successfully!');
$this->call('dump-autoload');
}
/**
* Create a base migration file for the reminders.
*
* @return string
*/
protected function createBaseMigration()
{
$name = 'create_password_reminders_table';
$path = $this->laravel['path'].'/database/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
/**
* Get the contents of the reminder migration stub.
*
* @return string
*/
protected function getMigrationStub()
{
$stub = $this->files->get(__DIR__.'/stubs/reminders.stub');
return str_replace('password_reminders', $this->getTable(), $stub);
}
/**
* Get the password reminder table name.
*
* @return string
*/
protected function getTable()
{
return $this->laravel['config']->get('auth.reminder.table');
}
}
<?php
class RemindersController extends Controller {
/**
* Display the password reminder view.
*
* @return Response
*/
public function getRemind()
{
return View::make('password.remind');
}
/**
* Handle a POST request to remind a user of their password.
*
* @return Response
*/
public function postRemind()
{
switch ($response = Password::remind(Input::only('email')))
{
case Password::INVALID_USER:
return Redirect::back()->with('error', Lang::get($response));
case Password::REMINDER_SENT:
return Redirect::back()->with('status', Lang::get($response));
}
}
/**
* Display the password reset view for the given token.
*
* @param string $token
* @return Response
*/
public function getReset($token = null)
{
if (is_null($token)) App::abort(404);
return View::make('password.reset')->with('token', $token);
}
/**
* Handle a POST request to reset a user's password.
*
* @return Response
*/
public function postReset()
{
$credentials = Input::only(
'email', 'password', 'password_confirmation', 'token'
);
$response = Password::reset($credentials, function($user, $password)
{
$user->password = Hash::make($password);
$user->save();
});
switch ($response)
{
case Password::INVALID_PASSWORD:
case Password::INVALID_TOKEN:
case Password::INVALID_USER:
return Redirect::back()->with('error', Lang::get($response));
case Password::PASSWORD_RESET:
return Redirect::to('/');
}
}
}
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePasswordRemindersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('password_reminders', function(Blueprint $table)
{
$table->string('email')->index();
$table->string('token')->index();
$table->timestamp('created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('password_reminders');
}
}
<?php namespace Illuminate\Auth;
use Illuminate\Database\Connection;
use Illuminate\Hashing\HasherInterface;
class DatabaseUserProvider implements UserProviderInterface {
/**
* The active database connection.
*
* @param \Illuminate\Database\Connection
*/
protected $conn;
/**
* The hasher implementation.
*
* @var \Illuminate\Hashing\HasherInterface
*/
protected $hasher;
/**
* The table containing the users.
*
* @var string
*/
protected $table;
/**
* Create a new database user provider.
*
* @param \Illuminate\Database\Connection $conn
* @param \Illuminate\Hashing\HasherInterface $hasher
* @param string $table
* @return void
*/
public function __construct(Connection $conn, HasherInterface $hasher, $table)
{
$this->conn = $conn;
$this->table = $table;
$this->hasher = $hasher;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier)
{
$user = $this->conn->table($this->table)->find($identifier);
if ( ! is_null($user))
{
return new GenericUser((array) $user);
}
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// generic "user" object that will be utilized by the Guard instances.
$query = $this->conn->table($this->table);
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password'))
{
$query->where($key, $value);
}
}
// Now we are ready to execute the query to see if we have an user matching
// the given credentials. If not, we will just return nulls and indicate
// that there are no matching users for these given credential arrays.
$user = $query->first();
if ( ! is_null($user))
{
return new GenericUser((array) $user);
}
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Auth\UserInterface $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserInterface $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
}
<?php namespace Illuminate\Auth;
use Illuminate\Hashing\HasherInterface;
class EloquentUserProvider implements UserProviderInterface {
/**
* The hasher implementation.
*
* @var \Illuminate\Hashing\HasherInterface
*/
protected $hasher;
/**
* The Eloquent user model.
*
* @var string
*/
protected $model;
/**
* Create a new database user provider.
*
* @param \Illuminate\Hashing\HasherInterface $hasher
* @param string $model
* @return void
*/
public function __construct(HasherInterface $hasher, $model)
{
$this->model = $model;
$this->hasher = $hasher;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier)
{
return $this->createModel()->newQuery()->find($identifier);
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password')) $query->where($key, $value);
}
return $query->first();
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Auth\UserInterface $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserInterface $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
/**
* Create a new instance of the model.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function createModel()
{
$class = '\\'.ltrim($this->model, '\\');
return new $class;
}
}
<?php namespace Illuminate\Auth;
class GenericUser implements UserInterface {
/**
* All of the user's attributes.
*
* @var array
*/
protected $attributes;
/**
* Create a new generic User object.
*
* @param array $attributes
* @return void
*/
public function __construct(array $attributes)
{
$this->attributes = $attributes;
}
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->attributes['id'];
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->attributes['password'];
}
/**
* Dynamically access the user's attributes.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this->attributes[$key];
}
/**
* Dynamically set an attribute on the user.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
$this->attributes[$key] = $value;
}
/**
* Dynamically check if a value is set on the user.
*
* @param string $key
* @return bool
*/
public function __isset($key)
{
return isset($this->attributes[$key]);
}
/**
* Dynamically unset a value on the user.
*
* @param string $key
* @return bool
*/
public function __unset($key)
{
unset($this->attributes[$key]);
}
}
<?php namespace Illuminate\Auth;
use Illuminate\Cookie\CookieJar;
use Illuminate\Events\Dispatcher;
use Symfony\Component\HttpFoundation\Request;
use Illuminate\Session\Store as SessionStore;
use Symfony\Component\HttpFoundation\Response;
class Guard {
/**
* The currently authenticated user.
*
* @var \Illuminate\Auth\UserInterface
*/
protected $user;
/**
* The user we last attempted to retrieve.
*
* @var \Illuminate\Auth\UserInterface
*/
protected $lastAttempted;
/**
* Indicates if the user was authenticated via a recaller cookie.
*
* @var bool
*/
protected $viaRemember = false;
/**
* The user provider implementation.
*
* @var \Illuminate\Auth\UserProviderInterface
*/
protected $provider;
/**
* The session store used by the guard.
*
* @var \Illuminate\Session\Store
*/
protected $session;
/**
* The Illuminate cookie creator service.
*
* @var \Illuminate\Cookie\CookieJar
*/
protected $cookie;
/**
* The request instance.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Events\Dispatcher
*/
protected $events;
/**
* Indicates if the logout method has been called.
*
* @var bool
*/
protected $loggedOut = false;
/**
* Create a new authentication guard.
*
* @param \Illuminate\Auth\UserProviderInterface $provider
* @param \Illuminate\Session\Store $session
* @return void
*/
public function __construct(UserProviderInterface $provider,
SessionStore $session,
Request $request = null)
{
$this->session = $session;
$this->request = $request;
$this->provider = $provider;
}
/**
* Determine if the current user is authenticated.
*
* @return bool
*/
public function check()
{
return ! is_null($this->user());
}
/**
* Determine if the current user is a guest.
*
* @return bool
*/
public function guest()
{
return ! $this->check();
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Auth\UserInterface|null
*/
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveByID($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
}
return $this->user = $user;
}
/**
* Pull a user from the repository by its recaller ID.
*
* @param mixed $id
* @return mixed
*/
protected function getUserByRecaller($id)
{
$this->viaRemember = ! is_null($user = $this->provider->retrieveByID($id));
return $user;
}
/**
* Get the decrypted recaller cookie for the request.
*
* @return string|null
*/
protected function getRecaller()
{
return $this->request->cookies->get($this->getRecallerName());
}
/**
* Log a user into the application without sessions or cookies.
*
* @param array $credentials
* @return bool
*/
public function once(array $credentials = array())
{
if ($this->validate($credentials))
{
$this->setUser($this->lastAttempted);
return true;
}
return false;
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = array())
{
return $this->attempt($credentials, false, false);
}
/**
* Attempt to authenticate using HTTP Basic Auth.
*
* @param string $field
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function basic($field = 'email', Request $request = null)
{
if ($this->check()) return;
$request = $request ?: $this->getRequest();
// If a username is set on the HTTP basic request, we will return out without
// interrupting the request lifecycle. Otherwise, we'll need to generate a
// request indicating that the given credentials were invalid for login.
if ($this->attemptBasic($request, $field)) return;
return $this->getBasicResponse();
}
/**
* Perform a stateless HTTP Basic login attempt.
*
* @param string $field
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function onceBasic($field = 'email', Request $request = null)
{
$request = $request ?: $this->getRequest();
if ( ! $this->once($this->getBasicCredentials($request, $field)))
{
return $this->getBasicResponse();
}
}
/**
* Attempt to authenticate using basic authentication.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $field
* @return bool
*/
protected function attemptBasic(Request $request, $field)
{
if ( ! $request->getUser()) return false;
return $this->attempt($this->getBasicCredentials($request, $field));
}
/**
* Get the credential array for a HTTP Basic request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $field
* @return array
*/
protected function getBasicCredentials(Request $request, $field)
{
return array($field => $request->getUser(), 'password' => $request->getPassword());
}
/**
* Get the response for basic authentication.
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getBasicResponse()
{
$headers = array('WWW-Authenticate' => 'Basic');
return new Response('Invalid credentials.', 401, $headers);
}
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return bool
*/
public function attempt(array $credentials = array(), $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials))
{
if ($login) $this->login($user, $remember);
return true;
}
return false;
}
/**
* Determine if the user matches the credentials.
*
* @param mixed $user
* @param array $credentials
* @return bool
*/
protected function hasValidCredentials($user, $credentials)
{
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
/**
* Fire the attempt event with the arguments.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return void
*/
protected function fireAttemptEvent(array $credentials, $remember, $login)
{
if ($this->events)
{
$payload = array($credentials, $remember, $login);
$this->events->fire('auth.attempt', $payload);
}
}
/**
* Register an authentication attempt event listener.
*
* @param mixed $callback
* @return void
*/
public function attempting($callback)
{
if ($this->events)
{
$this->events->listen('auth.attempt', $callback);
}
}
/**
* Log a user into the application.
*
* @param \Illuminate\Auth\UserInterface $user
* @param bool $remember
* @return void
*/
public function login(UserInterface $user, $remember = false)
{
$this->updateSession($id = $user->getAuthIdentifier());
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember)
{
$this->queueRecallerCookie($id);
}
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
if (isset($this->events))
{
$this->events->fire('auth.login', array($user, $remember));
}
$this->setUser($user);
}
/**
* Update the session with the given ID.
*
* @param string $id
* @return void
*/
protected function updateSession($id)
{
$this->session->put($this->getName(), $id);
$this->session->migrate(true);
}
/**
* Log the given user ID into the application.
*
* @param mixed $id
* @param bool $remember
* @return \Illuminate\Auth\UserInterface
*/
public function loginUsingId($id, $remember = false)
{
$this->session->put($this->getName(), $id);
$this->login($user = $this->provider->retrieveById($id), $remember);
return $user;
}
/**
* Log the given user ID into the application without sessions or cookies.
*
* @param mixed $id
* @return bool
*/
public function onceUsingId($id)
{
$this->setUser($this->provider->retrieveById($id));
return $this->user instanceof UserInterface;
}
/**
* Queue the recaller cookie into the cookie jar.
*
* @param string $id
* @return void
*/
protected function queueRecallerCookie($id)
{
$this->getCookieJar()->queue($this->createRecaller($id));
}
/**
* Create a remember me cookie for a given ID.
*
* @param mixed $id
* @return \Symfony\Component\HttpFoundation\Cookie
*/
protected function createRecaller($id)
{
return $this->getCookieJar()->forever($this->getRecallerName(), $id);
}
/**
* Log the user out of the application.
*
* @return void
*/
public function logout()
{
$user = $this->user();
// If we have an event dispatcher instance, we can fire off the logout event
// so any further processing can be done. This allows the developer to be
// listening for anytime a user signs out of this application manually.
$this->clearUserDataFromStorage();
if (isset($this->events))
{
$this->events->fire('auth.logout', array($user));
}
// Once we have fired the logout event we will clear the users out of memory
// so they are no longer available as the user is no longer considered as
// being signed into this application and should not be available here.
$this->user = null;
$this->loggedOut = true;
}
/**
* Remove the user data from the session and cookies.
*
* @return void
*/
protected function clearUserDataFromStorage()
{
$this->session->forget($this->getName());
$recaller = $this->getRecallerName();
$this->getCookieJar()->queue($this->getCookieJar()->forget($recaller));
}
/**
* Get the cookie creator instance used by the guard.
*
* @return \Illuminate\Cookie\CookieJar
*
* @throws \RuntimeException
*/
public function getCookieJar()
{
if ( ! isset($this->cookie))
{
throw new \RuntimeException("Cookie jar has not been set.");
}
return $this->cookie;
}
/**
* Set the cookie creator instance used by the guard.
*
* @param \Illuminate\Cookie\CookieJar $cookie
* @return void
*/
public function setCookieJar(CookieJar $cookie)
{
$this->cookie = $cookie;
}
/**
* Get the event dispatcher instance.
*
* @return \Illuminate\Events\Dispatcher
*/
public function getDispatcher()
{
return $this->events;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Events\Dispatcher
*/
public function setDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Get the session store used by the guard.
*
* @return \Illuminate\Session\Store
*/
public function getSession()
{
return $this->session;
}
/**
* Get the user provider used by the guard.
*
* @return \Illuminate\Auth\UserProviderInterface
*/
public function getProvider()
{
return $this->provider;
}
/**
* Set the user provider used by the guard.
*
* @param \Illuminate\Auth\UserProviderInterface $provider
* @return void
*/
public function setProvider(UserProviderInterface $provider)
{
$this->provider = $provider;
}
/**
* Return the currently cached user of the application.
*
* @return \Illuminate\Auth\UserInterface|null
*/
public function getUser()
{
return $this->user;
}
/**
* Set the current user of the application.
*
* @param \Illuminate\Auth\UserInterface $user
* @return void
*/
public function setUser(UserInterface $user)
{
$this->user = $user;
$this->loggedOut = false;
}
/**
* Get the current request instance.
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
{
return $this->request ?: Request::createFromGlobals();
}
/**
* Set the current request instance.
*
* @param \Symfony\Component\HttpFoundation\Request
* @return \Illuminate\Auth\Guard
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
/**
* Get the last user we attempted to authenticate.
*
* @return \Illuminate\Auth\UserInterface
*/
public function getLastAttempted()
{
return $this->lastAttempted;
}
/**
* Get a unique identifier for the auth session value.
*
* @return string
*/
public function getName()
{
return 'login_'.md5(get_class($this));
}
/**
* Get the name of the cookie used to store the "recaller".
*
* @return string
*/
public function getRecallerName()
{
return 'remember_'.md5(get_class($this));
}
/**
* Determine if the user was authenticated via "remember me" cookie.
*
* @return bool
*/
public function viaRemember()
{
return $this->viaRemember;
}
}
<?php namespace Illuminate\Auth\Reminders;
use Carbon\Carbon;
use Illuminate\Database\Connection;
class DatabaseReminderRepository implements ReminderRepositoryInterface {
/**
* The database connection instance.
*
* @var \Illuminate\Database\Connection
*/
protected $connection;
/**
* The reminder database table.
*
* @var string
*/
protected $table;
/**
* The hashing key.
*
* @var string
*/
protected $hashKey;
/**
* The number of seconds a reminder should last.
*
* @var int
*/
protected $expires;
/**
* Create a new reminder repository instance.
*
* @param \Illuminate\Database\Connection $connection
* @param string $table
* @param string $hashKey
* @param int $expires
* @return void
*/
public function __construct(Connection $connection, $table, $hashKey, $expires = 60)
{
$this->table = $table;
$this->hashKey = $hashKey;
$this->expires = $expires * 60;
$this->connection = $connection;
}
/**
* Create a new reminder record and token.
*
* @param \Illuminate\Auth\Reminders\RemindableInterface $user
* @return string
*/
public function create(RemindableInterface $user)
{
$email = $user->getReminderEmail();
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken($user);
$this->getTable()->insert($this->getPayload($email, $token));
return $token;
}
/**
* Build the record payload for the table.
*
* @param string $email
* @param string $token
* @return array
*/
protected function getPayload($email, $token)
{
return array('email' => $email, 'token' => $token, 'created_at' => new Carbon);
}
/**
* Determine if a reminder record exists and is valid.
*
* @param \Illuminate\Auth\Reminders\RemindableInterface $user
* @param string $token
* @return bool
*/
public function exists(RemindableInterface $user, $token)
{
$email = $user->getReminderEmail();
$reminder = $this->getTable()->where('email', $email)->where('token', $token)->first();
return $reminder && ! $this->reminderExpired($reminder);
}
/**
* Determine if the reminder has expired.
*
* @param object $reminder
* @return bool
*/
protected function reminderExpired($reminder)
{
$createdPlusHour = strtotime($reminder->created_at) + $this->expires;
return $createdPlusHour < $this->getCurrentTime();
}
/**
* Get the current UNIX timestamp.
*
* @return int
*/
protected function getCurrentTime()
{
return time();
}
/**
* Delete a reminder record by token.
*
* @param string $token
* @return void
*/
public function delete($token)
{
$this->getTable()->where('token', $token)->delete();
}
/**
* Delete expired reminders.
*
* @return void
*/
public function deleteExpired()
{
$expired = Carbon::now()->subSeconds($this->expires);
$this->getTable()->where('created_at', '<', $expired)->delete();
}
/**
* Create a new token for the user.
*
* @param \Illuminate\Auth\Reminders\RemindableInterface $user
* @return string
*/
public function createNewToken(RemindableInterface $user)
{
$email = $user->getReminderEmail();
$value = str_shuffle(sha1($email.spl_object_hash($this).microtime(true)));
return hash_hmac('sha1', $value, $this->hashKey);
}
/**
* Begin a new database query against the table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->connection->table($this->table);
}
/**
* Get the database connection instance.
*
* @return \Illuminate\Database\Connection
*/
public function getConnection()
{
return $this->connection;
}
}
<?php namespace Illuminate\Auth\Reminders;
use Closure;
use Illuminate\Mail\Mailer;
use Illuminate\Auth\UserProviderInterface;
class PasswordBroker {
/**
* Constant representing a successfully sent reminder.
*
* @var int
*/
const REMINDER_SENT = 'reminders.sent';
/**
* Constant representing a successfully reset password.
*
* @var int
*/
const PASSWORD_RESET = 'reminders.reset';
/**
* Constant representing the user not found response.
*
* @var int
*/
const INVALID_USER = 'reminders.user';
/**
* Constant representing an invalid password.
*
* @var int
*/
const INVALID_PASSWORD = 'reminders.password';
/**
* Constant representing an invalid token.
*
* @var int
*/
const INVALID_TOKEN = 'reminders.token';
/**
* The password reminder repository.
*
* @var \Illuminate\Auth\Reminders\ReminderRepositoryInterface $reminders
*/
protected $reminders;
/**
* The user provider implementation.
*
* @var \Illuminate\Auth\UserProviderInterface
*/
protected $users;
/**
* The mailer instance.
*
* @var \Illuminate\Mail\Mailer
*/
protected $mailer;
/**
* The view of the password reminder e-mail.
*
* @var string
*/
protected $reminderView;
/**
* The custom password validator callback.
*
* @var \Closure
*/
protected $passwordValidator;
/**
* Create a new password broker instance.
*
* @param \Illuminate\Auth\Reminders\ReminderRepositoryInterface $reminders
* @param \Illuminate\Auth\UserProviderInterface $users
* @param \Illuminate\Mail\Mailer $mailer
* @param string $reminderView
* @return void
*/
public function __construct(ReminderRepositoryInterface $reminders,
UserProviderInterface $users,
Mailer $mailer,
$reminderView)
{
$this->users = $users;
$this->mailer = $mailer;
$this->reminders = $reminders;
$this->reminderView = $reminderView;
}
/**
* Send a password reminder to a user.
*
* @param array $credentials
* @param Closure $callback
* @return string
*/
public function remind(array $credentials, Closure $callback = null)
{
// First we will check to see if we found a user at the given credentials and
// if we did not we will redirect back to this current URI with a piece of
// "flash" data in the session to indicate to the developers the errors.
$user = $this->getUser($credentials);
if (is_null($user))
{
return self::INVALID_USER;
}
// Once we have the reminder token, we are ready to send a message out to the
// user with a link to reset their password. We will then redirect back to
// the current URI having nothing set in the session to indicate errors.
$token = $this->reminders->create($user);
$this->sendReminder($user, $token, $callback);
return self::REMINDER_SENT;
}
/**
* Send the password reminder e-mail.
*
* @param \Illuminate\Auth\Reminders\RemindableInterface $user
* @param string $token
* @param Closure $callback
* @return void
*/
public function sendReminder(RemindableInterface $user, $token, Closure $callback = null)
{
// We will use the reminder view that was given to the broker to display the
// password reminder e-mail. We'll pass a "token" variable into the views
// so that it may be displayed for an user to click for password reset.
$view = $this->reminderView;
return $this->mailer->send($view, compact('token', 'user'), function($m) use ($user, $token, $callback)
{
$m->to($user->getReminderEmail());
if ( ! is_null($callback)) call_user_func($callback, $m, $user, $token);
});
}
/**
* Reset the password for the given token.
*
* @param array $credentials
* @param Closure $callback
* @return mixed
*/
public function reset(array $credentials, Closure $callback)
{
// If the responses from the validate method is not a user instance, we will
// assume that it is a redirect and simply return it from this method and
// the user is properly redirected having an error message on the post.
$user = $this->validateReset($credentials);
if ( ! $user instanceof RemindableInterface)
{
return $user;
}
$pass = $credentials['password'];
// Once we have called this callback, we will remove this token row from the
// table and return the response from this callback so the user gets sent
// to the destination given by the developers from the callback return.
call_user_func($callback, $user, $pass);
$this->reminders->delete($credentials['token']);
return self::PASSWORD_RESET;
}
/**
* Validate a password reset for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\Reminders\RemindableInterface
*/
protected function validateReset(array $credentials)
{
if (is_null($user = $this->getUser($credentials)))
{
return self::INVALID_USER;
}
if ( ! $this->validNewPasswords($credentials))
{
return self::INVALID_PASSWORD;
}
if ( ! $this->reminders->exists($user, $credentials['token']))
{
return self::INVALID_TOKEN;
}
return $user;
}
/**
* Set a custom password validator.
*
* @param \Closure $callback
* @return void
*/
public function validator(Closure $callback)
{
$this->passwordValidator = $callback;
}
/**
* Determine if the passwords match for the request.
*
* @param array $credentials
* @return bool
*/
protected function validNewPasswords(array $credentials)
{
list($password, $confirm) = array($credentials['password'], $credentials['password_confirmation']);
if (isset($this->passwordValidator))
{
return call_user_func($this->passwordValidator, $credentials) && $password == $confirm;
}
else
{
return $this->validatePasswordWithDefaults($credentials);
}
}
/**
* Determine if the passwords are valid for the request.
*
* @param array $credentials
* @return bool
*/
protected function validatePasswordWithDefaults(array $credentials)
{
$matches = $credentials['password'] == $credentials['password_confirmation'];
return $matches && $credentials['password'] && strlen($credentials['password']) >= 6;
}
/**
* Get the user for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\Reminders\RemindableInterface
*
* @throws \UnexpectedValueException
*/
public function getUser(array $credentials)
{
$credentials = array_except($credentials, array('token'));
$user = $this->users->retrieveByCredentials($credentials);
if ($user && ! $user instanceof RemindableInterface)
{
throw new \UnexpectedValueException("User must implement Remindable interface.");
}
return $user;
}
/**
* Get the password reminder repository implementation.
*
* @return \Illuminate\Auth\Reminders\ReminderRepositoryInterface
*/
protected function getRepository()
{
return $this->reminders;
}
}
<?php namespace Illuminate\Auth\Reminders;
interface RemindableInterface {
/**
* Get the e-mail address where password reminders are sent.
*
* @return string
*/
public function getReminderEmail();
}
<?php namespace Illuminate\Auth\Reminders;
interface ReminderRepositoryInterface {
/**
* Create a new reminder record and token.
*
* @param \Illuminate\Auth\Reminders\RemindableInterface $user
* @return string
*/
public function create(RemindableInterface $user);
/**
* Determine if a reminder record exists and is valid.
*
* @param \Illuminate\Auth\Reminders\RemindableInterface $user
* @param string $token
* @return bool
*/
public function exists(RemindableInterface $user, $token);
/**
* Delete a reminder record by token.
*
* @param string $token
* @return void
*/
public function delete($token);
/**
* Delete expired reminders.
*
* @return void
*/
public function deleteExpired();
}
<?php namespace Illuminate\Auth\Reminders;
use Illuminate\Support\ServiceProvider;
use Illuminate\Auth\Console\RemindersTableCommand;
use Illuminate\Auth\Console\ClearRemindersCommand;
use Illuminate\Auth\Console\RemindersControllerCommand;
use Illuminate\Auth\Reminders\DatabaseReminderRepository as DbRepository;
class ReminderServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerPasswordBroker();
$this->registerReminderRepository();
$this->registerCommands();
}
/**
* Register the password broker instance.
*
* @return void
*/
protected function registerPasswordBroker()
{
$this->app->bindShared('auth.reminder', function($app)
{
// The reminder repository is responsible for storing the user e-mail addresses
// and password reset tokens. It will be used to verify the tokens are valid
// for the given e-mail addresses. We will resolve an implementation here.
$reminders = $app['auth.reminder.repository'];
$users = $app['auth']->driver()->getProvider();
$view = $app['config']['auth.reminder.email'];
// The password broker uses the reminder repository to validate tokens and send
// reminder e-mails, as well as validating that password reset process as an
// aggregate service of sorts providing a convenient interface for resets.
return new PasswordBroker(
$reminders, $users, $app['mailer'], $view
);
});
}
/**
* Register the reminder repository implementation.
*
* @return void
*/
protected function registerReminderRepository()
{
$this->app->bindShared('auth.reminder.repository', function($app)
{
$connection = $app['db']->connection();
// The database reminder repository is an implementation of the reminder repo
// interface, and is responsible for the actual storing of auth tokens and
// their e-mail addresses. We will inject this table and hash key to it.
$table = $app['config']['auth.reminder.table'];
$key = $app['config']['app.key'];
$expire = $app['config']->get('auth.reminder.expire', 60);
return new DbRepository($connection, $table, $key, $expire);
});
}
/**
* Register the auth related console commands.
*
* @return void
*/
protected function registerCommands()
{
$this->app->bindShared('command.auth.reminders', function($app)
{
return new RemindersTableCommand($app['files']);
});
$this->app->bindShared('command.auth.reminders.clear', function($app)
{
return new ClearRemindersCommand;
});
$this->app->bindShared('command.auth.reminders.controller', function($app)
{
return new RemindersControllerCommand($app['files']);
});
$this->commands(
'command.auth.reminders', 'command.auth.reminders.clear', 'command.auth.reminders.controller'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('auth.reminder', 'auth.reminder.repository', 'command.auth.reminders');
}
}
<?php namespace Illuminate\Auth;
interface UserInterface {
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier();
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword();
}
<?php namespace Illuminate\Auth;
interface UserProviderInterface {
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier);
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByCredentials(array $credentials);
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Auth\UserInterface $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserInterface $user, array $credentials);
}
<?php namespace Illuminate\Cache;
class ApcStore extends TaggableStore implements StoreInterface {
/**
* The APC wrapper instance.
*
* @var \Illuminate\Cache\ApcWrapper
*/
protected $apc;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new APC store.
*
* @param \Illuminate\Cache\ApcWrapper $apc
* @param string $prefix
* @return void
*/
public function __construct(ApcWrapper $apc, $prefix = '')
{
$this->apc = $apc;
$this->prefix = $prefix;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = $this->apc->get($this->prefix.$key);
if ($value !== false)
{
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return array|bool
*/
public function put($key, $value, $minutes)
{
$this->apc->put($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return array|bool
*/
public function increment($key, $value = 1)
{
return $this->apc->increment($this->prefix.$key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return array|bool
*/
public function decrement($key, $value = 1)
{
return $this->apc->decrement($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return array|bool
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return array|bool
*/
public function forget($key)
{
$this->apc->delete($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->apc->flush();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}
<?php namespace Illuminate\Cache;
class ApcWrapper {
/**
* Indicates if APCu is supported.
*
* @var bool
*/
protected $apcu = false;
/**
* Create a new APC wrapper instance.
*
* @return void
*/
public function __construct()
{
$this->apcu = function_exists('apcu_fetch');
}
/**
* Get an item from the cache.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
return $this->apcu ? apcu_fetch($key) : apc_fetch($key);
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param int $seconds
* @return array|bool
*/
public function put($key, $value, $seconds)
{
return $this->apcu ? apcu_store($key, $value, $seconds) : apc_store($key, $value, $seconds);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return array|bool
*/
public function increment($key, $value)
{
return $this->apcu ? apcu_inc($key, $value) : apc_inc($key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return array|bool
*/
public function decrement($key, $value)
{
return $this->apcu ? apcu_dec($key, $value) : apc_dec($key, $value);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return array|bool
*/
public function delete($key)
{
return $this->apcu ? apcu_delete($key) : apc_delete($key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->apcu ? apcu_clear_cache() : apc_clear_cache('user');
}
}
<?php namespace Illuminate\Cache;
class ArrayStore extends TaggableStore implements StoreInterface {
/**
* The array of stored values.
*
* @var array
*/
protected $storage = array();
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
if (array_key_exists($key, $this->storage))
{
return $this->storage[$key];
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->storage[$key] = $value;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
$this->storage[$key] = $this->storage[$key] + $value;
return $this->storage[$key];
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
$this->storage[$key] = $this->storage[$key] - $value;
return $this->storage[$key];
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
unset($this->storage[$key]);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->storage = array();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
}
<?php namespace Illuminate\Cache;
use Illuminate\Support\Manager;
class CacheManager extends Manager {
/**
* Create an instance of the APC cache driver.
*
* @return \Illuminate\Cache\ApcStore
*/
protected function createApcDriver()
{
return $this->repository(new ApcStore(new ApcWrapper, $this->getPrefix()));
}
/**
* Create an instance of the array cache driver.
*
* @return \Illuminate\Cache\ArrayStore
*/
protected function createArrayDriver()
{
return $this->repository(new ArrayStore);
}
/**
* Create an instance of the file cache driver.
*
* @return \Illuminate\Cache\FileStore
*/
protected function createFileDriver()
{
$path = $this->app['config']['cache.path'];
return $this->repository(new FileStore($this->app['files'], $path));
}
/**
* Create an instance of the Memcached cache driver.
*
* @return \Illuminate\Cache\MemcachedStore
*/
protected function createMemcachedDriver()
{
$servers = $this->app['config']['cache.memcached'];
$memcached = $this->app['memcached.connector']->connect($servers);
return $this->repository(new MemcachedStore($memcached, $this->getPrefix()));
}
/**
* Create an instance of the WinCache cache driver.
*
* @return \Illuminate\Cache\WinCacheStore
*/
protected function createWincacheDriver()
{
return $this->repository(new WinCacheStore($this->getPrefix()));
}
/**
* Create an instance of the XCache cache driver.
*
* @return \Illuminate\Cache\WinCacheStore
*/
protected function createXcacheDriver()
{
return $this->repository(new XCacheStore($this->getPrefix()));
}
/**
* Create an instance of the Redis cache driver.
*
* @return \Illuminate\Cache\RedisStore
*/
protected function createRedisDriver()
{
$redis = $this->app['redis'];
return $this->repository(new RedisStore($redis, $this->getPrefix()));
}
/**
* Create an instance of the database cache driver.
*
* @return \Illuminate\Cache\DatabaseStore
*/
protected function createDatabaseDriver()
{
$connection = $this->getDatabaseConnection();
$encrypter = $this->app['encrypter'];
// We allow the developer to specify which connection and table should be used
// to store the cached items. We also need to grab a prefix in case a table
// is being used by multiple applications although this is very unlikely.
$table = $this->app['config']['cache.table'];
$prefix = $this->getPrefix();
return $this->repository(new DatabaseStore($connection, $encrypter, $table, $prefix));
}
/**
* Get the database connection for the database driver.
*
* @return \Illuminate\Database\Connection
*/
protected function getDatabaseConnection()
{
$connection = $this->app['config']['cache.connection'];
return $this->app['db']->connection($connection);
}
/**
* Get the cache "prefix" value.
*
* @return string
*/
public function getPrefix()
{
return $this->app['config']['cache.prefix'];
}
/**
* Set the cache "prefix" value.
*
* @param string $name
* @return void
*/
public function setPrefix($name)
{
$this->app['config']['cache.prefix'] = $name;
}
/**
* Create a new cache repository with the given implementation.
*
* @param \Illuminate\Cache\StoreInterface $store
* @return \Illuminate\Cache\Repository
*/
protected function repository(StoreInterface $store)
{
return new Repository($store);
}
/**
* Get the default cache driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['cache.driver'];
}
/**
* Set the default cache driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['cache.driver'] = $name;
}
}
<?php namespace Illuminate\Cache;
use Illuminate\Support\ServiceProvider;
class CacheServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bindShared('cache', function($app)
{
return new CacheManager($app);
});
$this->app->bindShared('cache.store', function($app)
{
return $app['cache']->driver();
});
$this->app->bindShared('memcached.connector', function()
{
return new MemcachedConnector;
});
$this->registerCommands();
}
/**
* Register the cache related console commands.
*
* @return void
*/
public function registerCommands()
{
$this->app->bindShared('command.cache.clear', function($app)
{
return new Console\ClearCommand($app['cache'], $app['files']);
});
$this->commands('command.cache.clear');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('cache', 'cache.store', 'memcached.connector', 'command.cache.clear');
}
}
{
"name": "illuminate/cache",
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/support": "4.1.*",
"nesbot/carbon": "1.*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"illuminate/database": "4.1.*",
"illuminate/encryption": "4.1.*",
"illuminate/filesystem": "4.1.*",
"illuminate/redis": "4.1.*"
},
"autoload": {
"psr-0": {"Illuminate\\Cache": ""}
},
"target-dir": "Illuminate/Cache",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"minimum-stability": "dev"
}
<?php namespace Illuminate\Cache\Console;
use Illuminate\Console\Command;
use Illuminate\Cache\CacheManager;
use Illuminate\Filesystem\Filesystem;
class ClearCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'cache:clear';
/**
* The console command description.
*
* @var string
*/
protected $description = "Flush the application cache";
/**
* The cache manager instance.
*
* @var \Illuminate\Cache\CacheManager
*/
protected $cache;
/**
* The file system instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new cache clear command instance.
*
* @param \Illuminate\Cache\CacheManager $cache
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(CacheManager $cache, Filesystem $files)
{
parent::__construct();
$this->cache = $cache;
$this->files = $files;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->cache->flush();
$this->files->delete($this->laravel['config']['app.manifest'].'/services.json');
$this->info('Application cache cleared!');
}
}
<?php namespace Illuminate\Cache;
use Illuminate\Database\Connection;
use Illuminate\Encryption\Encrypter;
class DatabaseStore implements StoreInterface {
/**
* The database connection instance.
*
* @var \Illuminate\Database\Connection
*/
protected $connection;
/**
* The encrypter instance.
*
* @var \Illuminate\Encryption\Encrypter
*/
protected $encrypter;
/**
* The name of the cache table.
*
* @var string
*/
protected $table;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new database store.
*
* @param \Illuminate\Database\Connection $connection
* @param \Illuminate\Encryption\Encrypter $encrypter
* @param string $table
* @param string $prefix
* @return void
*/
public function __construct(Connection $connection, Encrypter $encrypter, $table, $prefix = '')
{
$this->table = $table;
$this->prefix = $prefix;
$this->encrypter = $encrypter;
$this->connection = $connection;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$prefixed = $this->prefix.$key;
$cache = $this->table()->where('key', '=', $prefixed)->first();
// If we have a cache record we will check the expiration time against current
// time on the system and see if the record has expired. If it has, we will
// remove the records from the database table so it isn't returned again.
if ( ! is_null($cache))
{
if (is_array($cache)) $cache = (object) $cache;
if (time() >= $cache->expiration)
{
return $this->forget($key);
}
return $this->encrypter->decrypt($cache->value);
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$key = $this->prefix.$key;
// All of the cached values in the database are encrypted in case this is used
// as a session data store by the consumer. We'll also calculate the expire
// time and place that on the table so we will check it on our retrieval.
$value = $this->encrypter->encrypt($value);
$expiration = $this->getTime() + ($minutes * 60);
try
{
$this->table()->insert(compact('key', 'value', 'expiration'));
}
catch (\Exception $e)
{
$this->table()->where('key', '=', $key)->update(compact('value', 'expiration'));
}
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*
* @throws \LogicException
*/
public function increment($key, $value = 1)
{
throw new \LogicException("Increment operations not supported by this driver.");
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*
* @throws \LogicException
*/
public function decrement($key, $value = 1)
{
throw new \LogicException("Increment operations not supported by this driver.");
}
/**
* Get the current system time.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 5256000);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
$this->table()->where('key', '=', $this->prefix.$key)->delete();
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->table()->delete();
}
/**
* Get a query builder for the cache table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function table()
{
return $this->connection->table($this->table);
}
/**
* Get the underlying database connection.
*
* @return \Illuminate\Database\Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* Get the encrypter instance.
*
* @return \Illuminate\Encryption\Encrypter
*/
public function getEncrypter()
{
return $this->encrypter;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}
<?php namespace Illuminate\Cache;
use Illuminate\Filesystem\Filesystem;
class FileStore implements StoreInterface {
/**
* The Illuminate Filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The file cache directory
*
* @var string
*/
protected $directory;
/**
* Create a new file cache store instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param string $directory
* @return void
*/
public function __construct(Filesystem $files, $directory)
{
$this->files = $files;
$this->directory = $directory;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$path = $this->path($key);
// If the file doesn't exists, we obviously can't return the cache so we will
// just return null. Otherwise, we'll get the contents of the file and get
// the expiration UNIX timestamps from the start of the file's contents.
if ( ! $this->files->exists($path))
{
return null;
}
try
{
$expire = substr($contents = $this->files->get($path), 0, 10);
}
catch (\Exception $e)
{
return null;
}
// If the current time is greater than expiration timestamps we will delete
// the file and return null. This helps clean up the old files and keeps
// this directory much cleaner for us as old files aren't hanging out.
if (time() >= $expire)
{
return $this->forget($key);
}
return unserialize(substr($contents, 10));
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$value = $this->expiration($minutes).serialize($value);
$this->createCacheDirectory($path = $this->path($key));
$this->files->put($path, $value);
}
/**
* Create the file cache directory if necessary.
*
* @param string $path
* @return void
*/
protected function createCacheDirectory($path)
{
try
{
$this->files->makeDirectory(dirname($path), 0777, true, true);
}
catch (\Exception $e)
{
//
}
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*
* @throws \LogicException
*/
public function increment($key, $value = 1)
{
throw new \LogicException("Increment operations not supported by this driver.");
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*
* @throws \LogicException
*/
public function decrement($key, $value = 1)
{
throw new \LogicException("Decrement operations not supported by this driver.");
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
$file = $this->path($key);
if ($this->files->exists($file))
{
$this->files->delete($file);
}
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
foreach ($this->files->directories($this->directory) as $directory)
{
$this->files->deleteDirectory($directory);
}
}
/**
* Get the full path for the given cache key.
*
* @param string $key
* @return string
*/
protected function path($key)
{
$parts = array_slice(str_split($hash = md5($key), 2), 0, 2);
return $this->directory.'/'.join('/', $parts).'/'.$hash;
}
/**
* Get the expiration time based on the given minutes.
*
* @param int $minutes
* @return int
*/
protected function expiration($minutes)
{
if ($minutes === 0) return 9999999999;
return time() + ($minutes * 60);
}
/**
* Get the Filesystem instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
/**
* Get the working directory of the cache.
*
* @return string
*/
public function getDirectory()
{
return $this->directory;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return '';
}
}
<?php namespace Illuminate\Cache;
use Memcached;
class MemcachedConnector {
/**
* Create a new Memcached connection.
*
* @param array $servers
* @return \Memcached
*
* @throws \RuntimeException
*/
public function connect(array $servers)
{
$memcached = $this->getMemcached();
// For each server in the array, we'll just extract the configuration and add
// the server to the Memcached connection. Once we have added all of these
// servers we'll verify the connection is successful and return it back.
foreach ($servers as $server)
{
$memcached->addServer(
$server['host'], $server['port'], $server['weight']
);
}
if ($memcached->getVersion() === false)
{
throw new \RuntimeException("Could not establish Memcached connection.");
}
return $memcached;
}
/**
* Get a new Memcached instance.
*
* @return \Memcached
*/
protected function getMemcached()
{
return new Memcached;
}
}
<?php namespace Illuminate\Cache;
use Memcached;
class MemcachedStore extends TaggableStore implements StoreInterface {
/**
* The Memcached instance.
*
* @var \Memcached
*/
protected $memcached;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new Memcached store.
*
* @param \Memcached $memcached
* @param string $prefix
* @return void
*/
public function __construct(Memcached $memcached, $prefix = '')
{
$this->memcached = $memcached;
$this->prefix = strlen($prefix) > 0 ? $prefix.':' : '';
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = $this->memcached->get($this->prefix.$key);
if ($this->memcached->getResultCode() == 0)
{
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->memcached->set($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
return $this->memcached->increment($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
return $this->memcached->decrement($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
$this->memcached->delete($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->memcached->flush();
}
/**
* Get the underlying Memcached connection.
*
* @return \Memcached
*/
public function getMemcached()
{
return $this->memcached;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}
<?php namespace Illuminate\Cache;
use Illuminate\Redis\Database as Redis;
class RedisStore extends TaggableStore implements StoreInterface {
/**
* The Redis database connection.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* The Redis connection that should be used.
*
* @var string
*/
protected $connection;
/**
* Create a new Redis store.
*
* @param \Illuminate\Redis\Database $redis
* @param string $prefix
* @param string $connection
* @return void
*/
public function __construct(Redis $redis, $prefix = '', $connection = 'default')
{
$this->redis = $redis;
$this->connection = $connection;
$this->prefix = strlen($prefix) > 0 ? $prefix.':' : '';
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
if ( ! is_null($value = $this->connection()->get($this->prefix.$key)))
{
return is_numeric($value) ? $value : unserialize($value);
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$value = is_numeric($value) ? $value : serialize($value);
$this->connection()->set($this->prefix.$key, $value);
$this->connection()->expire($this->prefix.$key, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
return $this->connection()->incrby($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
return $this->connection()->decrby($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$value = is_numeric($value) ? $value : serialize($value);
$this->connection()->set($this->prefix.$key, $value);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
$this->connection()->del($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->connection()->flushdb();
}
/**
* Begin executing a new tags operation.
*
* @param array|dynamic $names
* @return \Illuminate\Cache\RedisTaggedCache
*/
public function tags($names)
{
return new RedisTaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
/**
* Get the Redis connection instance.
*
* @return \Predis\Connection\SingleConnectionInterface
*/
public function connection()
{
return $this->redis->connection($this->connection);
}
/**
* Set the connection name to be used.
*
* @param string $connection
* @return void
*/
public function setConnection($connection)
{
$this->connection = $connection;
}
/**
* Get the Redis database instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedis()
{
return $this->redis;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}
<?php namespace Illuminate\Cache;
class RedisTaggedCache extends TaggedCache {
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->pushForeverKeys($namespace = $this->tags->getNamespace(), $key);
$this->store->forever($this->getPrefix().sha1($namespace).':'.$key, $value);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->deleteForeverKeys();
parent::flush();
}
/**
* Store a copy of the full key for each namespace segment.
*
* @param string $namespace
* @param string $key
* @return void
*/
protected function pushForeverKeys($namespace, $key)
{
$fullKey = $this->getPrefix().sha1($namespace).':'.$key;
foreach (explode('|', $namespace) as $segment)
{
$this->store->connection()->lpush($this->foreverKey($segment), $fullKey);
}
}
/**
* Delete all of the items that were stored forever.
*
* @return void
*/
protected function deleteForeverKeys()
{
foreach (explode('|', $this->tags->getNamespace()) as $segment)
{
$this->deleteForeverValues($segment = $this->foreverKey($segment));
$this->store->connection()->del($segment);
}
}
/**
* Delete all of the keys that have been stored forever.
*
* @param string $foreverKey
* @return void
*/
protected function deleteForeverValues($foreverKey)
{
$forever = array_unique($this->store->connection()->lrange($foreverKey, 0, -1));
if (count($forever) > 0)
{
call_user_func_array(array($this->store->connection(), 'del'), $forever);
}
}
/**
* Get the forever reference key for hte segment.
*
* @param string $segment
* @return string
*/
protected function foreverKey($segment)
{
return $this->getPrefix().$segment.':forever';
}
}
<?php namespace Illuminate\Cache;
use Closure;
use DateTime;
use ArrayAccess;
use Carbon\Carbon;
class Repository implements ArrayAccess {
/**
* The cache store implementation.
*
* @var \Illuminate\Cache\StoreInterface
*/
protected $store;
/**
* The default number of minutes to store items.
*
* @var int
*/
protected $default = 60;
/**
* An array of registered Cache macros.
*
* @var array
*/
protected $macros = array();
/**
* Create a new cache repository instance.
*
* @param \Illuminate\Cache\StoreInterface $store
*/
public function __construct(StoreInterface $store)
{
$this->store = $store;
}
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ! is_null($this->get($key));
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
$value = $this->store->get($key);
return ! is_null($value) ? $value : value($default);
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$minutes = $this->getMinutes($minutes);
$this->store->put($key, $value, $minutes);
}
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
if (is_null($this->get($key)))
{
$this->put($key, $value, $minutes); return true;
}
return false;
}
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param \DateTime|int $minutes
* @param Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes in storage.
if ( ! is_null($value = $this->get($key)))
{
return $value;
}
$this->put($key, $value = $callback(), $minutes);
return $value;
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback)
{
return $this->rememberForever($key, $callback);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes. It's easy.
if ( ! is_null($value = $this->get($key)))
{
return $value;
}
$this->forever($key, $value = $callback());
return $value;
}
/**
* Get the default cache time.
*
* @return int
*/
public function getDefaultCacheTime()
{
return $this->default;
}
/**
* Set the default cache time in minutes.
*
* @param int $minutes
* @return void
*/
public function setDefaultCacheTime($minutes)
{
$this->default = $minutes;
}
/**
* Get the cache store implementation.
*
* @return \Illuminate\Cache\StoreInterface
*/
public function getStore()
{
return $this->store;
}
/**
* Determine if a cached value exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Store an item in the cache for the default time.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->put($key, $value, $this->default);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
return $this->forget($key);
}
/**
* Calculate the number of minutes with the given duration.
*
* @param \DateTime|int $duration
* @return int
*/
protected function getMinutes($duration)
{
if ($duration instanceof DateTime)
{
$duration = Carbon::instance($duration);
return max(0, Carbon::now()->diffInMinutes($duration, false));
}
else
{
return is_string($duration) ? intval($duration) : $duration;
}
}
/**
* Register a macro with the Cache class.
*
* @param string $name
* @param callable $callback
* @return void
*/
public function macro($name, $callback)
{
$this->macros[$name] = $callback;
}
/**
* Handle dynamic calls into macros or pass missing methods to the store.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (isset($this->macros[$method]))
{
return call_user_func_array($this->macros[$method], $parameters);
}
else
{
return call_user_func_array(array($this->store, $method), $parameters);
}
}
}
<?php namespace Illuminate\Cache;
interface StoreInterface {
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key);
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes);
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1);
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1);
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value);
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key);
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush();
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix();
}
<?php namespace Illuminate\Cache;
abstract class TaggableStore {
/**
* Begin executing a new tags operation.
*
* @param string $name
* @return \Illuminate\Cache\TaggedCache
*/
public function section($name)
{
return $this->tags($name);
}
/**
* Begin executing a new tags operation.
*
* @param array|dynamic $names
* @return \Illuminate\Cache\TaggedCache
*/
public function tags($names)
{
return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
}
<?php namespace Illuminate\Cache;
use Closure;
class TaggedCache implements StoreInterface {
/**
* The cache store implementation.
*
* @var \Illuminate\Cache\StoreInterface
*/
protected $store;
/**
* The tag set instance.
*
* @var \Illuminate\Cache\TagSet
*/
protected $tags;
/**
* Create a new tagged cache instance.
*
* @param \Illuminate\Cache\StoreInterface $store
* @param \Illuminate\Cache\TagSet $tags
* @return void
*/
public function __construct(StoreInterface $store, TagSet $tags)
{
$this->tags = $tags;
$this->store = $store;
}
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ! is_null($this->get($key));
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
$value = $this->store->get($this->taggedItemKey($key));
return ! is_null($value) ? $value : value($default);
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
return $this->store->put($this->taggedItemKey($key), $value, $minutes);
}
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
if (is_null($this->get($key)))
{
$this->put($key, $value, $minutes); return true;
}
return false;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
$this->store->increment($this->taggedItemKey($key), $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
$this->store->decrement($this->taggedItemKey($key), $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->store->forever($this->taggedItemKey($key), $value);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
$this->store->forget($this->taggedItemKey($key));
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->tags->reset();
}
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param int $minutes
* @param Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes in storage.
if ($this->has($key)) return $this->get($key);
$this->put($key, $value = $callback(), $minutes);
return $value;
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback)
{
return $this->rememberForever($key, $callback);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback)
{
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes. It's easy.
if ($this->has($key)) return $this->get($key);
$this->forever($key, $value = $callback());
return $value;
}
/**
* Get a fully qualified key for a tagged item.
*
* @param string $key
* @return string
*/
public function taggedItemKey($key)
{
return $this->getPrefix().sha1($this->tags->getNamespace()).':'.$key;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->store->getPrefix();
}
}
<?php namespace Illuminate\Cache;
class TagSet {
/**
* The cache store implementation.
*
* @var \Illuminate\Cache\StoreInterface
*/
protected $store;
/**
* The tag names.
*
* @var array
*/
protected $names = array();
/**
* Create a new TagSet instance.
*
* @param \Illuminate\Cache\StoreInterface $store
* @param string $names
* @return void
*/
public function __construct(StoreInterface $store, $names)
{
$this->store = $store;
$this->names = $names;
}
/**
* Reset all tags in the set.
*
* @return void
*/
public function reset()
{
array_walk($this->names, array($this, 'resetTag'));
}
/**
* Get the unique tag identifier for a given tag.
*
* @param string $name
* @return string
*/
public function tagId($name)
{
return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
}
/**
* Get an array of tag identifiers for all of the tags in the set.
*
* @return array
*/
protected function tagIds()
{
return array_map(array($this, 'tagId'), $this->names);
}
/**
* Get a unique namespace that changes when any of the tags are flushed.
*
* @return string
*/
public function getNamespace()
{
return implode('|', $this->tagIds());
}
/**
* Reset the tag and return the new tag identifier
*
* @param string $name
* @return string
*/
public function resetTag($name)
{
$this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));
return $id;
}
/**
* Get the tag identifier key for a given tag.
*
* @param string $name
* @return string
*/
public function tagKey($name)
{
return 'tag:'.$name.':key';
}
}
<?php namespace Illuminate\Cache;
class WinCacheStore extends TaggableStore implements StoreInterface {
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new WinCache store.
*
* @param string $prefix
* @return void
*/
public function __construct($prefix = '')
{
$this->prefix = $prefix;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = wincache_ucache_get($this->prefix.$key);
if ($value !== false)
{
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
wincache_ucache_set($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
return wincache_ucache_inc($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
return wincache_ucache_dec($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
wincache_ucache_delete($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
wincache_ucache_clear();
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}
<?php namespace Illuminate\Cache;
class XCacheStore extends TaggableStore implements StoreInterface {
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new WinCache store.
*
* @param string $prefix
* @return void
*/
public function __construct($prefix = '')
{
$this->prefix = $prefix;
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$value = xcache_get($this->prefix.$key);
if (isset($value))
{
return $value;
}
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
xcache_set($this->prefix.$key, $value, $minutes * 60);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
{
return xcache_inc($this->prefix.$key, $value);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
{
return xcache_dec($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
return $this->put($key, $value, 0);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function forget($key)
{
xcache_unset($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
xcache_clear_cache(XC_TYPE_VAR);
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
}
{
"name": "illuminate/config",
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/filesystem": "4.1.*",
"illuminate/support": "4.1.*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {"Illuminate\\Config": ""}
},
"target-dir": "Illuminate/Config",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"minimum-stability": "dev"
}
<?php namespace Illuminate\Config;
/**
* PHP $_ENV loader for protecting sensitive configuration options.
*
* Inspired by the wonderful "Dotenv" library by Vance Lucas.
*/
class EnvironmentVariables {
/**
* The environment loader implementation.
*
* @var \Illuminate\Config\EnvironmentLoaderInterface $loader
*/
protected $loader;
/**
* The server environment instance.
*
* @param \Illuminate\Config\EnvironmentLoaderInterface $loader
* @return void
*/
public function __construct(EnvironmentVariablesLoaderInterface $loader)
{
$this->loader = $loader;
}
/**
* Load the server variables for a given environment.
*
* @param string $environment
*/
public function load($environment = null)
{
foreach ($this->loader->load($environment) as $key => $value)
{
$_ENV[$key] = $value;
$_SERVER[$key] = $value;
putenv("{$key}={$value}");
}
}
}
<?php namespace Illuminate\Config;
interface EnvironmentVariablesLoaderInterface {
/**
* Load the environment variables for the given environment.
*
* @param string $environment
* @return array
*/
public function load($environment = null);
}
<?php namespace Illuminate\Config;
use Illuminate\Filesystem\Filesystem;
class FileEnvironmentVariablesLoader implements EnvironmentVariablesLoaderInterface {
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The path to the configuration files.
*
* @var string
*/
protected $path;
/**
* Create a new file environment loader instance.
*
* @param \Illumiante\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files, $path = null)
{
$this->files = $files;
$this->path = $path ?: base_path();
}
/**
* Load the environment variables for the given environment.
*
* @param string $environment
* @return array
*/
public function load($environment = null)
{
if ($environment == 'production') $environment = null;
if ( ! $this->files->exists($path = $this->getFile($environment)))
{
return array();
}
else
{
return $this->files->getRequire($path);
}
}
/**
* Get the file for the given environment.
*
* @param string $environment
* @return string
*/
protected function getFile($environment)
{
if ($environment)
{
return $this->path.'/.env.'.$environment.'.php';
}
else
{
return $this->path.'/.env.php';
}
}
}
<?php namespace Illuminate\Config;
use Illuminate\Filesystem\Filesystem;
class FileLoader implements LoaderInterface {
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The default configuration path.
*
* @var string
*/
protected $defaultPath;
/**
* All of the named path hints.
*
* @var array
*/
protected $hints = array();
/**
* A cache of whether namespaces and groups exists.
*
* @var array
*/
protected $exists = array();
/**
* Create a new file configuration loader.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param string $defaultPath
* @return void
*/
public function __construct(Filesystem $files, $defaultPath)
{
$this->files = $files;
$this->defaultPath = $defaultPath;
}
/**
* Load the given configuration group.
*
* @param string $environment
* @param string $group
* @param string $namespace
* @return array
*/
public function load($environment, $group, $namespace = null)
{
$items = array();
// First we'll get the root configuration path for the environment which is
// where all of the configuration files live for that namespace, as well
// as any environment folders with their specific configuration items.
$path = $this->getPath($namespace);
if (is_null($path))
{
return $items;
}
// First we'll get the main configuration file for the groups. Once we have
// that we can check for any environment specific files, which will get
// merged on top of the main arrays to make the environments cascade.
$file = "{$path}/{$group}.php";
if ($this->files->exists($file))
{
$items = $this->files->getRequire($file);
}
// Finally we're ready to check for the environment specific configuration
// file which will be merged on top of the main arrays so that they get
// precedence over them if we are currently in an environments setup.
$file = "{$path}/{$environment}/{$group}.php";
if ($this->files->exists($file))
{
$items = $this->mergeEnvironment($items, $file);
}
return $items;
}
/**
* Merge the items in the given file into the items.
*
* @param array $items
* @param string $file
* @return array
*/
protected function mergeEnvironment(array $items, $file)
{
return array_replace_recursive($items, $this->files->getRequire($file));
}
/**
* Determine if the given group exists.
*
* @param string $group
* @param string $namespace
* @return bool
*/
public function exists($group, $namespace = null)
{
$key = $group.$namespace;
// We'll first check to see if we have determined if this namespace and
// group combination have been checked before. If they have, we will
// just return the cached result so we don't have to hit the disk.
if (isset($this->exists[$key]))
{
return $this->exists[$key];
}
$path = $this->getPath($namespace);
// To check if a group exists, we will simply get the path based on the
// namespace, and then check to see if this files exists within that
// namespace. False is returned if no path exists for a namespace.
if (is_null($path))
{
return $this->exists[$key] = false;
}
$file = "{$path}/{$group}.php";
// Finally, we can simply check if this file exists. We will also cache
// the value in an array so we don't have to go through this process
// again on subsequent checks for the existing of the config file.
$exists = $this->files->exists($file);
return $this->exists[$key] = $exists;
}
/**
* Apply any cascades to an array of package options.
*
* @param string $env
* @param string $package
* @param string $group
* @param array $items
* @return array
*/
public function cascadePackage($env, $package, $group, $items)
{
// First we will look for a configuration file in the packages configuration
// folder. If it exists, we will load it and merge it with these original
// options so that we will easily "cascade" a package's configurations.
$file = "packages/{$package}/{$group}.php";
if ($this->files->exists($path = $this->defaultPath.'/'.$file))
{
$items = array_merge($items, $this->getRequire($path));
}
// Once we have merged the regular package configuration we need to look for
// an environment specific configuration file. If one exists, we will get
// the contents and merge them on top of this array of options we have.
$path = $this->getPackagePath($env, $package, $group);
if ($this->files->exists($path))
{
$items = array_merge($items, $this->getRequire($path));
}
return $items;
}
/**
* Get the package path for an environment and group.
*
* @param string $env
* @param string $package
* @param string $group
* @return string
*/
protected function getPackagePath($env, $package, $group)
{
$file = "packages/{$package}/{$env}/{$group}.php";
return $this->defaultPath.'/'.$file;
}
/**
* Get the configuration path for a namespace.
*
* @param string $namespace
* @return string
*/
protected function getPath($namespace)
{
if (is_null($namespace))
{
return $this->defaultPath;
}
elseif (isset($this->hints[$namespace]))
{
return $this->hints[$namespace];
}
}
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string $hint
* @return void
*/
public function addNamespace($namespace, $hint)
{
$this->hints[$namespace] = $hint;
}
/**
* Returns all registered namespaces with the config
* loader.
*
* @return array
*/
public function getNamespaces()
{
return $this->hints;
}
/**
* Get a file's contents by requiring it.
*
* @param string $path
* @return mixed
*/
protected function getRequire($path)
{
return $this->files->getRequire($path);
}
/**
* Get the Filesystem instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
}
<?php namespace Illuminate\Config;
interface LoaderInterface {
/**
* Load the given configuration group.
*
* @param string $environment
* @param string $group
* @param string $namespace
* @return array
*/
public function load($environment, $group, $namespace = null);
/**
* Determine if the given configuration group exists.
*
* @param string $group
* @param string $namespace
* @return bool
*/
public function exists($group, $namespace = null);
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string $hint
* @return void
*/
public function addNamespace($namespace, $hint);
/**
* Returns all registered namespaces with the config
* loader.
*
* @return array
*/
public function getNamespaces();
/**
* Apply any cascades to an array of package options.
*
* @param string $environment
* @param string $package
* @param string $group
* @param array $items
* @return array
*/
public function cascadePackage($environment, $package, $group, $items);
}
<?php namespace Illuminate\Config;
use Closure;
use ArrayAccess;
use Illuminate\Support\NamespacedItemResolver;
class Repository extends NamespacedItemResolver implements ArrayAccess {
/**
* The loader implementation.
*
* @var \Illuminate\Config\LoaderInterface
*/
protected $loader;
/**
* The current environment.
*
* @var string
*/
protected $environment;
/**
* All of the configuration items.
*
* @var array
*/
protected $items = array();
/**
* All of the registered packages.
*
* @var array
*/
protected $packages = array();
/**
* The after load callbacks for namespaces.
*
* @var array
*/
protected $afterLoad = array();
/**
* Create a new configuration repository.
*
* @param \Illuminate\Config\LoaderInterface $loader
* @param string $environment
* @return void
*/
public function __construct(LoaderInterface $loader, $environment)
{
$this->loader = $loader;
$this->environment = $environment;
}
/**
* Determine if the given configuration value exists.
*
* @param string $key
* @return bool
*/
public function has($key)
{
$default = microtime(true);
return $this->get($key, $default) !== $default;
}
/**
* Determine if a configuration group exists.
*
* @param string $key
* @return bool
*/
public function hasGroup($key)
{
list($namespace, $group, $item) = $this->parseKey($key);
return $this->loader->exists($group, $namespace);
}
/**
* Get the specified configuration value.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
list($namespace, $group, $item) = $this->parseKey($key);
// Configuration items are actually keyed by "collection", which is simply a
// combination of each namespace and groups, which allows a unique way to
// identify the arrays of configuration items for the particular files.
$collection = $this->getCollection($group, $namespace);
$this->load($group, $namespace, $collection);
return array_get($this->items[$collection], $item, $default);
}
/**
* Set a given configuration value.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function set($key, $value)
{
list($namespace, $group, $item) = $this->parseKey($key);
$collection = $this->getCollection($group, $namespace);
// We'll need to go ahead and lazy load each configuration groups even when
// we're just setting a configuration item so that the set item does not
// get overwritten if a different item in the group is requested later.
$this->load($group, $namespace, $collection);
if (is_null($item))
{
$this->items[$collection] = $value;
}
else
{
array_set($this->items[$collection], $item, $value);
}
}
/**
* Load the configuration group for the key.
*
* @param string $group
* @param string $namespace
* @param string $collection
* @return void
*/
protected function load($group, $namespace, $collection)
{
$env = $this->environment;
// If we've already loaded this collection, we will just bail out since we do
// not want to load it again. Once items are loaded a first time they will
// stay kept in memory within this class and not loaded from disk again.
if (isset($this->items[$collection]))
{
return;
}
$items = $this->loader->load($env, $group, $namespace);
// If we've already loaded this collection, we will just bail out since we do
// not want to load it again. Once items are loaded a first time they will
// stay kept in memory within this class and not loaded from disk again.
if (isset($this->afterLoad[$namespace]))
{
$items = $this->callAfterLoad($namespace, $group, $items);
}
$this->items[$collection] = $items;
}
/**
* Call the after load callback for a namespace.
*
* @param string $namespace
* @param string $group
* @param array $items
* @return array
*/
protected function callAfterLoad($namespace, $group, $items)
{
$callback = $this->afterLoad[$namespace];
return call_user_func($callback, $this, $group, $items);
}
/**
* Parse an array of namespaced segments.
*
* @param string $key
* @return array
*/
protected function parseNamespacedSegments($key)
{
list($namespace, $item) = explode('::', $key);
// If the namespace is registered as a package, we will just assume the group
// is equal to the namespace since all packages cascade in this way having
// a single file per package, otherwise we'll just parse them as normal.
if (in_array($namespace, $this->packages))
{
return $this->parsePackageSegments($key, $namespace, $item);
}
return parent::parseNamespacedSegments($key);
}
/**
* Parse the segments of a package namespace.
*
* @param string $key
* @param string $namespace
* @param string $item
* @return array
*/
protected function parsePackageSegments($key, $namespace, $item)
{
$itemSegments = explode('.', $item);
// If the configuration file doesn't exist for the given package group we can
// assume that we should implicitly use the config file matching the name
// of the namespace. Generally packages should use one type or another.
if ( ! $this->loader->exists($itemSegments[0], $namespace))
{
return array($namespace, 'config', $item);
}
return parent::parseNamespacedSegments($key);
}
/**
* Register a package for cascading configuration.
*
* @param string $package
* @param string $hint
* @param string $namespace
* @return void
*/
public function package($package, $hint, $namespace = null)
{
$namespace = $this->getPackageNamespace($package, $namespace);
$this->packages[] = $namespace;
// First we will simply register the namespace with the repository so that it
// can be loaded. Once we have done that we'll register an after namespace
// callback so that we can cascade an application package configuration.
$this->addNamespace($namespace, $hint);
$this->afterLoading($namespace, function($me, $group, $items) use ($package)
{
$env = $me->getEnvironment();
$loader = $me->getLoader();
return $loader->cascadePackage($env, $package, $group, $items);
});
}
/**
* Get the configuration namespace for a package.
*
* @param string $package
* @param string $namespace
* @return string
*/
protected function getPackageNamespace($package, $namespace)
{
if (is_null($namespace))
{
list($vendor, $namespace) = explode('/', $package);
}
return $namespace;
}
/**
* Register an after load callback for a given namespace.
*
* @param string $namespace
* @param \Closure $callback
* @return void
*/
public function afterLoading($namespace, Closure $callback)
{
$this->afterLoad[$namespace] = $callback;
}
/**
* Get the collection identifier.
*
* @param string $group
* @param string $namespace
* @return string
*/
protected function getCollection($group, $namespace = null)
{
$namespace = $namespace ?: '*';
return $namespace.'::'.$group;
}
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string $hint
* @return void
*/
public function addNamespace($namespace, $hint)
{
$this->loader->addNamespace($namespace, $hint);
}
/**
* Returns all registered namespaces with the config
* loader.
*
* @return array
*/
public function getNamespaces()
{
return $this->loader->getNamespaces();
}
/**
* Get the loader implementation.
*
* @return \Illuminate\Config\LoaderInterface
*/
public function getLoader()
{
return $this->loader;
}
/**
* Set the loader implementation.
*
* @param \Illuminate\Config\LoaderInterface $loader
* @return void
*/
public function setLoader(LoaderInterface $loader)
{
$this->loader = $loader;
}
/**
* Get the current configuration environment.
*
* @return string
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* Get the after load callback array.
*
* @return array
*/
public function getAfterLoadCallbacks()
{
return $this->afterLoad;
}
/**
* Get all of the configuration items.
*
* @return array
*/
public function getItems()
{
return $this->items;
}
/**
* Determine if the given configuration option exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Get a configuration option.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Set a configuration option.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->set($key, $value);
}
/**
* Unset a configuration option.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->set($key, null);
}
}
<?php namespace Illuminate\Console;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command as SymfonyCommand;
class Application extends \Symfony\Component\Console\Application {
/**
* The exception handler instance.
*
* @var \Illuminate\Exception\Handler
*/
protected $exceptionHandler;
/**
* The Laravel application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $laravel;
/**
* Create and boot a new Console application.
*
* @param \Illuminate\Foundation\Application $app
* @return \Illuminate\Console\Application
*/
public static function start($app)
{
return static::make($app)->boot();
}
/**
* Create a new Console application.
*
* @param \Illuminate\Foundation\Application $app
* @return \Illuminate\Console\Application
*/
public static function make($app)
{
$app->boot();
$console = with($console = new static('Laravel Framework', $app::VERSION))
->setLaravel($app)
->setExceptionHandler($app['exception'])
->setAutoExit(false);
$app->instance('artisan', $console);
return $console;
}
/**
* Boot the Console application.
*
* @return \Illuminate\Console\Application
*/
public function boot()
{
require $this->laravel['path'].'/start/artisan.php';
// If the event dispatcher is set on the application, we will fire an event
// with the Artisan instance to provide each listener the opportunity to
// register their commands on this application before it gets started.
if (isset($this->laravel['events']))
{
$this->laravel['events']
->fire('artisan.start', array($this));
}
return $this;
}
/**
* Run an Artisan console command by name.
*
* @param string $command
* @param array $parameters
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return void
*/
public function call($command, array $parameters = array(), OutputInterface $output = null)
{
$parameters['command'] = $command;
// Unless an output interface implementation was specifically passed to us we
// will use the "NullOutput" implementation by default to keep any writing
// suppressed so it doesn't leak out to the browser or any other source.
$output = $output ?: new NullOutput;
$input = new ArrayInput($parameters);
return $this->find($command)->run($input, $output);
}
/**
* Add a command to the console.
*
* @param \Symfony\Component\Console\Command\Command $command
* @return \Symfony\Component\Console\Command\Command
*/
public function add(SymfonyCommand $command)
{
if ($command instanceof Command)
{
$command->setLaravel($this->laravel);
}
return $this->addToParent($command);
}
/**
* Add the command to the parent instance.
*
* @param \Symfony\Component\Console\Command\Command $command
* @return \Symfony\Component\Console\Command\Command
*/
protected function addToParent(SymfonyCommand $command)
{
return parent::add($command);
}
/**
* Add a command, resolving through the application.
*
* @param string $command
* @return \Symfony\Component\Console\Command\Command
*/
public function resolve($command)
{
return $this->add($this->laravel[$command]);
}
/**
* Resolve an array of commands through the application.
*
* @param array|dynamic $commands
* @return void
*/
public function resolveCommands($commands)
{
$commands = is_array($commands) ? $commands : func_get_args();
foreach ($commands as $command)
{
$this->resolve($command);
}
}
/**
* Get the default input definitions for the applications.
*
* @return \Symfony\Component\Console\Input\InputDefinition
*/
protected function getDefaultInputDefinition()
{
$definition = parent::getDefaultInputDefinition();
$definition->addOption($this->getEnvironmentOption());
return $definition;
}
/**
* Get the global environment option for the definition.
*
* @return \Symfony\Component\Console\Input\InputOption
*/
protected function getEnvironmentOption()
{
$message = 'The environment the command should run under.';
return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message);
}
/**
* Render the given exception.
*
* @param \Exception $e
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return void
*/
public function renderException($e, $output)
{
// If we have an exception handler instance, we will call that first in case
// it has some handlers that need to be run first. We will pass "true" as
// the second parameter to indicate that it's handling a console error.
if (isset($this->exceptionHandler))
{
$this->exceptionHandler->handleConsole($e);
}
parent::renderException($e, $output);
}
/**
* Set the exception handler instance.
*
* @param \Illuminate\Exception\Handler $handler
* @return \Illuminate\Console\Application
*/
public function setExceptionHandler($handler)
{
$this->exceptionHandler = $handler;
return $this;
}
/**
* Set the Laravel application instance.
*
* @param \Illuminate\Foundation\Application $laravel
* @return \Illuminate\Console\Application
*/
public function setLaravel($laravel)
{
$this->laravel = $laravel;
return $this;
}
/**
* Set whether the Console app should auto-exit when done.
*
* @param bool $boolean
* @return \Illuminate\Console\Application
*/
public function setAutoExit($boolean)
{
parent::setAutoExit($boolean);
return $this;
}
}
<?php namespace Illuminate\Console;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Command extends \Symfony\Component\Console\Command\Command {
/**
* The Laravel application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $laravel;
/**
* The input interface implementation.
*
* @var \Symfony\Component\Console\Input\InputInterface
*/
protected $input;
/**
* The output interface implementation.
*
* @var \Symfony\Component\Console\Output\OutputInterface
*/
protected $output;
/**
* The console command name.
*
* @var string
*/
protected $name;
/**
* The console command description.
*
* @var string
*/
protected $description;
/**
* Create a new console command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct($this->name);
// We will go ahead and set the name, description, and parameters on console
// commands just to make things a little easier on the developer. This is
// so they don't have to all be manually specified in the constructors.
$this->setDescription($this->description);
$this->specifyParameters();
}
/**
* Specify the arguments and options on the command.
*
* @return void
*/
protected function specifyParameters()
{
// We will loop through all of the arguments and options for the command and
// set them all on the base command instance. This specifies what can get
// passed into these commands as "parameters" to control the execution.
foreach ($this->getArguments() as $arguments)
{
call_user_func_array(array($this, 'addArgument'), $arguments);
}
foreach ($this->getOptions() as $options)
{
call_user_func_array(array($this, 'addOption'), $options);
}
}
/**
* Run the console command.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return integer
*/
public function run(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
return parent::run($input, $output);
}
/**
* Execute the console command.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return mixed
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
return $this->fire();
}
/**
* Call another console command.
*
* @param string $command
* @param array $arguments
* @return integer
*/
public function call($command, array $arguments = array())
{
$instance = $this->getApplication()->find($command);
$arguments['command'] = $command;
return $instance->run(new ArrayInput($arguments), $this->output);
}
/**
* Call another console command silently.
*
* @param string $command
* @param array $arguments
* @return integer
*/
public function callSilent($command, array $arguments = array())
{
$instance = $this->getApplication()->find($command);
$arguments['command'] = $command;
return $instance->run(new ArrayInput($arguments), new NullOutput);
}
/**
* Get the value of a command argument.
*
* @param string $key
* @return string|array
*/
public function argument($key = null)
{
if (is_null($key)) return $this->input->getArguments();
return $this->input->getArgument($key);
}
/**
* Get the value of a command option.
*
* @param string $key
* @return string|array
*/
public function option($key = null)
{
if (is_null($key)) return $this->input->getOptions();
return $this->input->getOption($key);
}
/**
* Confirm a question with the user.
*
* @param string $question
* @param bool $default
* @return bool
*/
public function confirm($question, $default = true)
{
$dialog = $this->getHelperSet()->get('dialog');
return $dialog->askConfirmation($this->output, "<question>$question</question>", $default);
}
/**
* Prompt the user for input.
*
* @param string $question
* @param string $default
* @return string
*/
public function ask($question, $default = null)
{
$dialog = $this->getHelperSet()->get('dialog');
return $dialog->ask($this->output, "<question>$question</question>", $default);
}
/**
* Prompt the user for input but hide the answer from the console.
*
* @param string $question
* @param bool $fallback
* @return string
*/
public function secret($question, $fallback = true)
{
$dialog = $this->getHelperSet()->get('dialog');
return $dialog->askHiddenResponse($this->output, "<question>$question</question>", $fallback);
}
/**
* Write a string as standard output.
*
* @param string $string
* @return void
*/
public function line($string)
{
$this->output->writeln($string);
}
/**
* Write a string as information output.
*
* @param string $string
* @return void
*/
public function info($string)
{
$this->output->writeln("<info>$string</info>");
}
/**
* Write a string as comment output.
*
* @param string $string
* @return void
*/
public function comment($string)
{
$this->output->writeln("<comment>$string</comment>");
}
/**
* Write a string as question output.
*
* @param string $string
* @return void
*/
public function question($string)
{
$this->output->writeln("<question>$string</question>");
}
/**
* Write a string as error output.
*
* @param string $string
* @return void
*/
public function error($string)
{
$this->output->writeln("<error>$string</error>");
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array();
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array();
}
/**
* Get the output implementation.
*
* @return \Symfony\Component\Console\Output\OutputInterface
*/
public function getOutput()
{
return $this->output;
}
/**
* Set the Laravel application instance.
*
* @return \Illuminate\Foundation\Application
*/
public function getLaravel()
{
return $this->laravel;
}
/**
* Set the Laravel application instance.
*
* @param \Illuminate\Foundation\Application $laravel
* @return void
*/
public function setLaravel($laravel)
{
$this->laravel = $laravel;
}
}
{
"name": "illuminate/console",
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]"
}
],
"require": {
"symfony/console": "2.4.*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {
"Illuminate\\Console": ""
}
},
"target-dir": "Illuminate/Console",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"minimum-stability": "dev"
}
{
"name": "illuminate/container",
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {
"Illuminate\\Container": ""
}
},
"target-dir": "Illuminate/Container",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"minimum-stability": "dev"
}
<?php namespace Illuminate\Container;
use Closure;
use ArrayAccess;
use ReflectionClass;
use ReflectionParameter;
class BindingResolutionException extends \Exception {}
class Container implements ArrayAccess {
/**
* An array of the types that have been resolved.
*
* @var array
*/
protected $resolved = array();
/**
* The container's bindings.
*
* @var array
*/
protected $bindings = array();
/**
* The container's shared instances.
*
* @var array
*/
protected $instances = array();
/**
* The registered type aliases.
*
* @var array
*/
protected $aliases = array();
/**
* All of the registered rebound callbacks.
*
* @var array
*/
protected $reboundCallbacks = array();
/**
* All of the registered resolving callbacks.
*
* @var array
*/
protected $resolvingCallbacks = array();
/**
* All of the global resolving callbacks.
*
* @var array
*/
protected $globalResolvingCallbacks = array();
/**
* Determine if a given string is resolvable.
*
* @param string $abstract
* @return bool
*/
protected function resolvable($abstract)
{
return $this->bound($abstract) || $this->isAlias($abstract);
}
/**
* Determine if the given abstract type has been bound.
*
* @param string $abstract
* @return bool
*/
public function bound($abstract)
{
return isset($this[$abstract]) || isset($this->instances[$abstract]);
}
/**
* Determine if a given string is an alias.
*
* @param string $name
* @return bool
*/
public function isAlias($name)
{
return isset($this->aliases[$name]);
}
/**
* Register a binding with the container.
*
* @param string $abstract
* @param Closure|string|null $concrete
* @param bool $shared
* @return void
*/
public function bind($abstract, $concrete = null, $shared = false)
{
// If the given types are actually an array, we will assume an alias is being
// defined and will grab this "real" abstract class name and register this
// alias with the container so that it can be used as a shortcut for it.
if (is_array($abstract))
{
list($abstract, $alias) = $this->extractAlias($abstract);
$this->alias($abstract, $alias);
}
// If no concrete type was given, we will simply set the concrete type to the
// abstract type. This will allow concrete type to be registered as shared
// without being forced to state their classes in both of the parameter.
$this->dropStaleInstances($abstract);
if (is_null($concrete))
{
$concrete = $abstract;
}
// If the factory is not a Closure, it means it is just a class name which is
// is bound into this container to the abstract type and we will just wrap
// it up inside a Closure to make things more convenient when extending.
if ( ! $concrete instanceof Closure)
{
$concrete = $this->getClosure($abstract, $concrete);
}
$bound = $this->bound($abstract);
$this->bindings[$abstract] = compact('concrete', 'shared');
// If the abstract type was already bound in this container, we will fire the
// rebound listener so that any objects which have already gotten resolved
// can have their copy of the object updated via hte listener callbacks.
if ($bound)
{
$this->rebound($abstract);
}
}
/**
* Get the Closure to be used when building a type.
*
* @param string $abstract
* @param string $concrete
* @return \Closure
*/
protected function getClosure($abstract, $concrete)
{
return function($c) use ($abstract, $concrete)
{
$method = ($abstract == $concrete) ? 'build' : 'make';
return $c->$method($concrete);
};
}
/**
* Register a binding if it hasn't already been registered.
*
* @param string $abstract
* @param Closure|string|null $concrete
* @param bool $shared
* @return bool
*/
public function bindIf($abstract, $concrete = null, $shared = false)
{
if ( ! $this->bound($abstract))
{
$this->bind($abstract, $concrete, $shared);
}
}
/**
* Register a shared binding in the container.
*
* @param string $abstract
* @param Closure|string|null $concrete
* @return void
*/
public function singleton($abstract, $concrete = null)
{
return $this->bind($abstract, $concrete, true);
}
/**
* Wrap a Closure such that it is shared.
*
* @param Closure $closure
* @return Closure
*/
public function share(Closure $closure)
{
return function($container) use ($closure)
{
// We'll simply declare a static variable within the Closures and if it has
// not been set we will execute the given Closures to resolve this value
// and return it back to these consumers of the method as an instance.
static $object;
if (is_null($object))
{
$object = $closure($container);
}
return $object;
};
}
/**
* Bind a shared Closure into the container.
*
* @param string $abstract
* @param \Closure $closure
* @return void
*/
public function bindShared($abstract, Closure $closure)
{
return $this->bind($abstract, $this->share($closure), true);
}
/**
* "Extend" an abstract type in the container.
*
* @param string $abstract
* @param Closure $closure
* @return void
*
* @throws \InvalidArgumentException
*/
public function extend($abstract, Closure $closure)
{
if ( ! isset($this->bindings[$abstract]))
{
throw new \InvalidArgumentException("Type {$abstract} is not bound.");
}
if (isset($this->instances[$abstract]))
{
$this->instances[$abstract] = $closure($this->instances[$abstract], $this);
$this->rebound($abstract);
}
else
{
$extender = $this->getExtender($abstract, $closure);
$this->bind($abstract, $extender, $this->isShared($abstract));
}
}
/**
* Get an extender Closure for resolving a type.
*
* @param string $abstract
* @param \Closure $closure
* @return \Closure
*/
protected function getExtender($abstract, Closure $closure)
{
// To "extend" a binding, we will grab the old "resolver" Closure and pass it
// into a new one. The old resolver will be called first and the result is
// handed off to the "new" resolver, along with this container instance.
$resolver = $this->bindings[$abstract]['concrete'];
return function($container) use ($resolver, $closure)
{
return $closure($resolver($container), $container);
};
}
/**
* Register an existing instance as shared in the container.
*
* @param string $abstract
* @param mixed $instance
* @return void
*/
public function instance($abstract, $instance)
{
// First, we will extract the alias from the abstract if it is an array so we
// are using the correct name when binding the type. If we get an alias it
// will be registered with the container so we can resolve it out later.
if (is_array($abstract))
{
list($abstract, $alias) = $this->extractAlias($abstract);
$this->alias($abstract, $alias);
}
unset($this->aliases[$abstract]);
// We'll check to determine if this type has been bound before, and if it has
// we will fire the rebound callbacks registered with the container and it
// can be updated with consuming classes that have gotten resolved here.
$bound = $this->bound($abstract);
$this->instances[$abstract] = $instance;
if ($bound)
{
$this->rebound($abstract);
}
}
/**
* Alias a type to a shorter name.
*
* @param string $abstract
* @param string $alias
* @return void
*/
public function alias($abstract, $alias)
{
$this->aliases[$alias] = $abstract;
}
/**
* Extract the type and alias from a given definition.
*
* @param array $definition
* @return array
*/
protected function extractAlias(array $definition)
{
return array(key($definition), current($definition));
}
/**
* Bind a new callback to an abstract's rebind event.
*
* @param string $abstract
* @param \Closure $callback
* @return mixed
*/
public function rebinding($abstract, Closure $callback)
{
$this->reboundCallbacks[$abstract][] = $callback;
if ($this->bound($abstract)) return $this->make($abstract);
}
/**
* Refresh an instance on the given target and method.
*
* @param string $abstract
* @param mixed $target
* @param string $method
* @return mixed
*/
public function refresh($abstract, $target, $method)
{
return $this->rebinding($abstract, function($app, $instance) use ($target, $method)
{
$target->{$method}($instance);
});
}
/**
* Fire the "rebound" callbacks for the given abstract type.
*
* @param string $abstract
* @return void
*/
protected function rebound($abstract)
{
$instance = $this->make($abstract);
foreach ($this->getReboundCallbacks($abstract) as $callback)
{
call_user_func($callback, $this, $instance);
}
}
/**
* Get the rebound callbacks for a given type.
*
* @param string $abstract
* @return array
*/
protected function getReboundCallbacks($abstract)
{
if (isset($this->reboundCallbacks[$abstract]))
{
return $this->reboundCallbacks[$abstract];
}
else
{
return array();
}
}
/**
* Resolve the given type from the container.
*
* @param string $abstract
* @param array $parameters
* @return mixed
*/
public function make($abstract, $parameters = array())
{
$abstract = $this->getAlias($abstract);
$this->resolved[$abstract] = true;
// If an instance of the type is currently being managed as a singleton we'll
// just return an existing instance instead of instantiating new instances
// so the developer can keep using the same objects instance every time.
if (isset($this->instances[$abstract]))
{
return $this->instances[$abstract];
}
$concrete = $this->getConcrete($abstract);
// We're ready to instantiate an instance of the concrete type registered for
// the binding. This will instantiate the types, as well as resolve any of
// its "nested" dependencies recursively until all have gotten resolved.
if ($this->isBuildable($concrete, $abstract))
{
$object = $this->build($concrete, $parameters);
}
else
{
$object = $this->make($concrete, $parameters);
}
// If the requested type is registered as a singleton we'll want to cache off
// the instances in "memory" so we can return it later without creating an
// entirely new instance of an object on each subsequent request for it.
if ($this->isShared($abstract))
{
$this->instances[$abstract] = $object;
}
$this->fireResolvingCallbacks($abstract, $object);
return $object;
}
/**
* Get the concrete type for a given abstract.
*
* @param string $abstract
* @return mixed $concrete
*/
protected function getConcrete($abstract)
{
// If we don't have a registered resolver or concrete for the type, we'll just
// assume each type is a concrete name and will attempt to resolve it as is
// since the container should be able to resolve concretes automatically.
if ( ! isset($this->bindings[$abstract]))
{
return $abstract;
}
else
{
return $this->bindings[$abstract]['concrete'];
}
}
/**
* Instantiate a concrete instance of the given type.
*
* @param string $concrete
* @param array $parameters
* @return mixed
*
* @throws BindingResolutionException
*/
public function build($concrete, $parameters = array())
{
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure)
{
return $concrete($this, $parameters);
}
$reflector = new ReflectionClass($concrete);
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface of Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if ( ! $reflector->isInstantiable())
{
$message = "Target [$concrete] is not instantiable.";
throw new BindingResolutionException($message);
}
$constructor = $reflector->getConstructor();
// If there are no constructors, that means there are no dependencies then
// we can just resolve the instances of the objects right away, without
// resolving any other types or dependencies out of these containers.
if (is_null($constructor))
{
return new $concrete;
}
$dependencies = $constructor->getParameters();
// Once we have all the constructor's parameters we can create each of the
// dependency instances and then use the reflection instances to make a
// new instance of this class, injecting the created dependencies in.
$parameters = $this->keyParametersByArgument(
$dependencies, $parameters
);
$instances = $this->getDependencies(
$dependencies, $parameters
);
return $reflector->newInstanceArgs($instances);
}
/**
* Resolve all of the dependencies from the ReflectionParameters.
*
* @param array $parameters
* @param array $primitives
* @return array
*/
protected function getDependencies($parameters, array $primitives = array())
{
$dependencies = array();
foreach ($parameters as $parameter)
{
$dependency = $parameter->getClass();
// If the class is null, it means the dependency is a string or some other
// primitive type which we can not resolve since it is not a class and
// we will just bomb out with an error since we have no-where to go.
if (array_key_exists($parameter->name, $primitives))
{
$dependencies[] = $primitives[$parameter->name];
}
elseif (is_null($dependency))
{
$dependencies[] = $this->resolveNonClass($parameter);
}
else
{
$dependencies[] = $this->resolveClass($parameter);
}
}
return (array) $dependencies;
}
/**
* Resolve a non-class hinted dependency.
*
* @param ReflectionParameter $parameter
* @return mixed
*
* @throws BindingResolutionException
*/
protected function resolveNonClass(ReflectionParameter $parameter)
{
if ($parameter->isDefaultValueAvailable())
{
return $parameter->getDefaultValue();
}
else
{
$message = "Unresolvable dependency resolving [$parameter].";
throw new BindingResolutionException($message);
}
}
/**
* Resolve a class based dependency from the container.
*
* @param \ReflectionParameter $parameter
* @return mixed
*
* @throws BindingResolutionException
*/
protected function resolveClass(ReflectionParameter $parameter)
{
try
{
return $this->make($parameter->getClass()->name);
}
// If we can not resolve the class instance, we will check to see if the value
// is optional, and if it is we will return the optional parameter value as
// the value of the dependency, similarly to how we do this with scalars.
catch (BindingResolutionException $e)
{
if ($parameter->isOptional())
{
return $parameter->getDefaultValue();
}
else
{
throw $e;
}
}
}
/**
* If extra parameters are passed by numeric ID, rekey them by argument name.
*
* @param array $dependencies
* @param array $parameters
* @param array
*/
protected function keyParametersByArgument(array $dependencies, array $parameters)
{
foreach ($parameters as $key => $value)
{
if (is_numeric($key))
{
unset($parameters[$key]);
$parameters[$dependencies[$key]->name] = $value;
}
}
return $parameters;
}
/**
* Register a new resolving callback.
*
* @param string $abstract
* @param \Closure $callback
* @return void
*/
public function resolving($abstract, Closure $callback)
{
$this->resolvingCallbacks[$abstract][] = $callback;
}
/**
* Register a new resolving callback for all types.
*
* @param \Closure $callback
* @return void
*/
public function resolvingAny(Closure $callback)
{
$this->globalResolvingCallbacks[] = $callback;
}
/**
* Fire all of the resolving callbacks.
*
* @param mixed $object
* @return void
*/
protected function fireResolvingCallbacks($abstract, $object)
{
if (isset($this->resolvingCallbacks[$abstract]))
{
$this->fireCallbackArray($object, $this->resolvingCallbacks[$abstract]);
}
$this->fireCallbackArray($object, $this->globalResolvingCallbacks);
}
/**
* Fire an array of callbacks with an object.
*
* @param mixed $object
* @param array $callbacks
*/
protected function fireCallbackArray($object, array $callbacks)
{
foreach ($callbacks as $callback)
{
call_user_func($callback, $object, $this);
}
}
/**
* Determine if a given type is shared.
*
* @param string $abstract
* @return bool
*/
public function isShared($abstract)
{
if (isset($this->bindings[$abstract]['shared']))
{
$shared = $this->bindings[$abstract]['shared'];
}
else
{
$shared = false;
}
return isset($this->instances[$abstract]) || $shared === true;
}
/**
* Determine if the given concrete is buildable.
*
* @param mixed $concrete
* @param string $abstract
* @return bool
*/
protected function isBuildable($concrete, $abstract)
{
return $concrete === $abstract || $concrete instanceof Closure;
}
/**
* Get the alias for an abstract if available.
*
* @param string $abstract
* @return string
*/
protected function getAlias($abstract)
{
return isset($this->aliases[$abstract]) ? $this->aliases[$abstract] : $abstract;
}
/**
* Get the container's bindings.
*
* @return array
*/
public function getBindings()
{
return $this->bindings;
}
/**
* Drop all of the stale instances and aliases.
*
* @param string $abstract
* @return void
*/
protected function dropStaleInstances($abstract)
{
unset($this->instances[$abstract]);
unset($this->aliases[$abstract]);
}
/**
* Remove a resolved instance from the instance cache.
*
* @param string $abstract
* @return void
*/
public function forgetInstance($abstract)
{
unset($this->instances[$abstract]);
}
/**
* Clear all of the instances from the container.
*
* @return void
*/
public function forgetInstances()
{
$this->instances = array();
}
/**
* Determine if a given offset exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return isset($this->bindings[$key]);
}
/**
* Get the value at a given offset.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->make($key);
}
/**
* Set the value at a given offset.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
// If the value is not a Closure, we will make it one. This simply gives
// more "drop-in" replacement functionality for the Pimple which this
// container's simplest functions are base modeled and built after.
if ( ! $value instanceof Closure)
{
$value = function() use ($value)
{
return $value;
};
}
$this->bind($key, $value);
}
/**
* Unset the value at a given offset.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
unset($this->bindings[$key]);
unset($this->instances[$key]);
}
}
<?php namespace Illuminate\Database\Capsule;
use PDO;
use Illuminate\Support\Fluent;
use Illuminate\Events\Dispatcher;
use Illuminate\Cache\CacheManager;
use Illuminate\Container\Container;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Connectors\ConnectionFactory;
class Manager {
/**
* The current globally used instance.
*
* @var \Illuminate\Database\Capsule\Manager
*/
protected static $instance;
/**
* The database manager instance.
*
* @var \Illuminate\Database\DatabaseManager
*/
protected $manager;
/**
* Create a new database capsule manager.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function __construct(Container $container = null)
{
$this->setupContainer($container);
// Once we have the container setup, we will setup the default configuration
// options in the container "config" binding. This will make the database
// manager behave correctly since all the correct binding are in place.
$this->setupDefaultConfiguration();
$this->setupManager();
}
/**
* Setup the IoC container instance.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
protected function setupContainer($container)
{
$this->container = $container ?: new Container;
$this->container->instance('config', new Fluent);
}
/**
* Setup the default database configuration options.
*
* @return void
*/
protected function setupDefaultConfiguration()
{
$this->container['config']['database.fetch'] = PDO::FETCH_ASSOC;
$this->container['config']['database.default'] = 'default';
}
/**
* Build the database manager instance.
*
* @return void
*/
protected function setupManager()
{
$factory = new ConnectionFactory($this->container);
$this->manager = new DatabaseManager($this->container, $factory);
}
/**
* Get a connection instance from the global manager.
*
* @param string $connection
* @return \Illuminate\Database\Connection
*/
public static function connection($connection = null)
{
return static::$instance->getConnection($connection);
}
/**
* Get a fluent query builder instance.
*
* @param string $table
* @param string $connection
* @return \Illuminate\Database\Query\Builder
*/
public static function table($table, $connection = null)
{
return static::$instance->connection($connection)->table($table);
}
/**
* Get a schema builder instance.
*
* @param string $connection
* @return \Illuminate\Database\Schema\Builder
*/
public static function schema($connection = null)
{
return static::$instance->connection($connection)->getSchemaBuilder();
}
/**
* Get a registered connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function getConnection($name = null)
{
return $this->manager->connection($name);
}
/**
* Register a connection with the manager.
*
* @param array $config
* @param string $name
* @return void
*/
public function addConnection(array $config, $name = 'default')
{
$connections = $this->container['config']['database.connections'];
$connections[$name] = $config;
$this->container['config']['database.connections'] = $connections;
}
/**
* Bootstrap Eloquent so it is ready for usage.
*
* @return void
*/
public function bootEloquent()
{
Eloquent::setConnectionResolver($this->manager);
// If we have an event dispatcher instance, we will go ahead and register it
// with the Eloquent ORM, allowing for model callbacks while creating and
// updating "model" instances; however, if it not necessary to operate.
if ($dispatcher = $this->getEventDispatcher())
{
Eloquent::setEventDispatcher($dispatcher);
}
}
/**
* Set the fetch mode for the database connections.
*
* @param int $fetchMode
* @return \Illuminate\Database\Capsule\Manager
*/
public function setFetchMode($fetchMode)
{
$this->container['config']['database.fetch'] = $fetchMode;
return $this;
}
/**
* Make this capsule instance available globally.
*
* @return void
*/
public function setAsGlobal()
{
static::$instance = $this;
}
/**
* Get the database manager instance.
*
* @return \Illuminate\Database\Manager
*/
public function getDatabaseManager()
{
return $this->manager;
}
/**
* Get the current event dispatcher instance.
*
* @return \Illuminate\Events\Dispatcher
*/
public function getEventDispatcher()
{
if ($this->container->bound('events'))
{
return $this->container['events'];
}
}
/**
* Set the event dispatcher instance to be used by connections.
*
* @param \Illuminate\Events\Dispatcher $dispatcher
* @return void
*/
public function setEventDispatcher(Dispatcher $dispatcher)
{
$this->container->instance('events', $dispatcher);
}
/**
* Get the current cache manager instance.
*
* @return \Illuminate\Cache\Manager
*/
public function getCacheManager()
{
if ($this->container->bound('cache'))
{
return $this->container['cache'];
}
}
/**
* Set the cache manager to be used by connections.
*
* @param \Illuminate\Cache\CacheManager $cache
* @return void
*/
public function setCacheManager(CacheManager $cache)
{
$this->container->instance('cache', $cache);
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Set the IoC container instance.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function setContainer(Container $container)
{
$this->container = $container;
}
/**
* Dynamically pass methods to the default connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
return call_user_func_array(array(static::connection(), $method), $parameters);
}
}
<?php namespace Illuminate\Database;
use PDO;
use Closure;
use DateTime;
use Illuminate\Database\Query\Processors\Processor;
use Doctrine\DBAL\Connection as DoctrineConnection;
class Connection implements ConnectionInterface {
/**
* The active PDO connection.
*
* @var PDO
*/
protected $pdo;
/**
* The active PDO connection used for reads.
*
* @var PDO
*/
protected $readPdo;
/**
* The query grammar implementation.
*
* @var \Illuminate\Database\Query\Grammars\Grammar
*/
protected $queryGrammar;
/**
* The schema grammar implementation.
*
* @var \Illuminate\Database\Schema\Grammars\Grammar
*/
protected $schemaGrammar;
/**
* The query post processor implementation.
*
* @var \Illuminate\Database\Query\Processors\Processor
*/
protected $postProcessor;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Events\Dispatcher
*/
protected $events;
/**
* The paginator environment instance.
*
* @var \Illuminate\Pagination\Paginator
*/
protected $paginator;
/**
* The cache manager instance.
*
* @var \Illuminate\Cache\CacheManager
*/
protected $cache;
/**
* The default fetch mode of the connection.
*
* @var int
*/
protected $fetchMode = PDO::FETCH_ASSOC;
/**
* The number of active transasctions.
*
* @var int
*/
protected $transactions = 0;
/**
* All of the queries run against the connection.
*
* @var array
*/
protected $queryLog = array();
/**
* Indicates whether queries are being logged.
*
* @var bool
*/
protected $loggingQueries = true;
/**
* Indicates if the connection is in a "dry run".
*
* @var bool
*/
protected $pretending = false;
/**
* The name of the connected database.
*
* @var string
*/
protected $database;
/**
* The table prefix for the connection.
*
* @var string
*/
protected $tablePrefix = '';
/**
* The database connection configuration options.
*
* @var array
*/
protected $config = array();
/**
* Create a new database connection instance.
*
* @param PDO $pdo
* @param string $database
* @param string $tablePrefix
* @param array $config
* @return void
*/
public function __construct(PDO $pdo, $database = '', $tablePrefix = '', array $config = array())
{
$this->pdo = $pdo;
// First we will setup the default properties. We keep track of the DB
// name we are connected to since it is needed when some reflective
// type commands are run such as checking whether a table exists.
$this->database = $database;
$this->tablePrefix = $tablePrefix;
$this->config = $config;
// We need to initialize a query grammar and the query post processors
// which are both very important parts of the database abstractions
// so we initialize these to their default values while starting.
$this->useDefaultQueryGrammar();
$this->useDefaultPostProcessor();
}
/**
* Set the query grammar to the default implementation.
*
* @return void
*/
public function useDefaultQueryGrammar()
{
$this->queryGrammar = $this->getDefaultQueryGrammar();
}
/**
* Get the default query grammar instance.
*
* @return \Illuminate\Database\Query\Grammars\Grammar
*/
protected function getDefaultQueryGrammar()
{
return new Query\Grammars\Grammar;
}
/**
* Set the schema grammar to the default implementation.
*
* @return void
*/
public function useDefaultSchemaGrammar()
{
$this->schemaGrammar = $this->getDefaultSchemaGrammar();
}
/**
* Get the default schema grammar instance.
*
* @return \Illuminate\Database\Schema\Grammars\Grammar
*/
protected function getDefaultSchemaGrammar() {}
/**
* Set the query post processor to the default implementation.
*
* @return void
*/
public function useDefaultPostProcessor()
{
$this->postProcessor = $this->getDefaultPostProcessor();
}
/**
* Get the default post processor instance.
*
* @return \Illuminate\Database\Query\Processors\Processor
*/
protected function getDefaultPostProcessor()
{
return new Query\Processors\Processor;
}
/**
* Get a schema builder instance for the connection.
*
* @return \Illuminate\Database\Schema\Builder
*/
public function getSchemaBuilder()
{
if (is_null($this->schemaGrammar)) { $this->useDefaultSchemaGrammar(); }
return new Schema\Builder($this);
}
/**
* Begin a fluent query against a database table.
*
* @param string $table
* @return \Illuminate\Database\Query\Builder
*/
public function table($table)
{
$processor = $this->getPostProcessor();
$query = new Query\Builder($this, $this->getQueryGrammar(), $processor);
return $query->from($table);
}
/**
* Get a new raw query expression.
*
* @param mixed $value
* @return \Illuminate\Database\Query\Expression
*/
public function raw($value)
{
return new Query\Expression($value);
}
/**
* Run a select statement and return a single result.
*
* @param string $query
* @param array $bindings
* @return mixed
*/
public function selectOne($query, $bindings = array())
{
$records = $this->select($query, $bindings);
return count($records) > 0 ? reset($records) : null;
}
/**
* Run a select statement against the database.
*
* @param string $query
* @param array $bindings
* @return array
*/
public function select($query, $bindings = array())
{
return $this->run($query, $bindings, function($me, $query, $bindings)
{
if ($me->pretending()) return array();
// For select statements, we'll simply execute the query and return an array
// of the database result set. Each element in the array will be a single
// row from the database table, and will either be an array or objects.
$statement = $me->getReadPdo()->prepare($query);
$statement->execute($me->prepareBindings($bindings));
return $statement->fetchAll($me->getFetchMode());
});
}
/**
* Run an insert statement against the database.
*
* @param string $query
* @param array $bindings
* @return bool
*/
public function insert($query, $bindings = array())
{
return $this->statement($query, $bindings);
}
/**
* Run an update statement against the database.
*
* @param string $query
* @param array $bindings
* @return int
*/
public function update($query, $bindings = array())
{
return $this->affectingStatement($query, $bindings);
}
/**
* Run a delete statement against the database.
*
* @param string $query
* @param array $bindings
* @return int
*/
public function delete($query, $bindings = array())
{
return $this->affectingStatement($query, $bindings);
}
/**
* Execute an SQL statement and return the boolean result.
*
* @param string $query
* @param array $bindings
* @return bool
*/
public function statement($query, $bindings = array())
{
return $this->run($query, $bindings, function($me, $query, $bindings)
{
if ($me->pretending()) return true;
$bindings = $me->prepareBindings($bindings);
return $me->getPdo()->prepare($query)->execute($bindings);
});
}
/**
* Run an SQL statement and get the number of rows affected.
*
* @param string $query
* @param array $bindings
* @return int
*/
public function affectingStatement($query, $bindings = array())
{
return $this->run($query, $bindings, function($me, $query, $bindings)
{
if ($me->pretending()) return 0;
// For update or delete statements, we want to get the number of rows affected
// by the statement and return that back to the developer. We'll first need
// to execute the statement and then we'll use PDO to fetch the affected.
$statement = $me->getPdo()->prepare($query);
$statement->execute($me->prepareBindings($bindings));
return $statement->rowCount();
});
}
/**
* Run a raw, unprepared query against the PDO connection.
*
* @param string $query
* @return bool
*/
public function unprepared($query)
{
return $this->run($query, array(), function($me, $query, $bindings)
{
if ($me->pretending()) return true;
return (bool) $me->getPdo()->exec($query);
});
}
/**
* Prepare the query bindings for execution.
*
* @param array $bindings
* @return array
*/
public function prepareBindings(array $bindings)
{
$grammar = $this->getQueryGrammar();
foreach ($bindings as $key => $value)
{
// We need to transform all instances of the DateTime class into an actual
// date string. Each query grammar maintains its own date string format
// so we'll just ask the grammar for the format to get from the date.
if ($value instanceof DateTime)
{
$bindings[$key] = $value->format($grammar->getDateFormat());
}
elseif ($value === false)
{
$bindings[$key] = 0;
}
}
return $bindings;
}
/**
* Execute a Closure within a transaction.
*
* @param Closure $callback
* @return mixed
*
* @throws \Exception
*/
public function transaction(Closure $callback)
{
$this->beginTransaction();
// We'll simply execute the given callback within a try / catch block
// and if we catch any exception we can rollback the transaction
// so that none of the changes are persisted to the database.
try
{
$result = $callback($this);
$this->commit();
}
// If we catch an exception, we will roll back so nothing gets messed
// up in the database. Then we'll re-throw the exception so it can
// be handled how the developer sees fit for their applications.
catch (\Exception $e)
{
$this->rollBack();
throw $e;
}
return $result;
}
/**
* Start a new database transaction.
*
* @return void
*/
public function beginTransaction()
{
++$this->transactions;
if ($this->transactions == 1)
{
$this->pdo->beginTransaction();
}
}
/**
* Commit the active database transaction.
*
* @return void
*/
public function commit()
{
if ($this->transactions == 1) $this->pdo->commit();
--$this->transactions;
}
/**
* Rollback the active database transaction.
*
* @return void
*/
public function rollBack()
{
if ($this->transactions == 1)
{
$this->transactions = 0;
$this->pdo->rollBack();
}
else
{
--$this->transactions;
}
}
/**
* Execute the given callback in "dry run" mode.
*
* @param Closure $callback
* @return array
*/
public function pretend(Closure $callback)
{
$this->pretending = true;
$this->queryLog = array();
// Basically to make the database connection "pretend", we will just return
// the default values for all the query methods, then we will return an
// array of queries that were "executed" within the Closure callback.
$callback($this);
$this->pretending = false;
return $this->queryLog;
}
/**
* Run a SQL statement and log its execution context.
*
* @param string $query
* @param array $bindings
* @param Closure $callback
* @return mixed
*
* @throws QueryException
*/
protected function run($query, $bindings, Closure $callback)
{
$start = microtime(true);
// To execute the statement, we'll simply call the callback, which will actually
// run the SQL against the PDO connection. Then we can calculate the time it
// took to execute and log the query SQL, bindings and time in our memory.
try
{
$result = $callback($this, $query, $bindings);
}
// If an exception occurs when attempting to run a query, we'll format the error
// message to include the bindings with SQL, which will make this exception a
// lot more helpful to the developer instead of just the database's errors.
catch (\Exception $e)
{
throw new QueryException($query, $bindings, $e);
}
// Once we have run the query we will calculate the time that it took to run and
// then log the query, bindings, and execution time so we will report them on
// the event that the developer needs them. We'll log time in milliseconds.
$time = $this->getElapsedTime($start);
$this->logQuery($query, $bindings, $time);
return $result;
}
/**
* Log a query in the connection's query log.
*
* @param string $query
* @param array $bindings
* @param $time
* @return void
*/
public function logQuery($query, $bindings, $time = null)
{
if (isset($this->events))
{
$this->events->fire('illuminate.query', array($query, $bindings, $time, $this->getName()));
}
if ( ! $this->loggingQueries) return;
$this->queryLog[] = compact('query', 'bindings', 'time');
}
/**
* Register a database query listener with the connection.
*
* @param Closure $callback
* @return void
*/
public function listen(Closure $callback)
{
if (isset($this->events))
{
$this->events->listen('illuminate.query', $callback);
}
}
/**
* Get the elapsed time since a given starting point.
*
* @param int $start
* @return float
*/
protected function getElapsedTime($start)
{
return round((microtime(true) - $start) * 1000, 2);
}
/**
* Get a Doctrine Schema Column instance.
*
* @param string $table
* @param string $column
* @return \Doctrine\DBAL\Schema\Column
*/
public function getDoctrineColumn($table, $column)
{
$schema = $this->getDoctrineSchemaManager();
return $schema->listTableDetails($table)->getColumn($column);
}
/**
* Get the Doctrine DBAL schema manager for the connection.
*
* @return \Doctrine\DBAL\Schema\AbstractSchemaManager
*/
public function getDoctrineSchemaManager()
{
return $this->getDoctrineDriver()->getSchemaManager($this->getDoctrineConnection());
}
/**
* Get the Doctrine DBAL database connection instance.
*
* @return \Doctrine\DBAL\Connection
*/
public function getDoctrineConnection()
{
$driver = $this->getDoctrineDriver();
$data = array('pdo' => $this->pdo, 'dbname' => $this->getConfig('database'));
return new DoctrineConnection($data, $driver);
}
/**
* Get the current PDO connection.
*
* @return PDO
*/
public function getPdo()
{
return $this->pdo;
}
/**
* Get the current PDO connection used for reading.
*
* @return PDO
*/
public function getReadPdo()
{
if ($this->transactions >= 1) return $this->getPdo();
return $this->readPdo ?: $this->pdo;
}
/**
* Set the PDO connection.
*
* @param PDO $pdo
* @return \Illuminate\Database\Connection
*/
public function setPdo(PDO $pdo)
{
$this->pdo = $pdo;
return $this;
}
/**
* Set the PDO connection used for reading.
*
* @param PDO $pdo
* @return \Illuminate\Database\Connection
*/
public function setReadPdo(PDO $pdo)
{
$this->readPdo = $pdo;
return $this;
}
/**
* Get the database connection name.
*
* @return string|null
*/
public function getName()
{
return $this->getConfig('name');
}
/**
* Get an option from the configuration options.
*
* @param string $option
* @return mixed
*/
public function getConfig($option)
{
return array_get($this->config, $option);
}
/**
* Get the PDO driver name.
*
* @return string
*/
public function getDriverName()
{
return $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
}
/**
* Get the query grammar used by the connection.
*
* @return \Illuminate\Database\Query\Grammars\Grammar
*/
public function getQueryGrammar()
{
return $this->queryGrammar;
}
/**
* Set the query grammar used by the connection.
*
* @param \Illuminate\Database\Query\Grammars\Grammar
* @return void
*/
public function setQueryGrammar(Query\Grammars\Grammar $grammar)
{
$this->queryGrammar = $grammar;
}
/**
* Get the schema grammar used by the connection.
*
* @return \Illuminate\Database\Query\Grammars\Grammar
*/
public function getSchemaGrammar()
{
return $this->schemaGrammar;
}
/**
* Set the schema grammar used by the connection.
*
* @param \Illuminate\Database\Schema\Grammars\Grammar
* @return void
*/
public function setSchemaGrammar(Schema\Grammars\Grammar $grammar)
{
$this->schemaGrammar = $grammar;
}
/**
* Get the query post processor used by the connection.
*
* @return \Illuminate\Database\Query\Processors\Processor
*/
public function getPostProcessor()
{
return $this->postProcessor;
}
/**
* Set the query post processor used by the connection.
*
* @param \Illuminate\Database\Query\Processors\Processor
* @return void
*/
public function setPostProcessor(Processor $processor)
{
$this->postProcessor = $processor;
}
/**
* Get the event dispatcher used by the connection.
*
* @return \Illuminate\Events\Dispatcher
*/
public function getEventDispatcher()
{
return $this->events;
}
/**
* Set the event dispatcher instance on the connection.
*
* @param \Illuminate\Events\Dispatcher
* @return void
*/
public function setEventDispatcher(\Illuminate\Events\Dispatcher $events)
{
$this->events = $events;
}
/**
* Get the paginator environment instance.
*
* @return \Illuminate\Pagination\Environment
*/
public function getPaginator()
{
if ($this->paginator instanceof Closure)
{
$this->paginator = call_user_func($this->paginator);
}
return $this->paginator;
}
/**
* Set the pagination environment instance.
*
* @param \Illuminate\Pagination\Environment|\Closure $paginator
* @return void
*/
public function setPaginator($paginator)
{
$this->paginator = $paginator;
}
/**
* Get the cache manager instance.
*
* @return \Illuminate\Cache\CacheManager
*/
public function getCacheManager()
{
if ($this->cache instanceof Closure)
{
$this->cache = call_user_func($this->cache);
}
return $this->cache;
}
/**
* Set the cache manager instance on the connection.
*
* @param \Illuminate\Cache\CacheManager|\Closure $cache
* @return void
*/
public function setCacheManager($cache)
{
$this->cache = $cache;
}
/**
* Determine if the connection in a "dry run".
*
* @return bool
*/
public function pretending()
{
return $this->pretending === true;
}
/**
* Get the default fetch mode for the connection.
*
* @return int
*/
public function getFetchMode()
{
return $this->fetchMode;
}
/**
* Set the default fetch mode for the connection.
*
* @param int $fetchMode
* @return int
*/
public function setFetchMode($fetchMode)
{
$this->fetchMode = $fetchMode;
}
/**
* Get the connection query log.
*
* @return array
*/
public function getQueryLog()
{
return $this->queryLog;
}
/**
* Clear the query log.
*
* @return void
*/
public function flushQueryLog()
{
$this->queryLog = array();
}
/**
* Enable the query log on the connection.
*
* @return void
*/
public function enableQueryLog()
{
$this->loggingQueries = true;
}
/**
* Disable the query log on the connection.
*
* @return void
*/
public function disableQueryLog()
{
$this->loggingQueries = false;
}
/**
* Determine whether we're logging queries.
*
* @return bool
*/
public function logging()
{
return $this->loggingQueries;
}
/**
* Get the name of the connected database.
*
* @return string
*/
public function getDatabaseName()
{
return $this->database;
}
/**
* Set the name of the connected database.
*
* @param string $database
* @return string
*/
public function setDatabaseName($database)
{
$this->database = $database;
}
/**
* Get the table prefix for the connection.
*
* @return string
*/
public function getTablePrefix()
{
return $this->tablePrefix;
}
/**
* Set the table prefix in use by the connection.
*
* @param string $prefix
* @return void
*/
public function setTablePrefix($prefix)
{
$this->tablePrefix = $prefix;
$this->getQueryGrammar()->setTablePrefix($prefix);
}
/**
* Set the table prefix and return the grammar.
*
* @param \Illuminate\Database\Grammar $grammar
* @return \Illuminate\Database\Grammar
*/
public function withTablePrefix(Grammar $grammar)
{
$grammar->setTablePrefix($this->tablePrefix);
return $grammar;
}
}
<?php namespace Illuminate\Database;
use Closure;
interface ConnectionInterface {
/**
* Run a select statement and return a single result.
*
* @param string $query
* @param array $bindings
* @return mixed
*/
public function selectOne($query, $bindings = array());
/**
* Run a select statement against the database.
*
* @param string $query
* @param array $bindings
* @return array
*/
public function select($query, $bindings = array());
/**
* Run an insert statement against the database.
*
* @param string $query
* @param array $bindings
* @return bool
*/
public function insert($query, $bindings = array());
/**
* Run an update statement against the database.
*
* @param string $query
* @param array $bindings
* @return int
*/
public function update($query, $bindings = array());
/**
* Run a delete statement against the database.
*
* @param string $query
* @param array $bindings
* @return int
*/
public function delete($query, $bindings = array());
/**
* Execute an SQL statement and return the boolean result.
*
* @param string $query
* @param array $bindings
* @return bool
*/
public function statement($query, $bindings = array());
/**
* Execute a Closure within a transaction.
*
* @param Closure $callback
* @return mixed
*/
public function transaction(Closure $callback);
}
<?php namespace Illuminate\Database;
class ConnectionResolver implements ConnectionResolverInterface {
/**
* All of the registered connections.
*
* @var array
*/
protected $connections = array();
/**
* The default connection name.
*
* @var string
*/
protected $default;
/**
* Create a new connection resolver instance.
*
* @param array $connections
* @return void
*/
public function __construct(array $connections = array())
{
foreach ($connections as $name => $connection)
{
$this->addConnection($name, $connection);
}
}
/**
* Get a database connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function connection($name = null)
{
if (is_null($name)) $name = $this->getDefaultConnection();
return $this->connections[$name];
}
/**
* Add a connection to the resolver.
*
* @param string $name
* @param \Illuminate\Database\Connection $connection
* @return void
*/
public function addConnection($name, Connection $connection)
{
$this->connections[$name] = $connection;
}
/**
* Check if a connection has been registered.
*
* @param string $name
* @return bool
*/
public function hasConnection($name)
{
return isset($this->connections[$name]);
}
/**
* Get the default connection name.
*
* @return string
*/
public function getDefaultConnection()
{
return $this->default;
}
/**
* Set the default connection name.
*
* @param string $name
* @return void
*/
public function setDefaultConnection($name)
{
$this->default = $name;
}
}
<?php namespace Illuminate\Database;
interface ConnectionResolverInterface {
/**
* Get a database connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function connection($name = null);
/**
* Get the default connection name.
*
* @return string
*/
public function getDefaultConnection();
/**
* Set the default connection name.
*
* @param string $name
* @return void
*/
public function setDefaultConnection($name);
}
<?php namespace Illuminate\Database\Connectors;
use PDO;
use Illuminate\Container\Container;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\SQLiteConnection;
use Illuminate\Database\PostgresConnection;
use Illuminate\Database\SqlServerConnection;
class ConnectionFactory {
/**
* The IoC container instance.
*
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* Create a new connection factory instance.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* Establish a PDO connection based on the configuration.
*
* @param array $config
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function make(array $config, $name = null)
{
$config = $this->parseConfig($config, $name);
if (isset($config['read']))
{
return $this->createReadWriteConnection($config);
}
else
{
return $this->createSingleConnection($config);
}
}
/**
* Create a single database connection instance.
*
* @param array $config
* @return \Illuminate\Database\Connection
*/
protected function createSingleConnection(array $config)
{
$pdo = $this->createConnector($config)->connect($config);
return $this->createConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config);
}
/**
* Create a single database connection instance.
*
* @param array $config
* @return \Illuminate\Database\Connection
*/
protected function createReadWriteConnection(array $config)
{
$connection = $this->createSingleConnection($this->getWriteConfig($config));
return $connection->setReadPdo($this->createReadPdo($config));
}
/**
* Create a new PDO instance for reading.
*
* @param array $config
* @return \PDO
*/
protected function createReadPdo(array $config)
{
$readConfig = $this->getReadConfig($config);
return $this->createConnector($readConfig)->connect($readConfig);
}
/**
* Get the read configuration for a read / write connection.
*
* @param array $config
* @return array
*/
protected function getReadConfig(array $config)
{
$readConfig = $this->getReadWriteConfig($config, 'read');
return $this->mergeReadWriteConfig($config, $readConfig);
}
/**
* Get the read configuration for a read / write connection.
*
* @param array $config
* @return array
*/
protected function getWriteConfig(array $config)
{
$writeConfig = $this->getReadWriteConfig($config, 'write');
return $this->mergeReadWriteConfig($config, $writeConfig);
}
/**
* Get a read / write level configuration.
*
* @param array $config
* @param string $type
* @return array
*/
protected function getReadWriteConfig(array $config, $type)
{
if (isset($config[$type][0]))
{
return $config[$type][array_rand($config[$type])];
}
else
{
return $config[$type];
}
}
/**
* Merge a configuration for a read / write connection.
*
* @param array $config
* @param array $merge
* @return array
*/
protected function mergeReadWriteConfig(array $config, array $merge)
{
return array_except(array_merge($config, $merge), array('read', 'write'));
}
/**
* Parse and prepare the database configuration.
*
* @param array $config
* @param string $name
* @return array
*/
protected function parseConfig(array $config, $name)
{
return array_add(array_add($config, 'prefix', ''), 'name', $name);
}
/**
* Create a connector instance based on the configuration.
*
* @param array $config
* @return \Illuminate\Database\Connectors\ConnectorInterface
*
* @throws \InvalidArgumentException
*/
public function createConnector(array $config)
{
if ( ! isset($config['driver']))
{
throw new \InvalidArgumentException("A driver must be specified.");
}
if ($this->container->bound($key = "db.connector.{$config['driver']}"))
{
return $this->container->make($key);
}
switch ($config['driver'])
{
case 'mysql':
return new MySqlConnector;
case 'pgsql':
return new PostgresConnector;
case 'sqlite':
return new SQLiteConnector;
case 'sqlsrv':
return new SqlServerConnector;
}
throw new \InvalidArgumentException("Unsupported driver [{$config['driver']}]");
}
/**
* Create a new connection instance.
*
* @param string $driver
* @param PDO $connection
* @param string $database
* @param string $prefix
* @param array $config
* @return \Illuminate\Database\Connection
*
* @throws \InvalidArgumentException
*/
protected function createConnection($driver, PDO $connection, $database, $prefix = '', $config = null)
{
if ($this->container->bound($key = "db.connection.{$driver}"))
{
return $this->container->make($key, array($connection, $database, $prefix, $config));
}
switch ($driver)
{
case 'mysql':
return new MySqlConnection($connection, $database, $prefix, $config);
case 'pgsql':
return new PostgresConnection($connection, $database, $prefix, $config);
case 'sqlite':
return new SQLiteConnection($connection, $database, $prefix, $config);
case 'sqlsrv':
return new SqlServerConnection($connection, $database, $prefix, $config);
}
throw new \InvalidArgumentException("Unsupported driver [$driver]");
}
}
<?php namespace Illuminate\Database\Connectors;
use PDO;
class Connector {
/**
* The default PDO connection options.
*
* @var array
*/
protected $options = array(
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_EMULATE_PREPARES => false,
);
/**
* Get the PDO options based on the configuration.
*
* @param array $config
* @return array
*/
public function getOptions(array $config)
{
$options = array_get($config, 'options', array());
return array_diff_key($this->options, $options) + $options;
}
/**
* Create a new PDO connection.
*
* @param string $dsn
* @param array $config
* @param array $options
* @return PDO
*/
public function createConnection($dsn, array $config, array $options)
{
$username = array_get($config, 'username');
$password = array_get($config, 'password');
return new PDO($dsn, $username, $password, $options);
}
/**
* Get the default PDO connection options.
*
* @return array
*/
public function getDefaultOptions()
{
return $this->options;
}
/**
* Set the default PDO connection options.
*
* @param array $options
* @return void
*/
public function setDefaultOptions(array $options)
{
$this->options = $options;
}
}
<?php namespace Illuminate\Database\Connectors;
interface ConnectorInterface {
/**
* Establish a database connection.
*
* @param array $config
* @return \PDO
*/
public function connect(array $config);
}
<?php namespace Illuminate\Database\Connectors;
class MySqlConnector extends Connector implements ConnectorInterface {
/**
* Establish a database connection.
*
* @param array $config
* @return \PDO
*/
public function connect(array $config)
{
$dsn = $this->getDsn($config);
// We need to grab the PDO options that should be used while making the brand
// new connection instance. The PDO options control various aspects of the
// connection's behavior, and some might be specified by the developers.
$options = $this->getOptions($config);
$connection = $this->createConnection($dsn, $config, $options);
$collation = $config['collation'];
// Next we will set the "names" and "collation" on the clients connections so
// a correct character set will be used by this client. The collation also
// is set on the server but needs to be set here on this client objects.
$charset = $config['charset'];
$names = "set names '$charset'".
( ! is_null($collation) ? " collate '$collation'" : '');
$connection->prepare($names)->execute();
// If the "strict" option has been configured for the connection we'll enable
// strict mode on all of these tables. This enforces some extra rules when
// using the MySQL database system and is a quicker way to enforce them.
if (isset($config['strict']) && $config['strict'])
{
$connection->prepare("set session sql_mode='STRICT_ALL_TABLES'")->execute();
}
return $connection;
}
/**
* Create a DSN string from a configuration.
*
* @param array $config
* @return string
*/
protected function getDsn(array $config)
{
// First we will create the basic DSN setup as well as the port if it is in
// in the configuration options. This will give us the basic DSN we will
// need to establish the PDO connections and return them back for use.
extract($config);
$dsn = "mysql:host={$host};dbname={$database}";
if (isset($config['port']))
{
$dsn .= ";port={$port}";
}
// Sometimes the developer may specify the specific UNIX socket that should
// be used. If that is the case we will add that option to the string we
// have created so that it gets utilized while the connection is made.
if (isset($config['unix_socket']))
{
$dsn .= ";unix_socket={$config['unix_socket']}";
}
return $dsn;
}
}
<?php namespace Illuminate\Database\Connectors;
use PDO;
class PostgresConnector extends Connector implements ConnectorInterface {
/**
* The default PDO connection options.
*
* @var array
*/
protected $options = array(
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
);
/**
* Establish a database connection.
*
* @param array $config
* @return PDO
*/
public function connect(array $config)
{
// First we'll create the basic DSN and connection instance connecting to the
// using the configuration option specified by the developer. We will also
// set the default character set on the connections to UTF-8 by default.
$dsn = $this->getDsn($config);
$options = $this->getOptions($config);
$connection = $this->createConnection($dsn, $config, $options);
$charset = $config['charset'];
$connection->prepare("set names '$charset'")->execute();
// Unlike MySQL, Postgres allows the concept of "schema" and a default schema
// may have been specified on the connections. If that is the case we will
// set the default schema search paths to the specified database schema.
if (isset($config['schema']))
{
$schema = $config['schema'];
$connection->prepare("set search_path to {$schema}")->execute();
}
return $connection;
}
/**
* Create a DSN string from a configuration.
*
* @param array $config
* @return string
*/
protected function getDsn(array $config)
{
// First we will create the basic DSN setup as well as the port if it is in
// in the configuration options. This will give us the basic DSN we will
// need to establish the PDO connections and return them back for use.
extract($config);
$host = isset($host) ? "host={$host};" : '';
$dsn = "pgsql:{$host}dbname={$database}";
// If a port was specified, we will add it to this Postgres DSN connections
// format. Once we have done that we are ready to return this connection
// string back out for usage, as this has been fully constructed here.
if (isset($config['port']))
{
$dsn .= ";port={$port}";
}
return $dsn;
}
}
<?php namespace Illuminate\Database\Connectors;
class SQLiteConnector extends Connector implements ConnectorInterface {
/**
* Establish a database connection.
*
* @param array $config
* @return \PDO
*
* @throws \InvalidArgumentException
*/
public function connect(array $config)
{
$options = $this->getOptions($config);
// SQLite supports "in-memory" databases that only last as long as the owning
// connection does. These are useful for tests or for short lifetime store
// querying. In-memory databases may only have a single open connection.
if ($config['database'] == ':memory:')
{
return $this->createConnection('sqlite::memory:', $config, $options);
}
$path = realpath($config['database']);
// Here we'll verify that the SQLite database exists before we gooing further
// as the developer probably wants to know if the database exists and this
// SQLite driver will not throw any exception if it does not by default.
if ($path === false)
{
throw new \InvalidArgumentException("Database does not exist.");
}
return $this->createConnection("sqlite:{$path}", $config, $options);
}
}
<?php namespace Illuminate\Database\Connectors;
use PDO;
class SqlServerConnector extends Connector implements ConnectorInterface {
/**
* The PDO connection options.
*
* @var array
*/
protected $options = array(
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
);
/**
* Establish a database connection.
*
* @param array $config
* @return PDO
*/
public function connect(array $config)
{
$options = $this->getOptions($config);
return $this->createConnection($this->getDsn($config), $config, $options);
}
/**
* Create a DSN string from a configuration.
*
* @param array $config
* @return string
*/
protected function getDsn(array $config)
{
extract($config);
// First we will create the basic DSN setup as well as the port if it is in
// in the configuration options. This will give us the basic DSN we will
// need to establish the PDO connections and return them back for use.
$port = isset($config['port']) ? ','.$port : '';
if (in_array('dblib', $this->getAvailableDrivers()))
{
return "dblib:host={$host}{$port};dbname={$database}";
}
else
{
$dbName = $database != '' ? ";Database={$database}" : '';
return "sqlsrv:Server={$host}{$port}{$dbName}";
}
}
/**
* Get the available PDO drivers.
*
* @return array
*/
protected function getAvailableDrivers()
{
return PDO::getAvailableDrivers();
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Illuminate\Console\Command;
class BaseCommand extends Command {
/**
* Get the path to the migration directory.
*
* @return string
*/
protected function getMigrationPath()
{
$path = $this->input->getOption('path');
// First, we will check to see if a path option has been defined. If it has
// we will use the path relative to the root of this installation folder
// so that migrations may be run for any path within the applications.
if ( ! is_null($path))
{
return $this->laravel['path.base'].'/'.$path;
}
$package = $this->input->getOption('package');
// If the package is in the list of migration paths we received we will put
// the migrations in that path. Otherwise, we will assume the package is
// is in the package directories and will place them in that location.
if ( ! is_null($package))
{
return $this->packagePath.'/'.$package.'/src/migrations';
}
$bench = $this->input->getOption('bench');
// Finally we will check for the workbench option, which is a shortcut into
// specifying the full path for a "workbench" project. Workbenches allow
// developers to develop packages along side a "standard" app install.
if ( ! is_null($bench))
{
$path = "/workbench/{$bench}/src/migrations";
return $this->laravel['path.base'].$path;
}
return $this->laravel['path'].'/database/migrations';
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Illuminate\Database\Migrations\MigrationRepositoryInterface;
class InstallCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate:install';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create the migration repository';
/**
* The repository instance.
*
* @var \Illuminate\Database\Migrations\MigrationRepositoryInterface
*/
protected $repository;
/**
* Create a new migration install command instance.
*
* @param \Illuminate\Database\Migrations\MigrationRepositoryInterface $repository
* @return void
*/
public function __construct(MigrationRepositoryInterface $repository)
{
parent::__construct();
$this->repository = $repository;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->repository->setSource($this->input->getOption('database'));
$this->repository->createRepository();
$this->info("Migration table created successfully.");
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'),
);
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Illuminate\Database\Migrations\Migrator;
use Symfony\Component\Console\Input\InputOption;
class MigrateCommand extends BaseCommand {
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Run the database migrations';
/**
* The migrator instance.
*
* @var \Illuminate\Database\Migrations\Migrator
*/
protected $migrator;
/**
* The path to the packages directory (vendor).
*/
protected $packagePath;
/**
* Create a new migration command instance.
*
* @param \Illuminate\Database\Migrations\Migrator $migrator
* @param string $packagePath
* @return void
*/
public function __construct(Migrator $migrator, $packagePath)
{
parent::__construct();
$this->migrator = $migrator;
$this->packagePath = $packagePath;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->prepareDatabase();
// The pretend option can be used for "simulating" the migration and grabbing
// the SQL queries that would fire if the migration were to be run against
// a database for real, which is helpful for double checking migrations.
$pretend = $this->input->getOption('pretend');
$path = $this->getMigrationPath();
$this->migrator->run($path, $pretend);
// Once the migrator has run we will grab the note output and send it out to
// the console screen, since the migrator itself functions without having
// any instances of the OutputInterface contract passed into the class.
foreach ($this->migrator->getNotes() as $note)
{
$this->output->writeln($note);
}
// Finally, if the "seed" option has been given, we will re-run the database
// seed task to re-populate the database, which is convenient when adding
// a migration and a seed at the same time, as it is only this command.
if ($this->input->getOption('seed'))
{
$this->call('db:seed');
}
}
/**
* Prepare the migration database for running.
*
* @return void
*/
protected function prepareDatabase()
{
$this->migrator->setConnection($this->input->getOption('database'));
if ( ! $this->migrator->repositoryExists())
{
$options = array('--database' => $this->input->getOption('database'));
$this->call('migrate:install', $options);
}
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('bench', null, InputOption::VALUE_OPTIONAL, 'The name of the workbench to migrate.', null),
array('database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'),
array('path', null, InputOption::VALUE_OPTIONAL, 'The path to migration files.', null),
array('package', null, InputOption::VALUE_OPTIONAL, 'The package to migrate.', null),
array('pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'),
array('seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'),
);
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Illuminate\Database\Migrations\MigrationCreator;
class MigrateMakeCommand extends BaseCommand {
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate:make';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new migration file';
/**
* The migration creator instance.
*
* @var \Illuminate\Database\Migrations\MigrationCreator
*/
protected $creator;
/**
* The path to the packages directory (vendor).
*
* @var string
*/
protected $packagePath;
/**
* Create a new migration install command instance.
*
* @param \Illuminate\Database\Migrations\MigrationCreator $creator
* @param string $packagePath
* @return void
*/
public function __construct(MigrationCreator $creator, $packagePath)
{
parent::__construct();
$this->creator = $creator;
$this->packagePath = $packagePath;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
// It's possible for the developer to specify the tables to modify in this
// schema operation. The developer may also specify if this table needs
// to be freshly created so we can create the appropriate migrations.
$name = $this->input->getArgument('name');
$table = $this->input->getOption('table');
$create = $this->input->getOption('create');
if ( ! $table && is_string($create)) $table = $create;
// Now we are ready to write the migration out to disk. Once we've written
// the migration out, we will dump-autoload for the entire framework to
// make sure that the migrations are registered by the class loaders.
$this->writeMigration($name, $table, $create);
$this->call('dump-autoload');
}
/**
* Write the migration file to disk.
*
* @param string $name
* @param string $table
* @param bool $create
* @return string
*/
protected function writeMigration($name, $table, $create)
{
$path = $this->getMigrationPath();
$file = pathinfo($this->creator->create($name, $path, $table, $create), PATHINFO_FILENAME);
$this->line("<info>Created Migration:</info> $file");
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('name', InputArgument::REQUIRED, 'The name of the migration'),
);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('bench', null, InputOption::VALUE_OPTIONAL, 'The workbench the migration belongs to.', null),
array('create', null, InputOption::VALUE_OPTIONAL, 'The table to be created.'),
array('package', null, InputOption::VALUE_OPTIONAL, 'The package the migration belongs to.', null),
array('path', null, InputOption::VALUE_OPTIONAL, 'Where to store the migration.', null),
array('table', null, InputOption::VALUE_OPTIONAL, 'The table to migrate.'),
);
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
class RefreshCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate:refresh';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Reset and re-run all migrations';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$database = $this->input->getOption('database');
$this->call('migrate:reset', array('--database' => $database));
// The refresh command is essentially just a brief aggregate of a few other of
// the migration commands and just provides a convenient wrapper to execute
// them in succession. We'll also see if we need to res-eed the database.
$this->call('migrate', array('--database' => $database));
if ($this->needsSeeding())
{
$this->runSeeder($database);
}
}
/**
* Determine if the developer has requested database seeding.
*
* @return bool
*/
protected function needsSeeding()
{
return $this->option('seed') || $this->option('seeder');
}
/**
* Run the database seeder command.
*
* @param string $database
* @return void
*/
protected function runSeeder($database)
{
$class = $this->option('seeder') ?: 'DatabaseSeeder';
$this->call('db:seed', array('--database' => $database, '--class' => $class));
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'),
array('seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'),
array('seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder.'),
);
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Illuminate\Console\Command;
use Illuminate\Database\Migrations\Migrator;
use Symfony\Component\Console\Input\InputOption;
class ResetCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate:reset';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Rollback all database migrations';
/**
* The migrator instance.
*
* @var \Illuminate\Database\Migrations\Migrator
*/
protected $migrator;
/**
* Create a new migration rollback command instance.
*
* @param \Illuminate\Database\Migrations\Migrator $migrator
* @return void
*/
public function __construct(Migrator $migrator)
{
parent::__construct();
$this->migrator = $migrator;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->migrator->setConnection($this->input->getOption('database'));
$pretend = $this->input->getOption('pretend');
while (true)
{
$count = $this->migrator->rollback($pretend);
// Once the migrator has run we will grab the note output and send it out to
// the console screen, since the migrator itself functions without having
// any instances of the OutputInterface contract passed into the class.
foreach ($this->migrator->getNotes() as $note)
{
$this->output->writeln($note);
}
if ($count == 0) break;
}
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'),
array('pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'),
);
}
}
<?php namespace Illuminate\Database\Console\Migrations;
use Illuminate\Console\Command;
use Illuminate\Database\Migrations\Migrator;
use Symfony\Component\Console\Input\InputOption;
class RollbackCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate:rollback';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Rollback the last database migration';
/**
* The migrator instance.
*
* @var \Illuminate\Database\Migrations\Migrator
*/
protected $migrator;
/**
* Create a new migration rollback command instance.
*
* @param \Illuminate\Database\Migrations\Migrator $migrator
* @return void
*/
public function __construct(Migrator $migrator)
{
parent::__construct();
$this->migrator = $migrator;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->migrator->setConnection($this->input->getOption('database'));
$pretend = $this->input->getOption('pretend');
$this->migrator->rollback($pretend);
// Once the migrator has run we will grab the note output and send it out to
// the console screen, since the migrator itself functions without having
// any instances of the OutputInterface contract passed into the class.
foreach ($this->migrator->getNotes() as $note)
{
$this->output->writeln($note);
}
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'),
array('pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'),
);
}
}
<?php namespace Illuminate\Database\Console;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Illuminate\Database\ConnectionResolverInterface as Resolver;
class SeedCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'db:seed';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Seed the database with records';
/**
* The connection resolver instance.
*
* @var \Illuminate\Database\ConnectionResolverInterface
*/
protected $resolver;
/**
* Create a new database seed command instance.
*
* @param \Illuminate\Database\ConnectionResolverInterface $resolver
* @return void
*/
public function __construct(Resolver $resolver)
{
parent::__construct();
$this->resolver = $resolver;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->resolver->setDefaultConnection($this->getDatabase());
$this->getSeeder()->run();
}
/**
* Get a seeder instance from the container.
*
* @return \Illuminate\Database\Seeder
*/
protected function getSeeder()
{
$class = $this->laravel->make($this->input->getOption('class'));
return $class->setContainer($this->laravel)->setCommand($this);
}
/**
* Get the name of the database connection to use.
*
* @return string
*/
protected function getDatabase()
{
$database = $this->input->getOption('database');
return $database ?: $this->laravel['config']['database.default'];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('class', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder', 'DatabaseSeeder'),
array('database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'),
);
}
}
<?php namespace Illuminate\Database;
use Illuminate\Database\Connectors\ConnectionFactory;
class DatabaseManager implements ConnectionResolverInterface {
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The database connection factory instance.
*
* @var \Illuminate\Database\Connectors\ConnectionFactory
*/
protected $factory;
/**
* The active connection instances.
*
* @var array
*/
protected $connections = array();
/**
* The custom connection resolvers.
*
* @var array
*/
protected $extensions = array();
/**
* Create a new database manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @param \Illuminate\Database\Connectors\ConnectionFactory $factory
* @return void
*/
public function __construct($app, ConnectionFactory $factory)
{
$this->app = $app;
$this->factory = $factory;
}
/**
* Get a database connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function connection($name = null)
{
$name = $name ?: $this->getDefaultConnection();
// If we haven't created this connection, we'll create it based on the config
// provided in the application. Once we've created the connections we will
// set the "fetch mode" for PDO which determines the query return types.
if ( ! isset($this->connections[$name]))
{
$connection = $this->makeConnection($name);
$this->connections[$name] = $this->prepare($connection);
}
return $this->connections[$name];
}
/**
* Reconnect to the given database.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function reconnect($name = null)
{
$name = $name ?: $this->getDefaultConnection();
$this->disconnect($name);
return $this->connection($name);
}
/**
* Disconnect from the given database.
*
* @param string $name
* @return void
*/
public function disconnect($name = null)
{
$name = $name ?: $this->getDefaultConnection();
unset($this->connections[$name]);
}
/**
* Make the database connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
protected function makeConnection($name)
{
$config = $this->getConfig($name);
// First we will check by the connection name to see if an extension has been
// registered specifically for that connection. If it has we will call the
// Closure and pass it the config allowing it to resolve the connection.
if (isset($this->extensions[$name]))
{
return call_user_func($this->extensions[$name], $config, $name);
}
$driver = $config['driver'];
// Next we will check to see if an extension has been registered for a driver
// and will call the Closure if so, which allows us to have a more generic
// resolver for the drivers themselves which applies to all connections.
if (isset($this->extensions[$driver]))
{
return call_user_func($this->extensions[$driver], $config, $name);
}
return $this->factory->make($config, $name);
}
/**
* Prepare the database connection instance.
*
* @param \Illuminate\Database\Connection $connection
* @return \Illuminate\Database\Connection
*/
protected function prepare(Connection $connection)
{
$connection->setFetchMode($this->app['config']['database.fetch']);
if ($this->app->bound('events'))
{
$connection->setEventDispatcher($this->app['events']);
}
// The database connection can also utilize a cache manager instance when cache
// functionality is used on queries, which provides an expressive interface
// to caching both fluent queries and Eloquent queries that are executed.
$app = $this->app;
$connection->setCacheManager(function() use ($app)
{
return $app['cache'];
});
// We will setup a Closure to resolve the paginator instance on the connection
// since the Paginator isn't sued on every request and needs quite a few of
// our dependencies. It'll be more efficient to lazily resolve instances.
$connection->setPaginator(function() use ($app)
{
return $app['paginator'];
});
return $connection;
}
/**
* Get the configuration for a connection.
*
* @param string $name
* @return array
*
* @throws \InvalidArgumentException
*/
protected function getConfig($name)
{
$name = $name ?: $this->getDefaultConnection();
// To get the database connection configuration, we will just pull each of the
// connection configurations and get the configurations for the given name.
// If the configuration doesn't exist, we'll throw an exception and bail.
$connections = $this->app['config']['database.connections'];
if (is_null($config = array_get($connections, $name)))
{
throw new \InvalidArgumentException("Database [$name] not configured.");
}
return $config;
}
/**
* Get the default connection name.
*
* @return string
*/
public function getDefaultConnection()
{
return $this->app['config']['database.default'];
}
/**
* Set the default connection name.
*
* @param string $name
* @return void
*/
public function setDefaultConnection($name)
{
$this->app['config']['database.default'] = $name;
}
/**
* Register an extension connection resolver.
*
* @param string $name
* @param callable $resolver
* @return void
*/
public function extend($name, $resolver)
{
$this->extensions[$name] = $resolver;
}
/**
* Return all of the created connections.
*
* @return array
*/
public function getConnections()
{
return $this->connections;
}
/**
* Dynamically pass methods to the default connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array(array($this->connection(), $method), $parameters);
}
}
<?php namespace Illuminate\Database;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Connectors\ConnectionFactory;
class DatabaseServiceProvider extends ServiceProvider {
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
Model::setConnectionResolver($this->app['db']);
Model::setEventDispatcher($this->app['events']);
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// The connection factory is used to create the actual connection instances on
// the database. We will inject the factory into the manager so that it may
// make the connections while they are actually needed and not of before.
$this->app->bindShared('db.factory', function($app)
{
return new ConnectionFactory($app);
});
// The database manager is used to resolve various connections, since multiple
// connections might be managed. It also implements the connection resolver
// interface which may be used by other components requiring connections.
$this->app->bindShared('db', function($app)
{
return new DatabaseManager($app, $app['db.factory']);
});
}
}
<?php namespace Illuminate\Database\Eloquent;
use Closure;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder as QueryBuilder;
class Builder {
/**
* The base query builder instance.
*
* @var \Illuminate\Database\Query\Builder
*/
protected $query;
/**
* The model being queried.
*
* @var \Illuminate\Database\Eloquent\Model
*/
protected $model;
/**
* The relationships that should be eager loaded.
*
* @var array
*/
protected $eagerLoad = array();
/**
* The methods that should be returned from query builder.
*
* @var array
*/
protected $passthru = array(
'toSql', 'lists', 'insert', 'insertGetId', 'pluck', 'count',
'min', 'max', 'avg', 'sum', 'exists', 'getBindings',
);
/**
* Create a new Eloquent query builder instance.
*
* @param \Illuminate\Database\Query\Builder $query
* @return void
*/
public function __construct(QueryBuilder $query)
{
$this->query = $query;
}
/**
* Find a model by its primary key.
*
* @param mixed $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|static|null
*/
public function find($id, $columns = array('*'))
{
if (is_array($id))
{
return $this->findMany($id, $columns);
}
$this->query->where($this->model->getKeyName(), '=', $id);
return $this->first($columns);
}
/**
* Find a model by its primary key.
*
* @param array $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|Collection|static
*/
public function findMany($id, $columns = array('*'))
{
$this->query->whereIn($this->model->getKeyName(), $id);
return $this->get($columns);
}
/**
* Find a model by its primary key or throw an exception.
*
* @param mixed $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|static
*
* @throws ModelNotFoundException
*/
public function findOrFail($id, $columns = array('*'))
{
if ( ! is_null($model = $this->find($id, $columns))) return $model;
throw with(new ModelNotFoundException)->setModel(get_class($this->model));
}
/**
* Execute the query and get the first result.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|static|null
*/
public function first($columns = array('*'))
{
return $this->take(1)->get($columns)->first();
}
/**
* Execute the query and get the first result or throw an exception.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|static
*
* @throws ModelNotFoundException
*/
public function firstOrFail($columns = array('*'))
{
if ( ! is_null($model = $this->first($columns))) return $model;
throw with(new ModelNotFoundException)->setModel(get_class($this->model));
}
/**
* Execute the query as a "select" statement.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection|static[]
*/
public function get($columns = array('*'))
{
$models = $this->getModels($columns);
// If we actually found models we will also eager load any relationships that
// have been specified as needing to be eager loaded, which will solve the
// n+1 query issue for the developers to avoid running a lot of queries.
if (count($models) > 0)
{
$models = $this->eagerLoadRelations($models);
}
return $this->model->newCollection($models);
}
/**
* Pluck a single column from the database.
*
* @param string $column
* @return mixed
*/
public function pluck($column)
{
$result = $this->first(array($column));
if ($result) return $result->{$column};
}
/**
* Chunk the results of the query.
*
* @param int $count
* @param callable $callback
* @return void
*/
public function chunk($count, $callback)
{
$results = $this->forPage($page = 1, $count)->get();
while (count($results) > 0)
{
// On each chunk result set, we will pass them to the callback and then let the
// developer take care of everything within the callback, which allows us to
// keep the memory low for spinning through large result sets for working.
call_user_func($callback, $results);
$page++;
$results = $this->forPage($page, $count)->get();
}
}
/**
* Get an array with the values of a given column.
*
* @param string $column
* @param string $key
* @return array
*/
public function lists($column, $key = null)
{
$results = $this->query->lists($column, $key);
// If the model has a mutator for the requested column, we will spin through
// the results and mutate the values so that the mutated version of these
// columns are returned as you would expect from these Eloquent models.
if ($this->model->hasGetMutator($column))
{
foreach ($results as $key => &$value)
{
$fill = array($column => $value);
$value = $this->model->newFromBuilder($fill)->$column;
}
}
return $results;
}
/**
* Get a paginator for the "select" statement.
*
* @param int $perPage
* @param array $columns
* @return \Illuminate\Pagination\Paginator
*/
public function paginate($perPage = null, $columns = array('*'))
{
$perPage = $perPage ?: $this->model->getPerPage();
$paginator = $this->query->getConnection()->getPaginator();
if (isset($this->query->groups))
{
return $this->groupedPaginate($paginator, $perPage, $columns);
}
else
{
return $this->ungroupedPaginate($paginator, $perPage, $columns);
}
}
/**
* Get a paginator for a grouped statement.
*
* @param \Illuminate\Pagination\Environment $paginator
* @param int $perPage
* @param array $columns
* @return \Illuminate\Pagination\Paginator
*/
protected function groupedPaginate($paginator, $perPage, $columns)
{
$results = $this->get($columns)->all();
return $this->query->buildRawPaginator($paginator, $results, $perPage);
}
/**
* Get a paginator for an ungrouped statement.
*
* @param \Illuminate\Pagination\Environment $paginator
* @param int $perPage
* @param array $columns
* @return \Illuminate\Pagination\Paginator
*/
protected function ungroupedPaginate($paginator, $perPage, $columns)
{
$total = $this->query->getPaginationCount();
// Once we have the paginator we need to set the limit and offset values for
// the query so we can get the properly paginated items. Once we have an
// array of items we can create the paginator instances for the items.
$page = $paginator->getCurrentPage($total);
$this->query->forPage($page, $perPage);
return $paginator->make($this->get($columns)->all(), $total, $perPage);
}
/**
* Update a record in the database.
*
* @param array $values
* @return int
*/
public function update(array $values)
{
return $this->query->update($this->addUpdatedAtColumn($values));
}
/**
* Increment a column's value by a given amount.
*
* @param string $column
* @param int $amount
* @param array $extra
* @return int
*/
public function increment($column, $amount = 1, array $extra = array())
{
$extra = $this->addUpdatedAtColumn($extra);
return $this->query->increment($column, $amount, $extra);
}
/**
* Decrement a column's value by a given amount.
*
* @param string $column
* @param int $amount
* @param array $extra
* @return int
*/
public function decrement($column, $amount = 1, array $extra = array())
{
$extra = $this->addUpdatedAtColumn($extra);
return $this->query->decrement($column, $amount, $extra);
}
/**
* Add the "updated at" column to an array of values.
*
* @param array $values
* @return array
*/
protected function addUpdatedAtColumn(array $values)
{
if ( ! $this->model->usesTimestamps()) return $values;
$column = $this->model->getUpdatedAtColumn();
return array_add($values, $column, $this->model->freshTimestampString());
}
/**
* Delete a record from the database.
*
* @return int
*/
public function delete()
{
if ($this->model->isSoftDeleting())
{
return $this->softDelete();
}
else
{
return $this->query->delete();
}
}
/**
* Soft delete the record in the database.
*
* @return int
*/
protected function softDelete()
{
$column = $this->model->getDeletedAtColumn();
return $this->update(array($column => $this->model->freshTimestampString()));
}
/**
* Force a delete on a set of soft deleted models.
*
* @return int
*/
public function forceDelete()
{
return $this->query->delete();
}
/**
* Restore the soft-deleted model instances.
*
* @return int
*/
public function restore()
{
if ($this->model->isSoftDeleting())
{
$column = $this->model->getDeletedAtColumn();
return $this->update(array($column => null));
}
}
/**
* Include the soft deleted models in the results.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function withTrashed()
{
$column = $this->model->getQualifiedDeletedAtColumn();
foreach ((array) $this->query->wheres as $key => $where)
{
// If the where clause is a soft delete date constraint, we will remove it from
// the query and reset the keys on the wheres. This allows this developer to
// include deleted model in a relationship result set that is lazy loaded.
if ($this->isSoftDeleteConstraint($where, $column))
{
unset($this->query->wheres[$key]);
$this->query->wheres = array_values($this->query->wheres);
}
}
return $this;
}
/**
* Force the result set to only included soft deletes.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function onlyTrashed()
{
$this->withTrashed();
$this->query->whereNotNull($this->model->getQualifiedDeletedAtColumn());
return $this;
}
/**
* Determine if the given where clause is a soft delete constraint.
*
* @param array $where
* @param string $column
* @return bool
*/
protected function isSoftDeleteConstraint(array $where, $column)
{
return $where['type'] == 'Null' && $where['column'] == $column;
}
/**
* Get the hydrated models without eager loading.
*
* @param array $columns
* @return array|static[]
*/
public function getModels($columns = array('*'))
{
// First, we will simply get the raw results from the query builders which we
// can use to populate an array with Eloquent models. We will pass columns
// that should be selected as well, which are typically just everything.
$results = $this->query->get($columns);
$connection = $this->model->getConnectionName();
$models = array();
// Once we have the results, we can spin through them and instantiate a fresh
// model instance for each records we retrieved from the database. We will
// also set the proper connection name for the model after we create it.
foreach ($results as $result)
{
$models[] = $model = $this->model->newFromBuilder($result);
$model->setConnection($connection);
}
return $models;
}
/**
* Eager load the relationships for the models.
*
* @param array $models
* @return array
*/
public function eagerLoadRelations(array $models)
{
foreach ($this->eagerLoad as $name => $constraints)
{
// For nested eager loads we'll skip loading them here and they will be set as an
// eager load on the query to retrieve the relation so that they will be eager
// loaded on that query, because that is where they get hydrated as models.
if (strpos($name, '.') === false)
{
$models = $this->loadRelation($models, $name, $constraints);
}
}
return $models;
}
/**
* Eagerly load the relationship on a set of models.
*
* @param array $models
* @param string $name
* @param \Closure $constraints
* @return array
*/
protected function loadRelation(array $models, $name, Closure $constraints)
{
// First we will "back up" the existing where conditions on the query so we can
// add our eager constraints. Then we will merge the wheres that were on the
// query back to it in order that any where conditions might be specified.
$relation = $this->getRelation($name);
$relation->addEagerConstraints($models);
call_user_func($constraints, $relation);
$models = $relation->initRelation($models, $name);
// Once we have the results, we just match those back up to their parent models
// using the relationship instance. Then we just return the finished arrays
// of models which have been eagerly hydrated and are readied for return.
$results = $relation->get();
return $relation->match($models, $results, $name);
}
/**
* Get the relation instance for the given relation name.
*
* @param string $relation
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function getRelation($relation)
{
$me = $this;
// We want to run a relationship query without any constrains so that we will
// not have to remove these where clauses manually which gets really hacky
// and is error prone while we remove the developer's own where clauses.
$query = Relation::noConstraints(function() use ($me, $relation)
{
return $me->getModel()->$relation();
});
$nested = $this->nestedRelations($relation);
// If there are nested relationships set on the query, we will put those onto
// the query instances so that they can be handled after this relationship
// is loaded. In this way they will all trickle down as they are loaded.
if (count($nested) > 0)
{
$query->getQuery()->with($nested);
}
return $query;
}
/**
* Get the deeply nested relations for a given top-level relation.
*
* @param string $relation
* @return array
*/
protected function nestedRelations($relation)
{
$nested = array();
// We are basically looking for any relationships that are nested deeper than
// the given top-level relationship. We will just check for any relations
// that start with the given top relations and adds them to our arrays.
foreach ($this->eagerLoad as $name => $constraints)
{
if ($this->isNested($name, $relation))
{
$nested[substr($name, strlen($relation.'.'))] = $constraints;
}
}
return $nested;
}
/**
* Determine if the relationship is nested.
*
* @param string $name
* @param string $relation
* @return bool
*/
protected function isNested($name, $relation)
{
$dots = str_contains($name, '.');
return $dots && starts_with($name, $relation) && $name != $relation;
}
/**
* Add a basic where clause to the query.
*
* @param string $column
* @param string $operator
* @param mixed $value
* @param string $boolean
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
if ($column instanceof Closure)
{
$query = $this->model->newQuery(false);
call_user_func($column, $query);
$this->query->addNestedWhereQuery($query->getQuery(), $boolean);
}
else
{
call_user_func_array(array($this->query, 'where'), func_get_args());
}
return $this;
}
/**
* Add an "or where" clause to the query.
*
* @param string $column
* @param string $operator
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function orWhere($column, $operator = null, $value = null)
{
return $this->where($column, $operator, $value, 'or');
}
/**
* Add a relationship count condition to the query.
*
* @param string $relation
* @param string $operator
* @param int $count
* @param string $boolean
* @param \Closure $callback
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
{
$relation = $this->getHasRelationQuery($relation);
$query = $relation->getRelationCountQuery($relation->getRelated()->newQuery(), $this);
if ($callback) call_user_func($callback, $query);
return $this->addHasWhere($query, $relation, $operator, $count, $boolean);
}
/**
* Add a relationship count condition to the query with where clauses.
*
* @param string $relation
* @param \Closure $callback
* @param string $operator
* @param int $count
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1)
{
return $this->has($relation, $operator, $count, 'and', $callback);
}
/**
* Add a relationship count condition to the query with an "or".
*
* @param string $relation
* @param string $operator
* @param int $count
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function orHas($relation, $operator = '>=', $count = 1)
{
return $this->has($relation, $operator, $count, 'or');
}
/**
* Add a relationship count condition to the query with where clauses and an "or".
*
* @param string $relation
* @param \Closure $callback
* @param string $operator
* @param int $count
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function orWhereHas($relation, Closure $callback, $operator = '>=', $count = 1)
{
return $this->has($relation, $operator, $count, 'or', $callback);
}
/**
* Add the "has" condition where clause to the query.
*
* @param \Illuminate\Database\Eloquent\Builder $hasQuery
* @param \Illuminate\Database\Eloquent\Relations\Relation $relation
* @param string $operator
* @param int $count
* @param string $boolean
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function addHasWhere(Builder $hasQuery, Relation $relation, $operator, $count, $boolean)
{
$this->mergeWheresToHas($hasQuery, $relation);
return $this->where(new Expression('('.$hasQuery->toSql().')'), $operator, $count, $boolean);
}
/**
* Merge the "wheres" from a relation query to a has query.
*
* @param \Illuminate\Database\Eloquent\Builder $hasQuery
* @param \Illuminate\Database\Eloquent\Relations\Relation $relation
* @return void
*/
protected function mergeWheresToHas(Builder $hasQuery, Relation $relation)
{
// Here we have the "has" query and the original relation. We need to copy over any
// where clauses the developer may have put in the relationship function over to
// the has query, and then copy the bindings from the "has" query to the main.
$relationQuery = $relation->getBaseQuery();
$hasQuery->mergeWheres(
$relationQuery->wheres, $relationQuery->getBindings()
);
$this->query->mergeBindings($hasQuery->getQuery());
}
/**
* Get the "has relation" base query instance.
*
* @param string $relation
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function getHasRelationQuery($relation)
{
$me = $this;
return Relation::noConstraints(function() use ($me, $relation)
{
return $me->getModel()->$relation();
});
}
/**
* Set the relationships that should be eager loaded.
*
* @param dynamic $relations
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function with($relations)
{
if (is_string($relations)) $relations = func_get_args();
$eagers = $this->parseRelations($relations);
$this->eagerLoad = array_merge($this->eagerLoad, $eagers);
return $this;
}
/**
* Parse a list of relations into individuals.
*
* @param array $relations
* @return array
*/
protected function parseRelations(array $relations)
{
$results = array();
foreach ($relations as $name => $constraints)
{
// If the "relation" value is actually a numeric key, we can assume that no
// constraints have been specified for the eager load and we'll just put
// an empty Closure with the loader so that we can treat all the same.
if (is_numeric($name))
{
$f = function() {};
list($name, $constraints) = array($constraints, $f);
}
// We need to separate out any nested includes. Which allows the developers
// to load deep relationships using "dots" without stating each level of
// the relationship with its own key in the array of eager load names.
$results = $this->parseNested($name, $results);
$results[$name] = $constraints;
}
return $results;
}
/**
* Parse the nested relationships in a relation.
*
* @param string $name
* @param array $results
* @return array
*/
protected function parseNested($name, $results)
{
$progress = array();
// If the relation has already been set on the result array, we will not set it
// again, since that would override any constraints that were already placed
// on the relationships. We will only set the ones that are not specified.
foreach (explode('.', $name) as $segment)
{
$progress[] = $segment;
if ( ! isset($results[$last = implode('.', $progress)]))
{
$results[$last] = function() {};
}
}
return $results;
}
/**
* Call the given model scope on the underlying model.
*
* @param string $scope
* @param array $parameters
* @return \Illuminate\Database\Query\Builder
*/
protected function callScope($scope, $parameters)
{
array_unshift($parameters, $this);
return call_user_func_array(array($this->model, $scope), $parameters) ?: $this;
}
/**
* Get the underlying query builder instance.
*
* @return \Illuminate\Database\Query\Builder|static
*/
public function getQuery()
{
return $this->query;
}
/**
* Set the underlying query builder instance.
*
* @param \Illuminate\Database\Query\Builder $query
* @return void
*/
public function setQuery($query)
{
$this->query = $query;
}
/**
* Get the relationships being eagerly loaded.
*
* @return array
*/
public function getEagerLoads()
{
return $this->eagerLoad;
}
/**
* Set the relationships being eagerly loaded.
*
* @param array $eagerLoad
* @return void
*/
public function setEagerLoads(array $eagerLoad)
{
$this->eagerLoad = $eagerLoad;
}
/**
* Get the model instance being queried.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function getModel()
{
return $this->model;
}
/**
* Set a model instance for the model being queried.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Builder
*/
public function setModel(Model $model)
{
$this->model = $model;
$this->query->from($model->getTable());
return $this;
}
/**
* Dynamically handle calls into the query instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (method_exists($this->model, $scope = 'scope'.ucfirst($method)))
{
return $this->callScope($scope, $parameters);
}
else
{
$result = call_user_func_array(array($this->query, $method), $parameters);
}
return in_array($method, $this->passthru) ? $result : $this;
}
/**
* Force a clone of the underlying query builder when cloning.
*
* @return void
*/
public function __clone()
{
$this->query = clone $this->query;
}
}
<?php namespace Illuminate\Database\Eloquent;
use Illuminate\Support\Collection as BaseCollection;
class Collection extends BaseCollection {
/**
* Find a model in the collection by key.
*
* @param mixed $key
* @param mixed $default
* @return \Illuminate\Database\Eloquent\Model
*/
public function find($key, $default = null)
{
if ($key instanceof Model)
{
$key = $key->getKey();
}
return array_first($this->items, function($itemKey, $model) use ($key)
{
return $model->getKey() == $key;
}, $default);
}
/**
* Load a set of relationships onto the collection.
*
* @param dynamic $relations
* @return \Illuminate\Database\Eloquent\Collection
*/
public function load($relations)
{
if (count($this->items) > 0)
{
if (is_string($relations)) $relations = func_get_args();
$query = $this->first()->newQuery()->with($relations);
$this->items = $query->eagerLoadRelations($this->items);
}
return $this;
}
/**
* Add an item to the collection.
*
* @param mixed $item
* @return \Illuminate\Database\Eloquent\Collection
*/
public function add($item)
{
$this->items[] = $item;
return $this;
}
/**
* Determine if a key exists in the collection.
*
* @param mixed $key
* @return bool
*/
public function contains($key)
{
return ! is_null($this->find($key));
}
/**
* Fetch a nested element of the collection.
*
* @param string $key
* @return \Illuminate\Support\Collection
*/
public function fetch($key)
{
return new static(array_fetch($this->toArray(), $key));
}
/**
* Get the max value of a given key.
*
* @param string $key
* @return mixed
*/
public function max($key)
{
return $this->reduce(function($result, $item) use ($key)
{
return (is_null($result) || $item->{$key} > $result) ? $item->{$key} : $result;
});
}
/**
* Get the min value of a given key.
*
* @param string $key
* @return mixed
*/
public function min($key)
{
return $this->reduce(function($result, $item) use ($key)
{
return (is_null($result) || $item->{$key} < $result) ? $item->{$key} : $result;
});
}
/**
* Get the array of primary keys
*
* @return array
*/
public function modelKeys()
{
return array_map(function($m) { return $m->getKey(); }, $this->items);
}
/**
* Merge the collection with the given items.
*
* @param \Illuminate\Support\Collection|\Illuminate\Support\Contracts\ArrayableInterface|array $items
* @return \Illuminate\Support\Collection
*/
public function merge($collection)
{
$dictionary = $this->getDictionary($this);
foreach ($collection as $item)
{
$dictionary[$item->getKey()] = $item;
}
return new static(array_values($dictionary));
}
/**
* Diff the collection with the given items.
*
* @param \Illuminate\Support\Collection|\Illuminate\Support\Contracts\ArrayableInterface|array $items
* @return \Illuminate\Support\Collection
*/
public function diff($collection)
{
$diff = new static;
$dictionary = $this->getDictionary($collection);
foreach ($this->items as $item)
{
if ( ! isset($dictionary[$item->getKey()]))
{
$diff->add($item);
}
}
return $diff;
}
/**
* Intersect the collection with the given items.
*
* @param \Illuminate\Support\Collection|\Illuminate\Support\Contracts\ArrayableInterface|array $items
* @return \Illuminate\Support\Collection
*/
public function intersect($collection)
{
$intersect = new static;
$dictionary = $this->getDictionary($collection);
foreach ($this->items as $item)
{
if (isset($dictionary[$item->getKey()]))
{
$intersect->add($item);
}
}
return $intersect;
}
/**
* Return only unique items from the collection.
*
* @return \Illuminate\Support\Collection
*/
public function unique()
{
$dictionary = $this->getDictionary($this);
return new static(array_values($dictionary));
}
/**
* Get a dictionary keyed by primary keys.
*
* @param \Illuminate\Support\Collection $collection
* @return array
*/
public function getDictionary($collection)
{
$dictionary = array();
foreach ($collection as $value)
{
$dictionary[$value->getKey()] = $value;
}
return $dictionary;
}
/**
* Get a base Support collection instance from this collection.
*
* @return \Illuminate\Support\Collection
*/
public function toBase()
{
return new BaseCollection($this->items);
}
}
<?php namespace Illuminate\Database\Eloquent;
class MassAssignmentException extends \RuntimeException {}
View raw

(Sorry about that, but we can’t show files that are this big right now.)

This file has been truncated, but you can view the full file.
<?php namespace Illuminate\Database\Eloquent;
use DateTime;
use ArrayAccess;
use Carbon\Carbon;
use LogicException;
use Illuminate\Events\Dispatcher;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Contracts\JsonableInterface;
use Illuminate\Support\Contracts\ArrayableInterface;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\ConnectionResolverInterface as Resolver;
abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterface {
/**
* The connection name for the model.
*
* @var string
*/
protected $connection;
/**
* The table associated with the model.
*
* @var string
*/
protected $table;
/**
* The primary key for the model.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* The number of models to return for pagination.
*
* @var int
*/
protected $perPage = 15;
/**
* Indicates if the IDs are auto-incrementing.
*
* @var bool
*/
public $incrementing = true;
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
/**
* The model's attributes.
*
* @var array
*/
protected $attributes = array();
/**
* The model attribute's original state.
*
* @var array
*/
protected $original = array();
/**
* The loaded relationships for the model.
*
* @var array
*/
protected $relations = array();
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = array();
/**
* The attributes that should be visible in arrays.
*
* @var array
*/
protected $visible = array();
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = array();
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = array();
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = array('*');
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = array();
/**
* The relationships that should be touched on save.
*
* @var array
*/
protected $touches = array();
/**
* User exposed observable events
*
* @var array
*/
protected $observables = array();
/**
* The relations to eager load on every query.
*
* @var array
*/
protected $with = array();
/**
* Indicates if the model exists.
*
* @var bool
*/
public $exists = false;
/**
* Indicates if the model should soft delete.
*
* @var bool
*/
protected $softDelete = false;
/**
* Indicates whether attributes are snake cased on arrays.
*
* @var bool
*/
public static $snakeAttributes = true;
/**
* The connection resolver instance.
*
* @var \Illuminate\Database\ConnectionResolverInterface
*/
protected static $resolver;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Events\Dispatcher
*/
protected static $dispatcher;
/**
* The array of booted models.
*
* @var array
*/
protected static $booted = array();
/**
* Indicates if all mass assignment is enabled.
*
* @var bool
*/
protected static $unguarded = false;
/**
* The cache of the mutated attributes for each class.
*
* @var array
*/
protected static $mutatorCache = array();
/**
* The many to many relationship methods.
*
* @var array
*/
public static $manyMethods = array('belongsToMany', 'morphToMany', 'morphedByMany');
/**
* The name of the "created at" column.
*
* @var string
*/
const CREATED_AT = 'created_at';
/**
* The name of the "updated at" column.
*
* @var string
*/
const UPDATED_AT = 'updated_at';
/**
* The name of the "deleted at" column.
*
* @var string
*/
const DELETED_AT = 'deleted_at';
/**
* Create a new Eloquent model instance.
*
* @param array $attributes
* @return void
*/
public function __construct(array $attributes = array())
{
$this->bootIfNotBooted();
$this->syncOriginal();
$this->fill($attributes);
}
/**
* Check if the model needs to be booted and if so, do it.
*
* @return void
*/
protected function bootIfNotBooted()
{
if ( ! isset(static::$booted[get_class($this)]))
{
static::$booted[get_class($this)] = true;
$this->fireModelEvent('booting', false);
static::boot();
$this->fireModelEvent('booted', false);
}
}
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
$class = get_called_class();
static::$mutatorCache[$class] = array();
// Here we will extract all of the mutated attributes so that we can quickly
// spin through them after we export models to their array form, which we
// need to be fast. This will let us always know the attributes mutate.
foreach (get_class_methods($class) as $method)
{
if (preg_match('/^get(.+)Attribute$/', $method, $matches))
{
if (static::$snakeAttributes) $matches[1] = snake_case($matches[1]);
static::$mutatorCache[$class][] = lcfirst($matches[1]);
}
}
}
/**
* Register an observer with the Model.
*
* @param object $class
* @return void
*/
public static function observe($class)
{
$instance = new static;
$className = get_class($class);
// When registering a model observer, we will spin through the possible events
// and determine if this observer has that method. If it does, we will hook
// it into the model's event system, making it convenient to watch these.
foreach ($instance->getObservableEvents() as $event)
{
if (method_exists($class, $event))
{
static::registerModelEvent($event, $className.'@'.$event);
}
}
}
/**
* Fill the model with an array of attributes.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|static
*
* @throws MassAssignmentException
*/
public function fill(array $attributes)
{
$totallyGuarded = $this->totallyGuarded();
foreach ($this->fillableFromArray($attributes) as $key => $value)
{
$key = $this->removeTableFromKey($key);
// The developers may choose to place some attributes in the "fillable"
// array, which means only those attributes may be set through mass
// assignment to the model, and all others will just be ignored.
if ($this->isFillable($key))
{
$this->setAttribute($key, $value);
}
elseif ($totallyGuarded)
{
throw new MassAssignmentException($key);
}
}
return $this;
}
/**
* Get the fillable attributes of a given array.
*
* @param array $attributes
* @return array
*/
protected function fillableFromArray(array $attributes)
{
if (count($this->fillable) > 0 && ! static::$unguarded)
{
return array_intersect_key($attributes, array_flip($this->fillable));
}
return $attributes;
}
/**
* Create a new instance of the given model.
*
* @param array $attributes
* @param bool $exists
* @return \Illuminate\Database\Eloquent\Model|static
*/
public function newInstance($attributes = array(), $exists = false)
{
// This method just provides a convenient way for us to generate fresh model
// instances of this current model. It is particularly useful during the
// hydration of new objects via the Eloquent query builder instances.
$model = new static((array) $attributes);
$model->exists = $exists;
return $model;
}
/**
* Create a new model instance that is existing.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|static
*/
public function newFromBuilder($attributes = array())
{
$instance = $this->newInstance(array(), true);
$instance->setRawAttributes((array) $attributes, true);
return $instance;
}
/**
* Save a new model and return the instance.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|static
*/
public static function create(array $attributes)
{
$model = new static($attributes);
$model->save();
return $model;
}
/**
* Get the first record matching the attributes or create it.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model
*/
public static function firstOrCreate(array $attributes)
{
if ( ! is_null($instance = static::firstByAttributes($attributes)))
{
return $instance;
}
return static::create($attributes);
}
/**
* Get the first record matching the attributes or instantiate it.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model
*/
public static function firstOrNew(array $attributes)
{
if ( ! is_null($instance = static::firstByAttributes($attributes)))
{
return $instance;
}
return new static($attributes);
}
/**
* Get the first model for the given attributes.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|null
*/
protected static function firstByAttributes($attributes)
{
$query = static::query();
foreach ($attributes as $key => $value)
{
$query->where($key, $value);
}
return $query->first() ?: null;
}
/**
* Begin querying the model.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function query()
{
return with(new static)->newQuery();
}
/**
* Begin querying the model on a given connection.
*
* @param string $connection
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function on($connection = null)
{
// First we will just create a fresh instance of this model, and then we can
// set the connection on the model so that it is be used for the queries
// we execute, as well as being set on each relationship we retrieve.
$instance = new static;
$instance->setConnection($connection);
return $instance->newQuery();
}
/**
* Get all of the models from the database.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection|static[]
*/
public static function all($columns = array('*'))
{
$instance = new static;
return $instance->newQuery()->get($columns);
}
/**
* Find a model by its primary key.
*
* @param mixed $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|Collection|static
*/
public static function find($id, $columns = array('*'))
{
if (is_array($id) && empty($id)) return new Collection;
$instance = new static;
return $instance->newQuery()->find($id, $columns);
}
/**
* Find a model by its primary key or throw an exception.
*
* @param mixed $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|Collection|static
*
* @throws ModelNotFoundException
*/
public static function findOrFail($id, $columns = array('*'))
{
if ( ! is_null($model = static::find($id, $columns))) return $model;
throw with(new ModelNotFoundException)->setModel(get_called_class());
}
/**
* Eager load relations on the model.
*
* @param array|string $relations
* @return \Illuminate\Database\Eloquent\Model
*/
public function load($relations)
{
if (is_string($relations)) $relations = func_get_args();
$query = $this->newQuery()->with($relations);
$query->eagerLoadRelations(array($this));
return $this;
}
/**
* Being querying a model with eager loading.
*
* @param array|string $relations
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function with($relations)
{
if (is_string($relations)) $relations = func_get_args();
$instance = new static;
return $instance->newQuery()->with($relations);
}
/**
* Define a one-to-one relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function hasOne($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
$localKey = $localKey ?: $this->getKeyName();
return new HasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
}
/**
* Define a polymorphic one-to-one relationship.
*
* @param string $related
* @param string $name
* @param string $type
* @param string $id
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
*/
public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
{
$instance = new $related;
list($type, $id) = $this->getMorphs($name, $type, $id);
$table = $instance->getTable();
$localKey = $localKey ?: $this->getKeyName();
return new MorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
}
/**
* Define an inverse one-to-one or many relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $otherKey
* @param string $relation
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation))
{
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
// If no foreign key was supplied, we can use a backtrace to guess the proper
// foreign key name by using the name of the relationship function, which
// when combined with an "_id" should conventionally match the columns.
if (is_null($foreignKey))
{
$foreignKey = snake_case($relation).'_id';
}
$instance = new $related;
// Once we have the foreign key names, we'll just create a new Eloquent query
// for the related models and returns the relationship instance which will
// actually be responsible for retrieving and hydrating every relations.
$query = $instance->newQuery();
$otherKey = $otherKey ?: $instance->getKeyName();
return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
}
/**
* Define a polymorphic, inverse one-to-one or many relationship.
*
* @param string $name
* @param string $type
* @param string $id
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function morphTo($name = null, $type = null, $id = null)
{
// If no name is provided, we will use the backtrace to get the function name
// since that is most likely the name of the polymorphic interface. We can
// use that to get both the class and foreign key that will be utilized.
if (is_null($name))
{
list(, $caller) = debug_backtrace(false);
$name = snake_case($caller['function']);
}
// Next we will guess the type and ID if necessary. The type and IDs may also
// be passed into the function so that the developers may manually specify
// them on the relations. Otherwise, we will just make a great estimate.
list($type, $id) = $this->getMorphs($name, $type, $id);
$class = $this->$type;
return $this->belongsTo($class, $id);
}
/**
* Define a one-to-many relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function hasMany($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
$localKey = $localKey ?: $this->getKeyName();
return new HasMany($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
}
/**
* Define a has-many-through relationship.
*
* @param string $related
* @param string $through
* @param string|null $firstKey
* @param string|null $secondKey
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null)
{
$through = new $through;
$firstKey = $firstKey ?: $this->getForeignKey();
$secondKey = $secondKey ?: $through->getForeignKey();
return new HasManyThrough(with(new $related)->newQuery(), $this, $through, $firstKey, $secondKey);
}
/**
* Define a polymorphic one-to-many relationship.
*
* @param string $related
* @param string $name
* @param string $type
* @param string $id
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
{
$instance = new $related;
// Here we will gather up the morph type and ID for the relationship so that we
// can properly query the intermediate table of a relation. Finally, we will
// get the table and create the relationship instances for the developers.
list($type, $id) = $this->getMorphs($name, $type, $id);
$table = $instance->getTable();
$localKey = $localKey ?: $this->getKeyName();
return new MorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
}
/**
* Define a many-to-many relationship.
*
* @param string $related
* @param string $table
* @param string $foreignKey
* @param string $otherKey
* @param string $relation
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
{
// If no relationship name was passed, we will pull backtraces to get the
// name of the calling function. We will use that function name as the
// title of this relation since that is a great convention to apply.
if (is_null($relation))
{
$relation = $this->getBelongsToManyCaller();
}
// First, we'll need to determine the foreign key and "other key" for the
// relationship. Once we have determined the keys we'll make the query
// instances as well as the relationship instances we need for this.
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
$otherKey = $otherKey ?: $instance->getForeignKey();
// If no table name was provided, we can guess it by concatenating the two
// models using underscores in alphabetical order. The two model names
// are transformed to snake case from their default CamelCase also.
if (is_null($table))
{
$table = $this->joiningTable($related);
}
// Now we're ready to create a new query builder for the related model and
// the relationship instances for the relation. The relations will set
// appropriate query constraint and entirely manages the hydrations.
$query = $instance->newQuery();
return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation);
}
/**
* Define a polymorphic many-to-many relationship.
*
* @param string $related
* @param string $name
* @param string $table
* @param string $foreignKey
* @param string $otherKey
* @param bool $inverse
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/
public function morphToMany($related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
{
$caller = $this->getBelongsToManyCaller();
// First, we will need to determine the foreign key and "other key" for the
// relationship. Once we have determined the keys we will make the query
// instances, as well as the relationship instances we need for these.
$foreignKey = $foreignKey ?: $name.'_id';
$instance = new $related;
$otherKey = $otherKey ?: $instance->getForeignKey();
// Now we're ready to create a new query builder for this related model and
// the relationship instances for this relation. This relations will set
// appropriate query constraints then entirely manages the hydrations.
$query = $instance->newQuery();
$table = $table ?: str_plural($name);
return new MorphToMany(
$query, $this, $name, $table, $foreignKey,
$otherKey, $caller, $inverse
);
}
/**
* Define a polymorphic, inverse many-to-many relationship.
*
* @param string $related
* @param string $name
* @param string $table
* @param string $foreignKey
* @param string $otherKey
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/
public function morphedByMany($related, $name, $table = null, $foreignKey = null, $otherKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
// For the inverse of the polymorphic many-to-many relations, we will change
// the way we determine the foreign and other keys, as it is the opposite
// of the morph-to-many method since we're figuring out these inverses.
$otherKey = $otherKey ?: $name.'_id';
return $this->morphToMany($related, $name, $table, $foreignKey, $otherKey, true);
}
/**
* Get the relationship name of the belongs to many.
*
* @return string
*/
protected function getBelongsToManyCaller()
{
$self = __FUNCTION__;
$caller = array_first(debug_backtrace(false), function($key, $trace) use ($self)
{
$caller = $trace['function'];
return ( ! in_array($caller, Model::$manyMethods) && $caller != $self);
});
return ! is_null($caller) ? $caller['function'] : null;
}
/**
* Get the joining table name for a many-to-many relation.
*
* @param string $related
* @return string
*/
public function joiningTable($related)
{
// The joining table name, by convention, is simply the snake cased models
// sorted alphabetically and concatenated with an underscore, so we can
// just sort the models and join them together to get the table name.
$base = snake_case(class_basename($this));
$related = snake_case(class_basename($related));
$models = array($related, $base);
// Now that we have the model names in an array we can just sort them and
// use the implode function to join them together with an underscores,
// which is typically used by convention within the database system.
sort($models);
return strtolower(implode('_', $models));
}
/**
* Destroy the models for the given IDs.
*
* @param array|int $ids
* @return int
*/
public static function destroy($ids)
{
// We'll initialize a count here so we will return the total number of deletes
// for the operation. The developers can then check this number as a boolean
// type value or get this total count of records deleted for logging, etc.
$count = 0;
$ids = is_array($ids) ? $ids : func_get_args();
$instance = new static;
// We will actually pull the models from the database table and call delete on
// each of them individually so that their events get fired properly with a
// correct set of attributes in case the developers wants to check these.
$key = $instance->getKeyName();
foreach ($instance->whereIn($key, $ids)->get() as $model)
{
if ($model->delete()) $count++;
}
return $count;
}
/**
* Delete the model from the database.
*
* @return bool|null
*/
public function delete()
{
if ($this->exists)
{
if ($this->fireModelEvent('deleting') === false) return false;
// Here, we'll touch the owning models, verifying these timestamps get updated
// for the models. This will allow any caching to get broken on the parents
// by the timestamp. Then we will go ahead and delete the model instance.
$this->touchOwners();
$this->performDeleteOnModel();
$this->exists = false;
// Once the model has been deleted, we will fire off the deleted event so that
// the developers may hook into post-delete operations. We will then return
// a boolean true as the delete is presumably successful on the database.
$this->fireModelEvent('deleted', false);
return true;
}
}
/**
* Force a hard delete on a soft deleted model.
*
* @return void
*/
public function forceDelete()
{
$softDelete = $this->softDelete;
// We will temporarily disable false delete to allow us to perform the real
// delete operation against the model. We will then restore the deleting
// state to what this was prior to this given hard deleting operation.
$this->softDelete = false;
$this->delete();
$this->softDelete = $softDelete;
}
/**
* Perform the actual delete query on this model instance.
*
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment