mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-22 21:18:00 +01:00
10086 lines
328 KiB
PHP
10086 lines
328 KiB
PHP
<?php
|
||
namespace Illuminate\Support;
|
||
|
||
class ClassLoader
|
||
{
|
||
protected static $directories = array();
|
||
protected static $registered = false;
|
||
public static function load($class)
|
||
{
|
||
$class = static::normalizeClass($class);
|
||
foreach (static::$directories as $directory) {
|
||
if (file_exists($path = $directory . DIRECTORY_SEPARATOR . $class)) {
|
||
require_once $path;
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
public static function normalizeClass($class)
|
||
{
|
||
if ($class[0] == '\\') {
|
||
$class = substr($class, 1);
|
||
}
|
||
return str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $class) . '.php';
|
||
}
|
||
public static function register()
|
||
{
|
||
if (!static::$registered) {
|
||
spl_autoload_register(array('\\Illuminate\\Support\\ClassLoader', 'load'));
|
||
static::$registered = true;
|
||
}
|
||
}
|
||
public static function addDirectories($directories)
|
||
{
|
||
static::$directories = array_merge(static::$directories, (array) $directories);
|
||
static::$directories = array_unique(static::$directories);
|
||
}
|
||
public static function removeDirectories($directories = null)
|
||
{
|
||
if (is_null($directories)) {
|
||
static::$directories = array();
|
||
} else {
|
||
$directories = (array) $directories;
|
||
static::$directories = array_filter(static::$directories, function ($directory) use($directories) {
|
||
return !in_array($directory, $directories);
|
||
});
|
||
}
|
||
}
|
||
public static function getDirectories()
|
||
{
|
||
return static::$directories;
|
||
}
|
||
}
|
||
namespace Illuminate\Container;
|
||
|
||
use Closure, ArrayAccess, ReflectionParameter;
|
||
class BindingResolutionException extends \Exception
|
||
{
|
||
|
||
}
|
||
class Container implements ArrayAccess
|
||
{
|
||
protected $bindings = array();
|
||
protected $instances = array();
|
||
protected $aliases = array();
|
||
protected $resolvingCallbacks = array();
|
||
public function bound($abstract)
|
||
{
|
||
return isset($this[$abstract]) or isset($this->instances[$abstract]);
|
||
}
|
||
public function bind($abstract, $concrete = null, $shared = false)
|
||
{
|
||
if (is_array($abstract)) {
|
||
list($abstract, $alias) = $this->extractAlias($abstract);
|
||
$this->alias($abstract, $alias);
|
||
}
|
||
unset($this->instances[$abstract]);
|
||
if (is_null($concrete)) {
|
||
$concrete = $abstract;
|
||
}
|
||
if (!$concrete instanceof Closure) {
|
||
$concrete = function ($c) use($abstract, $concrete) {
|
||
$method = $abstract == $concrete ? 'build' : 'make';
|
||
return $c->{$method}($concrete);
|
||
};
|
||
}
|
||
$this->bindings[$abstract] = compact('concrete', 'shared');
|
||
}
|
||
public function bindIf($abstract, $concrete = null, $shared = false)
|
||
{
|
||
if (!$this->bound($abstract)) {
|
||
$this->bind($abstract, $concrete, $shared);
|
||
}
|
||
}
|
||
public function singleton($abstract, $concrete = null)
|
||
{
|
||
return $this->bind($abstract, $concrete, true);
|
||
}
|
||
public function share(Closure $closure)
|
||
{
|
||
return function ($container) use($closure) {
|
||
static $object;
|
||
if (is_null($object)) {
|
||
$object = $closure($container);
|
||
}
|
||
return $object;
|
||
};
|
||
}
|
||
public function extend($abstract, Closure $closure)
|
||
{
|
||
if (!isset($this->bindings[$abstract])) {
|
||
throw new \InvalidArgumentException("Type {$abstract} is not bound.");
|
||
}
|
||
$resolver = $this->bindings[$abstract]['concrete'];
|
||
$this->bind($abstract, function ($container) use($resolver, $closure) {
|
||
return $closure($resolver($container), $container);
|
||
}, $this->isShared($abstract));
|
||
}
|
||
public function instance($abstract, $instance)
|
||
{
|
||
if (is_array($abstract)) {
|
||
list($abstract, $alias) = $this->extractAlias($abstract);
|
||
$this->alias($abstract, $alias);
|
||
}
|
||
$this->instances[$abstract] = $instance;
|
||
}
|
||
public function alias($abstract, $alias)
|
||
{
|
||
$this->aliases[$alias] = $abstract;
|
||
}
|
||
protected function extractAlias(array $definition)
|
||
{
|
||
return array(key($definition), current($definition));
|
||
}
|
||
public function make($abstract, $parameters = array())
|
||
{
|
||
$abstract = $this->getAlias($abstract);
|
||
if (isset($this->instances[$abstract])) {
|
||
return $this->instances[$abstract];
|
||
}
|
||
$concrete = $this->getConcrete($abstract);
|
||
if ($this->isBuildable($concrete, $abstract)) {
|
||
$object = $this->build($concrete, $parameters);
|
||
} else {
|
||
$object = $this->make($concrete, $parameters);
|
||
}
|
||
if ($this->isShared($abstract)) {
|
||
$this->instances[$abstract] = $object;
|
||
}
|
||
$this->fireResolvingCallbacks($object);
|
||
return $object;
|
||
}
|
||
protected function getConcrete($abstract)
|
||
{
|
||
if (!isset($this->bindings[$abstract])) {
|
||
return $abstract;
|
||
} else {
|
||
return $this->bindings[$abstract]['concrete'];
|
||
}
|
||
}
|
||
public function build($concrete, $parameters = array())
|
||
{
|
||
if ($concrete instanceof Closure) {
|
||
return $concrete($this, $parameters);
|
||
}
|
||
$reflector = new \ReflectionClass($concrete);
|
||
if (!$reflector->isInstantiable()) {
|
||
$message = "Target [{$concrete}] is not instantiable.";
|
||
throw new BindingResolutionException($message);
|
||
}
|
||
$constructor = $reflector->getConstructor();
|
||
if (is_null($constructor)) {
|
||
return new $concrete();
|
||
}
|
||
$parameters = $constructor->getParameters();
|
||
$dependencies = $this->getDependencies($parameters);
|
||
return $reflector->newInstanceArgs($dependencies);
|
||
}
|
||
protected function getDependencies($parameters)
|
||
{
|
||
$dependencies = array();
|
||
foreach ($parameters as $parameter) {
|
||
$dependency = $parameter->getClass();
|
||
if (is_null($dependency)) {
|
||
$dependencies[] = $this->resolveNonClass($parameter);
|
||
} else {
|
||
$dependencies[] = $this->make($dependency->name);
|
||
}
|
||
}
|
||
return (array) $dependencies;
|
||
}
|
||
protected function resolveNonClass(ReflectionParameter $parameter)
|
||
{
|
||
if ($parameter->isDefaultValueAvailable()) {
|
||
return $parameter->getDefaultValue();
|
||
} else {
|
||
$message = "Unresolvable dependency resolving [{$parameter}].";
|
||
throw new BindingResolutionException($message);
|
||
}
|
||
}
|
||
public function resolving(Closure $callback)
|
||
{
|
||
$this->resolvingCallbacks[] = $callback;
|
||
}
|
||
protected function fireResolvingCallbacks($object)
|
||
{
|
||
foreach ($this->resolvingCallbacks as $callback) {
|
||
call_user_func($callback, $object);
|
||
}
|
||
}
|
||
protected function isShared($abstract)
|
||
{
|
||
$set = isset($this->bindings[$abstract]['shared']);
|
||
return $set and $this->bindings[$abstract]['shared'] === true;
|
||
}
|
||
protected function isBuildable($concrete, $abstract)
|
||
{
|
||
return $concrete === $abstract or $concrete instanceof Closure;
|
||
}
|
||
protected function getAlias($abstract)
|
||
{
|
||
return isset($this->aliases[$abstract]) ? $this->aliases[$abstract] : $abstract;
|
||
}
|
||
public function getBindings()
|
||
{
|
||
return $this->bindings;
|
||
}
|
||
public function offsetExists($key)
|
||
{
|
||
return isset($this->bindings[$key]);
|
||
}
|
||
public function offsetGet($key)
|
||
{
|
||
return $this->make($key);
|
||
}
|
||
public function offsetSet($key, $value)
|
||
{
|
||
if (!$value instanceof Closure) {
|
||
$value = function () use($value) {
|
||
return $value;
|
||
};
|
||
}
|
||
$this->bind($key, $value);
|
||
}
|
||
public function offsetUnset($key)
|
||
{
|
||
unset($this->bindings[$key]);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpKernel;
|
||
|
||
use Symfony\Component\HttpFoundation\Request;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
interface HttpKernelInterface
|
||
{
|
||
const MASTER_REQUEST = 1;
|
||
const SUB_REQUEST = 2;
|
||
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
|
||
}
|
||
namespace Illuminate\Support\Contracts;
|
||
|
||
interface ResponsePreparerInterface
|
||
{
|
||
public function prepareResponse($value);
|
||
}
|
||
namespace Illuminate\Foundation;
|
||
|
||
use Closure;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Http\Response;
|
||
use Illuminate\Routing\Route;
|
||
use Illuminate\Routing\Router;
|
||
use Illuminate\Config\FileLoader;
|
||
use Illuminate\Container\Container;
|
||
use Illuminate\Filesystem\Filesystem;
|
||
use Illuminate\Support\Facades\Facade;
|
||
use Illuminate\Support\ServiceProvider;
|
||
use Illuminate\Events\EventServiceProvider;
|
||
use Illuminate\Foundation\ProviderRepository;
|
||
use Illuminate\Routing\RoutingServiceProvider;
|
||
use Illuminate\Exception\ExceptionServiceProvider;
|
||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||
use Illuminate\Support\Contracts\ResponsePreparerInterface;
|
||
use Symfony\Component\HttpKernel\Exception\FatalErrorException;
|
||
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
|
||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||
use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirect;
|
||
class Application extends Container implements HttpKernelInterface, ResponsePreparerInterface
|
||
{
|
||
const VERSION = '4.0.2';
|
||
protected $booted = false;
|
||
protected $bootingCallbacks = array();
|
||
protected $bootedCallbacks = array();
|
||
protected $shutdownCallbacks = array();
|
||
protected $serviceProviders = array();
|
||
protected $loadedProviders = array();
|
||
protected $deferredServices = array();
|
||
public function __construct(Request $request = null)
|
||
{
|
||
$this['request'] = $this->createRequest($request);
|
||
$this->register(new ExceptionServiceProvider($this));
|
||
$this->register(new RoutingServiceProvider($this));
|
||
$this->register(new EventServiceProvider($this));
|
||
}
|
||
protected function createRequest(Request $request = null)
|
||
{
|
||
return $request ?: Request::createFromGlobals();
|
||
}
|
||
public function setRequestForConsoleEnvironment()
|
||
{
|
||
$url = $this['config']->get('app.url', 'http://localhost');
|
||
$this->instance('request', Request::create($url, 'GET', array(), array(), array(), $_SERVER));
|
||
}
|
||
public function redirectIfTrailingSlash()
|
||
{
|
||
if ($this->runningInConsole()) {
|
||
return;
|
||
}
|
||
$path = $this['request']->getPathInfo();
|
||
if ($path != '/' and ends_with($path, '/') and !ends_with($path, '//')) {
|
||
with(new SymfonyRedirect($this['request']->fullUrl(), 301))->send();
|
||
die;
|
||
}
|
||
}
|
||
public function bindInstallPaths(array $paths)
|
||
{
|
||
$this->instance('path', realpath($paths['app']));
|
||
foreach (array_except($paths, array('app')) as $key => $value) {
|
||
$this->instance("path.{$key}", realpath($value));
|
||
}
|
||
}
|
||
public static function getBootstrapFile()
|
||
{
|
||
return 'F:\\Nelson\\My Documents - Personal\\Visual Studio 2010\\Projects\\Poniverse\\spa.pony.fm\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation' . '/start.php';
|
||
}
|
||
public function startExceptionHandling()
|
||
{
|
||
$this['exception']->register($this->environment());
|
||
$this['exception']->setDebug($this['config']['app.debug']);
|
||
}
|
||
public function environment()
|
||
{
|
||
return $this['env'];
|
||
}
|
||
public function detectEnvironment($environments)
|
||
{
|
||
$base = $this['request']->getHost();
|
||
$arguments = $this['request']->server->get('argv');
|
||
if ($this->runningInConsole()) {
|
||
return $this->detectConsoleEnvironment($base, $environments, $arguments);
|
||
}
|
||
return $this->detectWebEnvironment($base, $environments);
|
||
}
|
||
protected function detectWebEnvironment($base, $environments)
|
||
{
|
||
if ($environments instanceof Closure) {
|
||
return $this['env'] = call_user_func($environments);
|
||
}
|
||
foreach ($environments as $environment => $hosts) {
|
||
foreach ((array) $hosts as $host) {
|
||
if (str_is($host, $base) or $this->isMachine($host)) {
|
||
return $this['env'] = $environment;
|
||
}
|
||
}
|
||
}
|
||
return $this['env'] = 'production';
|
||
}
|
||
protected function detectConsoleEnvironment($base, $environments, $arguments)
|
||
{
|
||
foreach ($arguments as $key => $value) {
|
||
if (starts_with($value, '--env=')) {
|
||
$segments = array_slice(explode('=', $value), 1);
|
||
return $this['env'] = head($segments);
|
||
}
|
||
}
|
||
return $this->detectWebEnvironment($base, $environments);
|
||
}
|
||
protected function isMachine($name)
|
||
{
|
||
return str_is($name, gethostname());
|
||
}
|
||
public function runningInConsole()
|
||
{
|
||
return php_sapi_name() == 'cli';
|
||
}
|
||
public function runningUnitTests()
|
||
{
|
||
return $this['env'] == 'testing';
|
||
}
|
||
public function register($provider, $options = array())
|
||
{
|
||
if (is_string($provider)) {
|
||
$provider = $this->resolveProviderClass($provider);
|
||
}
|
||
$provider->register();
|
||
foreach ($options as $key => $value) {
|
||
$this[$key] = $value;
|
||
}
|
||
$this->serviceProviders[] = $provider;
|
||
$this->loadedProviders[get_class($provider)] = true;
|
||
}
|
||
protected function resolveProviderClass($provider)
|
||
{
|
||
return new $provider($this);
|
||
}
|
||
public function loadDeferredProviders()
|
||
{
|
||
foreach (array_unique($this->deferredServices) as $provider) {
|
||
$this->register($instance = new $provider($this));
|
||
if ($this->booted) {
|
||
$instance->boot();
|
||
}
|
||
}
|
||
$this->deferredServices = array();
|
||
}
|
||
protected function loadDeferredProvider($service)
|
||
{
|
||
$provider = $this->deferredServices[$service];
|
||
if (!isset($this->loadedProviders[$provider])) {
|
||
$this->register($instance = new $provider($this));
|
||
unset($this->deferredServices[$service]);
|
||
$this->setupDeferredBoot($instance);
|
||
}
|
||
}
|
||
protected function setupDeferredBoot($instance)
|
||
{
|
||
if ($this->booted) {
|
||
return $instance->boot();
|
||
}
|
||
$this->booting(function () use($instance) {
|
||
$instance->boot();
|
||
});
|
||
}
|
||
public function make($abstract, $parameters = array())
|
||
{
|
||
if (isset($this->deferredServices[$abstract])) {
|
||
$this->loadDeferredProvider($abstract);
|
||
}
|
||
return parent::make($abstract, $parameters);
|
||
}
|
||
public function before($callback)
|
||
{
|
||
return $this['router']->before($callback);
|
||
}
|
||
public function after($callback)
|
||
{
|
||
return $this['router']->after($callback);
|
||
}
|
||
public function close($callback)
|
||
{
|
||
return $this['router']->close($callback);
|
||
}
|
||
public function finish($callback)
|
||
{
|
||
$this['router']->finish($callback);
|
||
}
|
||
public function shutdown($callback = null)
|
||
{
|
||
if (is_null($callback)) {
|
||
$this->fireAppCallbacks($this->shutdownCallbacks);
|
||
} else {
|
||
$this->shutdownCallbacks[] = $callback;
|
||
}
|
||
}
|
||
public function run()
|
||
{
|
||
$response = $this->dispatch($this['request']);
|
||
$this['router']->callCloseFilter($this['request'], $response);
|
||
$response->send();
|
||
$this['router']->callFinishFilter($this['request'], $response);
|
||
}
|
||
public function dispatch(Request $request)
|
||
{
|
||
if ($this->isDownForMaintenance()) {
|
||
$response = $this['events']->until('illuminate.app.down');
|
||
return $this->prepareResponse($response, $request);
|
||
} else {
|
||
return $this['router']->dispatch($this->prepareRequest($request));
|
||
}
|
||
}
|
||
public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
||
{
|
||
$this->instance('request', $request);
|
||
Facade::clearResolvedInstance('request');
|
||
return $this->dispatch($request);
|
||
}
|
||
public function boot()
|
||
{
|
||
if ($this->booted) {
|
||
return;
|
||
}
|
||
foreach ($this->serviceProviders as $provider) {
|
||
$provider->boot();
|
||
}
|
||
$this->fireAppCallbacks($this->bootingCallbacks);
|
||
$this->booted = true;
|
||
$this->fireAppCallbacks($this->bootedCallbacks);
|
||
}
|
||
public function booting($callback)
|
||
{
|
||
$this->bootingCallbacks[] = $callback;
|
||
}
|
||
public function booted($callback)
|
||
{
|
||
$this->bootedCallbacks[] = $callback;
|
||
}
|
||
protected function fireAppCallbacks(array $callbacks)
|
||
{
|
||
foreach ($callbacks as $callback) {
|
||
call_user_func($callback, $this);
|
||
}
|
||
}
|
||
public function prepareRequest(Request $request)
|
||
{
|
||
if (isset($this['session'])) {
|
||
$request->setSessionStore($this['session']);
|
||
}
|
||
return $request;
|
||
}
|
||
public function prepareResponse($value)
|
||
{
|
||
if (!$value instanceof SymfonyResponse) {
|
||
$value = new Response($value);
|
||
}
|
||
return $value->prepare($this['request']);
|
||
}
|
||
public function isDownForMaintenance()
|
||
{
|
||
return file_exists($this['path.storage'] . '/meta/down');
|
||
}
|
||
public function down(Closure $callback)
|
||
{
|
||
$this['events']->listen('illuminate.app.down', $callback);
|
||
}
|
||
public function abort($code, $message = '', array $headers = array())
|
||
{
|
||
if ($code == 404) {
|
||
throw new NotFoundHttpException($message);
|
||
} else {
|
||
throw new HttpException($code, $message, null, $headers);
|
||
}
|
||
}
|
||
public function missing(Closure $callback)
|
||
{
|
||
$this->error(function (NotFoundHttpException $e) use($callback) {
|
||
return call_user_func($callback, $e);
|
||
});
|
||
}
|
||
public function error(Closure $callback)
|
||
{
|
||
$this['exception']->error($callback);
|
||
}
|
||
public function pushError(Closure $closure)
|
||
{
|
||
$this['exception']->pushError($callback);
|
||
}
|
||
public function fatal(Closure $callback)
|
||
{
|
||
$this->error(function (FatalErrorException $e) use($callback) {
|
||
return call_user_func($callback, $e);
|
||
});
|
||
}
|
||
public function getConfigLoader()
|
||
{
|
||
return new FileLoader(new Filesystem(), $this['path'] . '/config');
|
||
}
|
||
public function getProviderRepository()
|
||
{
|
||
$manifest = $this['config']['app.manifest'];
|
||
return new ProviderRepository(new Filesystem(), $manifest);
|
||
}
|
||
public function setLocale($locale)
|
||
{
|
||
$this['config']->set('app.locale', $locale);
|
||
$this['translator']->setLocale($locale);
|
||
$this['events']->fire('locale.changed', array($locale));
|
||
}
|
||
public function getLoadedProviders()
|
||
{
|
||
return $this->loadedProviders;
|
||
}
|
||
public function setDeferredServices(array $services)
|
||
{
|
||
$this->deferredServices = $services;
|
||
}
|
||
public function __get($key)
|
||
{
|
||
return $this[$key];
|
||
}
|
||
public function __set($key, $value)
|
||
{
|
||
$this[$key] = $value;
|
||
}
|
||
}
|
||
namespace Illuminate\Http;
|
||
|
||
use Illuminate\Session\Store as SessionStore;
|
||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||
class Request extends \Symfony\Component\HttpFoundation\Request
|
||
{
|
||
protected $json;
|
||
protected $sessionStore;
|
||
public function instance()
|
||
{
|
||
return $this;
|
||
}
|
||
public function root()
|
||
{
|
||
return rtrim($this->getSchemeAndHttpHost() . $this->getBaseUrl(), '/');
|
||
}
|
||
public function url()
|
||
{
|
||
return rtrim(preg_replace('/\\?.*/', '', $this->getUri()), '/');
|
||
}
|
||
public function fullUrl()
|
||
{
|
||
$query = $this->getQueryString();
|
||
return $query ? $this->url() . '?' . $query : $this->url();
|
||
}
|
||
public function path()
|
||
{
|
||
$pattern = trim($this->getPathInfo(), '/');
|
||
return $pattern == '' ? '/' : $pattern;
|
||
}
|
||
public function segment($index, $default = null)
|
||
{
|
||
$segments = explode('/', trim($this->getPathInfo(), '/'));
|
||
$segments = array_filter($segments, function ($v) {
|
||
return $v != '';
|
||
});
|
||
return array_get($segments, $index - 1, $default);
|
||
}
|
||
public function segments()
|
||
{
|
||
$path = $this->path();
|
||
return $path == '/' ? array() : explode('/', $path);
|
||
}
|
||
public function is($pattern)
|
||
{
|
||
foreach (func_get_args() as $pattern) {
|
||
if (str_is($pattern, $this->path())) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
public function ajax()
|
||
{
|
||
return $this->isXmlHttpRequest();
|
||
}
|
||
public function secure()
|
||
{
|
||
return $this->isSecure();
|
||
}
|
||
public function has($key)
|
||
{
|
||
if (count(func_get_args()) > 1) {
|
||
foreach (func_get_args() as $value) {
|
||
if (!$this->has($value)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
if (is_array($this->input($key))) {
|
||
return true;
|
||
}
|
||
return trim((string) $this->input($key)) !== '';
|
||
}
|
||
public function all()
|
||
{
|
||
return $this->input() + $this->files->all();
|
||
}
|
||
public function input($key = null, $default = null)
|
||
{
|
||
$input = $this->getInputSource()->all() + $this->query->all();
|
||
return array_get($input, $key, $default);
|
||
}
|
||
public function only($keys)
|
||
{
|
||
$keys = is_array($keys) ? $keys : func_get_args();
|
||
return array_only($this->input(), $keys) + array_fill_keys($keys, null);
|
||
}
|
||
public function except($keys)
|
||
{
|
||
$keys = is_array($keys) ? $keys : func_get_args();
|
||
$results = $this->input();
|
||
foreach ($keys as $key) {
|
||
array_forget($results, $key);
|
||
}
|
||
return $results;
|
||
}
|
||
public function query($key = null, $default = null)
|
||
{
|
||
return $this->retrieveItem('query', $key, $default);
|
||
}
|
||
public function cookie($key = null, $default = null)
|
||
{
|
||
return $this->retrieveItem('cookies', $key, $default);
|
||
}
|
||
public function file($key = null, $default = null)
|
||
{
|
||
return $this->retrieveItem('files', $key, $default);
|
||
}
|
||
public function hasFile($key)
|
||
{
|
||
return $this->files->has($key) and !is_null($this->file($key));
|
||
}
|
||
public function header($key = null, $default = null)
|
||
{
|
||
return $this->retrieveItem('headers', $key, $default);
|
||
}
|
||
public function server($key = null, $default = null)
|
||
{
|
||
return $this->retrieveItem('server', $key, $default);
|
||
}
|
||
public function old($key = null, $default = null)
|
||
{
|
||
return $this->getSessionStore()->getOldInput($key, $default);
|
||
}
|
||
public function flash($filter = null, $keys = array())
|
||
{
|
||
$flash = !is_null($filter) ? $this->{$filter}($keys) : $this->input();
|
||
$this->getSessionStore()->flashInput($flash);
|
||
}
|
||
public function flashOnly($keys)
|
||
{
|
||
$keys = is_array($keys) ? $keys : func_get_args();
|
||
return $this->flash('only', $keys);
|
||
}
|
||
public function flashExcept($keys)
|
||
{
|
||
$keys = is_array($keys) ? $keys : func_get_args();
|
||
return $this->flash('except', $keys);
|
||
}
|
||
public function flush()
|
||
{
|
||
$this->getSessionStore()->flashInput(array());
|
||
}
|
||
protected function retrieveItem($source, $key, $default)
|
||
{
|
||
if (is_null($key)) {
|
||
return $this->{$source}->all();
|
||
} else {
|
||
return $this->{$source}->get($key, $default, true);
|
||
}
|
||
}
|
||
public function merge(array $input)
|
||
{
|
||
$this->getInputSource()->add($input);
|
||
}
|
||
public function replace(array $input)
|
||
{
|
||
$this->getInputSource()->replace($input);
|
||
}
|
||
public function json($key = null, $default = null)
|
||
{
|
||
if (!isset($this->json)) {
|
||
$this->json = new ParameterBag((array) json_decode($this->getContent(), true));
|
||
}
|
||
if (is_null($key)) {
|
||
return $this->json;
|
||
}
|
||
return array_get($this->json->all(), $key, $default);
|
||
}
|
||
protected function getInputSource()
|
||
{
|
||
if ($this->isJson()) {
|
||
return $this->json();
|
||
}
|
||
return $this->getMethod() == 'GET' ? $this->query : $this->request;
|
||
}
|
||
public function isJson()
|
||
{
|
||
return str_contains($this->header('CONTENT_TYPE'), '/json');
|
||
}
|
||
public function wantsJson()
|
||
{
|
||
$acceptable = $this->getAcceptableContentTypes();
|
||
return isset($acceptable[0]) and $acceptable[0] == 'application/json';
|
||
}
|
||
public function getSessionStore()
|
||
{
|
||
if (!isset($this->sessionStore)) {
|
||
throw new \RuntimeException('Session store not set on request.');
|
||
}
|
||
return $this->sessionStore;
|
||
}
|
||
public function setSessionStore(SessionStore $session)
|
||
{
|
||
$this->sessionStore = $session;
|
||
}
|
||
public function hasSessionStore()
|
||
{
|
||
return isset($this->sessionStore);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||
class Request
|
||
{
|
||
const HEADER_CLIENT_IP = 'client_ip';
|
||
const HEADER_CLIENT_HOST = 'client_host';
|
||
const HEADER_CLIENT_PROTO = 'client_proto';
|
||
const HEADER_CLIENT_PORT = 'client_port';
|
||
protected static $trustedProxies = array();
|
||
protected static $trustedHeaders = array(self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR', self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST', self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO', self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT');
|
||
protected static $httpMethodParameterOverride = false;
|
||
public $attributes;
|
||
public $request;
|
||
public $query;
|
||
public $server;
|
||
public $files;
|
||
public $cookies;
|
||
public $headers;
|
||
protected $content;
|
||
protected $languages;
|
||
protected $charsets;
|
||
protected $acceptableContentTypes;
|
||
protected $pathInfo;
|
||
protected $requestUri;
|
||
protected $baseUrl;
|
||
protected $basePath;
|
||
protected $method;
|
||
protected $format;
|
||
protected $session;
|
||
protected $locale;
|
||
protected $defaultLocale = 'en';
|
||
protected static $formats;
|
||
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
|
||
{
|
||
$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
|
||
}
|
||
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
|
||
{
|
||
$this->request = new ParameterBag($request);
|
||
$this->query = new ParameterBag($query);
|
||
$this->attributes = new ParameterBag($attributes);
|
||
$this->cookies = new ParameterBag($cookies);
|
||
$this->files = new FileBag($files);
|
||
$this->server = new ServerBag($server);
|
||
$this->headers = new HeaderBag($this->server->getHeaders());
|
||
$this->content = $content;
|
||
$this->languages = null;
|
||
$this->charsets = null;
|
||
$this->acceptableContentTypes = null;
|
||
$this->pathInfo = null;
|
||
$this->requestUri = null;
|
||
$this->baseUrl = null;
|
||
$this->basePath = null;
|
||
$this->method = null;
|
||
$this->format = null;
|
||
}
|
||
public static function createFromGlobals()
|
||
{
|
||
$request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
|
||
if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))) {
|
||
parse_str($request->getContent(), $data);
|
||
$request->request = new ParameterBag($data);
|
||
}
|
||
return $request;
|
||
}
|
||
public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
|
||
{
|
||
$server = array_replace(array('SERVER_NAME' => 'localhost', 'SERVER_PORT' => 80, 'HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Symfony/2.X', 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5', 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'REMOTE_ADDR' => '127.0.0.1', 'SCRIPT_NAME' => '', 'SCRIPT_FILENAME' => '', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'REQUEST_TIME' => time()), $server);
|
||
$server['PATH_INFO'] = '';
|
||
$server['REQUEST_METHOD'] = strtoupper($method);
|
||
$components = parse_url($uri);
|
||
if (isset($components['host'])) {
|
||
$server['SERVER_NAME'] = $components['host'];
|
||
$server['HTTP_HOST'] = $components['host'];
|
||
}
|
||
if (isset($components['scheme'])) {
|
||
if ('https' === $components['scheme']) {
|
||
$server['HTTPS'] = 'on';
|
||
$server['SERVER_PORT'] = 443;
|
||
} else {
|
||
unset($server['HTTPS']);
|
||
$server['SERVER_PORT'] = 80;
|
||
}
|
||
}
|
||
if (isset($components['port'])) {
|
||
$server['SERVER_PORT'] = $components['port'];
|
||
$server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $components['port'];
|
||
}
|
||
if (isset($components['user'])) {
|
||
$server['PHP_AUTH_USER'] = $components['user'];
|
||
}
|
||
if (isset($components['pass'])) {
|
||
$server['PHP_AUTH_PW'] = $components['pass'];
|
||
}
|
||
if (!isset($components['path'])) {
|
||
$components['path'] = '/';
|
||
}
|
||
switch (strtoupper($method)) {
|
||
case 'POST':
|
||
case 'PUT':
|
||
case 'DELETE':
|
||
if (!isset($server['CONTENT_TYPE'])) {
|
||
$server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
|
||
}
|
||
case 'PATCH':
|
||
$request = $parameters;
|
||
$query = array();
|
||
break;
|
||
default:
|
||
$request = array();
|
||
$query = $parameters;
|
||
break;
|
||
}
|
||
if (isset($components['query'])) {
|
||
parse_str(html_entity_decode($components['query']), $qs);
|
||
$query = array_replace($qs, $query);
|
||
}
|
||
$queryString = http_build_query($query, '', '&');
|
||
$server['REQUEST_URI'] = $components['path'] . ('' !== $queryString ? '?' . $queryString : '');
|
||
$server['QUERY_STRING'] = $queryString;
|
||
return new static($query, $request, array(), $cookies, $files, $server, $content);
|
||
}
|
||
public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
|
||
{
|
||
$dup = clone $this;
|
||
if ($query !== null) {
|
||
$dup->query = new ParameterBag($query);
|
||
}
|
||
if ($request !== null) {
|
||
$dup->request = new ParameterBag($request);
|
||
}
|
||
if ($attributes !== null) {
|
||
$dup->attributes = new ParameterBag($attributes);
|
||
}
|
||
if ($cookies !== null) {
|
||
$dup->cookies = new ParameterBag($cookies);
|
||
}
|
||
if ($files !== null) {
|
||
$dup->files = new FileBag($files);
|
||
}
|
||
if ($server !== null) {
|
||
$dup->server = new ServerBag($server);
|
||
$dup->headers = new HeaderBag($dup->server->getHeaders());
|
||
}
|
||
$dup->languages = null;
|
||
$dup->charsets = null;
|
||
$dup->acceptableContentTypes = null;
|
||
$dup->pathInfo = null;
|
||
$dup->requestUri = null;
|
||
$dup->baseUrl = null;
|
||
$dup->basePath = null;
|
||
$dup->method = null;
|
||
$dup->format = null;
|
||
return $dup;
|
||
}
|
||
public function __clone()
|
||
{
|
||
$this->query = clone $this->query;
|
||
$this->request = clone $this->request;
|
||
$this->attributes = clone $this->attributes;
|
||
$this->cookies = clone $this->cookies;
|
||
$this->files = clone $this->files;
|
||
$this->server = clone $this->server;
|
||
$this->headers = clone $this->headers;
|
||
}
|
||
public function __toString()
|
||
{
|
||
return sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL')) . '
|
||
' . $this->headers . '
|
||
' . $this->getContent();
|
||
}
|
||
public function overrideGlobals()
|
||
{
|
||
$_GET = $this->query->all();
|
||
$_POST = $this->request->all();
|
||
$_SERVER = $this->server->all();
|
||
$_COOKIE = $this->cookies->all();
|
||
foreach ($this->headers->all() as $key => $value) {
|
||
$key = strtoupper(str_replace('-', '_', $key));
|
||
if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
|
||
$_SERVER[$key] = implode(', ', $value);
|
||
} else {
|
||
$_SERVER['HTTP_' . $key] = implode(', ', $value);
|
||
}
|
||
}
|
||
$request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE);
|
||
$requestOrder = ini_get('request_order') ?: ini_get('variable_order');
|
||
$requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
|
||
$_REQUEST = array();
|
||
foreach (str_split($requestOrder) as $order) {
|
||
$_REQUEST = array_merge($_REQUEST, $request[$order]);
|
||
}
|
||
}
|
||
public static function setTrustedProxies(array $proxies)
|
||
{
|
||
self::$trustedProxies = $proxies;
|
||
}
|
||
public static function getTrustedProxies()
|
||
{
|
||
return self::$trustedProxies;
|
||
}
|
||
public static function setTrustedHeaderName($key, $value)
|
||
{
|
||
if (!array_key_exists($key, self::$trustedHeaders)) {
|
||
throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
|
||
}
|
||
self::$trustedHeaders[$key] = $value;
|
||
}
|
||
public static function getTrustedHeaderName($key)
|
||
{
|
||
if (!array_key_exists($key, self::$trustedHeaders)) {
|
||
throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key));
|
||
}
|
||
return self::$trustedHeaders[$key];
|
||
}
|
||
public static function normalizeQueryString($qs)
|
||
{
|
||
if ('' == $qs) {
|
||
return '';
|
||
}
|
||
$parts = array();
|
||
$order = array();
|
||
foreach (explode('&', $qs) as $param) {
|
||
if ('' === $param || '=' === $param[0]) {
|
||
continue;
|
||
}
|
||
$keyValuePair = explode('=', $param, 2);
|
||
$parts[] = isset($keyValuePair[1]) ? rawurlencode(urldecode($keyValuePair[0])) . '=' . rawurlencode(urldecode($keyValuePair[1])) : rawurlencode(urldecode($keyValuePair[0]));
|
||
$order[] = urldecode($keyValuePair[0]);
|
||
}
|
||
array_multisort($order, SORT_ASC, $parts);
|
||
return implode('&', $parts);
|
||
}
|
||
public static function enableHttpMethodParameterOverride()
|
||
{
|
||
self::$httpMethodParameterOverride = true;
|
||
}
|
||
public static function getHttpMethodParameterOverride()
|
||
{
|
||
return self::$httpMethodParameterOverride;
|
||
}
|
||
public function get($key, $default = null, $deep = false)
|
||
{
|
||
return $this->query->get($key, $this->attributes->get($key, $this->request->get($key, $default, $deep), $deep), $deep);
|
||
}
|
||
public function getSession()
|
||
{
|
||
return $this->session;
|
||
}
|
||
public function hasPreviousSession()
|
||
{
|
||
return $this->hasSession() && $this->cookies->has($this->session->getName());
|
||
}
|
||
public function hasSession()
|
||
{
|
||
return null !== $this->session;
|
||
}
|
||
public function setSession(SessionInterface $session)
|
||
{
|
||
$this->session = $session;
|
||
}
|
||
public function getClientIps()
|
||
{
|
||
$ip = $this->server->get('REMOTE_ADDR');
|
||
if (!self::$trustedProxies) {
|
||
return array($ip);
|
||
}
|
||
if (!self::$trustedHeaders[self::HEADER_CLIENT_IP] || !$this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
|
||
return array($ip);
|
||
}
|
||
$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
|
||
$clientIps[] = $ip;
|
||
$trustedProxies = !self::$trustedProxies ? array($ip) : self::$trustedProxies;
|
||
$ip = $clientIps[0];
|
||
foreach ($clientIps as $key => $clientIp) {
|
||
if (IpUtils::checkIp($clientIp, $trustedProxies)) {
|
||
unset($clientIps[$key]);
|
||
continue;
|
||
}
|
||
}
|
||
return $clientIps ? array_reverse($clientIps) : array($ip);
|
||
}
|
||
public function getClientIp()
|
||
{
|
||
$ipAddresses = $this->getClientIps();
|
||
return $ipAddresses[0];
|
||
}
|
||
public function getScriptName()
|
||
{
|
||
return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
|
||
}
|
||
public function getPathInfo()
|
||
{
|
||
if (null === $this->pathInfo) {
|
||
$this->pathInfo = $this->preparePathInfo();
|
||
}
|
||
return $this->pathInfo;
|
||
}
|
||
public function getBasePath()
|
||
{
|
||
if (null === $this->basePath) {
|
||
$this->basePath = $this->prepareBasePath();
|
||
}
|
||
return $this->basePath;
|
||
}
|
||
public function getBaseUrl()
|
||
{
|
||
if (null === $this->baseUrl) {
|
||
$this->baseUrl = $this->prepareBaseUrl();
|
||
}
|
||
return $this->baseUrl;
|
||
}
|
||
public function getScheme()
|
||
{
|
||
return $this->isSecure() ? 'https' : 'http';
|
||
}
|
||
public function getPort()
|
||
{
|
||
if (self::$trustedProxies) {
|
||
if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && ($port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT]))) {
|
||
return $port;
|
||
}
|
||
if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && 'https' === $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO], 'http')) {
|
||
return 443;
|
||
}
|
||
}
|
||
return $this->server->get('SERVER_PORT');
|
||
}
|
||
public function getUser()
|
||
{
|
||
return $this->server->get('PHP_AUTH_USER');
|
||
}
|
||
public function getPassword()
|
||
{
|
||
return $this->server->get('PHP_AUTH_PW');
|
||
}
|
||
public function getUserInfo()
|
||
{
|
||
$userinfo = $this->getUser();
|
||
$pass = $this->getPassword();
|
||
if ('' != $pass) {
|
||
$userinfo .= ":{$pass}";
|
||
}
|
||
return $userinfo;
|
||
}
|
||
public function getHttpHost()
|
||
{
|
||
$scheme = $this->getScheme();
|
||
$port = $this->getPort();
|
||
if ('http' == $scheme && $port == 80 || 'https' == $scheme && $port == 443) {
|
||
return $this->getHost();
|
||
}
|
||
return $this->getHost() . ':' . $port;
|
||
}
|
||
public function getRequestUri()
|
||
{
|
||
if (null === $this->requestUri) {
|
||
$this->requestUri = $this->prepareRequestUri();
|
||
}
|
||
return $this->requestUri;
|
||
}
|
||
public function getSchemeAndHttpHost()
|
||
{
|
||
return $this->getScheme() . '://' . $this->getHttpHost();
|
||
}
|
||
public function getUri()
|
||
{
|
||
if (null !== ($qs = $this->getQueryString())) {
|
||
$qs = '?' . $qs;
|
||
}
|
||
return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $this->getPathInfo() . $qs;
|
||
}
|
||
public function getUriForPath($path)
|
||
{
|
||
return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $path;
|
||
}
|
||
public function getQueryString()
|
||
{
|
||
$qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
|
||
return '' === $qs ? null : $qs;
|
||
}
|
||
public function isSecure()
|
||
{
|
||
if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && ($proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO]))) {
|
||
return in_array(strtolower($proto), array('https', 'on', '1'));
|
||
}
|
||
return 'on' == strtolower($this->server->get('HTTPS')) || 1 == $this->server->get('HTTPS');
|
||
}
|
||
public function getHost()
|
||
{
|
||
if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && ($host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST]))) {
|
||
$elements = explode(',', $host);
|
||
$host = $elements[count($elements) - 1];
|
||
} elseif (!($host = $this->headers->get('HOST'))) {
|
||
if (!($host = $this->server->get('SERVER_NAME'))) {
|
||
$host = $this->server->get('SERVER_ADDR', '');
|
||
}
|
||
}
|
||
$host = strtolower(preg_replace('/:\\d+$/', '', trim($host)));
|
||
if ($host && !preg_match('/^\\[?(?:[a-zA-Z0-9-:\\]_]+\\.?)+$/', $host)) {
|
||
throw new \UnexpectedValueException('Invalid Host');
|
||
}
|
||
return $host;
|
||
}
|
||
public function setMethod($method)
|
||
{
|
||
$this->method = null;
|
||
$this->server->set('REQUEST_METHOD', $method);
|
||
}
|
||
public function getMethod()
|
||
{
|
||
if (null === $this->method) {
|
||
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
|
||
if ('POST' === $this->method) {
|
||
if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
|
||
$this->method = strtoupper($method);
|
||
} elseif (self::$httpMethodParameterOverride) {
|
||
$this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
|
||
}
|
||
}
|
||
}
|
||
return $this->method;
|
||
}
|
||
public function getRealMethod()
|
||
{
|
||
return strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
|
||
}
|
||
public function getMimeType($format)
|
||
{
|
||
if (null === static::$formats) {
|
||
static::initializeFormats();
|
||
}
|
||
return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
|
||
}
|
||
public function getFormat($mimeType)
|
||
{
|
||
if (false !== ($pos = strpos($mimeType, ';'))) {
|
||
$mimeType = substr($mimeType, 0, $pos);
|
||
}
|
||
if (null === static::$formats) {
|
||
static::initializeFormats();
|
||
}
|
||
foreach (static::$formats as $format => $mimeTypes) {
|
||
if (in_array($mimeType, (array) $mimeTypes)) {
|
||
return $format;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
public function setFormat($format, $mimeTypes)
|
||
{
|
||
if (null === static::$formats) {
|
||
static::initializeFormats();
|
||
}
|
||
static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
|
||
}
|
||
public function getRequestFormat($default = 'html')
|
||
{
|
||
if (null === $this->format) {
|
||
$this->format = $this->get('_format', $default);
|
||
}
|
||
return $this->format;
|
||
}
|
||
public function setRequestFormat($format)
|
||
{
|
||
$this->format = $format;
|
||
}
|
||
public function getContentType()
|
||
{
|
||
return $this->getFormat($this->headers->get('CONTENT_TYPE'));
|
||
}
|
||
public function setDefaultLocale($locale)
|
||
{
|
||
$this->defaultLocale = $locale;
|
||
if (null === $this->locale) {
|
||
$this->setPhpDefaultLocale($locale);
|
||
}
|
||
}
|
||
public function setLocale($locale)
|
||
{
|
||
$this->setPhpDefaultLocale($this->locale = $locale);
|
||
}
|
||
public function getLocale()
|
||
{
|
||
return null === $this->locale ? $this->defaultLocale : $this->locale;
|
||
}
|
||
public function isMethod($method)
|
||
{
|
||
return $this->getMethod() === strtoupper($method);
|
||
}
|
||
public function isMethodSafe()
|
||
{
|
||
return in_array($this->getMethod(), array('GET', 'HEAD'));
|
||
}
|
||
public function getContent($asResource = false)
|
||
{
|
||
if (false === $this->content || true === $asResource && null !== $this->content) {
|
||
throw new \LogicException('getContent() can only be called once when using the resource return type.');
|
||
}
|
||
if (true === $asResource) {
|
||
$this->content = false;
|
||
return fopen('php://input', 'rb');
|
||
}
|
||
if (null === $this->content) {
|
||
$this->content = file_get_contents('php://input');
|
||
}
|
||
return $this->content;
|
||
}
|
||
public function getETags()
|
||
{
|
||
return preg_split('/\\s*,\\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
|
||
}
|
||
public function isNoCache()
|
||
{
|
||
return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
|
||
}
|
||
public function getPreferredLanguage(array $locales = null)
|
||
{
|
||
$preferredLanguages = $this->getLanguages();
|
||
if (empty($locales)) {
|
||
return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null;
|
||
}
|
||
if (!$preferredLanguages) {
|
||
return $locales[0];
|
||
}
|
||
$extendedPreferredLanguages = array();
|
||
foreach ($preferredLanguages as $language) {
|
||
$extendedPreferredLanguages[] = $language;
|
||
if (false !== ($position = strpos($language, '_'))) {
|
||
$superLanguage = substr($language, 0, $position);
|
||
if (!in_array($superLanguage, $preferredLanguages)) {
|
||
$extendedPreferredLanguages[] = $superLanguage;
|
||
}
|
||
}
|
||
}
|
||
$preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
|
||
return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
|
||
}
|
||
public function getLanguages()
|
||
{
|
||
if (null !== $this->languages) {
|
||
return $this->languages;
|
||
}
|
||
$languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
|
||
$this->languages = array();
|
||
foreach (array_keys($languages) as $lang) {
|
||
if (strstr($lang, '-')) {
|
||
$codes = explode('-', $lang);
|
||
if ($codes[0] == 'i') {
|
||
if (count($codes) > 1) {
|
||
$lang = $codes[1];
|
||
}
|
||
} else {
|
||
for ($i = 0, $max = count($codes); $i < $max; $i++) {
|
||
if ($i == 0) {
|
||
$lang = strtolower($codes[0]);
|
||
} else {
|
||
$lang .= '_' . strtoupper($codes[$i]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$this->languages[] = $lang;
|
||
}
|
||
return $this->languages;
|
||
}
|
||
public function getCharsets()
|
||
{
|
||
if (null !== $this->charsets) {
|
||
return $this->charsets;
|
||
}
|
||
return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
|
||
}
|
||
public function getAcceptableContentTypes()
|
||
{
|
||
if (null !== $this->acceptableContentTypes) {
|
||
return $this->acceptableContentTypes;
|
||
}
|
||
return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
|
||
}
|
||
public function isXmlHttpRequest()
|
||
{
|
||
return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
|
||
}
|
||
protected function prepareRequestUri()
|
||
{
|
||
$requestUri = '';
|
||
if ($this->headers->has('X_ORIGINAL_URL')) {
|
||
$requestUri = $this->headers->get('X_ORIGINAL_URL');
|
||
$this->headers->remove('X_ORIGINAL_URL');
|
||
$this->server->remove('HTTP_X_ORIGINAL_URL');
|
||
$this->server->remove('UNENCODED_URL');
|
||
$this->server->remove('IIS_WasUrlRewritten');
|
||
} elseif ($this->headers->has('X_REWRITE_URL')) {
|
||
$requestUri = $this->headers->get('X_REWRITE_URL');
|
||
$this->headers->remove('X_REWRITE_URL');
|
||
} elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
|
||
$requestUri = $this->server->get('UNENCODED_URL');
|
||
$this->server->remove('UNENCODED_URL');
|
||
$this->server->remove('IIS_WasUrlRewritten');
|
||
} elseif ($this->server->has('REQUEST_URI')) {
|
||
$requestUri = $this->server->get('REQUEST_URI');
|
||
$schemeAndHttpHost = $this->getSchemeAndHttpHost();
|
||
if (strpos($requestUri, $schemeAndHttpHost) === 0) {
|
||
$requestUri = substr($requestUri, strlen($schemeAndHttpHost));
|
||
}
|
||
} elseif ($this->server->has('ORIG_PATH_INFO')) {
|
||
$requestUri = $this->server->get('ORIG_PATH_INFO');
|
||
if ('' != $this->server->get('QUERY_STRING')) {
|
||
$requestUri .= '?' . $this->server->get('QUERY_STRING');
|
||
}
|
||
$this->server->remove('ORIG_PATH_INFO');
|
||
}
|
||
$this->server->set('REQUEST_URI', $requestUri);
|
||
return $requestUri;
|
||
}
|
||
protected function prepareBaseUrl()
|
||
{
|
||
$filename = basename($this->server->get('SCRIPT_FILENAME'));
|
||
if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
|
||
$baseUrl = $this->server->get('SCRIPT_NAME');
|
||
} elseif (basename($this->server->get('PHP_SELF')) === $filename) {
|
||
$baseUrl = $this->server->get('PHP_SELF');
|
||
} elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
|
||
$baseUrl = $this->server->get('ORIG_SCRIPT_NAME');
|
||
} else {
|
||
$path = $this->server->get('PHP_SELF', '');
|
||
$file = $this->server->get('SCRIPT_FILENAME', '');
|
||
$segs = explode('/', trim($file, '/'));
|
||
$segs = array_reverse($segs);
|
||
$index = 0;
|
||
$last = count($segs);
|
||
$baseUrl = '';
|
||
do {
|
||
$seg = $segs[$index];
|
||
$baseUrl = '/' . $seg . $baseUrl;
|
||
++$index;
|
||
} while ($last > $index && false !== ($pos = strpos($path, $baseUrl)) && 0 != $pos);
|
||
}
|
||
$requestUri = $this->getRequestUri();
|
||
if ($baseUrl && false !== ($prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl))) {
|
||
return $prefix;
|
||
}
|
||
if ($baseUrl && false !== ($prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl)))) {
|
||
return rtrim($prefix, '/');
|
||
}
|
||
$truncatedRequestUri = $requestUri;
|
||
if (($pos = strpos($requestUri, '?')) !== false) {
|
||
$truncatedRequestUri = substr($requestUri, 0, $pos);
|
||
}
|
||
$basename = basename($baseUrl);
|
||
if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
|
||
return '';
|
||
}
|
||
if (strlen($requestUri) >= strlen($baseUrl) && (false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0)) {
|
||
$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
|
||
}
|
||
return rtrim($baseUrl, '/');
|
||
}
|
||
protected function prepareBasePath()
|
||
{
|
||
$filename = basename($this->server->get('SCRIPT_FILENAME'));
|
||
$baseUrl = $this->getBaseUrl();
|
||
if (empty($baseUrl)) {
|
||
return '';
|
||
}
|
||
if (basename($baseUrl) === $filename) {
|
||
$basePath = dirname($baseUrl);
|
||
} else {
|
||
$basePath = $baseUrl;
|
||
}
|
||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||
$basePath = str_replace('\\', '/', $basePath);
|
||
}
|
||
return rtrim($basePath, '/');
|
||
}
|
||
protected function preparePathInfo()
|
||
{
|
||
$baseUrl = $this->getBaseUrl();
|
||
if (null === ($requestUri = $this->getRequestUri())) {
|
||
return '/';
|
||
}
|
||
$pathInfo = '/';
|
||
if ($pos = strpos($requestUri, '?')) {
|
||
$requestUri = substr($requestUri, 0, $pos);
|
||
}
|
||
if (null !== $baseUrl && false === ($pathInfo = substr($requestUri, strlen($baseUrl)))) {
|
||
return '/';
|
||
} elseif (null === $baseUrl) {
|
||
return $requestUri;
|
||
}
|
||
return (string) $pathInfo;
|
||
}
|
||
protected static function initializeFormats()
|
||
{
|
||
static::$formats = array('html' => array('text/html', 'application/xhtml+xml'), 'txt' => array('text/plain'), 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'), 'css' => array('text/css'), 'json' => array('application/json', 'application/x-json'), 'xml' => array('text/xml', 'application/xml', 'application/x-xml'), 'rdf' => array('application/rdf+xml'), 'atom' => array('application/atom+xml'), 'rss' => array('application/rss+xml'));
|
||
}
|
||
private function setPhpDefaultLocale($locale)
|
||
{
|
||
try {
|
||
if (class_exists('Locale', false)) {
|
||
\Locale::setDefault($locale);
|
||
}
|
||
} catch (\Exception $e) {
|
||
|
||
}
|
||
}
|
||
private function getUrlencodedPrefix($string, $prefix)
|
||
{
|
||
if (0 !== strpos(rawurldecode($string), $prefix)) {
|
||
return false;
|
||
}
|
||
$len = strlen($prefix);
|
||
if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
|
||
return $match[0];
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class ParameterBag implements \IteratorAggregate, \Countable
|
||
{
|
||
protected $parameters;
|
||
public function __construct(array $parameters = array())
|
||
{
|
||
$this->parameters = $parameters;
|
||
}
|
||
public function all()
|
||
{
|
||
return $this->parameters;
|
||
}
|
||
public function keys()
|
||
{
|
||
return array_keys($this->parameters);
|
||
}
|
||
public function replace(array $parameters = array())
|
||
{
|
||
$this->parameters = $parameters;
|
||
}
|
||
public function add(array $parameters = array())
|
||
{
|
||
$this->parameters = array_replace($this->parameters, $parameters);
|
||
}
|
||
public function get($path, $default = null, $deep = false)
|
||
{
|
||
if (!$deep || false === ($pos = strpos($path, '['))) {
|
||
return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default;
|
||
}
|
||
$root = substr($path, 0, $pos);
|
||
if (!array_key_exists($root, $this->parameters)) {
|
||
return $default;
|
||
}
|
||
$value = $this->parameters[$root];
|
||
$currentKey = null;
|
||
for ($i = $pos, $c = strlen($path); $i < $c; $i++) {
|
||
$char = $path[$i];
|
||
if ('[' === $char) {
|
||
if (null !== $currentKey) {
|
||
throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i));
|
||
}
|
||
$currentKey = '';
|
||
} elseif (']' === $char) {
|
||
if (null === $currentKey) {
|
||
throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i));
|
||
}
|
||
if (!is_array($value) || !array_key_exists($currentKey, $value)) {
|
||
return $default;
|
||
}
|
||
$value = $value[$currentKey];
|
||
$currentKey = null;
|
||
} else {
|
||
if (null === $currentKey) {
|
||
throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i));
|
||
}
|
||
$currentKey .= $char;
|
||
}
|
||
}
|
||
if (null !== $currentKey) {
|
||
throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".'));
|
||
}
|
||
return $value;
|
||
}
|
||
public function set($key, $value)
|
||
{
|
||
$this->parameters[$key] = $value;
|
||
}
|
||
public function has($key)
|
||
{
|
||
return array_key_exists($key, $this->parameters);
|
||
}
|
||
public function remove($key)
|
||
{
|
||
unset($this->parameters[$key]);
|
||
}
|
||
public function getAlpha($key, $default = '', $deep = false)
|
||
{
|
||
return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep));
|
||
}
|
||
public function getAlnum($key, $default = '', $deep = false)
|
||
{
|
||
return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep));
|
||
}
|
||
public function getDigits($key, $default = '', $deep = false)
|
||
{
|
||
return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT));
|
||
}
|
||
public function getInt($key, $default = 0, $deep = false)
|
||
{
|
||
return (int) $this->get($key, $default, $deep);
|
||
}
|
||
public function filter($key, $default = null, $deep = false, $filter = FILTER_DEFAULT, $options = array())
|
||
{
|
||
$value = $this->get($key, $default, $deep);
|
||
if (!is_array($options) && $options) {
|
||
$options = array('flags' => $options);
|
||
}
|
||
if (is_array($value) && !isset($options['flags'])) {
|
||
$options['flags'] = FILTER_REQUIRE_ARRAY;
|
||
}
|
||
return filter_var($value, $filter, $options);
|
||
}
|
||
public function getIterator()
|
||
{
|
||
return new \ArrayIterator($this->parameters);
|
||
}
|
||
public function count()
|
||
{
|
||
return count($this->parameters);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||
class FileBag extends ParameterBag
|
||
{
|
||
private static $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
|
||
public function __construct(array $parameters = array())
|
||
{
|
||
$this->replace($parameters);
|
||
}
|
||
public function replace(array $files = array())
|
||
{
|
||
$this->parameters = array();
|
||
$this->add($files);
|
||
}
|
||
public function set($key, $value)
|
||
{
|
||
if (!is_array($value) && !$value instanceof UploadedFile) {
|
||
throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
|
||
}
|
||
parent::set($key, $this->convertFileInformation($value));
|
||
}
|
||
public function add(array $files = array())
|
||
{
|
||
foreach ($files as $key => $file) {
|
||
$this->set($key, $file);
|
||
}
|
||
}
|
||
protected function convertFileInformation($file)
|
||
{
|
||
if ($file instanceof UploadedFile) {
|
||
return $file;
|
||
}
|
||
$file = $this->fixPhpFilesArray($file);
|
||
if (is_array($file)) {
|
||
$keys = array_keys($file);
|
||
sort($keys);
|
||
if ($keys == self::$fileKeys) {
|
||
if (UPLOAD_ERR_NO_FILE == $file['error']) {
|
||
$file = null;
|
||
} else {
|
||
$file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
|
||
}
|
||
} else {
|
||
$file = array_map(array($this, 'convertFileInformation'), $file);
|
||
}
|
||
}
|
||
return $file;
|
||
}
|
||
protected function fixPhpFilesArray($data)
|
||
{
|
||
if (!is_array($data)) {
|
||
return $data;
|
||
}
|
||
$keys = array_keys($data);
|
||
sort($keys);
|
||
if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
|
||
return $data;
|
||
}
|
||
$files = $data;
|
||
foreach (self::$fileKeys as $k) {
|
||
unset($files[$k]);
|
||
}
|
||
foreach (array_keys($data['name']) as $key) {
|
||
$files[$key] = $this->fixPhpFilesArray(array('error' => $data['error'][$key], 'name' => $data['name'][$key], 'type' => $data['type'][$key], 'tmp_name' => $data['tmp_name'][$key], 'size' => $data['size'][$key]));
|
||
}
|
||
return $files;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class ServerBag extends ParameterBag
|
||
{
|
||
public function getHeaders()
|
||
{
|
||
$headers = array();
|
||
$contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
|
||
foreach ($this->parameters as $key => $value) {
|
||
if (0 === strpos($key, 'HTTP_')) {
|
||
$headers[substr($key, 5)] = $value;
|
||
} elseif (isset($contentHeaders[$key])) {
|
||
$headers[$key] = $value;
|
||
}
|
||
}
|
||
if (isset($this->parameters['PHP_AUTH_USER'])) {
|
||
$headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER'];
|
||
$headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
|
||
} else {
|
||
$authorizationHeader = null;
|
||
if (isset($this->parameters['HTTP_AUTHORIZATION'])) {
|
||
$authorizationHeader = $this->parameters['HTTP_AUTHORIZATION'];
|
||
} elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||
$authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION'];
|
||
}
|
||
if (null !== $authorizationHeader && 0 === stripos($authorizationHeader, 'basic')) {
|
||
$exploded = explode(':', base64_decode(substr($authorizationHeader, 6)));
|
||
if (count($exploded) == 2) {
|
||
list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
|
||
}
|
||
}
|
||
}
|
||
if (isset($headers['PHP_AUTH_USER'])) {
|
||
$headers['AUTHORIZATION'] = 'Basic ' . base64_encode($headers['PHP_AUTH_USER'] . ':' . $headers['PHP_AUTH_PW']);
|
||
}
|
||
return $headers;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class HeaderBag implements \IteratorAggregate, \Countable
|
||
{
|
||
protected $headers;
|
||
protected $cacheControl;
|
||
public function __construct(array $headers = array())
|
||
{
|
||
$this->cacheControl = array();
|
||
$this->headers = array();
|
||
foreach ($headers as $key => $values) {
|
||
$this->set($key, $values);
|
||
}
|
||
}
|
||
public function __toString()
|
||
{
|
||
if (!$this->headers) {
|
||
return '';
|
||
}
|
||
$max = max(array_map('strlen', array_keys($this->headers))) + 1;
|
||
$content = '';
|
||
ksort($this->headers);
|
||
foreach ($this->headers as $name => $values) {
|
||
$name = implode('-', array_map('ucfirst', explode('-', $name)));
|
||
foreach ($values as $value) {
|
||
$content .= sprintf("%-{$max}s %s\r\n", $name . ':', $value);
|
||
}
|
||
}
|
||
return $content;
|
||
}
|
||
public function all()
|
||
{
|
||
return $this->headers;
|
||
}
|
||
public function keys()
|
||
{
|
||
return array_keys($this->headers);
|
||
}
|
||
public function replace(array $headers = array())
|
||
{
|
||
$this->headers = array();
|
||
$this->add($headers);
|
||
}
|
||
public function add(array $headers)
|
||
{
|
||
foreach ($headers as $key => $values) {
|
||
$this->set($key, $values);
|
||
}
|
||
}
|
||
public function get($key, $default = null, $first = true)
|
||
{
|
||
$key = strtr(strtolower($key), '_', '-');
|
||
if (!array_key_exists($key, $this->headers)) {
|
||
if (null === $default) {
|
||
return $first ? null : array();
|
||
}
|
||
return $first ? $default : array($default);
|
||
}
|
||
if ($first) {
|
||
return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
|
||
}
|
||
return $this->headers[$key];
|
||
}
|
||
public function set($key, $values, $replace = true)
|
||
{
|
||
$key = strtr(strtolower($key), '_', '-');
|
||
$values = array_values((array) $values);
|
||
if (true === $replace || !isset($this->headers[$key])) {
|
||
$this->headers[$key] = $values;
|
||
} else {
|
||
$this->headers[$key] = array_merge($this->headers[$key], $values);
|
||
}
|
||
if ('cache-control' === $key) {
|
||
$this->cacheControl = $this->parseCacheControl($values[0]);
|
||
}
|
||
}
|
||
public function has($key)
|
||
{
|
||
return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers);
|
||
}
|
||
public function contains($key, $value)
|
||
{
|
||
return in_array($value, $this->get($key, null, false));
|
||
}
|
||
public function remove($key)
|
||
{
|
||
$key = strtr(strtolower($key), '_', '-');
|
||
unset($this->headers[$key]);
|
||
if ('cache-control' === $key) {
|
||
$this->cacheControl = array();
|
||
}
|
||
}
|
||
public function getDate($key, \DateTime $default = null)
|
||
{
|
||
if (null === ($value = $this->get($key))) {
|
||
return $default;
|
||
}
|
||
if (false === ($date = \DateTime::createFromFormat(DATE_RFC2822, $value))) {
|
||
throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
|
||
}
|
||
return $date;
|
||
}
|
||
public function addCacheControlDirective($key, $value = true)
|
||
{
|
||
$this->cacheControl[$key] = $value;
|
||
$this->set('Cache-Control', $this->getCacheControlHeader());
|
||
}
|
||
public function hasCacheControlDirective($key)
|
||
{
|
||
return array_key_exists($key, $this->cacheControl);
|
||
}
|
||
public function getCacheControlDirective($key)
|
||
{
|
||
return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
|
||
}
|
||
public function removeCacheControlDirective($key)
|
||
{
|
||
unset($this->cacheControl[$key]);
|
||
$this->set('Cache-Control', $this->getCacheControlHeader());
|
||
}
|
||
public function getIterator()
|
||
{
|
||
return new \ArrayIterator($this->headers);
|
||
}
|
||
public function count()
|
||
{
|
||
return count($this->headers);
|
||
}
|
||
protected function getCacheControlHeader()
|
||
{
|
||
$parts = array();
|
||
ksort($this->cacheControl);
|
||
foreach ($this->cacheControl as $key => $value) {
|
||
if (true === $value) {
|
||
$parts[] = $key;
|
||
} else {
|
||
if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
|
||
$value = '"' . $value . '"';
|
||
}
|
||
$parts[] = "{$key}={$value}";
|
||
}
|
||
}
|
||
return implode(', ', $parts);
|
||
}
|
||
protected function parseCacheControl($header)
|
||
{
|
||
$cacheControl = array();
|
||
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\\s*(?:=(?:"([^"]*)"|([^ \\t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
|
||
foreach ($matches as $match) {
|
||
$cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
|
||
}
|
||
return $cacheControl;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||
interface SessionInterface
|
||
{
|
||
public function start();
|
||
public function getId();
|
||
public function setId($id);
|
||
public function getName();
|
||
public function setName($name);
|
||
public function invalidate($lifetime = null);
|
||
public function migrate($destroy = false, $lifetime = null);
|
||
public function save();
|
||
public function has($name);
|
||
public function get($name, $default = null);
|
||
public function set($name, $value);
|
||
public function all();
|
||
public function replace(array $attributes);
|
||
public function remove($name);
|
||
public function clear();
|
||
public function isStarted();
|
||
public function registerBag(SessionBagInterface $bag);
|
||
public function getBag($name);
|
||
public function getMetadataBag();
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||
interface SessionStorageInterface
|
||
{
|
||
public function start();
|
||
public function isStarted();
|
||
public function getId();
|
||
public function setId($id);
|
||
public function getName();
|
||
public function setName($name);
|
||
public function regenerate($destroy = false, $lifetime = null);
|
||
public function save();
|
||
public function clear();
|
||
public function getBag($name);
|
||
public function registerBag(SessionBagInterface $bag);
|
||
public function getMetadataBag();
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session;
|
||
|
||
interface SessionBagInterface
|
||
{
|
||
public function getName();
|
||
public function initialize(array &$array);
|
||
public function getStorageKey();
|
||
public function clear();
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Attribute;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||
interface AttributeBagInterface extends SessionBagInterface
|
||
{
|
||
public function has($name);
|
||
public function get($name, $default = null);
|
||
public function set($name, $value);
|
||
public function all();
|
||
public function replace(array $attributes);
|
||
public function remove($name);
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
|
||
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
||
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
|
||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
|
||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
|
||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
|
||
class Session implements SessionInterface, \IteratorAggregate, \Countable
|
||
{
|
||
protected $storage;
|
||
private $flashName;
|
||
private $attributeName;
|
||
public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
|
||
{
|
||
$this->storage = $storage ?: new NativeSessionStorage();
|
||
$attributes = $attributes ?: new AttributeBag();
|
||
$this->attributeName = $attributes->getName();
|
||
$this->registerBag($attributes);
|
||
$flashes = $flashes ?: new FlashBag();
|
||
$this->flashName = $flashes->getName();
|
||
$this->registerBag($flashes);
|
||
}
|
||
public function start()
|
||
{
|
||
return $this->storage->start();
|
||
}
|
||
public function has($name)
|
||
{
|
||
return $this->storage->getBag($this->attributeName)->has($name);
|
||
}
|
||
public function get($name, $default = null)
|
||
{
|
||
return $this->storage->getBag($this->attributeName)->get($name, $default);
|
||
}
|
||
public function set($name, $value)
|
||
{
|
||
$this->storage->getBag($this->attributeName)->set($name, $value);
|
||
}
|
||
public function all()
|
||
{
|
||
return $this->storage->getBag($this->attributeName)->all();
|
||
}
|
||
public function replace(array $attributes)
|
||
{
|
||
$this->storage->getBag($this->attributeName)->replace($attributes);
|
||
}
|
||
public function remove($name)
|
||
{
|
||
return $this->storage->getBag($this->attributeName)->remove($name);
|
||
}
|
||
public function clear()
|
||
{
|
||
$this->storage->getBag($this->attributeName)->clear();
|
||
}
|
||
public function isStarted()
|
||
{
|
||
return $this->storage->isStarted();
|
||
}
|
||
public function getIterator()
|
||
{
|
||
return new \ArrayIterator($this->storage->getBag($this->attributeName)->all());
|
||
}
|
||
public function count()
|
||
{
|
||
return count($this->storage->getBag($this->attributeName)->all());
|
||
}
|
||
public function invalidate($lifetime = null)
|
||
{
|
||
$this->storage->clear();
|
||
return $this->migrate(true, $lifetime);
|
||
}
|
||
public function migrate($destroy = false, $lifetime = null)
|
||
{
|
||
return $this->storage->regenerate($destroy, $lifetime);
|
||
}
|
||
public function save()
|
||
{
|
||
$this->storage->save();
|
||
}
|
||
public function getId()
|
||
{
|
||
return $this->storage->getId();
|
||
}
|
||
public function setId($id)
|
||
{
|
||
$this->storage->setId($id);
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->storage->getName();
|
||
}
|
||
public function setName($name)
|
||
{
|
||
$this->storage->setName($name);
|
||
}
|
||
public function getMetadataBag()
|
||
{
|
||
return $this->storage->getMetadataBag();
|
||
}
|
||
public function registerBag(SessionBagInterface $bag)
|
||
{
|
||
$this->storage->registerBag($bag);
|
||
}
|
||
public function getBag($name)
|
||
{
|
||
return $this->storage->getBag($name);
|
||
}
|
||
public function getFlashBag()
|
||
{
|
||
return $this->getBag($this->flashName);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
|
||
class NativeSessionStorage implements SessionStorageInterface
|
||
{
|
||
protected $bags;
|
||
protected $started = false;
|
||
protected $closed = false;
|
||
protected $saveHandler;
|
||
protected $metadataBag;
|
||
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
|
||
{
|
||
session_cache_limiter('');
|
||
ini_set('session.use_cookies', 1);
|
||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||
session_register_shutdown();
|
||
} else {
|
||
register_shutdown_function('session_write_close');
|
||
}
|
||
$this->setMetadataBag($metaBag);
|
||
$this->setOptions($options);
|
||
$this->setSaveHandler($handler);
|
||
}
|
||
public function getSaveHandler()
|
||
{
|
||
return $this->saveHandler;
|
||
}
|
||
public function start()
|
||
{
|
||
if ($this->started && !$this->closed) {
|
||
return true;
|
||
}
|
||
if (version_compare(phpversion(), '5.4.0', '>=') && \PHP_SESSION_ACTIVE === session_status()) {
|
||
throw new \RuntimeException('Failed to start the session: already started by PHP.');
|
||
}
|
||
if (version_compare(phpversion(), '5.4.0', '<') && isset($_SESSION) && session_id()) {
|
||
throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
|
||
}
|
||
if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
|
||
throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
|
||
}
|
||
if (!session_start()) {
|
||
throw new \RuntimeException('Failed to start the session');
|
||
}
|
||
$this->loadSession();
|
||
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
|
||
$this->saveHandler->setActive(true);
|
||
}
|
||
return true;
|
||
}
|
||
public function getId()
|
||
{
|
||
if (!$this->started) {
|
||
return '';
|
||
}
|
||
return $this->saveHandler->getId();
|
||
}
|
||
public function setId($id)
|
||
{
|
||
$this->saveHandler->setId($id);
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->saveHandler->getName();
|
||
}
|
||
public function setName($name)
|
||
{
|
||
$this->saveHandler->setName($name);
|
||
}
|
||
public function regenerate($destroy = false, $lifetime = null)
|
||
{
|
||
if (null !== $lifetime) {
|
||
ini_set('session.cookie_lifetime', $lifetime);
|
||
}
|
||
if ($destroy) {
|
||
$this->metadataBag->stampNew();
|
||
}
|
||
return session_regenerate_id($destroy);
|
||
}
|
||
public function save()
|
||
{
|
||
session_write_close();
|
||
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
|
||
$this->saveHandler->setActive(false);
|
||
}
|
||
$this->closed = true;
|
||
}
|
||
public function clear()
|
||
{
|
||
foreach ($this->bags as $bag) {
|
||
$bag->clear();
|
||
}
|
||
$_SESSION = array();
|
||
$this->loadSession();
|
||
}
|
||
public function registerBag(SessionBagInterface $bag)
|
||
{
|
||
$this->bags[$bag->getName()] = $bag;
|
||
}
|
||
public function getBag($name)
|
||
{
|
||
if (!isset($this->bags[$name])) {
|
||
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
|
||
}
|
||
if ($this->saveHandler->isActive() && !$this->started) {
|
||
$this->loadSession();
|
||
} elseif (!$this->started) {
|
||
$this->start();
|
||
}
|
||
return $this->bags[$name];
|
||
}
|
||
public function setMetadataBag(MetadataBag $metaBag = null)
|
||
{
|
||
if (null === $metaBag) {
|
||
$metaBag = new MetadataBag();
|
||
}
|
||
$this->metadataBag = $metaBag;
|
||
}
|
||
public function getMetadataBag()
|
||
{
|
||
return $this->metadataBag;
|
||
}
|
||
public function isStarted()
|
||
{
|
||
return $this->started;
|
||
}
|
||
public function setOptions(array $options)
|
||
{
|
||
$validOptions = array_flip(array('cache_limiter', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', 'hash_function', 'name', 'referer_check', 'serialize_handler', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'));
|
||
foreach ($options as $key => $value) {
|
||
if (isset($validOptions[$key])) {
|
||
ini_set('session.' . $key, $value);
|
||
}
|
||
}
|
||
}
|
||
public function setSaveHandler($saveHandler = null)
|
||
{
|
||
if (!$saveHandler instanceof AbstractProxy && !$saveHandler instanceof NativeSessionHandler && !$saveHandler instanceof \SessionHandlerInterface && null !== $saveHandler) {
|
||
throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \\SessionHandlerInterface; or be null.');
|
||
}
|
||
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
|
||
$saveHandler = new SessionHandlerProxy($saveHandler);
|
||
} elseif (!$saveHandler instanceof AbstractProxy) {
|
||
$saveHandler = version_compare(phpversion(), '5.4.0', '>=') ? new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy();
|
||
}
|
||
$this->saveHandler = $saveHandler;
|
||
if ($this->saveHandler instanceof \SessionHandlerInterface) {
|
||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||
session_set_save_handler($this->saveHandler, false);
|
||
} else {
|
||
session_set_save_handler(array($this->saveHandler, 'open'), array($this->saveHandler, 'close'), array($this->saveHandler, 'read'), array($this->saveHandler, 'write'), array($this->saveHandler, 'destroy'), array($this->saveHandler, 'gc'));
|
||
}
|
||
}
|
||
}
|
||
protected function loadSession(array &$session = null)
|
||
{
|
||
if (null === $session) {
|
||
$session =& $_SESSION;
|
||
}
|
||
$bags = array_merge($this->bags, array($this->metadataBag));
|
||
foreach ($bags as $bag) {
|
||
$key = $bag->getStorageKey();
|
||
$session[$key] = isset($session[$key]) ? $session[$key] : array();
|
||
$bag->initialize($session[$key]);
|
||
}
|
||
$this->started = true;
|
||
$this->closed = false;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Attribute;
|
||
|
||
class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable
|
||
{
|
||
private $name = 'attributes';
|
||
private $storageKey;
|
||
protected $attributes = array();
|
||
public function __construct($storageKey = '_sf2_attributes')
|
||
{
|
||
$this->storageKey = $storageKey;
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->name;
|
||
}
|
||
public function setName($name)
|
||
{
|
||
$this->name = $name;
|
||
}
|
||
public function initialize(array &$attributes)
|
||
{
|
||
$this->attributes =& $attributes;
|
||
}
|
||
public function getStorageKey()
|
||
{
|
||
return $this->storageKey;
|
||
}
|
||
public function has($name)
|
||
{
|
||
return array_key_exists($name, $this->attributes);
|
||
}
|
||
public function get($name, $default = null)
|
||
{
|
||
return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
|
||
}
|
||
public function set($name, $value)
|
||
{
|
||
$this->attributes[$name] = $value;
|
||
}
|
||
public function all()
|
||
{
|
||
return $this->attributes;
|
||
}
|
||
public function replace(array $attributes)
|
||
{
|
||
$this->attributes = array();
|
||
foreach ($attributes as $key => $value) {
|
||
$this->set($key, $value);
|
||
}
|
||
}
|
||
public function remove($name)
|
||
{
|
||
$retval = null;
|
||
if (array_key_exists($name, $this->attributes)) {
|
||
$retval = $this->attributes[$name];
|
||
unset($this->attributes[$name]);
|
||
}
|
||
return $retval;
|
||
}
|
||
public function clear()
|
||
{
|
||
$return = $this->attributes;
|
||
$this->attributes = array();
|
||
return $return;
|
||
}
|
||
public function getIterator()
|
||
{
|
||
return new \ArrayIterator($this->attributes);
|
||
}
|
||
public function count()
|
||
{
|
||
return count($this->attributes);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Flash;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||
interface FlashBagInterface extends SessionBagInterface
|
||
{
|
||
public function add($type, $message);
|
||
public function set($type, $message);
|
||
public function peek($type, array $default = array());
|
||
public function peekAll();
|
||
public function get($type, array $default = array());
|
||
public function all();
|
||
public function setAll(array $messages);
|
||
public function has($type);
|
||
public function keys();
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Flash;
|
||
|
||
class FlashBag implements FlashBagInterface, \IteratorAggregate
|
||
{
|
||
private $name = 'flashes';
|
||
private $flashes = array();
|
||
private $storageKey;
|
||
public function __construct($storageKey = '_sf2_flashes')
|
||
{
|
||
$this->storageKey = $storageKey;
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->name;
|
||
}
|
||
public function setName($name)
|
||
{
|
||
$this->name = $name;
|
||
}
|
||
public function initialize(array &$flashes)
|
||
{
|
||
$this->flashes =& $flashes;
|
||
}
|
||
public function add($type, $message)
|
||
{
|
||
$this->flashes[$type][] = $message;
|
||
}
|
||
public function peek($type, array $default = array())
|
||
{
|
||
return $this->has($type) ? $this->flashes[$type] : $default;
|
||
}
|
||
public function peekAll()
|
||
{
|
||
return $this->flashes;
|
||
}
|
||
public function get($type, array $default = array())
|
||
{
|
||
if (!$this->has($type)) {
|
||
return $default;
|
||
}
|
||
$return = $this->flashes[$type];
|
||
unset($this->flashes[$type]);
|
||
return $return;
|
||
}
|
||
public function all()
|
||
{
|
||
$return = $this->peekAll();
|
||
$this->flashes = array();
|
||
return $return;
|
||
}
|
||
public function set($type, $messages)
|
||
{
|
||
$this->flashes[$type] = (array) $messages;
|
||
}
|
||
public function setAll(array $messages)
|
||
{
|
||
$this->flashes = $messages;
|
||
}
|
||
public function has($type)
|
||
{
|
||
return array_key_exists($type, $this->flashes) && $this->flashes[$type];
|
||
}
|
||
public function keys()
|
||
{
|
||
return array_keys($this->flashes);
|
||
}
|
||
public function getStorageKey()
|
||
{
|
||
return $this->storageKey;
|
||
}
|
||
public function clear()
|
||
{
|
||
return $this->all();
|
||
}
|
||
public function getIterator()
|
||
{
|
||
return new \ArrayIterator($this->all());
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Flash;
|
||
|
||
class AutoExpireFlashBag implements FlashBagInterface
|
||
{
|
||
private $name = 'flashes';
|
||
private $flashes = array();
|
||
private $storageKey;
|
||
public function __construct($storageKey = '_sf2_flashes')
|
||
{
|
||
$this->storageKey = $storageKey;
|
||
$this->flashes = array('display' => array(), 'new' => array());
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->name;
|
||
}
|
||
public function setName($name)
|
||
{
|
||
$this->name = $name;
|
||
}
|
||
public function initialize(array &$flashes)
|
||
{
|
||
$this->flashes =& $flashes;
|
||
$this->flashes['display'] = array_key_exists('new', $this->flashes) ? $this->flashes['new'] : array();
|
||
$this->flashes['new'] = array();
|
||
}
|
||
public function add($type, $message)
|
||
{
|
||
$this->flashes['new'][$type][] = $message;
|
||
}
|
||
public function peek($type, array $default = array())
|
||
{
|
||
return $this->has($type) ? $this->flashes['display'][$type] : $default;
|
||
}
|
||
public function peekAll()
|
||
{
|
||
return array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : array();
|
||
}
|
||
public function get($type, array $default = array())
|
||
{
|
||
$return = $default;
|
||
if (!$this->has($type)) {
|
||
return $return;
|
||
}
|
||
if (isset($this->flashes['display'][$type])) {
|
||
$return = $this->flashes['display'][$type];
|
||
unset($this->flashes['display'][$type]);
|
||
}
|
||
return $return;
|
||
}
|
||
public function all()
|
||
{
|
||
$return = $this->flashes['display'];
|
||
$this->flashes = array('new' => array(), 'display' => array());
|
||
return $return;
|
||
}
|
||
public function setAll(array $messages)
|
||
{
|
||
$this->flashes['new'] = $messages;
|
||
}
|
||
public function set($type, $messages)
|
||
{
|
||
$this->flashes['new'][$type] = (array) $messages;
|
||
}
|
||
public function has($type)
|
||
{
|
||
return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
|
||
}
|
||
public function keys()
|
||
{
|
||
return array_keys($this->flashes['display']);
|
||
}
|
||
public function getStorageKey()
|
||
{
|
||
return $this->storageKey;
|
||
}
|
||
public function clear()
|
||
{
|
||
return $this->all();
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||
class MetadataBag implements SessionBagInterface
|
||
{
|
||
const CREATED = 'c';
|
||
const UPDATED = 'u';
|
||
const LIFETIME = 'l';
|
||
private $name = '__metadata';
|
||
private $storageKey;
|
||
protected $meta = array();
|
||
private $lastUsed;
|
||
public function __construct($storageKey = '_sf2_meta')
|
||
{
|
||
$this->storageKey = $storageKey;
|
||
$this->meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0);
|
||
}
|
||
public function initialize(array &$array)
|
||
{
|
||
$this->meta =& $array;
|
||
if (isset($array[self::CREATED])) {
|
||
$this->lastUsed = $this->meta[self::UPDATED];
|
||
$this->meta[self::UPDATED] = time();
|
||
} else {
|
||
$this->stampCreated();
|
||
}
|
||
}
|
||
public function getLifetime()
|
||
{
|
||
return $this->meta[self::LIFETIME];
|
||
}
|
||
public function stampNew($lifetime = null)
|
||
{
|
||
$this->stampCreated($lifetime);
|
||
}
|
||
public function getStorageKey()
|
||
{
|
||
return $this->storageKey;
|
||
}
|
||
public function getCreated()
|
||
{
|
||
return $this->meta[self::CREATED];
|
||
}
|
||
public function getLastUsed()
|
||
{
|
||
return $this->lastUsed;
|
||
}
|
||
public function clear()
|
||
{
|
||
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->name;
|
||
}
|
||
public function setName($name)
|
||
{
|
||
$this->name = $name;
|
||
}
|
||
private function stampCreated($lifetime = null)
|
||
{
|
||
$timeStamp = time();
|
||
$this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
|
||
$this->meta[self::LIFETIME] = null === $lifetime ? ini_get('session.cookie_lifetime') : $lifetime;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
||
|
||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||
class NativeSessionHandler extends \SessionHandler
|
||
{
|
||
|
||
}
|
||
} else {
|
||
class NativeSessionHandler
|
||
{
|
||
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
|
||
|
||
abstract class AbstractProxy
|
||
{
|
||
protected $wrapper = false;
|
||
protected $active = false;
|
||
protected $saveHandlerName;
|
||
public function getSaveHandlerName()
|
||
{
|
||
return $this->saveHandlerName;
|
||
}
|
||
public function isSessionHandlerInterface()
|
||
{
|
||
return $this instanceof \SessionHandlerInterface;
|
||
}
|
||
public function isWrapper()
|
||
{
|
||
return $this->wrapper;
|
||
}
|
||
public function isActive()
|
||
{
|
||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||
return $this->active = \PHP_SESSION_ACTIVE === session_status();
|
||
}
|
||
return $this->active;
|
||
}
|
||
public function setActive($flag)
|
||
{
|
||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||
throw new \LogicException('This method is disabled in PHP 5.4.0+');
|
||
}
|
||
$this->active = (bool) $flag;
|
||
}
|
||
public function getId()
|
||
{
|
||
return session_id();
|
||
}
|
||
public function setId($id)
|
||
{
|
||
if ($this->isActive()) {
|
||
throw new \LogicException('Cannot change the ID of an active session');
|
||
}
|
||
session_id($id);
|
||
}
|
||
public function getName()
|
||
{
|
||
return session_name();
|
||
}
|
||
public function setName($name)
|
||
{
|
||
if ($this->isActive()) {
|
||
throw new \LogicException('Cannot change the name of an active session');
|
||
}
|
||
session_name($name);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
|
||
|
||
class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface
|
||
{
|
||
protected $handler;
|
||
public function __construct(\SessionHandlerInterface $handler)
|
||
{
|
||
$this->handler = $handler;
|
||
$this->wrapper = $handler instanceof \SessionHandler;
|
||
$this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user';
|
||
}
|
||
public function open($savePath, $sessionName)
|
||
{
|
||
$return = (bool) $this->handler->open($savePath, $sessionName);
|
||
if (true === $return) {
|
||
$this->active = true;
|
||
}
|
||
return $return;
|
||
}
|
||
public function close()
|
||
{
|
||
$this->active = false;
|
||
return (bool) $this->handler->close();
|
||
}
|
||
public function read($id)
|
||
{
|
||
return (string) $this->handler->read($id);
|
||
}
|
||
public function write($id, $data)
|
||
{
|
||
return (bool) $this->handler->write($id, $data);
|
||
}
|
||
public function destroy($id)
|
||
{
|
||
return (bool) $this->handler->destroy($id);
|
||
}
|
||
public function gc($maxlifetime)
|
||
{
|
||
return (bool) $this->handler->gc($maxlifetime);
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class AcceptHeaderItem
|
||
{
|
||
private $value;
|
||
private $quality = 1.0;
|
||
private $index = 0;
|
||
private $attributes = array();
|
||
public function __construct($value, array $attributes = array())
|
||
{
|
||
$this->value = $value;
|
||
foreach ($attributes as $name => $value) {
|
||
$this->setAttribute($name, $value);
|
||
}
|
||
}
|
||
public static function fromString($itemValue)
|
||
{
|
||
$bits = preg_split('/\\s*(?:;*("[^"]+");*|;*(\'[^\']+\');*|;+)\\s*/', $itemValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||
$value = array_shift($bits);
|
||
$attributes = array();
|
||
$lastNullAttribute = null;
|
||
foreach ($bits as $bit) {
|
||
if (($start = substr($bit, 0, 1)) === ($end = substr($bit, -1)) && ($start === '"' || $start === '\'')) {
|
||
$attributes[$lastNullAttribute] = substr($bit, 1, -1);
|
||
} elseif ('=' === $end) {
|
||
$lastNullAttribute = $bit = substr($bit, 0, -1);
|
||
$attributes[$bit] = null;
|
||
} else {
|
||
$parts = explode('=', $bit);
|
||
$attributes[$parts[0]] = isset($parts[1]) && strlen($parts[1]) > 0 ? $parts[1] : '';
|
||
}
|
||
}
|
||
return new self(($start = substr($value, 0, 1)) === ($end = substr($value, -1)) && ($start === '"' || $start === '\'') ? substr($value, 1, -1) : $value, $attributes);
|
||
}
|
||
public function __toString()
|
||
{
|
||
$string = $this->value . ($this->quality < 1 ? ';q=' . $this->quality : '');
|
||
if (count($this->attributes) > 0) {
|
||
$string .= ';' . implode(';', array_map(function ($name, $value) {
|
||
return sprintf(preg_match('/[,;=]/', $value) ? '%s="%s"' : '%s=%s', $name, $value);
|
||
}, array_keys($this->attributes), $this->attributes));
|
||
}
|
||
return $string;
|
||
}
|
||
public function setValue($value)
|
||
{
|
||
$this->value = $value;
|
||
return $this;
|
||
}
|
||
public function getValue()
|
||
{
|
||
return $this->value;
|
||
}
|
||
public function setQuality($quality)
|
||
{
|
||
$this->quality = $quality;
|
||
return $this;
|
||
}
|
||
public function getQuality()
|
||
{
|
||
return $this->quality;
|
||
}
|
||
public function setIndex($index)
|
||
{
|
||
$this->index = $index;
|
||
return $this;
|
||
}
|
||
public function getIndex()
|
||
{
|
||
return $this->index;
|
||
}
|
||
public function hasAttribute($name)
|
||
{
|
||
return isset($this->attributes[$name]);
|
||
}
|
||
public function getAttribute($name, $default = null)
|
||
{
|
||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||
}
|
||
public function getAttributes()
|
||
{
|
||
return $this->attributes;
|
||
}
|
||
public function setAttribute($name, $value)
|
||
{
|
||
if ('q' === $name) {
|
||
$this->quality = (double) $value;
|
||
} else {
|
||
$this->attributes[$name] = (string) $value;
|
||
}
|
||
return $this;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class AcceptHeader
|
||
{
|
||
private $items = array();
|
||
private $sorted = true;
|
||
public function __construct(array $items)
|
||
{
|
||
foreach ($items as $item) {
|
||
$this->add($item);
|
||
}
|
||
}
|
||
public static function fromString($headerValue)
|
||
{
|
||
$index = 0;
|
||
return new self(array_map(function ($itemValue) use(&$index) {
|
||
$item = AcceptHeaderItem::fromString($itemValue);
|
||
$item->setIndex($index++);
|
||
return $item;
|
||
}, preg_split('/\\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
|
||
}
|
||
public function __toString()
|
||
{
|
||
return implode(',', $this->items);
|
||
}
|
||
public function has($value)
|
||
{
|
||
return isset($this->items[$value]);
|
||
}
|
||
public function get($value)
|
||
{
|
||
return isset($this->items[$value]) ? $this->items[$value] : null;
|
||
}
|
||
public function add(AcceptHeaderItem $item)
|
||
{
|
||
$this->items[$item->getValue()] = $item;
|
||
$this->sorted = false;
|
||
return $this;
|
||
}
|
||
public function all()
|
||
{
|
||
$this->sort();
|
||
return $this->items;
|
||
}
|
||
public function filter($pattern)
|
||
{
|
||
return new self(array_filter($this->items, function (AcceptHeaderItem $item) use($pattern) {
|
||
return preg_match($pattern, $item->getValue());
|
||
}));
|
||
}
|
||
public function first()
|
||
{
|
||
$this->sort();
|
||
return !empty($this->items) ? reset($this->items) : null;
|
||
}
|
||
private function sort()
|
||
{
|
||
if (!$this->sorted) {
|
||
uasort($this->items, function ($a, $b) {
|
||
$qA = $a->getQuality();
|
||
$qB = $b->getQuality();
|
||
if ($qA === $qB) {
|
||
return $a->getIndex() > $b->getIndex() ? 1 : -1;
|
||
}
|
||
return $qA > $qB ? -1 : 1;
|
||
});
|
||
$this->sorted = true;
|
||
}
|
||
}
|
||
}
|
||
namespace Symfony\Component\Debug;
|
||
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
use Symfony\Component\Debug\Exception\FlattenException;
|
||
if (!defined('ENT_SUBSTITUTE')) {
|
||
define('ENT_SUBSTITUTE', 8);
|
||
}
|
||
class ExceptionHandler
|
||
{
|
||
private $debug;
|
||
private $charset;
|
||
public function __construct($debug = true, $charset = 'UTF-8')
|
||
{
|
||
$this->debug = $debug;
|
||
$this->charset = $charset;
|
||
}
|
||
public static function register($debug = true)
|
||
{
|
||
$handler = new static($debug);
|
||
set_exception_handler(array($handler, 'handle'));
|
||
return $handler;
|
||
}
|
||
public function handle(\Exception $exception)
|
||
{
|
||
if (class_exists('Symfony\\Component\\HttpFoundation\\Response')) {
|
||
$this->createResponse($exception)->send();
|
||
} else {
|
||
$this->sendPhpResponse($exception);
|
||
}
|
||
}
|
||
public function sendPhpResponse($exception)
|
||
{
|
||
if (!$exception instanceof FlattenException) {
|
||
$exception = FlattenException::create($exception);
|
||
}
|
||
header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
|
||
foreach ($exception->getHeaders() as $name => $value) {
|
||
header($name . ': ' . $value, false);
|
||
}
|
||
echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
|
||
}
|
||
public function createResponse($exception)
|
||
{
|
||
if (!$exception instanceof FlattenException) {
|
||
$exception = FlattenException::create($exception);
|
||
}
|
||
return new Response($this->decorate($this->getContent($exception), $this->getStylesheet($exception)), $exception->getStatusCode(), $exception->getHeaders());
|
||
}
|
||
public function getContent(FlattenException $exception)
|
||
{
|
||
switch ($exception->getStatusCode()) {
|
||
case 404:
|
||
$title = 'Sorry, the page you are looking for could not be found.';
|
||
break;
|
||
default:
|
||
$title = 'Whoops, looks like something went wrong.';
|
||
}
|
||
$content = '';
|
||
if ($this->debug) {
|
||
try {
|
||
$count = count($exception->getAllPrevious());
|
||
$total = $count + 1;
|
||
foreach ($exception->toArray() as $position => $e) {
|
||
$ind = $count - $position + 1;
|
||
$class = $this->abbrClass($e['class']);
|
||
$message = nl2br($e['message']);
|
||
$content .= sprintf(' <div class="block_exception clear_fix">
|
||
<h2><span>%d/%d</span> %s: %s</h2>
|
||
</div>
|
||
<div class="block">
|
||
<ol class="traces list_exception">
|
||
', $ind, $total, $class, $message);
|
||
foreach ($e['trace'] as $trace) {
|
||
$content .= ' <li>';
|
||
if ($trace['function']) {
|
||
$content .= sprintf('at %s%s%s(%s)', $this->abbrClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
|
||
}
|
||
if (isset($trace['file']) && isset($trace['line'])) {
|
||
if ($linkFormat = ini_get('xdebug.file_link_format')) {
|
||
$link = str_replace(array('%f', '%l'), array($trace['file'], $trace['line']), $linkFormat);
|
||
$content .= sprintf(' in <a href="%s" title="Go to source">%s line %s</a>', $link, $trace['file'], $trace['line']);
|
||
} else {
|
||
$content .= sprintf(' in %s line %s', $trace['file'], $trace['line']);
|
||
}
|
||
}
|
||
$content .= '</li>
|
||
';
|
||
}
|
||
$content .= ' </ol>
|
||
</div>
|
||
';
|
||
}
|
||
} catch (\Exception $e) {
|
||
if ($this->debug) {
|
||
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($exception), $exception->getMessage());
|
||
} else {
|
||
$title = 'Whoops, looks like something went wrong.';
|
||
}
|
||
}
|
||
}
|
||
return " <div id=\"sf-resetcontent\" class=\"sf-reset\">\r\n <h1>{$title}</h1>\r\n {$content}\r\n </div>";
|
||
}
|
||
public function getStylesheet(FlattenException $exception)
|
||
{
|
||
return ' .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }
|
||
.sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }
|
||
.sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }
|
||
.sf-reset .clear_fix { display:inline-block; }
|
||
.sf-reset * html .clear_fix { height:1%; }
|
||
.sf-reset .clear_fix { display:block; }
|
||
.sf-reset, .sf-reset .block { margin: auto }
|
||
.sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
|
||
.sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
|
||
.sf-reset strong { font-weight:bold; }
|
||
.sf-reset a { color:#6c6159; }
|
||
.sf-reset a img { border:none; }
|
||
.sf-reset a:hover { text-decoration:underline; }
|
||
.sf-reset em { font-style:italic; }
|
||
.sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
|
||
.sf-reset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; }
|
||
.sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
|
||
.sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
|
||
-webkit-border-bottom-right-radius: 16px;
|
||
-webkit-border-bottom-left-radius: 16px;
|
||
-moz-border-radius-bottomright: 16px;
|
||
-moz-border-radius-bottomleft: 16px;
|
||
border-bottom-right-radius: 16px;
|
||
border-bottom-left-radius: 16px;
|
||
border-bottom:1px solid #ccc;
|
||
border-right:1px solid #ccc;
|
||
border-left:1px solid #ccc;
|
||
}
|
||
.sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;
|
||
-webkit-border-top-left-radius: 16px;
|
||
-webkit-border-top-right-radius: 16px;
|
||
-moz-border-radius-topleft: 16px;
|
||
-moz-border-radius-topright: 16px;
|
||
border-top-left-radius: 16px;
|
||
border-top-right-radius: 16px;
|
||
border-top:1px solid #ccc;
|
||
border-right:1px solid #ccc;
|
||
border-left:1px solid #ccc;
|
||
overflow: hidden;
|
||
word-wrap: break-word;
|
||
}
|
||
.sf-reset li a { background:none; color:#868686; text-decoration:none; }
|
||
.sf-reset li a:hover { background:none; color:#313131; text-decoration:underline; }
|
||
.sf-reset ol { padding: 10px 0; }
|
||
.sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
|
||
-webkit-border-radius: 10px;
|
||
-moz-border-radius: 10px;
|
||
border-radius: 10px;
|
||
border: 1px solid #ccc;
|
||
}';
|
||
}
|
||
private function decorate($content, $css)
|
||
{
|
||
return "<!DOCTYPE html>\r\n<html>\r\n <head>\r\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\r\n <meta name=\"robots\" content=\"noindex,nofollow\" />\r\n <style>\r\n /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */\r\n html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}\r\n\r\n html { background: #eee; padding: 10px }\r\n img { border: 0; }\r\n #sf-resetcontent { width:970px; margin:0 auto; }\r\n {$css}\r\n </style>\r\n </head>\r\n <body>\r\n {$content}\r\n </body>\r\n</html>";
|
||
}
|
||
private function abbrClass($class)
|
||
{
|
||
$parts = explode('\\', $class);
|
||
return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
|
||
}
|
||
private function formatArgs(array $args)
|
||
{
|
||
$result = array();
|
||
foreach ($args as $key => $item) {
|
||
if ('object' === $item[0]) {
|
||
$formattedValue = sprintf('<em>object</em>(%s)', $this->abbrClass($item[1]));
|
||
} elseif ('array' === $item[0]) {
|
||
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
||
} elseif ('string' === $item[0]) {
|
||
$formattedValue = sprintf('\'%s\'', htmlspecialchars($item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset));
|
||
} elseif ('null' === $item[0]) {
|
||
$formattedValue = '<em>null</em>';
|
||
} elseif ('boolean' === $item[0]) {
|
||
$formattedValue = '<em>' . strtolower(var_export($item[1], true)) . '</em>';
|
||
} elseif ('resource' === $item[0]) {
|
||
$formattedValue = '<em>resource</em>';
|
||
} else {
|
||
$formattedValue = str_replace('
|
||
', '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), true));
|
||
}
|
||
$result[] = is_int($key) ? $formattedValue : sprintf('\'%s\' => %s', $key, $formattedValue);
|
||
}
|
||
return implode(', ', $result);
|
||
}
|
||
}
|
||
namespace Illuminate\Support;
|
||
|
||
use ReflectionClass;
|
||
abstract class ServiceProvider
|
||
{
|
||
protected $app;
|
||
protected $defer = false;
|
||
public function __construct($app)
|
||
{
|
||
$this->app = $app;
|
||
}
|
||
public function boot()
|
||
{
|
||
|
||
}
|
||
public abstract function register();
|
||
public function package($package, $namespace = null, $path = null)
|
||
{
|
||
$namespace = $this->getPackageNamespace($package, $namespace);
|
||
$path = $path ?: $this->guessPackagePath();
|
||
$config = $path . '/config';
|
||
if ($this->app['files']->isDirectory($config)) {
|
||
$this->app['config']->package($package, $config, $namespace);
|
||
}
|
||
$lang = $path . '/lang';
|
||
if ($this->app['files']->isDirectory($lang)) {
|
||
$this->app['translator']->addNamespace($namespace, $lang);
|
||
}
|
||
$appView = $this->getAppViewPath($package, $namespace);
|
||
if ($this->app['files']->isDirectory($appView)) {
|
||
$this->app['view']->addNamespace($namespace, $appView);
|
||
}
|
||
$view = $path . '/views';
|
||
if ($this->app['files']->isDirectory($view)) {
|
||
$this->app['view']->addNamespace($namespace, $view);
|
||
}
|
||
}
|
||
public function guessPackagePath()
|
||
{
|
||
$reflect = new ReflectionClass($this);
|
||
$chain = $this->getClassChain($reflect);
|
||
$path = $chain[count($chain) - 2]->getFileName();
|
||
return realpath(dirname($path) . '/../../');
|
||
}
|
||
protected function getClassChain(ReflectionClass $reflect)
|
||
{
|
||
$lastName = null;
|
||
while ($reflect !== false) {
|
||
$classes[] = $reflect;
|
||
$reflect = $reflect->getParentClass();
|
||
}
|
||
return $classes;
|
||
}
|
||
protected function getPackageNamespace($package, $namespace)
|
||
{
|
||
if (is_null($namespace)) {
|
||
list($vendor, $namespace) = explode('/', $package);
|
||
}
|
||
return $namespace;
|
||
}
|
||
public function commands()
|
||
{
|
||
$commands = func_get_args();
|
||
$events = $this->app['events'];
|
||
$events->listen('artisan.start', function ($artisan) use($commands) {
|
||
$artisan->resolveCommands($commands);
|
||
});
|
||
}
|
||
protected function getAppViewPath($package, $namespace)
|
||
{
|
||
return $this->app['path'] . "/views/packages/{$package}/{$namespace}";
|
||
}
|
||
public function provides()
|
||
{
|
||
return array();
|
||
}
|
||
public function isDeferred()
|
||
{
|
||
return $this->defer;
|
||
}
|
||
}
|
||
namespace Illuminate\Exception;
|
||
|
||
use Closure;
|
||
use Whoops\Handler\PrettyPageHandler;
|
||
use Whoops\Handler\JsonResponseHandler;
|
||
use Illuminate\Support\ServiceProvider;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
use Symfony\Component\Debug\ExceptionHandler as KernelHandler;
|
||
class ExceptionServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->registerDisplayers();
|
||
$this->registerHandler();
|
||
}
|
||
protected function registerDisplayers()
|
||
{
|
||
$this->registerPlainDisplayer();
|
||
$this->registerDebugDisplayer();
|
||
}
|
||
protected function registerHandler()
|
||
{
|
||
$this->app['exception'] = $this->app->share(function ($app) {
|
||
return new Handler($app, $app['exception.plain'], $app['exception.debug']);
|
||
});
|
||
}
|
||
protected function registerPlainDisplayer()
|
||
{
|
||
$this->app['exception.plain'] = $this->app->share(function ($app) {
|
||
$handler = new KernelHandler($app['config']['app.debug']);
|
||
return new SymfonyDisplayer($handler);
|
||
});
|
||
}
|
||
protected function registerDebugDisplayer()
|
||
{
|
||
$this->registerWhoops();
|
||
$this->app['exception.debug'] = $this->app->share(function ($app) {
|
||
return new WhoopsDisplayer($app['whoops'], $app->runningInConsole());
|
||
});
|
||
}
|
||
protected function registerWhoops()
|
||
{
|
||
$this->registerWhoopsHandler();
|
||
$this->app['whoops'] = $this->app->share(function ($app) {
|
||
with($whoops = new \Whoops\Run())->allowQuit(false);
|
||
return $whoops->pushHandler($app['whoops.handler']);
|
||
});
|
||
}
|
||
protected function registerWhoopsHandler()
|
||
{
|
||
if ($this->shouldReturnJson()) {
|
||
$this->app['whoops.handler'] = $this->app->share(function () {
|
||
return new JsonResponseHandler();
|
||
});
|
||
} else {
|
||
$this->registerPrettyWhoopsHandler();
|
||
}
|
||
}
|
||
protected function shouldReturnJson()
|
||
{
|
||
$definitely = ($this->app['request']->ajax() or $this->app->runningInConsole());
|
||
return $definitely or $this->app['request']->wantsJson();
|
||
}
|
||
protected function registerPrettyWhoopsHandler()
|
||
{
|
||
$me = $this;
|
||
$this->app['whoops.handler'] = $this->app->share(function () use($me) {
|
||
with($handler = new PrettyPageHandler())->setEditor('sublime');
|
||
if (!is_null($path = $me->resourcePath())) {
|
||
$handler->setResourcesPath($path);
|
||
}
|
||
return $handler;
|
||
});
|
||
}
|
||
public function resourcePath()
|
||
{
|
||
if (is_dir($path = $this->getResourcePath())) {
|
||
return $path;
|
||
}
|
||
}
|
||
protected function getResourcePath()
|
||
{
|
||
$base = $this->app['path.base'];
|
||
return $base . '/vendor/laravel/framework/src/Illuminate/Exception/resources';
|
||
}
|
||
}
|
||
namespace Illuminate\Routing;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class RoutingServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->registerRouter();
|
||
$this->registerUrlGenerator();
|
||
$this->registerRedirector();
|
||
}
|
||
protected function registerRouter()
|
||
{
|
||
$this->app['router'] = $this->app->share(function ($app) {
|
||
$router = new Router($app);
|
||
if ($app['env'] == 'testing') {
|
||
$router->disableFilters();
|
||
}
|
||
return $router;
|
||
});
|
||
}
|
||
protected function registerUrlGenerator()
|
||
{
|
||
$this->app['url'] = $this->app->share(function ($app) {
|
||
$routes = $app['router']->getRoutes();
|
||
return new UrlGenerator($routes, $app['request']);
|
||
});
|
||
}
|
||
protected function registerRedirector()
|
||
{
|
||
$this->app['redirect'] = $this->app->share(function ($app) {
|
||
$redirector = new Redirector($app['url']);
|
||
if (isset($app['session'])) {
|
||
$redirector->setSession($app['session']);
|
||
}
|
||
return $redirector;
|
||
});
|
||
}
|
||
}
|
||
namespace Illuminate\Events;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class EventServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->app['events'] = $this->app->share(function ($app) {
|
||
return new Dispatcher($app);
|
||
});
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Facades;
|
||
|
||
use Mockery\MockInterface;
|
||
abstract class Facade
|
||
{
|
||
protected static $app;
|
||
protected static $resolvedInstance;
|
||
public static function swap($instance)
|
||
{
|
||
static::$resolvedInstance[static::getFacadeAccessor()] = $instance;
|
||
static::$app->instance(static::getFacadeAccessor(), $instance);
|
||
}
|
||
public static function shouldReceive()
|
||
{
|
||
$name = static::getFacadeAccessor();
|
||
if (static::isMock()) {
|
||
$mock = static::$resolvedInstance[$name];
|
||
} else {
|
||
static::$resolvedInstance[$name] = $mock = \Mockery::mock(static::getMockableClass($name));
|
||
static::$app->instance($name, $mock);
|
||
}
|
||
return call_user_func_array(array($mock, 'shouldReceive'), func_get_args());
|
||
}
|
||
protected static function isMock()
|
||
{
|
||
$name = static::getFacadeAccessor();
|
||
return isset(static::$resolvedInstance[$name]) and static::$resolvedInstance[$name] instanceof MockInterface;
|
||
}
|
||
protected static function getMockableClass()
|
||
{
|
||
return get_class(static::getFacadeRoot());
|
||
}
|
||
public static function getFacadeRoot()
|
||
{
|
||
return static::resolveFacadeInstance(static::getFacadeAccessor());
|
||
}
|
||
protected static function getFacadeAccessor()
|
||
{
|
||
throw new \RuntimeException('Facade does not implement getFacadeAccessor method.');
|
||
}
|
||
protected static function resolveFacadeInstance($name)
|
||
{
|
||
if (is_object($name)) {
|
||
return $name;
|
||
}
|
||
if (isset(static::$resolvedInstance[$name])) {
|
||
return static::$resolvedInstance[$name];
|
||
}
|
||
return static::$resolvedInstance[$name] = static::$app[$name];
|
||
}
|
||
public static function clearResolvedInstance($name)
|
||
{
|
||
unset(static::$resolvedInstance[$name]);
|
||
}
|
||
public static function clearResolvedInstances()
|
||
{
|
||
static::$resolvedInstance = array();
|
||
}
|
||
public static function getFacadeApplication()
|
||
{
|
||
return static::$app;
|
||
}
|
||
public static function setFacadeApplication($app)
|
||
{
|
||
static::$app = $app;
|
||
}
|
||
public static function __callStatic($method, $args)
|
||
{
|
||
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
|
||
switch (count($args)) {
|
||
case 0:
|
||
return $instance->{$method}();
|
||
case 1:
|
||
return $instance->{$method}($args[0]);
|
||
case 2:
|
||
return $instance->{$method}($args[0], $args[1]);
|
||
case 3:
|
||
return $instance->{$method}($args[0], $args[1], $args[2]);
|
||
case 4:
|
||
return $instance->{$method}($args[0], $args[1], $args[2], $args[3]);
|
||
default:
|
||
return call_user_func_array(array($instance, $method), $args);
|
||
}
|
||
}
|
||
}
|
||
namespace Illuminate\Support;
|
||
|
||
class Str
|
||
{
|
||
protected static $macros = array();
|
||
public static function ascii($value)
|
||
{
|
||
return \Patchwork\Utf8::toAscii($value);
|
||
}
|
||
public static function camel($value)
|
||
{
|
||
return lcfirst(static::studly($value));
|
||
}
|
||
public static function contains($haystack, $needle)
|
||
{
|
||
foreach ((array) $needle as $n) {
|
||
if (strpos($haystack, $n) !== false) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
public static function endsWith($haystack, $needles)
|
||
{
|
||
foreach ((array) $needles as $needle) {
|
||
if ($needle == substr($haystack, strlen($haystack) - strlen($needle))) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
public static function finish($value, $cap)
|
||
{
|
||
return rtrim($value, $cap) . $cap;
|
||
}
|
||
public static function is($pattern, $value)
|
||
{
|
||
if ($pattern == $value) {
|
||
return true;
|
||
}
|
||
$pattern = preg_quote($pattern, '#');
|
||
if ($pattern !== '/') {
|
||
$pattern = str_replace('\\*', '.*', $pattern) . '\\z';
|
||
} else {
|
||
$pattern = '/$';
|
||
}
|
||
return (bool) preg_match('#^' . $pattern . '#', $value);
|
||
}
|
||
public static function length($value)
|
||
{
|
||
return mb_strlen($value);
|
||
}
|
||
public static function limit($value, $limit = 100, $end = '...')
|
||
{
|
||
if (mb_strlen($value) <= $limit) {
|
||
return $value;
|
||
}
|
||
return mb_substr($value, 0, $limit, 'UTF-8') . $end;
|
||
}
|
||
public static function lower($value)
|
||
{
|
||
return mb_strtolower($value);
|
||
}
|
||
public static function words($value, $words = 100, $end = '...')
|
||
{
|
||
preg_match('/^\\s*+(?:\\S++\\s*+){1,' . $words . '}/u', $value, $matches);
|
||
if (!isset($matches[0])) {
|
||
return $value;
|
||
}
|
||
if (strlen($value) == strlen($matches[0])) {
|
||
return $value;
|
||
}
|
||
return rtrim($matches[0]) . $end;
|
||
}
|
||
public static function plural($value, $count = 2)
|
||
{
|
||
return Pluralizer::plural($value, $count);
|
||
}
|
||
public static function random($length = 16)
|
||
{
|
||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||
$bytes = openssl_random_pseudo_bytes($length * 2);
|
||
if ($bytes === false) {
|
||
throw new \RuntimeException('Unable to generate random string.');
|
||
}
|
||
return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
|
||
}
|
||
return static::quickRandom($length);
|
||
}
|
||
public static function quickRandom($length = 16)
|
||
{
|
||
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||
return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
|
||
}
|
||
public static function upper($value)
|
||
{
|
||
return mb_strtoupper($value);
|
||
}
|
||
public static function singular($value)
|
||
{
|
||
return Pluralizer::singular($value);
|
||
}
|
||
public static function slug($title, $separator = '-')
|
||
{
|
||
$title = static::ascii($title);
|
||
$title = preg_replace('![^' . preg_quote($separator) . '\\pL\\pN\\s]+!u', '', mb_strtolower($title));
|
||
$flip = $separator == '-' ? '_' : '-';
|
||
$title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title);
|
||
$title = preg_replace('![' . preg_quote($separator) . '\\s]+!u', $separator, $title);
|
||
return trim($title, $separator);
|
||
}
|
||
public static function snake($value, $delimiter = '_')
|
||
{
|
||
$replace = '$1' . $delimiter . '$2';
|
||
return ctype_lower($value) ? $value : strtolower(preg_replace('/(.)([A-Z])/', $replace, $value));
|
||
}
|
||
public static function startsWith($haystack, $needles)
|
||
{
|
||
foreach ((array) $needles as $needle) {
|
||
if (strpos($haystack, $needle) === 0) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
public static function studly($value)
|
||
{
|
||
$value = ucwords(str_replace(array('-', '_'), ' ', $value));
|
||
return str_replace(' ', '', $value);
|
||
}
|
||
public static function macro($name, $macro)
|
||
{
|
||
static::$macros[$name] = $macro;
|
||
}
|
||
public static function __callStatic($method, $parameters)
|
||
{
|
||
if (isset(static::$macros[$method])) {
|
||
return call_user_func_array(static::$macros[$method], $parameters);
|
||
}
|
||
throw new \BadMethodCallException("Method {$method} does not exist.");
|
||
}
|
||
}
|
||
namespace Symfony\Component\Debug;
|
||
|
||
use Symfony\Component\Debug\Exception\FatalErrorException;
|
||
use Symfony\Component\Debug\Exception\ContextErrorException;
|
||
use Psr\Log\LoggerInterface;
|
||
class ErrorHandler
|
||
{
|
||
const TYPE_DEPRECATION = -100;
|
||
private $levels = array(E_WARNING => 'Warning', E_NOTICE => 'Notice', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice', E_RECOVERABLE_ERROR => 'Catchable Fatal Error', E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'User Deprecated', E_ERROR => 'Error', E_CORE_ERROR => 'Core Error', E_COMPILE_ERROR => 'Compile Error', E_PARSE => 'Parse');
|
||
private $level;
|
||
private $reservedMemory;
|
||
private $displayErrors;
|
||
private static $loggers = array();
|
||
public static function register($level = null, $displayErrors = true)
|
||
{
|
||
$handler = new static();
|
||
$handler->setLevel($level);
|
||
$handler->setDisplayErrors($displayErrors);
|
||
ini_set('display_errors', 0);
|
||
set_error_handler(array($handler, 'handle'));
|
||
register_shutdown_function(array($handler, 'handleFatal'));
|
||
$handler->reservedMemory = str_repeat('x', 10240);
|
||
return $handler;
|
||
}
|
||
public function setLevel($level)
|
||
{
|
||
$this->level = null === $level ? error_reporting() : $level;
|
||
}
|
||
public function setDisplayErrors($displayErrors)
|
||
{
|
||
$this->displayErrors = $displayErrors;
|
||
}
|
||
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
|
||
{
|
||
self::$loggers[$channel] = $logger;
|
||
}
|
||
public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
|
||
{
|
||
if (0 === $this->level) {
|
||
return false;
|
||
}
|
||
if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
|
||
if (isset(self::$loggers['deprecation'])) {
|
||
if (version_compare(PHP_VERSION, '5.4', '<')) {
|
||
$stack = array_map(function ($row) {
|
||
unset($row['args']);
|
||
return $row;
|
||
}, array_slice(debug_backtrace(false), 0, 10));
|
||
} else {
|
||
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
|
||
}
|
||
self::$loggers['deprecation']->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack));
|
||
}
|
||
return true;
|
||
}
|
||
if ($this->displayErrors && error_reporting() & $level && $this->level & $level) {
|
||
throw new ContextErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line, $context);
|
||
}
|
||
return false;
|
||
}
|
||
public function handleFatal()
|
||
{
|
||
if (null === ($error = error_get_last())) {
|
||
return;
|
||
}
|
||
unset($this->reservedMemory);
|
||
$type = $error['type'];
|
||
if (0 === $this->level || !in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE))) {
|
||
return;
|
||
}
|
||
if (isset(self::$loggers['emergency'])) {
|
||
$fatal = array('type' => $type, 'file' => $error['file'], 'line' => $error['line']);
|
||
self::$loggers['emergency']->emerg($error['message'], $fatal);
|
||
}
|
||
if (!$this->displayErrors) {
|
||
return;
|
||
}
|
||
$exceptionHandler = set_exception_handler(function () {
|
||
|
||
});
|
||
restore_exception_handler();
|
||
if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) {
|
||
$level = isset($this->levels[$type]) ? $this->levels[$type] : $type;
|
||
$message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']);
|
||
$exception = new FatalErrorException($message, 0, $type, $error['file'], $error['line']);
|
||
$exceptionHandler[0]->handle($exception);
|
||
}
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpKernel\Debug;
|
||
|
||
use Symfony\Component\Debug\ErrorHandler as DebugErrorHandler;
|
||
class ErrorHandler extends DebugErrorHandler
|
||
{
|
||
|
||
}
|
||
namespace Illuminate\Config;
|
||
|
||
use Closure;
|
||
use ArrayAccess;
|
||
use Illuminate\Support\NamespacedItemResolver;
|
||
class Repository extends NamespacedItemResolver implements ArrayAccess
|
||
{
|
||
protected $loader;
|
||
protected $environment;
|
||
protected $items = array();
|
||
protected $packages = array();
|
||
protected $afterLoad = array();
|
||
public function __construct(LoaderInterface $loader, $environment)
|
||
{
|
||
$this->loader = $loader;
|
||
$this->environment = $environment;
|
||
}
|
||
public function has($key)
|
||
{
|
||
$default = microtime(true);
|
||
return $this->get($key, $default) != $default;
|
||
}
|
||
public function hasGroup($key)
|
||
{
|
||
list($namespace, $group, $item) = $this->parseKey($key);
|
||
return $this->loader->exists($group, $namespace);
|
||
}
|
||
public function get($key, $default = null)
|
||
{
|
||
list($namespace, $group, $item) = $this->parseKey($key);
|
||
$collection = $this->getCollection($group, $namespace);
|
||
$this->load($group, $namespace, $collection);
|
||
return array_get($this->items[$collection], $item, $default);
|
||
}
|
||
public function set($key, $value)
|
||
{
|
||
list($namespace, $group, $item) = $this->parseKey($key);
|
||
$collection = $this->getCollection($group, $namespace);
|
||
$this->load($group, $namespace, $collection);
|
||
if (is_null($item)) {
|
||
$this->items[$collection] = $value;
|
||
} else {
|
||
array_set($this->items[$collection], $item, $value);
|
||
}
|
||
}
|
||
protected function load($group, $namespace, $collection)
|
||
{
|
||
$env = $this->environment;
|
||
if (isset($this->items[$collection])) {
|
||
return;
|
||
}
|
||
$items = $this->loader->load($env, $group, $namespace);
|
||
if (isset($this->afterLoad[$namespace])) {
|
||
$items = $this->callAfterLoad($namespace, $group, $items);
|
||
}
|
||
$this->items[$collection] = $items;
|
||
}
|
||
protected function callAfterLoad($namespace, $group, $items)
|
||
{
|
||
$callback = $this->afterLoad[$namespace];
|
||
return call_user_func($callback, $this, $group, $items);
|
||
}
|
||
protected function parseNamespacedSegments($key)
|
||
{
|
||
list($namespace, $item) = explode('::', $key);
|
||
if (in_array($namespace, $this->packages)) {
|
||
return $this->parsePackageSegments($key, $namespace, $item);
|
||
}
|
||
return parent::parseNamespacedSegments($key);
|
||
}
|
||
protected function parsePackageSegments($key, $namespace, $item)
|
||
{
|
||
$itemSegments = explode('.', $item);
|
||
if (!$this->loader->exists($itemSegments[0], $namespace)) {
|
||
return array($namespace, 'config', $item);
|
||
}
|
||
return parent::parseNamespacedSegments($key);
|
||
}
|
||
public function package($package, $hint, $namespace = null)
|
||
{
|
||
$namespace = $this->getPackageNamespace($package, $namespace);
|
||
$this->packages[] = $namespace;
|
||
$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);
|
||
});
|
||
}
|
||
protected function getPackageNamespace($package, $namespace)
|
||
{
|
||
if (is_null($namespace)) {
|
||
list($vendor, $namespace) = explode('/', $package);
|
||
}
|
||
return $namespace;
|
||
}
|
||
public function afterLoading($namespace, Closure $callback)
|
||
{
|
||
$this->afterLoad[$namespace] = $callback;
|
||
}
|
||
protected function getCollection($group, $namespace = null)
|
||
{
|
||
$namespace = $namespace ?: '*';
|
||
return $namespace . '::' . $group;
|
||
}
|
||
public function addNamespace($namespace, $hint)
|
||
{
|
||
return $this->loader->addNamespace($namespace, $hint);
|
||
}
|
||
public function getNamespaces()
|
||
{
|
||
return $this->loader->getNamespaces();
|
||
}
|
||
public function getLoader()
|
||
{
|
||
return $this->loader;
|
||
}
|
||
public function setLoader(LoaderInterface $loader)
|
||
{
|
||
$this->loader = $loader;
|
||
}
|
||
public function getEnvironment()
|
||
{
|
||
return $this->environment;
|
||
}
|
||
public function getAfterLoadCallbacks()
|
||
{
|
||
return $this->afterLoad;
|
||
}
|
||
public function getItems()
|
||
{
|
||
return $this->items;
|
||
}
|
||
public function offsetExists($key)
|
||
{
|
||
return $this->has($key);
|
||
}
|
||
public function offsetGet($key)
|
||
{
|
||
return $this->get($key);
|
||
}
|
||
public function offsetSet($key, $value)
|
||
{
|
||
$this->set($key, $value);
|
||
}
|
||
public function offsetUnset($key)
|
||
{
|
||
$this->set($key, null);
|
||
}
|
||
}
|
||
namespace Illuminate\Support;
|
||
|
||
class NamespacedItemResolver
|
||
{
|
||
protected $parsed = array();
|
||
public function parseKey($key)
|
||
{
|
||
if (isset($this->parsed[$key])) {
|
||
return $this->parsed[$key];
|
||
}
|
||
$segments = explode('.', $key);
|
||
if (strpos($key, '::') === false) {
|
||
$parsed = $this->parseBasicSegments($segments);
|
||
} else {
|
||
$parsed = $this->parseNamespacedSegments($key);
|
||
}
|
||
return $this->parsed[$key] = $parsed;
|
||
}
|
||
protected function parseBasicSegments(array $segments)
|
||
{
|
||
$group = $segments[0];
|
||
if (count($segments) == 1) {
|
||
return array(null, $group, null);
|
||
} else {
|
||
$item = implode('.', array_slice($segments, 1));
|
||
return array(null, $group, $item);
|
||
}
|
||
}
|
||
protected function parseNamespacedSegments($key)
|
||
{
|
||
list($namespace, $item) = explode('::', $key);
|
||
$itemSegments = explode('.', $item);
|
||
$groupAndItem = array_slice($this->parseBasicSegments($itemSegments), 1);
|
||
return array_merge(array($namespace), $groupAndItem);
|
||
}
|
||
public function setParsedKey($key, $parsed)
|
||
{
|
||
$this->parsed[$key] = $parsed;
|
||
}
|
||
}
|
||
namespace Illuminate\Config;
|
||
|
||
use Illuminate\Filesystem\Filesystem;
|
||
class FileLoader implements LoaderInterface
|
||
{
|
||
protected $files;
|
||
protected $defaultPath;
|
||
protected $hints = array();
|
||
protected $exists = array();
|
||
public function __construct(Filesystem $files, $defaultPath)
|
||
{
|
||
$this->files = $files;
|
||
$this->defaultPath = $defaultPath;
|
||
}
|
||
public function load($environment, $group, $namespace = null)
|
||
{
|
||
$items = array();
|
||
$path = $this->getPath($namespace);
|
||
if (is_null($path)) {
|
||
return $items;
|
||
}
|
||
$file = "{$path}/{$group}.php";
|
||
if ($this->files->exists($file)) {
|
||
$items = $this->files->getRequire($file);
|
||
}
|
||
$file = "{$path}/{$environment}/{$group}.php";
|
||
if ($this->files->exists($file)) {
|
||
$items = $this->mergeEnvironment($items, $file);
|
||
}
|
||
return $items;
|
||
}
|
||
protected function mergeEnvironment(array $items, $file)
|
||
{
|
||
return array_replace_recursive($items, $this->files->getRequire($file));
|
||
}
|
||
public function exists($group, $namespace = null)
|
||
{
|
||
$key = $group . $namespace;
|
||
if (isset($this->exists[$key])) {
|
||
return $this->exists[$key];
|
||
}
|
||
$path = $this->getPath($namespace);
|
||
if (is_null($path)) {
|
||
return $this->exists[$key] = false;
|
||
}
|
||
$file = "{$path}/{$group}.php";
|
||
$exists = $this->files->exists($file);
|
||
return $this->exists[$key] = $exists;
|
||
}
|
||
public function cascadePackage($env, $package, $group, $items)
|
||
{
|
||
$file = "packages/{$package}/{$group}.php";
|
||
if ($this->files->exists($path = $this->defaultPath . '/' . $file)) {
|
||
$items = array_merge($items, $this->getRequire($path));
|
||
}
|
||
$path = $this->getPackagePath($env, $package, $group);
|
||
if ($this->files->exists($path)) {
|
||
$items = array_merge($items, $this->getRequire($path));
|
||
}
|
||
return $items;
|
||
}
|
||
protected function getPackagePath($env, $package, $group)
|
||
{
|
||
$file = "packages/{$package}/{$env}/{$group}.php";
|
||
return $this->defaultPath . '/' . $file;
|
||
}
|
||
protected function getPath($namespace)
|
||
{
|
||
if (is_null($namespace)) {
|
||
return $this->defaultPath;
|
||
} elseif (isset($this->hints[$namespace])) {
|
||
return $this->hints[$namespace];
|
||
}
|
||
}
|
||
public function addNamespace($namespace, $hint)
|
||
{
|
||
$this->hints[$namespace] = $hint;
|
||
}
|
||
public function getNamespaces()
|
||
{
|
||
return $this->hints;
|
||
}
|
||
protected function getRequire($path)
|
||
{
|
||
return $this->files->getRequire($path);
|
||
}
|
||
public function getFilesystem()
|
||
{
|
||
return $this->files;
|
||
}
|
||
}
|
||
namespace Illuminate\Config;
|
||
|
||
interface LoaderInterface
|
||
{
|
||
public function load($environment, $group, $namespace = null);
|
||
public function exists($group, $namespace = null);
|
||
public function addNamespace($namespace, $hint);
|
||
public function getNamespaces();
|
||
public function cascadePackage($environment, $package, $group, $items);
|
||
}
|
||
namespace Illuminate\Filesystem;
|
||
|
||
use FilesystemIterator;
|
||
use Symfony\Component\Finder\Finder;
|
||
class FileNotFoundException extends \Exception
|
||
{
|
||
|
||
}
|
||
class Filesystem
|
||
{
|
||
public function exists($path)
|
||
{
|
||
return file_exists($path);
|
||
}
|
||
public function get($path)
|
||
{
|
||
if ($this->isFile($path)) {
|
||
return file_get_contents($path);
|
||
}
|
||
throw new FileNotFoundException("File does not exist at path {$path}");
|
||
}
|
||
public function getRemote($path)
|
||
{
|
||
return file_get_contents($path);
|
||
}
|
||
public function getRequire($path)
|
||
{
|
||
if ($this->isFile($path)) {
|
||
return require $path;
|
||
}
|
||
throw new FileNotFoundException("File does not exist at path {$path}");
|
||
}
|
||
public function requireOnce($file)
|
||
{
|
||
require_once $file;
|
||
}
|
||
public function put($path, $contents)
|
||
{
|
||
return file_put_contents($path, $contents);
|
||
}
|
||
public function append($path, $data)
|
||
{
|
||
return file_put_contents($path, $data, FILE_APPEND);
|
||
}
|
||
public function delete($path)
|
||
{
|
||
return @unlink($path);
|
||
}
|
||
public function move($path, $target)
|
||
{
|
||
return rename($path, $target);
|
||
}
|
||
public function copy($path, $target)
|
||
{
|
||
return copy($path, $target);
|
||
}
|
||
public function extension($path)
|
||
{
|
||
return pathinfo($path, PATHINFO_EXTENSION);
|
||
}
|
||
public function type($path)
|
||
{
|
||
return filetype($path);
|
||
}
|
||
public function size($path)
|
||
{
|
||
return filesize($path);
|
||
}
|
||
public function lastModified($path)
|
||
{
|
||
return filemtime(realpath($path));
|
||
}
|
||
public function isDirectory($directory)
|
||
{
|
||
return is_dir($directory);
|
||
}
|
||
public function isWritable($path)
|
||
{
|
||
return is_writable($path);
|
||
}
|
||
public function isFile($file)
|
||
{
|
||
return is_file($file);
|
||
}
|
||
public function glob($pattern, $flags = 0)
|
||
{
|
||
return glob($pattern, $flags);
|
||
}
|
||
public function files($directory)
|
||
{
|
||
$glob = glob($directory . '/*');
|
||
if ($glob === false) {
|
||
return array();
|
||
}
|
||
return array_filter($glob, function ($file) {
|
||
return filetype($file) == 'file';
|
||
});
|
||
}
|
||
public function allFiles($directory)
|
||
{
|
||
return iterator_to_array(Finder::create()->files()->in($directory), false);
|
||
}
|
||
public function directories($directory)
|
||
{
|
||
$directories = array();
|
||
foreach (Finder::create()->in($directory)->directories()->depth(0) as $dir) {
|
||
$directories[] = $dir->getRealPath();
|
||
}
|
||
return $directories;
|
||
}
|
||
public function makeDirectory($path, $mode = 511, $recursive = false)
|
||
{
|
||
return mkdir($path, $mode, $recursive);
|
||
}
|
||
public function copyDirectory($directory, $destination, $options = null)
|
||
{
|
||
if (!$this->isDirectory($directory)) {
|
||
return false;
|
||
}
|
||
$options = $options ?: FilesystemIterator::SKIP_DOTS;
|
||
if (!$this->isDirectory($destination)) {
|
||
$this->makeDirectory($destination, 511, true);
|
||
}
|
||
$items = new FilesystemIterator($directory, $options);
|
||
foreach ($items as $item) {
|
||
$target = $destination . '/' . $item->getBasename();
|
||
if ($item->isDir()) {
|
||
$path = $item->getRealPath();
|
||
if (!$this->copyDirectory($path, $target, $options)) {
|
||
return false;
|
||
}
|
||
} else {
|
||
if (!$this->copy($item->getRealPath(), $target)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
public function deleteDirectory($directory, $preserve = false)
|
||
{
|
||
if (!$this->isDirectory($directory)) {
|
||
return;
|
||
}
|
||
$items = new FilesystemIterator($directory);
|
||
foreach ($items as $item) {
|
||
if ($item->isDir()) {
|
||
$this->deleteDirectory($item->getRealPath());
|
||
} else {
|
||
$this->delete($item->getRealPath());
|
||
}
|
||
}
|
||
if (!$preserve) {
|
||
@rmdir($directory);
|
||
}
|
||
}
|
||
public function cleanDirectory($directory)
|
||
{
|
||
return $this->deleteDirectory($directory, true);
|
||
}
|
||
}
|
||
namespace Illuminate\Foundation;
|
||
|
||
class AliasLoader
|
||
{
|
||
protected $aliases;
|
||
protected $registered = false;
|
||
protected static $instance;
|
||
public function __construct(array $aliases = array())
|
||
{
|
||
$this->aliases = $aliases;
|
||
}
|
||
public static function getInstance(array $aliases = array())
|
||
{
|
||
if (is_null(static::$instance)) {
|
||
static::$instance = new static($aliases);
|
||
}
|
||
$aliases = array_merge(static::$instance->getAliases(), $aliases);
|
||
static::$instance->setAliases($aliases);
|
||
return static::$instance;
|
||
}
|
||
public function load($alias)
|
||
{
|
||
if (isset($this->aliases[$alias])) {
|
||
return class_alias($this->aliases[$alias], $alias);
|
||
}
|
||
}
|
||
public function alias($class, $alias)
|
||
{
|
||
$this->aliases[$class] = $alias;
|
||
}
|
||
public function register()
|
||
{
|
||
if (!$this->registered) {
|
||
$this->prependToLoaderStack();
|
||
$this->registered = true;
|
||
}
|
||
}
|
||
protected function prependToLoaderStack()
|
||
{
|
||
spl_autoload_register(array($this, 'load'), true, true);
|
||
}
|
||
public function getAliases()
|
||
{
|
||
return $this->aliases;
|
||
}
|
||
public function setAliases(array $aliases)
|
||
{
|
||
$this->aliases = $aliases;
|
||
}
|
||
public function isRegistered()
|
||
{
|
||
return $this->registered;
|
||
}
|
||
public function setRegistered($value)
|
||
{
|
||
$this->registered = $value;
|
||
}
|
||
public static function setInstance($loader)
|
||
{
|
||
static::$instance = $loader;
|
||
}
|
||
}
|
||
namespace Illuminate\Foundation;
|
||
|
||
use Illuminate\Filesystem\Filesystem;
|
||
class ProviderRepository
|
||
{
|
||
protected $files;
|
||
protected $manifestPath;
|
||
public function __construct(Filesystem $files, $manifestPath)
|
||
{
|
||
$this->files = $files;
|
||
$this->manifestPath = $manifestPath;
|
||
}
|
||
public function load(Application $app, array $providers)
|
||
{
|
||
$manifest = $this->loadManifest();
|
||
if ($this->shouldRecompile($manifest, $providers)) {
|
||
$manifest = $this->compileManifest($app, $providers);
|
||
}
|
||
if ($app->runningInConsole()) {
|
||
$manifest['eager'] = $manifest['providers'];
|
||
}
|
||
foreach ($manifest['eager'] as $provider) {
|
||
$app->register($this->createProvider($app, $provider));
|
||
}
|
||
$app->setDeferredServices($manifest['deferred']);
|
||
}
|
||
protected function compileManifest(Application $app, $providers)
|
||
{
|
||
$manifest = $this->freshManifest($providers);
|
||
foreach ($providers as $provider) {
|
||
$instance = $this->createProvider($app, $provider);
|
||
if ($instance->isDeferred()) {
|
||
foreach ($instance->provides() as $service) {
|
||
$manifest['deferred'][$service] = $provider;
|
||
}
|
||
} else {
|
||
$manifest['eager'][] = $provider;
|
||
}
|
||
}
|
||
return $this->writeManifest($manifest);
|
||
}
|
||
public function createProvider(Application $app, $provider)
|
||
{
|
||
return new $provider($app);
|
||
}
|
||
public function shouldRecompile($manifest, $providers)
|
||
{
|
||
return is_null($manifest) or $manifest['providers'] != $providers;
|
||
}
|
||
public function loadManifest()
|
||
{
|
||
$path = $this->manifestPath . '/services.json';
|
||
if ($this->files->exists($path)) {
|
||
return json_decode($this->files->get($path), true);
|
||
}
|
||
}
|
||
public function writeManifest($manifest)
|
||
{
|
||
$path = $this->manifestPath . '/services.json';
|
||
$this->files->put($path, json_encode($manifest));
|
||
return $manifest;
|
||
}
|
||
protected function getManifestPath($app)
|
||
{
|
||
return $this->manifestPath;
|
||
}
|
||
protected function freshManifest(array $providers)
|
||
{
|
||
list($eager, $deferred) = array(array(), array());
|
||
return compact('providers', 'eager', 'deferred');
|
||
}
|
||
public function getFilesystem()
|
||
{
|
||
return $this->files;
|
||
}
|
||
}
|
||
namespace Illuminate\Cookie;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class CookieServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->app['cookie'] = $this->app->share(function ($app) {
|
||
$cookies = new CookieJar($app['request'], $app['encrypter']);
|
||
$config = $app['config']['session'];
|
||
return $cookies->setDefaultPathAndDomain($config['path'], $config['domain']);
|
||
});
|
||
}
|
||
}
|
||
namespace Illuminate\Database;
|
||
|
||
use Illuminate\Database\Eloquent\Model;
|
||
use Illuminate\Support\ServiceProvider;
|
||
use Illuminate\Database\Connectors\ConnectionFactory;
|
||
class DatabaseServiceProvider extends ServiceProvider
|
||
{
|
||
public function boot()
|
||
{
|
||
Model::setConnectionResolver($this->app['db']);
|
||
Model::setEventDispatcher($this->app['events']);
|
||
}
|
||
public function register()
|
||
{
|
||
$this->app['db.factory'] = $this->app->share(function ($app) {
|
||
return new ConnectionFactory($app);
|
||
});
|
||
$this->app['db'] = $this->app->share(function ($app) {
|
||
return new DatabaseManager($app, $app['db.factory']);
|
||
});
|
||
}
|
||
}
|
||
namespace Illuminate\Encryption;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class EncryptionServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->app['encrypter'] = $this->app->share(function ($app) {
|
||
return new Encrypter($app['config']['app.key']);
|
||
});
|
||
}
|
||
}
|
||
namespace Illuminate\Filesystem;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class FilesystemServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->app['files'] = $this->app->share(function () {
|
||
return new Filesystem();
|
||
});
|
||
}
|
||
}
|
||
namespace Illuminate\Session;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class SessionServiceProvider extends ServiceProvider
|
||
{
|
||
public function boot()
|
||
{
|
||
$this->registerSessionEvents();
|
||
}
|
||
public function register()
|
||
{
|
||
$this->setupDefaultDriver();
|
||
$this->registerSessionManager();
|
||
$this->registerSessionDriver();
|
||
}
|
||
protected function setupDefaultDriver()
|
||
{
|
||
if ($this->app->runningInConsole()) {
|
||
$this->app['config']['session.driver'] = 'array';
|
||
}
|
||
}
|
||
protected function registerSessionManager()
|
||
{
|
||
$this->app['session.manager'] = $this->app->share(function ($app) {
|
||
return new SessionManager($app);
|
||
});
|
||
}
|
||
protected function registerSessionDriver()
|
||
{
|
||
$this->app['session'] = $this->app->share(function ($app) {
|
||
$manager = $app['session.manager'];
|
||
return $manager->driver();
|
||
});
|
||
}
|
||
protected function registerSessionEvents()
|
||
{
|
||
$app = $this->app;
|
||
$config = $app['config']['session'];
|
||
if (!is_null($config['driver'])) {
|
||
$this->registerBootingEvent();
|
||
$this->registerCloseEvent();
|
||
}
|
||
}
|
||
protected function registerBootingEvent()
|
||
{
|
||
$app = $this->app;
|
||
$this->app->booting(function ($app) use($app) {
|
||
$app['session']->start();
|
||
});
|
||
}
|
||
protected function registerCloseEvent()
|
||
{
|
||
if ($this->getDriver() == 'array') {
|
||
return;
|
||
}
|
||
$this->registerCookieToucher();
|
||
$app = $this->app;
|
||
$this->app->close(function () use($app) {
|
||
$app['session']->save();
|
||
});
|
||
}
|
||
protected function registerCookieToucher()
|
||
{
|
||
$me = $this;
|
||
$this->app->close(function () use($me) {
|
||
if (!headers_sent()) {
|
||
$me->touchSessionCookie();
|
||
}
|
||
});
|
||
}
|
||
public function touchSessionCookie()
|
||
{
|
||
$config = $this->app['config']['session'];
|
||
$expire = $this->getExpireTime($config);
|
||
setcookie($config['cookie'], session_id(), $expire, $config['path'], $config['domain']);
|
||
}
|
||
protected function getExpireTime($config)
|
||
{
|
||
return $config['lifetime'] == 0 ? 0 : time() + $config['lifetime'] * 60;
|
||
}
|
||
protected function getDriver()
|
||
{
|
||
return $this->app['config']['session.driver'];
|
||
}
|
||
}
|
||
namespace Illuminate\View;
|
||
|
||
use Illuminate\Support\MessageBag;
|
||
use Illuminate\View\Engines\PhpEngine;
|
||
use Illuminate\Support\ServiceProvider;
|
||
use Illuminate\View\Engines\BladeEngine;
|
||
use Illuminate\View\Engines\CompilerEngine;
|
||
use Illuminate\View\Engines\EngineResolver;
|
||
use Illuminate\View\Compilers\BladeCompiler;
|
||
class ViewServiceProvider extends ServiceProvider
|
||
{
|
||
public function register()
|
||
{
|
||
$this->registerEngineResolver();
|
||
$this->registerViewFinder();
|
||
$this->registerEnvironment();
|
||
$this->registerSessionBinder();
|
||
}
|
||
public function registerEngineResolver()
|
||
{
|
||
list($me, $app) = array($this, $this->app);
|
||
$app['view.engine.resolver'] = $app->share(function ($app) use($me) {
|
||
$resolver = new EngineResolver();
|
||
foreach (array('php', 'blade') as $engine) {
|
||
$me->{'register' . ucfirst($engine) . 'Engine'}($resolver);
|
||
}
|
||
return $resolver;
|
||
});
|
||
}
|
||
public function registerPhpEngine($resolver)
|
||
{
|
||
$resolver->register('php', function () {
|
||
return new PhpEngine();
|
||
});
|
||
}
|
||
public function registerBladeEngine($resolver)
|
||
{
|
||
$app = $this->app;
|
||
$resolver->register('blade', function () use($app) {
|
||
$cache = $app['path.storage'] . '/views';
|
||
$compiler = new BladeCompiler($app['files'], $cache);
|
||
return new CompilerEngine($compiler, $app['files']);
|
||
});
|
||
}
|
||
public function registerViewFinder()
|
||
{
|
||
$this->app['view.finder'] = $this->app->share(function ($app) {
|
||
$paths = $app['config']['view.paths'];
|
||
return new FileViewFinder($app['files'], $paths);
|
||
});
|
||
}
|
||
public function registerEnvironment()
|
||
{
|
||
$this->app['view'] = $this->app->share(function ($app) {
|
||
$resolver = $app['view.engine.resolver'];
|
||
$finder = $app['view.finder'];
|
||
$env = new Environment($resolver, $finder, $app['events']);
|
||
$env->setContainer($app);
|
||
$env->share('app', $app);
|
||
return $env;
|
||
});
|
||
}
|
||
protected function registerSessionBinder()
|
||
{
|
||
list($app, $me) = array($this->app, $this);
|
||
$app->booted(function () use($app, $me) {
|
||
if ($me->sessionHasErrors($app)) {
|
||
$errors = $app['session']->get('errors');
|
||
$app['view']->share('errors', $errors);
|
||
} else {
|
||
$app['view']->share('errors', new MessageBag());
|
||
}
|
||
});
|
||
}
|
||
public function sessionHasErrors($app)
|
||
{
|
||
$config = $app['config']['session'];
|
||
if (isset($app['session']) and !is_null($config['driver'])) {
|
||
return $app['session']->has('errors');
|
||
}
|
||
}
|
||
}
|
||
namespace Illuminate\Routing;
|
||
|
||
use Closure;
|
||
use Illuminate\Http\Response;
|
||
use Illuminate\Container\Container;
|
||
use Symfony\Component\HttpFoundation\Request;
|
||
use Symfony\Component\Routing\RequestContext;
|
||
use Illuminate\Routing\Controllers\Inspector;
|
||
use Symfony\Component\Routing\RouteCollection;
|
||
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||
use Symfony\Component\Routing\Exception\ExceptionInterface;
|
||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||
class Router
|
||
{
|
||
protected $routes;
|
||
protected $filters = array();
|
||
protected $patternFilters = array();
|
||
protected $globalFilters = array();
|
||
protected $groupStack = array();
|
||
protected $container;
|
||
protected $inspector;
|
||
protected $patterns = array();
|
||
protected $binders = array();
|
||
protected $currentRequest;
|
||
protected $currentRoute;
|
||
protected $runFilters = true;
|
||
protected $resourceDefaults = array('index', 'create', 'store', 'show', 'edit', 'update', 'destroy');
|
||
public function __construct(Container $container = null)
|
||
{
|
||
$this->container = $container;
|
||
$this->routes = new RouteCollection();
|
||
$this->bind('_missing', function ($v) {
|
||
return explode('/', $v);
|
||
});
|
||
}
|
||
public function get($pattern, $action)
|
||
{
|
||
return $this->createRoute('get', $pattern, $action);
|
||
}
|
||
public function post($pattern, $action)
|
||
{
|
||
return $this->createRoute('post', $pattern, $action);
|
||
}
|
||
public function put($pattern, $action)
|
||
{
|
||
return $this->createRoute('put', $pattern, $action);
|
||
}
|
||
public function patch($pattern, $action)
|
||
{
|
||
return $this->createRoute('patch', $pattern, $action);
|
||
}
|
||
public function delete($pattern, $action)
|
||
{
|
||
return $this->createRoute('delete', $pattern, $action);
|
||
}
|
||
public function options($pattern, $action)
|
||
{
|
||
return $this->createRoute('options', $pattern, $action);
|
||
}
|
||
public function match($method, $pattern, $action)
|
||
{
|
||
return $this->createRoute($method, $pattern, $action);
|
||
}
|
||
public function any($pattern, $action)
|
||
{
|
||
return $this->createRoute('get|post|put|patch|delete', $pattern, $action);
|
||
}
|
||
public function controllers(array $controllers)
|
||
{
|
||
foreach ($controllers as $uri => $name) {
|
||
$this->controller($uri, $name);
|
||
}
|
||
}
|
||
public function controller($uri, $controller, $names = array())
|
||
{
|
||
$routable = $this->getInspector()->getRoutable($controller, $uri);
|
||
foreach ($routable as $method => $routes) {
|
||
foreach ($routes as $route) {
|
||
$this->registerInspected($route, $controller, $method, $names);
|
||
}
|
||
}
|
||
$this->addFallthroughRoute($controller, $uri);
|
||
}
|
||
protected function registerInspected($route, $controller, $method, &$names)
|
||
{
|
||
$action = array('uses' => $controller . '@' . $method);
|
||
$action['as'] = array_pull($names, $method);
|
||
$this->{$route['verb']}($route['uri'], $action);
|
||
}
|
||
protected function addFallthroughRoute($controller, $uri)
|
||
{
|
||
$missing = $this->any($uri . '/{_missing}', $controller . '@missingMethod');
|
||
$missing->where('_missing', '(.*)');
|
||
}
|
||
public function resource($resource, $controller, array $options = array())
|
||
{
|
||
if (str_contains($resource, '/')) {
|
||
$this->prefixedResource($resource, $controller, $options);
|
||
return;
|
||
}
|
||
$base = $this->getBaseResource($resource);
|
||
$defaults = $this->resourceDefaults;
|
||
foreach ($this->getResourceMethods($defaults, $options) as $method) {
|
||
$this->{'addResource' . ucfirst($method)}($resource, $base, $controller);
|
||
}
|
||
}
|
||
protected function prefixedResource($resource, $controller, array $options)
|
||
{
|
||
list($resource, $prefix) = $this->extractResourcePrefix($resource);
|
||
$me = $this;
|
||
return $this->group(array('prefix' => $prefix), function () use($me, $resource, $controller, $options) {
|
||
$me->resource($resource, $controller, $options);
|
||
});
|
||
}
|
||
protected function extractResourcePrefix($resource)
|
||
{
|
||
$segments = explode('/', $resource);
|
||
return array($segments[count($segments) - 1], implode('/', array_slice($segments, 0, -1)));
|
||
}
|
||
protected function getResourceMethods($defaults, $options)
|
||
{
|
||
if (isset($options['only'])) {
|
||
return array_intersect($defaults, $options['only']);
|
||
} elseif (isset($options['except'])) {
|
||
return array_diff($defaults, $options['except']);
|
||
}
|
||
return $defaults;
|
||
}
|
||
protected function addResourceIndex($name, $base, $controller)
|
||
{
|
||
$action = $this->getResourceAction($name, $controller, 'index');
|
||
return $this->get($this->getResourceUri($name), $action);
|
||
}
|
||
protected function addResourceCreate($name, $base, $controller)
|
||
{
|
||
$action = $this->getResourceAction($name, $controller, 'create');
|
||
return $this->get($this->getResourceUri($name) . '/create', $action);
|
||
}
|
||
protected function addResourceStore($name, $base, $controller)
|
||
{
|
||
$action = $this->getResourceAction($name, $controller, 'store');
|
||
return $this->post($this->getResourceUri($name), $action);
|
||
}
|
||
protected function addResourceShow($name, $base, $controller)
|
||
{
|
||
$uri = $this->getResourceUri($name) . '/{' . $base . '}';
|
||
return $this->get($uri, $this->getResourceAction($name, $controller, 'show'));
|
||
}
|
||
protected function addResourceEdit($name, $base, $controller)
|
||
{
|
||
$uri = $this->getResourceUri($name) . '/{' . $base . '}/edit';
|
||
return $this->get($uri, $this->getResourceAction($name, $controller, 'edit'));
|
||
}
|
||
protected function addResourceUpdate($name, $base, $controller)
|
||
{
|
||
$this->addPutResourceUpdate($name, $base, $controller);
|
||
return $this->addPatchResourceUpdate($name, $base, $controller);
|
||
}
|
||
protected function addPutResourceUpdate($name, $base, $controller)
|
||
{
|
||
$uri = $this->getResourceUri($name) . '/{' . $base . '}';
|
||
return $this->put($uri, $this->getResourceAction($name, $controller, 'update'));
|
||
}
|
||
protected function addPatchResourceUpdate($name, $base, $controller)
|
||
{
|
||
$uri = $this->getResourceUri($name) . '/{' . $base . '}';
|
||
$this->patch($uri, $controller . '@update');
|
||
}
|
||
protected function addResourceDestroy($name, $base, $controller)
|
||
{
|
||
$uri = $this->getResourceUri($name) . '/{' . $base . '}';
|
||
return $this->delete($uri, $this->getResourceAction($name, $controller, 'destroy'));
|
||
}
|
||
public function getResourceUri($resource)
|
||
{
|
||
if (!str_contains($resource, '.')) {
|
||
return $resource;
|
||
}
|
||
$segments = explode('.', $resource);
|
||
$nested = $this->getNestedResourceUri($segments);
|
||
$last = $this->getResourceWildcard(last($segments));
|
||
return str_replace('/{' . $last . '}', '', $nested);
|
||
}
|
||
protected function getNestedResourceUri(array $segments)
|
||
{
|
||
$me = $this;
|
||
return implode('/', array_map(function ($s) use($me) {
|
||
return $s . '/{' . $me->getResourceWildcard($s) . '}';
|
||
}, $segments));
|
||
}
|
||
protected function getResourceAction($resource, $controller, $method)
|
||
{
|
||
$name = $resource . '.' . $method;
|
||
$name = $this->getResourceName($resource, $method);
|
||
return array('as' => $name, 'uses' => $controller . '@' . $method);
|
||
}
|
||
protected function getResourceName($resource, $method)
|
||
{
|
||
if (count($this->groupStack) == 0) {
|
||
return $resource . '.' . $method;
|
||
}
|
||
return $this->getResourcePrefix($resource, $method);
|
||
}
|
||
protected function getResourcePrefix($resource, $method)
|
||
{
|
||
$prefix = str_replace('/', '.', $this->getGroupPrefix());
|
||
if ($prefix != '') {
|
||
$prefix .= '.';
|
||
}
|
||
return "{$prefix}{$resource}.{$method}";
|
||
}
|
||
protected function getBaseResource($resource)
|
||
{
|
||
$segments = explode('.', $resource);
|
||
return $this->getResourceWildcard($segments[count($segments) - 1]);
|
||
}
|
||
public function getResourceWildcard($value)
|
||
{
|
||
return str_replace('-', '_', $value);
|
||
}
|
||
public function group(array $attributes, Closure $callback)
|
||
{
|
||
$this->updateGroupStack($attributes);
|
||
call_user_func($callback);
|
||
array_pop($this->groupStack);
|
||
}
|
||
protected function updateGroupStack(array $attributes)
|
||
{
|
||
if (count($this->groupStack) > 0) {
|
||
$last = $this->groupStack[count($this->groupStack) - 1];
|
||
$this->groupStack[] = array_merge_recursive($last, $attributes);
|
||
} else {
|
||
$this->groupStack[] = $attributes;
|
||
}
|
||
}
|
||
protected function createRoute($method, $pattern, $action)
|
||
{
|
||
if (!is_array($action)) {
|
||
$action = $this->parseAction($action);
|
||
}
|
||
$groupCount = count($this->groupStack);
|
||
if ($groupCount > 0) {
|
||
$index = $groupCount - 1;
|
||
$action = $this->mergeGroup($action, $index);
|
||
}
|
||
list($pattern, $optional) = $this->getOptional($pattern);
|
||
if (isset($action['prefix'])) {
|
||
$prefix = $action['prefix'];
|
||
$pattern = $this->addPrefix($pattern, $prefix);
|
||
}
|
||
$route = with(new Route($pattern))->setOptions(array('_call' => $this->getCallback($action)))->setRouter($this)->addRequirements($this->patterns);
|
||
$route->setRequirement('_method', $method);
|
||
$this->setAttributes($route, $action, $optional);
|
||
$name = $this->getName($method, $pattern, $action);
|
||
$this->routes->add($name, $route);
|
||
return $route;
|
||
}
|
||
protected function parseAction($action)
|
||
{
|
||
if ($action instanceof Closure) {
|
||
return array($action);
|
||
} elseif (is_string($action)) {
|
||
return array('uses' => $action);
|
||
}
|
||
throw new \InvalidArgumentException('Unroutable action.');
|
||
}
|
||
protected function mergeGroup($action, $index)
|
||
{
|
||
$prefix = $this->mergeGroupPrefix($action);
|
||
$action = array_merge_recursive($this->groupStack[$index], $action);
|
||
if ($prefix != '') {
|
||
$action['prefix'] = $prefix;
|
||
}
|
||
return $action;
|
||
}
|
||
protected function getGroupPrefix()
|
||
{
|
||
if (count($this->groupStack) > 0) {
|
||
$group = $this->groupStack[count($this->groupStack) - 1];
|
||
if (isset($group['prefix'])) {
|
||
if (is_array($group['prefix'])) {
|
||
return implode('/', $group['prefix']);
|
||
}
|
||
return $group['prefix'];
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
protected function mergeGroupPrefix($action)
|
||
{
|
||
$prefix = isset($action['prefix']) ? $action['prefix'] : '';
|
||
return trim($this->getGroupPrefix() . '/' . $prefix, '/');
|
||
}
|
||
protected function addPrefix($pattern, $prefix)
|
||
{
|
||
$pattern = trim($prefix, '/') . '/' . ltrim($pattern, '/');
|
||
return trim($pattern, '/');
|
||
}
|
||
protected function setAttributes(Route $route, $action, $optional)
|
||
{
|
||
if (in_array('https', $action)) {
|
||
$route->setRequirement('_scheme', 'https');
|
||
}
|
||
if (in_array('http', $action)) {
|
||
$route->setRequirement('_scheme', 'http');
|
||
}
|
||
if (isset($action['before'])) {
|
||
$route->setBeforeFilters($action['before']);
|
||
}
|
||
if (isset($action['after'])) {
|
||
$route->setAfterFilters($action['after']);
|
||
}
|
||
if (isset($action['uses'])) {
|
||
$route->setOption('_uses', $action['uses']);
|
||
}
|
||
if (isset($action['domain'])) {
|
||
$route->setHost($action['domain']);
|
||
}
|
||
foreach ($optional as $key) {
|
||
$route->setDefault($key, null);
|
||
}
|
||
}
|
||
protected function getOptional($pattern)
|
||
{
|
||
$optional = array();
|
||
preg_match_all('#\\{(\\w+)\\?\\}#', $pattern, $matches);
|
||
foreach ($matches[0] as $key => $value) {
|
||
$optional[] = $name = $matches[1][$key];
|
||
$pattern = str_replace($value, '{' . $name . '}', $pattern);
|
||
}
|
||
return array($pattern, $optional);
|
||
}
|
||
protected function getName($method, $pattern, array $action)
|
||
{
|
||
if (isset($action['as'])) {
|
||
return $action['as'];
|
||
}
|
||
$domain = isset($action['domain']) ? $action['domain'] . ' ' : '';
|
||
return "{$domain}{$method} {$pattern}";
|
||
}
|
||
protected function getCallback(array $action)
|
||
{
|
||
foreach ($action as $key => $attribute) {
|
||
if ($key === 'uses') {
|
||
return $this->createControllerCallback($attribute);
|
||
} elseif ($attribute instanceof Closure) {
|
||
return $attribute;
|
||
}
|
||
}
|
||
}
|
||
protected function createControllerCallback($attribute)
|
||
{
|
||
$ioc = $this->container;
|
||
$me = $this;
|
||
return function () use($me, $ioc, $attribute) {
|
||
list($controller, $method) = explode('@', $attribute);
|
||
$route = $me->getCurrentRoute();
|
||
$args = array_values($route->getParametersWithoutDefaults());
|
||
$instance = $ioc->make($controller);
|
||
return $instance->callAction($ioc, $me, $method, $args);
|
||
};
|
||
}
|
||
public function dispatch(Request $request)
|
||
{
|
||
$this->currentRequest = $request;
|
||
$response = $this->callGlobalFilter($request, 'before');
|
||
if (!is_null($response)) {
|
||
$response = $this->prepare($response, $request);
|
||
} else {
|
||
$this->currentRoute = $route = $this->findRoute($request);
|
||
$response = $route->run($request);
|
||
}
|
||
$this->callAfterFilter($request, $response);
|
||
return $response;
|
||
}
|
||
protected function findRoute(Request $request)
|
||
{
|
||
try {
|
||
$path = $request->getPathInfo();
|
||
$parameters = $this->getUrlMatcher($request)->match($path);
|
||
} catch (ExceptionInterface $e) {
|
||
$this->handleRoutingException($e);
|
||
}
|
||
$route = $this->routes->get($parameters['_route']);
|
||
$route->setParameters($parameters);
|
||
return $route;
|
||
}
|
||
public function before($callback)
|
||
{
|
||
$this->globalFilters['before'][] = $this->buildGlobalFilter($callback);
|
||
}
|
||
public function after($callback)
|
||
{
|
||
$this->globalFilters['after'][] = $this->buildGlobalFilter($callback);
|
||
}
|
||
public function close($callback)
|
||
{
|
||
$this->globalFilters['close'][] = $this->buildGlobalFilter($callback);
|
||
}
|
||
public function finish($callback)
|
||
{
|
||
$this->globalFilters['finish'][] = $this->buildGlobalFilter($callback);
|
||
}
|
||
protected function buildGlobalFilter($callback)
|
||
{
|
||
if (is_string($callback)) {
|
||
$container = $this->container;
|
||
return function () use($callback, $container) {
|
||
$callable = array($container->make($callback), 'filter');
|
||
return call_user_func_array($callable, func_get_args());
|
||
};
|
||
} else {
|
||
return $callback;
|
||
}
|
||
}
|
||
public function filter($name, $callback)
|
||
{
|
||
$this->filters[$name] = $callback;
|
||
}
|
||
public function getFilter($name)
|
||
{
|
||
if (array_key_exists($name, $this->filters)) {
|
||
$filter = $this->filters[$name];
|
||
if (is_string($filter)) {
|
||
return $this->getClassBasedFilter($filter);
|
||
}
|
||
return $filter;
|
||
}
|
||
}
|
||
protected function getClassBasedFilter($filter)
|
||
{
|
||
if (str_contains($filter, '@')) {
|
||
list($class, $method) = explode('@', $filter);
|
||
return array($this->container->make($class), $method);
|
||
}
|
||
return array($this->container->make($filter), 'filter');
|
||
}
|
||
public function when($pattern, $names, $methods = null)
|
||
{
|
||
foreach ((array) $names as $name) {
|
||
if (!is_null($methods)) {
|
||
$methods = array_change_key_case((array) $methods);
|
||
}
|
||
$this->patternFilters[$pattern][] = compact('name', 'methods');
|
||
}
|
||
}
|
||
public function findPatternFilters(Request $request)
|
||
{
|
||
$results = array();
|
||
foreach ($this->patternFilters as $pattern => $filters) {
|
||
if (str_is('/' . $pattern, $request->getPathInfo())) {
|
||
$merge = $this->filterPatternsByMethod($request, $filters);
|
||
$results = array_merge($results, $merge);
|
||
}
|
||
}
|
||
return $results;
|
||
}
|
||
protected function filterPatternsByMethod(Request $request, $filters)
|
||
{
|
||
$results = array();
|
||
$method = strtolower($request->getMethod());
|
||
foreach ($filters as $filter) {
|
||
if (is_null($filter['methods']) or in_array($method, $filter['methods'])) {
|
||
$results[] = $filter['name'];
|
||
}
|
||
}
|
||
return $results;
|
||
}
|
||
protected function callAfterFilter(Request $request, SymfonyResponse $response)
|
||
{
|
||
$this->callGlobalFilter($request, 'after', array($response));
|
||
}
|
||
public function callFinishFilter(Request $request, SymfonyResponse $response)
|
||
{
|
||
$this->callGlobalFilter($request, 'finish', array($response));
|
||
}
|
||
public function callCloseFilter(Request $request, SymfonyResponse $response)
|
||
{
|
||
$this->callGlobalFilter($request, 'close', array($response));
|
||
}
|
||
protected function callGlobalFilter(Request $request, $name, array $parameters = array())
|
||
{
|
||
if (!$this->filtersEnabled()) {
|
||
return;
|
||
}
|
||
array_unshift($parameters, $request);
|
||
if (isset($this->globalFilters[$name])) {
|
||
foreach ($this->globalFilters[$name] as $filter) {
|
||
$response = call_user_func_array($filter, $parameters);
|
||
if (!is_null($response)) {
|
||
return $response;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
public function pattern($key, $pattern)
|
||
{
|
||
$this->patterns[$key] = $pattern;
|
||
}
|
||
public function model($key, $class, Closure $callback = null)
|
||
{
|
||
return $this->bind($key, function ($value) use($class, $callback) {
|
||
if (is_null($value)) {
|
||
return null;
|
||
}
|
||
if (!is_null($model = with(new $class())->find($value))) {
|
||
return $model;
|
||
}
|
||
if ($callback instanceof Closure) {
|
||
return call_user_func($callback);
|
||
}
|
||
throw new NotFoundHttpException();
|
||
});
|
||
}
|
||
public function bind($key, $binder)
|
||
{
|
||
$this->binders[str_replace('-', '_', $key)] = $binder;
|
||
}
|
||
public function hasBinder($key)
|
||
{
|
||
return isset($this->binders[$key]);
|
||
}
|
||
public function performBinding($key, $value, $route)
|
||
{
|
||
return call_user_func($this->binders[$key], $value, $route);
|
||
}
|
||
public function prepare($value, Request $request)
|
||
{
|
||
if (!$value instanceof SymfonyResponse) {
|
||
$value = new Response($value);
|
||
}
|
||
return $value->prepare($request);
|
||
}
|
||
protected function handleRoutingException(\Exception $e)
|
||
{
|
||
if ($e instanceof ResourceNotFoundException) {
|
||
throw new NotFoundHttpException($e->getMessage());
|
||
} elseif ($e instanceof MethodNotAllowedException) {
|
||
$allowed = $e->getAllowedMethods();
|
||
throw new MethodNotAllowedHttpException($allowed, $e->getMessage());
|
||
}
|
||
}
|
||
public function currentRouteName()
|
||
{
|
||
foreach ($this->routes->all() as $name => $route) {
|
||
if ($route === $this->currentRoute) {
|
||
return $name;
|
||
}
|
||
}
|
||
}
|
||
public function currentRouteNamed($name)
|
||
{
|
||
$route = $this->routes->get($name);
|
||
return !is_null($route) and $route === $this->currentRoute;
|
||
}
|
||
public function currentRouteAction()
|
||
{
|
||
$currentRoute = $this->currentRoute;
|
||
if (!is_null($currentRoute)) {
|
||
return $currentRoute->getOption('_uses');
|
||
}
|
||
}
|
||
public function currentRouteUses($action)
|
||
{
|
||
return $this->currentRouteAction() === $action;
|
||
}
|
||
public function filtersEnabled()
|
||
{
|
||
return $this->runFilters;
|
||
}
|
||
public function enableFilters()
|
||
{
|
||
$this->runFilters = true;
|
||
}
|
||
public function disableFilters()
|
||
{
|
||
$this->runFilters = false;
|
||
}
|
||
public function getRoutes()
|
||
{
|
||
return $this->routes;
|
||
}
|
||
public function getRequest()
|
||
{
|
||
return $this->currentRequest;
|
||
}
|
||
public function getCurrentRoute()
|
||
{
|
||
return $this->currentRoute;
|
||
}
|
||
public function setCurrentRoute(Route $route)
|
||
{
|
||
$this->currentRoute = $route;
|
||
}
|
||
public function getFilters()
|
||
{
|
||
return $this->filters;
|
||
}
|
||
public function getGlobalFilters()
|
||
{
|
||
return $this->globalFilters;
|
||
}
|
||
protected function getUrlMatcher(Request $request)
|
||
{
|
||
$context = new RequestContext();
|
||
$context->fromRequest($request);
|
||
return new UrlMatcher($this->routes, $context);
|
||
}
|
||
public function getInspector()
|
||
{
|
||
return $this->inspector ?: new Controllers\Inspector();
|
||
}
|
||
public function setInspector(Inspector $inspector)
|
||
{
|
||
$this->inspector = $inspector;
|
||
}
|
||
public function getContainer()
|
||
{
|
||
return $this->container;
|
||
}
|
||
public function setContainer(Container $container)
|
||
{
|
||
$this->container = $container;
|
||
}
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||
class RouteCollection implements \IteratorAggregate, \Countable
|
||
{
|
||
private $routes = array();
|
||
private $resources = array();
|
||
public function __clone()
|
||
{
|
||
foreach ($this->routes as $name => $route) {
|
||
$this->routes[$name] = clone $route;
|
||
}
|
||
}
|
||
public function getIterator()
|
||
{
|
||
return new \ArrayIterator($this->routes);
|
||
}
|
||
public function count()
|
||
{
|
||
return count($this->routes);
|
||
}
|
||
public function add($name, Route $route)
|
||
{
|
||
unset($this->routes[$name]);
|
||
$this->routes[$name] = $route;
|
||
}
|
||
public function all()
|
||
{
|
||
return $this->routes;
|
||
}
|
||
public function get($name)
|
||
{
|
||
return isset($this->routes[$name]) ? $this->routes[$name] : null;
|
||
}
|
||
public function remove($name)
|
||
{
|
||
foreach ((array) $name as $n) {
|
||
unset($this->routes[$n]);
|
||
}
|
||
}
|
||
public function addCollection(RouteCollection $collection)
|
||
{
|
||
foreach ($collection->all() as $name => $route) {
|
||
unset($this->routes[$name]);
|
||
$this->routes[$name] = $route;
|
||
}
|
||
$this->resources = array_merge($this->resources, $collection->getResources());
|
||
}
|
||
public function addPrefix($prefix, array $defaults = array(), array $requirements = array())
|
||
{
|
||
$prefix = trim(trim($prefix), '/');
|
||
if ('' === $prefix) {
|
||
return;
|
||
}
|
||
foreach ($this->routes as $route) {
|
||
$route->setPath('/' . $prefix . $route->getPath());
|
||
$route->addDefaults($defaults);
|
||
$route->addRequirements($requirements);
|
||
}
|
||
}
|
||
public function setHost($pattern, array $defaults = array(), array $requirements = array())
|
||
{
|
||
foreach ($this->routes as $route) {
|
||
$route->setHost($pattern);
|
||
$route->addDefaults($defaults);
|
||
$route->addRequirements($requirements);
|
||
}
|
||
}
|
||
public function addDefaults(array $defaults)
|
||
{
|
||
if ($defaults) {
|
||
foreach ($this->routes as $route) {
|
||
$route->addDefaults($defaults);
|
||
}
|
||
}
|
||
}
|
||
public function addRequirements(array $requirements)
|
||
{
|
||
if ($requirements) {
|
||
foreach ($this->routes as $route) {
|
||
$route->addRequirements($requirements);
|
||
}
|
||
}
|
||
}
|
||
public function addOptions(array $options)
|
||
{
|
||
if ($options) {
|
||
foreach ($this->routes as $route) {
|
||
$route->addOptions($options);
|
||
}
|
||
}
|
||
}
|
||
public function setSchemes($schemes)
|
||
{
|
||
foreach ($this->routes as $route) {
|
||
$route->setSchemes($schemes);
|
||
}
|
||
}
|
||
public function setMethods($methods)
|
||
{
|
||
foreach ($this->routes as $route) {
|
||
$route->setMethods($methods);
|
||
}
|
||
}
|
||
public function getResources()
|
||
{
|
||
return array_unique($this->resources);
|
||
}
|
||
public function addResource(ResourceInterface $resource)
|
||
{
|
||
$this->resources[] = $resource;
|
||
}
|
||
}
|
||
namespace Illuminate\Workbench;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
use Illuminate\Workbench\Console\WorkbenchMakeCommand;
|
||
class WorkbenchServiceProvider extends ServiceProvider
|
||
{
|
||
protected $defer = false;
|
||
public function register()
|
||
{
|
||
$this->app['package.creator'] = $this->app->share(function ($app) {
|
||
return new PackageCreator($app['files']);
|
||
});
|
||
$this->app['command.workbench'] = $this->app->share(function ($app) {
|
||
return new WorkbenchMakeCommand($app['package.creator']);
|
||
});
|
||
$this->commands('command.workbench');
|
||
}
|
||
public function provides()
|
||
{
|
||
return array('package.creator', 'command.workbench');
|
||
}
|
||
}
|
||
namespace Illuminate\Events;
|
||
|
||
use Illuminate\Container\Container;
|
||
class Dispatcher
|
||
{
|
||
protected $container;
|
||
protected $listeners = array();
|
||
protected $wildcards = array();
|
||
protected $sorted = array();
|
||
public function __construct(Container $container = null)
|
||
{
|
||
$this->container = $container;
|
||
}
|
||
public function listen($event, $listener, $priority = 0)
|
||
{
|
||
if (str_contains($event, '*')) {
|
||
return $this->setupWildcardListen($event, $listener, $priority = 0);
|
||
}
|
||
$this->listeners[$event][$priority][] = $this->makeListener($listener);
|
||
unset($this->sorted[$event]);
|
||
}
|
||
protected function setupWildcardListen($event, $listener, $priority)
|
||
{
|
||
$this->wildcards[$event][] = $listener;
|
||
}
|
||
public function hasListeners($eventName)
|
||
{
|
||
return isset($this->listeners[$eventName]);
|
||
}
|
||
public function queue($event, $payload = array())
|
||
{
|
||
$me = $this;
|
||
$this->listen($event . '_queue', function () use($me, $event, $payload) {
|
||
$me->fire($event, $payload);
|
||
});
|
||
}
|
||
public function subscribe($subscriber)
|
||
{
|
||
$subscriber = $this->resolveSubscriber($subscriber);
|
||
$subscriber->subscribe($this);
|
||
}
|
||
protected function resolveSubscriber($subscriber)
|
||
{
|
||
if (is_string($subscriber)) {
|
||
return $this->container->make($subscriber);
|
||
}
|
||
return $subscriber;
|
||
}
|
||
public function until($event, $payload = array())
|
||
{
|
||
return $this->fire($event, $payload, true);
|
||
}
|
||
public function flush($event)
|
||
{
|
||
$this->fire($event . '_queue');
|
||
}
|
||
public function fire($event, $payload = array(), $halt = false)
|
||
{
|
||
$responses = array();
|
||
if (!is_array($payload)) {
|
||
$payload = array($payload);
|
||
}
|
||
$payload[] = $event;
|
||
foreach ($this->getListeners($event) as $listener) {
|
||
$response = call_user_func_array($listener, $payload);
|
||
if (!is_null($response) and $halt) {
|
||
return $response;
|
||
}
|
||
if ($response === false) {
|
||
break;
|
||
}
|
||
$responses[] = $response;
|
||
}
|
||
return $halt ? null : $responses;
|
||
}
|
||
public function getListeners($eventName)
|
||
{
|
||
$wildcards = $this->getWildcardListeners($eventName);
|
||
if (!isset($this->sorted[$eventName])) {
|
||
$this->sortListeners($eventName);
|
||
}
|
||
return array_merge($this->sorted[$eventName], $wildcards);
|
||
}
|
||
protected function getWildcardListeners($eventName)
|
||
{
|
||
$wildcards = array();
|
||
foreach ($this->wildcards as $key => $listeners) {
|
||
if (str_is($key, $eventName)) {
|
||
$wildcards = array_merge($wildcards, $listeners);
|
||
}
|
||
}
|
||
return $wildcards;
|
||
}
|
||
protected function sortListeners($eventName)
|
||
{
|
||
$this->sorted[$eventName] = array();
|
||
if (isset($this->listeners[$eventName])) {
|
||
krsort($this->listeners[$eventName]);
|
||
$this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
|
||
}
|
||
}
|
||
public function makeListener($listener)
|
||
{
|
||
if (is_string($listener)) {
|
||
$listener = $this->createClassListener($listener);
|
||
}
|
||
return $listener;
|
||
}
|
||
public function createClassListener($listener)
|
||
{
|
||
$container = $this->container;
|
||
return function () use($listener, $container) {
|
||
$segments = explode('@', $listener);
|
||
$method = count($segments) == 2 ? $segments[1] : 'handle';
|
||
$callable = array($container->make($segments[0]), $method);
|
||
$data = func_get_args();
|
||
return call_user_func_array($callable, $data);
|
||
};
|
||
}
|
||
public function forget($event)
|
||
{
|
||
unset($this->listeners[$event]);
|
||
unset($this->sorted[$event]);
|
||
}
|
||
}
|
||
namespace Illuminate\Database\Eloquent;
|
||
|
||
use Closure;
|
||
use DateTime;
|
||
use Carbon\Carbon;
|
||
use ArrayAccess;
|
||
use Illuminate\Events\Dispatcher;
|
||
use Illuminate\Database\Connection;
|
||
use Illuminate\Database\Eloquent\Collection;
|
||
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\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\BelongsToMany;
|
||
use Illuminate\Database\ConnectionResolverInterface as Resolver;
|
||
abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterface
|
||
{
|
||
protected $connection;
|
||
protected $table;
|
||
protected $primaryKey = 'id';
|
||
protected $perPage = 15;
|
||
public $incrementing = true;
|
||
public $timestamps = true;
|
||
protected $attributes = array();
|
||
protected $original = array();
|
||
protected $relations = array();
|
||
protected $hidden = array();
|
||
protected $visible = array();
|
||
protected $fillable = array();
|
||
protected $guarded = array('*');
|
||
protected $touches = array();
|
||
protected $with = array();
|
||
public $exists = false;
|
||
protected $softDelete = false;
|
||
public static $snakeAttributes = true;
|
||
protected static $resolver;
|
||
protected static $dispatcher;
|
||
protected static $booted = array();
|
||
protected static $unguarded = false;
|
||
protected static $mutatorCache = array();
|
||
const CREATED_AT = 'created_at';
|
||
const UPDATED_AT = 'updated_at';
|
||
const DELETED_AT = 'deleted_at';
|
||
public function __construct(array $attributes = array())
|
||
{
|
||
if (!isset(static::$booted[get_class($this)])) {
|
||
static::boot();
|
||
static::$booted[get_class($this)] = true;
|
||
}
|
||
$this->fill($attributes);
|
||
}
|
||
protected static function boot()
|
||
{
|
||
$class = get_called_class();
|
||
static::$mutatorCache[$class] = array();
|
||
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]);
|
||
}
|
||
}
|
||
}
|
||
public static function observe($class)
|
||
{
|
||
$instance = new static();
|
||
$className = get_class($class);
|
||
foreach ($instance->getObservableEvents() as $event) {
|
||
if (method_exists($class, $event)) {
|
||
static::registerModelEvent($event, $className . '@' . $event);
|
||
}
|
||
}
|
||
}
|
||
public function fill(array $attributes)
|
||
{
|
||
foreach ($attributes as $key => $value) {
|
||
$key = $this->removeTableFromKey($key);
|
||
if ($this->isFillable($key)) {
|
||
$this->setAttribute($key, $value);
|
||
} elseif ($this->totallyGuarded()) {
|
||
throw new MassAssignmentException($key);
|
||
}
|
||
}
|
||
return $this;
|
||
}
|
||
public function newInstance($attributes = array(), $exists = false)
|
||
{
|
||
$model = new static((array) $attributes);
|
||
$model->exists = $exists;
|
||
return $model;
|
||
}
|
||
public function newFromBuilder($attributes = array())
|
||
{
|
||
$instance = $this->newInstance(array(), true);
|
||
$instance->setRawAttributes((array) $attributes, true);
|
||
return $instance;
|
||
}
|
||
public static function create(array $attributes)
|
||
{
|
||
$model = new static($attributes);
|
||
$model->save();
|
||
return $model;
|
||
}
|
||
public static function on($connection = null)
|
||
{
|
||
$instance = new static();
|
||
$instance->setConnection($connection);
|
||
return $instance->newQuery();
|
||
}
|
||
public static function all($columns = array('*'))
|
||
{
|
||
$instance = new static();
|
||
return $instance->newQuery()->get($columns);
|
||
}
|
||
public static function find($id, $columns = array('*'))
|
||
{
|
||
$instance = new static();
|
||
if (is_array($id)) {
|
||
return $instance->newQuery()->whereIn($instance->getKeyName(), $id)->get($columns);
|
||
}
|
||
return $instance->newQuery()->find($id, $columns);
|
||
}
|
||
public static function findOrFail($id, $columns = array('*'))
|
||
{
|
||
if (!is_null($model = static::find($id, $columns))) {
|
||
return $model;
|
||
}
|
||
throw new ModelNotFoundException();
|
||
}
|
||
public function load($relations)
|
||
{
|
||
if (is_string($relations)) {
|
||
$relations = func_get_args();
|
||
}
|
||
$query = $this->newQuery()->with($relations);
|
||
$query->eagerLoadRelations(array($this));
|
||
}
|
||
public static function with($relations)
|
||
{
|
||
if (is_string($relations)) {
|
||
$relations = func_get_args();
|
||
}
|
||
$instance = new static();
|
||
return $instance->newQuery()->with($relations);
|
||
}
|
||
public function hasOne($related, $foreignKey = null)
|
||
{
|
||
$foreignKey = $foreignKey ?: $this->getForeignKey();
|
||
$instance = new $related();
|
||
return new HasOne($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey);
|
||
}
|
||
public function morphOne($related, $name, $type = null, $id = null)
|
||
{
|
||
$instance = new $related();
|
||
list($type, $id) = $this->getMorphs($name, $type, $id);
|
||
$table = $instance->getTable();
|
||
return new MorphOne($instance->newQuery(), $this, $table . '.' . $type, $table . '.' . $id);
|
||
}
|
||
public function belongsTo($related, $foreignKey = null)
|
||
{
|
||
list(, $caller) = debug_backtrace(false);
|
||
$relation = $caller['function'];
|
||
if (is_null($foreignKey)) {
|
||
$foreignKey = snake_case($relation) . '_id';
|
||
}
|
||
$instance = new $related();
|
||
$query = $instance->newQuery();
|
||
return new BelongsTo($query, $this, $foreignKey, $relation);
|
||
}
|
||
public function morphTo($name = null, $type = null, $id = null)
|
||
{
|
||
if (is_null($name)) {
|
||
list(, $caller) = debug_backtrace(false);
|
||
$name = snake_case($caller['function']);
|
||
}
|
||
list($type, $id) = $this->getMorphs($name, $type, $id);
|
||
$class = $this->{$type};
|
||
return $this->belongsTo($class, $id);
|
||
}
|
||
public function hasMany($related, $foreignKey = null)
|
||
{
|
||
$foreignKey = $foreignKey ?: $this->getForeignKey();
|
||
$instance = new $related();
|
||
return new HasMany($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey);
|
||
}
|
||
public function morphMany($related, $name, $type = null, $id = null)
|
||
{
|
||
$instance = new $related();
|
||
list($type, $id) = $this->getMorphs($name, $type, $id);
|
||
$table = $instance->getTable();
|
||
return new MorphMany($instance->newQuery(), $this, $table . '.' . $type, $table . '.' . $id);
|
||
}
|
||
public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null)
|
||
{
|
||
$caller = $this->getBelongsToManyCaller();
|
||
$foreignKey = $foreignKey ?: $this->getForeignKey();
|
||
$instance = new $related();
|
||
$otherKey = $otherKey ?: $instance->getForeignKey();
|
||
if (is_null($table)) {
|
||
$table = $this->joiningTable($related);
|
||
}
|
||
$query = $instance->newQuery();
|
||
return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $caller['function']);
|
||
}
|
||
protected function getBelongsToManyCaller()
|
||
{
|
||
$self = __FUNCTION__;
|
||
return array_first(debug_backtrace(false), function ($trace) use($self) {
|
||
$caller = $trace['function'];
|
||
return $caller != 'belongsToMany' and $caller != $self;
|
||
});
|
||
}
|
||
public function joiningTable($related)
|
||
{
|
||
$base = snake_case(class_basename($this));
|
||
$related = snake_case(class_basename($related));
|
||
$models = array($related, $base);
|
||
sort($models);
|
||
return strtolower(implode('_', $models));
|
||
}
|
||
public static function destroy($ids)
|
||
{
|
||
$ids = is_array($ids) ? $ids : func_get_args();
|
||
$instance = new static();
|
||
$key = $instance->getKeyName();
|
||
foreach ($instance->whereIn($key, $ids)->get() as $model) {
|
||
$model->delete();
|
||
}
|
||
}
|
||
public function delete()
|
||
{
|
||
if ($this->exists) {
|
||
if ($this->fireModelEvent('deleting') === false) {
|
||
return false;
|
||
}
|
||
$this->touchOwners();
|
||
$this->performDeleteOnModel();
|
||
$this->exists = false;
|
||
$this->fireModelEvent('deleted', false);
|
||
return true;
|
||
}
|
||
}
|
||
public function forceDelete()
|
||
{
|
||
$softDelete = $this->softDelete;
|
||
$this->softDelete = false;
|
||
$this->delete();
|
||
$this->softDelete = $softDelete;
|
||
}
|
||
protected function performDeleteOnModel()
|
||
{
|
||
$query = $this->newQuery()->where($this->getKeyName(), $this->getKey());
|
||
if ($this->softDelete) {
|
||
$query->update(array(static::DELETED_AT => new DateTime()));
|
||
} else {
|
||
$query->delete();
|
||
}
|
||
}
|
||
public function restore()
|
||
{
|
||
if ($this->softDelete) {
|
||
$this->{static::DELETED_AT} = null;
|
||
return $this->save();
|
||
}
|
||
}
|
||
public static function saving($callback)
|
||
{
|
||
static::registerModelEvent('saving', $callback);
|
||
}
|
||
public static function saved($callback)
|
||
{
|
||
static::registerModelEvent('saved', $callback);
|
||
}
|
||
public static function updating($callback)
|
||
{
|
||
static::registerModelEvent('updating', $callback);
|
||
}
|
||
public static function updated($callback)
|
||
{
|
||
static::registerModelEvent('updated', $callback);
|
||
}
|
||
public static function creating($callback)
|
||
{
|
||
static::registerModelEvent('creating', $callback);
|
||
}
|
||
public static function created($callback)
|
||
{
|
||
static::registerModelEvent('created', $callback);
|
||
}
|
||
public static function deleting($callback)
|
||
{
|
||
static::registerModelEvent('deleting', $callback);
|
||
}
|
||
public static function deleted($callback)
|
||
{
|
||
static::registerModelEvent('deleted', $callback);
|
||
}
|
||
public static function flushEventListeners()
|
||
{
|
||
if (!isset(static::$dispatcher)) {
|
||
return;
|
||
}
|
||
$instance = new static();
|
||
foreach ($instance->getObservableEvents() as $event) {
|
||
static::$dispatcher->forget("eloquent.{$event}: " . get_called_class());
|
||
}
|
||
}
|
||
protected static function registerModelEvent($event, $callback)
|
||
{
|
||
if (isset(static::$dispatcher)) {
|
||
$name = get_called_class();
|
||
static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback);
|
||
}
|
||
}
|
||
public function getObservableEvents()
|
||
{
|
||
return array('creating', 'created', 'updating', 'updated', 'deleting', 'deleted', 'saving', 'saved');
|
||
}
|
||
protected function increment($column, $amount = 1)
|
||
{
|
||
return $this->incrementOrDecrement($column, $amount, 'increment');
|
||
}
|
||
protected function decrement($column, $amount = 1)
|
||
{
|
||
return $this->incrementOrDecrement($column, $amount, 'decrement');
|
||
}
|
||
protected function incrementOrDecrement($column, $amount, $method)
|
||
{
|
||
$query = $this->newQuery();
|
||
if (!$this->exists) {
|
||
return $query->{$method}($column, $amount);
|
||
}
|
||
return $query->where($this->getKeyName(), $this->getKey())->{$method}($column, $amount);
|
||
}
|
||
public function update(array $attributes = array())
|
||
{
|
||
if (!$this->exists) {
|
||
return $this->newQuery()->update($attributes);
|
||
}
|
||
return $this->fill($attributes)->save();
|
||
}
|
||
public function push()
|
||
{
|
||
if (!$this->save()) {
|
||
return false;
|
||
}
|
||
foreach ($this->relations as $models) {
|
||
foreach (Collection::make($models) as $model) {
|
||
if (!$model->push()) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
public function save(array $options = array())
|
||
{
|
||
$query = $this->newQueryWithDeleted();
|
||
if ($this->fireModelEvent('saving') === false) {
|
||
return false;
|
||
}
|
||
if ($this->exists) {
|
||
$saved = $this->performUpdate($query);
|
||
} else {
|
||
$saved = $this->performInsert($query);
|
||
}
|
||
if ($saved) {
|
||
$this->finishSave($options);
|
||
}
|
||
return $saved;
|
||
}
|
||
protected function finishSave(array $options)
|
||
{
|
||
$this->syncOriginal();
|
||
$this->fireModelEvent('saved', false);
|
||
if (array_get($options, 'touch', true)) {
|
||
$this->touchOwners();
|
||
}
|
||
}
|
||
protected function performUpdate($query)
|
||
{
|
||
$dirty = $this->getDirty();
|
||
if (count($dirty) > 0) {
|
||
if ($this->fireModelEvent('updating') === false) {
|
||
return false;
|
||
}
|
||
if ($this->timestamps) {
|
||
$this->updateTimestamps();
|
||
$dirty = $this->getDirty();
|
||
}
|
||
$this->setKeysForSaveQuery($query)->update($dirty);
|
||
$this->fireModelEvent('updated', false);
|
||
}
|
||
return true;
|
||
}
|
||
protected function performInsert($query)
|
||
{
|
||
if ($this->fireModelEvent('creating') === false) {
|
||
return false;
|
||
}
|
||
if ($this->timestamps) {
|
||
$this->updateTimestamps();
|
||
}
|
||
$attributes = $this->attributes;
|
||
if ($this->incrementing) {
|
||
$this->insertAndSetId($query, $attributes);
|
||
} else {
|
||
$query->insert($attributes);
|
||
}
|
||
$this->exists = true;
|
||
$this->fireModelEvent('created', false);
|
||
return true;
|
||
}
|
||
protected function insertAndSetId($query, $attributes)
|
||
{
|
||
$id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
|
||
$this->setAttribute($keyName, $id);
|
||
}
|
||
public function touchOwners()
|
||
{
|
||
foreach ($this->touches as $relation) {
|
||
$this->{$relation}()->touch();
|
||
}
|
||
}
|
||
public function touches($relation)
|
||
{
|
||
return in_array($relation, $this->touches);
|
||
}
|
||
protected function fireModelEvent($event, $halt = true)
|
||
{
|
||
if (!isset(static::$dispatcher)) {
|
||
return true;
|
||
}
|
||
$event = "eloquent.{$event}: " . get_class($this);
|
||
$method = $halt ? 'until' : 'fire';
|
||
return static::$dispatcher->{$method}($event, $this);
|
||
}
|
||
protected function setKeysForSaveQuery($query)
|
||
{
|
||
$query->where($this->getKeyName(), '=', $this->getKey());
|
||
return $query;
|
||
}
|
||
public function touch()
|
||
{
|
||
$this->updateTimestamps();
|
||
return $this->save();
|
||
}
|
||
protected function updateTimestamps()
|
||
{
|
||
$time = $this->freshTimestamp();
|
||
if (!$this->isDirty(static::UPDATED_AT)) {
|
||
$this->setUpdatedAt($time);
|
||
}
|
||
if (!$this->exists and !$this->isDirty(static::CREATED_AT)) {
|
||
$this->setCreatedAt($time);
|
||
}
|
||
}
|
||
public function setCreatedAt($value)
|
||
{
|
||
$this->{static::CREATED_AT} = $value;
|
||
}
|
||
public function setUpdatedAt($value)
|
||
{
|
||
$this->{static::UPDATED_AT} = $value;
|
||
}
|
||
public function getCreatedAtColumn()
|
||
{
|
||
return static::CREATED_AT;
|
||
}
|
||
public function getUpdatedAtColumn()
|
||
{
|
||
return static::UPDATED_AT;
|
||
}
|
||
public function getDeletedAtColumn()
|
||
{
|
||
return static::DELETED_AT;
|
||
}
|
||
public function getQualifiedDeletedAtColumn()
|
||
{
|
||
return $this->getTable() . '.' . $this->getDeletedAtColumn();
|
||
}
|
||
public function freshTimestamp()
|
||
{
|
||
return new DateTime();
|
||
}
|
||
public function newQuery($excludeDeleted = true)
|
||
{
|
||
$builder = new Builder($this->newBaseQueryBuilder());
|
||
$builder->setModel($this)->with($this->with);
|
||
if ($excludeDeleted and $this->softDelete) {
|
||
$builder->whereNull($this->getQualifiedDeletedAtColumn());
|
||
}
|
||
return $builder;
|
||
}
|
||
public function newQueryWithDeleted()
|
||
{
|
||
return $this->newQuery(false);
|
||
}
|
||
public function trashed()
|
||
{
|
||
return $this->softDelete and !is_null($this->{static::DELETED_AT});
|
||
}
|
||
public static function withTrashed()
|
||
{
|
||
return with(new static())->newQueryWithDeleted();
|
||
}
|
||
public static function onlyTrashed()
|
||
{
|
||
$instance = new static();
|
||
$column = $instance->getQualifiedDeletedAtColumn();
|
||
return $instance->newQueryWithDeleted()->whereNotNull($column);
|
||
}
|
||
protected function newBaseQueryBuilder()
|
||
{
|
||
$conn = $this->getConnection();
|
||
$grammar = $conn->getQueryGrammar();
|
||
return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
|
||
}
|
||
public function newCollection(array $models = array())
|
||
{
|
||
return new Collection($models);
|
||
}
|
||
public function getTable()
|
||
{
|
||
if (isset($this->table)) {
|
||
return $this->table;
|
||
}
|
||
return str_replace('\\', '', snake_case(str_plural(get_class($this))));
|
||
}
|
||
public function setTable($table)
|
||
{
|
||
$this->table = $table;
|
||
}
|
||
public function getKey()
|
||
{
|
||
return $this->getAttribute($this->getKeyName());
|
||
}
|
||
public function getKeyName()
|
||
{
|
||
return $this->primaryKey;
|
||
}
|
||
public function getQualifiedKeyName()
|
||
{
|
||
return $this->getTable() . '.' . $this->getKeyName();
|
||
}
|
||
public function usesTimestamps()
|
||
{
|
||
return $this->timestamps;
|
||
}
|
||
public function isSoftDeleting()
|
||
{
|
||
return $this->softDelete;
|
||
}
|
||
public function setSoftDeleting($enabled)
|
||
{
|
||
$this->softDelete = $enabled;
|
||
}
|
||
protected function getMorphs($name, $type, $id)
|
||
{
|
||
$type = $type ?: $name . '_type';
|
||
$id = $id ?: $name . '_id';
|
||
return array($type, $id);
|
||
}
|
||
public function getPerPage()
|
||
{
|
||
return $this->perPage;
|
||
}
|
||
public function setPerPage($perPage)
|
||
{
|
||
$this->perPage = $perPage;
|
||
}
|
||
public function getForeignKey()
|
||
{
|
||
return snake_case(class_basename($this)) . '_id';
|
||
}
|
||
public function getHidden()
|
||
{
|
||
return $this->hidden;
|
||
}
|
||
public function setHidden(array $hidden)
|
||
{
|
||
$this->hidden = $hidden;
|
||
}
|
||
public function setVisible(array $visible)
|
||
{
|
||
$this->visible = $visible;
|
||
}
|
||
public function getFillable()
|
||
{
|
||
return $this->fillable;
|
||
}
|
||
public function fillable(array $fillable)
|
||
{
|
||
$this->fillable = $fillable;
|
||
return $this;
|
||
}
|
||
public function guard(array $guarded)
|
||
{
|
||
$this->guarded = $guarded;
|
||
return $this;
|
||
}
|
||
public static function unguard()
|
||
{
|
||
static::$unguarded = true;
|
||
}
|
||
public static function reguard()
|
||
{
|
||
static::$unguarded = false;
|
||
}
|
||
public static function setUnguardState($state)
|
||
{
|
||
static::$unguarded = $state;
|
||
}
|
||
public function isFillable($key)
|
||
{
|
||
if (static::$unguarded) {
|
||
return true;
|
||
}
|
||
if (in_array($key, $this->fillable)) {
|
||
return true;
|
||
}
|
||
if ($this->isGuarded($key)) {
|
||
return false;
|
||
}
|
||
return empty($this->fillable) and !starts_with($key, '_');
|
||
}
|
||
public function isGuarded($key)
|
||
{
|
||
return in_array($key, $this->guarded) or $this->guarded == array('*');
|
||
}
|
||
public function totallyGuarded()
|
||
{
|
||
return count($this->fillable) == 0 and $this->guarded == array('*');
|
||
}
|
||
protected function removeTableFromKey($key)
|
||
{
|
||
if (!str_contains($key, '.')) {
|
||
return $key;
|
||
}
|
||
return last(explode('.', $key));
|
||
}
|
||
public function getTouchedRelations()
|
||
{
|
||
return $this->touches;
|
||
}
|
||
public function setTouchedRelations(array $touches)
|
||
{
|
||
$this->touches = $touches;
|
||
}
|
||
public function getIncrementing()
|
||
{
|
||
return $this->incrementing;
|
||
}
|
||
public function setIncrementing($value)
|
||
{
|
||
$this->incrementing = $value;
|
||
}
|
||
public function toJson($options = 0)
|
||
{
|
||
return json_encode($this->toArray(), $options);
|
||
}
|
||
public function toArray()
|
||
{
|
||
$attributes = $this->attributesToArray();
|
||
return array_merge($attributes, $this->relationsToArray());
|
||
}
|
||
public function attributesToArray()
|
||
{
|
||
$attributes = $this->getAccessibleAttributes();
|
||
foreach ($this->getMutatedAttributes() as $key) {
|
||
if (!array_key_exists($key, $attributes)) {
|
||
continue;
|
||
}
|
||
$attributes[$key] = $this->mutateAttribute($key, $attributes[$key]);
|
||
}
|
||
return $attributes;
|
||
}
|
||
protected function getAccessibleAttributes()
|
||
{
|
||
if (count($this->visible) > 0) {
|
||
return array_intersect_key($this->attributes, array_flip($this->visible));
|
||
}
|
||
return array_diff_key($this->attributes, array_flip($this->hidden));
|
||
}
|
||
public function relationsToArray()
|
||
{
|
||
$attributes = array();
|
||
foreach ($this->relations as $key => $value) {
|
||
if (in_array($key, $this->hidden)) {
|
||
continue;
|
||
}
|
||
if ($value instanceof ArrayableInterface) {
|
||
$relation = $value->toArray();
|
||
} elseif (is_null($value)) {
|
||
$relation = $value;
|
||
}
|
||
if (static::$snakeAttributes) {
|
||
$key = snake_case($key);
|
||
}
|
||
if (isset($relation)) {
|
||
$attributes[$key] = $relation;
|
||
}
|
||
}
|
||
return $attributes;
|
||
}
|
||
public function getAttribute($key)
|
||
{
|
||
$inAttributes = array_key_exists($key, $this->attributes);
|
||
if ($inAttributes or $this->hasGetMutator($key)) {
|
||
return $this->getAttributeValue($key);
|
||
}
|
||
if (array_key_exists($key, $this->relations)) {
|
||
return $this->relations[$key];
|
||
}
|
||
$camelKey = camel_case($key);
|
||
if (method_exists($this, $camelKey)) {
|
||
$relations = $this->{$camelKey}()->getResults();
|
||
return $this->relations[$key] = $relations;
|
||
}
|
||
}
|
||
protected function getAttributeValue($key)
|
||
{
|
||
$value = $this->getAttributeFromArray($key);
|
||
if ($this->hasGetMutator($key)) {
|
||
return $this->mutateAttribute($key, $value);
|
||
} elseif (in_array($key, $this->getDates())) {
|
||
if ($value) {
|
||
return $this->asDateTime($value);
|
||
}
|
||
}
|
||
return $value;
|
||
}
|
||
protected function getAttributeFromArray($key)
|
||
{
|
||
if (array_key_exists($key, $this->attributes)) {
|
||
return $this->attributes[$key];
|
||
}
|
||
}
|
||
public function hasGetMutator($key)
|
||
{
|
||
return method_exists($this, 'get' . studly_case($key) . 'Attribute');
|
||
}
|
||
protected function mutateAttribute($key, $value)
|
||
{
|
||
return $this->{'get' . studly_case($key) . 'Attribute'}($value);
|
||
}
|
||
public function setAttribute($key, $value)
|
||
{
|
||
if ($this->hasSetMutator($key)) {
|
||
$method = 'set' . studly_case($key) . 'Attribute';
|
||
return $this->{$method}($value);
|
||
} elseif (in_array($key, $this->getDates())) {
|
||
if ($value) {
|
||
$value = $this->fromDateTime($value);
|
||
}
|
||
}
|
||
$this->attributes[$key] = $value;
|
||
}
|
||
public function hasSetMutator($key)
|
||
{
|
||
return method_exists($this, 'set' . studly_case($key) . 'Attribute');
|
||
}
|
||
public function getDates()
|
||
{
|
||
return array(static::CREATED_AT, static::UPDATED_AT, static::DELETED_AT);
|
||
}
|
||
protected function fromDateTime($value)
|
||
{
|
||
$format = $this->getDateFormat();
|
||
if ($value instanceof DateTime) {
|
||
|
||
} elseif (is_numeric($value)) {
|
||
$value = Carbon::createFromTimestamp($value);
|
||
} elseif (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value)) {
|
||
$value = Carbon::createFromFormat('Y-m-d', $value);
|
||
} elseif (!$value instanceof DateTime) {
|
||
$value = Carbon::createFromFormat($format, $value);
|
||
}
|
||
return $value->format($format);
|
||
}
|
||
protected function asDateTime($value)
|
||
{
|
||
if (is_numeric($value)) {
|
||
return Carbon::createFromTimestamp($value);
|
||
} elseif (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value)) {
|
||
return Carbon::createFromFormat('Y-m-d', $value);
|
||
} elseif (!$value instanceof DateTime) {
|
||
$format = $this->getDateFormat();
|
||
return Carbon::createFromFormat($format, $value);
|
||
}
|
||
return Carbon::instance($value);
|
||
}
|
||
protected function getDateFormat()
|
||
{
|
||
return $this->getConnection()->getQueryGrammar()->getDateFormat();
|
||
}
|
||
public function replicate()
|
||
{
|
||
$attributes = array_except($this->attributes, array($this->getKeyName()));
|
||
with($instance = new static())->setRawAttributes($attributes);
|
||
return $instance->setRelations($this->relations);
|
||
}
|
||
public function getAttributes()
|
||
{
|
||
return $this->attributes;
|
||
}
|
||
public function setRawAttributes(array $attributes, $sync = false)
|
||
{
|
||
$this->attributes = $attributes;
|
||
if ($sync) {
|
||
$this->syncOriginal();
|
||
}
|
||
}
|
||
public function getOriginal($key = null, $default = null)
|
||
{
|
||
return array_get($this->original, $key, $default);
|
||
}
|
||
public function syncOriginal()
|
||
{
|
||
$this->original = $this->attributes;
|
||
return $this;
|
||
}
|
||
public function isDirty($attribute)
|
||
{
|
||
return array_key_exists($attribute, $this->getDirty());
|
||
}
|
||
public function getDirty()
|
||
{
|
||
$dirty = array();
|
||
foreach ($this->attributes as $key => $value) {
|
||
if (!array_key_exists($key, $this->original) or $value !== $this->original[$key]) {
|
||
$dirty[$key] = $value;
|
||
}
|
||
}
|
||
return $dirty;
|
||
}
|
||
public function getRelation($relation)
|
||
{
|
||
return $this->relations[$relation];
|
||
}
|
||
public function setRelation($relation, $value)
|
||
{
|
||
$this->relations[$relation] = $value;
|
||
return $this;
|
||
}
|
||
public function setRelations(array $relations)
|
||
{
|
||
$this->relations = $relations;
|
||
return $this;
|
||
}
|
||
public function getConnection()
|
||
{
|
||
return static::resolveConnection($this->connection);
|
||
}
|
||
public function getConnectionName()
|
||
{
|
||
return $this->connection;
|
||
}
|
||
public function setConnection($name)
|
||
{
|
||
$this->connection = $name;
|
||
}
|
||
public static function resolveConnection($connection = null)
|
||
{
|
||
return static::$resolver->connection($connection);
|
||
}
|
||
public static function getConnectionResolver()
|
||
{
|
||
return static::$resolver;
|
||
}
|
||
public static function setConnectionResolver(Resolver $resolver)
|
||
{
|
||
static::$resolver = $resolver;
|
||
}
|
||
public static function getEventDispatcher()
|
||
{
|
||
return static::$dispatcher;
|
||
}
|
||
public static function setEventDispatcher(Dispatcher $dispatcher)
|
||
{
|
||
static::$dispatcher = $dispatcher;
|
||
}
|
||
public static function unsetEventDispatcher()
|
||
{
|
||
static::$dispatcher = null;
|
||
}
|
||
public function getMutatedAttributes()
|
||
{
|
||
$class = get_class($this);
|
||
if (isset(static::$mutatorCache[$class])) {
|
||
return static::$mutatorCache[get_class($this)];
|
||
}
|
||
return array();
|
||
}
|
||
public function __get($key)
|
||
{
|
||
return $this->getAttribute($key);
|
||
}
|
||
public function __set($key, $value)
|
||
{
|
||
$this->setAttribute($key, $value);
|
||
}
|
||
public function offsetExists($offset)
|
||
{
|
||
return isset($this->{$offset});
|
||
}
|
||
public function offsetGet($offset)
|
||
{
|
||
return $this->{$offset};
|
||
}
|
||
public function offsetSet($offset, $value)
|
||
{
|
||
$this->{$offset} = $value;
|
||
}
|
||
public function offsetUnset($offset)
|
||
{
|
||
unset($this->{$offset});
|
||
}
|
||
public function __isset($key)
|
||
{
|
||
return isset($this->attributes[$key]) or isset($this->relations[$key]);
|
||
}
|
||
public function __unset($key)
|
||
{
|
||
unset($this->attributes[$key]);
|
||
unset($this->relations[$key]);
|
||
}
|
||
public function __call($method, $parameters)
|
||
{
|
||
if (in_array($method, array('increment', 'decrement'))) {
|
||
return call_user_func_array(array($this, $method), $parameters);
|
||
}
|
||
$query = $this->newQuery();
|
||
return call_user_func_array(array($query, $method), $parameters);
|
||
}
|
||
public static function __callStatic($method, $parameters)
|
||
{
|
||
$instance = new static();
|
||
return call_user_func_array(array($instance, $method), $parameters);
|
||
}
|
||
public function __toString()
|
||
{
|
||
return $this->toJson();
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Contracts;
|
||
|
||
interface ArrayableInterface
|
||
{
|
||
public function toArray();
|
||
}
|
||
namespace Illuminate\Support\Contracts;
|
||
|
||
interface JsonableInterface
|
||
{
|
||
public function toJson($options = 0);
|
||
}
|
||
namespace Illuminate\Database;
|
||
|
||
use Illuminate\Support\Manager;
|
||
use Illuminate\Database\Connectors\ConnectionFactory;
|
||
class DatabaseManager implements ConnectionResolverInterface
|
||
{
|
||
protected $app;
|
||
protected $factory;
|
||
protected $connections = array();
|
||
protected $extensions = array();
|
||
public function __construct($app, ConnectionFactory $factory)
|
||
{
|
||
$this->app = $app;
|
||
$this->factory = $factory;
|
||
}
|
||
public function connection($name = null)
|
||
{
|
||
$name = $name ?: $this->getDefaultConnection();
|
||
if (!isset($this->connections[$name])) {
|
||
$connection = $this->makeConnection($name);
|
||
$this->connections[$name] = $this->prepare($connection);
|
||
}
|
||
return $this->connections[$name];
|
||
}
|
||
public function reconnect($name = null)
|
||
{
|
||
unset($this->connections[$name]);
|
||
return $this->connection($name);
|
||
}
|
||
protected function makeConnection($name)
|
||
{
|
||
$config = $this->getConfig($name);
|
||
if (isset($this->extensions[$name])) {
|
||
return call_user_func($this->extensions[$name], $config);
|
||
}
|
||
return $this->factory->make($config, $name);
|
||
}
|
||
protected function prepare(Connection $connection)
|
||
{
|
||
$connection->setFetchMode($this->app['config']['database.fetch']);
|
||
if ($this->app->bound('events')) {
|
||
$connection->setEventDispatcher($this->app['events']);
|
||
}
|
||
$app = $this->app;
|
||
$connection->setCacheManager(function () use($app) {
|
||
return $app['cache'];
|
||
});
|
||
$connection->setPaginator(function () use($app) {
|
||
return $app['paginator'];
|
||
});
|
||
return $connection;
|
||
}
|
||
protected function getConfig($name)
|
||
{
|
||
$name = $name ?: $this->getDefaultConnection();
|
||
$connections = $this->app['config']['database.connections'];
|
||
if (is_null($config = array_get($connections, $name))) {
|
||
throw new \InvalidArgumentException("Database [{$name}] not configured.");
|
||
}
|
||
return $config;
|
||
}
|
||
public function getDefaultConnection()
|
||
{
|
||
return $this->app['config']['database.default'];
|
||
}
|
||
public function setDefaultConnection($name)
|
||
{
|
||
$this->app['config']['database.default'] = $name;
|
||
}
|
||
public function extend($name, $resolver)
|
||
{
|
||
$this->extensions[$name] = $resolver;
|
||
}
|
||
public function __call($method, $parameters)
|
||
{
|
||
return call_user_func_array(array($this->connection(), $method), $parameters);
|
||
}
|
||
}
|
||
namespace Illuminate\Database;
|
||
|
||
interface ConnectionResolverInterface
|
||
{
|
||
public function connection($name = null);
|
||
public function getDefaultConnection();
|
||
public function setDefaultConnection($name);
|
||
}
|
||
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
|
||
{
|
||
protected $container;
|
||
public function __construct(Container $container)
|
||
{
|
||
$this->container = $container;
|
||
}
|
||
public function make(array $config, $name = null)
|
||
{
|
||
$config = $this->parseConfig($config, $name);
|
||
$pdo = $this->createConnector($config)->connect($config);
|
||
return $this->createConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config);
|
||
}
|
||
protected function parseConfig(array $config, $name)
|
||
{
|
||
return array_add(array_add($config, 'prefix', ''), 'name', $name);
|
||
}
|
||
public function createConnector(array $config)
|
||
{
|
||
if (!isset($config['driver'])) {
|
||
throw new \InvalidArgumentException('A driver must be specified.');
|
||
}
|
||
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']}]");
|
||
}
|
||
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}]");
|
||
}
|
||
}
|
||
namespace Illuminate\Session;
|
||
|
||
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
|
||
class Store extends SymfonySession
|
||
{
|
||
public function start()
|
||
{
|
||
parent::start();
|
||
if (!$this->has('_token')) {
|
||
$this->put('_token', str_random(40));
|
||
}
|
||
}
|
||
public function save()
|
||
{
|
||
$this->ageFlashData();
|
||
return parent::save();
|
||
}
|
||
protected function ageFlashData()
|
||
{
|
||
foreach ($this->get('flash.old', array()) as $old) {
|
||
$this->forget($old);
|
||
}
|
||
$this->put('flash.old', $this->get('flash.new', array()));
|
||
$this->put('flash.new', array());
|
||
}
|
||
public function has($name)
|
||
{
|
||
return !is_null($this->get($name));
|
||
}
|
||
public function get($name, $default = null)
|
||
{
|
||
return array_get($this->all(), $name, $default);
|
||
}
|
||
public function hasOldInput($key)
|
||
{
|
||
return !is_null($this->getOldInput($key));
|
||
}
|
||
public function getOldInput($key = null, $default = null)
|
||
{
|
||
$input = $this->get('_old_input', array());
|
||
if (is_null($key)) {
|
||
return $input;
|
||
}
|
||
return array_get($input, $key, $default);
|
||
}
|
||
public function getToken()
|
||
{
|
||
return $this->token();
|
||
}
|
||
public function token()
|
||
{
|
||
return $this->get('_token');
|
||
}
|
||
public function put($key, $value)
|
||
{
|
||
$all = $this->all();
|
||
array_set($all, $key, $value);
|
||
$this->replace($all);
|
||
}
|
||
public function push($key, $value)
|
||
{
|
||
$array = $this->get($key, array());
|
||
$array[] = $value;
|
||
$this->put($key, $array);
|
||
}
|
||
public function flash($key, $value)
|
||
{
|
||
$this->put($key, $value);
|
||
$this->push('flash.new', $key);
|
||
$this->removeFromOldFlashData(array($key));
|
||
}
|
||
public function flashInput(array $value)
|
||
{
|
||
return $this->flash('_old_input', $value);
|
||
}
|
||
public function reflash()
|
||
{
|
||
$this->mergeNewFlashes($this->get('flash.old'));
|
||
$this->put('flash.old', array());
|
||
}
|
||
public function keep($keys = null)
|
||
{
|
||
$keys = is_array($keys) ? $keys : func_get_args();
|
||
$this->mergeNewFlashes($keys);
|
||
$this->removeFromOldFlashData($keys);
|
||
}
|
||
protected function mergeNewFlashes(array $keys)
|
||
{
|
||
$values = array_unique(array_merge($this->get('flash.new'), $keys));
|
||
$this->put('flash.new', $values);
|
||
}
|
||
protected function removeFromOldFlashData(array $keys)
|
||
{
|
||
$this->put('flash.old', array_diff($this->get('flash.old', array()), $keys));
|
||
}
|
||
public function forget($key)
|
||
{
|
||
$all = $this->all();
|
||
array_forget($all, $key);
|
||
$this->replace($all);
|
||
}
|
||
public function flush()
|
||
{
|
||
return $this->clear();
|
||
}
|
||
public function regenerate()
|
||
{
|
||
return $this->migrate();
|
||
}
|
||
}
|
||
namespace Illuminate\Session;
|
||
|
||
use Illuminate\Support\Manager;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
|
||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
|
||
class SessionManager extends Manager
|
||
{
|
||
protected function callCustomCreator($driver)
|
||
{
|
||
return $this->buildSession(parent::callCustomCreator($driver));
|
||
}
|
||
protected function createArrayDriver()
|
||
{
|
||
return new Store(new MockArraySessionStorage());
|
||
}
|
||
protected function createCookieDriver()
|
||
{
|
||
$lifetime = $this->app['config']['session.lifetime'];
|
||
return $this->buildSession(new CookieSessionHandler($this->app['cookie'], $lifetime));
|
||
}
|
||
protected function createNativeDriver()
|
||
{
|
||
$path = $this->app['config']['session.files'];
|
||
return $this->buildSession(new NativeFileSessionHandler($path));
|
||
}
|
||
protected function createDatabaseDriver()
|
||
{
|
||
$connection = $this->getDatabaseConnection();
|
||
$table = $connection->getTablePrefix() . $this->app['config']['session.table'];
|
||
return $this->buildSession(new PdoSessionHandler($connection->getPdo(), $this->getDatabaseOptions($table)));
|
||
}
|
||
protected function getDatabaseConnection()
|
||
{
|
||
$connection = $this->app['config']['session.connection'];
|
||
return $this->app['db']->connection($connection);
|
||
}
|
||
protected function getDatabaseOptions($table)
|
||
{
|
||
return array('db_table' => $table, 'db_id_col' => 'id', 'db_data_col' => 'payload', 'db_time_col' => 'last_activity');
|
||
}
|
||
protected function createApcDriver()
|
||
{
|
||
return $this->createCacheBased('apc');
|
||
}
|
||
protected function createMemcachedDriver()
|
||
{
|
||
return $this->createCacheBased('memcached');
|
||
}
|
||
protected function createWincacheDriver()
|
||
{
|
||
return $this->createCacheBased('wincache');
|
||
}
|
||
protected function createRedisDriver()
|
||
{
|
||
return $this->createCacheBased('redis');
|
||
}
|
||
protected function createCacheBased($driver)
|
||
{
|
||
$minutes = $this->app['config']['session.lifetime'];
|
||
$handler = new CacheBasedSessionHandler($this->app['cache']->driver($driver), $minutes);
|
||
return $this->buildSession($handler);
|
||
}
|
||
protected function buildSession($handler)
|
||
{
|
||
return new Store(new NativeSessionStorage($this->getOptions(), $handler));
|
||
}
|
||
protected function getOptions()
|
||
{
|
||
$config = $this->app['config']['session'];
|
||
return array('cookie_domain' => $config['domain'], 'cookie_lifetime' => $config['lifetime'] * 60, 'cookie_path' => $config['path'], 'cookie_httponly' => '1', 'name' => $config['cookie'], 'gc_divisor' => $config['lottery'][1], 'gc_probability' => $config['lottery'][0]);
|
||
}
|
||
protected function getDefaultDriver()
|
||
{
|
||
return $this->app['config']['session.driver'];
|
||
}
|
||
}
|
||
namespace Illuminate\Support;
|
||
|
||
use Closure;
|
||
abstract class Manager
|
||
{
|
||
protected $app;
|
||
protected $customCreators = array();
|
||
protected $drivers = array();
|
||
public function __construct($app)
|
||
{
|
||
$this->app = $app;
|
||
}
|
||
public function driver($driver = null)
|
||
{
|
||
$driver = $driver ?: $this->getDefaultDriver();
|
||
if (!isset($this->drivers[$driver])) {
|
||
$this->drivers[$driver] = $this->createDriver($driver);
|
||
}
|
||
return $this->drivers[$driver];
|
||
}
|
||
protected function createDriver($driver)
|
||
{
|
||
$method = 'create' . ucfirst($driver) . 'Driver';
|
||
if (isset($this->customCreators[$driver])) {
|
||
return $this->callCustomCreator($driver);
|
||
} elseif (method_exists($this, $method)) {
|
||
return $this->{$method}();
|
||
}
|
||
throw new \InvalidArgumentException("Driver [{$driver}] not supported.");
|
||
}
|
||
protected function callCustomCreator($driver)
|
||
{
|
||
return $this->customCreators[$driver]($this->app);
|
||
}
|
||
public function extend($driver, Closure $callback)
|
||
{
|
||
$this->customCreators[$driver] = $callback;
|
||
}
|
||
public function getDrivers()
|
||
{
|
||
return $this->drivers;
|
||
}
|
||
public function __call($method, $parameters)
|
||
{
|
||
return call_user_func_array(array($this->driver(), $method), $parameters);
|
||
}
|
||
}
|
||
namespace Illuminate\Cookie;
|
||
|
||
use Closure;
|
||
use Illuminate\Encryption\Encrypter;
|
||
use Symfony\Component\HttpFoundation\Cookie;
|
||
use Symfony\Component\HttpFoundation\Request;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
class CookieJar
|
||
{
|
||
protected $request;
|
||
protected $encrypter;
|
||
protected $path = '/';
|
||
protected $domain = null;
|
||
public function __construct(Request $request, Encrypter $encrypter)
|
||
{
|
||
$this->request = $request;
|
||
$this->encrypter = $encrypter;
|
||
}
|
||
public function has($key)
|
||
{
|
||
return !is_null($this->get($key));
|
||
}
|
||
public function get($key, $default = null)
|
||
{
|
||
$value = $this->request->cookies->get($key);
|
||
if (!is_null($value)) {
|
||
return $this->decrypt($value);
|
||
}
|
||
return $default instanceof Closure ? $default() : $default;
|
||
}
|
||
protected function decrypt($value)
|
||
{
|
||
try {
|
||
return $this->encrypter->decrypt($value);
|
||
} catch (\Exception $e) {
|
||
return null;
|
||
}
|
||
}
|
||
public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
|
||
{
|
||
list($path, $domain) = $this->getPathAndDomain($path, $domain);
|
||
$time = $minutes == 0 ? 0 : time() + $minutes * 60;
|
||
$value = $this->encrypter->encrypt($value);
|
||
return new Cookie($name, $value, $time, $path, $domain, $secure, $httpOnly);
|
||
}
|
||
public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true)
|
||
{
|
||
return $this->make($name, $value, 2628000, $path, $domain, $secure, $httpOnly);
|
||
}
|
||
public function forget($name)
|
||
{
|
||
return $this->make($name, null, -2628000);
|
||
}
|
||
protected function getPathAndDomain($path, $domain)
|
||
{
|
||
return array($path ?: $this->path, $domain ?: $this->domain);
|
||
}
|
||
public function setDefaultPathAndDomain($path, $domain)
|
||
{
|
||
list($this->path, $this->domain) = array($path, $domain);
|
||
return $this;
|
||
}
|
||
public function getRequest()
|
||
{
|
||
return $this->request;
|
||
}
|
||
public function getEncrypter()
|
||
{
|
||
return $this->encrypter;
|
||
}
|
||
}
|
||
namespace Illuminate\Encryption;
|
||
|
||
class DecryptException extends \RuntimeException
|
||
{
|
||
|
||
}
|
||
class Encrypter
|
||
{
|
||
protected $key;
|
||
protected $cipher = 'rijndael-256';
|
||
protected $mode = 'cbc';
|
||
protected $block = 32;
|
||
public function __construct($key)
|
||
{
|
||
$this->key = $key;
|
||
}
|
||
public function encrypt($value)
|
||
{
|
||
$iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
|
||
$value = base64_encode($this->padAndMcrypt($value, $iv));
|
||
$mac = $this->hash($iv = base64_encode($iv), $value);
|
||
return base64_encode(json_encode(compact('iv', 'value', 'mac')));
|
||
}
|
||
protected function padAndMcrypt($value, $iv)
|
||
{
|
||
$value = $this->addPadding(serialize($value));
|
||
return mcrypt_encrypt($this->cipher, $this->key, $value, $this->mode, $iv);
|
||
}
|
||
public function decrypt($payload)
|
||
{
|
||
$payload = $this->getJsonPayload($payload);
|
||
$value = base64_decode($payload['value']);
|
||
$iv = base64_decode($payload['iv']);
|
||
return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
|
||
}
|
||
protected function mcryptDecrypt($value, $iv)
|
||
{
|
||
return mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv);
|
||
}
|
||
protected function getJsonPayload($payload)
|
||
{
|
||
$payload = json_decode(base64_decode($payload), true);
|
||
if (!$payload or $this->invalidPayload($payload)) {
|
||
throw new DecryptException('Invalid data.');
|
||
}
|
||
if ($payload['mac'] !== $this->hash($payload['iv'], $payload['value'])) {
|
||
throw new DecryptException('MAC is invalid.');
|
||
}
|
||
return $payload;
|
||
}
|
||
protected function hash($iv, $value)
|
||
{
|
||
return hash_hmac('sha256', $iv . $value, $this->key);
|
||
}
|
||
protected function addPadding($value)
|
||
{
|
||
$pad = $this->block - strlen($value) % $this->block;
|
||
return $value . str_repeat(chr($pad), $pad);
|
||
}
|
||
protected function stripPadding($value)
|
||
{
|
||
$pad = ord($value[($len = strlen($value)) - 1]);
|
||
return $this->paddingIsValid($pad, $value) ? substr($value, 0, strlen($value) - $pad) : $value;
|
||
}
|
||
protected function paddingIsValid($pad, $value)
|
||
{
|
||
$beforePad = strlen($value) - $pad;
|
||
return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
|
||
}
|
||
protected function invalidPayload(array $data)
|
||
{
|
||
return !isset($data['iv']) or !isset($data['value']) or !isset($data['mac']);
|
||
}
|
||
protected function getIvSize()
|
||
{
|
||
return mcrypt_get_iv_size($this->cipher, $this->mode);
|
||
}
|
||
protected function getRandomizer()
|
||
{
|
||
if (defined('MCRYPT_DEV_URANDOM')) {
|
||
return MCRYPT_DEV_URANDOM;
|
||
}
|
||
if (defined('MCRYPT_DEV_RANDOM')) {
|
||
return MCRYPT_DEV_RANDOM;
|
||
}
|
||
mt_srand();
|
||
return MCRYPT_RAND;
|
||
}
|
||
public function setKey($key)
|
||
{
|
||
$this->key = $key;
|
||
}
|
||
public function setCipher($cipher)
|
||
{
|
||
$this->cipher = $cipher;
|
||
}
|
||
public function setMode($mode)
|
||
{
|
||
$this->mode = $mode;
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Facades;
|
||
|
||
class Log extends Facade
|
||
{
|
||
protected static function getFacadeAccessor()
|
||
{
|
||
return 'log';
|
||
}
|
||
}
|
||
namespace Illuminate\Log;
|
||
|
||
use Illuminate\Support\ServiceProvider;
|
||
class LogServiceProvider extends ServiceProvider
|
||
{
|
||
protected $defer = true;
|
||
public function register()
|
||
{
|
||
$logger = new Writer(new \Monolog\Logger('log'), $this->app['events']);
|
||
$this->app->instance('log', $logger);
|
||
if (isset($this->app['log.setup'])) {
|
||
call_user_func($this->app['log.setup'], $logger);
|
||
}
|
||
}
|
||
public function provides()
|
||
{
|
||
return array('log');
|
||
}
|
||
}
|
||
namespace Illuminate\Log;
|
||
|
||
use Closure;
|
||
use Illuminate\Events\Dispatcher;
|
||
use Monolog\Handler\StreamHandler;
|
||
use Monolog\Logger as MonologLogger;
|
||
use Monolog\Handler\RotatingFileHandler;
|
||
class Writer
|
||
{
|
||
protected $monolog;
|
||
protected $levels = array('debug', 'info', 'notice', 'warning', 'error', 'critical', 'alert', 'emergency');
|
||
protected $dispatcher;
|
||
public function __construct(MonologLogger $monolog, Dispatcher $dispatcher = null)
|
||
{
|
||
$this->monolog = $monolog;
|
||
if (isset($dispatcher)) {
|
||
$this->dispatcher = $dispatcher;
|
||
}
|
||
}
|
||
public function useFiles($path, $level = 'debug')
|
||
{
|
||
$level = $this->parseLevel($level);
|
||
$this->monolog->pushHandler(new StreamHandler($path, $level));
|
||
}
|
||
public function useDailyFiles($path, $days = 0, $level = 'debug')
|
||
{
|
||
$level = $this->parseLevel($level);
|
||
$this->monolog->pushHandler(new RotatingFileHandler($path, $days, $level));
|
||
}
|
||
protected function parseLevel($level)
|
||
{
|
||
switch ($level) {
|
||
case 'debug':
|
||
return MonologLogger::DEBUG;
|
||
case 'info':
|
||
return MonologLogger::INFO;
|
||
case 'notice':
|
||
return MonologLogger::NOTICE;
|
||
case 'warning':
|
||
return MonologLogger::WARNING;
|
||
case 'error':
|
||
return MonologLogger::ERROR;
|
||
case 'critical':
|
||
return MonologLogger::CRITICAL;
|
||
case 'alert':
|
||
return MonologLogger::ALERT;
|
||
case 'emergency':
|
||
return MonologLogger::EMERGENCY;
|
||
default:
|
||
throw new \InvalidArgumentException('Invalid log level.');
|
||
}
|
||
}
|
||
public function getMonolog()
|
||
{
|
||
return $this->monolog;
|
||
}
|
||
public function listen(Closure $callback)
|
||
{
|
||
if (!isset($this->dispatcher)) {
|
||
throw new \RuntimeException('Events dispatcher has not been set.');
|
||
}
|
||
$this->dispatcher->listen('illuminate.log', $callback);
|
||
}
|
||
public function getEventDispatcher()
|
||
{
|
||
return $this->dispatcher;
|
||
}
|
||
public function setEventDispatcher(Dispatcher $dispatcher)
|
||
{
|
||
$this->dispatcher = $dispatcher;
|
||
}
|
||
protected function fireLogEvent($level, $message, array $context = array())
|
||
{
|
||
if (isset($this->dispatcher)) {
|
||
$this->dispatcher->fire('illuminate.log', compact('level', 'message', 'context'));
|
||
}
|
||
}
|
||
public function __call($method, $parameters)
|
||
{
|
||
if (in_array($method, $this->levels)) {
|
||
call_user_func_array(array($this, 'fireLogEvent'), array_merge(array($method), $parameters));
|
||
$method = 'add' . ucfirst($method);
|
||
return call_user_func_array(array($this->monolog, $method), $parameters);
|
||
}
|
||
throw new \BadMethodCallException("Method [{$method}] does not exist.");
|
||
}
|
||
}
|
||
namespace Monolog;
|
||
|
||
use Monolog\Handler\HandlerInterface;
|
||
use Monolog\Handler\StreamHandler;
|
||
use Psr\Log\LoggerInterface;
|
||
use Psr\Log\InvalidArgumentException;
|
||
class Logger implements LoggerInterface
|
||
{
|
||
const DEBUG = 100;
|
||
const INFO = 200;
|
||
const NOTICE = 250;
|
||
const WARNING = 300;
|
||
const ERROR = 400;
|
||
const CRITICAL = 500;
|
||
const ALERT = 550;
|
||
const EMERGENCY = 600;
|
||
protected static $levels = array(100 => 'DEBUG', 200 => 'INFO', 250 => 'NOTICE', 300 => 'WARNING', 400 => 'ERROR', 500 => 'CRITICAL', 550 => 'ALERT', 600 => 'EMERGENCY');
|
||
protected static $timezone;
|
||
protected $name;
|
||
protected $handlers;
|
||
protected $processors;
|
||
public function __construct($name, array $handlers = array(), array $processors = array())
|
||
{
|
||
$this->name = $name;
|
||
$this->handlers = $handlers;
|
||
$this->processors = $processors;
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->name;
|
||
}
|
||
public function pushHandler(HandlerInterface $handler)
|
||
{
|
||
array_unshift($this->handlers, $handler);
|
||
}
|
||
public function popHandler()
|
||
{
|
||
if (!$this->handlers) {
|
||
throw new \LogicException('You tried to pop from an empty handler stack.');
|
||
}
|
||
return array_shift($this->handlers);
|
||
}
|
||
public function pushProcessor($callback)
|
||
{
|
||
if (!is_callable($callback)) {
|
||
throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given');
|
||
}
|
||
array_unshift($this->processors, $callback);
|
||
}
|
||
public function popProcessor()
|
||
{
|
||
if (!$this->processors) {
|
||
throw new \LogicException('You tried to pop from an empty processor stack.');
|
||
}
|
||
return array_shift($this->processors);
|
||
}
|
||
public function addRecord($level, $message, array $context = array())
|
||
{
|
||
if (!$this->handlers) {
|
||
$this->pushHandler(new StreamHandler('php://stderr', static::DEBUG));
|
||
}
|
||
if (!static::$timezone) {
|
||
static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC');
|
||
}
|
||
$record = array('message' => (string) $message, 'context' => $context, 'level' => $level, 'level_name' => static::getLevelName($level), 'channel' => $this->name, 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone)->setTimezone(static::$timezone), 'extra' => array());
|
||
$handlerKey = null;
|
||
foreach ($this->handlers as $key => $handler) {
|
||
if ($handler->isHandling($record)) {
|
||
$handlerKey = $key;
|
||
break;
|
||
}
|
||
}
|
||
if (null === $handlerKey) {
|
||
return false;
|
||
}
|
||
foreach ($this->processors as $processor) {
|
||
$record = call_user_func($processor, $record);
|
||
}
|
||
while (isset($this->handlers[$handlerKey]) && false === $this->handlers[$handlerKey]->handle($record)) {
|
||
$handlerKey++;
|
||
}
|
||
return true;
|
||
}
|
||
public function addDebug($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::DEBUG, $message, $context);
|
||
}
|
||
public function addInfo($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::INFO, $message, $context);
|
||
}
|
||
public function addNotice($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::NOTICE, $message, $context);
|
||
}
|
||
public function addWarning($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::WARNING, $message, $context);
|
||
}
|
||
public function addError($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::ERROR, $message, $context);
|
||
}
|
||
public function addCritical($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::CRITICAL, $message, $context);
|
||
}
|
||
public function addAlert($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::ALERT, $message, $context);
|
||
}
|
||
public function addEmergency($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::EMERGENCY, $message, $context);
|
||
}
|
||
public static function getLevels()
|
||
{
|
||
return array_flip(static::$levels);
|
||
}
|
||
public static function getLevelName($level)
|
||
{
|
||
if (!isset(static::$levels[$level])) {
|
||
throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(static::$levels)));
|
||
}
|
||
return static::$levels[$level];
|
||
}
|
||
public function isHandling($level)
|
||
{
|
||
$record = array('level' => $level);
|
||
foreach ($this->handlers as $handler) {
|
||
if ($handler->isHandling($record)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
public function log($level, $message, array $context = array())
|
||
{
|
||
if (is_string($level) && defined(__CLASS__ . '::' . strtoupper($level))) {
|
||
$level = constant(__CLASS__ . '::' . strtoupper($level));
|
||
}
|
||
return $this->addRecord($level, $message, $context);
|
||
}
|
||
public function debug($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::DEBUG, $message, $context);
|
||
}
|
||
public function info($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::INFO, $message, $context);
|
||
}
|
||
public function notice($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::NOTICE, $message, $context);
|
||
}
|
||
public function warn($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::WARNING, $message, $context);
|
||
}
|
||
public function warning($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::WARNING, $message, $context);
|
||
}
|
||
public function err($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::ERROR, $message, $context);
|
||
}
|
||
public function error($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::ERROR, $message, $context);
|
||
}
|
||
public function crit($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::CRITICAL, $message, $context);
|
||
}
|
||
public function critical($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::CRITICAL, $message, $context);
|
||
}
|
||
public function alert($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::ALERT, $message, $context);
|
||
}
|
||
public function emerg($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::EMERGENCY, $message, $context);
|
||
}
|
||
public function emergency($message, array $context = array())
|
||
{
|
||
return $this->addRecord(static::EMERGENCY, $message, $context);
|
||
}
|
||
}
|
||
namespace Psr\Log;
|
||
|
||
interface LoggerInterface
|
||
{
|
||
public function emergency($message, array $context = array());
|
||
public function alert($message, array $context = array());
|
||
public function critical($message, array $context = array());
|
||
public function error($message, array $context = array());
|
||
public function warning($message, array $context = array());
|
||
public function notice($message, array $context = array());
|
||
public function info($message, array $context = array());
|
||
public function debug($message, array $context = array());
|
||
public function log($level, $message, array $context = array());
|
||
}
|
||
namespace Monolog\Handler;
|
||
|
||
use Monolog\Logger;
|
||
use Monolog\Formatter\FormatterInterface;
|
||
use Monolog\Formatter\LineFormatter;
|
||
abstract class AbstractHandler implements HandlerInterface
|
||
{
|
||
protected $level = Logger::DEBUG;
|
||
protected $bubble = false;
|
||
protected $formatter;
|
||
protected $processors = array();
|
||
public function __construct($level = Logger::DEBUG, $bubble = true)
|
||
{
|
||
$this->level = $level;
|
||
$this->bubble = $bubble;
|
||
}
|
||
public function isHandling(array $record)
|
||
{
|
||
return $record['level'] >= $this->level;
|
||
}
|
||
public function handleBatch(array $records)
|
||
{
|
||
foreach ($records as $record) {
|
||
$this->handle($record);
|
||
}
|
||
}
|
||
public function close()
|
||
{
|
||
|
||
}
|
||
public function pushProcessor($callback)
|
||
{
|
||
if (!is_callable($callback)) {
|
||
throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given');
|
||
}
|
||
array_unshift($this->processors, $callback);
|
||
}
|
||
public function popProcessor()
|
||
{
|
||
if (!$this->processors) {
|
||
throw new \LogicException('You tried to pop from an empty processor stack.');
|
||
}
|
||
return array_shift($this->processors);
|
||
}
|
||
public function setFormatter(FormatterInterface $formatter)
|
||
{
|
||
$this->formatter = $formatter;
|
||
}
|
||
public function getFormatter()
|
||
{
|
||
if (!$this->formatter) {
|
||
$this->formatter = $this->getDefaultFormatter();
|
||
}
|
||
return $this->formatter;
|
||
}
|
||
public function setLevel($level)
|
||
{
|
||
$this->level = $level;
|
||
}
|
||
public function getLevel()
|
||
{
|
||
return $this->level;
|
||
}
|
||
public function setBubble($bubble)
|
||
{
|
||
$this->bubble = $bubble;
|
||
}
|
||
public function getBubble()
|
||
{
|
||
return $this->bubble;
|
||
}
|
||
public function __destruct()
|
||
{
|
||
try {
|
||
$this->close();
|
||
} catch (\Exception $e) {
|
||
|
||
}
|
||
}
|
||
protected function getDefaultFormatter()
|
||
{
|
||
return new LineFormatter();
|
||
}
|
||
}
|
||
namespace Monolog\Handler;
|
||
|
||
abstract class AbstractProcessingHandler extends AbstractHandler
|
||
{
|
||
public function handle(array $record)
|
||
{
|
||
if ($record['level'] < $this->level) {
|
||
return false;
|
||
}
|
||
$record = $this->processRecord($record);
|
||
$record['formatted'] = $this->getFormatter()->format($record);
|
||
$this->write($record);
|
||
return false === $this->bubble;
|
||
}
|
||
protected abstract function write(array $record);
|
||
protected function processRecord(array $record)
|
||
{
|
||
if ($this->processors) {
|
||
foreach ($this->processors as $processor) {
|
||
$record = call_user_func($processor, $record);
|
||
}
|
||
}
|
||
return $record;
|
||
}
|
||
}
|
||
namespace Monolog\Handler;
|
||
|
||
use Monolog\Logger;
|
||
class StreamHandler extends AbstractProcessingHandler
|
||
{
|
||
protected $stream;
|
||
protected $url;
|
||
public function __construct($stream, $level = Logger::DEBUG, $bubble = true)
|
||
{
|
||
parent::__construct($level, $bubble);
|
||
if (is_resource($stream)) {
|
||
$this->stream = $stream;
|
||
} else {
|
||
$this->url = $stream;
|
||
}
|
||
}
|
||
public function close()
|
||
{
|
||
if (is_resource($this->stream)) {
|
||
fclose($this->stream);
|
||
}
|
||
$this->stream = null;
|
||
}
|
||
protected function write(array $record)
|
||
{
|
||
if (null === $this->stream) {
|
||
if (!$this->url) {
|
||
throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
|
||
}
|
||
$errorMessage = null;
|
||
set_error_handler(function ($code, $msg) use(&$errorMessage) {
|
||
$errorMessage = preg_replace('{^fopen\\(.*?\\): }', '', $msg);
|
||
});
|
||
$this->stream = fopen($this->url, 'a');
|
||
restore_error_handler();
|
||
if (!is_resource($this->stream)) {
|
||
$this->stream = null;
|
||
throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $errorMessage, $this->url));
|
||
}
|
||
}
|
||
fwrite($this->stream, (string) $record['formatted']);
|
||
}
|
||
}
|
||
namespace Monolog\Handler;
|
||
|
||
use Monolog\Logger;
|
||
class RotatingFileHandler extends StreamHandler
|
||
{
|
||
protected $filename;
|
||
protected $maxFiles;
|
||
protected $mustRotate;
|
||
protected $nextRotation;
|
||
public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true)
|
||
{
|
||
$this->filename = $filename;
|
||
$this->maxFiles = (int) $maxFiles;
|
||
$this->nextRotation = new \DateTime('tomorrow');
|
||
parent::__construct($this->getTimedFilename(), $level, $bubble);
|
||
}
|
||
public function close()
|
||
{
|
||
parent::close();
|
||
if (true === $this->mustRotate) {
|
||
$this->rotate();
|
||
}
|
||
}
|
||
protected function write(array $record)
|
||
{
|
||
if (null === $this->mustRotate) {
|
||
$this->mustRotate = !file_exists($this->url);
|
||
}
|
||
if ($this->nextRotation < $record['datetime']) {
|
||
$this->mustRotate = true;
|
||
$this->close();
|
||
}
|
||
parent::write($record);
|
||
}
|
||
protected function rotate()
|
||
{
|
||
$this->url = $this->getTimedFilename();
|
||
$this->nextRotation = new \DateTime('tomorrow');
|
||
if (0 === $this->maxFiles) {
|
||
return;
|
||
}
|
||
$fileInfo = pathinfo($this->filename);
|
||
$glob = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '-*';
|
||
if (!empty($fileInfo['extension'])) {
|
||
$glob .= '.' . $fileInfo['extension'];
|
||
}
|
||
$iterator = new \GlobIterator($glob);
|
||
$count = $iterator->count();
|
||
if ($this->maxFiles >= $count) {
|
||
return;
|
||
}
|
||
$array = iterator_to_array($iterator);
|
||
usort($array, function ($a, $b) {
|
||
return strcmp($b->getFilename(), $a->getFilename());
|
||
});
|
||
foreach (array_slice($array, $this->maxFiles) as $file) {
|
||
if ($file->isWritable()) {
|
||
unlink($file->getRealPath());
|
||
}
|
||
}
|
||
}
|
||
protected function getTimedFilename()
|
||
{
|
||
$fileInfo = pathinfo($this->filename);
|
||
$timedFilename = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '-' . date('Y-m-d');
|
||
if (!empty($fileInfo['extension'])) {
|
||
$timedFilename .= '.' . $fileInfo['extension'];
|
||
}
|
||
return $timedFilename;
|
||
}
|
||
}
|
||
namespace Monolog\Handler;
|
||
|
||
use Monolog\Formatter\FormatterInterface;
|
||
interface HandlerInterface
|
||
{
|
||
public function isHandling(array $record);
|
||
public function handle(array $record);
|
||
public function handleBatch(array $records);
|
||
public function pushProcessor($callback);
|
||
public function popProcessor();
|
||
public function setFormatter(FormatterInterface $formatter);
|
||
public function getFormatter();
|
||
}
|
||
namespace Illuminate\Support\Facades;
|
||
|
||
class App extends Facade
|
||
{
|
||
protected static function getFacadeAccessor()
|
||
{
|
||
return 'app';
|
||
}
|
||
}
|
||
namespace Illuminate\Exception;
|
||
|
||
use Exception;
|
||
interface ExceptionDisplayerInterface
|
||
{
|
||
public function display(Exception $exception);
|
||
}
|
||
namespace Illuminate\Exception;
|
||
|
||
use Exception;
|
||
use Symfony\Component\Debug\ExceptionHandler;
|
||
class SymfonyDisplayer implements ExceptionDisplayerInterface
|
||
{
|
||
protected $symfony;
|
||
public function __construct(ExceptionHandler $symfony)
|
||
{
|
||
$this->symfony = $symfony;
|
||
}
|
||
public function display(Exception $exception)
|
||
{
|
||
$this->symfony->handle($exception);
|
||
}
|
||
}
|
||
namespace Illuminate\Exception;
|
||
|
||
use Exception;
|
||
use Whoops\Run;
|
||
class WhoopsDisplayer implements ExceptionDisplayerInterface
|
||
{
|
||
protected $whoops;
|
||
protected $runningInConsole;
|
||
public function __construct(Run $whoops, $runningInConsole)
|
||
{
|
||
$this->whoops = $whoops;
|
||
$this->runningInConsole = $runningInConsole;
|
||
}
|
||
public function display(Exception $exception)
|
||
{
|
||
if (!$this->runningInConsole and !headers_sent()) {
|
||
header('HTTP/1.1 500 Internal Server Error');
|
||
}
|
||
$this->whoops->handleException($exception);
|
||
}
|
||
}
|
||
namespace Illuminate\Exception;
|
||
|
||
use Closure;
|
||
use ErrorException;
|
||
use ReflectionFunction;
|
||
use Illuminate\Support\Contracts\ResponsePreparerInterface;
|
||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||
use Symfony\Component\Debug\Exception\FatalErrorException as FatalError;
|
||
class Handler
|
||
{
|
||
protected $responsePreparer;
|
||
protected $plainDisplayer;
|
||
protected $debugDisplayer;
|
||
protected $debug;
|
||
protected $handlers = array();
|
||
protected $handled = array();
|
||
public function __construct(ResponsePreparerInterface $responsePreparer, ExceptionDisplayerInterface $plainDisplayer, ExceptionDisplayerInterface $debugDisplayer, $debug = true)
|
||
{
|
||
$this->debug = $debug;
|
||
$this->plainDisplayer = $plainDisplayer;
|
||
$this->debugDisplayer = $debugDisplayer;
|
||
$this->responsePreparer = $responsePreparer;
|
||
}
|
||
public function register($environment)
|
||
{
|
||
$this->registerErrorHandler();
|
||
$this->registerExceptionHandler();
|
||
if ($environment != 'testing') {
|
||
$this->registerShutdownHandler();
|
||
}
|
||
}
|
||
protected function registerErrorHandler()
|
||
{
|
||
set_error_handler(array($this, 'handleError'));
|
||
}
|
||
protected function registerExceptionHandler()
|
||
{
|
||
set_exception_handler(array($this, 'handleException'));
|
||
}
|
||
protected function registerShutdownHandler()
|
||
{
|
||
register_shutdown_function(array($this, 'handleShutdown'));
|
||
}
|
||
public function handleError($level, $message, $file, $line, $context)
|
||
{
|
||
if (error_reporting() & $level) {
|
||
$e = new ErrorException($message, $level, 0, $file, $line);
|
||
$this->handleException($e);
|
||
}
|
||
}
|
||
public function handleException($exception)
|
||
{
|
||
$response = $this->callCustomHandlers($exception);
|
||
if (!is_null($response)) {
|
||
$response = $this->prepareResponse($response);
|
||
$response->send();
|
||
} else {
|
||
$this->displayException($exception);
|
||
}
|
||
$this->bail();
|
||
}
|
||
public function handleShutdown()
|
||
{
|
||
$error = error_get_last();
|
||
if (!is_null($error)) {
|
||
extract($error);
|
||
if (!$this->isFatal($type)) {
|
||
return;
|
||
}
|
||
$this->handleException(new FatalError($message, $type, 0, $file, $line));
|
||
}
|
||
}
|
||
protected function isFatal($type)
|
||
{
|
||
return in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE));
|
||
}
|
||
public function handleConsole($exception)
|
||
{
|
||
return $this->callCustomHandlers($exception, true);
|
||
}
|
||
protected function callCustomHandlers($exception, $fromConsole = false)
|
||
{
|
||
foreach ($this->handlers as $handler) {
|
||
if (!$this->handlesException($handler, $exception)) {
|
||
continue;
|
||
} elseif ($exception instanceof HttpExceptionInterface) {
|
||
$code = $exception->getStatusCode();
|
||
} else {
|
||
$code = 500;
|
||
}
|
||
try {
|
||
$response = $handler($exception, $code, $fromConsole);
|
||
} catch (\Exception $e) {
|
||
$response = $this->formatException($e);
|
||
}
|
||
if (isset($response) and !is_null($response)) {
|
||
return $response;
|
||
}
|
||
}
|
||
}
|
||
protected function displayException($exception)
|
||
{
|
||
$displayer = $this->debug ? $this->debugDisplayer : $this->plainDisplayer;
|
||
$displayer->display($exception);
|
||
}
|
||
protected function handlesException(Closure $handler, $exception)
|
||
{
|
||
$reflection = new ReflectionFunction($handler);
|
||
return $reflection->getNumberOfParameters() == 0 or $this->hints($reflection, $exception);
|
||
}
|
||
protected function hints(ReflectionFunction $reflection, $exception)
|
||
{
|
||
$parameters = $reflection->getParameters();
|
||
$expected = $parameters[0];
|
||
return !$expected->getClass() or $expected->getClass()->isInstance($exception);
|
||
}
|
||
protected function formatException(\Exception $e)
|
||
{
|
||
$location = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
|
||
return 'Error in exception handler: ' . $location;
|
||
}
|
||
public function error(Closure $callback)
|
||
{
|
||
array_unshift($this->handlers, $callback);
|
||
}
|
||
public function pushError(Closure $callback)
|
||
{
|
||
$this->handlers[] = $callback;
|
||
}
|
||
protected function prepareResponse($response)
|
||
{
|
||
return $this->responsePreparer->prepareResponse($response);
|
||
}
|
||
protected function bail()
|
||
{
|
||
die(1);
|
||
}
|
||
public function setDebug($debug)
|
||
{
|
||
$this->debug = $debug;
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Facades;
|
||
|
||
class Route extends Facade
|
||
{
|
||
public static function is($name)
|
||
{
|
||
return static::$app['router']->currentRouteNamed($name);
|
||
}
|
||
public static function uses($action)
|
||
{
|
||
return static::$app['router']->currentRouteUses($action);
|
||
}
|
||
protected static function getFacadeAccessor()
|
||
{
|
||
return 'router';
|
||
}
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
class Route implements \Serializable
|
||
{
|
||
private $path = '/';
|
||
private $host = '';
|
||
private $schemes = array();
|
||
private $methods = array();
|
||
private $defaults = array();
|
||
private $requirements = array();
|
||
private $options = array();
|
||
private $compiled;
|
||
public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array())
|
||
{
|
||
$this->setPath($path);
|
||
$this->setDefaults($defaults);
|
||
$this->setRequirements($requirements);
|
||
$this->setOptions($options);
|
||
$this->setHost($host);
|
||
if ($schemes) {
|
||
$this->setSchemes($schemes);
|
||
}
|
||
if ($methods) {
|
||
$this->setMethods($methods);
|
||
}
|
||
}
|
||
public function serialize()
|
||
{
|
||
return serialize(array('path' => $this->path, 'host' => $this->host, 'defaults' => $this->defaults, 'requirements' => $this->requirements, 'options' => $this->options, 'schemes' => $this->schemes, 'methods' => $this->methods));
|
||
}
|
||
public function unserialize($data)
|
||
{
|
||
$data = unserialize($data);
|
||
$this->path = $data['path'];
|
||
$this->host = $data['host'];
|
||
$this->defaults = $data['defaults'];
|
||
$this->requirements = $data['requirements'];
|
||
$this->options = $data['options'];
|
||
$this->schemes = $data['schemes'];
|
||
$this->methods = $data['methods'];
|
||
}
|
||
public function getPattern()
|
||
{
|
||
return $this->path;
|
||
}
|
||
public function setPattern($pattern)
|
||
{
|
||
return $this->setPath($pattern);
|
||
}
|
||
public function getPath()
|
||
{
|
||
return $this->path;
|
||
}
|
||
public function setPath($pattern)
|
||
{
|
||
$this->path = '/' . ltrim(trim($pattern), '/');
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getHost()
|
||
{
|
||
return $this->host;
|
||
}
|
||
public function setHost($pattern)
|
||
{
|
||
$this->host = (string) $pattern;
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getSchemes()
|
||
{
|
||
return $this->schemes;
|
||
}
|
||
public function setSchemes($schemes)
|
||
{
|
||
$this->schemes = array_map('strtolower', (array) $schemes);
|
||
if ($this->schemes) {
|
||
$this->requirements['_scheme'] = implode('|', $this->schemes);
|
||
} else {
|
||
unset($this->requirements['_scheme']);
|
||
}
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getMethods()
|
||
{
|
||
return $this->methods;
|
||
}
|
||
public function setMethods($methods)
|
||
{
|
||
$this->methods = array_map('strtoupper', (array) $methods);
|
||
if ($this->methods) {
|
||
$this->requirements['_method'] = implode('|', $this->methods);
|
||
} else {
|
||
unset($this->requirements['_method']);
|
||
}
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getOptions()
|
||
{
|
||
return $this->options;
|
||
}
|
||
public function setOptions(array $options)
|
||
{
|
||
$this->options = array('compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler');
|
||
return $this->addOptions($options);
|
||
}
|
||
public function addOptions(array $options)
|
||
{
|
||
foreach ($options as $name => $option) {
|
||
$this->options[$name] = $option;
|
||
}
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function setOption($name, $value)
|
||
{
|
||
$this->options[$name] = $value;
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getOption($name)
|
||
{
|
||
return isset($this->options[$name]) ? $this->options[$name] : null;
|
||
}
|
||
public function hasOption($name)
|
||
{
|
||
return array_key_exists($name, $this->options);
|
||
}
|
||
public function getDefaults()
|
||
{
|
||
return $this->defaults;
|
||
}
|
||
public function setDefaults(array $defaults)
|
||
{
|
||
$this->defaults = array();
|
||
return $this->addDefaults($defaults);
|
||
}
|
||
public function addDefaults(array $defaults)
|
||
{
|
||
foreach ($defaults as $name => $default) {
|
||
$this->defaults[$name] = $default;
|
||
}
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getDefault($name)
|
||
{
|
||
return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
|
||
}
|
||
public function hasDefault($name)
|
||
{
|
||
return array_key_exists($name, $this->defaults);
|
||
}
|
||
public function setDefault($name, $default)
|
||
{
|
||
$this->defaults[$name] = $default;
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getRequirements()
|
||
{
|
||
return $this->requirements;
|
||
}
|
||
public function setRequirements(array $requirements)
|
||
{
|
||
$this->requirements = array();
|
||
return $this->addRequirements($requirements);
|
||
}
|
||
public function addRequirements(array $requirements)
|
||
{
|
||
foreach ($requirements as $key => $regex) {
|
||
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
||
}
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function getRequirement($key)
|
||
{
|
||
return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
|
||
}
|
||
public function hasRequirement($key)
|
||
{
|
||
return array_key_exists($key, $this->requirements);
|
||
}
|
||
public function setRequirement($key, $regex)
|
||
{
|
||
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
||
$this->compiled = null;
|
||
return $this;
|
||
}
|
||
public function compile()
|
||
{
|
||
if (null !== $this->compiled) {
|
||
return $this->compiled;
|
||
}
|
||
$class = $this->getOption('compiler_class');
|
||
return $this->compiled = $class::compile($this);
|
||
}
|
||
private function sanitizeRequirement($key, $regex)
|
||
{
|
||
if (!is_string($regex)) {
|
||
throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key));
|
||
}
|
||
if ('' !== $regex && '^' === $regex[0]) {
|
||
$regex = (string) substr($regex, 1);
|
||
}
|
||
if ('$' === substr($regex, -1)) {
|
||
$regex = substr($regex, 0, -1);
|
||
}
|
||
if ('' === $regex) {
|
||
throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
|
||
}
|
||
if ('_scheme' === $key) {
|
||
$this->setSchemes(explode('|', $regex));
|
||
} elseif ('_method' === $key) {
|
||
$this->setMethods(explode('|', $regex));
|
||
}
|
||
return $regex;
|
||
}
|
||
}
|
||
namespace Illuminate\Routing;
|
||
|
||
use Illuminate\Http\Response;
|
||
use Symfony\Component\HttpFoundation\Request;
|
||
use Symfony\Component\Routing\Route as BaseRoute;
|
||
class Route extends BaseRoute
|
||
{
|
||
protected $router;
|
||
protected $parameters;
|
||
protected $parsedParameters;
|
||
public function run(Request $request)
|
||
{
|
||
$this->parsedParameters = null;
|
||
$response = $this->callBeforeFilters($request);
|
||
if (!isset($response)) {
|
||
$response = $this->callCallable();
|
||
} else {
|
||
$fromFilter = true;
|
||
}
|
||
$response = $this->router->prepare($response, $request);
|
||
if (!isset($fromFilter)) {
|
||
$this->callAfterFilters($request, $response);
|
||
}
|
||
return $response;
|
||
}
|
||
protected function callCallable()
|
||
{
|
||
$variables = array_values($this->getParametersWithoutDefaults());
|
||
return call_user_func_array($this->getOption('_call'), $variables);
|
||
}
|
||
protected function callBeforeFilters(Request $request)
|
||
{
|
||
$before = $this->getAllBeforeFilters($request);
|
||
$response = null;
|
||
foreach ($before as $filter) {
|
||
$response = $this->callFilter($filter, $request);
|
||
if (!is_null($response)) {
|
||
return $response;
|
||
}
|
||
}
|
||
}
|
||
protected function getAllBeforeFilters(Request $request)
|
||
{
|
||
$before = $this->getBeforeFilters();
|
||
return array_merge($before, $this->router->findPatternFilters($request));
|
||
}
|
||
protected function callAfterFilters(Request $request, $response)
|
||
{
|
||
foreach ($this->getAfterFilters() as $filter) {
|
||
$this->callFilter($filter, $request, array($response));
|
||
}
|
||
}
|
||
public function callFilter($name, Request $request, array $params = array())
|
||
{
|
||
if (!$this->router->filtersEnabled()) {
|
||
return;
|
||
}
|
||
$merge = array($this->router->getCurrentRoute(), $request);
|
||
$params = array_merge($merge, $params);
|
||
list($name, $params) = $this->parseFilter($name, $params);
|
||
if (!is_null($callable = $this->router->getFilter($name))) {
|
||
return call_user_func_array($callable, $params);
|
||
}
|
||
}
|
||
protected function parseFilter($name, $parameters = array())
|
||
{
|
||
if (str_contains($name, ':')) {
|
||
$segments = explode(':', $name);
|
||
$name = $segments[0];
|
||
$arguments = explode(',', $segments[1]);
|
||
$parameters = array_merge($parameters, $arguments);
|
||
}
|
||
return array($name, $parameters);
|
||
}
|
||
public function getParameter($name, $default = null)
|
||
{
|
||
return array_get($this->getParameters(), $name, $default);
|
||
}
|
||
public function getParameters()
|
||
{
|
||
if (isset($this->parsedParameters)) {
|
||
return $this->parsedParameters;
|
||
}
|
||
$variables = $this->compile()->getVariables();
|
||
$parameters = array();
|
||
foreach ($variables as $variable) {
|
||
$parameters[$variable] = $this->resolveParameter($variable);
|
||
}
|
||
return $this->parsedParameters = $parameters;
|
||
}
|
||
protected function resolveParameter($key)
|
||
{
|
||
$value = $this->parameters[$key];
|
||
if ($this->router->hasBinder($key)) {
|
||
return $this->router->performBinding($key, $value, $this);
|
||
}
|
||
return $value;
|
||
}
|
||
public function getParametersWithoutDefaults()
|
||
{
|
||
$parameters = $this->getParameters();
|
||
foreach ($parameters as $key => $value) {
|
||
if ($this->isMissingDefault($key, $value)) {
|
||
unset($parameters[$key]);
|
||
}
|
||
}
|
||
return $parameters;
|
||
}
|
||
protected function isMissingDefault($key, $value)
|
||
{
|
||
return $this->isOptional($key) and is_null($value);
|
||
}
|
||
public function isOptional($key)
|
||
{
|
||
return array_key_exists($key, $this->getDefaults());
|
||
}
|
||
public function getParameterKeys()
|
||
{
|
||
return $this->compile()->getVariables();
|
||
}
|
||
public function where($name, $expression = null)
|
||
{
|
||
if (is_array($name)) {
|
||
return $this->setArrayOfWheres($name);
|
||
}
|
||
$this->setRequirement($name, $expression);
|
||
return $this;
|
||
}
|
||
protected function setArrayOfWheres(array $wheres)
|
||
{
|
||
foreach ($wheres as $name => $expression) {
|
||
$this->where($name, $expression);
|
||
}
|
||
return $this;
|
||
}
|
||
public function defaults($key, $value)
|
||
{
|
||
$this->setDefault($key, $value);
|
||
return $this;
|
||
}
|
||
public function before()
|
||
{
|
||
$this->setBeforeFilters(func_get_args());
|
||
return $this;
|
||
}
|
||
public function after()
|
||
{
|
||
$this->setAfterFilters(func_get_args());
|
||
return $this;
|
||
}
|
||
public function getAction()
|
||
{
|
||
return $this->getOption('_uses');
|
||
}
|
||
public function getBeforeFilters()
|
||
{
|
||
return $this->getOption('_before') ?: array();
|
||
}
|
||
public function setBeforeFilters($value)
|
||
{
|
||
$filters = is_string($value) ? explode('|', $value) : (array) $value;
|
||
$this->setOption('_before', array_merge($this->getBeforeFilters(), $filters));
|
||
}
|
||
public function getAfterFilters()
|
||
{
|
||
return $this->getOption('_after') ?: array();
|
||
}
|
||
public function setAfterFilters($value)
|
||
{
|
||
$filters = is_string($value) ? explode('|', $value) : (array) $value;
|
||
$this->setOption('_after', array_merge($this->getAfterFilters(), $filters));
|
||
}
|
||
public function setParameters($parameters)
|
||
{
|
||
$this->parameters = $parameters;
|
||
}
|
||
public function setRouter(Router $router)
|
||
{
|
||
$this->router = $router;
|
||
return $this;
|
||
}
|
||
}
|
||
namespace Illuminate\View\Engines;
|
||
|
||
use Closure;
|
||
class EngineResolver
|
||
{
|
||
protected $resolvers = array();
|
||
protected $resolved = array();
|
||
public function register($engine, Closure $resolver)
|
||
{
|
||
$this->resolvers[$engine] = $resolver;
|
||
}
|
||
public function resolve($engine)
|
||
{
|
||
if (!isset($this->resolved[$engine])) {
|
||
$this->resolved[$engine] = call_user_func($this->resolvers[$engine]);
|
||
}
|
||
return $this->resolved[$engine];
|
||
}
|
||
}
|
||
namespace Illuminate\View;
|
||
|
||
interface ViewFinderInterface
|
||
{
|
||
public function find($view);
|
||
public function addLocation($location);
|
||
public function addNamespace($namespace, $hint);
|
||
public function addExtension($extension);
|
||
}
|
||
namespace Illuminate\View;
|
||
|
||
use Illuminate\Filesystem\Filesystem;
|
||
class FileViewFinder implements ViewFinderInterface
|
||
{
|
||
protected $files;
|
||
protected $paths;
|
||
protected $hints = array();
|
||
protected $extensions = array('blade.php', 'php');
|
||
public function __construct(Filesystem $files, array $paths, array $extensions = null)
|
||
{
|
||
$this->files = $files;
|
||
$this->paths = $paths;
|
||
if (isset($extensions)) {
|
||
$this->extensions = $extensions;
|
||
}
|
||
}
|
||
public function find($name)
|
||
{
|
||
if (strpos($name, '::') !== false) {
|
||
return $this->findNamedPathView($name);
|
||
}
|
||
return $this->findInPaths($name, $this->paths);
|
||
}
|
||
protected function findNamedPathView($name)
|
||
{
|
||
list($namespace, $view) = $this->getNamespaceSegments($name);
|
||
return $this->findInPaths($view, $this->hints[$namespace]);
|
||
}
|
||
protected function getNamespaceSegments($name)
|
||
{
|
||
$segments = explode('::', $name);
|
||
if (count($segments) != 2) {
|
||
throw new \InvalidArgumentException("View [{$name}] has an invalid name.");
|
||
}
|
||
if (!isset($this->hints[$segments[0]])) {
|
||
throw new \InvalidArgumentException("No hint path defined for [{$segments[0]}].");
|
||
}
|
||
return $segments;
|
||
}
|
||
protected function findInPaths($name, $paths)
|
||
{
|
||
foreach ((array) $paths as $path) {
|
||
foreach ($this->getPossibleViewFiles($name) as $file) {
|
||
if ($this->files->exists($viewPath = $path . '/' . $file)) {
|
||
return $viewPath;
|
||
}
|
||
}
|
||
}
|
||
throw new \InvalidArgumentException("View [{$name}] not found.");
|
||
}
|
||
protected function getPossibleViewFiles($name)
|
||
{
|
||
return array_map(function ($extension) use($name) {
|
||
return str_replace('.', '/', $name) . '.' . $extension;
|
||
}, $this->extensions);
|
||
}
|
||
public function addLocation($location)
|
||
{
|
||
$this->paths[] = $location;
|
||
}
|
||
public function addNamespace($namespace, $hints)
|
||
{
|
||
$hints = (array) $hints;
|
||
if (isset($this->hints[$namespace])) {
|
||
$hints = array_merge($this->hints[$namespace], $hints);
|
||
}
|
||
$this->hints[$namespace] = $hints;
|
||
}
|
||
public function addExtension($extension)
|
||
{
|
||
if (($index = array_search($extension, $this->extensions)) !== false) {
|
||
unset($this->extensions[$index]);
|
||
}
|
||
array_unshift($this->extensions, $extension);
|
||
}
|
||
public function getFilesystem()
|
||
{
|
||
return $this->files;
|
||
}
|
||
public function getPaths()
|
||
{
|
||
return $this->paths;
|
||
}
|
||
public function getHints()
|
||
{
|
||
return $this->hints;
|
||
}
|
||
public function getExtensions()
|
||
{
|
||
return $this->extensions;
|
||
}
|
||
}
|
||
namespace Illuminate\View;
|
||
|
||
use Closure;
|
||
use Illuminate\Events\Dispatcher;
|
||
use Illuminate\Container\Container;
|
||
use Illuminate\View\Engines\EngineResolver;
|
||
use Illuminate\Support\Contracts\ArrayableInterface as Arrayable;
|
||
class Environment
|
||
{
|
||
protected $engines;
|
||
protected $finder;
|
||
protected $events;
|
||
protected $container;
|
||
protected $shared = array();
|
||
protected $names = array();
|
||
protected $extensions = array('blade.php' => 'blade', 'php' => 'php');
|
||
protected $composers = array();
|
||
protected $sections = array();
|
||
protected $sectionStack = array();
|
||
protected $renderCount = 0;
|
||
public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events)
|
||
{
|
||
$this->finder = $finder;
|
||
$this->events = $events;
|
||
$this->engines = $engines;
|
||
$this->share('__env', $this);
|
||
}
|
||
public function make($view, $data = array(), $mergeData = array())
|
||
{
|
||
$path = $this->finder->find($view);
|
||
$data = array_merge($mergeData, $this->parseData($data));
|
||
return new View($this, $this->getEngineFromPath($path), $view, $path, $data);
|
||
}
|
||
protected function parseData($data)
|
||
{
|
||
return $data instanceof Arrayable ? $data->toArray() : $data;
|
||
}
|
||
public function of($view, $data = array())
|
||
{
|
||
return $this->make($this->names[$view], $data);
|
||
}
|
||
public function name($view, $name)
|
||
{
|
||
$this->names[$name] = $view;
|
||
}
|
||
public function exists($view)
|
||
{
|
||
try {
|
||
$this->finder->find($view);
|
||
} catch (\InvalidArgumentException $e) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
public function renderEach($view, $data, $iterator, $empty = 'raw|')
|
||
{
|
||
$result = '';
|
||
if (count($data) > 0) {
|
||
foreach ($data as $key => $value) {
|
||
$data = array('key' => $key, $iterator => $value);
|
||
$result .= $this->make($view, $data)->render();
|
||
}
|
||
} else {
|
||
if (starts_with($empty, 'raw|')) {
|
||
$result = substr($empty, 4);
|
||
} else {
|
||
$result = $this->make($empty)->render();
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
protected function getEngineFromPath($path)
|
||
{
|
||
$engine = $this->extensions[$this->getExtension($path)];
|
||
return $this->engines->resolve($engine);
|
||
}
|
||
protected function getExtension($path)
|
||
{
|
||
$extensions = array_keys($this->extensions);
|
||
return array_first($extensions, function ($key, $value) use($path) {
|
||
return ends_with($path, $value);
|
||
});
|
||
}
|
||
public function share($key, $value = null)
|
||
{
|
||
if (!is_array($key)) {
|
||
return $this->shared[$key] = $value;
|
||
}
|
||
foreach ($key as $innerKey => $innerValue) {
|
||
$this->share($innerKey, $innerValue);
|
||
}
|
||
}
|
||
public function composer($views, $callback)
|
||
{
|
||
$composers = array();
|
||
foreach ((array) $views as $view) {
|
||
$composers[] = $this->addComposer($view, $callback);
|
||
}
|
||
return $composers;
|
||
}
|
||
protected function addComposer($view, $callback)
|
||
{
|
||
if ($callback instanceof Closure) {
|
||
$this->events->listen('composing: ' . $view, $callback);
|
||
return $callback;
|
||
} elseif (is_string($callback)) {
|
||
return $this->addClassComposer($view, $callback);
|
||
}
|
||
}
|
||
protected function addClassComposer($view, $class)
|
||
{
|
||
$name = 'composing: ' . $view;
|
||
$callback = $this->buildClassComposerCallback($class);
|
||
$this->events->listen($name, $callback);
|
||
return $callback;
|
||
}
|
||
protected function buildClassComposerCallback($class)
|
||
{
|
||
$container = $this->container;
|
||
list($class, $method) = $this->parseClassComposer($class);
|
||
return function () use($class, $method, $container) {
|
||
$callable = array($container->make($class), $method);
|
||
return call_user_func_array($callable, func_get_args());
|
||
};
|
||
}
|
||
protected function parseClassComposer($class)
|
||
{
|
||
return str_contains($class, '@') ? explode('@', $class) : array($class, 'compose');
|
||
}
|
||
public function callComposer(View $view)
|
||
{
|
||
$this->events->fire('composing: ' . $view->getName(), array($view));
|
||
}
|
||
public function startSection($section, $content = '')
|
||
{
|
||
if ($content === '') {
|
||
ob_start() and $this->sectionStack[] = $section;
|
||
} else {
|
||
$this->extendSection($section, $content);
|
||
}
|
||
}
|
||
public function inject($section, $content)
|
||
{
|
||
return $this->startSection($section, $content);
|
||
}
|
||
public function yieldSection()
|
||
{
|
||
return $this->yieldContent($this->stopSection());
|
||
}
|
||
public function stopSection($overwrite = false)
|
||
{
|
||
$last = array_pop($this->sectionStack);
|
||
if ($overwrite) {
|
||
$this->sections[$last] = ob_get_clean();
|
||
} else {
|
||
$this->extendSection($last, ob_get_clean());
|
||
}
|
||
return $last;
|
||
}
|
||
protected function extendSection($section, $content)
|
||
{
|
||
if (isset($this->sections[$section])) {
|
||
$content = str_replace('@parent', $content, $this->sections[$section]);
|
||
$this->sections[$section] = $content;
|
||
} else {
|
||
$this->sections[$section] = $content;
|
||
}
|
||
}
|
||
public function yieldContent($section)
|
||
{
|
||
return isset($this->sections[$section]) ? $this->sections[$section] : '';
|
||
}
|
||
public function flushSections()
|
||
{
|
||
$this->sections = array();
|
||
$this->sectionStack = array();
|
||
}
|
||
public function incrementRender()
|
||
{
|
||
$this->renderCount++;
|
||
}
|
||
public function decrementRender()
|
||
{
|
||
$this->renderCount--;
|
||
}
|
||
public function doneRendering()
|
||
{
|
||
return $this->renderCount == 0;
|
||
}
|
||
public function addLocation($location)
|
||
{
|
||
$this->finder->addLocation($location);
|
||
}
|
||
public function addNamespace($namespace, $hints)
|
||
{
|
||
$this->finder->addNamespace($namespace, $hints);
|
||
}
|
||
public function addExtension($extension, $engine, $resolver = null)
|
||
{
|
||
$this->finder->addExtension($extension);
|
||
if (isset($resolver)) {
|
||
$this->engines->register($engine, $resolver);
|
||
}
|
||
unset($this->extensions[$engine]);
|
||
$this->extensions = array_merge(array($extension => $engine), $this->extensions);
|
||
}
|
||
public function getExtensions()
|
||
{
|
||
return $this->extensions;
|
||
}
|
||
public function getEngineResolver()
|
||
{
|
||
return $this->engines;
|
||
}
|
||
public function getFinder()
|
||
{
|
||
return $this->finder;
|
||
}
|
||
public function getDispatcher()
|
||
{
|
||
return $this->events;
|
||
}
|
||
public function getContainer()
|
||
{
|
||
return $this->container;
|
||
}
|
||
public function setContainer(Container $container)
|
||
{
|
||
$this->container = $container;
|
||
}
|
||
public function getShared()
|
||
{
|
||
return $this->shared;
|
||
}
|
||
public function getSections()
|
||
{
|
||
return $this->sections;
|
||
}
|
||
public function getNames()
|
||
{
|
||
return $this->names;
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Contracts;
|
||
|
||
interface MessageProviderInterface
|
||
{
|
||
public function getMessageBag();
|
||
}
|
||
namespace Illuminate\Support;
|
||
|
||
use Countable;
|
||
use Illuminate\Support\Contracts\ArrayableInterface;
|
||
use Illuminate\Support\Contracts\JsonableInterface;
|
||
use Illuminate\Support\Contracts\MessageProviderInterface;
|
||
class MessageBag implements ArrayableInterface, Countable, JsonableInterface, MessageProviderInterface
|
||
{
|
||
protected $messages = array();
|
||
protected $format = ':message';
|
||
public function __construct(array $messages = array())
|
||
{
|
||
foreach ($messages as $key => $value) {
|
||
$this->messages[$key] = (array) $value;
|
||
}
|
||
}
|
||
public function add($key, $message)
|
||
{
|
||
if ($this->isUnique($key, $message)) {
|
||
$this->messages[$key][] = $message;
|
||
}
|
||
return $this;
|
||
}
|
||
public function merge(array $messages)
|
||
{
|
||
$this->messages = array_merge_recursive($this->messages, $messages);
|
||
return $this;
|
||
}
|
||
protected function isUnique($key, $message)
|
||
{
|
||
$messages = (array) $this->messages;
|
||
return !isset($messages[$key]) or !in_array($message, $messages[$key]);
|
||
}
|
||
public function has($key = null)
|
||
{
|
||
return $this->first($key) !== '';
|
||
}
|
||
public function first($key = null, $format = null)
|
||
{
|
||
$messages = is_null($key) ? $this->all($format) : $this->get($key, $format);
|
||
return count($messages) > 0 ? $messages[0] : '';
|
||
}
|
||
public function get($key, $format = null)
|
||
{
|
||
$format = $this->checkFormat($format);
|
||
if (array_key_exists($key, $this->messages)) {
|
||
return $this->transform($this->messages[$key], $format, $key);
|
||
}
|
||
return array();
|
||
}
|
||
public function all($format = null)
|
||
{
|
||
$format = $this->checkFormat($format);
|
||
$all = array();
|
||
foreach ($this->messages as $key => $messages) {
|
||
$all = array_merge($all, $this->transform($messages, $format, $key));
|
||
}
|
||
return $all;
|
||
}
|
||
protected function transform($messages, $format, $messageKey)
|
||
{
|
||
$messages = (array) $messages;
|
||
foreach ($messages as $key => &$message) {
|
||
$replace = array(':message', ':key');
|
||
$message = str_replace($replace, array($message, $messageKey), $format);
|
||
}
|
||
return $messages;
|
||
}
|
||
protected function checkFormat($format)
|
||
{
|
||
return $format === null ? $this->format : $format;
|
||
}
|
||
public function getMessages()
|
||
{
|
||
return $this->messages;
|
||
}
|
||
public function getMessageBag()
|
||
{
|
||
return $this;
|
||
}
|
||
public function getFormat()
|
||
{
|
||
return $this->format;
|
||
}
|
||
public function setFormat($format = ':message')
|
||
{
|
||
$this->format = $format;
|
||
}
|
||
public function any()
|
||
{
|
||
return $this->count() > 0;
|
||
}
|
||
public function count()
|
||
{
|
||
return count($this->messages);
|
||
}
|
||
public function toArray()
|
||
{
|
||
return $this->getMessages();
|
||
}
|
||
public function toJson($options = 0)
|
||
{
|
||
return json_encode($this->toArray(), $options);
|
||
}
|
||
public function __toString()
|
||
{
|
||
return $this->toJson();
|
||
}
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
use Symfony\Component\HttpFoundation\Request;
|
||
class RequestContext
|
||
{
|
||
private $baseUrl;
|
||
private $pathInfo;
|
||
private $method;
|
||
private $host;
|
||
private $scheme;
|
||
private $httpPort;
|
||
private $httpsPort;
|
||
private $queryString;
|
||
private $parameters = array();
|
||
public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443, $path = '/', $queryString = '')
|
||
{
|
||
$this->baseUrl = $baseUrl;
|
||
$this->method = strtoupper($method);
|
||
$this->host = $host;
|
||
$this->scheme = strtolower($scheme);
|
||
$this->httpPort = $httpPort;
|
||
$this->httpsPort = $httpsPort;
|
||
$this->pathInfo = $path;
|
||
$this->queryString = $queryString;
|
||
}
|
||
public function fromRequest(Request $request)
|
||
{
|
||
$this->setBaseUrl($request->getBaseUrl());
|
||
$this->setPathInfo($request->getPathInfo());
|
||
$this->setMethod($request->getMethod());
|
||
$this->setHost($request->getHost());
|
||
$this->setScheme($request->getScheme());
|
||
$this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
|
||
$this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
|
||
$this->setQueryString($request->server->get('QUERY_STRING'));
|
||
}
|
||
public function getBaseUrl()
|
||
{
|
||
return $this->baseUrl;
|
||
}
|
||
public function setBaseUrl($baseUrl)
|
||
{
|
||
$this->baseUrl = $baseUrl;
|
||
}
|
||
public function getPathInfo()
|
||
{
|
||
return $this->pathInfo;
|
||
}
|
||
public function setPathInfo($pathInfo)
|
||
{
|
||
$this->pathInfo = $pathInfo;
|
||
}
|
||
public function getMethod()
|
||
{
|
||
return $this->method;
|
||
}
|
||
public function setMethod($method)
|
||
{
|
||
$this->method = strtoupper($method);
|
||
}
|
||
public function getHost()
|
||
{
|
||
return $this->host;
|
||
}
|
||
public function setHost($host)
|
||
{
|
||
$this->host = $host;
|
||
}
|
||
public function getScheme()
|
||
{
|
||
return $this->scheme;
|
||
}
|
||
public function setScheme($scheme)
|
||
{
|
||
$this->scheme = strtolower($scheme);
|
||
}
|
||
public function getHttpPort()
|
||
{
|
||
return $this->httpPort;
|
||
}
|
||
public function setHttpPort($httpPort)
|
||
{
|
||
$this->httpPort = $httpPort;
|
||
}
|
||
public function getHttpsPort()
|
||
{
|
||
return $this->httpsPort;
|
||
}
|
||
public function setHttpsPort($httpsPort)
|
||
{
|
||
$this->httpsPort = $httpsPort;
|
||
}
|
||
public function getQueryString()
|
||
{
|
||
return $this->queryString;
|
||
}
|
||
public function setQueryString($queryString)
|
||
{
|
||
$this->queryString = $queryString;
|
||
}
|
||
public function getParameters()
|
||
{
|
||
return $this->parameters;
|
||
}
|
||
public function setParameters(array $parameters)
|
||
{
|
||
$this->parameters = $parameters;
|
||
return $this;
|
||
}
|
||
public function getParameter($name)
|
||
{
|
||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
||
}
|
||
public function hasParameter($name)
|
||
{
|
||
return array_key_exists($name, $this->parameters);
|
||
}
|
||
public function setParameter($name, $parameter)
|
||
{
|
||
$this->parameters[$name] = $parameter;
|
||
}
|
||
}
|
||
namespace Symfony\Component\Routing\Matcher;
|
||
|
||
use Symfony\Component\Routing\RequestContextAwareInterface;
|
||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||
interface UrlMatcherInterface extends RequestContextAwareInterface
|
||
{
|
||
public function match($pathinfo);
|
||
}
|
||
namespace Symfony\Component\Routing\Matcher;
|
||
|
||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||
use Symfony\Component\Routing\RouteCollection;
|
||
use Symfony\Component\Routing\RequestContext;
|
||
use Symfony\Component\Routing\Route;
|
||
class UrlMatcher implements UrlMatcherInterface
|
||
{
|
||
const REQUIREMENT_MATCH = 0;
|
||
const REQUIREMENT_MISMATCH = 1;
|
||
const ROUTE_MATCH = 2;
|
||
protected $context;
|
||
protected $allow = array();
|
||
protected $routes;
|
||
public function __construct(RouteCollection $routes, RequestContext $context)
|
||
{
|
||
$this->routes = $routes;
|
||
$this->context = $context;
|
||
}
|
||
public function setContext(RequestContext $context)
|
||
{
|
||
$this->context = $context;
|
||
}
|
||
public function getContext()
|
||
{
|
||
return $this->context;
|
||
}
|
||
public function match($pathinfo)
|
||
{
|
||
$this->allow = array();
|
||
if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
|
||
return $ret;
|
||
}
|
||
throw 0 < count($this->allow) ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) : new ResourceNotFoundException();
|
||
}
|
||
protected function matchCollection($pathinfo, RouteCollection $routes)
|
||
{
|
||
foreach ($routes as $name => $route) {
|
||
$compiledRoute = $route->compile();
|
||
if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
|
||
continue;
|
||
}
|
||
if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
|
||
continue;
|
||
}
|
||
$hostMatches = array();
|
||
if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
|
||
continue;
|
||
}
|
||
if ($req = $route->getRequirement('_method')) {
|
||
if ('HEAD' === ($method = $this->context->getMethod())) {
|
||
$method = 'GET';
|
||
}
|
||
if (!in_array($method, $req = explode('|', strtoupper($req)))) {
|
||
$this->allow = array_merge($this->allow, $req);
|
||
continue;
|
||
}
|
||
}
|
||
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
|
||
if (self::ROUTE_MATCH === $status[0]) {
|
||
return $status[1];
|
||
}
|
||
if (self::REQUIREMENT_MISMATCH === $status[0]) {
|
||
continue;
|
||
}
|
||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
|
||
}
|
||
}
|
||
protected function getAttributes(Route $route, $name, array $attributes)
|
||
{
|
||
$attributes['_route'] = $name;
|
||
return $this->mergeDefaults($attributes, $route->getDefaults());
|
||
}
|
||
protected function handleRouteRequirements($pathinfo, $name, Route $route)
|
||
{
|
||
$scheme = $route->getRequirement('_scheme');
|
||
$status = $scheme && $scheme !== $this->context->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
|
||
return array($status, null);
|
||
}
|
||
protected function mergeDefaults($params, $defaults)
|
||
{
|
||
foreach ($params as $key => $value) {
|
||
if (!is_int($key)) {
|
||
$defaults[$key] = $value;
|
||
}
|
||
}
|
||
return $defaults;
|
||
}
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
interface RequestContextAwareInterface
|
||
{
|
||
public function setContext(RequestContext $context);
|
||
public function getContext();
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
interface RouteCompilerInterface
|
||
{
|
||
public static function compile(Route $route);
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
class RouteCompiler implements RouteCompilerInterface
|
||
{
|
||
const REGEX_DELIMITER = '#';
|
||
const SEPARATORS = '/,;.:-_~+*=@|';
|
||
public static function compile(Route $route)
|
||
{
|
||
$staticPrefix = null;
|
||
$hostVariables = array();
|
||
$pathVariables = array();
|
||
$variables = array();
|
||
$tokens = array();
|
||
$regex = null;
|
||
$hostRegex = null;
|
||
$hostTokens = array();
|
||
if ('' !== ($host = $route->getHost())) {
|
||
$result = self::compilePattern($route, $host, true);
|
||
$hostVariables = $result['variables'];
|
||
$variables = array_merge($variables, $hostVariables);
|
||
$hostTokens = $result['tokens'];
|
||
$hostRegex = $result['regex'];
|
||
}
|
||
$path = $route->getPath();
|
||
$result = self::compilePattern($route, $path, false);
|
||
$staticPrefix = $result['staticPrefix'];
|
||
$pathVariables = $result['variables'];
|
||
$variables = array_merge($variables, $pathVariables);
|
||
$tokens = $result['tokens'];
|
||
$regex = $result['regex'];
|
||
return new CompiledRoute($staticPrefix, $regex, $tokens, $pathVariables, $hostRegex, $hostTokens, $hostVariables, array_unique($variables));
|
||
}
|
||
private static function compilePattern(Route $route, $pattern, $isHost)
|
||
{
|
||
$tokens = array();
|
||
$variables = array();
|
||
$matches = array();
|
||
$pos = 0;
|
||
$defaultSeparator = $isHost ? '.' : '/';
|
||
preg_match_all('#\\{\\w+\\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
|
||
foreach ($matches as $match) {
|
||
$varName = substr($match[0][0], 1, -1);
|
||
$precedingText = substr($pattern, $pos, $match[0][1] - $pos);
|
||
$pos = $match[0][1] + strlen($match[0][0]);
|
||
$precedingChar = strlen($precedingText) > 0 ? substr($precedingText, -1) : '';
|
||
$isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar);
|
||
if (is_numeric($varName)) {
|
||
throw new \DomainException(sprintf('Variable name "%s" cannot be numeric in route pattern "%s". Please use a different name.', $varName, $pattern));
|
||
}
|
||
if (in_array($varName, $variables)) {
|
||
throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName));
|
||
}
|
||
if ($isSeparator && strlen($precedingText) > 1) {
|
||
$tokens[] = array('text', substr($precedingText, 0, -1));
|
||
} elseif (!$isSeparator && strlen($precedingText) > 0) {
|
||
$tokens[] = array('text', $precedingText);
|
||
}
|
||
$regexp = $route->getRequirement($varName);
|
||
if (null === $regexp) {
|
||
$followingPattern = (string) substr($pattern, $pos);
|
||
$nextSeparator = self::findNextSeparator($followingPattern);
|
||
$regexp = sprintf('[^%s%s]+', preg_quote($defaultSeparator, self::REGEX_DELIMITER), $defaultSeparator !== $nextSeparator && '' !== $nextSeparator ? preg_quote($nextSeparator, self::REGEX_DELIMITER) : '');
|
||
if ('' !== $nextSeparator && !preg_match('#^\\{\\w+\\}#', $followingPattern) || '' === $followingPattern) {
|
||
$regexp .= '+';
|
||
}
|
||
}
|
||
$tokens[] = array('variable', $isSeparator ? $precedingChar : '', $regexp, $varName);
|
||
$variables[] = $varName;
|
||
}
|
||
if ($pos < strlen($pattern)) {
|
||
$tokens[] = array('text', substr($pattern, $pos));
|
||
}
|
||
$firstOptional = PHP_INT_MAX;
|
||
if (!$isHost) {
|
||
for ($i = count($tokens) - 1; $i >= 0; $i--) {
|
||
$token = $tokens[$i];
|
||
if ('variable' === $token[0] && $route->hasDefault($token[3])) {
|
||
$firstOptional = $i;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
$regexp = '';
|
||
for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) {
|
||
$regexp .= self::computeRegexp($tokens, $i, $firstOptional);
|
||
}
|
||
return array('staticPrefix' => 'text' === $tokens[0][0] ? $tokens[0][1] : '', 'regex' => self::REGEX_DELIMITER . '^' . $regexp . '$' . self::REGEX_DELIMITER . 's', 'tokens' => array_reverse($tokens), 'variables' => $variables);
|
||
}
|
||
private static function findNextSeparator($pattern)
|
||
{
|
||
if ('' == $pattern) {
|
||
return '';
|
||
}
|
||
$pattern = preg_replace('#\\{\\w+\\}#', '', $pattern);
|
||
return isset($pattern[0]) && false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';
|
||
}
|
||
private static function computeRegexp(array $tokens, $index, $firstOptional)
|
||
{
|
||
$token = $tokens[$index];
|
||
if ('text' === $token[0]) {
|
||
return preg_quote($token[1], self::REGEX_DELIMITER);
|
||
} else {
|
||
if (0 === $index && 0 === $firstOptional) {
|
||
return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
|
||
} else {
|
||
$regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
|
||
if ($index >= $firstOptional) {
|
||
$regexp = "(?:{$regexp}";
|
||
$nbTokens = count($tokens);
|
||
if ($nbTokens - 1 == $index) {
|
||
$regexp .= str_repeat(')?', $nbTokens - $firstOptional - (0 === $firstOptional ? 1 : 0));
|
||
}
|
||
}
|
||
return $regexp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
namespace Symfony\Component\Routing;
|
||
|
||
class CompiledRoute
|
||
{
|
||
private $variables;
|
||
private $tokens;
|
||
private $staticPrefix;
|
||
private $regex;
|
||
private $pathVariables;
|
||
private $hostVariables;
|
||
private $hostRegex;
|
||
private $hostTokens;
|
||
public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array())
|
||
{
|
||
$this->staticPrefix = (string) $staticPrefix;
|
||
$this->regex = $regex;
|
||
$this->tokens = $tokens;
|
||
$this->pathVariables = $pathVariables;
|
||
$this->hostRegex = $hostRegex;
|
||
$this->hostTokens = $hostTokens;
|
||
$this->hostVariables = $hostVariables;
|
||
$this->variables = $variables;
|
||
}
|
||
public function getStaticPrefix()
|
||
{
|
||
return $this->staticPrefix;
|
||
}
|
||
public function getRegex()
|
||
{
|
||
return $this->regex;
|
||
}
|
||
public function getHostRegex()
|
||
{
|
||
return $this->hostRegex;
|
||
}
|
||
public function getTokens()
|
||
{
|
||
return $this->tokens;
|
||
}
|
||
public function getHostTokens()
|
||
{
|
||
return $this->hostTokens;
|
||
}
|
||
public function getVariables()
|
||
{
|
||
return $this->variables;
|
||
}
|
||
public function getPathVariables()
|
||
{
|
||
return $this->pathVariables;
|
||
}
|
||
public function getHostVariables()
|
||
{
|
||
return $this->hostVariables;
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Facades;
|
||
|
||
class View extends Facade
|
||
{
|
||
protected static function getFacadeAccessor()
|
||
{
|
||
return 'view';
|
||
}
|
||
}
|
||
namespace Illuminate\Support\Contracts;
|
||
|
||
interface RenderableInterface
|
||
{
|
||
public function render();
|
||
}
|
||
namespace Illuminate\View;
|
||
|
||
use ArrayAccess;
|
||
use Illuminate\View\Engines\EngineInterface;
|
||
use Illuminate\Support\Contracts\ArrayableInterface as Arrayable;
|
||
use Illuminate\Support\Contracts\RenderableInterface as Renderable;
|
||
class View implements ArrayAccess, Renderable
|
||
{
|
||
protected $environment;
|
||
protected $engine;
|
||
protected $view;
|
||
protected $data;
|
||
protected $path;
|
||
public function __construct(Environment $environment, EngineInterface $engine, $view, $path, $data = array())
|
||
{
|
||
$this->view = $view;
|
||
$this->path = $path;
|
||
$this->engine = $engine;
|
||
$this->environment = $environment;
|
||
$this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;
|
||
}
|
||
public function render()
|
||
{
|
||
$env = $this->environment;
|
||
$env->incrementRender();
|
||
$env->callComposer($this);
|
||
$contents = trim($this->getContents());
|
||
$env->decrementRender();
|
||
if ($env->doneRendering()) {
|
||
$env->flushSections();
|
||
}
|
||
return $contents;
|
||
}
|
||
protected function getContents()
|
||
{
|
||
return $this->engine->get($this->path, $this->gatherData());
|
||
}
|
||
protected function gatherData()
|
||
{
|
||
$data = array_merge($this->environment->getShared(), $this->data);
|
||
foreach ($data as $key => $value) {
|
||
if ($value instanceof Renderable) {
|
||
$data[$key] = $value->render();
|
||
}
|
||
}
|
||
return $data;
|
||
}
|
||
public function with($key, $value = null)
|
||
{
|
||
if (is_array($key)) {
|
||
$this->data = array_merge($this->data, $key);
|
||
} else {
|
||
$this->data[$key] = $value;
|
||
}
|
||
return $this;
|
||
}
|
||
public function nest($key, $view, array $data = array())
|
||
{
|
||
return $this->with($key, $this->environment->make($view, $data));
|
||
}
|
||
public function getEnvironment()
|
||
{
|
||
return $this->environment;
|
||
}
|
||
public function getEngine()
|
||
{
|
||
return $this->engine;
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->view;
|
||
}
|
||
public function getData()
|
||
{
|
||
return $this->data;
|
||
}
|
||
public function getPath()
|
||
{
|
||
return $this->path;
|
||
}
|
||
public function setPath($path)
|
||
{
|
||
$this->path = $path;
|
||
}
|
||
public function offsetExists($key)
|
||
{
|
||
return array_key_exists($key, $this->data);
|
||
}
|
||
public function offsetGet($key)
|
||
{
|
||
return $this->data[$key];
|
||
}
|
||
public function offsetSet($key, $value)
|
||
{
|
||
$this->with($key, $value);
|
||
}
|
||
public function offsetUnset($key)
|
||
{
|
||
unset($this->data[$key]);
|
||
}
|
||
public function __get($key)
|
||
{
|
||
return $this->data[$key];
|
||
}
|
||
public function __set($key, $value)
|
||
{
|
||
$this->with($key, $value);
|
||
}
|
||
public function __isset($key)
|
||
{
|
||
return isset($this->data[$key]);
|
||
}
|
||
public function __unset($key)
|
||
{
|
||
unset($this->data[$key]);
|
||
}
|
||
public function __toString()
|
||
{
|
||
return $this->render();
|
||
}
|
||
}
|
||
namespace Illuminate\View\Engines;
|
||
|
||
interface EngineInterface
|
||
{
|
||
public function get($path, array $data = array());
|
||
}
|
||
namespace Illuminate\View\Engines;
|
||
|
||
use Illuminate\View\Exception;
|
||
use Illuminate\View\Environment;
|
||
class PhpEngine implements EngineInterface
|
||
{
|
||
public function get($path, array $data = array())
|
||
{
|
||
return $this->evaluatePath($path, $data);
|
||
}
|
||
protected function evaluatePath($__path, $__data)
|
||
{
|
||
ob_start();
|
||
extract($__data);
|
||
try {
|
||
include $__path;
|
||
} catch (\Exception $e) {
|
||
$this->handleViewException($e);
|
||
}
|
||
return ob_get_clean();
|
||
}
|
||
protected function handleViewException($e)
|
||
{
|
||
ob_get_clean();
|
||
throw $e;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class Response
|
||
{
|
||
public $headers;
|
||
protected $content;
|
||
protected $version;
|
||
protected $statusCode;
|
||
protected $statusText;
|
||
protected $charset;
|
||
public static $statusTexts = array(100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-Status', 208 => 'Already Reported', 226 => 'IM Used', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Reserved', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Reserved for WebDAV advanced collections expired proposal', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates (Experimental)', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 510 => 'Not Extended', 511 => 'Network Authentication Required');
|
||
public function __construct($content = '', $status = 200, $headers = array())
|
||
{
|
||
$this->headers = new ResponseHeaderBag($headers);
|
||
$this->setContent($content);
|
||
$this->setStatusCode($status);
|
||
$this->setProtocolVersion('1.0');
|
||
if (!$this->headers->has('Date')) {
|
||
$this->setDate(new \DateTime(null, new \DateTimeZone('UTC')));
|
||
}
|
||
}
|
||
public static function create($content = '', $status = 200, $headers = array())
|
||
{
|
||
return new static($content, $status, $headers);
|
||
}
|
||
public function __toString()
|
||
{
|
||
return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText) . '
|
||
' . $this->headers . '
|
||
' . $this->getContent();
|
||
}
|
||
public function __clone()
|
||
{
|
||
$this->headers = clone $this->headers;
|
||
}
|
||
public function prepare(Request $request)
|
||
{
|
||
$headers = $this->headers;
|
||
if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
|
||
$this->setContent(null);
|
||
}
|
||
if (!$headers->has('Content-Type')) {
|
||
$format = $request->getRequestFormat();
|
||
if (null !== $format && ($mimeType = $request->getMimeType($format))) {
|
||
$headers->set('Content-Type', $mimeType);
|
||
}
|
||
}
|
||
$charset = $this->charset ?: 'UTF-8';
|
||
if (!$headers->has('Content-Type')) {
|
||
$headers->set('Content-Type', 'text/html; charset=' . $charset);
|
||
} elseif (0 === strpos($headers->get('Content-Type'), 'text/') && false === strpos($headers->get('Content-Type'), 'charset')) {
|
||
$headers->set('Content-Type', $headers->get('Content-Type') . '; charset=' . $charset);
|
||
}
|
||
if ($headers->has('Transfer-Encoding')) {
|
||
$headers->remove('Content-Length');
|
||
}
|
||
if ($request->isMethod('HEAD')) {
|
||
$length = $headers->get('Content-Length');
|
||
$this->setContent(null);
|
||
if ($length) {
|
||
$headers->set('Content-Length', $length);
|
||
}
|
||
}
|
||
if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
|
||
$this->setProtocolVersion('1.1');
|
||
}
|
||
if ('1.0' == $this->getProtocolVersion() && 'no-cache' == $this->headers->get('Cache-Control')) {
|
||
$this->headers->set('pragma', 'no-cache');
|
||
$this->headers->set('expires', -1);
|
||
}
|
||
$this->ensureIEOverSSLCompatibility($request);
|
||
return $this;
|
||
}
|
||
public function sendHeaders()
|
||
{
|
||
if (headers_sent()) {
|
||
return $this;
|
||
}
|
||
header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
|
||
foreach ($this->headers->allPreserveCase() as $name => $values) {
|
||
foreach ($values as $value) {
|
||
header($name . ': ' . $value, false);
|
||
}
|
||
}
|
||
foreach ($this->headers->getCookies() as $cookie) {
|
||
setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
|
||
}
|
||
return $this;
|
||
}
|
||
public function sendContent()
|
||
{
|
||
echo $this->content;
|
||
return $this;
|
||
}
|
||
public function send()
|
||
{
|
||
$this->sendHeaders();
|
||
$this->sendContent();
|
||
if (function_exists('fastcgi_finish_request')) {
|
||
fastcgi_finish_request();
|
||
} elseif ('cli' !== PHP_SAPI) {
|
||
$previous = null;
|
||
$obStatus = ob_get_status(1);
|
||
while (($level = ob_get_level()) > 0 && $level !== $previous) {
|
||
$previous = $level;
|
||
if ($obStatus[$level - 1] && isset($obStatus[$level - 1]['del']) && $obStatus[$level - 1]['del']) {
|
||
ob_end_flush();
|
||
}
|
||
}
|
||
flush();
|
||
}
|
||
return $this;
|
||
}
|
||
public function setContent($content)
|
||
{
|
||
if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) {
|
||
throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content)));
|
||
}
|
||
$this->content = (string) $content;
|
||
return $this;
|
||
}
|
||
public function getContent()
|
||
{
|
||
return $this->content;
|
||
}
|
||
public function setProtocolVersion($version)
|
||
{
|
||
$this->version = $version;
|
||
return $this;
|
||
}
|
||
public function getProtocolVersion()
|
||
{
|
||
return $this->version;
|
||
}
|
||
public function setStatusCode($code, $text = null)
|
||
{
|
||
$this->statusCode = $code = (int) $code;
|
||
if ($this->isInvalid()) {
|
||
throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
|
||
}
|
||
if (null === $text) {
|
||
$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : '';
|
||
return $this;
|
||
}
|
||
if (false === $text) {
|
||
$this->statusText = '';
|
||
return $this;
|
||
}
|
||
$this->statusText = $text;
|
||
return $this;
|
||
}
|
||
public function getStatusCode()
|
||
{
|
||
return $this->statusCode;
|
||
}
|
||
public function setCharset($charset)
|
||
{
|
||
$this->charset = $charset;
|
||
return $this;
|
||
}
|
||
public function getCharset()
|
||
{
|
||
return $this->charset;
|
||
}
|
||
public function isCacheable()
|
||
{
|
||
if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) {
|
||
return false;
|
||
}
|
||
if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
|
||
return false;
|
||
}
|
||
return $this->isValidateable() || $this->isFresh();
|
||
}
|
||
public function isFresh()
|
||
{
|
||
return $this->getTtl() > 0;
|
||
}
|
||
public function isValidateable()
|
||
{
|
||
return $this->headers->has('Last-Modified') || $this->headers->has('ETag');
|
||
}
|
||
public function setPrivate()
|
||
{
|
||
$this->headers->removeCacheControlDirective('public');
|
||
$this->headers->addCacheControlDirective('private');
|
||
return $this;
|
||
}
|
||
public function setPublic()
|
||
{
|
||
$this->headers->addCacheControlDirective('public');
|
||
$this->headers->removeCacheControlDirective('private');
|
||
return $this;
|
||
}
|
||
public function mustRevalidate()
|
||
{
|
||
return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('proxy-revalidate');
|
||
}
|
||
public function getDate()
|
||
{
|
||
return $this->headers->getDate('Date', new \DateTime());
|
||
}
|
||
public function setDate(\DateTime $date)
|
||
{
|
||
$date->setTimezone(new \DateTimeZone('UTC'));
|
||
$this->headers->set('Date', $date->format('D, d M Y H:i:s') . ' GMT');
|
||
return $this;
|
||
}
|
||
public function getAge()
|
||
{
|
||
if (null !== ($age = $this->headers->get('Age'))) {
|
||
return (int) $age;
|
||
}
|
||
return max(time() - $this->getDate()->format('U'), 0);
|
||
}
|
||
public function expire()
|
||
{
|
||
if ($this->isFresh()) {
|
||
$this->headers->set('Age', $this->getMaxAge());
|
||
}
|
||
return $this;
|
||
}
|
||
public function getExpires()
|
||
{
|
||
try {
|
||
return $this->headers->getDate('Expires');
|
||
} catch (\RuntimeException $e) {
|
||
return \DateTime::createFromFormat(DATE_RFC2822, 'Sat, 01 Jan 00 00:00:00 +0000');
|
||
}
|
||
}
|
||
public function setExpires(\DateTime $date = null)
|
||
{
|
||
if (null === $date) {
|
||
$this->headers->remove('Expires');
|
||
} else {
|
||
$date = clone $date;
|
||
$date->setTimezone(new \DateTimeZone('UTC'));
|
||
$this->headers->set('Expires', $date->format('D, d M Y H:i:s') . ' GMT');
|
||
}
|
||
return $this;
|
||
}
|
||
public function getMaxAge()
|
||
{
|
||
if ($this->headers->hasCacheControlDirective('s-maxage')) {
|
||
return (int) $this->headers->getCacheControlDirective('s-maxage');
|
||
}
|
||
if ($this->headers->hasCacheControlDirective('max-age')) {
|
||
return (int) $this->headers->getCacheControlDirective('max-age');
|
||
}
|
||
if (null !== $this->getExpires()) {
|
||
return $this->getExpires()->format('U') - $this->getDate()->format('U');
|
||
}
|
||
return null;
|
||
}
|
||
public function setMaxAge($value)
|
||
{
|
||
$this->headers->addCacheControlDirective('max-age', $value);
|
||
return $this;
|
||
}
|
||
public function setSharedMaxAge($value)
|
||
{
|
||
$this->setPublic();
|
||
$this->headers->addCacheControlDirective('s-maxage', $value);
|
||
return $this;
|
||
}
|
||
public function getTtl()
|
||
{
|
||
if (null !== ($maxAge = $this->getMaxAge())) {
|
||
return $maxAge - $this->getAge();
|
||
}
|
||
return null;
|
||
}
|
||
public function setTtl($seconds)
|
||
{
|
||
$this->setSharedMaxAge($this->getAge() + $seconds);
|
||
return $this;
|
||
}
|
||
public function setClientTtl($seconds)
|
||
{
|
||
$this->setMaxAge($this->getAge() + $seconds);
|
||
return $this;
|
||
}
|
||
public function getLastModified()
|
||
{
|
||
return $this->headers->getDate('Last-Modified');
|
||
}
|
||
public function setLastModified(\DateTime $date = null)
|
||
{
|
||
if (null === $date) {
|
||
$this->headers->remove('Last-Modified');
|
||
} else {
|
||
$date = clone $date;
|
||
$date->setTimezone(new \DateTimeZone('UTC'));
|
||
$this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s') . ' GMT');
|
||
}
|
||
return $this;
|
||
}
|
||
public function getEtag()
|
||
{
|
||
return $this->headers->get('ETag');
|
||
}
|
||
public function setEtag($etag = null, $weak = false)
|
||
{
|
||
if (null === $etag) {
|
||
$this->headers->remove('Etag');
|
||
} else {
|
||
if (0 !== strpos($etag, '"')) {
|
||
$etag = '"' . $etag . '"';
|
||
}
|
||
$this->headers->set('ETag', (true === $weak ? 'W/' : '') . $etag);
|
||
}
|
||
return $this;
|
||
}
|
||
public function setCache(array $options)
|
||
{
|
||
if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) {
|
||
throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff))));
|
||
}
|
||
if (isset($options['etag'])) {
|
||
$this->setEtag($options['etag']);
|
||
}
|
||
if (isset($options['last_modified'])) {
|
||
$this->setLastModified($options['last_modified']);
|
||
}
|
||
if (isset($options['max_age'])) {
|
||
$this->setMaxAge($options['max_age']);
|
||
}
|
||
if (isset($options['s_maxage'])) {
|
||
$this->setSharedMaxAge($options['s_maxage']);
|
||
}
|
||
if (isset($options['public'])) {
|
||
if ($options['public']) {
|
||
$this->setPublic();
|
||
} else {
|
||
$this->setPrivate();
|
||
}
|
||
}
|
||
if (isset($options['private'])) {
|
||
if ($options['private']) {
|
||
$this->setPrivate();
|
||
} else {
|
||
$this->setPublic();
|
||
}
|
||
}
|
||
return $this;
|
||
}
|
||
public function setNotModified()
|
||
{
|
||
$this->setStatusCode(304);
|
||
$this->setContent(null);
|
||
foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) {
|
||
$this->headers->remove($header);
|
||
}
|
||
return $this;
|
||
}
|
||
public function hasVary()
|
||
{
|
||
return null !== $this->headers->get('Vary');
|
||
}
|
||
public function getVary()
|
||
{
|
||
if (!($vary = $this->headers->get('Vary'))) {
|
||
return array();
|
||
}
|
||
return is_array($vary) ? $vary : preg_split('/[\\s,]+/', $vary);
|
||
}
|
||
public function setVary($headers, $replace = true)
|
||
{
|
||
$this->headers->set('Vary', $headers, $replace);
|
||
return $this;
|
||
}
|
||
public function isNotModified(Request $request)
|
||
{
|
||
if (!$request->isMethodSafe()) {
|
||
return false;
|
||
}
|
||
$lastModified = $request->headers->get('If-Modified-Since');
|
||
$notModified = false;
|
||
if ($etags = $request->getEtags()) {
|
||
$notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified);
|
||
} elseif ($lastModified) {
|
||
$notModified = $lastModified == $this->headers->get('Last-Modified');
|
||
}
|
||
if ($notModified) {
|
||
$this->setNotModified();
|
||
}
|
||
return $notModified;
|
||
}
|
||
public function isInvalid()
|
||
{
|
||
return $this->statusCode < 100 || $this->statusCode >= 600;
|
||
}
|
||
public function isInformational()
|
||
{
|
||
return $this->statusCode >= 100 && $this->statusCode < 200;
|
||
}
|
||
public function isSuccessful()
|
||
{
|
||
return $this->statusCode >= 200 && $this->statusCode < 300;
|
||
}
|
||
public function isRedirection()
|
||
{
|
||
return $this->statusCode >= 300 && $this->statusCode < 400;
|
||
}
|
||
public function isClientError()
|
||
{
|
||
return $this->statusCode >= 400 && $this->statusCode < 500;
|
||
}
|
||
public function isServerError()
|
||
{
|
||
return $this->statusCode >= 500 && $this->statusCode < 600;
|
||
}
|
||
public function isOk()
|
||
{
|
||
return 200 === $this->statusCode;
|
||
}
|
||
public function isForbidden()
|
||
{
|
||
return 403 === $this->statusCode;
|
||
}
|
||
public function isNotFound()
|
||
{
|
||
return 404 === $this->statusCode;
|
||
}
|
||
public function isRedirect($location = null)
|
||
{
|
||
return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location'));
|
||
}
|
||
public function isEmpty()
|
||
{
|
||
return in_array($this->statusCode, array(201, 204, 304));
|
||
}
|
||
protected function ensureIEOverSSLCompatibility(Request $request)
|
||
{
|
||
if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) {
|
||
if (intval(preg_replace('/(MSIE )(.*?);/', '$2', $match[0])) < 9) {
|
||
$this->headers->remove('Cache-Control');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
namespace Illuminate\Http;
|
||
|
||
use Symfony\Component\HttpFoundation\Cookie;
|
||
use Illuminate\Support\Contracts\JsonableInterface;
|
||
use Illuminate\Support\Contracts\RenderableInterface;
|
||
class Response extends \Symfony\Component\HttpFoundation\Response
|
||
{
|
||
public $original;
|
||
public function header($key, $value, $replace = true)
|
||
{
|
||
$this->headers->set($key, $value, $replace);
|
||
return $this;
|
||
}
|
||
public function withCookie(Cookie $cookie)
|
||
{
|
||
$this->headers->setCookie($cookie);
|
||
return $this;
|
||
}
|
||
public function setContent($content)
|
||
{
|
||
$this->original = $content;
|
||
if ($this->shouldBeJson($content)) {
|
||
$this->headers->set('Content-Type', 'application/json');
|
||
$content = $this->morphToJson($content);
|
||
} elseif ($content instanceof RenderableInterface) {
|
||
$content = $content->render();
|
||
}
|
||
return parent::setContent($content);
|
||
}
|
||
protected function morphToJson($content)
|
||
{
|
||
if ($content instanceof JsonableInterface) {
|
||
return $content->toJson();
|
||
}
|
||
return json_encode($content);
|
||
}
|
||
protected function shouldBeJson($content)
|
||
{
|
||
return $content instanceof JsonableInterface or is_array($content);
|
||
}
|
||
public function getOriginalContent()
|
||
{
|
||
return $this->original;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class ResponseHeaderBag extends HeaderBag
|
||
{
|
||
const COOKIES_FLAT = 'flat';
|
||
const COOKIES_ARRAY = 'array';
|
||
const DISPOSITION_ATTACHMENT = 'attachment';
|
||
const DISPOSITION_INLINE = 'inline';
|
||
protected $computedCacheControl = array();
|
||
protected $cookies = array();
|
||
protected $headerNames = array();
|
||
public function __construct(array $headers = array())
|
||
{
|
||
parent::__construct($headers);
|
||
if (!isset($this->headers['cache-control'])) {
|
||
$this->set('Cache-Control', '');
|
||
}
|
||
}
|
||
public function __toString()
|
||
{
|
||
$cookies = '';
|
||
foreach ($this->getCookies() as $cookie) {
|
||
$cookies .= 'Set-Cookie: ' . $cookie . '
|
||
';
|
||
}
|
||
ksort($this->headerNames);
|
||
return parent::__toString() . $cookies;
|
||
}
|
||
public function allPreserveCase()
|
||
{
|
||
return array_combine($this->headerNames, $this->headers);
|
||
}
|
||
public function replace(array $headers = array())
|
||
{
|
||
$this->headerNames = array();
|
||
parent::replace($headers);
|
||
if (!isset($this->headers['cache-control'])) {
|
||
$this->set('Cache-Control', '');
|
||
}
|
||
}
|
||
public function set($key, $values, $replace = true)
|
||
{
|
||
parent::set($key, $values, $replace);
|
||
$uniqueKey = strtr(strtolower($key), '_', '-');
|
||
$this->headerNames[$uniqueKey] = $key;
|
||
if (in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'))) {
|
||
$computed = $this->computeCacheControlValue();
|
||
$this->headers['cache-control'] = array($computed);
|
||
$this->headerNames['cache-control'] = 'Cache-Control';
|
||
$this->computedCacheControl = $this->parseCacheControl($computed);
|
||
}
|
||
}
|
||
public function remove($key)
|
||
{
|
||
parent::remove($key);
|
||
$uniqueKey = strtr(strtolower($key), '_', '-');
|
||
unset($this->headerNames[$uniqueKey]);
|
||
if ('cache-control' === $uniqueKey) {
|
||
$this->computedCacheControl = array();
|
||
}
|
||
}
|
||
public function hasCacheControlDirective($key)
|
||
{
|
||
return array_key_exists($key, $this->computedCacheControl);
|
||
}
|
||
public function getCacheControlDirective($key)
|
||
{
|
||
return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
|
||
}
|
||
public function setCookie(Cookie $cookie)
|
||
{
|
||
$this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
|
||
}
|
||
public function removeCookie($name, $path = '/', $domain = null)
|
||
{
|
||
if (null === $path) {
|
||
$path = '/';
|
||
}
|
||
unset($this->cookies[$domain][$path][$name]);
|
||
if (empty($this->cookies[$domain][$path])) {
|
||
unset($this->cookies[$domain][$path]);
|
||
if (empty($this->cookies[$domain])) {
|
||
unset($this->cookies[$domain]);
|
||
}
|
||
}
|
||
}
|
||
public function getCookies($format = self::COOKIES_FLAT)
|
||
{
|
||
if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) {
|
||
throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY))));
|
||
}
|
||
if (self::COOKIES_ARRAY === $format) {
|
||
return $this->cookies;
|
||
}
|
||
$flattenedCookies = array();
|
||
foreach ($this->cookies as $path) {
|
||
foreach ($path as $cookies) {
|
||
foreach ($cookies as $cookie) {
|
||
$flattenedCookies[] = $cookie;
|
||
}
|
||
}
|
||
}
|
||
return $flattenedCookies;
|
||
}
|
||
public function clearCookie($name, $path = '/', $domain = null)
|
||
{
|
||
$this->setCookie(new Cookie($name, null, 1, $path, $domain));
|
||
}
|
||
public function makeDisposition($disposition, $filename, $filenameFallback = '')
|
||
{
|
||
if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
|
||
throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
|
||
}
|
||
if ('' == $filenameFallback) {
|
||
$filenameFallback = $filename;
|
||
}
|
||
if (!preg_match('/^[\\x20-\\x7e]*$/', $filenameFallback)) {
|
||
throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
|
||
}
|
||
if (false !== strpos($filenameFallback, '%')) {
|
||
throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
|
||
}
|
||
if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
|
||
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
|
||
}
|
||
$output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
|
||
if ($filename !== $filenameFallback) {
|
||
$output .= sprintf('; filename*=utf-8\'\'%s', rawurlencode($filename));
|
||
}
|
||
return $output;
|
||
}
|
||
protected function computeCacheControlValue()
|
||
{
|
||
if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
|
||
return 'no-cache';
|
||
}
|
||
if (!$this->cacheControl) {
|
||
return 'private, must-revalidate';
|
||
}
|
||
$header = $this->getCacheControlHeader();
|
||
if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
|
||
return $header;
|
||
}
|
||
if (!isset($this->cacheControl['s-maxage'])) {
|
||
return $header . ', private';
|
||
}
|
||
return $header;
|
||
}
|
||
}
|
||
namespace Symfony\Component\HttpFoundation;
|
||
|
||
class Cookie
|
||
{
|
||
protected $name;
|
||
protected $value;
|
||
protected $domain;
|
||
protected $expire;
|
||
protected $path;
|
||
protected $secure;
|
||
protected $httpOnly;
|
||
public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true)
|
||
{
|
||
if (preg_match('/[=,;
|
||
]/', $name)) {
|
||
throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
|
||
}
|
||
if (empty($name)) {
|
||
throw new \InvalidArgumentException('The cookie name cannot be empty.');
|
||
}
|
||
if ($expire instanceof \DateTime) {
|
||
$expire = $expire->format('U');
|
||
} elseif (!is_numeric($expire)) {
|
||
$expire = strtotime($expire);
|
||
if (false === $expire || -1 === $expire) {
|
||
throw new \InvalidArgumentException('The cookie expiration time is not valid.');
|
||
}
|
||
}
|
||
$this->name = $name;
|
||
$this->value = $value;
|
||
$this->domain = $domain;
|
||
$this->expire = $expire;
|
||
$this->path = empty($path) ? '/' : $path;
|
||
$this->secure = (bool) $secure;
|
||
$this->httpOnly = (bool) $httpOnly;
|
||
}
|
||
public function __toString()
|
||
{
|
||
$str = urlencode($this->getName()) . '=';
|
||
if ('' === (string) $this->getValue()) {
|
||
$str .= 'deleted; expires=' . gmdate('D, d-M-Y H:i:s T', time() - 31536001);
|
||
} else {
|
||
$str .= urlencode($this->getValue());
|
||
if ($this->getExpiresTime() !== 0) {
|
||
$str .= '; expires=' . gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime());
|
||
}
|
||
}
|
||
if ($this->path) {
|
||
$str .= '; path=' . $this->path;
|
||
}
|
||
if ($this->getDomain()) {
|
||
$str .= '; domain=' . $this->getDomain();
|
||
}
|
||
if (true === $this->isSecure()) {
|
||
$str .= '; secure';
|
||
}
|
||
if (true === $this->isHttpOnly()) {
|
||
$str .= '; httponly';
|
||
}
|
||
return $str;
|
||
}
|
||
public function getName()
|
||
{
|
||
return $this->name;
|
||
}
|
||
public function getValue()
|
||
{
|
||
return $this->value;
|
||
}
|
||
public function getDomain()
|
||
{
|
||
return $this->domain;
|
||
}
|
||
public function getExpiresTime()
|
||
{
|
||
return $this->expire;
|
||
}
|
||
public function getPath()
|
||
{
|
||
return $this->path;
|
||
}
|
||
public function isSecure()
|
||
{
|
||
return $this->secure;
|
||
}
|
||
public function isHttpOnly()
|
||
{
|
||
return $this->httpOnly;
|
||
}
|
||
public function isCleared()
|
||
{
|
||
return $this->expire < time();
|
||
}
|
||
}
|
||
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 $handlerStack = array();
|
||
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;
|
||
}
|
||
public function popHandler()
|
||
{
|
||
return array_pop($this->handlerStack);
|
||
}
|
||
public function getHandlers()
|
||
{
|
||
return $this->handlerStack;
|
||
}
|
||
public function clearHandlers()
|
||
{
|
||
$this->handlerStack = array();
|
||
return $this;
|
||
}
|
||
protected function getInspector(Exception $exception)
|
||
{
|
||
return new Inspector($exception);
|
||
}
|
||
public function register()
|
||
{
|
||
if (!$this->isRegistered) {
|
||
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;
|
||
}
|
||
public function unregister()
|
||
{
|
||
if ($this->isRegistered) {
|
||
restore_exception_handler();
|
||
restore_error_handler();
|
||
$this->isRegistered = false;
|
||
}
|
||
return $this;
|
||
}
|
||
public function allowQuit($exit = null)
|
||
{
|
||
if (func_num_args() == 0) {
|
||
return $this->allowQuit;
|
||
}
|
||
return $this->allowQuit = (bool) $exit;
|
||
}
|
||
public function writeToOutput($send = null)
|
||
{
|
||
if (func_num_args() == 0) {
|
||
return $this->sendOutput;
|
||
}
|
||
return $this->sendOutput = (bool) $send;
|
||
}
|
||
public function handleException(Exception $exception)
|
||
{
|
||
$inspector = $this->getInspector($exception);
|
||
ob_start();
|
||
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))) {
|
||
break;
|
||
}
|
||
}
|
||
$output = ob_get_clean();
|
||
if ($this->allowQuit()) {
|
||
echo $output;
|
||
die;
|
||
} else {
|
||
if ($this->writeToOutput()) {
|
||
echo $output;
|
||
}
|
||
return $output;
|
||
}
|
||
}
|
||
public function handleError($level, $message, $file = null, $line = null)
|
||
{
|
||
if ($level & error_reporting()) {
|
||
$this->handleException(new ErrorException($message, $level, 0, $file, $line));
|
||
}
|
||
}
|
||
public function handleShutdown()
|
||
{
|
||
if ($error = error_get_last()) {
|
||
$this->handleError($error['type'], $error['message'], $error['file'], $error['line']);
|
||
}
|
||
}
|
||
}
|
||
namespace Whoops\Handler;
|
||
|
||
use Whoops\Exception\Inspector;
|
||
use Whoops\Run;
|
||
use Exception;
|
||
interface HandlerInterface
|
||
{
|
||
public function handle();
|
||
public function setRun(Run $run);
|
||
public function setException(Exception $exception);
|
||
public function setInspector(Inspector $inspector);
|
||
}
|
||
namespace Whoops\Handler;
|
||
|
||
use Whoops\Handler\HandlerInterface;
|
||
use Whoops\Exception\Inspector;
|
||
use Whoops\Run;
|
||
use Exception;
|
||
abstract class Handler implements HandlerInterface
|
||
{
|
||
const DONE = 16;
|
||
const LAST_HANDLER = 32;
|
||
const QUIT = 48;
|
||
private $run;
|
||
private $inspector;
|
||
private $exception;
|
||
public function setRun(Run $run)
|
||
{
|
||
$this->run = $run;
|
||
}
|
||
protected function getRun()
|
||
{
|
||
return $this->run;
|
||
}
|
||
public function setInspector(Inspector $inspector)
|
||
{
|
||
$this->inspector = $inspector;
|
||
}
|
||
protected function getInspector()
|
||
{
|
||
return $this->inspector;
|
||
}
|
||
public function setException(Exception $exception)
|
||
{
|
||
$this->exception = $exception;
|
||
}
|
||
protected function getException()
|
||
{
|
||
return $this->exception;
|
||
}
|
||
}
|
||
namespace Whoops\Handler;
|
||
|
||
use Whoops\Handler\Handler;
|
||
use InvalidArgumentException;
|
||
class PrettyPageHandler extends Handler
|
||
{
|
||
private $resourcesPath;
|
||
private $extraTables = array();
|
||
private $pageTitle = 'Whoops! There was an error.';
|
||
protected $editor;
|
||
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');
|
||
public function __construct()
|
||
{
|
||
if (extension_loaded('xdebug')) {
|
||
$this->editors['xdebug'] = function ($file, $line) {
|
||
return str_replace(array('%f', '%l'), array($file, $line), ini_get('xdebug.file_link_format'));
|
||
};
|
||
}
|
||
}
|
||
public function handle()
|
||
{
|
||
if (php_sapi_name() === 'cli' && !isset($_ENV['whoops-test'])) {
|
||
return Handler::DONE;
|
||
}
|
||
if (!($resources = $this->getResourcesPath())) {
|
||
$resources = 'F:\\Nelson\\My Documents - Personal\\Visual Studio 2010\\Projects\\Poniverse\\spa.pony.fm\\vendor\\filp\\whoops\\src\\Whoops\\Handler' . '/../Resources';
|
||
}
|
||
$templateFile = "{$resources}/pretty-template.php";
|
||
$cssFile = "{$resources}/pretty-page.css";
|
||
$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());
|
||
$v->tables = array_merge($extraTables, $v->tables);
|
||
call_user_func(function () use($templateFile, $v) {
|
||
$e = function ($_, $allowLinks = false) {
|
||
$escaped = htmlspecialchars($_, ENT_QUOTES, 'UTF-8');
|
||
if ($allowLinks) {
|
||
$escaped = preg_replace('@([A-z]+?://([-\\w\\.]+[-\\w])+(:\\d+)?(/([\\w/_\\.#-]*(\\?\\S+)?[^\\.\\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $escaped);
|
||
}
|
||
return $escaped;
|
||
};
|
||
$slug = function ($_) {
|
||
$_ = str_replace(' ', '-', $_);
|
||
$_ = preg_replace('/[^\\w\\d\\-\\_]/i', '', $_);
|
||
return strtolower($_);
|
||
};
|
||
require $templateFile;
|
||
});
|
||
return Handler::QUIT;
|
||
}
|
||
public function addDataTable($label, array $data)
|
||
{
|
||
$this->extraTables[$label] = $data;
|
||
}
|
||
public function addDataTableCallback($label, $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);
|
||
return is_array($result) || $result instanceof \Traversable ? $result : array();
|
||
} catch (\Exception $e) {
|
||
return array();
|
||
}
|
||
};
|
||
}
|
||
public function getDataTables($label = null)
|
||
{
|
||
if ($label !== null) {
|
||
return isset($this->extraTables[$label]) ? $this->extraTables[$label] : array();
|
||
}
|
||
return $this->extraTables;
|
||
}
|
||
public function addEditor($identifier, $resolver)
|
||
{
|
||
$this->editors[$identifier] = $resolver;
|
||
}
|
||
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;
|
||
}
|
||
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);
|
||
}
|
||
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;
|
||
}
|
||
public function setPageTitle($title)
|
||
{
|
||
$this->pageTitle = (string) $title;
|
||
}
|
||
public function getPageTitle()
|
||
{
|
||
return $this->pageTitle;
|
||
}
|
||
public function getResourcesPath()
|
||
{
|
||
return $this->resourcesPath;
|
||
}
|
||
public function setResourcesPath($resourcesPath)
|
||
{
|
||
if (!is_dir($resourcesPath)) {
|
||
throw new InvalidArgumentException("{$resourcesPath} is not a valid directory");
|
||
}
|
||
$this->resourcesPath = $resourcesPath;
|
||
}
|
||
}
|
||
namespace Whoops\Handler;
|
||
|
||
use Whoops\Handler\Handler;
|
||
class JsonResponseHandler extends Handler
|
||
{
|
||
private $returnFrames = false;
|
||
private $onlyForAjaxRequests = false;
|
||
public function addTraceToOutput($returnFrames = null)
|
||
{
|
||
if (func_num_args() == 0) {
|
||
return $this->returnFrames;
|
||
}
|
||
$this->returnFrames = (bool) $returnFrames;
|
||
}
|
||
public function onlyForAjaxRequests($onlyForAjaxRequests = null)
|
||
{
|
||
if (func_num_args() == 0) {
|
||
return $this->onlyForAjaxRequests;
|
||
}
|
||
$this->onlyForAjaxRequests = (bool) $onlyForAjaxRequests;
|
||
}
|
||
private function isAjaxRequest()
|
||
{
|
||
return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
|
||
}
|
||
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) {
|
||
$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;
|
||
}
|
||
}
|