PageRenderTime 108ms CodeModel.GetById 6ms RepoModel.GetById 1ms app.codeStats 1ms

/bootstrap/compiled.php

https://github.com/AmaniYunge/greenWeb
PHP | 10757 lines | 10669 code | 88 blank | 0 comment | 804 complexity | 94aec080e230b723f7a542c5cdee6ddc MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. <?php
  2. namespace Illuminate\Support;
  3. class ClassLoader
  4. {
  5. protected static $directories = array();
  6. protected static $registered = false;
  7. public static function load($class)
  8. {
  9. $class = static::normalizeClass($class);
  10. foreach (static::$directories as $directory) {
  11. if (file_exists($path = $directory . DIRECTORY_SEPARATOR . $class)) {
  12. require_once $path;
  13. return true;
  14. }
  15. }
  16. return false;
  17. }
  18. public static function normalizeClass($class)
  19. {
  20. if ($class[0] == '\\') {
  21. $class = substr($class, 1);
  22. }
  23. return str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $class) . '.php';
  24. }
  25. public static function register()
  26. {
  27. if (!static::$registered) {
  28. static::$registered = spl_autoload_register(array('\\Illuminate\\Support\\ClassLoader', 'load'));
  29. }
  30. }
  31. public static function addDirectories($directories)
  32. {
  33. static::$directories = array_merge(static::$directories, (array) $directories);
  34. static::$directories = array_unique(static::$directories);
  35. }
  36. public static function removeDirectories($directories = null)
  37. {
  38. if (is_null($directories)) {
  39. static::$directories = array();
  40. } else {
  41. $directories = (array) $directories;
  42. static::$directories = array_filter(static::$directories, function ($directory) use($directories) {
  43. return !in_array($directory, $directories);
  44. });
  45. }
  46. }
  47. public static function getDirectories()
  48. {
  49. return static::$directories;
  50. }
  51. }
  52. namespace Illuminate\Container;
  53. use Closure;
  54. use ArrayAccess;
  55. use ReflectionClass;
  56. use ReflectionParameter;
  57. class BindingResolutionException extends \Exception
  58. {
  59. }
  60. class Container implements ArrayAccess
  61. {
  62. protected $resolved = array();
  63. protected $bindings = array();
  64. protected $instances = array();
  65. protected $aliases = array();
  66. protected $reboundCallbacks = array();
  67. protected $resolvingCallbacks = array();
  68. protected $globalResolvingCallbacks = array();
  69. protected function resolvable($abstract)
  70. {
  71. return $this->bound($abstract) || $this->isAlias($abstract);
  72. }
  73. public function bound($abstract)
  74. {
  75. return isset($this[$abstract]) || isset($this->instances[$abstract]);
  76. }
  77. public function isAlias($name)
  78. {
  79. return isset($this->aliases[$name]);
  80. }
  81. public function bind($abstract, $concrete = null, $shared = false)
  82. {
  83. if (is_array($abstract)) {
  84. list($abstract, $alias) = $this->extractAlias($abstract);
  85. $this->alias($abstract, $alias);
  86. }
  87. $this->dropStaleInstances($abstract);
  88. if (is_null($concrete)) {
  89. $concrete = $abstract;
  90. }
  91. if (!$concrete instanceof Closure) {
  92. $concrete = $this->getClosure($abstract, $concrete);
  93. }
  94. $bound = $this->bound($abstract);
  95. $this->bindings[$abstract] = compact('concrete', 'shared');
  96. if ($bound) {
  97. $this->rebound($abstract);
  98. }
  99. }
  100. protected function getClosure($abstract, $concrete)
  101. {
  102. return function ($c, $parameters = array()) use($abstract, $concrete) {
  103. $method = $abstract == $concrete ? 'build' : 'make';
  104. return $c->{$method}($concrete, $parameters);
  105. };
  106. }
  107. public function bindIf($abstract, $concrete = null, $shared = false)
  108. {
  109. if (!$this->bound($abstract)) {
  110. $this->bind($abstract, $concrete, $shared);
  111. }
  112. }
  113. public function singleton($abstract, $concrete = null)
  114. {
  115. return $this->bind($abstract, $concrete, true);
  116. }
  117. public function share(Closure $closure)
  118. {
  119. return function ($container) use($closure) {
  120. static $object;
  121. if (is_null($object)) {
  122. $object = $closure($container);
  123. }
  124. return $object;
  125. };
  126. }
  127. public function bindShared($abstract, Closure $closure)
  128. {
  129. return $this->bind($abstract, $this->share($closure), true);
  130. }
  131. public function extend($abstract, Closure $closure)
  132. {
  133. if (!isset($this->bindings[$abstract])) {
  134. throw new \InvalidArgumentException("Type {$abstract} is not bound.");
  135. }
  136. if (isset($this->instances[$abstract])) {
  137. $this->instances[$abstract] = $closure($this->instances[$abstract], $this);
  138. $this->rebound($abstract);
  139. } else {
  140. $extender = $this->getExtender($abstract, $closure);
  141. $this->bind($abstract, $extender, $this->isShared($abstract));
  142. }
  143. }
  144. protected function getExtender($abstract, Closure $closure)
  145. {
  146. $resolver = $this->bindings[$abstract]['concrete'];
  147. return function ($container) use($resolver, $closure) {
  148. return $closure($resolver($container), $container);
  149. };
  150. }
  151. public function instance($abstract, $instance)
  152. {
  153. if (is_array($abstract)) {
  154. list($abstract, $alias) = $this->extractAlias($abstract);
  155. $this->alias($abstract, $alias);
  156. }
  157. unset($this->aliases[$abstract]);
  158. $bound = $this->bound($abstract);
  159. $this->instances[$abstract] = $instance;
  160. if ($bound) {
  161. $this->rebound($abstract);
  162. }
  163. }
  164. public function alias($abstract, $alias)
  165. {
  166. $this->aliases[$alias] = $abstract;
  167. }
  168. protected function extractAlias(array $definition)
  169. {
  170. return array(key($definition), current($definition));
  171. }
  172. public function rebinding($abstract, Closure $callback)
  173. {
  174. $this->reboundCallbacks[$abstract][] = $callback;
  175. if ($this->bound($abstract)) {
  176. return $this->make($abstract);
  177. }
  178. }
  179. public function refresh($abstract, $target, $method)
  180. {
  181. return $this->rebinding($abstract, function ($app, $instance) use($target, $method) {
  182. $target->{$method}($instance);
  183. });
  184. }
  185. protected function rebound($abstract)
  186. {
  187. $instance = $this->make($abstract);
  188. foreach ($this->getReboundCallbacks($abstract) as $callback) {
  189. call_user_func($callback, $this, $instance);
  190. }
  191. }
  192. protected function getReboundCallbacks($abstract)
  193. {
  194. if (isset($this->reboundCallbacks[$abstract])) {
  195. return $this->reboundCallbacks[$abstract];
  196. } else {
  197. return array();
  198. }
  199. }
  200. public function make($abstract, $parameters = array())
  201. {
  202. $abstract = $this->getAlias($abstract);
  203. $this->resolved[$abstract] = true;
  204. if (isset($this->instances[$abstract])) {
  205. return $this->instances[$abstract];
  206. }
  207. $concrete = $this->getConcrete($abstract);
  208. if ($this->isBuildable($concrete, $abstract)) {
  209. $object = $this->build($concrete, $parameters);
  210. } else {
  211. $object = $this->make($concrete, $parameters);
  212. }
  213. if ($this->isShared($abstract)) {
  214. $this->instances[$abstract] = $object;
  215. }
  216. $this->fireResolvingCallbacks($abstract, $object);
  217. return $object;
  218. }
  219. protected function getConcrete($abstract)
  220. {
  221. if (!isset($this->bindings[$abstract])) {
  222. if ($this->missingLeadingSlash($abstract) && isset($this->bindings['\\' . $abstract])) {
  223. $abstract = '\\' . $abstract;
  224. }
  225. return $abstract;
  226. } else {
  227. return $this->bindings[$abstract]['concrete'];
  228. }
  229. }
  230. protected function missingLeadingSlash($abstract)
  231. {
  232. return is_string($abstract) && strpos($abstract, '\\') !== 0;
  233. }
  234. public function build($concrete, $parameters = array())
  235. {
  236. if ($concrete instanceof Closure) {
  237. return $concrete($this, $parameters);
  238. }
  239. $reflector = new ReflectionClass($concrete);
  240. if (!$reflector->isInstantiable()) {
  241. $message = "Target [{$concrete}] is not instantiable.";
  242. throw new BindingResolutionException($message);
  243. }
  244. $constructor = $reflector->getConstructor();
  245. if (is_null($constructor)) {
  246. return new $concrete();
  247. }
  248. $dependencies = $constructor->getParameters();
  249. $parameters = $this->keyParametersByArgument($dependencies, $parameters);
  250. $instances = $this->getDependencies($dependencies, $parameters);
  251. return $reflector->newInstanceArgs($instances);
  252. }
  253. protected function getDependencies($parameters, array $primitives = array())
  254. {
  255. $dependencies = array();
  256. foreach ($parameters as $parameter) {
  257. $dependency = $parameter->getClass();
  258. if (array_key_exists($parameter->name, $primitives)) {
  259. $dependencies[] = $primitives[$parameter->name];
  260. } elseif (is_null($dependency)) {
  261. $dependencies[] = $this->resolveNonClass($parameter);
  262. } else {
  263. $dependencies[] = $this->resolveClass($parameter);
  264. }
  265. }
  266. return (array) $dependencies;
  267. }
  268. protected function resolveNonClass(ReflectionParameter $parameter)
  269. {
  270. if ($parameter->isDefaultValueAvailable()) {
  271. return $parameter->getDefaultValue();
  272. } else {
  273. $message = "Unresolvable dependency resolving [{$parameter}].";
  274. throw new BindingResolutionException($message);
  275. }
  276. }
  277. protected function resolveClass(ReflectionParameter $parameter)
  278. {
  279. try {
  280. return $this->make($parameter->getClass()->name);
  281. } catch (BindingResolutionException $e) {
  282. if ($parameter->isOptional()) {
  283. return $parameter->getDefaultValue();
  284. } else {
  285. throw $e;
  286. }
  287. }
  288. }
  289. protected function keyParametersByArgument(array $dependencies, array $parameters)
  290. {
  291. foreach ($parameters as $key => $value) {
  292. if (is_numeric($key)) {
  293. unset($parameters[$key]);
  294. $parameters[$dependencies[$key]->name] = $value;
  295. }
  296. }
  297. return $parameters;
  298. }
  299. public function resolving($abstract, Closure $callback)
  300. {
  301. $this->resolvingCallbacks[$abstract][] = $callback;
  302. }
  303. public function resolvingAny(Closure $callback)
  304. {
  305. $this->globalResolvingCallbacks[] = $callback;
  306. }
  307. protected function fireResolvingCallbacks($abstract, $object)
  308. {
  309. if (isset($this->resolvingCallbacks[$abstract])) {
  310. $this->fireCallbackArray($object, $this->resolvingCallbacks[$abstract]);
  311. }
  312. $this->fireCallbackArray($object, $this->globalResolvingCallbacks);
  313. }
  314. protected function fireCallbackArray($object, array $callbacks)
  315. {
  316. foreach ($callbacks as $callback) {
  317. call_user_func($callback, $object, $this);
  318. }
  319. }
  320. public function isShared($abstract)
  321. {
  322. if (isset($this->bindings[$abstract]['shared'])) {
  323. $shared = $this->bindings[$abstract]['shared'];
  324. } else {
  325. $shared = false;
  326. }
  327. return isset($this->instances[$abstract]) || $shared === true;
  328. }
  329. protected function isBuildable($concrete, $abstract)
  330. {
  331. return $concrete === $abstract || $concrete instanceof Closure;
  332. }
  333. protected function getAlias($abstract)
  334. {
  335. return isset($this->aliases[$abstract]) ? $this->aliases[$abstract] : $abstract;
  336. }
  337. public function getBindings()
  338. {
  339. return $this->bindings;
  340. }
  341. protected function dropStaleInstances($abstract)
  342. {
  343. unset($this->instances[$abstract]);
  344. unset($this->aliases[$abstract]);
  345. }
  346. public function forgetInstance($abstract)
  347. {
  348. unset($this->instances[$abstract]);
  349. }
  350. public function forgetInstances()
  351. {
  352. $this->instances = array();
  353. }
  354. public function offsetExists($key)
  355. {
  356. return isset($this->bindings[$key]);
  357. }
  358. public function offsetGet($key)
  359. {
  360. return $this->make($key);
  361. }
  362. public function offsetSet($key, $value)
  363. {
  364. if (!$value instanceof Closure) {
  365. $value = function () use($value) {
  366. return $value;
  367. };
  368. }
  369. $this->bind($key, $value);
  370. }
  371. public function offsetUnset($key)
  372. {
  373. unset($this->bindings[$key]);
  374. unset($this->instances[$key]);
  375. }
  376. }
  377. namespace Symfony\Component\HttpKernel;
  378. use Symfony\Component\HttpFoundation\Request;
  379. use Symfony\Component\HttpFoundation\Response;
  380. interface HttpKernelInterface
  381. {
  382. const MASTER_REQUEST = 1;
  383. const SUB_REQUEST = 2;
  384. public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
  385. }
  386. namespace Symfony\Component\HttpKernel;
  387. use Symfony\Component\HttpFoundation\Request;
  388. use Symfony\Component\HttpFoundation\Response;
  389. interface TerminableInterface
  390. {
  391. public function terminate(Request $request, Response $response);
  392. }
  393. namespace Illuminate\Support\Contracts;
  394. interface ResponsePreparerInterface
  395. {
  396. public function prepareResponse($value);
  397. public function readyForResponses();
  398. }
  399. namespace Illuminate\Foundation;
  400. use Closure;
  401. use Illuminate\Http\Request;
  402. use Illuminate\Http\Response;
  403. use Illuminate\Config\FileLoader;
  404. use Illuminate\Container\Container;
  405. use Illuminate\Filesystem\Filesystem;
  406. use Illuminate\Support\Facades\Facade;
  407. use Illuminate\Events\EventServiceProvider;
  408. use Illuminate\Routing\RoutingServiceProvider;
  409. use Illuminate\Exception\ExceptionServiceProvider;
  410. use Illuminate\Config\FileEnvironmentVariablesLoader;
  411. use Symfony\Component\HttpKernel\HttpKernelInterface;
  412. use Symfony\Component\HttpKernel\TerminableInterface;
  413. use Symfony\Component\HttpKernel\Exception\HttpException;
  414. use Symfony\Component\Debug\Exception\FatalErrorException;
  415. use Illuminate\Support\Contracts\ResponsePreparerInterface;
  416. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  417. use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
  418. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  419. class Application extends Container implements HttpKernelInterface, TerminableInterface, ResponsePreparerInterface
  420. {
  421. const VERSION = '4.2.1';
  422. protected $booted = false;
  423. protected $bootingCallbacks = array();
  424. protected $bootedCallbacks = array();
  425. protected $finishCallbacks = array();
  426. protected $shutdownCallbacks = array();
  427. protected $middlewares = array();
  428. protected $serviceProviders = array();
  429. protected $loadedProviders = array();
  430. protected $deferredServices = array();
  431. protected static $requestClass = 'Illuminate\\Http\\Request';
  432. public function __construct(Request $request = null)
  433. {
  434. $this->registerBaseBindings($request ?: $this->createNewRequest());
  435. $this->registerBaseServiceProviders();
  436. $this->registerBaseMiddlewares();
  437. }
  438. protected function createNewRequest()
  439. {
  440. return forward_static_call(array(static::$requestClass, 'createFromGlobals'));
  441. }
  442. protected function registerBaseBindings($request)
  443. {
  444. $this->instance('request', $request);
  445. $this->instance('Illuminate\\Container\\Container', $this);
  446. }
  447. protected function registerBaseServiceProviders()
  448. {
  449. foreach (array('Event', 'Exception', 'Routing') as $name) {
  450. $this->{"register{$name}Provider"}();
  451. }
  452. }
  453. protected function registerExceptionProvider()
  454. {
  455. $this->register(new ExceptionServiceProvider($this));
  456. }
  457. protected function registerRoutingProvider()
  458. {
  459. $this->register(new RoutingServiceProvider($this));
  460. }
  461. protected function registerEventProvider()
  462. {
  463. $this->register(new EventServiceProvider($this));
  464. }
  465. public function bindInstallPaths(array $paths)
  466. {
  467. $this->instance('path', realpath($paths['app']));
  468. foreach (array_except($paths, array('app')) as $key => $value) {
  469. $this->instance("path.{$key}", realpath($value));
  470. }
  471. }
  472. public static function getBootstrapFile()
  473. {
  474. return '/home/hristraining/website/greenWeb/vendor/laravel/framework/src/Illuminate/Foundation' . '/start.php';
  475. }
  476. public function startExceptionHandling()
  477. {
  478. $this['exception']->register($this->environment());
  479. $this['exception']->setDebug($this['config']['app.debug']);
  480. }
  481. public function environment()
  482. {
  483. if (count(func_get_args()) > 0) {
  484. return in_array($this['env'], func_get_args());
  485. } else {
  486. return $this['env'];
  487. }
  488. }
  489. public function isLocal()
  490. {
  491. return $this['env'] == 'local';
  492. }
  493. public function detectEnvironment($envs)
  494. {
  495. $args = isset($_SERVER['argv']) ? $_SERVER['argv'] : null;
  496. return $this['env'] = with(new EnvironmentDetector())->detect($envs, $args);
  497. }
  498. public function runningInConsole()
  499. {
  500. return php_sapi_name() == 'cli';
  501. }
  502. public function runningUnitTests()
  503. {
  504. return $this['env'] == 'testing';
  505. }
  506. public function forceRegister($provider, $options = array())
  507. {
  508. return $this->register($provider, $options, true);
  509. }
  510. public function register($provider, $options = array(), $force = false)
  511. {
  512. if ($registered = $this->getRegistered($provider) && !$force) {
  513. return $registered;
  514. }
  515. if (is_string($provider)) {
  516. $provider = $this->resolveProviderClass($provider);
  517. }
  518. $provider->register();
  519. foreach ($options as $key => $value) {
  520. $this[$key] = $value;
  521. }
  522. $this->markAsRegistered($provider);
  523. if ($this->booted) {
  524. $provider->boot();
  525. }
  526. return $provider;
  527. }
  528. public function getRegistered($provider)
  529. {
  530. $name = is_string($provider) ? $provider : get_class($provider);
  531. if (array_key_exists($name, $this->loadedProviders)) {
  532. return array_first($this->serviceProviders, function ($key, $value) use($name) {
  533. return get_class($value) == $name;
  534. });
  535. }
  536. }
  537. public function resolveProviderClass($provider)
  538. {
  539. return new $provider($this);
  540. }
  541. protected function markAsRegistered($provider)
  542. {
  543. $this['events']->fire($class = get_class($provider), array($provider));
  544. $this->serviceProviders[] = $provider;
  545. $this->loadedProviders[$class] = true;
  546. }
  547. public function loadDeferredProviders()
  548. {
  549. foreach ($this->deferredServices as $service => $provider) {
  550. $this->loadDeferredProvider($service);
  551. }
  552. $this->deferredServices = array();
  553. }
  554. protected function loadDeferredProvider($service)
  555. {
  556. $provider = $this->deferredServices[$service];
  557. if (!isset($this->loadedProviders[$provider])) {
  558. $this->registerDeferredProvider($provider, $service);
  559. }
  560. }
  561. public function registerDeferredProvider($provider, $service = null)
  562. {
  563. if ($service) {
  564. unset($this->deferredServices[$service]);
  565. }
  566. $this->register($instance = new $provider($this));
  567. if (!$this->booted) {
  568. $this->booting(function () use($instance) {
  569. $instance->boot();
  570. });
  571. }
  572. }
  573. public function make($abstract, $parameters = array())
  574. {
  575. $abstract = $this->getAlias($abstract);
  576. if (isset($this->deferredServices[$abstract])) {
  577. $this->loadDeferredProvider($abstract);
  578. }
  579. return parent::make($abstract, $parameters);
  580. }
  581. public function before($callback)
  582. {
  583. return $this['router']->before($callback);
  584. }
  585. public function after($callback)
  586. {
  587. return $this['router']->after($callback);
  588. }
  589. public function finish($callback)
  590. {
  591. $this->finishCallbacks[] = $callback;
  592. }
  593. public function shutdown($callback = null)
  594. {
  595. if (is_null($callback)) {
  596. $this->fireAppCallbacks($this->shutdownCallbacks);
  597. } else {
  598. $this->shutdownCallbacks[] = $callback;
  599. }
  600. }
  601. public function useArraySessions(Closure $callback)
  602. {
  603. $this->bind('session.reject', function () use($callback) {
  604. return $callback;
  605. });
  606. }
  607. public function isBooted()
  608. {
  609. return $this->booted;
  610. }
  611. public function boot()
  612. {
  613. if ($this->booted) {
  614. return;
  615. }
  616. array_walk($this->serviceProviders, function ($p) {
  617. $p->boot();
  618. });
  619. $this->bootApplication();
  620. }
  621. protected function bootApplication()
  622. {
  623. $this->fireAppCallbacks($this->bootingCallbacks);
  624. $this->booted = true;
  625. $this->fireAppCallbacks($this->bootedCallbacks);
  626. }
  627. public function booting($callback)
  628. {
  629. $this->bootingCallbacks[] = $callback;
  630. }
  631. public function booted($callback)
  632. {
  633. $this->bootedCallbacks[] = $callback;
  634. if ($this->isBooted()) {
  635. $this->fireAppCallbacks(array($callback));
  636. }
  637. }
  638. public function run(SymfonyRequest $request = null)
  639. {
  640. $request = $request ?: $this['request'];
  641. $response = with($stack = $this->getStackedClient())->handle($request);
  642. $response->send();
  643. $stack->terminate($request, $response);
  644. }
  645. protected function getStackedClient()
  646. {
  647. $sessionReject = $this->bound('session.reject') ? $this['session.reject'] : null;
  648. $client = with(new \Stack\Builder())->push('Illuminate\\Cookie\\Guard', $this['encrypter'])->push('Illuminate\\Cookie\\Queue', $this['cookie'])->push('Illuminate\\Session\\Middleware', $this['session'], $sessionReject);
  649. $this->mergeCustomMiddlewares($client);
  650. return $client->resolve($this);
  651. }
  652. protected function mergeCustomMiddlewares(\Stack\Builder $stack)
  653. {
  654. foreach ($this->middlewares as $middleware) {
  655. list($class, $parameters) = array_values($middleware);
  656. array_unshift($parameters, $class);
  657. call_user_func_array(array($stack, 'push'), $parameters);
  658. }
  659. }
  660. protected function registerBaseMiddlewares()
  661. {
  662. }
  663. public function middleware($class, array $parameters = array())
  664. {
  665. $this->middlewares[] = compact('class', 'parameters');
  666. return $this;
  667. }
  668. public function forgetMiddleware($class)
  669. {
  670. $this->middlewares = array_filter($this->middlewares, function ($m) use($class) {
  671. return $m['class'] != $class;
  672. });
  673. }
  674. public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  675. {
  676. try {
  677. $this->refreshRequest($request = Request::createFromBase($request));
  678. $this->boot();
  679. return $this->dispatch($request);
  680. } catch (\Exception $e) {
  681. if ($this->runningUnitTests()) {
  682. throw $e;
  683. }
  684. return $this['exception']->handleException($e);
  685. }
  686. }
  687. public function dispatch(Request $request)
  688. {
  689. if ($this->isDownForMaintenance()) {
  690. $response = $this['events']->until('illuminate.app.down');
  691. if (!is_null($response)) {
  692. return $this->prepareResponse($response, $request);
  693. }
  694. }
  695. if ($this->runningUnitTests() && !$this['session']->isStarted()) {
  696. $this['session']->start();
  697. }
  698. return $this['router']->dispatch($this->prepareRequest($request));
  699. }
  700. public function terminate(SymfonyRequest $request, SymfonyResponse $response)
  701. {
  702. $this->callFinishCallbacks($request, $response);
  703. $this->shutdown();
  704. }
  705. protected function refreshRequest(Request $request)
  706. {
  707. $this->instance('request', $request);
  708. Facade::clearResolvedInstance('request');
  709. }
  710. public function callFinishCallbacks(SymfonyRequest $request, SymfonyResponse $response)
  711. {
  712. foreach ($this->finishCallbacks as $callback) {
  713. call_user_func($callback, $request, $response);
  714. }
  715. }
  716. protected function fireAppCallbacks(array $callbacks)
  717. {
  718. foreach ($callbacks as $callback) {
  719. call_user_func($callback, $this);
  720. }
  721. }
  722. public function prepareRequest(Request $request)
  723. {
  724. if (!is_null($this['config']['session.driver']) && !$request->hasSession()) {
  725. $request->setSession($this['session']->driver());
  726. }
  727. return $request;
  728. }
  729. public function prepareResponse($value)
  730. {
  731. if (!$value instanceof SymfonyResponse) {
  732. $value = new Response($value);
  733. }
  734. return $value->prepare($this['request']);
  735. }
  736. public function readyForResponses()
  737. {
  738. return $this->booted;
  739. }
  740. public function isDownForMaintenance()
  741. {
  742. return file_exists($this['config']['app.manifest'] . '/down');
  743. }
  744. public function down(Closure $callback)
  745. {
  746. $this['events']->listen('illuminate.app.down', $callback);
  747. }
  748. public function abort($code, $message = '', array $headers = array())
  749. {
  750. if ($code == 404) {
  751. throw new NotFoundHttpException($message);
  752. } else {
  753. throw new HttpException($code, $message, null, $headers);
  754. }
  755. }
  756. public function missing(Closure $callback)
  757. {
  758. $this->error(function (NotFoundHttpException $e) use($callback) {
  759. return call_user_func($callback, $e);
  760. });
  761. }
  762. public function error(Closure $callback)
  763. {
  764. $this['exception']->error($callback);
  765. }
  766. public function pushError(Closure $callback)
  767. {
  768. $this['exception']->pushError($callback);
  769. }
  770. public function fatal(Closure $callback)
  771. {
  772. $this->error(function (FatalErrorException $e) use($callback) {
  773. return call_user_func($callback, $e);
  774. });
  775. }
  776. public function getConfigLoader()
  777. {
  778. return new FileLoader(new Filesystem(), $this['path'] . '/config');
  779. }
  780. public function getEnvironmentVariablesLoader()
  781. {
  782. return new FileEnvironmentVariablesLoader(new Filesystem(), $this['path.base']);
  783. }
  784. public function getProviderRepository()
  785. {
  786. $manifest = $this['config']['app.manifest'];
  787. return new ProviderRepository(new Filesystem(), $manifest);
  788. }
  789. public function getLoadedProviders()
  790. {
  791. return $this->loadedProviders;
  792. }
  793. public function setDeferredServices(array $services)
  794. {
  795. $this->deferredServices = $services;
  796. }
  797. public function isDeferredService($service)
  798. {
  799. return isset($this->deferredServices[$service]);
  800. }
  801. public static function requestClass($class = null)
  802. {
  803. if (!is_null($class)) {
  804. static::$requestClass = $class;
  805. }
  806. return static::$requestClass;
  807. }
  808. public function setRequestForConsoleEnvironment()
  809. {
  810. $url = $this['config']->get('app.url', 'http://localhost');
  811. $parameters = array($url, 'GET', array(), array(), array(), $_SERVER);
  812. $this->refreshRequest(static::onRequest('create', $parameters));
  813. }
  814. public static function onRequest($method, $parameters = array())
  815. {
  816. return forward_static_call_array(array(static::requestClass(), $method), $parameters);
  817. }
  818. public function getLocale()
  819. {
  820. return $this['config']->get('app.locale');
  821. }
  822. public function setLocale($locale)
  823. {
  824. $this['config']->set('app.locale', $locale);
  825. $this['translator']->setLocale($locale);
  826. $this['events']->fire('locale.changed', array($locale));
  827. }
  828. public function registerCoreContainerAliases()
  829. {
  830. $aliases = array('app' => 'Illuminate\\Foundation\\Application', 'artisan' => 'Illuminate\\Console\\Application', 'auth' => 'Illuminate\\Auth\\AuthManager', 'auth.reminder.repository' => 'Illuminate\\Auth\\Reminders\\ReminderRepositoryInterface', 'blade.compiler' => 'Illuminate\\View\\Compilers\\BladeCompiler', 'cache' => 'Illuminate\\Cache\\CacheManager', 'cache.store' => 'Illuminate\\Cache\\Repository', 'config' => 'Illuminate\\Config\\Repository', 'cookie' => 'Illuminate\\Cookie\\CookieJar', 'encrypter' => 'Illuminate\\Encryption\\Encrypter', 'db' => 'Illuminate\\Database\\DatabaseManager', 'events' => 'Illuminate\\Events\\Dispatcher', 'files' => 'Illuminate\\Filesystem\\Filesystem', 'form' => 'Illuminate\\Html\\FormBuilder', 'hash' => 'Illuminate\\Hashing\\HasherInterface', 'html' => 'Illuminate\\Html\\HtmlBuilder', 'translator' => 'Illuminate\\Translation\\Translator', 'log' => 'Illuminate\\Log\\Writer', 'mailer' => 'Illuminate\\Mail\\Mailer', 'paginator' => 'Illuminate\\Pagination\\Factory', 'auth.reminder' => 'Illuminate\\Auth\\Reminders\\PasswordBroker', 'queue' => 'Illuminate\\Queue\\QueueManager', 'redirect' => 'Illuminate\\Routing\\Redirector', 'redis' => 'Illuminate\\Redis\\Database', 'request' => 'Illuminate\\Http\\Request', 'router' => 'Illuminate\\Routing\\Router', 'session' => 'Illuminate\\Session\\SessionManager', 'session.store' => 'Illuminate\\Session\\Store', 'remote' => 'Illuminate\\Remote\\RemoteManager', 'url' => 'Illuminate\\Routing\\UrlGenerator', 'validator' => 'Illuminate\\Validation\\Factory', 'view' => 'Illuminate\\View\\Factory');
  831. foreach ($aliases as $key => $alias) {
  832. $this->alias($key, $alias);
  833. }
  834. }
  835. public function __get($key)
  836. {
  837. return $this[$key];
  838. }
  839. public function __set($key, $value)
  840. {
  841. $this[$key] = $value;
  842. }
  843. }
  844. namespace Illuminate\Foundation;
  845. use Closure;
  846. class EnvironmentDetector
  847. {
  848. public function detect($environments, $consoleArgs = null)
  849. {
  850. if ($consoleArgs) {
  851. return $this->detectConsoleEnvironment($environments, $consoleArgs);
  852. } else {
  853. return $this->detectWebEnvironment($environments);
  854. }
  855. }
  856. protected function detectWebEnvironment($environments)
  857. {
  858. if ($environments instanceof Closure) {
  859. return call_user_func($environments);
  860. }
  861. foreach ($environments as $environment => $hosts) {
  862. foreach ((array) $hosts as $host) {
  863. if ($this->isMachine($host)) {
  864. return $environment;
  865. }
  866. }
  867. }
  868. return 'production';
  869. }
  870. protected function detectConsoleEnvironment($environments, array $args)
  871. {
  872. if (!is_null($value = $this->getEnvironmentArgument($args))) {
  873. return head(array_slice(explode('=', $value), 1));
  874. } else {
  875. return $this->detectWebEnvironment($environments);
  876. }
  877. }
  878. protected function getEnvironmentArgument(array $args)
  879. {
  880. return array_first($args, function ($k, $v) {
  881. return starts_with($v, '--env');
  882. });
  883. }
  884. public function isMachine($name)
  885. {
  886. return str_is($name, gethostname());
  887. }
  888. }
  889. namespace Illuminate\Http;
  890. use Symfony\Component\HttpFoundation\ParameterBag;
  891. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  892. class Request extends SymfonyRequest
  893. {
  894. protected $json;
  895. protected $sessionStore;
  896. public function instance()
  897. {
  898. return $this;
  899. }
  900. public function method()
  901. {
  902. return $this->getMethod();
  903. }
  904. public function root()
  905. {
  906. return rtrim($this->getSchemeAndHttpHost() . $this->getBaseUrl(), '/');
  907. }
  908. public function url()
  909. {
  910. return rtrim(preg_replace('/\\?.*/', '', $this->getUri()), '/');
  911. }
  912. public function fullUrl()
  913. {
  914. $query = $this->getQueryString();
  915. return $query ? $this->url() . '?' . $query : $this->url();
  916. }
  917. public function path()
  918. {
  919. $pattern = trim($this->getPathInfo(), '/');
  920. return $pattern == '' ? '/' : $pattern;
  921. }
  922. public function decodedPath()
  923. {
  924. return rawurldecode($this->path());
  925. }
  926. public function segment($index, $default = null)
  927. {
  928. return array_get($this->segments(), $index - 1, $default);
  929. }
  930. public function segments()
  931. {
  932. $segments = explode('/', $this->path());
  933. return array_values(array_filter($segments, function ($v) {
  934. return $v != '';
  935. }));
  936. }
  937. public function is()
  938. {
  939. foreach (func_get_args() as $pattern) {
  940. if (str_is($pattern, urldecode($this->path()))) {
  941. return true;
  942. }
  943. }
  944. return false;
  945. }
  946. public function ajax()
  947. {
  948. return $this->isXmlHttpRequest();
  949. }
  950. public function secure()
  951. {
  952. return $this->isSecure();
  953. }
  954. public function exists($key)
  955. {
  956. $keys = is_array($key) ? $key : func_get_args();
  957. $input = $this->all();
  958. foreach ($keys as $value) {
  959. if (!array_key_exists($value, $input)) {
  960. return false;
  961. }
  962. }
  963. return true;
  964. }
  965. public function has($key)
  966. {
  967. $keys = is_array($key) ? $key : func_get_args();
  968. foreach ($keys as $value) {
  969. if ($this->isEmptyString($value)) {
  970. return false;
  971. }
  972. }
  973. return true;
  974. }
  975. protected function isEmptyString($key)
  976. {
  977. $boolOrArray = is_bool($this->input($key)) || is_array($this->input($key));
  978. return !$boolOrArray && trim((string) $this->input($key)) === '';
  979. }
  980. public function all()
  981. {
  982. return array_merge_recursive($this->input(), $this->files->all());
  983. }
  984. public function input($key = null, $default = null)
  985. {
  986. $input = $this->getInputSource()->all() + $this->query->all();
  987. return array_get($input, $key, $default);
  988. }
  989. public function only($keys)
  990. {
  991. $keys = is_array($keys) ? $keys : func_get_args();
  992. return array_only($this->input(), $keys) + array_fill_keys($keys, null);
  993. }
  994. public function except($keys)
  995. {
  996. $keys = is_array($keys) ? $keys : func_get_args();
  997. $results = $this->input();
  998. foreach ($keys as $key) {
  999. array_forget($results, $key);
  1000. }
  1001. return $results;
  1002. }
  1003. public function query($key = null, $default = null)
  1004. {
  1005. return $this->retrieveItem('query', $key, $default);
  1006. }
  1007. public function hasCookie($key)
  1008. {
  1009. return !is_null($this->cookie($key));
  1010. }
  1011. public function cookie($key = null, $default = null)
  1012. {
  1013. return $this->retrieveItem('cookies', $key, $default);
  1014. }
  1015. public function file($key = null, $default = null)
  1016. {
  1017. return array_get($this->files->all(), $key, $default);
  1018. }
  1019. public function hasFile($key)
  1020. {
  1021. if (is_array($file = $this->file($key))) {
  1022. $file = head($file);
  1023. }
  1024. return $file instanceof \SplFileInfo && $file->getPath() != '';
  1025. }
  1026. public function header($key = null, $default = null)
  1027. {
  1028. return $this->retrieveItem('headers', $key, $default);
  1029. }
  1030. public function server($key = null, $default = null)
  1031. {
  1032. return $this->retrieveItem('server', $key, $default);
  1033. }
  1034. public function old($key = null, $default = null)
  1035. {
  1036. return $this->session()->getOldInput($key, $default);
  1037. }
  1038. public function flash($filter = null, $keys = array())
  1039. {
  1040. $flash = !is_null($filter) ? $this->{$filter}($keys) : $this->input();
  1041. $this->session()->flashInput($flash);
  1042. }
  1043. public function flashOnly($keys)
  1044. {
  1045. $keys = is_array($keys) ? $keys : func_get_args();
  1046. return $this->flash('only', $keys);
  1047. }
  1048. public function flashExcept($keys)
  1049. {
  1050. $keys = is_array($keys) ? $keys : func_get_args();
  1051. return $this->flash('except', $keys);
  1052. }
  1053. public function flush()
  1054. {
  1055. $this->session()->flashInput(array());
  1056. }
  1057. protected function retrieveItem($source, $key, $default)
  1058. {
  1059. if (is_null($key)) {
  1060. return $this->{$source}->all();
  1061. } else {
  1062. return $this->{$source}->get($key, $default, true);
  1063. }
  1064. }
  1065. public function merge(array $input)
  1066. {
  1067. $this->getInputSource()->add($input);
  1068. }
  1069. public function replace(array $input)
  1070. {
  1071. $this->getInputSource()->replace($input);
  1072. }
  1073. public function json($key = null, $default = null)
  1074. {
  1075. if (!isset($this->json)) {
  1076. $this->json = new ParameterBag((array) json_decode($this->getContent(), true));
  1077. }
  1078. if (is_null($key)) {
  1079. return $this->json;
  1080. }
  1081. return array_get($this->json->all(), $key, $default);
  1082. }
  1083. protected function getInputSource()
  1084. {
  1085. if ($this->isJson()) {
  1086. return $this->json();
  1087. }
  1088. return $this->getMethod() == 'GET' ? $this->query : $this->request;
  1089. }
  1090. public function isJson()
  1091. {
  1092. return str_contains($this->header('CONTENT_TYPE'), '/json');
  1093. }
  1094. public function wantsJson()
  1095. {
  1096. $acceptable = $this->getAcceptableContentTypes();
  1097. return isset($acceptable[0]) && $acceptable[0] == 'application/json';
  1098. }
  1099. public function format($default = 'html')
  1100. {
  1101. foreach ($this->getAcceptableContentTypes() as $type) {
  1102. if ($format = $this->getFormat($type)) {
  1103. return $format;
  1104. }
  1105. }
  1106. return $default;
  1107. }
  1108. public static function createFromBase(SymfonyRequest $request)
  1109. {
  1110. if ($request instanceof static) {
  1111. return $request;
  1112. }
  1113. return with(new static())->duplicate($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all());
  1114. }
  1115. public function session()
  1116. {
  1117. if (!$this->hasSession()) {
  1118. throw new \RuntimeException('Session store not set on request.');
  1119. }
  1120. return $this->getSession();
  1121. }
  1122. }
  1123. namespace Illuminate\Http;
  1124. use Symfony\Component\HttpKernel\HttpKernelInterface;
  1125. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  1126. class FrameGuard implements HttpKernelInterface
  1127. {
  1128. protected $app;
  1129. public function __construct(HttpKernelInterface $app)
  1130. {
  1131. $this->app = $app;
  1132. }
  1133. public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  1134. {
  1135. $response = $this->app->handle($request, $type, $catch);
  1136. $response->headers->set('X-Frame-Options', 'SAMEORIGIN', false);
  1137. return $response;
  1138. }
  1139. }
  1140. namespace Symfony\Component\HttpFoundation;
  1141. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  1142. class Request
  1143. {
  1144. const HEADER_CLIENT_IP = 'client_ip';
  1145. const HEADER_CLIENT_HOST = 'client_host';
  1146. const HEADER_CLIENT_PROTO = 'client_proto';
  1147. const HEADER_CLIENT_PORT = 'client_port';
  1148. protected static $trustedProxies = array();
  1149. protected static $trustedHostPatterns = array();
  1150. protected static $trustedHosts = array();
  1151. 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');
  1152. protected static $httpMethodParameterOverride = false;
  1153. public $attributes;
  1154. public $request;
  1155. public $query;
  1156. public $server;
  1157. public $files;
  1158. public $cookies;
  1159. public $headers;
  1160. protected $content;
  1161. protected $languages;
  1162. protected $charsets;
  1163. protected $encodings;
  1164. protected $acceptableContentTypes;
  1165. protected $pathInfo;
  1166. protected $requestUri;
  1167. protected $baseUrl;
  1168. protected $basePath;
  1169. protected $method;
  1170. protected $format;
  1171. protected $session;
  1172. protected $locale;
  1173. protected $defaultLocale = 'en';
  1174. protected static $formats;
  1175. protected static $requestFactory;
  1176. public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
  1177. {
  1178. $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
  1179. }
  1180. public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
  1181. {
  1182. $this->request = new ParameterBag($request);
  1183. $this->query = new ParameterBag($query);
  1184. $this->attributes = new ParameterBag($attributes);
  1185. $this->cookies = new ParameterBag($cookies);
  1186. $this->files = new FileBag($files);
  1187. $this->server = new ServerBag($server);
  1188. $this->headers = new HeaderBag($this->server->getHeaders());
  1189. $this->content = $content;
  1190. $this->languages = null;
  1191. $this->charsets = null;
  1192. $this->encodings = null;
  1193. $this->acceptableContentTypes = null;
  1194. $this->pathInfo = null;
  1195. $this->requestUri = null;
  1196. $this->baseUrl = null;
  1197. $this->basePath = null;
  1198. $this->method = null;
  1199. $this->format = null;
  1200. }
  1201. public static function createFromGlobals()
  1202. {
  1203. $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
  1204. 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'))) {
  1205. parse_str($request->getContent(), $data);
  1206. $request->request = new ParameterBag($data);
  1207. }
  1208. return $request;
  1209. }
  1210. public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
  1211. {
  1212. $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);
  1213. $server['PATH_INFO'] = '';
  1214. $server['REQUEST_METHOD'] = strtoupper($method);
  1215. $components = parse_url($uri);
  1216. if (isset($components['host'])) {
  1217. $server['SERVER_NAME'] = $components['host'];
  1218. $server['HTTP_HOST'] = $components['host'];
  1219. }
  1220. if (isset($components['scheme'])) {
  1221. if ('https' === $components['scheme']) {
  1222. $server['HTTPS'] = 'on';
  1223. $server['SERVER_PORT'] = 443;
  1224. } else {
  1225. unset($server['HTTPS']);
  1226. $server['SERVER_PORT'] = 80;
  1227. }
  1228. }
  1229. if (isset($components['port'])) {
  1230. $server['SERVER_PORT'] = $components['port'];
  1231. $server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $components['port'];
  1232. }
  1233. if (isset($components['user'])) {
  1234. $server['PHP_AUTH_USER'] = $components['user'];
  1235. }
  1236. if (isset($components['pass'])) {
  1237. $server['PHP_AUTH_PW'] = $components['pass'];
  1238. }
  1239. if (!isset($components['path'])) {
  1240. $components['path'] = '/';
  1241. }
  1242. switch (strtoupper($method)) {
  1243. case 'POST':
  1244. case 'PUT':
  1245. case 'DELETE':
  1246. if (!isset($server['CONTENT_TYPE'])) {
  1247. $server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
  1248. }
  1249. case 'PATCH':
  1250. $request = $parameters;
  1251. $query = array();
  1252. break;
  1253. default:
  1254. $request = array();
  1255. $query = $parameters;
  1256. break;
  1257. }
  1258. $queryString = '';
  1259. if (isset($components['query'])) {
  1260. parse_str(html_entity_decode($components['query']), $qs);
  1261. if ($query) {
  1262. $query = array_replace($qs, $query);
  1263. $queryString = http_build_query($query, '', '&');
  1264. } else {
  1265. $query = $qs;
  1266. $queryString = $components['query'];
  1267. }
  1268. } elseif ($query) {
  1269. $queryString = http_build_query($query, '', '&');
  1270. }
  1271. $server['REQUEST_URI'] = $components['path'] . ('' !== $queryString ? '?' . $queryString : '');
  1272. $server['QUERY_STRING'] = $queryString;
  1273. return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content);
  1274. }
  1275. public static function setFactory($callable)
  1276. {
  1277. self::$requestFactory = $callable;
  1278. }
  1279. public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
  1280. {
  1281. $dup = clone $this;
  1282. if ($query !== null) {
  1283. $dup->query = new ParameterBag($query);
  1284. }
  1285. if ($request !== null) {
  1286. $dup->request = new ParameterBag($request);
  1287. }
  1288. if ($attributes !== null) {
  1289. $dup->attributes = new ParameterBag($attributes);
  1290. }
  1291. if ($cookies !== null) {
  1292. $dup->cookies = new ParameterBag($cookies);
  1293. }
  1294. if ($files !== null) {
  1295. $dup->files = new FileBag($files);
  1296. }
  1297. if ($server !== null) {
  1298. $dup->server = new ServerBag($server);
  1299. $dup->headers = new HeaderBag($dup->server->getHeaders());
  1300. }
  1301. $dup->languages = null;
  1302. $dup->charsets = null;
  1303. $dup->encodings = null;
  1304. $dup->acceptableContentTypes = null;
  1305. $dup->pathInfo = null;
  1306. $dup->requestUri = null;
  1307. $dup->baseUrl = null;
  1308. $dup->basePath = null;
  1309. $dup->method = null;
  1310. $dup->format = null;
  1311. if (!$dup->get('_format') && $this->get('_format')) {
  1312. $dup->attributes->set('_format', $this->get('_format'));
  1313. }
  1314. if (!$dup->getRequestFormat(null)) {
  1315. $dup->setRequestFormat($format = $this->getRequestFormat(null));
  1316. }
  1317. return $dup;
  1318. }
  1319. public function __clone()
  1320. {
  1321. $this->query = clone $this->query;
  1322. $this->request = clone $this->request;
  1323. $this->attributes = clone $this->attributes;
  1324. $this->cookies = clone $this->cookies;
  1325. $this->files = clone $this->files;
  1326. $this->server = clone $this->server;
  1327. $this->headers = clone $this->headers;
  1328. }
  1329. public function __toString()
  1330. {
  1331. return sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL')) . '
  1332. ' . $this->headers . '
  1333. ' . $this->getContent();
  1334. }
  1335. public function overrideGlobals()
  1336. {
  1337. $_GET = $this->query->all();
  1338. $_POST = $this->request->all();
  1339. $_SERVER = $this->server->all();
  1340. $_COOKIE = $this->cookies->all();
  1341. foreach ($this->headers->all() as $key => $value) {
  1342. $key = strtoupper(str_replace('-', '_', $key));
  1343. if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
  1344. $_SERVER[$key] = implode(', ', $value);
  1345. } else {
  1346. $_SERVER['HTTP_' . $key] = implode(', ', $value);
  1347. }
  1348. }
  1349. $request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE);
  1350. $requestOrder = ini_get('request_order') ?: ini_get('variables_order');
  1351. $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
  1352. $_REQUEST = array();
  1353. foreach (str_split($requestOrder) as $order) {
  1354. $_REQUEST = array_merge($_REQUEST, $request[$order]);
  1355. }
  1356. }
  1357. public static function setTrustedProxies(array $proxies)
  1358. {
  1359. self::$trustedProxies = $proxies;
  1360. }
  1361. public static function getTrustedProxies()
  1362. {
  1363. return self::$trustedProxies;
  1364. }
  1365. public static function setTrustedHosts(array $hostPatterns)
  1366. {
  1367. self::$trustedHostPatterns = array_map(function ($hostPattern) {
  1368. return sprintf('{%s}i', str_replace('}', '\\}', $hostPattern));
  1369. }, $hostPatterns);
  1370. self::$trustedHosts = array();
  1371. }
  1372. public static function getTrustedHosts()
  1373. {
  1374. return self::$trustedHostPatterns;
  1375. }
  1376. public static function setTrustedHeaderName($key, $value)
  1377. {
  1378. if (!array_key_exists($key, self::$trustedHeaders)) {
  1379. throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
  1380. }
  1381. self::$trustedHeaders[$key] = $value;
  1382. }
  1383. public static function getTrustedHeaderName($key)
  1384. {
  1385. if (!array_key_exists($key, self::$trustedHeaders)) {
  1386. throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key));
  1387. }
  1388. return self::$trustedHeaders[$key];
  1389. }
  1390. public static function normalizeQueryString($qs)
  1391. {
  1392. if ('' == $qs) {
  1393. return '';
  1394. }
  1395. $parts = array();
  1396. $order = array();
  1397. foreach (explode('&', $qs) as $param) {
  1398. if ('' === $param || '=' === $param[0]) {
  1399. continue;
  1400. }
  1401. $keyValuePair = explode('=', $param, 2);
  1402. $parts[] = isset($keyValuePair[1]) ? rawurlencode(urldecode($keyValuePair[0])) . '=' . rawurlencode(urldecode($keyValuePair[1])) : rawurlencode(urldecode($keyValuePair[0]));
  1403. $order[] = urldecode($keyValuePair[0]);
  1404. }
  1405. array_multisort($order, SORT_ASC, $parts);
  1406. return implode('&', $parts);
  1407. }
  1408. public static function enableHttpMethodParameterOverride()
  1409. {
  1410. self::$httpMethodParameterOverride = true;
  1411. }
  1412. public static function getHttpMethodParameterOverride()
  1413. {
  1414. return self::$httpMethodParameterOverride;
  1415. }
  1416. public function get($key, $default = null, $deep = false)
  1417. {
  1418. return $this->query->get($key, $this->attributes->get($key, $this->request->get($key, $default, $deep), $deep), $deep);
  1419. }
  1420. public function getSession()
  1421. {
  1422. return $this->session;
  1423. }
  1424. public function hasPreviousSession()
  1425. {
  1426. return $this->hasSession() && $this->cookies->has($this->session->getName());
  1427. }
  1428. public function hasSession()
  1429. {
  1430. return null !== $this->session;
  1431. }
  1432. public function setSession(SessionInterface $session)
  1433. {
  1434. $this->session = $session;
  1435. }
  1436. public function getClientIps()
  1437. {
  1438. $ip = $this->server->get('REMOTE_ADDR');
  1439. if (!self::$trustedProxies) {
  1440. return array($ip);
  1441. }
  1442. if (!self::$trustedHeaders[self::HEADER_CLIENT_IP] || !$this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
  1443. return array($ip);
  1444. }
  1445. $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
  1446. $clientIps[] = $ip;
  1447. $ip = $clientIps[0];
  1448. foreach ($clientIps as $key => $clientIp) {
  1449. if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
  1450. unset($clientIps[$key]);
  1451. }
  1452. }
  1453. return $clientIps ? array_reverse($clientIps) : array($ip);
  1454. }
  1455. public function getClientIp()
  1456. {
  1457. $ipAddresses = $this->getClientIps();
  1458. return $ipAddresses[0];
  1459. }
  1460. public function getScriptName()
  1461. {
  1462. return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
  1463. }
  1464. public function getPathInfo()
  1465. {
  1466. if (null === $this->pathInfo) {
  1467. $this->pathInfo = $this->preparePathInfo();
  1468. }
  1469. return $this->pathInfo;
  1470. }
  1471. public function getBasePath()
  1472. {
  1473. if (null === $this->basePath) {
  1474. $this->basePath = $this->prepareBasePath();
  1475. }
  1476. return $this->basePath;
  1477. }
  1478. public function getBaseUrl()
  1479. {
  1480. if (null === $this->baseUrl) {
  1481. $this->baseUrl = $this->prepareBaseUrl();
  1482. }
  1483. return $this->baseUrl;
  1484. }
  1485. public function getScheme()
  1486. {
  1487. return $this->isSecure() ? 'https' : 'http';
  1488. }
  1489. public function getPort()
  1490. {
  1491. if (self::$trustedProxies) {
  1492. if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && ($port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT]))) {
  1493. return $port;
  1494. }
  1495. if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && 'https' === $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO], 'http')) {
  1496. return 443;
  1497. }
  1498. }
  1499. if ($host = $this->headers->get('HOST')) {
  1500. if (false !== ($pos = strrpos($host, ':'))) {
  1501. return intval(substr($host, $pos + 1));
  1502. }
  1503. return 'https' === $this->getScheme() ? 443 : 80;
  1504. }
  1505. return $this->server->get('SERVER_PORT');
  1506. }
  1507. public function getUser()
  1508. {
  1509. return $this->server->get('PHP_AUTH_USER');
  1510. }
  1511. public function getPassword()
  1512. {
  1513. return $this->server->get('PHP_AUTH_PW');
  1514. }
  1515. public function getUserInfo()
  1516. {
  1517. $userinfo = $this->getUser();
  1518. $pass = $this->getPassword();
  1519. if ('' != $pass) {
  1520. $userinfo .= ":{$pass}";
  1521. }
  1522. return $userinfo;
  1523. }
  1524. public function getHttpHost()
  1525. {
  1526. $scheme = $this->getScheme();
  1527. $port = $this->getPort();
  1528. if ('http' == $scheme && $port == 80 || 'https' == $scheme && $port == 443) {
  1529. return $this->getHost();
  1530. }
  1531. return $this->getHost() . ':' . $port;
  1532. }
  1533. public function getRequestUri()
  1534. {
  1535. if (null === $this->requestUri) {
  1536. $this->requestUri = $this->prepareRequestUri();
  1537. }
  1538. return $this->requestUri;
  1539. }
  1540. public function getSchemeAndHttpHost()
  1541. {
  1542. return $this->getScheme() . '://' . $this->getHttpHost();
  1543. }
  1544. public function getUri()
  1545. {
  1546. if (null !== ($qs = $this->getQueryString())) {
  1547. $qs = '?' . $qs;
  1548. }
  1549. return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $this->getPathInfo() . $qs;
  1550. }
  1551. public function getUriForPath($path)
  1552. {
  1553. return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $path;
  1554. }
  1555. public function getQueryString()
  1556. {
  1557. $qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
  1558. return '' === $qs ? null : $qs;
  1559. }
  1560. public function isSecure()
  1561. {
  1562. if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && ($proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO]))) {
  1563. return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1'));
  1564. }
  1565. return 'on' == strtolower($this->server->get('HTTPS')) || 1 == $this->server->get('HTTPS');
  1566. }
  1567. public function getHost()
  1568. {
  1569. if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && ($host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST]))) {
  1570. $elements = explode(',', $host);
  1571. $host = $elements[count($elements) - 1];
  1572. } elseif (!($host = $this->headers->get('HOST'))) {
  1573. if (!($host = $this->server->get('SERVER_NAME'))) {
  1574. $host = $this->server->get('SERVER_ADDR', '');
  1575. }
  1576. }
  1577. $host = strtolower(preg_replace('/:\\d+$/', '', trim($host)));
  1578. if ($host && !preg_match('/^\\[?(?:[a-zA-Z0-9-:\\]_]+\\.?)+$/', $host)) {
  1579. throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host));
  1580. }
  1581. if (count(self::$trustedHostPatterns) > 0) {
  1582. if (in_array($host, self::$trustedHosts)) {
  1583. return $host;
  1584. }
  1585. foreach (self::$trustedHostPatterns as $pattern) {
  1586. if (preg_match($pattern, $host)) {
  1587. self::$trustedHosts[] = $host;
  1588. return $host;
  1589. }
  1590. }
  1591. throw new \UnexpectedValueException(sprintf('Untrusted Host "%s"', $host));
  1592. }
  1593. return $host;
  1594. }
  1595. public function setMethod($method)
  1596. {
  1597. $this->method = null;
  1598. $this->server->set('REQUEST_METHOD', $method);
  1599. }
  1600. public function getMethod()
  1601. {
  1602. if (null === $this->method) {
  1603. $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
  1604. if ('POST' === $this->method) {
  1605. if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
  1606. $this->method = strtoupper($method);
  1607. } elseif (self::$httpMethodParameterOverride) {
  1608. $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
  1609. }
  1610. }
  1611. }
  1612. return $this->method;
  1613. }
  1614. public function getRealMethod()
  1615. {
  1616. return strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
  1617. }
  1618. public function getMimeType($format)
  1619. {
  1620. if (null === static::$formats) {
  1621. static::initializeFormats();
  1622. }
  1623. return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
  1624. }
  1625. public function getFormat($mimeType)
  1626. {
  1627. if (false !== ($pos = strpos($mimeType, ';'))) {
  1628. $mimeType = substr($mimeType, 0, $pos);
  1629. }
  1630. if (null === static::$formats) {
  1631. static::initializeFormats();
  1632. }
  1633. foreach (static::$formats as $format => $mimeTypes) {
  1634. if (in_array($mimeType, (array) $mimeTypes)) {
  1635. return $format;
  1636. }
  1637. }
  1638. }
  1639. public function setFormat($format, $mimeTypes)
  1640. {
  1641. if (null === static::$formats) {
  1642. static::initializeFormats();
  1643. }
  1644. static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
  1645. }
  1646. public function getRequestFormat($default = 'html')
  1647. {
  1648. if (null === $this->format) {
  1649. $this->format = $this->get('_format', $default);
  1650. }
  1651. return $this->format;
  1652. }
  1653. public function setRequestFormat($format)
  1654. {
  1655. $this->format = $format;
  1656. }
  1657. public function getContentType()
  1658. {
  1659. return $this->getFormat($this->headers->get('CONTENT_TYPE'));
  1660. }
  1661. public function setDefaultLocale($locale)
  1662. {
  1663. $this->defaultLocale = $locale;
  1664. if (null === $this->locale) {
  1665. $this->setPhpDefaultLocale($locale);
  1666. }
  1667. }
  1668. public function setLocale($locale)
  1669. {
  1670. $this->setPhpDefaultLocale($this->locale = $locale);
  1671. }
  1672. public function getLocale()
  1673. {
  1674. return null === $this->locale ? $this->defaultLocale : $this->locale;
  1675. }
  1676. public function isMethod($method)
  1677. {
  1678. return $this->getMethod() === strtoupper($method);
  1679. }
  1680. public function isMethodSafe()
  1681. {
  1682. return in_array($this->getMethod(), array('GET', 'HEAD'));
  1683. }
  1684. public function getContent($asResource = false)
  1685. {
  1686. if (false === $this->content || true === $asResource && null !== $this->content) {
  1687. throw new \LogicException('getContent() can only be called once when using the resource return type.');
  1688. }
  1689. if (true === $asResource) {
  1690. $this->content = false;
  1691. return fopen('php://input', 'rb');
  1692. }
  1693. if (null === $this->content) {
  1694. $this->content = file_get_contents('php://input');
  1695. }
  1696. return $this->content;
  1697. }
  1698. public function getETags()
  1699. {
  1700. return preg_split('/\\s*,\\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
  1701. }
  1702. public function isNoCache()
  1703. {
  1704. return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
  1705. }
  1706. public function getPreferredLanguage(array $locales = null)
  1707. {
  1708. $preferredLanguages = $this->getLanguages();
  1709. if (empty($locales)) {
  1710. return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null;
  1711. }
  1712. if (!$preferredLanguages) {
  1713. return $locales[0];
  1714. }
  1715. $extendedPreferredLanguages = array();
  1716. foreach ($preferredLanguages as $language) {
  1717. $extendedPreferredLanguages[] = $language;
  1718. if (false !== ($position = strpos($language, '_'))) {
  1719. $superLanguage = substr($language, 0, $position);
  1720. if (!in_array($superLanguage, $preferredLanguages)) {
  1721. $extendedPreferredLanguages[] = $superLanguage;
  1722. }
  1723. }
  1724. }
  1725. $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
  1726. return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
  1727. }
  1728. public function getLanguages()
  1729. {
  1730. if (null !== $this->languages) {
  1731. return $this->languages;
  1732. }
  1733. $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
  1734. $this->languages = array();
  1735. foreach (array_keys($languages) as $lang) {
  1736. if (strstr($lang, '-')) {
  1737. $codes = explode('-', $lang);
  1738. if ($codes[0] == 'i') {
  1739. if (count($codes) > 1) {
  1740. $lang = $codes[1];
  1741. }
  1742. } else {
  1743. for ($i = 0, $max = count($codes); $i < $max; $i++) {
  1744. if ($i == 0) {
  1745. $lang = strtolower($codes[0]);
  1746. } else {
  1747. $lang .= '_' . strtoupper($codes[$i]);
  1748. }
  1749. }
  1750. }
  1751. }
  1752. $this->languages[] = $lang;
  1753. }
  1754. return $this->languages;
  1755. }
  1756. public function getCharsets()
  1757. {
  1758. if (null !== $this->charsets) {
  1759. return $this->charsets;
  1760. }
  1761. return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
  1762. }
  1763. public function getEncodings()
  1764. {
  1765. if (null !== $this->encodings) {
  1766. return $this->encodings;
  1767. }
  1768. return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all());
  1769. }
  1770. public function getAcceptableContentTypes()
  1771. {
  1772. if (null !== $this->acceptableContentTypes) {
  1773. return $this->acceptableContentTypes;
  1774. }
  1775. return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
  1776. }
  1777. public function isXmlHttpRequest()
  1778. {
  1779. return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
  1780. }
  1781. protected function prepareRequestUri()
  1782. {
  1783. $requestUri = '';
  1784. if ($this->headers->has('X_ORIGINAL_URL')) {
  1785. $requestUri = $this->headers->get('X_ORIGINAL_URL');
  1786. $this->headers->remove('X_ORIGINAL_URL');
  1787. $this->server->remove('HTTP_X_ORIGINAL_URL');
  1788. $this->server->remove('UNENCODED_URL');
  1789. $this->server->remove('IIS_WasUrlRewritten');
  1790. } elseif ($this->headers->has('X_REWRITE_URL')) {
  1791. $requestUri = $this->headers->get('X_REWRITE_URL');
  1792. $this->headers->remove('X_REWRITE_URL');
  1793. } elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
  1794. $requestUri = $this->server->get('UNENCODED_URL');
  1795. $this->server->remove('UNENCODED_URL');
  1796. $this->server->remove('IIS_WasUrlRewritten');
  1797. } elseif ($this->server->has('REQUEST_URI')) {
  1798. $requestUri = $this->server->get('REQUEST_URI');
  1799. $schemeAndHttpHost = $this->getSchemeAndHttpHost();
  1800. if (strpos($requestUri, $schemeAndHttpHost) === 0) {
  1801. $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
  1802. }
  1803. } elseif ($this->server->has('ORIG_PATH_INFO')) {
  1804. $requestUri = $this->server->get('ORIG_PATH_INFO');
  1805. if ('' != $this->server->get('QUERY_STRING')) {
  1806. $requestUri .= '?' . $this->server->get('QUERY_STRING');
  1807. }
  1808. $this->server->remove('ORIG_PATH_INFO');
  1809. }
  1810. $this->server->set('REQUEST_URI', $requestUri);
  1811. return $requestUri;
  1812. }
  1813. protected function prepareBaseUrl()
  1814. {
  1815. $filename = basename($this->server->get('SCRIPT_FILENAME'));
  1816. if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
  1817. $baseUrl = $this->server->get('SCRIPT_NAME');
  1818. } elseif (basename($this->server->get('PHP_SELF')) === $filename) {
  1819. $baseUrl = $this->server->get('PHP_SELF');
  1820. } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
  1821. $baseUrl = $this->server->get('ORIG_SCRIPT_NAME');
  1822. } else {
  1823. $path = $this->server->get('PHP_SELF', '');
  1824. $file = $this->server->get('SCRIPT_FILENAME', '');
  1825. $segs = explode('/', trim($file, '/'));
  1826. $segs = array_reverse($segs);
  1827. $index = 0;
  1828. $last = count($segs);
  1829. $baseUrl = '';
  1830. do {
  1831. $seg = $segs[$index];
  1832. $baseUrl = '/' . $seg . $baseUrl;
  1833. ++$index;
  1834. } while ($last > $index && false !== ($pos = strpos($path, $baseUrl)) && 0 != $pos);
  1835. }
  1836. $requestUri = $this->getRequestUri();
  1837. if ($baseUrl && false !== ($prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl))) {
  1838. return $prefix;
  1839. }
  1840. if ($baseUrl && false !== ($prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl)))) {
  1841. return rtrim($prefix, '/');
  1842. }
  1843. $truncatedRequestUri = $requestUri;
  1844. if (false !== ($pos = strpos($requestUri, '?'))) {
  1845. $truncatedRequestUri = substr($requestUri, 0, $pos);
  1846. }
  1847. $basename = basename($baseUrl);
  1848. if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
  1849. return '';
  1850. }
  1851. if (strlen($requestUri) >= strlen($baseUrl) && false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0) {
  1852. $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
  1853. }
  1854. return rtrim($baseUrl, '/');
  1855. }
  1856. protected function prepareBasePath()
  1857. {
  1858. $filename = basename($this->server->get('SCRIPT_FILENAME'));
  1859. $baseUrl = $this->getBaseUrl();
  1860. if (empty($baseUrl)) {
  1861. return '';
  1862. }
  1863. if (basename($baseUrl) === $filename) {
  1864. $basePath = dirname($baseUrl);
  1865. } else {
  1866. $basePath = $baseUrl;
  1867. }
  1868. if ('\\' === DIRECTORY_SEPARATOR) {
  1869. $basePath = str_replace('\\', '/', $basePath);
  1870. }
  1871. return rtrim($basePath, '/');
  1872. }
  1873. protected function preparePathInfo()
  1874. {
  1875. $baseUrl = $this->getBaseUrl();
  1876. if (null === ($requestUri = $this->getRequestUri())) {
  1877. return '/';
  1878. }
  1879. $pathInfo = '/';
  1880. if ($pos = strpos($requestUri, '?')) {
  1881. $requestUri = substr($requestUri, 0, $pos);
  1882. }
  1883. if (null !== $baseUrl && false === ($pathInfo = substr($requestUri, strlen($baseUrl)))) {
  1884. return '/';
  1885. } elseif (null === $baseUrl) {
  1886. return $requestUri;
  1887. }
  1888. return (string) $pathInfo;
  1889. }
  1890. protected static function initializeFormats()
  1891. {
  1892. 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'));
  1893. }
  1894. private function setPhpDefaultLocale($locale)
  1895. {
  1896. try {
  1897. if (class_exists('Locale', false)) {
  1898. \Locale::setDefault($locale);
  1899. }
  1900. } catch (\Exception $e) {
  1901. }
  1902. }
  1903. private function getUrlencodedPrefix($string, $prefix)
  1904. {
  1905. if (0 !== strpos(rawurldecode($string), $prefix)) {
  1906. return false;
  1907. }
  1908. $len = strlen($prefix);
  1909. if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
  1910. return $match[0];
  1911. }
  1912. return false;
  1913. }
  1914. private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
  1915. {
  1916. if (self::$requestFactory) {
  1917. $request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content);
  1918. if (!$request instanceof Request) {
  1919. throw new \LogicException('The Request factory must return an instance of Symfony\\Component\\HttpFoundation\\Request.');
  1920. }
  1921. return $request;
  1922. }
  1923. return new static($query, $request, $attributes, $cookies, $files, $server, $content);
  1924. }
  1925. }
  1926. namespace Symfony\Component\HttpFoundation;
  1927. class ParameterBag implements \IteratorAggregate, \Countable
  1928. {
  1929. protected $parameters;
  1930. public function __construct(array $parameters = array())
  1931. {
  1932. $this->parameters = $parameters;
  1933. }
  1934. public function all()
  1935. {
  1936. return $this->parameters;
  1937. }
  1938. public function keys()
  1939. {
  1940. return array_keys($this->parameters);
  1941. }
  1942. public function replace(array $parameters = array())
  1943. {
  1944. $this->parameters = $parameters;
  1945. }
  1946. public function add(array $parameters = array())
  1947. {
  1948. $this->parameters = array_replace($this->parameters, $parameters);
  1949. }
  1950. public function get($path, $default = null, $deep = false)
  1951. {
  1952. if (!$deep || false === ($pos = strpos($path, '['))) {
  1953. return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default;
  1954. }
  1955. $root = substr($path, 0, $pos);
  1956. if (!array_key_exists($root, $this->parameters)) {
  1957. return $default;
  1958. }
  1959. $value = $this->parameters[$root];
  1960. $currentKey = null;
  1961. for ($i = $pos, $c = strlen($path); $i < $c; $i++) {
  1962. $char = $path[$i];
  1963. if ('[' === $char) {
  1964. if (null !== $currentKey) {
  1965. throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i));
  1966. }
  1967. $currentKey = '';
  1968. } elseif (']' === $char) {
  1969. if (null === $currentKey) {
  1970. throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i));
  1971. }
  1972. if (!is_array($value) || !array_key_exists($currentKey, $value)) {
  1973. return $default;
  1974. }
  1975. $value = $value[$currentKey];
  1976. $currentKey = null;
  1977. } else {
  1978. if (null === $currentKey) {
  1979. throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i));
  1980. }
  1981. $currentKey .= $char;
  1982. }
  1983. }
  1984. if (null !== $currentKey) {
  1985. throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".'));
  1986. }
  1987. return $value;
  1988. }
  1989. public function set($key, $value)
  1990. {
  1991. $this->parameters[$key] = $value;
  1992. }
  1993. public function has($key)
  1994. {
  1995. return array_key_exists($key, $this->parameters);
  1996. }
  1997. public function remove($key)
  1998. {
  1999. unset($this->parameters[$key]);
  2000. }
  2001. public function getAlpha($key, $default = '', $deep = false)
  2002. {
  2003. return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep));
  2004. }
  2005. public function getAlnum($key, $default = '', $deep = false)
  2006. {
  2007. return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep));
  2008. }
  2009. public function getDigits($key, $default = '', $deep = false)
  2010. {
  2011. return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT));
  2012. }
  2013. public function getInt($key, $default = 0, $deep = false)
  2014. {
  2015. return (int) $this->get($key, $default, $deep);
  2016. }
  2017. public function filter($key, $default = null, $deep = false, $filter = FILTER_DEFAULT, $options = array())
  2018. {
  2019. $value = $this->get($key, $default, $deep);
  2020. if (!is_array($options) && $options) {
  2021. $options = array('flags' => $options);
  2022. }
  2023. if (is_array($value) && !isset($options['flags'])) {
  2024. $options['flags'] = FILTER_REQUIRE_ARRAY;
  2025. }
  2026. return filter_var($value, $filter, $options);
  2027. }
  2028. public function getIterator()
  2029. {
  2030. return new \ArrayIterator($this->parameters);
  2031. }
  2032. public function count()
  2033. {
  2034. return count($this->parameters);
  2035. }
  2036. }
  2037. namespace Symfony\Component\HttpFoundation;
  2038. use Symfony\Component\HttpFoundation\File\UploadedFile;
  2039. class FileBag extends ParameterBag
  2040. {
  2041. private static $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
  2042. public function __construct(array $parameters = array())
  2043. {
  2044. $this->replace($parameters);
  2045. }
  2046. public function replace(array $files = array())
  2047. {
  2048. $this->parameters = array();
  2049. $this->add($files);
  2050. }
  2051. public function set($key, $value)
  2052. {
  2053. if (!is_array($value) && !$value instanceof UploadedFile) {
  2054. throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
  2055. }
  2056. parent::set($key, $this->convertFileInformation($value));
  2057. }
  2058. public function add(array $files = array())
  2059. {
  2060. foreach ($files as $key => $file) {
  2061. $this->set($key, $file);
  2062. }
  2063. }
  2064. protected function convertFileInformation($file)
  2065. {
  2066. if ($file instanceof UploadedFile) {
  2067. return $file;
  2068. }
  2069. $file = $this->fixPhpFilesArray($file);
  2070. if (is_array($file)) {
  2071. $keys = array_keys($file);
  2072. sort($keys);
  2073. if ($keys == self::$fileKeys) {
  2074. if (UPLOAD_ERR_NO_FILE == $file['error']) {
  2075. $file = null;
  2076. } else {
  2077. $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
  2078. }
  2079. } else {
  2080. $file = array_map(array($this, 'convertFileInformation'), $file);
  2081. }
  2082. }
  2083. return $file;
  2084. }
  2085. protected function fixPhpFilesArray($data)
  2086. {
  2087. if (!is_array($data)) {
  2088. return $data;
  2089. }
  2090. $keys = array_keys($data);
  2091. sort($keys);
  2092. if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
  2093. return $data;
  2094. }
  2095. $files = $data;
  2096. foreach (self::$fileKeys as $k) {
  2097. unset($files[$k]);
  2098. }
  2099. foreach (array_keys($data['name']) as $key) {
  2100. $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]));
  2101. }
  2102. return $files;
  2103. }
  2104. }
  2105. namespace Symfony\Component\HttpFoundation;
  2106. class ServerBag extends ParameterBag
  2107. {
  2108. public function getHeaders()
  2109. {
  2110. $headers = array();
  2111. $contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
  2112. foreach ($this->parameters as $key => $value) {
  2113. if (0 === strpos($key, 'HTTP_')) {
  2114. $headers[substr($key, 5)] = $value;
  2115. } elseif (isset($contentHeaders[$key])) {
  2116. $headers[$key] = $value;
  2117. }
  2118. }
  2119. if (isset($this->parameters['PHP_AUTH_USER'])) {
  2120. $headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER'];
  2121. $headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
  2122. } else {
  2123. $authorizationHeader = null;
  2124. if (isset($this->parameters['HTTP_AUTHORIZATION'])) {
  2125. $authorizationHeader = $this->parameters['HTTP_AUTHORIZATION'];
  2126. } elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
  2127. $authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION'];
  2128. }
  2129. if (null !== $authorizationHeader) {
  2130. if (0 === stripos($authorizationHeader, 'basic')) {
  2131. $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)));
  2132. if (count($exploded) == 2) {
  2133. list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
  2134. }
  2135. } elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && 0 === stripos($authorizationHeader, 'digest')) {
  2136. $headers['PHP_AUTH_DIGEST'] = $authorizationHeader;
  2137. $this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader;
  2138. }
  2139. }
  2140. }
  2141. if (isset($headers['PHP_AUTH_USER'])) {
  2142. $headers['AUTHORIZATION'] = 'Basic ' . base64_encode($headers['PHP_AUTH_USER'] . ':' . $headers['PHP_AUTH_PW']);
  2143. } elseif (isset($headers['PHP_AUTH_DIGEST'])) {
  2144. $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
  2145. }
  2146. return $headers;
  2147. }
  2148. }
  2149. namespace Symfony\Component\HttpFoundation;
  2150. class HeaderBag implements \IteratorAggregate, \Countable
  2151. {
  2152. protected $headers = array();
  2153. protected $cacheControl = array();
  2154. public function __construct(array $headers = array())
  2155. {
  2156. foreach ($headers as $key => $values) {
  2157. $this->set($key, $values);
  2158. }
  2159. }
  2160. public function __toString()
  2161. {
  2162. if (!$this->headers) {
  2163. return '';
  2164. }
  2165. $max = max(array_map('strlen', array_keys($this->headers))) + 1;
  2166. $content = '';
  2167. ksort($this->headers);
  2168. foreach ($this->headers as $name => $values) {
  2169. $name = implode('-', array_map('ucfirst', explode('-', $name)));
  2170. foreach ($values as $value) {
  2171. $content .= sprintf("%-{$max}s %s\r\n", $name . ':', $value);
  2172. }
  2173. }
  2174. return $content;
  2175. }
  2176. public function all()
  2177. {
  2178. return $this->headers;
  2179. }
  2180. public function keys()
  2181. {
  2182. return array_keys($this->headers);
  2183. }
  2184. public function replace(array $headers = array())
  2185. {
  2186. $this->headers = array();
  2187. $this->add($headers);
  2188. }
  2189. public function add(array $headers)
  2190. {
  2191. foreach ($headers as $key => $values) {
  2192. $this->set($key, $values);
  2193. }
  2194. }
  2195. public function get($key, $default = null, $first = true)
  2196. {
  2197. $key = strtr(strtolower($key), '_', '-');
  2198. if (!array_key_exists($key, $this->headers)) {
  2199. if (null === $default) {
  2200. return $first ? null : array();
  2201. }
  2202. return $first ? $default : array($default);
  2203. }
  2204. if ($first) {
  2205. return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
  2206. }
  2207. return $this->headers[$key];
  2208. }
  2209. public function set($key, $values, $replace = true)
  2210. {
  2211. $key = strtr(strtolower($key), '_', '-');
  2212. $values = array_values((array) $values);
  2213. if (true === $replace || !isset($this->headers[$key])) {
  2214. $this->headers[$key] = $values;
  2215. } else {
  2216. $this->headers[$key] = array_merge($this->headers[$key], $values);
  2217. }
  2218. if ('cache-control' === $key) {
  2219. $this->cacheControl = $this->parseCacheControl($values[0]);
  2220. }
  2221. }
  2222. public function has($key)
  2223. {
  2224. return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers);
  2225. }
  2226. public function contains($key, $value)
  2227. {
  2228. return in_array($value, $this->get($key, null, false));
  2229. }
  2230. public function remove($key)
  2231. {
  2232. $key = strtr(strtolower($key), '_', '-');
  2233. unset($this->headers[$key]);
  2234. if ('cache-control' === $key) {
  2235. $this->cacheControl = array();
  2236. }
  2237. }
  2238. public function getDate($key, \DateTime $default = null)
  2239. {
  2240. if (null === ($value = $this->get($key))) {
  2241. return $default;
  2242. }
  2243. if (false === ($date = \DateTime::createFromFormat(DATE_RFC2822, $value))) {
  2244. throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
  2245. }
  2246. return $date;
  2247. }
  2248. public function addCacheControlDirective($key, $value = true)
  2249. {
  2250. $this->cacheControl[$key] = $value;
  2251. $this->set('Cache-Control', $this->getCacheControlHeader());
  2252. }
  2253. public function hasCacheControlDirective($key)
  2254. {
  2255. return array_key_exists($key, $this->cacheControl);
  2256. }
  2257. public function getCacheControlDirective($key)
  2258. {
  2259. return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
  2260. }
  2261. public function removeCacheControlDirective($key)
  2262. {
  2263. unset($this->cacheControl[$key]);
  2264. $this->set('Cache-Control', $this->getCacheControlHeader());
  2265. }
  2266. public function getIterator()
  2267. {
  2268. return new \ArrayIterator($this->headers);
  2269. }
  2270. public function count()
  2271. {
  2272. return count($this->headers);
  2273. }
  2274. protected function getCacheControlHeader()
  2275. {
  2276. $parts = array();
  2277. ksort($this->cacheControl);
  2278. foreach ($this->cacheControl as $key => $value) {
  2279. if (true === $value) {
  2280. $parts[] = $key;
  2281. } else {
  2282. if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
  2283. $value = '"' . $value . '"';
  2284. }
  2285. $parts[] = "{$key}={$value}";
  2286. }
  2287. }
  2288. return implode(', ', $parts);
  2289. }
  2290. protected function parseCacheControl($header)
  2291. {
  2292. $cacheControl = array();
  2293. preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\\s*(?:=(?:"([^"]*)"|([^ \\t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
  2294. foreach ($matches as $match) {
  2295. $cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
  2296. }
  2297. return $cacheControl;
  2298. }
  2299. }
  2300. namespace Symfony\Component\HttpFoundation\Session;
  2301. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  2302. interface SessionInterface
  2303. {
  2304. public function start();
  2305. public function getId();
  2306. public function setId($id);
  2307. public function getName();
  2308. public function setName($name);
  2309. public function invalidate($lifetime = null);
  2310. public function migrate($destroy = false, $lifetime = null);
  2311. public function save();
  2312. public function has($name);
  2313. public function get($name, $default = null);
  2314. public function set($name, $value);
  2315. public function all();
  2316. public function replace(array $attributes);
  2317. public function remove($name);
  2318. public function clear();
  2319. public function isStarted();
  2320. public function registerBag(SessionBagInterface $bag);
  2321. public function getBag($name);
  2322. public function getMetadataBag();
  2323. }
  2324. namespace Symfony\Component\HttpFoundation\Session;
  2325. interface SessionBagInterface
  2326. {
  2327. public function getName();
  2328. public function initialize(array &$array);
  2329. public function getStorageKey();
  2330. public function clear();
  2331. }
  2332. namespace Symfony\Component\HttpFoundation\Session\Attribute;
  2333. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  2334. interface AttributeBagInterface extends SessionBagInterface
  2335. {
  2336. public function has($name);
  2337. public function get($name, $default = null);
  2338. public function set($name, $value);
  2339. public function all();
  2340. public function replace(array $attributes);
  2341. public function remove($name);
  2342. }
  2343. namespace Symfony\Component\HttpFoundation\Session\Attribute;
  2344. class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable
  2345. {
  2346. private $name = 'attributes';
  2347. private $storageKey;
  2348. protected $attributes = array();
  2349. public function __construct($storageKey = '_sf2_attributes')
  2350. {
  2351. $this->storageKey = $storageKey;
  2352. }
  2353. public function getName()
  2354. {
  2355. return $this->name;
  2356. }
  2357. public function setName($name)
  2358. {
  2359. $this->name = $name;
  2360. }
  2361. public function initialize(array &$attributes)
  2362. {
  2363. $this->attributes =& $attributes;
  2364. }
  2365. public function getStorageKey()
  2366. {
  2367. return $this->storageKey;
  2368. }
  2369. public function has($name)
  2370. {
  2371. return array_key_exists($name, $this->attributes);
  2372. }
  2373. public function get($name, $default = null)
  2374. {
  2375. return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
  2376. }
  2377. public function set($name, $value)
  2378. {
  2379. $this->attributes[$name] = $value;
  2380. }
  2381. public function all()
  2382. {
  2383. return $this->attributes;
  2384. }
  2385. public function replace(array $attributes)
  2386. {
  2387. $this->attributes = array();
  2388. foreach ($attributes as $key => $value) {
  2389. $this->set($key, $value);
  2390. }
  2391. }
  2392. public function remove($name)
  2393. {
  2394. $retval = null;
  2395. if (array_key_exists($name, $this->attributes)) {
  2396. $retval = $this->attributes[$name];
  2397. unset($this->attributes[$name]);
  2398. }
  2399. return $retval;
  2400. }
  2401. public function clear()
  2402. {
  2403. $return = $this->attributes;
  2404. $this->attributes = array();
  2405. return $return;
  2406. }
  2407. public function getIterator()
  2408. {
  2409. return new \ArrayIterator($this->attributes);
  2410. }
  2411. public function count()
  2412. {
  2413. return count($this->attributes);
  2414. }
  2415. }
  2416. namespace Symfony\Component\HttpFoundation\Session\Storage;
  2417. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  2418. class MetadataBag implements SessionBagInterface
  2419. {
  2420. const CREATED = 'c';
  2421. const UPDATED = 'u';
  2422. const LIFETIME = 'l';
  2423. private $name = '__metadata';
  2424. private $storageKey;
  2425. protected $meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0);
  2426. private $lastUsed;
  2427. private $updateThreshold;
  2428. public function __construct($storageKey = '_sf2_meta', $updateThreshold = 0)
  2429. {
  2430. $this->storageKey = $storageKey;
  2431. $this->updateThreshold = $updateThreshold;
  2432. }
  2433. public function initialize(array &$array)
  2434. {
  2435. $this->meta =& $array;
  2436. if (isset($array[self::CREATED])) {
  2437. $this->lastUsed = $this->meta[self::UPDATED];
  2438. $timeStamp = time();
  2439. if ($timeStamp - $array[self::UPDATED] >= $this->updateThreshold) {
  2440. $this->meta[self::UPDATED] = $timeStamp;
  2441. }
  2442. } else {
  2443. $this->stampCreated();
  2444. }
  2445. }
  2446. public function getLifetime()
  2447. {
  2448. return $this->meta[self::LIFETIME];
  2449. }
  2450. public function stampNew($lifetime = null)
  2451. {
  2452. $this->stampCreated($lifetime);
  2453. }
  2454. public function getStorageKey()
  2455. {
  2456. return $this->storageKey;
  2457. }
  2458. public function getCreated()
  2459. {
  2460. return $this->meta[self::CREATED];
  2461. }
  2462. public function getLastUsed()
  2463. {
  2464. return $this->lastUsed;
  2465. }
  2466. public function clear()
  2467. {
  2468. }
  2469. public function getName()
  2470. {
  2471. return $this->name;
  2472. }
  2473. public function setName($name)
  2474. {
  2475. $this->name = $name;
  2476. }
  2477. private function stampCreated($lifetime = null)
  2478. {
  2479. $timeStamp = time();
  2480. $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
  2481. $this->meta[self::LIFETIME] = null === $lifetime ? ini_get('session.cookie_lifetime') : $lifetime;
  2482. }
  2483. }
  2484. namespace Symfony\Component\HttpFoundation;
  2485. class AcceptHeaderItem
  2486. {
  2487. private $value;
  2488. private $quality = 1.0;
  2489. private $index = 0;
  2490. private $attributes = array();
  2491. public function __construct($value, array $attributes = array())
  2492. {
  2493. $this->value = $value;
  2494. foreach ($attributes as $name => $value) {
  2495. $this->setAttribute($name, $value);
  2496. }
  2497. }
  2498. public static function fromString($itemValue)
  2499. {
  2500. $bits = preg_split('/\\s*(?:;*("[^"]+");*|;*(\'[^\']+\');*|;+)\\s*/', $itemValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
  2501. $value = array_shift($bits);
  2502. $attributes = array();
  2503. $lastNullAttribute = null;
  2504. foreach ($bits as $bit) {
  2505. if (($start = substr($bit, 0, 1)) === ($end = substr($bit, -1)) && ($start === '"' || $start === '\'')) {
  2506. $attributes[$lastNullAttribute] = substr($bit, 1, -1);
  2507. } elseif ('=' === $end) {
  2508. $lastNullAttribute = $bit = substr($bit, 0, -1);
  2509. $attributes[$bit] = null;
  2510. } else {
  2511. $parts = explode('=', $bit);
  2512. $attributes[$parts[0]] = isset($parts[1]) && strlen($parts[1]) > 0 ? $parts[1] : '';
  2513. }
  2514. }
  2515. return new self(($start = substr($value, 0, 1)) === ($end = substr($value, -1)) && ($start === '"' || $start === '\'') ? substr($value, 1, -1) : $value, $attributes);
  2516. }
  2517. public function __toString()
  2518. {
  2519. $string = $this->value . ($this->quality < 1 ? ';q=' . $this->quality : '');
  2520. if (count($this->attributes) > 0) {
  2521. $string .= ';' . implode(';', array_map(function ($name, $value) {
  2522. return sprintf(preg_match('/[,;=]/', $value) ? '%s="%s"' : '%s=%s', $name, $value);
  2523. }, array_keys($this->attributes), $this->attributes));
  2524. }
  2525. return $string;
  2526. }
  2527. public function setValue($value)
  2528. {
  2529. $this->value = $value;
  2530. return $this;
  2531. }
  2532. public function getValue()
  2533. {
  2534. return $this->value;
  2535. }
  2536. public function setQuality($quality)
  2537. {
  2538. $this->quality = $quality;
  2539. return $this;
  2540. }
  2541. public function getQuality()
  2542. {
  2543. return $this->quality;
  2544. }
  2545. public function setIndex($index)
  2546. {
  2547. $this->index = $index;
  2548. return $this;
  2549. }
  2550. public function getIndex()
  2551. {
  2552. return $this->index;
  2553. }
  2554. public function hasAttribute($name)
  2555. {
  2556. return isset($this->attributes[$name]);
  2557. }
  2558. public function getAttribute($name, $default = null)
  2559. {
  2560. return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
  2561. }
  2562. public function getAttributes()
  2563. {
  2564. return $this->attributes;
  2565. }
  2566. public function setAttribute($name, $value)
  2567. {
  2568. if ('q' === $name) {
  2569. $this->quality = (double) $value;
  2570. } else {
  2571. $this->attributes[$name] = (string) $value;
  2572. }
  2573. return $this;
  2574. }
  2575. }
  2576. namespace Symfony\Component\HttpFoundation;
  2577. class AcceptHeader
  2578. {
  2579. private $items = array();
  2580. private $sorted = true;
  2581. public function __construct(array $items)
  2582. {
  2583. foreach ($items as $item) {
  2584. $this->add($item);
  2585. }
  2586. }
  2587. public static function fromString($headerValue)
  2588. {
  2589. $index = 0;
  2590. return new self(array_map(function ($itemValue) use(&$index) {
  2591. $item = AcceptHeaderItem::fromString($itemValue);
  2592. $item->setIndex($index++);
  2593. return $item;
  2594. }, preg_split('/\\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
  2595. }
  2596. public function __toString()
  2597. {
  2598. return implode(',', $this->items);
  2599. }
  2600. public function has($value)
  2601. {
  2602. return isset($this->items[$value]);
  2603. }
  2604. public function get($value)
  2605. {
  2606. return isset($this->items[$value]) ? $this->items[$value] : null;
  2607. }
  2608. public function add(AcceptHeaderItem $item)
  2609. {
  2610. $this->items[$item->getValue()] = $item;
  2611. $this->sorted = false;
  2612. return $this;
  2613. }
  2614. public function all()
  2615. {
  2616. $this->sort();
  2617. return $this->items;
  2618. }
  2619. public function filter($pattern)
  2620. {
  2621. return new self(array_filter($this->items, function (AcceptHeaderItem $item) use($pattern) {
  2622. return preg_match($pattern, $item->getValue());
  2623. }));
  2624. }
  2625. public function first()
  2626. {
  2627. $this->sort();
  2628. return !empty($this->items) ? reset($this->items) : null;
  2629. }
  2630. private function sort()
  2631. {
  2632. if (!$this->sorted) {
  2633. uasort($this->items, function ($a, $b) {
  2634. $qA = $a->getQuality();
  2635. $qB = $b->getQuality();
  2636. if ($qA === $qB) {
  2637. return $a->getIndex() > $b->getIndex() ? 1 : -1;
  2638. }
  2639. return $qA > $qB ? -1 : 1;
  2640. });
  2641. $this->sorted = true;
  2642. }
  2643. }
  2644. }
  2645. namespace Symfony\Component\Debug;
  2646. use Symfony\Component\HttpFoundation\Response;
  2647. use Symfony\Component\Debug\Exception\FlattenException;
  2648. use Symfony\Component\Debug\Exception\OutOfMemoryException;
  2649. if (!defined('ENT_SUBSTITUTE')) {
  2650. define('ENT_SUBSTITUTE', 8);
  2651. }
  2652. class ExceptionHandler
  2653. {
  2654. private $debug;
  2655. private $charset;
  2656. private $handler;
  2657. private $caughtOutput = 0;
  2658. public function __construct($debug = true, $charset = 'UTF-8')
  2659. {
  2660. $this->debug = $debug;
  2661. $this->charset = $charset;
  2662. }
  2663. public static function register($debug = true)
  2664. {
  2665. $handler = new static($debug);
  2666. set_exception_handler(array($handler, 'handle'));
  2667. return $handler;
  2668. }
  2669. public function setHandler($handler)
  2670. {
  2671. if (isset($handler) && !is_callable($handler)) {
  2672. throw new \LogicException('The exception handler must be a valid PHP callable.');
  2673. }
  2674. $old = $this->handler;
  2675. $this->handler = $handler;
  2676. return $old;
  2677. }
  2678. public function handle(\Exception $exception)
  2679. {
  2680. if ($exception instanceof OutOfMemoryException) {
  2681. $this->sendPhpResponse($exception);
  2682. return;
  2683. }
  2684. $caughtOutput = 0;
  2685. $this->caughtOutput = false;
  2686. ob_start(array($this, 'catchOutput'));
  2687. try {
  2688. if (class_exists('Symfony\\Component\\HttpFoundation\\Response')) {
  2689. $response = $this->createResponse($exception);
  2690. $response->sendHeaders();
  2691. $response->sendContent();
  2692. } else {
  2693. $this->sendPhpResponse($exception);
  2694. }
  2695. } catch (\Exception $e) {
  2696. }
  2697. if (false === $this->caughtOutput) {
  2698. ob_end_clean();
  2699. }
  2700. if (isset($this->caughtOutput[0])) {
  2701. ob_start(array($this, 'cleanOutput'));
  2702. echo $this->caughtOutput;
  2703. $caughtOutput = ob_get_length();
  2704. }
  2705. $this->caughtOutput = 0;
  2706. if (!empty($this->handler)) {
  2707. try {
  2708. call_user_func($this->handler, $exception);
  2709. if ($caughtOutput) {
  2710. $this->caughtOutput = $caughtOutput;
  2711. }
  2712. } catch (\Exception $e) {
  2713. if (!$caughtOutput) {
  2714. throw $exception;
  2715. }
  2716. }
  2717. }
  2718. }
  2719. public function sendPhpResponse($exception)
  2720. {
  2721. if (!$exception instanceof FlattenException) {
  2722. $exception = FlattenException::create($exception);
  2723. }
  2724. if (!headers_sent()) {
  2725. header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
  2726. foreach ($exception->getHeaders() as $name => $value) {
  2727. header($name . ': ' . $value, false);
  2728. }
  2729. }
  2730. echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
  2731. }
  2732. public function createResponse($exception)
  2733. {
  2734. if (!$exception instanceof FlattenException) {
  2735. $exception = FlattenException::create($exception);
  2736. }
  2737. return new Response($this->decorate($this->getContent($exception), $this->getStylesheet($exception)), $exception->getStatusCode(), $exception->getHeaders());
  2738. }
  2739. public function getContent(FlattenException $exception)
  2740. {
  2741. switch ($exception->getStatusCode()) {
  2742. case 404:
  2743. $title = 'Sorry, the page you are looking for could not be found.';
  2744. break;
  2745. default:
  2746. $title = 'Whoops, looks like something went wrong.';
  2747. }
  2748. $content = '';
  2749. if ($this->debug) {
  2750. try {
  2751. $count = count($exception->getAllPrevious());
  2752. $total = $count + 1;
  2753. foreach ($exception->toArray() as $position => $e) {
  2754. $ind = $count - $position + 1;
  2755. $class = $this->abbrClass($e['class']);
  2756. $message = nl2br($e['message']);
  2757. $content .= sprintf(' <div class="block_exception clear_fix">
  2758. <h2><span>%d/%d</span> %s: %s</h2>
  2759. </div>
  2760. <div class="block">
  2761. <ol class="traces list_exception">', $ind, $total, $class, $message);
  2762. foreach ($e['trace'] as $trace) {
  2763. $content .= ' <li>';
  2764. if ($trace['function']) {
  2765. $content .= sprintf('at %s%s%s(%s)', $this->abbrClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
  2766. }
  2767. if (isset($trace['file']) && isset($trace['line'])) {
  2768. if ($linkFormat = ini_get('xdebug.file_link_format')) {
  2769. $link = str_replace(array('%f', '%l'), array($trace['file'], $trace['line']), $linkFormat);
  2770. $content .= sprintf(' in <a href="%s" title="Go to source">%s line %s</a>', $link, $trace['file'], $trace['line']);
  2771. } else {
  2772. $content .= sprintf(' in %s line %s', $trace['file'], $trace['line']);
  2773. }
  2774. }
  2775. $content .= '</li>
  2776. ';
  2777. }
  2778. $content .= ' </ol>
  2779. </div>
  2780. ';
  2781. }
  2782. } catch (\Exception $e) {
  2783. if ($this->debug) {
  2784. $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($exception), $exception->getMessage());
  2785. } else {
  2786. $title = 'Whoops, looks like something went wrong.';
  2787. }
  2788. }
  2789. }
  2790. return " <div id=\"sf-resetcontent\" class=\"sf-reset\">\n <h1>{$title}</h1>\n {$content}\n </div>";
  2791. }
  2792. public function getStylesheet(FlattenException $exception)
  2793. {
  2794. return ' .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }
  2795. .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }
  2796. .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }
  2797. .sf-reset .clear_fix { display:inline-block; }
  2798. .sf-reset * html .clear_fix { height:1%; }
  2799. .sf-reset .clear_fix { display:block; }
  2800. .sf-reset, .sf-reset .block { margin: auto }
  2801. .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
  2802. .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
  2803. .sf-reset strong { font-weight:bold; }
  2804. .sf-reset a { color:#6c6159; }
  2805. .sf-reset a img { border:none; }
  2806. .sf-reset a:hover { text-decoration:underline; }
  2807. .sf-reset em { font-style:italic; }
  2808. .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
  2809. .sf-reset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; }
  2810. .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
  2811. .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
  2812. -webkit-border-bottom-right-radius: 16px;
  2813. -webkit-border-bottom-left-radius: 16px;
  2814. -moz-border-radius-bottomright: 16px;
  2815. -moz-border-radius-bottomleft: 16px;
  2816. border-bottom-right-radius: 16px;
  2817. border-bottom-left-radius: 16px;
  2818. border-bottom:1px solid #ccc;
  2819. border-right:1px solid #ccc;
  2820. border-left:1px solid #ccc;
  2821. }
  2822. .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;
  2823. -webkit-border-top-left-radius: 16px;
  2824. -webkit-border-top-right-radius: 16px;
  2825. -moz-border-radius-topleft: 16px;
  2826. -moz-border-radius-topright: 16px;
  2827. border-top-left-radius: 16px;
  2828. border-top-right-radius: 16px;
  2829. border-top:1px solid #ccc;
  2830. border-right:1px solid #ccc;
  2831. border-left:1px solid #ccc;
  2832. overflow: hidden;
  2833. word-wrap: break-word;
  2834. }
  2835. .sf-reset li a { background:none; color:#868686; text-decoration:none; }
  2836. .sf-reset li a:hover { background:none; color:#313131; text-decoration:underline; }
  2837. .sf-reset ol { padding: 10px 0; }
  2838. .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
  2839. -webkit-border-radius: 10px;
  2840. -moz-border-radius: 10px;
  2841. border-radius: 10px;
  2842. border: 1px solid #ccc;
  2843. }';
  2844. }
  2845. private function decorate($content, $css)
  2846. {
  2847. return "<!DOCTYPE html>\n<html>\n <head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n <meta name=\"robots\" content=\"noindex,nofollow\" />\n <style>\n /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */\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;}\n\n html { background: #eee; padding: 10px }\n img { border: 0; }\n #sf-resetcontent { width:970px; margin:0 auto; }\n {$css}\n </style>\n </head>\n <body>\n {$content}\n </body>\n</html>";
  2848. }
  2849. private function abbrClass($class)
  2850. {
  2851. $parts = explode('\\', $class);
  2852. return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
  2853. }
  2854. private function formatArgs(array $args)
  2855. {
  2856. $result = array();
  2857. foreach ($args as $key => $item) {
  2858. if ('object' === $item[0]) {
  2859. $formattedValue = sprintf('<em>object</em>(%s)', $this->abbrClass($item[1]));
  2860. } elseif ('array' === $item[0]) {
  2861. $formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
  2862. } elseif ('string' === $item[0]) {
  2863. $formattedValue = sprintf('\'%s\'', htmlspecialchars($item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset));
  2864. } elseif ('null' === $item[0]) {
  2865. $formattedValue = '<em>null</em>';
  2866. } elseif ('boolean' === $item[0]) {
  2867. $formattedValue = '<em>' . strtolower(var_export($item[1], true)) . '</em>';
  2868. } elseif ('resource' === $item[0]) {
  2869. $formattedValue = '<em>resource</em>';
  2870. } else {
  2871. $formattedValue = str_replace('
  2872. ', '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), true));
  2873. }
  2874. $result[] = is_int($key) ? $formattedValue : sprintf('\'%s\' => %s', $key, $formattedValue);
  2875. }
  2876. return implode(', ', $result);
  2877. }
  2878. public function catchOutput($buffer)
  2879. {
  2880. $this->caughtOutput = $buffer;
  2881. return '';
  2882. }
  2883. public function cleanOutput($buffer)
  2884. {
  2885. if ($this->caughtOutput) {
  2886. $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtOutput);
  2887. if (isset($cleanBuffer[0])) {
  2888. $buffer = $cleanBuffer;
  2889. }
  2890. }
  2891. return $buffer;
  2892. }
  2893. }
  2894. namespace Illuminate\Support;
  2895. use ReflectionClass;
  2896. abstract class ServiceProvider
  2897. {
  2898. protected $app;
  2899. protected $defer = false;
  2900. public function __construct($app)
  2901. {
  2902. $this->app = $app;
  2903. }
  2904. public function boot()
  2905. {
  2906. }
  2907. public abstract function register();
  2908. public function package($package, $namespace = null, $path = null)
  2909. {
  2910. $namespace = $this->getPackageNamespace($package, $namespace);
  2911. $path = $path ?: $this->guessPackagePath();
  2912. $config = $path . '/config';
  2913. if ($this->app['files']->isDirectory($config)) {
  2914. $this->app['config']->package($package, $config, $namespace);
  2915. }
  2916. $lang = $path . '/lang';
  2917. if ($this->app['files']->isDirectory($lang)) {
  2918. $this->app['translator']->addNamespace($namespace, $lang);
  2919. }
  2920. $appView = $this->getAppViewPath($package);
  2921. if ($this->app['files']->isDirectory($appView)) {
  2922. $this->app['view']->addNamespace($namespace, $appView);
  2923. }
  2924. $view = $path . '/views';
  2925. if ($this->app['files']->isDirectory($view)) {
  2926. $this->app['view']->addNamespace($namespace, $view);
  2927. }
  2928. }
  2929. public function guessPackagePath()
  2930. {
  2931. $path = with(new ReflectionClass($this))->getFileName();
  2932. return realpath(dirname($path) . '/../../');
  2933. }
  2934. protected function getPackageNamespace($package, $namespace)
  2935. {
  2936. if (is_null($namespace)) {
  2937. list($vendor, $namespace) = explode('/', $package);
  2938. }
  2939. return $namespace;
  2940. }
  2941. public function commands($commands)
  2942. {
  2943. $commands = is_array($commands) ? $commands : func_get_args();
  2944. $events = $this->app['events'];
  2945. $events->listen('artisan.start', function ($artisan) use($commands) {
  2946. $artisan->resolveCommands($commands);
  2947. });
  2948. }
  2949. protected function getAppViewPath($package)
  2950. {
  2951. return $this->app['path'] . "/views/packages/{$package}";
  2952. }
  2953. public function provides()
  2954. {
  2955. return array();
  2956. }
  2957. public function when()
  2958. {
  2959. return array();
  2960. }
  2961. public function isDeferred()
  2962. {
  2963. return $this->defer;
  2964. }
  2965. }
  2966. namespace Illuminate\Exception;
  2967. use Whoops\Run;
  2968. use Whoops\Handler\PrettyPageHandler;
  2969. use Whoops\Handler\JsonResponseHandler;
  2970. use Illuminate\Support\ServiceProvider;
  2971. class ExceptionServiceProvider extends ServiceProvider
  2972. {
  2973. public function register()
  2974. {
  2975. $this->registerDisplayers();
  2976. $this->registerHandler();
  2977. }
  2978. protected function registerDisplayers()
  2979. {
  2980. $this->registerPlainDisplayer();
  2981. $this->registerDebugDisplayer();
  2982. }
  2983. protected function registerHandler()
  2984. {
  2985. $this->app['exception'] = $this->app->share(function ($app) {
  2986. return new Handler($app, $app['exception.plain'], $app['exception.debug']);
  2987. });
  2988. }
  2989. protected function registerPlainDisplayer()
  2990. {
  2991. $this->app['exception.plain'] = $this->app->share(function ($app) {
  2992. if ($app->runningInConsole()) {
  2993. return $app['exception.debug'];
  2994. } else {
  2995. return new PlainDisplayer();
  2996. }
  2997. });
  2998. }
  2999. protected function registerDebugDisplayer()
  3000. {
  3001. $this->registerWhoops();
  3002. $this->app['exception.debug'] = $this->app->share(function ($app) {
  3003. return new WhoopsDisplayer($app['whoops'], $app->runningInConsole());
  3004. });
  3005. }
  3006. protected function registerWhoops()
  3007. {
  3008. $this->registerWhoopsHandler();
  3009. $this->app['whoops'] = $this->app->share(function ($app) {
  3010. with($whoops = new Run())->allowQuit(false);
  3011. $whoops->writeToOutput(false);
  3012. return $whoops->pushHandler($app['whoops.handler']);
  3013. });
  3014. }
  3015. protected function registerWhoopsHandler()
  3016. {
  3017. if ($this->shouldReturnJson()) {
  3018. $this->app['whoops.handler'] = $this->app->share(function () {
  3019. return new JsonResponseHandler();
  3020. });
  3021. } else {
  3022. $this->registerPrettyWhoopsHandler();
  3023. }
  3024. }
  3025. protected function shouldReturnJson()
  3026. {
  3027. return $this->app->runningInConsole() || $this->requestWantsJson();
  3028. }
  3029. protected function requestWantsJson()
  3030. {
  3031. return $this->app['request']->ajax() || $this->app['request']->wantsJson();
  3032. }
  3033. protected function registerPrettyWhoopsHandler()
  3034. {
  3035. $this->app['whoops.handler'] = $this->app->share(function () {
  3036. with($handler = new PrettyPageHandler())->setEditor('sublime');
  3037. if (!is_null($path = $this->resourcePath())) {
  3038. $handler->addResourcePath($path);
  3039. }
  3040. return $handler;
  3041. });
  3042. }
  3043. public function resourcePath()
  3044. {
  3045. if (is_dir($path = $this->getResourcePath())) {
  3046. return $path;
  3047. }
  3048. }
  3049. protected function getResourcePath()
  3050. {
  3051. $base = $this->app['path.base'];
  3052. return $base . '/vendor/laravel/framework/src/Illuminate/Exception/resources';
  3053. }
  3054. }
  3055. namespace Illuminate\Routing;
  3056. use Illuminate\Support\ServiceProvider;
  3057. class RoutingServiceProvider extends ServiceProvider
  3058. {
  3059. public function register()
  3060. {
  3061. $this->registerRouter();
  3062. $this->registerUrlGenerator();
  3063. $this->registerRedirector();
  3064. }
  3065. protected function registerRouter()
  3066. {
  3067. $this->app['router'] = $this->app->share(function ($app) {
  3068. $router = new Router($app['events'], $app);
  3069. if ($app['env'] == 'testing') {
  3070. $router->disableFilters();
  3071. }
  3072. return $router;
  3073. });
  3074. }
  3075. protected function registerUrlGenerator()
  3076. {
  3077. $this->app['url'] = $this->app->share(function ($app) {
  3078. $routes = $app['router']->getRoutes();
  3079. return new UrlGenerator($routes, $app->rebinding('request', function ($app, $request) {
  3080. $app['url']->setRequest($request);
  3081. }));
  3082. });
  3083. }
  3084. protected function registerRedirector()
  3085. {
  3086. $this->app['redirect'] = $this->app->share(function ($app) {
  3087. $redirector = new Redirector($app['url']);
  3088. if (isset($app['session.store'])) {
  3089. $redirector->setSession($app['session.store']);
  3090. }
  3091. return $redirector;
  3092. });
  3093. }
  3094. }
  3095. namespace Illuminate\Events;
  3096. use Illuminate\Support\ServiceProvider;
  3097. class EventServiceProvider extends ServiceProvider
  3098. {
  3099. public function register()
  3100. {
  3101. $this->app['events'] = $this->app->share(function ($app) {
  3102. return new Dispatcher($app);
  3103. });
  3104. }
  3105. }
  3106. namespace Illuminate\Support\Facades;
  3107. use Mockery\MockInterface;
  3108. abstract class Facade
  3109. {
  3110. protected static $app;
  3111. protected static $resolvedInstance;
  3112. public static function swap($instance)
  3113. {
  3114. static::$resolvedInstance[static::getFacadeAccessor()] = $instance;
  3115. static::$app->instance(static::getFacadeAccessor(), $instance);
  3116. }
  3117. public static function shouldReceive()
  3118. {
  3119. $name = static::getFacadeAccessor();
  3120. if (static::isMock()) {
  3121. $mock = static::$resolvedInstance[$name];
  3122. } else {
  3123. $mock = static::createFreshMockInstance($name);
  3124. }
  3125. return call_user_func_array(array($mock, 'shouldReceive'), func_get_args());
  3126. }
  3127. protected static function createFreshMockInstance($name)
  3128. {
  3129. static::$resolvedInstance[$name] = $mock = static::createMockByName($name);
  3130. if (isset(static::$app)) {
  3131. static::$app->instance($name, $mock);
  3132. }
  3133. return $mock;
  3134. }
  3135. protected static function createMockByName($name)
  3136. {
  3137. $class = static::getMockableClass($name);
  3138. return $class ? \Mockery::mock($class) : \Mockery::mock();
  3139. }
  3140. protected static function isMock()
  3141. {
  3142. $name = static::getFacadeAccessor();
  3143. return isset(static::$resolvedInstance[$name]) && static::$resolvedInstance[$name] instanceof MockInterface;
  3144. }
  3145. protected static function getMockableClass()
  3146. {
  3147. if ($root = static::getFacadeRoot()) {
  3148. return get_class($root);
  3149. }
  3150. }
  3151. public static function getFacadeRoot()
  3152. {
  3153. return static::resolveFacadeInstance(static::getFacadeAccessor());
  3154. }
  3155. protected static function getFacadeAccessor()
  3156. {
  3157. throw new \RuntimeException('Facade does not implement getFacadeAccessor method.');
  3158. }
  3159. protected static function resolveFacadeInstance($name)
  3160. {
  3161. if (is_object($name)) {
  3162. return $name;
  3163. }
  3164. if (isset(static::$resolvedInstance[$name])) {
  3165. return static::$resolvedInstance[$name];
  3166. }
  3167. return static::$resolvedInstance[$name] = static::$app[$name];
  3168. }
  3169. public static function clearResolvedInstance($name)
  3170. {
  3171. unset(static::$resolvedInstance[$name]);
  3172. }
  3173. public static function clearResolvedInstances()
  3174. {
  3175. static::$resolvedInstance = array();
  3176. }
  3177. public static function getFacadeApplication()
  3178. {
  3179. return static::$app;
  3180. }
  3181. public static function setFacadeApplication($app)
  3182. {
  3183. static::$app = $app;
  3184. }
  3185. public static function __callStatic($method, $args)
  3186. {
  3187. $instance = static::getFacadeRoot();
  3188. switch (count($args)) {
  3189. case 0:
  3190. return $instance->{$method}();
  3191. case 1:
  3192. return $instance->{$method}($args[0]);
  3193. case 2:
  3194. return $instance->{$method}($args[0], $args[1]);
  3195. case 3:
  3196. return $instance->{$method}($args[0], $args[1], $args[2]);
  3197. case 4:
  3198. return $instance->{$method}($args[0], $args[1], $args[2], $args[3]);
  3199. default:
  3200. return call_user_func_array(array($instance, $method), $args);
  3201. }
  3202. }
  3203. }
  3204. namespace Illuminate\Support;
  3205. use Illuminate\Support\Traits\MacroableTrait;
  3206. class Str
  3207. {
  3208. use MacroableTrait;
  3209. public static function ascii($value)
  3210. {
  3211. return \Patchwork\Utf8::toAscii($value);
  3212. }
  3213. public static function camel($value)
  3214. {
  3215. return lcfirst(static::studly($value));
  3216. }
  3217. public static function contains($haystack, $needles)
  3218. {
  3219. foreach ((array) $needles as $needle) {
  3220. if ($needle != '' && strpos($haystack, $needle) !== false) {
  3221. return true;
  3222. }
  3223. }
  3224. return false;
  3225. }
  3226. public static function endsWith($haystack, $needles)
  3227. {
  3228. foreach ((array) $needles as $needle) {
  3229. if ($needle == substr($haystack, -strlen($needle))) {
  3230. return true;
  3231. }
  3232. }
  3233. return false;
  3234. }
  3235. public static function finish($value, $cap)
  3236. {
  3237. $quoted = preg_quote($cap, '/');
  3238. return preg_replace('/(?:' . $quoted . ')+$/', '', $value) . $cap;
  3239. }
  3240. public static function is($pattern, $value)
  3241. {
  3242. if ($pattern == $value) {
  3243. return true;
  3244. }
  3245. $pattern = preg_quote($pattern, '#');
  3246. $pattern = str_replace('\\*', '.*', $pattern) . '\\z';
  3247. return (bool) preg_match('#^' . $pattern . '#', $value);
  3248. }
  3249. public static function length($value)
  3250. {
  3251. return mb_strlen($value);
  3252. }
  3253. public static function limit($value, $limit = 100, $end = '...')
  3254. {
  3255. if (mb_strlen($value) <= $limit) {
  3256. return $value;
  3257. }
  3258. return rtrim(mb_substr($value, 0, $limit, 'UTF-8')) . $end;
  3259. }
  3260. public static function lower($value)
  3261. {
  3262. return mb_strtolower($value);
  3263. }
  3264. public static function words($value, $words = 100, $end = '...')
  3265. {
  3266. preg_match('/^\\s*+(?:\\S++\\s*+){1,' . $words . '}/u', $value, $matches);
  3267. if (!isset($matches[0])) {
  3268. return $value;
  3269. }
  3270. if (strlen($value) == strlen($matches[0])) {
  3271. return $value;
  3272. }
  3273. return rtrim($matches[0]) . $end;
  3274. }
  3275. public static function parseCallback($callback, $default)
  3276. {
  3277. return static::contains($callback, '@') ? explode('@', $callback, 2) : array($callback, $default);
  3278. }
  3279. public static function plural($value, $count = 2)
  3280. {
  3281. return Pluralizer::plural($value, $count);
  3282. }
  3283. public static function random($length = 16)
  3284. {
  3285. if (function_exists('openssl_random_pseudo_bytes')) {
  3286. $bytes = openssl_random_pseudo_bytes($length * 2);
  3287. if ($bytes === false) {
  3288. throw new \RuntimeException('Unable to generate random string.');
  3289. }
  3290. return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
  3291. }
  3292. return static::quickRandom($length);
  3293. }
  3294. public static function quickRandom($length = 16)
  3295. {
  3296. $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  3297. return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
  3298. }
  3299. public static function upper($value)
  3300. {
  3301. return mb_strtoupper($value);
  3302. }
  3303. public static function title($value)
  3304. {
  3305. return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
  3306. }
  3307. public static function singular($value)
  3308. {
  3309. return Pluralizer::singular($value);
  3310. }
  3311. public static function slug($title, $separator = '-')
  3312. {
  3313. $title = static::ascii($title);
  3314. $flip = $separator == '-' ? '_' : '-';
  3315. $title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title);
  3316. $title = preg_replace('![^' . preg_quote($separator) . '\\pL\\pN\\s]+!u', '', mb_strtolower($title));
  3317. $title = preg_replace('![' . preg_quote($separator) . '\\s]+!u', $separator, $title);
  3318. return trim($title, $separator);
  3319. }
  3320. public static function snake($value, $delimiter = '_')
  3321. {
  3322. $replace = '$1' . $delimiter . '$2';
  3323. return ctype_lower($value) ? $value : strtolower(preg_replace('/(.)([A-Z])/', $replace, $value));
  3324. }
  3325. public static function startsWith($haystack, $needles)
  3326. {
  3327. foreach ((array) $needles as $needle) {
  3328. if ($needle != '' && strpos($haystack, $needle) === 0) {
  3329. return true;
  3330. }
  3331. }
  3332. return false;
  3333. }
  3334. public static function studly($value)
  3335. {
  3336. $value = ucwords(str_replace(array('-', '_'), ' ', $value));
  3337. return str_replace(' ', '', $value);
  3338. }
  3339. }
  3340. namespace Symfony\Component\Debug;
  3341. use Psr\Log\LogLevel;
  3342. use Psr\Log\LoggerInterface;
  3343. use Symfony\Component\Debug\Exception\ContextErrorException;
  3344. use Symfony\Component\Debug\Exception\FatalErrorException;
  3345. use Symfony\Component\Debug\Exception\OutOfMemoryException;
  3346. use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
  3347. use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
  3348. use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
  3349. use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
  3350. class ErrorHandler
  3351. {
  3352. const TYPE_DEPRECATION = -100;
  3353. 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 Error');
  3354. private $level;
  3355. private $reservedMemory;
  3356. private $displayErrors;
  3357. private static $loggers = array();
  3358. private static $stackedErrors = array();
  3359. private static $stackedErrorLevels = array();
  3360. public static function register($level = null, $displayErrors = true)
  3361. {
  3362. $handler = new static();
  3363. $handler->setLevel($level);
  3364. $handler->setDisplayErrors($displayErrors);
  3365. ini_set('display_errors', 0);
  3366. set_error_handler(array($handler, 'handle'));
  3367. register_shutdown_function(array($handler, 'handleFatal'));
  3368. $handler->reservedMemory = str_repeat('x', 10240);
  3369. return $handler;
  3370. }
  3371. public function setLevel($level)
  3372. {
  3373. $this->level = null === $level ? error_reporting() : $level;
  3374. }
  3375. public function setDisplayErrors($displayErrors)
  3376. {
  3377. $this->displayErrors = $displayErrors;
  3378. }
  3379. public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
  3380. {
  3381. self::$loggers[$channel] = $logger;
  3382. }
  3383. public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
  3384. {
  3385. if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
  3386. if (isset(self::$loggers['deprecation'])) {
  3387. if (self::$stackedErrorLevels) {
  3388. self::$stackedErrors[] = func_get_args();
  3389. } else {
  3390. if (version_compare(PHP_VERSION, '5.4', '<')) {
  3391. $stack = array_map(function ($row) {
  3392. unset($row['args']);
  3393. return $row;
  3394. }, array_slice(debug_backtrace(false), 0, 10));
  3395. } else {
  3396. $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
  3397. }
  3398. self::$loggers['deprecation']->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack));
  3399. }
  3400. return true;
  3401. }
  3402. } elseif ($this->displayErrors && error_reporting() & $level && $this->level & $level) {
  3403. if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && is_array($context)) {
  3404. $c = $context;
  3405. unset($c['GLOBALS'], $context);
  3406. $context = $c;
  3407. }
  3408. $exception = sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line);
  3409. if ($context && class_exists('Symfony\\Component\\Debug\\Exception\\ContextErrorException')) {
  3410. $exception = new ContextErrorException($exception, 0, $level, $file, $line, $context);
  3411. } else {
  3412. $exception = new \ErrorException($exception, 0, $level, $file, $line);
  3413. }
  3414. if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
  3415. $exception->errorHandlerCanary = new ErrorHandlerCanary();
  3416. }
  3417. throw $exception;
  3418. }
  3419. if (isset(self::$loggers['scream']) && !(error_reporting() & $level)) {
  3420. if (self::$stackedErrorLevels) {
  3421. self::$stackedErrors[] = func_get_args();
  3422. } else {
  3423. switch ($level) {
  3424. case E_USER_ERROR:
  3425. case E_RECOVERABLE_ERROR:
  3426. $logLevel = LogLevel::ERROR;
  3427. break;
  3428. case E_WARNING:
  3429. case E_USER_WARNING:
  3430. $logLevel = LogLevel::WARNING;
  3431. break;
  3432. default:
  3433. $logLevel = LogLevel::NOTICE;
  3434. break;
  3435. }
  3436. self::$loggers['scream']->log($logLevel, $message, array('type' => $level, 'file' => $file, 'line' => $line, 'scream' => error_reporting()));
  3437. }
  3438. }
  3439. return false;
  3440. }
  3441. public static function stackErrors()
  3442. {
  3443. self::$stackedErrorLevels[] = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
  3444. }
  3445. public static function unstackErrors()
  3446. {
  3447. $level = array_pop(self::$stackedErrorLevels);
  3448. if (null !== $level) {
  3449. $e = error_reporting($level);
  3450. if ($e !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) {
  3451. error_reporting($e);
  3452. }
  3453. }
  3454. if (empty(self::$stackedErrorLevels)) {
  3455. $errors = self::$stackedErrors;
  3456. self::$stackedErrors = array();
  3457. $errorHandler = set_error_handler('var_dump');
  3458. restore_error_handler();
  3459. if ($errorHandler) {
  3460. foreach ($errors as $e) {
  3461. call_user_func_array($errorHandler, $e);
  3462. }
  3463. }
  3464. }
  3465. }
  3466. public function handleFatal()
  3467. {
  3468. $this->reservedMemory = '';
  3469. gc_collect_cycles();
  3470. $error = error_get_last();
  3471. $exceptionHandler = set_exception_handler('var_dump');
  3472. restore_exception_handler();
  3473. try {
  3474. while (self::$stackedErrorLevels) {
  3475. static::unstackErrors();
  3476. }
  3477. } catch (\Exception $exception) {
  3478. if ($exceptionHandler) {
  3479. call_user_func($exceptionHandler, $exception);
  3480. return;
  3481. }
  3482. if ($this->displayErrors) {
  3483. ini_set('display_errors', 1);
  3484. }
  3485. throw $exception;
  3486. }
  3487. if (!$error || !$this->level || !($error['type'] & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_PARSE))) {
  3488. return;
  3489. }
  3490. if (isset(self::$loggers['emergency'])) {
  3491. $fatal = array('type' => $error['type'], 'file' => $error['file'], 'line' => $error['line']);
  3492. self::$loggers['emergency']->emergency($error['message'], $fatal);
  3493. }
  3494. if ($this->displayErrors && $exceptionHandler) {
  3495. $this->handleFatalError($exceptionHandler, $error);
  3496. }
  3497. }
  3498. protected function getFatalErrorHandlers()
  3499. {
  3500. return array(new UndefinedFunctionFatalErrorHandler(), new UndefinedMethodFatalErrorHandler(), new ClassNotFoundFatalErrorHandler());
  3501. }
  3502. private function handleFatalError($exceptionHandler, array $error)
  3503. {
  3504. set_error_handler('var_dump', 0);
  3505. ini_set('display_errors', 1);
  3506. $level = isset($this->levels[$error['type']]) ? $this->levels[$error['type']] : $error['type'];
  3507. $message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']);
  3508. if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
  3509. $exception = new OutOfMemoryException($message, 0, $error['type'], $error['file'], $error['line'], 3, false);
  3510. } else {
  3511. $exception = new FatalErrorException($message, 0, $error['type'], $error['file'], $error['line'], 3, true);
  3512. foreach ($this->getFatalErrorHandlers() as $handler) {
  3513. if ($e = $handler->handleError($error, $exception)) {
  3514. $exception = $e;
  3515. break;
  3516. }
  3517. }
  3518. }
  3519. try {
  3520. call_user_func($exceptionHandler, $exception);
  3521. } catch (\Exception $e) {
  3522. throw $exception;
  3523. }
  3524. }
  3525. }
  3526. class ErrorHandlerCanary
  3527. {
  3528. private static $displayErrors = null;
  3529. public function __construct()
  3530. {
  3531. if (null === self::$displayErrors) {
  3532. self::$displayErrors = ini_set('display_errors', 1);
  3533. }
  3534. }
  3535. public function __destruct()
  3536. {
  3537. if (null !== self::$displayErrors) {
  3538. ini_set('display_errors', self::$displayErrors);
  3539. self::$displayErrors = null;
  3540. }
  3541. }
  3542. }
  3543. namespace Symfony\Component\HttpKernel\Debug;
  3544. use Symfony\Component\Debug\ErrorHandler as DebugErrorHandler;
  3545. class ErrorHandler extends DebugErrorHandler
  3546. {
  3547. }
  3548. namespace Illuminate\Config;
  3549. use Closure;
  3550. use ArrayAccess;
  3551. use Illuminate\Support\NamespacedItemResolver;
  3552. class Repository extends NamespacedItemResolver implements ArrayAccess
  3553. {
  3554. protected $loader;
  3555. protected $environment;
  3556. protected $items = array();
  3557. protected $packages = array();
  3558. protected $afterLoad = array();
  3559. public function __construct(LoaderInterface $loader, $environment)
  3560. {
  3561. $this->loader = $loader;
  3562. $this->environment = $environment;
  3563. }
  3564. public function has($key)
  3565. {
  3566. $default = microtime(true);
  3567. return $this->get($key, $default) !== $default;
  3568. }
  3569. public function hasGroup($key)
  3570. {
  3571. list($namespace, $group, $item) = $this->parseKey($key);
  3572. return $this->loader->exists($group, $namespace);
  3573. }
  3574. public function get($key, $default = null)
  3575. {
  3576. list($namespace, $group, $item) = $this->parseKey($key);
  3577. $collection = $this->getCollection($group, $namespace);
  3578. $this->load($group, $namespace, $collection);
  3579. return array_get($this->items[$collection], $item, $default);
  3580. }
  3581. public function set($key, $value)
  3582. {
  3583. list($namespace, $group, $item) = $this->parseKey($key);
  3584. $collection = $this->getCollection($group, $namespace);
  3585. $this->load($group, $namespace, $collection);
  3586. if (is_null($item)) {
  3587. $this->items[$collection] = $value;
  3588. } else {
  3589. array_set($this->items[$collection], $item, $value);
  3590. }
  3591. }
  3592. protected function load($group, $namespace, $collection)
  3593. {
  3594. $env = $this->environment;
  3595. if (isset($this->items[$collection])) {
  3596. return;
  3597. }
  3598. $items = $this->loader->load($env, $group, $namespace);
  3599. if (isset($this->afterLoad[$namespace])) {
  3600. $items = $this->callAfterLoad($namespace, $group, $items);
  3601. }
  3602. $this->items[$collection] = $items;
  3603. }
  3604. protected function callAfterLoad($namespace, $group, $items)
  3605. {
  3606. $callback = $this->afterLoad[$namespace];
  3607. return call_user_func($callback, $this, $group, $items);
  3608. }
  3609. protected function parseNamespacedSegments($key)
  3610. {
  3611. list($namespace, $item) = explode('::', $key);
  3612. if (in_array($namespace, $this->packages)) {
  3613. return $this->parsePackageSegments($key, $namespace, $item);
  3614. }
  3615. return parent::parseNamespacedSegments($key);
  3616. }
  3617. protected function parsePackageSegments($key, $namespace, $item)
  3618. {
  3619. $itemSegments = explode('.', $item);
  3620. if (!$this->loader->exists($itemSegments[0], $namespace)) {
  3621. return array($namespace, 'config', $item);
  3622. }
  3623. return parent::parseNamespacedSegments($key);
  3624. }
  3625. public function package($package, $hint, $namespace = null)
  3626. {
  3627. $namespace = $this->getPackageNamespace($package, $namespace);
  3628. $this->packages[] = $namespace;
  3629. $this->addNamespace($namespace, $hint);
  3630. $this->afterLoading($namespace, function ($me, $group, $items) use($package) {
  3631. $env = $me->getEnvironment();
  3632. $loader = $me->getLoader();
  3633. return $loader->cascadePackage($env, $package, $group, $items);
  3634. });
  3635. }
  3636. protected function getPackageNamespace($package, $namespace)
  3637. {
  3638. if (is_null($namespace)) {
  3639. list($vendor, $namespace) = explode('/', $package);
  3640. }
  3641. return $namespace;
  3642. }
  3643. public function afterLoading($namespace, Closure $callback)
  3644. {
  3645. $this->afterLoad[$namespace] = $callback;
  3646. }
  3647. protected function getCollection($group, $namespace = null)
  3648. {
  3649. $namespace = $namespace ?: '*';
  3650. return $namespace . '::' . $group;
  3651. }
  3652. public function addNamespace($namespace, $hint)
  3653. {
  3654. $this->loader->addNamespace($namespace, $hint);
  3655. }
  3656. public function getNamespaces()
  3657. {
  3658. return $this->loader->getNamespaces();
  3659. }
  3660. public function getLoader()
  3661. {
  3662. return $this->loader;
  3663. }
  3664. public function setLoader(LoaderInterface $loader)
  3665. {
  3666. $this->loader = $loader;
  3667. }
  3668. public function getEnvironment()
  3669. {
  3670. return $this->environment;
  3671. }
  3672. public function getAfterLoadCallbacks()
  3673. {
  3674. return $this->afterLoad;
  3675. }
  3676. public function getItems()
  3677. {
  3678. return $this->items;
  3679. }
  3680. public function offsetExists($key)
  3681. {
  3682. return $this->has($key);
  3683. }
  3684. public function offsetGet($key)
  3685. {
  3686. return $this->get($key);
  3687. }
  3688. public function offsetSet($key, $value)
  3689. {
  3690. $this->set($key, $value);
  3691. }
  3692. public function offsetUnset($key)
  3693. {
  3694. $this->set($key, null);
  3695. }
  3696. }
  3697. namespace Illuminate\Support;
  3698. class NamespacedItemResolver
  3699. {
  3700. protected $parsed = array();
  3701. public function parseKey($key)
  3702. {
  3703. if (isset($this->parsed[$key])) {
  3704. return $this->parsed[$key];
  3705. }
  3706. $segments = explode('.', $key);
  3707. if (strpos($key, '::') === false) {
  3708. $parsed = $this->parseBasicSegments($segments);
  3709. } else {
  3710. $parsed = $this->parseNamespacedSegments($key);
  3711. }
  3712. return $this->parsed[$key] = $parsed;
  3713. }
  3714. protected function parseBasicSegments(array $segments)
  3715. {
  3716. $group = $segments[0];
  3717. if (count($segments) == 1) {
  3718. return array(null, $group, null);
  3719. } else {
  3720. $item = implode('.', array_slice($segments, 1));
  3721. return array(null, $group, $item);
  3722. }
  3723. }
  3724. protected function parseNamespacedSegments($key)
  3725. {
  3726. list($namespace, $item) = explode('::', $key);
  3727. $itemSegments = explode('.', $item);
  3728. $groupAndItem = array_slice($this->parseBasicSegments($itemSegments), 1);
  3729. return array_merge(array($namespace), $groupAndItem);
  3730. }
  3731. public function setParsedKey($key, $parsed)
  3732. {
  3733. $this->parsed[$key] = $parsed;
  3734. }
  3735. }
  3736. namespace Illuminate\Config;
  3737. use Illuminate\Filesystem\Filesystem;
  3738. class FileLoader implements LoaderInterface
  3739. {
  3740. protected $files;
  3741. protected $defaultPath;
  3742. protected $hints = array();
  3743. protected $exists = array();
  3744. public function __construct(Filesystem $files, $defaultPath)
  3745. {
  3746. $this->files = $files;
  3747. $this->defaultPath = $defaultPath;
  3748. }
  3749. public function load($environment, $group, $namespace = null)
  3750. {
  3751. $items = array();
  3752. $path = $this->getPath($namespace);
  3753. if (is_null($path)) {
  3754. return $items;
  3755. }
  3756. $file = "{$path}/{$group}.php";
  3757. if ($this->files->exists($file)) {
  3758. $items = $this->files->getRequire($file);
  3759. }
  3760. $file = "{$path}/{$environment}/{$group}.php";
  3761. if ($this->files->exists($file)) {
  3762. $items = $this->mergeEnvironment($items, $file);
  3763. }
  3764. return $items;
  3765. }
  3766. protected function mergeEnvironment(array $items, $file)
  3767. {
  3768. return array_replace_recursive($items, $this->files->getRequire($file));
  3769. }
  3770. public function exists($group, $namespace = null)
  3771. {
  3772. $key = $group . $namespace;
  3773. if (isset($this->exists[$key])) {
  3774. return $this->exists[$key];
  3775. }
  3776. $path = $this->getPath($namespace);
  3777. if (is_null($path)) {
  3778. return $this->exists[$key] = false;
  3779. }
  3780. $file = "{$path}/{$group}.php";
  3781. $exists = $this->files->exists($file);
  3782. return $this->exists[$key] = $exists;
  3783. }
  3784. public function cascadePackage($env, $package, $group, $items)
  3785. {
  3786. $file = "packages/{$package}/{$group}.php";
  3787. if ($this->files->exists($path = $this->defaultPath . '/' . $file)) {
  3788. $items = array_merge($items, $this->getRequire($path));
  3789. }
  3790. $path = $this->getPackagePath($env, $package, $group);
  3791. if ($this->files->exists($path)) {
  3792. $items = array_merge($items, $this->getRequire($path));
  3793. }
  3794. return $items;
  3795. }
  3796. protected function getPackagePath($env, $package, $group)
  3797. {
  3798. $file = "packages/{$package}/{$env}/{$group}.php";
  3799. return $this->defaultPath . '/' . $file;
  3800. }
  3801. protected function getPath($namespace)
  3802. {
  3803. if (is_null($namespace)) {
  3804. return $this->defaultPath;
  3805. } elseif (isset($this->hints[$namespace])) {
  3806. return $this->hints[$namespace];
  3807. }
  3808. }
  3809. public function addNamespace($namespace, $hint)
  3810. {
  3811. $this->hints[$namespace] = $hint;
  3812. }
  3813. public function getNamespaces()
  3814. {
  3815. return $this->hints;
  3816. }
  3817. protected function getRequire($path)
  3818. {
  3819. return $this->files->getRequire($path);
  3820. }
  3821. public function getFilesystem()
  3822. {
  3823. return $this->files;
  3824. }
  3825. }
  3826. namespace Illuminate\Config;
  3827. interface LoaderInterface
  3828. {
  3829. public function load($environment, $group, $namespace = null);
  3830. public function exists($group, $namespace = null);
  3831. public function addNamespace($namespace, $hint);
  3832. public function getNamespaces();
  3833. public function cascadePackage($environment, $package, $group, $items);
  3834. }
  3835. namespace Illuminate\Config;
  3836. interface EnvironmentVariablesLoaderInterface
  3837. {
  3838. public function load($environment = null);
  3839. }
  3840. namespace Illuminate\Config;
  3841. use Illuminate\Filesystem\Filesystem;
  3842. class FileEnvironmentVariablesLoader implements EnvironmentVariablesLoaderInterface
  3843. {
  3844. protected $files;
  3845. protected $path;
  3846. public function __construct(Filesystem $files, $path = null)
  3847. {
  3848. $this->files = $files;
  3849. $this->path = $path ?: base_path();
  3850. }
  3851. public function load($environment = null)
  3852. {
  3853. if ($environment == 'production') {
  3854. $environment = null;
  3855. }
  3856. if (!$this->files->exists($path = $this->getFile($environment))) {
  3857. return array();
  3858. } else {
  3859. return $this->files->getRequire($path);
  3860. }
  3861. }
  3862. protected function getFile($environment)
  3863. {
  3864. if ($environment) {
  3865. return $this->path . '/.env.' . $environment . '.php';
  3866. } else {
  3867. return $this->path . '/.env.php';
  3868. }
  3869. }
  3870. }
  3871. namespace Illuminate\Config;
  3872. class EnvironmentVariables
  3873. {
  3874. protected $loader;
  3875. public function __construct(EnvironmentVariablesLoaderInterface $loader)
  3876. {
  3877. $this->loader = $loader;
  3878. }
  3879. public function load($environment = null)
  3880. {
  3881. foreach ($this->loader->load($environment) as $key => $value) {
  3882. $_ENV[$key] = $value;
  3883. $_SERVER[$key] = $value;
  3884. putenv("{$key}={$value}");
  3885. }
  3886. }
  3887. }
  3888. namespace Illuminate\Filesystem;
  3889. use FilesystemIterator;
  3890. use Symfony\Component\Finder\Finder;
  3891. class FileNotFoundException extends \Exception
  3892. {
  3893. }
  3894. class Filesystem
  3895. {
  3896. public function exists($path)
  3897. {
  3898. return file_exists($path);
  3899. }
  3900. public function get($path)
  3901. {
  3902. if ($this->isFile($path)) {
  3903. return file_get_contents($path);
  3904. }
  3905. throw new FileNotFoundException("File does not exist at path {$path}");
  3906. }
  3907. public function getRequire($path)
  3908. {
  3909. if ($this->isFile($path)) {
  3910. return require $path;
  3911. }
  3912. throw new FileNotFoundException("File does not exist at path {$path}");
  3913. }
  3914. public function requireOnce($file)
  3915. {
  3916. require_once $file;
  3917. }
  3918. public function put($path, $contents)
  3919. {
  3920. return file_put_contents($path, $contents);
  3921. }
  3922. public function prepend($path, $data)
  3923. {
  3924. if ($this->exists($path)) {
  3925. return $this->put($path, $data . $this->get($path));
  3926. } else {
  3927. return $this->put($path, $data);
  3928. }
  3929. }
  3930. public function append($path, $data)
  3931. {
  3932. return file_put_contents($path, $data, FILE_APPEND);
  3933. }
  3934. public function delete($paths)
  3935. {
  3936. $paths = is_array($paths) ? $paths : func_get_args();
  3937. $success = true;
  3938. foreach ($paths as $path) {
  3939. if (!@unlink($path)) {
  3940. $success = false;
  3941. }
  3942. }
  3943. return $success;
  3944. }
  3945. public function move($path, $target)
  3946. {
  3947. return rename($path, $target);
  3948. }
  3949. public function copy($path, $target)
  3950. {
  3951. return copy($path, $target);
  3952. }
  3953. public function extension($path)
  3954. {
  3955. return pathinfo($path, PATHINFO_EXTENSION);
  3956. }
  3957. public function type($path)
  3958. {
  3959. return filetype($path);
  3960. }
  3961. public function size($path)
  3962. {
  3963. return filesize($path);
  3964. }
  3965. public function lastModified($path)
  3966. {
  3967. return filemtime($path);
  3968. }
  3969. public function isDirectory($directory)
  3970. {
  3971. return is_dir($directory);
  3972. }
  3973. public function isWritable($path)
  3974. {
  3975. return is_writable($path);
  3976. }
  3977. public function isFile($file)
  3978. {
  3979. return is_file($file);
  3980. }
  3981. public function glob($pattern, $flags = 0)
  3982. {
  3983. return glob($pattern, $flags);
  3984. }
  3985. public function files($directory)
  3986. {
  3987. $glob = glob($directory . '/*');
  3988. if ($glob === false) {
  3989. return array();
  3990. }
  3991. return array_filter($glob, function ($file) {
  3992. return filetype($file) == 'file';
  3993. });
  3994. }
  3995. public function allFiles($directory)
  3996. {
  3997. return iterator_to_array(Finder::create()->files()->in($directory), false);
  3998. }
  3999. public function directories($directory)
  4000. {
  4001. $directories = array();
  4002. foreach (Finder::create()->in($directory)->directories()->depth(0) as $dir) {
  4003. $directories[] = $dir->getPathname();
  4004. }
  4005. return $directories;
  4006. }
  4007. public function makeDirectory($path, $mode = 493, $recursive = false, $force = false)
  4008. {
  4009. if ($force) {
  4010. return @mkdir($path, $mode, $recursive);
  4011. } else {
  4012. return mkdir($path, $mode, $recursive);
  4013. }
  4014. }
  4015. public function copyDirectory($directory, $destination, $options = null)
  4016. {
  4017. if (!$this->isDirectory($directory)) {
  4018. return false;
  4019. }
  4020. $options = $options ?: FilesystemIterator::SKIP_DOTS;
  4021. if (!$this->isDirectory($destination)) {
  4022. $this->makeDirectory($destination, 511, true);
  4023. }
  4024. $items = new FilesystemIterator($directory, $options);
  4025. foreach ($items as $item) {
  4026. $target = $destination . '/' . $item->getBasename();
  4027. if ($item->isDir()) {
  4028. $path = $item->getPathname();
  4029. if (!$this->copyDirectory($path, $target, $options)) {
  4030. return false;
  4031. }
  4032. } else {
  4033. if (!$this->copy($item->getPathname(), $target)) {
  4034. return false;
  4035. }
  4036. }
  4037. }
  4038. return true;
  4039. }
  4040. public function deleteDirectory($directory, $preserve = false)
  4041. {
  4042. if (!$this->isDirectory($directory)) {
  4043. return false;
  4044. }
  4045. $items = new FilesystemIterator($directory);
  4046. foreach ($items as $item) {
  4047. if ($item->isDir()) {
  4048. $this->deleteDirectory($item->getPathname());
  4049. } else {
  4050. $this->delete($item->getPathname());
  4051. }
  4052. }
  4053. if (!$preserve) {
  4054. @rmdir($directory);
  4055. }
  4056. return true;
  4057. }
  4058. public function cleanDirectory($directory)
  4059. {
  4060. return $this->deleteDirectory($directory, true);
  4061. }
  4062. }
  4063. namespace Illuminate\Foundation;
  4064. class AliasLoader
  4065. {
  4066. protected $aliases;
  4067. protected $registered = false;
  4068. protected static $instance;
  4069. public function __construct(array $aliases = array())
  4070. {
  4071. $this->aliases = $aliases;
  4072. }
  4073. public static function getInstance(array $aliases = array())
  4074. {
  4075. if (is_null(static::$instance)) {
  4076. static::$instance = new static($aliases);
  4077. }
  4078. $aliases = array_merge(static::$instance->getAliases(), $aliases);
  4079. static::$instance->setAliases($aliases);
  4080. return static::$instance;
  4081. }
  4082. public function load($alias)
  4083. {
  4084. if (isset($this->aliases[$alias])) {
  4085. return class_alias($this->aliases[$alias], $alias);
  4086. }
  4087. }
  4088. public function alias($class, $alias)
  4089. {
  4090. $this->aliases[$class] = $alias;
  4091. }
  4092. public function register()
  4093. {
  4094. if (!$this->registered) {
  4095. $this->prependToLoaderStack();
  4096. $this->registered = true;
  4097. }
  4098. }
  4099. protected function prependToLoaderStack()
  4100. {
  4101. spl_autoload_register(array($this, 'load'), true, true);
  4102. }
  4103. public function getAliases()
  4104. {
  4105. return $this->aliases;
  4106. }
  4107. public function setAliases(array $aliases)
  4108. {
  4109. $this->aliases = $aliases;
  4110. }
  4111. public function isRegistered()
  4112. {
  4113. return $this->registered;
  4114. }
  4115. public function setRegistered($value)
  4116. {
  4117. $this->registered = $value;
  4118. }
  4119. public static function setInstance($loader)
  4120. {
  4121. static::$instance = $loader;
  4122. }
  4123. }
  4124. namespace Illuminate\Foundation;
  4125. use Illuminate\Filesystem\Filesystem;
  4126. class ProviderRepository
  4127. {
  4128. protected $files;
  4129. protected $manifestPath;
  4130. protected $default = array('when' => array());
  4131. public function __construct(Filesystem $files, $manifestPath)
  4132. {
  4133. $this->files = $files;
  4134. $this->manifestPath = $manifestPath;
  4135. }
  4136. public function load(Application $app, array $providers)
  4137. {
  4138. $manifest = $this->loadManifest();
  4139. if ($this->shouldRecompile($manifest, $providers)) {
  4140. $manifest = $this->compileManifest($app, $providers);
  4141. }
  4142. if ($app->runningInConsole()) {
  4143. $manifest['eager'] = $manifest['providers'];
  4144. }
  4145. foreach ($manifest['when'] as $provider => $events) {
  4146. $this->registerLoadEvents($app, $provider, $events);
  4147. }
  4148. foreach ($manifest['eager'] as $provider) {
  4149. $app->register($this->createProvider($app, $provider));
  4150. }
  4151. $app->setDeferredServices($manifest['deferred']);
  4152. }
  4153. protected function registerLoadEvents(Application $app, $provider, array $events)
  4154. {
  4155. if (count($events) < 1) {
  4156. return;
  4157. }
  4158. $app->make('events')->listen($events, function () use($app, $provider) {
  4159. $app->register($provider);
  4160. });
  4161. }
  4162. protected function compileManifest(Application $app, $providers)
  4163. {
  4164. $manifest = $this->freshManifest($providers);
  4165. foreach ($providers as $provider) {
  4166. $instance = $this->createProvider($app, $provider);
  4167. if ($instance->isDeferred()) {
  4168. foreach ($instance->provides() as $service) {
  4169. $manifest['deferred'][$service] = $provider;
  4170. }
  4171. $manifest['when'][$provider] = $instance->when();
  4172. } else {
  4173. $manifest['eager'][] = $provider;
  4174. }
  4175. }
  4176. return $this->writeManifest($manifest);
  4177. }
  4178. public function createProvider(Application $app, $provider)
  4179. {
  4180. return new $provider($app);
  4181. }
  4182. public function shouldRecompile($manifest, $providers)
  4183. {
  4184. return is_null($manifest) || $manifest['providers'] != $providers;
  4185. }
  4186. public function loadManifest()
  4187. {
  4188. $path = $this->manifestPath . '/services.json';
  4189. if ($this->files->exists($path)) {
  4190. $manifest = json_decode($this->files->get($path), true);
  4191. return array_merge($this->default, $manifest);
  4192. }
  4193. }
  4194. public function writeManifest($manifest)
  4195. {
  4196. $path = $this->manifestPath . '/services.json';
  4197. $this->files->put($path, json_encode($manifest, JSON_PRETTY_PRINT));
  4198. return $manifest;
  4199. }
  4200. protected function freshManifest(array $providers)
  4201. {
  4202. list($eager, $deferred) = array(array(), array());
  4203. return compact('providers', 'eager', 'deferred');
  4204. }
  4205. public function getFilesystem()
  4206. {
  4207. return $this->files;
  4208. }
  4209. }
  4210. namespace Illuminate\Cookie;
  4211. use Illuminate\Support\ServiceProvider;
  4212. class CookieServiceProvider extends ServiceProvider
  4213. {
  4214. public function register()
  4215. {
  4216. $this->app->bindShared('cookie', function ($app) {
  4217. $config = $app['config']['session'];
  4218. return with(new CookieJar())->setDefaultPathAndDomain($config['path'], $config['domain']);
  4219. });
  4220. }
  4221. }
  4222. namespace Illuminate\Database;
  4223. use Illuminate\Database\Eloquent\Model;
  4224. use Illuminate\Support\ServiceProvider;
  4225. use Illuminate\Database\Connectors\ConnectionFactory;
  4226. class DatabaseServiceProvider extends ServiceProvider
  4227. {
  4228. public function boot()
  4229. {
  4230. Model::setConnectionResolver($this->app['db']);
  4231. Model::setEventDispatcher($this->app['events']);
  4232. }
  4233. public function register()
  4234. {
  4235. $this->app->bindShared('db.factory', function ($app) {
  4236. return new ConnectionFactory($app);
  4237. });
  4238. $this->app->bindShared('db', function ($app) {
  4239. return new DatabaseManager($app, $app['db.factory']);
  4240. });
  4241. }
  4242. }
  4243. namespace Illuminate\Encryption;
  4244. use Illuminate\Support\ServiceProvider;
  4245. class EncryptionServiceProvider extends ServiceProvider
  4246. {
  4247. public function register()
  4248. {
  4249. $this->app->bindShared('encrypter', function ($app) {
  4250. $encrypter = new Encrypter($app['config']['app.key']);
  4251. if ($app['config']->has('app.cipher')) {
  4252. $encrypter->setCipher($app['config']['app.cipher']);
  4253. }
  4254. return $encrypter;
  4255. });
  4256. }
  4257. }
  4258. namespace Illuminate\Filesystem;
  4259. use Illuminate\Support\ServiceProvider;
  4260. class FilesystemServiceProvider extends ServiceProvider
  4261. {
  4262. public function register()
  4263. {
  4264. $this->app->bindShared('files', function () {
  4265. return new Filesystem();
  4266. });
  4267. }
  4268. }
  4269. namespace Illuminate\Session;
  4270. use Illuminate\Support\ServiceProvider;
  4271. class SessionServiceProvider extends ServiceProvider
  4272. {
  4273. public function register()
  4274. {
  4275. $this->setupDefaultDriver();
  4276. $this->registerSessionManager();
  4277. $this->registerSessionDriver();
  4278. }
  4279. protected function setupDefaultDriver()
  4280. {
  4281. if ($this->app->runningInConsole()) {
  4282. $this->app['config']['session.driver'] = 'array';
  4283. }
  4284. }
  4285. protected function registerSessionManager()
  4286. {
  4287. $this->app->bindShared('session', function ($app) {
  4288. return new SessionManager($app);
  4289. });
  4290. }
  4291. protected function registerSessionDriver()
  4292. {
  4293. $this->app->bindShared('session.store', function ($app) {
  4294. $manager = $app['session'];
  4295. return $manager->driver();
  4296. });
  4297. }
  4298. protected function getDriver()
  4299. {
  4300. return $this->app['config']['session.driver'];
  4301. }
  4302. }
  4303. namespace Illuminate\View;
  4304. use Illuminate\Support\ViewErrorBag;
  4305. use Illuminate\View\Engines\PhpEngine;
  4306. use Illuminate\Support\ServiceProvider;
  4307. use Illuminate\View\Engines\CompilerEngine;
  4308. use Illuminate\View\Engines\EngineResolver;
  4309. use Illuminate\View\Compilers\BladeCompiler;
  4310. class ViewServiceProvider extends ServiceProvider
  4311. {
  4312. public function register()
  4313. {
  4314. $this->registerEngineResolver();
  4315. $this->registerViewFinder();
  4316. $this->registerFactory();
  4317. $this->registerSessionBinder();
  4318. }
  4319. public function registerEngineResolver()
  4320. {
  4321. $this->app->bindShared('view.engine.resolver', function ($app) {
  4322. $resolver = new EngineResolver();
  4323. foreach (array('php', 'blade') as $engine) {
  4324. $this->{'register' . ucfirst($engine) . 'Engine'}($resolver);
  4325. }
  4326. return $resolver;
  4327. });
  4328. }
  4329. public function registerPhpEngine($resolver)
  4330. {
  4331. $resolver->register('php', function () {
  4332. return new PhpEngine();
  4333. });
  4334. }
  4335. public function registerBladeEngine($resolver)
  4336. {
  4337. $app = $this->app;
  4338. $app->bindShared('blade.compiler', function ($app) {
  4339. $cache = $app['path.storage'] . '/views';
  4340. return new BladeCompiler($app['files'], $cache);
  4341. });
  4342. $resolver->register('blade', function () use($app) {
  4343. return new CompilerEngine($app['blade.compiler'], $app['files']);
  4344. });
  4345. }
  4346. public function registerViewFinder()
  4347. {
  4348. $this->app->bindShared('view.finder', function ($app) {
  4349. $paths = $app['config']['view.paths'];
  4350. return new FileViewFinder($app['files'], $paths);
  4351. });
  4352. }
  4353. public function registerFactory()
  4354. {
  4355. $this->app->bindShared('view', function ($app) {
  4356. $resolver = $app['view.engine.resolver'];
  4357. $finder = $app['view.finder'];
  4358. $env = new Factory($resolver, $finder, $app['events']);
  4359. $env->setContainer($app);
  4360. $env->share('app', $app);
  4361. return $env;
  4362. });
  4363. }
  4364. protected function registerSessionBinder()
  4365. {
  4366. list($app, $me) = array($this->app, $this);
  4367. $app->booted(function () use($app, $me) {
  4368. if ($me->sessionHasErrors($app)) {
  4369. $errors = $app['session.store']->get('errors');
  4370. $app['view']->share('errors', $errors);
  4371. } else {
  4372. $app['view']->share('errors', new ViewErrorBag());
  4373. }
  4374. });
  4375. }
  4376. public function sessionHasErrors($app)
  4377. {
  4378. $config = $app['config']['session'];
  4379. if (isset($app['session.store']) && !is_null($config['driver'])) {
  4380. return $app['session.store']->has('errors');
  4381. }
  4382. }
  4383. }
  4384. namespace Illuminate\Routing;
  4385. interface RouteFiltererInterface
  4386. {
  4387. public function filter($name, $callback);
  4388. public function callRouteFilter($filter, $parameters, $route, $request, $response = null);
  4389. }
  4390. namespace Illuminate\Routing;
  4391. use Closure;
  4392. use Illuminate\Http\Request;
  4393. use Illuminate\Http\Response;
  4394. use Illuminate\Events\Dispatcher;
  4395. use Illuminate\Container\Container;
  4396. use Symfony\Component\HttpKernel\HttpKernelInterface;
  4397. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  4398. use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
  4399. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  4400. class Router implements HttpKernelInterface, RouteFiltererInterface
  4401. {
  4402. protected $events;
  4403. protected $container;
  4404. protected $routes;
  4405. protected $current;
  4406. protected $currentRequest;
  4407. protected $controllerDispatcher;
  4408. protected $inspector;
  4409. protected $filtering = true;
  4410. protected $patternFilters = array();
  4411. protected $regexFilters = array();
  4412. protected $binders = array();
  4413. protected $patterns = array();
  4414. protected $groupStack = array();
  4415. public static $verbs = array('GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS');
  4416. protected $resourceDefaults = array('index', 'create', 'store', 'show', 'edit', 'update', 'destroy');
  4417. public function __construct(Dispatcher $events, Container $container = null)
  4418. {
  4419. $this->events = $events;
  4420. $this->routes = new RouteCollection();
  4421. $this->container = $container ?: new Container();
  4422. $this->bind('_missing', function ($v) {
  4423. return explode('/', $v);
  4424. });
  4425. }
  4426. public function get($uri, $action)
  4427. {
  4428. return $this->addRoute(array('GET', 'HEAD'), $uri, $action);
  4429. }
  4430. public function post($uri, $action)
  4431. {
  4432. return $this->addRoute('POST', $uri, $action);
  4433. }
  4434. public function put($uri, $action)
  4435. {
  4436. return $this->addRoute('PUT', $uri, $action);
  4437. }
  4438. public function patch($uri, $action)
  4439. {
  4440. return $this->addRoute('PATCH', $uri, $action);
  4441. }
  4442. public function delete($uri, $action)
  4443. {
  4444. return $this->addRoute('DELETE', $uri, $action);
  4445. }
  4446. public function options($uri, $action)
  4447. {
  4448. return $this->addRoute('OPTIONS', $uri, $action);
  4449. }
  4450. public function any($uri, $action)
  4451. {
  4452. $verbs = array('GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE');
  4453. return $this->addRoute($verbs, $uri, $action);
  4454. }
  4455. public function match($methods, $uri, $action)
  4456. {
  4457. return $this->addRoute($methods, $uri, $action);
  4458. }
  4459. public function controllers(array $controllers)
  4460. {
  4461. foreach ($controllers as $uri => $name) {
  4462. $this->controller($uri, $name);
  4463. }
  4464. }
  4465. public function controller($uri, $controller, $names = array())
  4466. {
  4467. $prepended = $controller;
  4468. if (count($this->groupStack) > 0) {
  4469. $prepended = $this->prependGroupUses($controller);
  4470. }
  4471. $routable = $this->getInspector()->getRoutable($prepended, $uri);
  4472. foreach ($routable as $method => $routes) {
  4473. foreach ($routes as $route) {
  4474. $this->registerInspected($route, $controller, $method, $names);
  4475. }
  4476. }
  4477. $this->addFallthroughRoute($controller, $uri);
  4478. }
  4479. protected function registerInspected($route, $controller, $method, &$names)
  4480. {
  4481. $action = array('uses' => $controller . '@' . $method);
  4482. $action['as'] = array_pull($names, $method);
  4483. $this->{$route['verb']}($route['uri'], $action);
  4484. }
  4485. protected function addFallthroughRoute($controller, $uri)
  4486. {
  4487. $missing = $this->any($uri . '/{_missing}', $controller . '@missingMethod');
  4488. $missing->where('_missing', '(.*)');
  4489. }
  4490. public function resource($name, $controller, array $options = array())
  4491. {
  4492. if (str_contains($name, '/')) {
  4493. $this->prefixedResource($name, $controller, $options);
  4494. return;
  4495. }
  4496. $base = $this->getResourceWildcard(last(explode('.', $name)));
  4497. $defaults = $this->resourceDefaults;
  4498. foreach ($this->getResourceMethods($defaults, $options) as $m) {
  4499. $this->{'addResource' . ucfirst($m)}($name, $base, $controller, $options);
  4500. }
  4501. }
  4502. protected function prefixedResource($name, $controller, array $options)
  4503. {
  4504. list($name, $prefix) = $this->getResourcePrefix($name);
  4505. $callback = function ($me) use($name, $controller, $options) {
  4506. $me->resource($name, $controller, $options);
  4507. };
  4508. return $this->group(compact('prefix'), $callback);
  4509. }
  4510. protected function getResourcePrefix($name)
  4511. {
  4512. $segments = explode('/', $name);
  4513. $prefix = implode('/', array_slice($segments, 0, -1));
  4514. return array($segments[count($segments) - 1], $prefix);
  4515. }
  4516. protected function getResourceMethods($defaults, $options)
  4517. {
  4518. if (isset($options['only'])) {
  4519. return array_intersect($defaults, $options['only']);
  4520. } elseif (isset($options['except'])) {
  4521. return array_diff($defaults, $options['except']);
  4522. }
  4523. return $defaults;
  4524. }
  4525. public function getResourceUri($resource)
  4526. {
  4527. if (!str_contains($resource, '.')) {
  4528. return $resource;
  4529. }
  4530. $segments = explode('.', $resource);
  4531. $uri = $this->getNestedResourceUri($segments);
  4532. return str_replace('/{' . $this->getResourceWildcard(last($segments)) . '}', '', $uri);
  4533. }
  4534. protected function getNestedResourceUri(array $segments)
  4535. {
  4536. return implode('/', array_map(function ($s) {
  4537. return $s . '/{' . $this->getResourceWildcard($s) . '}';
  4538. }, $segments));
  4539. }
  4540. protected function getResourceAction($resource, $controller, $method, $options)
  4541. {
  4542. $name = $this->getResourceName($resource, $method, $options);
  4543. return array('as' => $name, 'uses' => $controller . '@' . $method);
  4544. }
  4545. protected function getResourceName($resource, $method, $options)
  4546. {
  4547. if (isset($options['names'][$method])) {
  4548. return $options['names'][$method];
  4549. }
  4550. $prefix = isset($options['as']) ? $options['as'] . '.' : '';
  4551. if (count($this->groupStack) == 0) {
  4552. return $prefix . $resource . '.' . $method;
  4553. }
  4554. return $this->getGroupResourceName($prefix, $resource, $method);
  4555. }
  4556. protected function getGroupResourceName($prefix, $resource, $method)
  4557. {
  4558. $group = str_replace('/', '.', $this->getLastGroupPrefix());
  4559. return trim("{$prefix}{$group}.{$resource}.{$method}", '.');
  4560. }
  4561. public function getResourceWildcard($value)
  4562. {
  4563. return str_replace('-', '_', $value);
  4564. }
  4565. protected function addResourceIndex($name, $base, $controller, $options)
  4566. {
  4567. $action = $this->getResourceAction($name, $controller, 'index', $options);
  4568. return $this->get($this->getResourceUri($name), $action);
  4569. }
  4570. protected function addResourceCreate($name, $base, $controller, $options)
  4571. {
  4572. $action = $this->getResourceAction($name, $controller, 'create', $options);
  4573. return $this->get($this->getResourceUri($name) . '/create', $action);
  4574. }
  4575. protected function addResourceStore($name, $base, $controller, $options)
  4576. {
  4577. $action = $this->getResourceAction($name, $controller, 'store', $options);
  4578. return $this->post($this->getResourceUri($name), $action);
  4579. }
  4580. protected function addResourceShow($name, $base, $controller, $options)
  4581. {
  4582. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4583. return $this->get($uri, $this->getResourceAction($name, $controller, 'show', $options));
  4584. }
  4585. protected function addResourceEdit($name, $base, $controller, $options)
  4586. {
  4587. $uri = $this->getResourceUri($name) . '/{' . $base . '}/edit';
  4588. return $this->get($uri, $this->getResourceAction($name, $controller, 'edit', $options));
  4589. }
  4590. protected function addResourceUpdate($name, $base, $controller, $options)
  4591. {
  4592. $this->addPutResourceUpdate($name, $base, $controller, $options);
  4593. return $this->addPatchResourceUpdate($name, $base, $controller);
  4594. }
  4595. protected function addPutResourceUpdate($name, $base, $controller, $options)
  4596. {
  4597. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4598. return $this->put($uri, $this->getResourceAction($name, $controller, 'update', $options));
  4599. }
  4600. protected function addPatchResourceUpdate($name, $base, $controller)
  4601. {
  4602. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4603. $this->patch($uri, $controller . '@update');
  4604. }
  4605. protected function addResourceDestroy($name, $base, $controller, $options)
  4606. {
  4607. $action = $this->getResourceAction($name, $controller, 'destroy', $options);
  4608. return $this->delete($this->getResourceUri($name) . '/{' . $base . '}', $action);
  4609. }
  4610. public function group(array $attributes, Closure $callback)
  4611. {
  4612. $this->updateGroupStack($attributes);
  4613. call_user_func($callback, $this);
  4614. array_pop($this->groupStack);
  4615. }
  4616. protected function updateGroupStack(array $attributes)
  4617. {
  4618. if (count($this->groupStack) > 0) {
  4619. $attributes = $this->mergeGroup($attributes, last($this->groupStack));
  4620. }
  4621. $this->groupStack[] = $attributes;
  4622. }
  4623. public function mergeWithLastGroup($new)
  4624. {
  4625. return $this->mergeGroup($new, last($this->groupStack));
  4626. }
  4627. public static function mergeGroup($new, $old)
  4628. {
  4629. $new['namespace'] = static::formatUsesPrefix($new, $old);
  4630. $new['prefix'] = static::formatGroupPrefix($new, $old);
  4631. if (isset($new['domain'])) {
  4632. unset($old['domain']);
  4633. }
  4634. return array_merge_recursive(array_except($old, array('namespace', 'prefix')), $new);
  4635. }
  4636. protected static function formatUsesPrefix($new, $old)
  4637. {
  4638. if (isset($new['namespace'])) {
  4639. return trim(array_get($old, 'namespace'), '\\') . '\\' . trim($new['namespace'], '\\');
  4640. } else {
  4641. return array_get($old, 'namespace');
  4642. }
  4643. }
  4644. protected static function formatGroupPrefix($new, $old)
  4645. {
  4646. if (isset($new['prefix'])) {
  4647. return trim(array_get($old, 'prefix'), '/') . '/' . trim($new['prefix'], '/');
  4648. } else {
  4649. return array_get($old, 'prefix');
  4650. }
  4651. }
  4652. protected function getLastGroupPrefix()
  4653. {
  4654. if (count($this->groupStack) > 0) {
  4655. return array_get(last($this->groupStack), 'prefix', '');
  4656. }
  4657. return '';
  4658. }
  4659. protected function addRoute($methods, $uri, $action)
  4660. {
  4661. return $this->routes->add($this->createRoute($methods, $uri, $action));
  4662. }
  4663. protected function createRoute($methods, $uri, $action)
  4664. {
  4665. if ($this->routingToController($action)) {
  4666. $action = $this->getControllerAction($action);
  4667. }
  4668. $route = $this->newRoute($methods, $uri = $this->prefix($uri), $action);
  4669. $route->where($this->patterns);
  4670. if (count($this->groupStack) > 0) {
  4671. $this->mergeController($route);
  4672. }
  4673. return $route;
  4674. }
  4675. protected function newRoute($methods, $uri, $action)
  4676. {
  4677. return new Route($methods, $uri, $action);
  4678. }
  4679. protected function prefix($uri)
  4680. {
  4681. return trim(trim($this->getLastGroupPrefix(), '/') . '/' . trim($uri, '/'), '/') ?: '/';
  4682. }
  4683. protected function mergeController($route)
  4684. {
  4685. $action = $this->mergeWithLastGroup($route->getAction());
  4686. $route->setAction($action);
  4687. }
  4688. protected function routingToController($action)
  4689. {
  4690. if ($action instanceof Closure) {
  4691. return false;
  4692. }
  4693. return is_string($action) || is_string(array_get($action, 'uses'));
  4694. }
  4695. protected function getControllerAction($action)
  4696. {
  4697. if (is_string($action)) {
  4698. $action = array('uses' => $action);
  4699. }
  4700. if (count($this->groupStack) > 0) {
  4701. $action['uses'] = $this->prependGroupUses($action['uses']);
  4702. }
  4703. $action['controller'] = $action['uses'];
  4704. $closure = $this->getClassClosure($action['uses']);
  4705. return array_set($action, 'uses', $closure);
  4706. }
  4707. protected function getClassClosure($controller)
  4708. {
  4709. $d = $this->getControllerDispatcher();
  4710. return function () use($d, $controller) {
  4711. $route = $this->current();
  4712. $request = $this->getCurrentRequest();
  4713. list($class, $method) = explode('@', $controller);
  4714. return $d->dispatch($route, $request, $class, $method);
  4715. };
  4716. }
  4717. protected function prependGroupUses($uses)
  4718. {
  4719. $group = last($this->groupStack);
  4720. return isset($group['namespace']) ? $group['namespace'] . '\\' . $uses : $uses;
  4721. }
  4722. public function dispatch(Request $request)
  4723. {
  4724. $this->currentRequest = $request;
  4725. $response = $this->callFilter('before', $request);
  4726. if (is_null($response)) {
  4727. $response = $this->dispatchToRoute($request);
  4728. }
  4729. $response = $this->prepareResponse($request, $response);
  4730. $this->callFilter('after', $request, $response);
  4731. return $response;
  4732. }
  4733. public function dispatchToRoute(Request $request)
  4734. {
  4735. $route = $this->findRoute($request);
  4736. $this->events->fire('router.matched', array($route, $request));
  4737. $response = $this->callRouteBefore($route, $request);
  4738. if (is_null($response)) {
  4739. $response = $route->run($request);
  4740. }
  4741. $response = $this->prepareResponse($request, $response);
  4742. $this->callRouteAfter($route, $request, $response);
  4743. return $response;
  4744. }
  4745. protected function findRoute($request)
  4746. {
  4747. $this->current = $route = $this->routes->match($request);
  4748. return $this->substituteBindings($route);
  4749. }
  4750. protected function substituteBindings($route)
  4751. {
  4752. foreach ($route->parameters() as $key => $value) {
  4753. if (isset($this->binders[$key])) {
  4754. $route->setParameter($key, $this->performBinding($key, $value, $route));
  4755. }
  4756. }
  4757. return $route;
  4758. }
  4759. protected function performBinding($key, $value, $route)
  4760. {
  4761. return call_user_func($this->binders[$key], $value, $route);
  4762. }
  4763. public function matched($callback)
  4764. {
  4765. $this->events->listen('router.matched', $callback);
  4766. }
  4767. public function before($callback)
  4768. {
  4769. $this->addGlobalFilter('before', $callback);
  4770. }
  4771. public function after($callback)
  4772. {
  4773. $this->addGlobalFilter('after', $callback);
  4774. }
  4775. protected function addGlobalFilter($filter, $callback)
  4776. {
  4777. $this->events->listen('router.' . $filter, $this->parseFilter($callback));
  4778. }
  4779. public function filter($name, $callback)
  4780. {
  4781. $this->events->listen('router.filter: ' . $name, $this->parseFilter($callback));
  4782. }
  4783. protected function parseFilter($callback)
  4784. {
  4785. if (is_string($callback) && !str_contains($callback, '@')) {
  4786. return $callback . '@filter';
  4787. } else {
  4788. return $callback;
  4789. }
  4790. }
  4791. public function when($pattern, $name, $methods = null)
  4792. {
  4793. if (!is_null($methods)) {
  4794. $methods = array_map('strtoupper', (array) $methods);
  4795. }
  4796. $this->patternFilters[$pattern][] = compact('name', 'methods');
  4797. }
  4798. public function whenRegex($pattern, $name, $methods = null)
  4799. {
  4800. if (!is_null($methods)) {
  4801. $methods = array_map('strtoupper', (array) $methods);
  4802. }
  4803. $this->regexFilters[$pattern][] = compact('name', 'methods');
  4804. }
  4805. public function model($key, $class, Closure $callback = null)
  4806. {
  4807. return $this->bind($key, function ($value) use($class, $callback) {
  4808. if (is_null($value)) {
  4809. return null;
  4810. }
  4811. if ($model = with(new $class())->find($value)) {
  4812. return $model;
  4813. }
  4814. if ($callback instanceof Closure) {
  4815. return call_user_func($callback);
  4816. }
  4817. throw new NotFoundHttpException();
  4818. });
  4819. }
  4820. public function bind($key, $binder)
  4821. {
  4822. $this->binders[str_replace('-', '_', $key)] = $binder;
  4823. }
  4824. public function pattern($key, $pattern)
  4825. {
  4826. $this->patterns[$key] = $pattern;
  4827. }
  4828. protected function callFilter($filter, $request, $response = null)
  4829. {
  4830. if (!$this->filtering) {
  4831. return null;
  4832. }
  4833. return $this->events->until('router.' . $filter, array($request, $response));
  4834. }
  4835. public function callRouteBefore($route, $request)
  4836. {
  4837. $response = $this->callPatternFilters($route, $request);
  4838. return $response ?: $this->callAttachedBefores($route, $request);
  4839. }
  4840. protected function callPatternFilters($route, $request)
  4841. {
  4842. foreach ($this->findPatternFilters($request) as $filter => $parameters) {
  4843. $response = $this->callRouteFilter($filter, $parameters, $route, $request);
  4844. if (!is_null($response)) {
  4845. return $response;
  4846. }
  4847. }
  4848. }
  4849. public function findPatternFilters($request)
  4850. {
  4851. $results = array();
  4852. list($path, $method) = array($request->path(), $request->getMethod());
  4853. foreach ($this->patternFilters as $pattern => $filters) {
  4854. if (str_is($pattern, $path)) {
  4855. $merge = $this->patternsByMethod($method, $filters);
  4856. $results = array_merge($results, $merge);
  4857. }
  4858. }
  4859. foreach ($this->regexFilters as $pattern => $filters) {
  4860. if (preg_match($pattern, $path)) {
  4861. $merge = $this->patternsByMethod($method, $filters);
  4862. $results = array_merge($results, $merge);
  4863. }
  4864. }
  4865. return $results;
  4866. }
  4867. protected function patternsByMethod($method, $filters)
  4868. {
  4869. $results = array();
  4870. foreach ($filters as $filter) {
  4871. if ($this->filterSupportsMethod($filter, $method)) {
  4872. $parsed = Route::parseFilters($filter['name']);
  4873. $results = array_merge($results, $parsed);
  4874. }
  4875. }
  4876. return $results;
  4877. }
  4878. protected function filterSupportsMethod($filter, $method)
  4879. {
  4880. $methods = $filter['methods'];
  4881. return is_null($methods) || in_array($method, $methods);
  4882. }
  4883. protected function callAttachedBefores($route, $request)
  4884. {
  4885. foreach ($route->beforeFilters() as $filter => $parameters) {
  4886. $response = $this->callRouteFilter($filter, $parameters, $route, $request);
  4887. if (!is_null($response)) {
  4888. return $response;
  4889. }
  4890. }
  4891. }
  4892. public function callRouteAfter($route, $request, $response)
  4893. {
  4894. foreach ($route->afterFilters() as $filter => $parameters) {
  4895. $this->callRouteFilter($filter, $parameters, $route, $request, $response);
  4896. }
  4897. }
  4898. public function callRouteFilter($filter, $parameters, $route, $request, $response = null)
  4899. {
  4900. if (!$this->filtering) {
  4901. return null;
  4902. }
  4903. $data = array_merge(array($route, $request, $response), $parameters);
  4904. return $this->events->until('router.filter: ' . $filter, $this->cleanFilterParameters($data));
  4905. }
  4906. protected function cleanFilterParameters(array $parameters)
  4907. {
  4908. return array_filter($parameters, function ($p) {
  4909. return !is_null($p) && $p !== '';
  4910. });
  4911. }
  4912. protected function prepareResponse($request, $response)
  4913. {
  4914. if (!$response instanceof SymfonyResponse) {
  4915. $response = new Response($response);
  4916. }
  4917. return $response->prepare($request);
  4918. }
  4919. public function withoutFilters($callback)
  4920. {
  4921. $this->disableFilters();
  4922. call_user_func($callback);
  4923. $this->enableFilters();
  4924. }
  4925. public function enableFilters()
  4926. {
  4927. $this->filtering = true;
  4928. }
  4929. public function disableFilters()
  4930. {
  4931. $this->filtering = false;
  4932. }
  4933. public function input($key, $default = null)
  4934. {
  4935. return $this->current()->parameter($key, $default);
  4936. }
  4937. public function getCurrentRoute()
  4938. {
  4939. return $this->current();
  4940. }
  4941. public function current()
  4942. {
  4943. return $this->current;
  4944. }
  4945. public function currentRouteName()
  4946. {
  4947. return $this->current() ? $this->current()->getName() : null;
  4948. }
  4949. public function is()
  4950. {
  4951. foreach (func_get_args() as $pattern) {
  4952. if (str_is($pattern, $this->currentRouteName())) {
  4953. return true;
  4954. }
  4955. }
  4956. return false;
  4957. }
  4958. public function currentRouteNamed($name)
  4959. {
  4960. return $this->current() ? $this->current()->getName() == $name : false;
  4961. }
  4962. public function currentRouteAction()
  4963. {
  4964. $action = $this->current()->getAction();
  4965. return isset($action['controller']) ? $action['controller'] : null;
  4966. }
  4967. public function uses()
  4968. {
  4969. foreach (func_get_args() as $pattern) {
  4970. if (str_is($pattern, $this->currentRouteAction())) {
  4971. return true;
  4972. }
  4973. }
  4974. return false;
  4975. }
  4976. public function currentRouteUses($action)
  4977. {
  4978. return $this->currentRouteAction() == $action;
  4979. }
  4980. public function getCurrentRequest()
  4981. {
  4982. return $this->currentRequest;
  4983. }
  4984. public function getRoutes()
  4985. {
  4986. return $this->routes;
  4987. }
  4988. public function getControllerDispatcher()
  4989. {
  4990. if (is_null($this->controllerDispatcher)) {
  4991. $this->controllerDispatcher = new ControllerDispatcher($this, $this->container);
  4992. }
  4993. return $this->controllerDispatcher;
  4994. }
  4995. public function setControllerDispatcher(ControllerDispatcher $dispatcher)
  4996. {
  4997. $this->controllerDispatcher = $dispatcher;
  4998. }
  4999. public function getInspector()
  5000. {
  5001. return $this->inspector ?: ($this->inspector = new ControllerInspector());
  5002. }
  5003. public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  5004. {
  5005. return $this->dispatch(Request::createFromBase($request));
  5006. }
  5007. }
  5008. namespace Illuminate\Routing;
  5009. use Closure;
  5010. use Illuminate\Http\Request;
  5011. use Illuminate\Routing\Matching\UriValidator;
  5012. use Illuminate\Routing\Matching\HostValidator;
  5013. use Illuminate\Routing\Matching\MethodValidator;
  5014. use Illuminate\Routing\Matching\SchemeValidator;
  5015. use Symfony\Component\Routing\Route as SymfonyRoute;
  5016. class Route
  5017. {
  5018. protected $uri;
  5019. protected $methods;
  5020. protected $action;
  5021. protected $defaults = array();
  5022. protected $wheres = array();
  5023. protected $parameters;
  5024. protected $parameterNames;
  5025. protected $compiled;
  5026. protected static $validators;
  5027. public function __construct($methods, $uri, $action)
  5028. {
  5029. $this->uri = $uri;
  5030. $this->methods = (array) $methods;
  5031. $this->action = $this->parseAction($action);
  5032. if (isset($this->action['prefix'])) {
  5033. $this->prefix($this->action['prefix']);
  5034. }
  5035. }
  5036. public function run()
  5037. {
  5038. $parameters = array_filter($this->parameters(), function ($p) {
  5039. return isset($p);
  5040. });
  5041. return call_user_func_array($this->action['uses'], $parameters);
  5042. }
  5043. public function matches(Request $request, $includingMethod = true)
  5044. {
  5045. $this->compileRoute();
  5046. foreach ($this->getValidators() as $validator) {
  5047. if (!$includingMethod && $validator instanceof MethodValidator) {
  5048. continue;
  5049. }
  5050. if (!$validator->matches($this, $request)) {
  5051. return false;
  5052. }
  5053. }
  5054. return true;
  5055. }
  5056. protected function compileRoute()
  5057. {
  5058. $optionals = $this->extractOptionalParameters();
  5059. $uri = preg_replace('/\\{(\\w+?)\\?\\}/', '{$1}', $this->uri);
  5060. $this->compiled = with(new SymfonyRoute($uri, $optionals, $this->wheres, array(), $this->domain() ?: ''))->compile();
  5061. }
  5062. protected function extractOptionalParameters()
  5063. {
  5064. preg_match_all('/\\{(\\w+?)\\?\\}/', $this->uri, $matches);
  5065. $optional = array();
  5066. if (isset($matches[1])) {
  5067. foreach ($matches[1] as $key) {
  5068. $optional[$key] = null;
  5069. }
  5070. }
  5071. return $optional;
  5072. }
  5073. public function beforeFilters()
  5074. {
  5075. if (!isset($this->action['before'])) {
  5076. return array();
  5077. }
  5078. return $this->parseFilters($this->action['before']);
  5079. }
  5080. public function afterFilters()
  5081. {
  5082. if (!isset($this->action['after'])) {
  5083. return array();
  5084. }
  5085. return $this->parseFilters($this->action['after']);
  5086. }
  5087. public static function parseFilters($filters)
  5088. {
  5089. return array_build(static::explodeFilters($filters), function ($key, $value) {
  5090. return Route::parseFilter($value);
  5091. });
  5092. }
  5093. protected static function explodeFilters($filters)
  5094. {
  5095. if (is_array($filters)) {
  5096. return static::explodeArrayFilters($filters);
  5097. }
  5098. return explode('|', $filters);
  5099. }
  5100. protected static function explodeArrayFilters(array $filters)
  5101. {
  5102. $results = array();
  5103. foreach ($filters as $filter) {
  5104. $results = array_merge($results, explode('|', $filter));
  5105. }
  5106. return $results;
  5107. }
  5108. public static function parseFilter($filter)
  5109. {
  5110. if (!str_contains($filter, ':')) {
  5111. return array($filter, array());
  5112. }
  5113. return static::parseParameterFilter($filter);
  5114. }
  5115. protected static function parseParameterFilter($filter)
  5116. {
  5117. list($name, $parameters) = explode(':', $filter, 2);
  5118. return array($name, explode(',', $parameters));
  5119. }
  5120. public function getParameter($name, $default = null)
  5121. {
  5122. return $this->parameter($name, $default);
  5123. }
  5124. public function parameter($name, $default = null)
  5125. {
  5126. return array_get($this->parameters(), $name) ?: $default;
  5127. }
  5128. public function setParameter($name, $value)
  5129. {
  5130. $this->parameters();
  5131. $this->parameters[$name] = $value;
  5132. }
  5133. public function forgetParameter($name)
  5134. {
  5135. $this->parameters();
  5136. unset($this->parameters[$name]);
  5137. }
  5138. public function parameters()
  5139. {
  5140. if (isset($this->parameters)) {
  5141. return array_map(function ($value) {
  5142. return is_string($value) ? rawurldecode($value) : $value;
  5143. }, $this->parameters);
  5144. }
  5145. throw new \LogicException('Route is not bound.');
  5146. }
  5147. public function parametersWithoutNulls()
  5148. {
  5149. return array_filter($this->parameters(), function ($p) {
  5150. return !is_null($p);
  5151. });
  5152. }
  5153. public function parameterNames()
  5154. {
  5155. if (isset($this->parameterNames)) {
  5156. return $this->parameterNames;
  5157. }
  5158. return $this->parameterNames = $this->compileParameterNames();
  5159. }
  5160. protected function compileParameterNames()
  5161. {
  5162. preg_match_all('/\\{(.*?)\\}/', $this->domain() . $this->uri, $matches);
  5163. return array_map(function ($m) {
  5164. return trim($m, '?');
  5165. }, $matches[1]);
  5166. }
  5167. public function bind(Request $request)
  5168. {
  5169. $this->compileRoute();
  5170. $this->bindParameters($request);
  5171. return $this;
  5172. }
  5173. public function bindParameters(Request $request)
  5174. {
  5175. $params = $this->matchToKeys(array_slice($this->bindPathParameters($request), 1));
  5176. if (!is_null($this->compiled->getHostRegex())) {
  5177. $params = $this->bindHostParameters($request, $params);
  5178. }
  5179. return $this->parameters = $this->replaceDefaults($params);
  5180. }
  5181. protected function bindPathParameters(Request $request)
  5182. {
  5183. preg_match($this->compiled->getRegex(), '/' . $request->decodedPath(), $matches);
  5184. return $matches;
  5185. }
  5186. protected function bindHostParameters(Request $request, $parameters)
  5187. {
  5188. preg_match($this->compiled->getHostRegex(), $request->getHost(), $matches);
  5189. return array_merge($this->matchToKeys(array_slice($matches, 1)), $parameters);
  5190. }
  5191. protected function matchToKeys(array $matches)
  5192. {
  5193. if (count($this->parameterNames()) == 0) {
  5194. return array();
  5195. }
  5196. $parameters = array_intersect_key($matches, array_flip($this->parameterNames()));
  5197. return array_filter($parameters, function ($value) {
  5198. return is_string($value) && strlen($value) > 0;
  5199. });
  5200. }
  5201. protected function replaceDefaults(array $parameters)
  5202. {
  5203. foreach ($parameters as $key => &$value) {
  5204. $value = isset($value) ? $value : array_get($this->defaults, $key);
  5205. }
  5206. return $parameters;
  5207. }
  5208. protected function parseAction($action)
  5209. {
  5210. if ($action instanceof Closure) {
  5211. return array('uses' => $action);
  5212. } elseif (!isset($action['uses'])) {
  5213. $action['uses'] = $this->findClosure($action);
  5214. }
  5215. return $action;
  5216. }
  5217. protected function findClosure(array $action)
  5218. {
  5219. return array_first($action, function ($key, $value) {
  5220. return $value instanceof Closure;
  5221. });
  5222. }
  5223. public static function getValidators()
  5224. {
  5225. if (isset(static::$validators)) {
  5226. return static::$validators;
  5227. }
  5228. return static::$validators = array(new MethodValidator(), new SchemeValidator(), new HostValidator(), new UriValidator());
  5229. }
  5230. public function before($filters)
  5231. {
  5232. return $this->addFilters('before', $filters);
  5233. }
  5234. public function after($filters)
  5235. {
  5236. return $this->addFilters('after', $filters);
  5237. }
  5238. protected function addFilters($type, $filters)
  5239. {
  5240. if (isset($this->action[$type])) {
  5241. $this->action[$type] .= '|' . $filters;
  5242. } else {
  5243. $this->action[$type] = $filters;
  5244. }
  5245. return $this;
  5246. }
  5247. public function defaults($key, $value)
  5248. {
  5249. $this->defaults[$key] = $value;
  5250. return $this;
  5251. }
  5252. public function where($name, $expression = null)
  5253. {
  5254. foreach ($this->parseWhere($name, $expression) as $name => $expression) {
  5255. $this->wheres[$name] = $expression;
  5256. }
  5257. return $this;
  5258. }
  5259. protected function parseWhere($name, $expression)
  5260. {
  5261. return is_array($name) ? $name : array($name => $expression);
  5262. }
  5263. protected function whereArray(array $wheres)
  5264. {
  5265. foreach ($wheres as $name => $expression) {
  5266. $this->where($name, $expression);
  5267. }
  5268. return $this;
  5269. }
  5270. public function prefix($prefix)
  5271. {
  5272. $this->uri = trim($prefix, '/') . '/' . trim($this->uri, '/');
  5273. return $this;
  5274. }
  5275. public function getPath()
  5276. {
  5277. return $this->uri();
  5278. }
  5279. public function uri()
  5280. {
  5281. return $this->uri;
  5282. }
  5283. public function getMethods()
  5284. {
  5285. return $this->methods();
  5286. }
  5287. public function methods()
  5288. {
  5289. return $this->methods;
  5290. }
  5291. public function httpOnly()
  5292. {
  5293. return in_array('http', $this->action, true);
  5294. }
  5295. public function httpsOnly()
  5296. {
  5297. return $this->secure();
  5298. }
  5299. public function secure()
  5300. {
  5301. return in_array('https', $this->action, true);
  5302. }
  5303. public function domain()
  5304. {
  5305. return array_get($this->action, 'domain');
  5306. }
  5307. public function getUri()
  5308. {
  5309. return $this->uri;
  5310. }
  5311. public function setUri($uri)
  5312. {
  5313. $this->uri = $uri;
  5314. return $this;
  5315. }
  5316. public function getPrefix()
  5317. {
  5318. return array_get($this->action, 'prefix');
  5319. }
  5320. public function getName()
  5321. {
  5322. return array_get($this->action, 'as');
  5323. }
  5324. public function getActionName()
  5325. {
  5326. return array_get($this->action, 'controller', 'Closure');
  5327. }
  5328. public function getAction()
  5329. {
  5330. return $this->action;
  5331. }
  5332. public function setAction(array $action)
  5333. {
  5334. $this->action = $action;
  5335. return $this;
  5336. }
  5337. public function getCompiled()
  5338. {
  5339. return $this->compiled;
  5340. }
  5341. }
  5342. namespace Illuminate\Routing;
  5343. use Countable;
  5344. use ArrayIterator;
  5345. use IteratorAggregate;
  5346. use Illuminate\Http\Request;
  5347. use Illuminate\Http\Response;
  5348. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  5349. use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
  5350. class RouteCollection implements Countable, IteratorAggregate
  5351. {
  5352. protected $routes = array();
  5353. protected $allRoutes = array();
  5354. protected $nameList = array();
  5355. protected $actionList = array();
  5356. public function add(Route $route)
  5357. {
  5358. $this->addToCollections($route);
  5359. $this->addLookups($route);
  5360. return $route;
  5361. }
  5362. protected function addToCollections($route)
  5363. {
  5364. foreach ($route->methods() as $method) {
  5365. $this->routes[$method][$route->domain() . $route->getUri()] = $route;
  5366. }
  5367. $this->allRoutes[$method . $route->domain() . $route->getUri()] = $route;
  5368. }
  5369. protected function addLookups($route)
  5370. {
  5371. $action = $route->getAction();
  5372. if (isset($action['as'])) {
  5373. $this->nameList[$action['as']] = $route;
  5374. }
  5375. if (isset($action['controller'])) {
  5376. $this->addToActionList($action, $route);
  5377. }
  5378. }
  5379. protected function addToActionList($action, $route)
  5380. {
  5381. if (!isset($this->actionList[$action['controller']])) {
  5382. $this->actionList[$action['controller']] = $route;
  5383. }
  5384. }
  5385. public function match(Request $request)
  5386. {
  5387. $routes = $this->get($request->getMethod());
  5388. $route = $this->check($routes, $request);
  5389. if (!is_null($route)) {
  5390. return $route->bind($request);
  5391. }
  5392. $others = $this->checkForAlternateVerbs($request);
  5393. if (count($others) > 0) {
  5394. return $this->getOtherMethodsRoute($request, $others);
  5395. }
  5396. throw new NotFoundHttpException();
  5397. }
  5398. protected function checkForAlternateVerbs($request)
  5399. {
  5400. $methods = array_diff(Router::$verbs, array($request->getMethod()));
  5401. $others = array();
  5402. foreach ($methods as $method) {
  5403. if (!is_null($this->check($this->get($method), $request, false))) {
  5404. $others[] = $method;
  5405. }
  5406. }
  5407. return $others;
  5408. }
  5409. protected function getOtherMethodsRoute($request, array $others)
  5410. {
  5411. if ($request->method() == 'OPTIONS') {
  5412. return with(new Route('OPTIONS', $request->path(), function () use($others) {
  5413. return new Response('', 200, array('Allow' => implode(',', $others)));
  5414. }))->bind($request);
  5415. } else {
  5416. $this->methodNotAllowed($others);
  5417. }
  5418. }
  5419. protected function methodNotAllowed(array $others)
  5420. {
  5421. throw new MethodNotAllowedHttpException($others);
  5422. }
  5423. protected function check(array $routes, $request, $includingMethod = true)
  5424. {
  5425. return array_first($routes, function ($key, $value) use($request, $includingMethod) {
  5426. return $value->matches($request, $includingMethod);
  5427. });
  5428. }
  5429. protected function get($method = null)
  5430. {
  5431. if (is_null($method)) {
  5432. return $this->getRoutes();
  5433. }
  5434. return array_get($this->routes, $method, array());
  5435. }
  5436. public function hasNamedRoute($name)
  5437. {
  5438. return !is_null($this->getByName($name));
  5439. }
  5440. public function getByName($name)
  5441. {
  5442. return isset($this->nameList[$name]) ? $this->nameList[$name] : null;
  5443. }
  5444. public function getByAction($action)
  5445. {
  5446. return isset($this->actionList[$action]) ? $this->actionList[$action] : null;
  5447. }
  5448. public function getRoutes()
  5449. {
  5450. return array_values($this->allRoutes);
  5451. }
  5452. public function getIterator()
  5453. {
  5454. return new ArrayIterator($this->getRoutes());
  5455. }
  5456. public function count()
  5457. {
  5458. return count($this->getRoutes());
  5459. }
  5460. }
  5461. namespace Illuminate\Routing;
  5462. use Closure;
  5463. use Illuminate\Http\Request;
  5464. use Illuminate\Container\Container;
  5465. class ControllerDispatcher
  5466. {
  5467. protected $filterer;
  5468. protected $container;
  5469. public function __construct(RouteFiltererInterface $filterer, Container $container = null)
  5470. {
  5471. $this->filterer = $filterer;
  5472. $this->container = $container;
  5473. }
  5474. public function dispatch(Route $route, Request $request, $controller, $method)
  5475. {
  5476. $instance = $this->makeController($controller);
  5477. $this->assignAfter($instance, $route, $request, $method);
  5478. $response = $this->before($instance, $route, $request, $method);
  5479. if (is_null($response)) {
  5480. $response = $this->call($instance, $route, $method);
  5481. }
  5482. return $response;
  5483. }
  5484. protected function makeController($controller)
  5485. {
  5486. Controller::setFilterer($this->filterer);
  5487. return $this->container->make($controller);
  5488. }
  5489. protected function call($instance, $route, $method)
  5490. {
  5491. $parameters = $route->parametersWithoutNulls();
  5492. return $instance->callAction($method, $parameters);
  5493. }
  5494. protected function before($instance, $route, $request, $method)
  5495. {
  5496. foreach ($instance->getBeforeFilters() as $filter) {
  5497. if ($this->filterApplies($filter, $request, $method)) {
  5498. $response = $this->callFilter($filter, $route, $request);
  5499. if (!is_null($response)) {
  5500. return $response;
  5501. }
  5502. }
  5503. }
  5504. }
  5505. protected function assignAfter($instance, $route, $request, $method)
  5506. {
  5507. foreach ($instance->getAfterFilters() as $filter) {
  5508. if ($this->filterApplies($filter, $request, $method)) {
  5509. $route->after($this->getAssignableAfter($filter));
  5510. }
  5511. }
  5512. }
  5513. protected function getAssignableAfter($filter)
  5514. {
  5515. return $filter['original'] instanceof Closure ? $filter['filter'] : $filter['original'];
  5516. }
  5517. protected function filterApplies($filter, $request, $method)
  5518. {
  5519. foreach (array('Only', 'Except', 'On') as $type) {
  5520. if ($this->{"filterFails{$type}"}($filter, $request, $method)) {
  5521. return false;
  5522. }
  5523. }
  5524. return true;
  5525. }
  5526. protected function filterFailsOnly($filter, $request, $method)
  5527. {
  5528. if (!isset($filter['options']['only'])) {
  5529. return false;
  5530. }
  5531. return !in_array($method, (array) $filter['options']['only']);
  5532. }
  5533. protected function filterFailsExcept($filter, $request, $method)
  5534. {
  5535. if (!isset($filter['options']['except'])) {
  5536. return false;
  5537. }
  5538. return in_array($method, (array) $filter['options']['except']);
  5539. }
  5540. protected function filterFailsOn($filter, $request, $method)
  5541. {
  5542. $on = array_get($filter, 'options.on', null);
  5543. if (is_null($on)) {
  5544. return false;
  5545. }
  5546. if (is_string($on)) {
  5547. $on = explode('|', $on);
  5548. }
  5549. return !in_array(strtolower($request->getMethod()), $on);
  5550. }
  5551. protected function callFilter($filter, $route, $request)
  5552. {
  5553. extract($filter);
  5554. return $this->filterer->callRouteFilter($filter, $parameters, $route, $request);
  5555. }
  5556. }
  5557. namespace Illuminate\Routing;
  5558. use Illuminate\Http\Request;
  5559. use InvalidArgumentException;
  5560. class UrlGenerator
  5561. {
  5562. protected $routes;
  5563. protected $request;
  5564. protected $forcedRoot;
  5565. protected $forceSchema;
  5566. protected $dontEncode = array('%2F' => '/', '%40' => '@', '%3A' => ':', '%3B' => ';', '%2C' => ',', '%3D' => '=', '%2B' => '+', '%21' => '!', '%2A' => '*', '%7C' => '|');
  5567. public function __construct(RouteCollection $routes, Request $request)
  5568. {
  5569. $this->routes = $routes;
  5570. $this->setRequest($request);
  5571. }
  5572. public function full()
  5573. {
  5574. return $this->request->fullUrl();
  5575. }
  5576. public function current()
  5577. {
  5578. return $this->to($this->request->getPathInfo());
  5579. }
  5580. public function previous()
  5581. {
  5582. return $this->to($this->request->headers->get('referer'));
  5583. }
  5584. public function to($path, $extra = array(), $secure = null)
  5585. {
  5586. if ($this->isValidUrl($path)) {
  5587. return $path;
  5588. }
  5589. $scheme = $this->getScheme($secure);
  5590. $tail = implode('/', array_map('rawurlencode', (array) $extra));
  5591. $root = $this->getRootUrl($scheme);
  5592. return $this->trimUrl($root, $path, $tail);
  5593. }
  5594. public function secure($path, $parameters = array())
  5595. {
  5596. return $this->to($path, $parameters, true);
  5597. }
  5598. public function asset($path, $secure = null)
  5599. {
  5600. if ($this->isValidUrl($path)) {
  5601. return $path;
  5602. }
  5603. $root = $this->getRootUrl($this->getScheme($secure));
  5604. return $this->removeIndex($root) . '/' . trim($path, '/');
  5605. }
  5606. protected function removeIndex($root)
  5607. {
  5608. $i = 'index.php';
  5609. return str_contains($root, $i) ? str_replace('/' . $i, '', $root) : $root;
  5610. }
  5611. public function secureAsset($path)
  5612. {
  5613. return $this->asset($path, true);
  5614. }
  5615. protected function getScheme($secure)
  5616. {
  5617. if (is_null($secure)) {
  5618. return $this->forceSchema ?: $this->request->getScheme() . '://';
  5619. } else {
  5620. return $secure ? 'https://' : 'http://';
  5621. }
  5622. }
  5623. public function forceSchema($schema)
  5624. {
  5625. $this->forceSchema = $schema . '://';
  5626. }
  5627. public function route($name, $parameters = array(), $absolute = true, $route = null)
  5628. {
  5629. $route = $route ?: $this->routes->getByName($name);
  5630. $parameters = (array) $parameters;
  5631. if (!is_null($route)) {
  5632. return $this->toRoute($route, $parameters, $absolute);
  5633. } else {
  5634. throw new InvalidArgumentException("Route [{$name}] not defined.");
  5635. }
  5636. }
  5637. protected function toRoute($route, array $parameters, $absolute)
  5638. {
  5639. $domain = $this->getRouteDomain($route, $parameters);
  5640. $uri = strtr(rawurlencode($this->trimUrl($root = $this->replaceRoot($route, $domain, $parameters), $this->replaceRouteParameters($route->uri(), $parameters))), $this->dontEncode) . $this->getRouteQueryString($parameters);
  5641. return $absolute ? $uri : '/' . ltrim(str_replace($root, '', $uri), '/');
  5642. }
  5643. protected function replaceRoot($route, $domain, &$parameters)
  5644. {
  5645. return $this->replaceRouteParameters($this->getRouteRoot($route, $domain), $parameters);
  5646. }
  5647. protected function replaceRouteParameters($path, array &$parameters)
  5648. {
  5649. if (count($parameters)) {
  5650. $path = preg_replace_sub('/\\{.*?\\}/', $parameters, $this->replaceNamedParameters($path, $parameters));
  5651. }
  5652. return trim(preg_replace('/\\{.*?\\?\\}/', '', $path), '/');
  5653. }
  5654. protected function replaceNamedParameters($path, &$parameters)
  5655. {
  5656. return preg_replace_callback('/\\{(.*?)\\??\\}/', function ($m) use(&$parameters) {
  5657. return isset($parameters[$m[1]]) ? array_pull($parameters, $m[1]) : $m[0];
  5658. }, $path);
  5659. }
  5660. protected function getRouteQueryString(array $parameters)
  5661. {
  5662. if (count($parameters) == 0) {
  5663. return '';
  5664. }
  5665. $query = http_build_query($keyed = $this->getStringParameters($parameters));
  5666. if (count($keyed) < count($parameters)) {
  5667. $query .= '&' . implode('&', $this->getNumericParameters($parameters));
  5668. }
  5669. return '?' . trim($query, '&');
  5670. }
  5671. protected function getStringParameters(array $parameters)
  5672. {
  5673. return array_where($parameters, function ($k, $v) {
  5674. return is_string($k);
  5675. });
  5676. }
  5677. protected function getNumericParameters(array $parameters)
  5678. {
  5679. return array_where($parameters, function ($k, $v) {
  5680. return is_numeric($k);
  5681. });
  5682. }
  5683. protected function getRouteDomain($route, &$parameters)
  5684. {
  5685. return $route->domain() ? $this->formatDomain($route, $parameters) : null;
  5686. }
  5687. protected function formatDomain($route, &$parameters)
  5688. {
  5689. return $this->addPortToDomain($this->getDomainAndScheme($route));
  5690. }
  5691. protected function getDomainAndScheme($route)
  5692. {
  5693. return $this->getRouteScheme($route) . $route->domain();
  5694. }
  5695. protected function addPortToDomain($domain)
  5696. {
  5697. if (in_array($this->request->getPort(), array('80', '443'))) {
  5698. return $domain;
  5699. } else {
  5700. return $domain .= ':' . $this->request->getPort();
  5701. }
  5702. }
  5703. protected function getRouteRoot($route, $domain)
  5704. {
  5705. return $this->getRootUrl($this->getRouteScheme($route), $domain);
  5706. }
  5707. protected function getRouteScheme($route)
  5708. {
  5709. if ($route->httpOnly()) {
  5710. return $this->getScheme(false);
  5711. } elseif ($route->httpsOnly()) {
  5712. return $this->getScheme(true);
  5713. } else {
  5714. return $this->getScheme(null);
  5715. }
  5716. }
  5717. public function action($action, $parameters = array(), $absolute = true)
  5718. {
  5719. return $this->route($action, $parameters, $absolute, $this->routes->getByAction($action));
  5720. }
  5721. protected function getRootUrl($scheme, $root = null)
  5722. {
  5723. if (is_null($root)) {
  5724. $root = $this->forcedRoot ?: $this->request->root();
  5725. }
  5726. $start = starts_with($root, 'http://') ? 'http://' : 'https://';
  5727. return preg_replace('~' . $start . '~', $scheme, $root, 1);
  5728. }
  5729. public function forceRootUrl($root)
  5730. {
  5731. $this->forcedRoot = $root;
  5732. }
  5733. public function isValidUrl($path)
  5734. {
  5735. if (starts_with($path, array('#', '//', 'mailto:', 'tel:'))) {
  5736. return true;
  5737. }
  5738. return filter_var($path, FILTER_VALIDATE_URL) !== false;
  5739. }
  5740. protected function trimUrl($root, $path, $tail = '')
  5741. {
  5742. return trim($root . '/' . trim($path . '/' . $tail, '/'), '/');
  5743. }
  5744. public function getRequest()
  5745. {
  5746. return $this->request;
  5747. }
  5748. public function setRequest(Request $request)
  5749. {
  5750. $this->request = $request;
  5751. }
  5752. }
  5753. namespace Illuminate\Routing\Matching;
  5754. use Illuminate\Http\Request;
  5755. use Illuminate\Routing\Route;
  5756. interface ValidatorInterface
  5757. {
  5758. public function matches(Route $route, Request $request);
  5759. }
  5760. namespace Illuminate\Routing\Matching;
  5761. use Illuminate\Http\Request;
  5762. use Illuminate\Routing\Route;
  5763. class HostValidator implements ValidatorInterface
  5764. {
  5765. public function matches(Route $route, Request $request)
  5766. {
  5767. if (is_null($route->getCompiled()->getHostRegex())) {
  5768. return true;
  5769. }
  5770. return preg_match($route->getCompiled()->getHostRegex(), $request->getHost());
  5771. }
  5772. }
  5773. namespace Illuminate\Routing\Matching;
  5774. use Illuminate\Http\Request;
  5775. use Illuminate\Routing\Route;
  5776. class MethodValidator implements ValidatorInterface
  5777. {
  5778. public function matches(Route $route, Request $request)
  5779. {
  5780. return in_array($request->getMethod(), $route->methods());
  5781. }
  5782. }
  5783. namespace Illuminate\Routing\Matching;
  5784. use Illuminate\Http\Request;
  5785. use Illuminate\Routing\Route;
  5786. class SchemeValidator implements ValidatorInterface
  5787. {
  5788. public function matches(Route $route, Request $request)
  5789. {
  5790. if ($route->httpOnly()) {
  5791. return !$request->secure();
  5792. } elseif ($route->secure()) {
  5793. return $request->secure();
  5794. }
  5795. return true;
  5796. }
  5797. }
  5798. namespace Illuminate\Routing\Matching;
  5799. use Illuminate\Http\Request;
  5800. use Illuminate\Routing\Route;
  5801. class UriValidator implements ValidatorInterface
  5802. {
  5803. public function matches(Route $route, Request $request)
  5804. {
  5805. $path = $request->path() == '/' ? '/' : '/' . $request->path();
  5806. return preg_match($route->getCompiled()->getRegex(), rawurldecode($path));
  5807. }
  5808. }
  5809. namespace Illuminate\Workbench;
  5810. use Illuminate\Support\ServiceProvider;
  5811. use Illuminate\Workbench\Console\WorkbenchMakeCommand;
  5812. class WorkbenchServiceProvider extends ServiceProvider
  5813. {
  5814. protected $defer = false;
  5815. public function register()
  5816. {
  5817. $this->app->bindShared('package.creator', function ($app) {
  5818. return new PackageCreator($app['files']);
  5819. });
  5820. $this->app->bindShared('command.workbench', function ($app) {
  5821. return new WorkbenchMakeCommand($app['package.creator']);
  5822. });
  5823. $this->commands('command.workbench');
  5824. }
  5825. public function provides()
  5826. {
  5827. return array('package.creator', 'command.workbench');
  5828. }
  5829. }
  5830. namespace Illuminate\Events;
  5831. use Illuminate\Container\Container;
  5832. class Dispatcher
  5833. {
  5834. protected $container;
  5835. protected $listeners = array();
  5836. protected $wildcards = array();
  5837. protected $sorted = array();
  5838. protected $firing = array();
  5839. public function __construct(Container $container = null)
  5840. {
  5841. $this->container = $container ?: new Container();
  5842. }
  5843. public function listen($events, $listener, $priority = 0)
  5844. {
  5845. foreach ((array) $events as $event) {
  5846. if (str_contains($event, '*')) {
  5847. return $this->setupWildcardListen($event, $listener);
  5848. }
  5849. $this->listeners[$event][$priority][] = $this->makeListener($listener);
  5850. unset($this->sorted[$event]);
  5851. }
  5852. }
  5853. protected function setupWildcardListen($event, $listener)
  5854. {
  5855. $this->wildcards[$event][] = $this->makeListener($listener);
  5856. }
  5857. public function hasListeners($eventName)
  5858. {
  5859. return isset($this->listeners[$eventName]);
  5860. }
  5861. public function queue($event, $payload = array())
  5862. {
  5863. $this->listen($event . '_queue', function () use($event, $payload) {
  5864. $this->fire($event, $payload);
  5865. });
  5866. }
  5867. public function subscribe($subscriber)
  5868. {
  5869. $subscriber = $this->resolveSubscriber($subscriber);
  5870. $subscriber->subscribe($this);
  5871. }
  5872. protected function resolveSubscriber($subscriber)
  5873. {
  5874. if (is_string($subscriber)) {
  5875. return $this->container->make($subscriber);
  5876. }
  5877. return $subscriber;
  5878. }
  5879. public function until($event, $payload = array())
  5880. {
  5881. return $this->fire($event, $payload, true);
  5882. }
  5883. public function flush($event)
  5884. {
  5885. $this->fire($event . '_queue');
  5886. }
  5887. public function firing()
  5888. {
  5889. return last($this->firing);
  5890. }
  5891. public function fire($event, $payload = array(), $halt = false)
  5892. {
  5893. $responses = array();
  5894. if (!is_array($payload)) {
  5895. $payload = array($payload);
  5896. }
  5897. $this->firing[] = $event;
  5898. foreach ($this->getListeners($event) as $listener) {
  5899. $response = call_user_func_array($listener, $payload);
  5900. if (!is_null($response) && $halt) {
  5901. array_pop($this->firing);
  5902. return $response;
  5903. }
  5904. if ($response === false) {
  5905. break;
  5906. }
  5907. $responses[] = $response;
  5908. }
  5909. array_pop($this->firing);
  5910. return $halt ? null : $responses;
  5911. }
  5912. public function getListeners($eventName)
  5913. {
  5914. $wildcards = $this->getWildcardListeners($eventName);
  5915. if (!isset($this->sorted[$eventName])) {
  5916. $this->sortListeners($eventName);
  5917. }
  5918. return array_merge($this->sorted[$eventName], $wildcards);
  5919. }
  5920. protected function getWildcardListeners($eventName)
  5921. {
  5922. $wildcards = array();
  5923. foreach ($this->wildcards as $key => $listeners) {
  5924. if (str_is($key, $eventName)) {
  5925. $wildcards = array_merge($wildcards, $listeners);
  5926. }
  5927. }
  5928. return $wildcards;
  5929. }
  5930. protected function sortListeners($eventName)
  5931. {
  5932. $this->sorted[$eventName] = array();
  5933. if (isset($this->listeners[$eventName])) {
  5934. krsort($this->listeners[$eventName]);
  5935. $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
  5936. }
  5937. }
  5938. public function makeListener($listener)
  5939. {
  5940. if (is_string($listener)) {
  5941. $listener = $this->createClassListener($listener);
  5942. }
  5943. return $listener;
  5944. }
  5945. public function createClassListener($listener)
  5946. {
  5947. $container = $this->container;
  5948. return function () use($listener, $container) {
  5949. $segments = explode('@', $listener);
  5950. $method = count($segments) == 2 ? $segments[1] : 'handle';
  5951. $callable = array($container->make($segments[0]), $method);
  5952. $data = func_get_args();
  5953. return call_user_func_array($callable, $data);
  5954. };
  5955. }
  5956. public function forget($event)
  5957. {
  5958. unset($this->listeners[$event]);
  5959. unset($this->sorted[$event]);
  5960. }
  5961. }
  5962. namespace Illuminate\Database\Eloquent;
  5963. use DateTime;
  5964. use ArrayAccess;
  5965. use Carbon\Carbon;
  5966. use LogicException;
  5967. use JsonSerializable;
  5968. use Illuminate\Events\Dispatcher;
  5969. use Illuminate\Database\Eloquent\Relations\Pivot;
  5970. use Illuminate\Database\Eloquent\Relations\HasOne;
  5971. use Illuminate\Database\Eloquent\Relations\HasMany;
  5972. use Illuminate\Database\Eloquent\Relations\MorphTo;
  5973. use Illuminate\Support\Contracts\JsonableInterface;
  5974. use Illuminate\Support\Contracts\ArrayableInterface;
  5975. use Illuminate\Database\Eloquent\Relations\Relation;
  5976. use Illuminate\Database\Eloquent\Relations\MorphOne;
  5977. use Illuminate\Database\Eloquent\Relations\MorphMany;
  5978. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  5979. use Illuminate\Database\Query\Builder as QueryBuilder;
  5980. use Illuminate\Database\Eloquent\Relations\MorphToMany;
  5981. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  5982. use Illuminate\Database\Eloquent\Relations\HasManyThrough;
  5983. use Illuminate\Database\ConnectionResolverInterface as Resolver;
  5984. abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterface, JsonSerializable
  5985. {
  5986. protected $connection;
  5987. protected $table;
  5988. protected $primaryKey = 'id';
  5989. protected $perPage = 15;
  5990. public $incrementing = true;
  5991. public $timestamps = true;
  5992. protected $attributes = array();
  5993. protected $original = array();
  5994. protected $relations = array();
  5995. protected $hidden = array();
  5996. protected $visible = array();
  5997. protected $appends = array();
  5998. protected $fillable = array();
  5999. protected $guarded = array('*');
  6000. protected $dates = array();
  6001. protected $touches = array();
  6002. protected $observables = array();
  6003. protected $with = array();
  6004. protected $morphClass;
  6005. public $exists = false;
  6006. public static $snakeAttributes = true;
  6007. protected static $resolver;
  6008. protected static $dispatcher;
  6009. protected static $booted = array();
  6010. protected static $globalScopes = array();
  6011. protected static $unguarded = false;
  6012. protected static $mutatorCache = array();
  6013. public static $manyMethods = array('belongsToMany', 'morphToMany', 'morphedByMany');
  6014. const CREATED_AT = 'created_at';
  6015. const UPDATED_AT = 'updated_at';
  6016. public function __construct(array $attributes = array())
  6017. {
  6018. $this->bootIfNotBooted();
  6019. $this->syncOriginal();
  6020. $this->fill($attributes);
  6021. }
  6022. protected function bootIfNotBooted()
  6023. {
  6024. if (!isset(static::$booted[get_class($this)])) {
  6025. static::$booted[get_class($this)] = true;
  6026. $this->fireModelEvent('booting', false);
  6027. static::boot();
  6028. $this->fireModelEvent('booted', false);
  6029. }
  6030. }
  6031. protected static function boot()
  6032. {
  6033. $class = get_called_class();
  6034. static::$mutatorCache[$class] = array();
  6035. foreach (get_class_methods($class) as $method) {
  6036. if (preg_match('/^get(.+)Attribute$/', $method, $matches)) {
  6037. if (static::$snakeAttributes) {
  6038. $matches[1] = snake_case($matches[1]);
  6039. }
  6040. static::$mutatorCache[$class][] = lcfirst($matches[1]);
  6041. }
  6042. }
  6043. static::bootTraits();
  6044. }
  6045. protected static function bootTraits()
  6046. {
  6047. foreach (class_uses(get_called_class()) as $trait) {
  6048. if (method_exists(get_called_class(), $method = 'boot' . class_basename($trait))) {
  6049. forward_static_call(array(get_called_class(), $method));
  6050. }
  6051. }
  6052. }
  6053. public static function addGlobalScope(ScopeInterface $scope)
  6054. {
  6055. static::$globalScopes[get_called_class()][get_class($scope)] = $scope;
  6056. }
  6057. public static function hasGlobalScope($scope)
  6058. {
  6059. return !is_null(static::getGlobalScope($scope));
  6060. }
  6061. public static function getGlobalScope($scope)
  6062. {
  6063. return array_first(static::$globalScopes[get_called_class()], function ($key, $value) use($scope) {
  6064. return $scope instanceof $value;
  6065. });
  6066. }
  6067. public function getGlobalScopes()
  6068. {
  6069. return array_get(static::$globalScopes, get_class($this), array());
  6070. }
  6071. public static function observe($class)
  6072. {
  6073. $instance = new static();
  6074. $className = get_class($class);
  6075. foreach ($instance->getObservableEvents() as $event) {
  6076. if (method_exists($class, $event)) {
  6077. static::registerModelEvent($event, $className . '@' . $event);
  6078. }
  6079. }
  6080. }
  6081. public function fill(array $attributes)
  6082. {
  6083. $totallyGuarded = $this->totallyGuarded();
  6084. foreach ($this->fillableFromArray($attributes) as $key => $value) {
  6085. $key = $this->removeTableFromKey($key);
  6086. if ($this->isFillable($key)) {
  6087. $this->setAttribute($key, $value);
  6088. } elseif ($totallyGuarded) {
  6089. throw new MassAssignmentException($key);
  6090. }
  6091. }
  6092. return $this;
  6093. }
  6094. protected function fillableFromArray(array $attributes)
  6095. {
  6096. if (count($this->fillable) > 0 && !static::$unguarded) {
  6097. return array_intersect_key($attributes, array_flip($this->fillable));
  6098. }
  6099. return $attributes;
  6100. }
  6101. public function newInstance($attributes = array(), $exists = false)
  6102. {
  6103. $model = new static((array) $attributes);
  6104. $model->exists = $exists;
  6105. return $model;
  6106. }
  6107. public function newFromBuilder($attributes = array())
  6108. {
  6109. $instance = $this->newInstance(array(), true);
  6110. $instance->setRawAttributes((array) $attributes, true);
  6111. return $instance;
  6112. }
  6113. public static function hydrate(array $items, $connection = null)
  6114. {
  6115. $collection = with($instance = new static())->newCollection();
  6116. foreach ($items as $item) {
  6117. $model = $instance->newFromBuilder($item);
  6118. if (!is_null($connection)) {
  6119. $model->setConnection($connection);
  6120. }
  6121. $collection->push($model);
  6122. }
  6123. return $collection;
  6124. }
  6125. public static function hydrateRaw($query, $bindings = array(), $connection = null)
  6126. {
  6127. $instance = new static();
  6128. if (!is_null($connection)) {
  6129. $instance->setConnection($connection);
  6130. }
  6131. $items = $instance->getConnection()->select($query, $bindings);
  6132. return static::hydrate($items, $connection);
  6133. }
  6134. public static function create(array $attributes)
  6135. {
  6136. $model = new static($attributes);
  6137. $model->save();
  6138. return $model;
  6139. }
  6140. public static function firstOrCreate(array $attributes)
  6141. {
  6142. if (!is_null($instance = static::firstByAttributes($attributes))) {
  6143. return $instance;
  6144. }
  6145. return static::create($attributes);
  6146. }
  6147. public static function firstOrNew(array $attributes)
  6148. {
  6149. if (!is_null($instance = static::firstByAttributes($attributes))) {
  6150. return $instance;
  6151. }
  6152. return new static($attributes);
  6153. }
  6154. protected static function firstByAttributes($attributes)
  6155. {
  6156. $query = static::query();
  6157. foreach ($attributes as $key => $value) {
  6158. $query->where($key, $value);
  6159. }
  6160. return $query->first() ?: null;
  6161. }
  6162. public static function query()
  6163. {
  6164. return with(new static())->newQuery();
  6165. }
  6166. public static function on($connection = null)
  6167. {
  6168. $instance = new static();
  6169. $instance->setConnection($connection);
  6170. return $instance->newQuery();
  6171. }
  6172. public static function all($columns = array('*'))
  6173. {
  6174. $instance = new static();
  6175. return $instance->newQuery()->get($columns);
  6176. }
  6177. public static function find($id, $columns = array('*'))
  6178. {
  6179. if (is_array($id) && empty($id)) {
  6180. return new Collection();
  6181. }
  6182. $instance = new static();
  6183. return $instance->newQuery()->find($id, $columns);
  6184. }
  6185. public static function findOrNew($id, $columns = array('*'))
  6186. {
  6187. if (!is_null($model = static::find($id, $columns))) {
  6188. return $model;
  6189. }
  6190. return new static($columns);
  6191. }
  6192. public static function findOrFail($id, $columns = array('*'))
  6193. {
  6194. if (!is_null($model = static::find($id, $columns))) {
  6195. return $model;
  6196. }
  6197. throw with(new ModelNotFoundException())->setModel(get_called_class());
  6198. }
  6199. public function load($relations)
  6200. {
  6201. if (is_string($relations)) {
  6202. $relations = func_get_args();
  6203. }
  6204. $query = $this->newQuery()->with($relations);
  6205. $query->eagerLoadRelations(array($this));
  6206. return $this;
  6207. }
  6208. public static function with($relations)
  6209. {
  6210. if (is_string($relations)) {
  6211. $relations = func_get_args();
  6212. }
  6213. $instance = new static();
  6214. return $instance->newQuery()->with($relations);
  6215. }
  6216. public function hasOne($related, $foreignKey = null, $localKey = null)
  6217. {
  6218. $foreignKey = $foreignKey ?: $this->getForeignKey();
  6219. $instance = new $related();
  6220. $localKey = $localKey ?: $this->getKeyName();
  6221. return new HasOne($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey, $localKey);
  6222. }
  6223. public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
  6224. {
  6225. $instance = new $related();
  6226. list($type, $id) = $this->getMorphs($name, $type, $id);
  6227. $table = $instance->getTable();
  6228. $localKey = $localKey ?: $this->getKeyName();
  6229. return new MorphOne($instance->newQuery(), $this, $table . '.' . $type, $table . '.' . $id, $localKey);
  6230. }
  6231. public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
  6232. {
  6233. if (is_null($relation)) {
  6234. list(, $caller) = debug_backtrace(false);
  6235. $relation = $caller['function'];
  6236. }
  6237. if (is_null($foreignKey)) {
  6238. $foreignKey = snake_case($relation) . '_id';
  6239. }
  6240. $instance = new $related();
  6241. $query = $instance->newQuery();
  6242. $otherKey = $otherKey ?: $instance->getKeyName();
  6243. return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
  6244. }
  6245. public function morphTo($name = null, $type = null, $id = null)
  6246. {
  6247. if (is_null($name)) {
  6248. list(, $caller) = debug_backtrace(false);
  6249. $name = snake_case($caller['function']);
  6250. }
  6251. list($type, $id) = $this->getMorphs($name, $type, $id);
  6252. if (is_null($class = $this->{$type})) {
  6253. return new MorphTo($this->newQuery(), $this, $id, null, $type, $name);
  6254. } else {
  6255. $instance = new $class();
  6256. return new MorphTo(with($instance)->newQuery(), $this, $id, $instance->getKeyName(), $type, $name);
  6257. }
  6258. }
  6259. public function hasMany($related, $foreignKey = null, $localKey = null)
  6260. {
  6261. $foreignKey = $foreignKey ?: $this->getForeignKey();
  6262. $instance = new $related();
  6263. $localKey = $localKey ?: $this->getKeyName();
  6264. return new HasMany($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey, $localKey);
  6265. }
  6266. public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null)
  6267. {
  6268. $through = new $through();
  6269. $firstKey = $firstKey ?: $this->getForeignKey();
  6270. $secondKey = $secondKey ?: $through->getForeignKey();
  6271. return new HasManyThrough(with(new $related())->newQuery(), $this, $through, $firstKey, $secondKey);
  6272. }
  6273. public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
  6274. {
  6275. $instance = new $related();
  6276. list($type, $id) = $this->getMorphs($name, $type, $id);
  6277. $table = $instance->getTable();
  6278. $localKey = $localKey ?: $this->getKeyName();
  6279. return new MorphMany($instance->newQuery(), $this, $table . '.' . $type, $table . '.' . $id, $localKey);
  6280. }
  6281. public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
  6282. {
  6283. if (is_null($relation)) {
  6284. $relation = $this->getBelongsToManyCaller();
  6285. }
  6286. $foreignKey = $foreignKey ?: $this->getForeignKey();
  6287. $instance = new $related();
  6288. $otherKey = $otherKey ?: $instance->getForeignKey();
  6289. if (is_null($table)) {
  6290. $table = $this->joiningTable($related);
  6291. }
  6292. $query = $instance->newQuery();
  6293. return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation);
  6294. }
  6295. public function morphToMany($related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
  6296. {
  6297. $caller = $this->getBelongsToManyCaller();
  6298. $foreignKey = $foreignKey ?: $name . '_id';
  6299. $instance = new $related();
  6300. $otherKey = $otherKey ?: $instance->getForeignKey();
  6301. $query = $instance->newQuery();
  6302. $table = $table ?: str_plural($name);
  6303. return new MorphToMany($query, $this, $name, $table, $foreignKey, $otherKey, $caller, $inverse);
  6304. }
  6305. public function morphedByMany($related, $name, $table = null, $foreignKey = null, $otherKey = null)
  6306. {
  6307. $foreignKey = $foreignKey ?: $this->getForeignKey();
  6308. $otherKey = $otherKey ?: $name . '_id';
  6309. return $this->morphToMany($related, $name, $table, $foreignKey, $otherKey, true);
  6310. }
  6311. protected function getBelongsToManyCaller()
  6312. {
  6313. $self = __FUNCTION__;
  6314. $caller = array_first(debug_backtrace(false), function ($key, $trace) use($self) {
  6315. $caller = $trace['function'];
  6316. return !in_array($caller, Model::$manyMethods) && $caller != $self;
  6317. });
  6318. return !is_null($caller) ? $caller['function'] : null;
  6319. }
  6320. public function joiningTable($related)
  6321. {
  6322. $base = snake_case(class_basename($this));
  6323. $related = snake_case(class_basename($related));
  6324. $models = array($related, $base);
  6325. sort($models);
  6326. return strtolower(implode('_', $models));
  6327. }
  6328. public static function destroy($ids)
  6329. {
  6330. $count = 0;
  6331. $ids = is_array($ids) ? $ids : func_get_args();
  6332. $instance = new static();
  6333. $key = $instance->getKeyName();
  6334. foreach ($instance->whereIn($key, $ids)->get() as $model) {
  6335. if ($model->delete()) {
  6336. $count++;
  6337. }
  6338. }
  6339. return $count;
  6340. }
  6341. public function delete()
  6342. {
  6343. if (is_null($this->primaryKey)) {
  6344. throw new \Exception('No primary key defined on model.');
  6345. }
  6346. if ($this->exists) {
  6347. if ($this->fireModelEvent('deleting') === false) {
  6348. return false;
  6349. }
  6350. $this->touchOwners();
  6351. $this->performDeleteOnModel();
  6352. $this->exists = false;
  6353. $this->fireModelEvent('deleted', false);
  6354. return true;
  6355. }
  6356. }
  6357. protected function performDeleteOnModel()
  6358. {
  6359. $this->newQuery()->where($this->getKeyName(), $this->getKey())->delete();
  6360. }
  6361. public static function saving($callback)
  6362. {
  6363. static::registerModelEvent('saving', $callback);
  6364. }
  6365. public static function saved($callback)
  6366. {
  6367. static::registerModelEvent('saved', $callback);
  6368. }
  6369. public static function updating($callback)
  6370. {
  6371. static::registerModelEvent('updating', $callback);
  6372. }
  6373. public static function updated($callback)
  6374. {
  6375. static::registerModelEvent('updated', $callback);
  6376. }
  6377. public static function creating($callback)
  6378. {
  6379. static::registerModelEvent('creating', $callback);
  6380. }
  6381. public static function created($callback)
  6382. {
  6383. static::registerModelEvent('created', $callback);
  6384. }
  6385. public static function deleting($callback)
  6386. {
  6387. static::registerModelEvent('deleting', $callback);
  6388. }
  6389. public static function deleted($callback)
  6390. {
  6391. static::registerModelEvent('deleted', $callback);
  6392. }
  6393. public static function flushEventListeners()
  6394. {
  6395. if (!isset(static::$dispatcher)) {
  6396. return;
  6397. }
  6398. $instance = new static();
  6399. foreach ($instance->getObservableEvents() as $event) {
  6400. static::$dispatcher->forget("eloquent.{$event}: " . get_called_class());
  6401. }
  6402. }
  6403. protected static function registerModelEvent($event, $callback)
  6404. {
  6405. if (isset(static::$dispatcher)) {
  6406. $name = get_called_class();
  6407. static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback);
  6408. }
  6409. }
  6410. public function getObservableEvents()
  6411. {
  6412. return array_merge(array('creating', 'created', 'updating', 'updated', 'deleting', 'deleted', 'saving', 'saved', 'restoring', 'restored'), $this->observables);
  6413. }
  6414. protected function increment($column, $amount = 1)
  6415. {
  6416. return $this->incrementOrDecrement($column, $amount, 'increment');
  6417. }
  6418. protected function decrement($column, $amount = 1)
  6419. {
  6420. return $this->incrementOrDecrement($column, $amount, 'decrement');
  6421. }
  6422. protected function incrementOrDecrement($column, $amount, $method)
  6423. {
  6424. $query = $this->newQuery();
  6425. if (!$this->exists) {
  6426. return $query->{$method}($column, $amount);
  6427. }
  6428. return $query->where($this->getKeyName(), $this->getKey())->{$method}($column, $amount);
  6429. }
  6430. public function update(array $attributes = array())
  6431. {
  6432. if (!$this->exists) {
  6433. return $this->newQuery()->update($attributes);
  6434. }
  6435. return $this->fill($attributes)->save();
  6436. }
  6437. public function push()
  6438. {
  6439. if (!$this->save()) {
  6440. return false;
  6441. }
  6442. foreach ($this->relations as $models) {
  6443. foreach (Collection::make($models) as $model) {
  6444. if (!$model->push()) {
  6445. return false;
  6446. }
  6447. }
  6448. }
  6449. return true;
  6450. }
  6451. public function save(array $options = array())
  6452. {
  6453. $query = $this->newQueryWithoutScopes();
  6454. if ($this->fireModelEvent('saving') === false) {
  6455. return false;
  6456. }
  6457. if ($this->exists) {
  6458. $saved = $this->performUpdate($query);
  6459. } else {
  6460. $saved = $this->performInsert($query);
  6461. }
  6462. if ($saved) {
  6463. $this->finishSave($options);
  6464. }
  6465. return $saved;
  6466. }
  6467. protected function finishSave(array $options)
  6468. {
  6469. $this->syncOriginal();
  6470. $this->fireModelEvent('saved', false);
  6471. if (array_get($options, 'touch', true)) {
  6472. $this->touchOwners();
  6473. }
  6474. }
  6475. protected function performUpdate(Builder $query)
  6476. {
  6477. $dirty = $this->getDirty();
  6478. if (count($dirty) > 0) {
  6479. if ($this->fireModelEvent('updating') === false) {
  6480. return false;
  6481. }
  6482. if ($this->timestamps) {
  6483. $this->updateTimestamps();
  6484. }
  6485. $dirty = $this->getDirty();
  6486. if (count($dirty) > 0) {
  6487. $this->setKeysForSaveQuery($query)->update($dirty);
  6488. $this->fireModelEvent('updated', false);
  6489. }
  6490. }
  6491. return true;
  6492. }
  6493. protected function performInsert(Builder $query)
  6494. {
  6495. if ($this->fireModelEvent('creating') === false) {
  6496. return false;
  6497. }
  6498. if ($this->timestamps) {
  6499. $this->updateTimestamps();
  6500. }
  6501. $attributes = $this->attributes;
  6502. if ($this->incrementing) {
  6503. $this->insertAndSetId($query, $attributes);
  6504. } else {
  6505. $query->insert($attributes);
  6506. }
  6507. $this->exists = true;
  6508. $this->fireModelEvent('created', false);
  6509. return true;
  6510. }
  6511. protected function insertAndSetId(Builder $query, $attributes)
  6512. {
  6513. $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
  6514. $this->setAttribute($keyName, $id);
  6515. }
  6516. public function touchOwners()
  6517. {
  6518. foreach ($this->touches as $relation) {
  6519. $this->{$relation}()->touch();
  6520. }
  6521. }
  6522. public function touches($relation)
  6523. {
  6524. return in_array($relation, $this->touches);
  6525. }
  6526. protected function fireModelEvent($event, $halt = true)
  6527. {
  6528. if (!isset(static::$dispatcher)) {
  6529. return true;
  6530. }
  6531. $event = "eloquent.{$event}: " . get_class($this);
  6532. $method = $halt ? 'until' : 'fire';
  6533. return static::$dispatcher->{$method}($event, $this);
  6534. }
  6535. protected function setKeysForSaveQuery(Builder $query)
  6536. {
  6537. $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
  6538. return $query;
  6539. }
  6540. protected function getKeyForSaveQuery()
  6541. {
  6542. if (isset($this->original[$this->getKeyName()])) {
  6543. return $this->original[$this->getKeyName()];
  6544. } else {
  6545. return $this->getAttribute($this->getKeyName());
  6546. }
  6547. }
  6548. public function touch()
  6549. {
  6550. $this->updateTimestamps();
  6551. return $this->save();
  6552. }
  6553. protected function updateTimestamps()
  6554. {
  6555. $time = $this->freshTimestamp();
  6556. if (!$this->isDirty(static::UPDATED_AT)) {
  6557. $this->setUpdatedAt($time);
  6558. }
  6559. if (!$this->exists && !$this->isDirty(static::CREATED_AT)) {
  6560. $this->setCreatedAt($time);
  6561. }
  6562. }
  6563. public function setCreatedAt($value)
  6564. {
  6565. $this->{static::CREATED_AT} = $value;
  6566. }
  6567. public function setUpdatedAt($value)
  6568. {
  6569. $this->{static::UPDATED_AT} = $value;
  6570. }
  6571. public function getCreatedAtColumn()
  6572. {
  6573. return static::CREATED_AT;
  6574. }
  6575. public function getUpdatedAtColumn()
  6576. {
  6577. return static::UPDATED_AT;
  6578. }
  6579. public function freshTimestamp()
  6580. {
  6581. return new Carbon();
  6582. }
  6583. public function freshTimestampString()
  6584. {
  6585. return $this->fromDateTime($this->freshTimestamp());
  6586. }
  6587. public function newQuery()
  6588. {
  6589. $builder = $this->newEloquentBuilder($this->newBaseQueryBuilder());
  6590. $builder->setModel($this)->with($this->with);
  6591. return $this->applyGlobalScopes($builder);
  6592. }
  6593. public function newQueryWithoutScope($scope)
  6594. {
  6595. $this->getGlobalScope($scope)->remove($builder = $this->newQuery(), $this);
  6596. return $builder;
  6597. }
  6598. public function newQueryWithoutScopes()
  6599. {
  6600. return $this->removeGlobalScopes($this->newQuery());
  6601. }
  6602. public function applyGlobalScopes($builder)
  6603. {
  6604. foreach ($this->getGlobalScopes() as $scope) {
  6605. $scope->apply($builder, $this);
  6606. }
  6607. return $builder;
  6608. }
  6609. public function removeGlobalScopes($builder)
  6610. {
  6611. foreach ($this->getGlobalScopes() as $scope) {
  6612. $scope->remove($builder, $this);
  6613. }
  6614. return $builder;
  6615. }
  6616. public function newEloquentBuilder($query)
  6617. {
  6618. return new Builder($query);
  6619. }
  6620. protected function newBaseQueryBuilder()
  6621. {
  6622. $conn = $this->getConnection();
  6623. $grammar = $conn->getQueryGrammar();
  6624. return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
  6625. }
  6626. public function newCollection(array $models = array())
  6627. {
  6628. return new Collection($models);
  6629. }
  6630. public function newPivot(Model $parent, array $attributes, $table, $exists)
  6631. {
  6632. return new Pivot($parent, $attributes, $table, $exists);
  6633. }
  6634. public function getTable()
  6635. {
  6636. if (isset($this->table)) {
  6637. return $this->table;
  6638. }
  6639. return str_replace('\\', '', snake_case(str_plural(class_basename($this))));
  6640. }
  6641. public function setTable($table)
  6642. {
  6643. $this->table = $table;
  6644. }
  6645. public function getKey()
  6646. {
  6647. return $this->getAttribute($this->getKeyName());
  6648. }
  6649. public function getKeyName()
  6650. {
  6651. return $this->primaryKey;
  6652. }
  6653. public function getQualifiedKeyName()
  6654. {
  6655. return $this->getTable() . '.' . $this->getKeyName();
  6656. }
  6657. public function usesTimestamps()
  6658. {
  6659. return $this->timestamps;
  6660. }
  6661. protected function getMorphs($name, $type, $id)
  6662. {
  6663. $type = $type ?: $name . '_type';
  6664. $id = $id ?: $name . '_id';
  6665. return array($type, $id);
  6666. }
  6667. public function getMorphClass()
  6668. {
  6669. return $this->morphClass ?: get_class($this);
  6670. }
  6671. public function getPerPage()
  6672. {
  6673. return $this->perPage;
  6674. }
  6675. public function setPerPage($perPage)
  6676. {
  6677. $this->perPage = $perPage;
  6678. }
  6679. public function getForeignKey()
  6680. {
  6681. return snake_case(class_basename($this)) . '_id';
  6682. }
  6683. public function getHidden()
  6684. {
  6685. return $this->hidden;
  6686. }
  6687. public function setHidden(array $hidden)
  6688. {
  6689. $this->hidden = $hidden;
  6690. }
  6691. public function setVisible(array $visible)
  6692. {
  6693. $this->visible = $visible;
  6694. }
  6695. public function setAppends(array $appends)
  6696. {
  6697. $this->appends = $appends;
  6698. }
  6699. public function getFillable()
  6700. {
  6701. return $this->fillable;
  6702. }
  6703. public function fillable(array $fillable)
  6704. {
  6705. $this->fillable = $fillable;
  6706. return $this;
  6707. }
  6708. public function guard(array $guarded)
  6709. {
  6710. $this->guarded = $guarded;
  6711. return $this;
  6712. }
  6713. public static function unguard()
  6714. {
  6715. static::$unguarded = true;
  6716. }
  6717. public static function reguard()
  6718. {
  6719. static::$unguarded = false;
  6720. }
  6721. public static function setUnguardState($state)
  6722. {
  6723. static::$unguarded = $state;
  6724. }
  6725. public function isFillable($key)
  6726. {
  6727. if (static::$unguarded) {
  6728. return true;
  6729. }
  6730. if (in_array($key, $this->fillable)) {
  6731. return true;
  6732. }
  6733. if ($this->isGuarded($key)) {
  6734. return false;
  6735. }
  6736. return empty($this->fillable) && !starts_with($key, '_');
  6737. }
  6738. public function isGuarded($key)
  6739. {
  6740. return in_array($key, $this->guarded) || $this->guarded == array('*');
  6741. }
  6742. public function totallyGuarded()
  6743. {
  6744. return count($this->fillable) == 0 && $this->guarded == array('*');
  6745. }
  6746. protected function removeTableFromKey($key)
  6747. {
  6748. if (!str_contains($key, '.')) {
  6749. return $key;
  6750. }
  6751. return last(explode('.', $key));
  6752. }
  6753. public function getTouchedRelations()
  6754. {
  6755. return $this->touches;
  6756. }
  6757. public function setTouchedRelations(array $touches)
  6758. {
  6759. $this->touches = $touches;
  6760. }
  6761. public function getIncrementing()
  6762. {
  6763. return $this->incrementing;
  6764. }
  6765. public function setIncrementing($value)
  6766. {
  6767. $this->incrementing = $value;
  6768. }
  6769. public function toJson($options = 0)
  6770. {
  6771. return json_encode($this->toArray(), $options);
  6772. }
  6773. public function jsonSerialize()
  6774. {
  6775. return $this->toArray();
  6776. }
  6777. public function toArray()
  6778. {
  6779. $attributes = $this->attributesToArray();
  6780. return array_merge($attributes, $this->relationsToArray());
  6781. }
  6782. public function attributesToArray()
  6783. {
  6784. $attributes = $this->getArrayableAttributes();
  6785. foreach ($this->getDates() as $key) {
  6786. if (!isset($attributes[$key])) {
  6787. continue;
  6788. }
  6789. $attributes[$key] = (string) $this->asDateTime($attributes[$key]);
  6790. }
  6791. foreach ($this->getMutatedAttributes() as $key) {
  6792. if (!array_key_exists($key, $attributes)) {
  6793. continue;
  6794. }
  6795. $attributes[$key] = $this->mutateAttributeForArray($key, $attributes[$key]);
  6796. }
  6797. foreach ($this->appends as $key) {
  6798. $attributes[$key] = $this->mutateAttributeForArray($key, null);
  6799. }
  6800. return $attributes;
  6801. }
  6802. protected function getArrayableAttributes()
  6803. {
  6804. return $this->getArrayableItems($this->attributes);
  6805. }
  6806. public function relationsToArray()
  6807. {
  6808. $attributes = array();
  6809. foreach ($this->getArrayableRelations() as $key => $value) {
  6810. if (in_array($key, $this->hidden)) {
  6811. continue;
  6812. }
  6813. if ($value instanceof ArrayableInterface) {
  6814. $relation = $value->toArray();
  6815. } elseif (is_null($value)) {
  6816. $relation = $value;
  6817. }
  6818. if (static::$snakeAttributes) {
  6819. $key = snake_case($key);
  6820. }
  6821. if (isset($relation) || is_null($value)) {
  6822. $attributes[$key] = $relation;
  6823. }
  6824. }
  6825. return $attributes;
  6826. }
  6827. protected function getArrayableRelations()
  6828. {
  6829. return $this->getArrayableItems($this->relations);
  6830. }
  6831. protected function getArrayableItems(array $values)
  6832. {
  6833. if (count($this->visible) > 0) {
  6834. return array_intersect_key($values, array_flip($this->visible));
  6835. }
  6836. return array_diff_key($values, array_flip($this->hidden));
  6837. }
  6838. public function getAttribute($key)
  6839. {
  6840. $inAttributes = array_key_exists($key, $this->attributes);
  6841. if ($inAttributes || $this->hasGetMutator($key)) {
  6842. return $this->getAttributeValue($key);
  6843. }
  6844. if (array_key_exists($key, $this->relations)) {
  6845. return $this->relations[$key];
  6846. }
  6847. $camelKey = camel_case($key);
  6848. if (method_exists($this, $camelKey)) {
  6849. return $this->getRelationshipFromMethod($key, $camelKey);
  6850. }
  6851. }
  6852. protected function getAttributeValue($key)
  6853. {
  6854. $value = $this->getAttributeFromArray($key);
  6855. if ($this->hasGetMutator($key)) {
  6856. return $this->mutateAttribute($key, $value);
  6857. } elseif (in_array($key, $this->getDates())) {
  6858. if ($value) {
  6859. return $this->asDateTime($value);
  6860. }
  6861. }
  6862. return $value;
  6863. }
  6864. protected function getAttributeFromArray($key)
  6865. {
  6866. if (array_key_exists($key, $this->attributes)) {
  6867. return $this->attributes[$key];
  6868. }
  6869. }
  6870. protected function getRelationshipFromMethod($key, $camelKey)
  6871. {
  6872. $relations = $this->{$camelKey}();
  6873. if (!$relations instanceof Relation) {
  6874. throw new LogicException('Relationship method must return an object of type ' . 'Illuminate\\Database\\Eloquent\\Relations\\Relation');
  6875. }
  6876. return $this->relations[$key] = $relations->getResults();
  6877. }
  6878. public function hasGetMutator($key)
  6879. {
  6880. return method_exists($this, 'get' . studly_case($key) . 'Attribute');
  6881. }
  6882. protected function mutateAttribute($key, $value)
  6883. {
  6884. return $this->{'get' . studly_case($key) . 'Attribute'}($value);
  6885. }
  6886. protected function mutateAttributeForArray($key, $value)
  6887. {
  6888. $value = $this->mutateAttribute($key, $value);
  6889. return $value instanceof ArrayableInterface ? $value->toArray() : $value;
  6890. }
  6891. public function setAttribute($key, $value)
  6892. {
  6893. if ($this->hasSetMutator($key)) {
  6894. $method = 'set' . studly_case($key) . 'Attribute';
  6895. return $this->{$method}($value);
  6896. } elseif (in_array($key, $this->getDates())) {
  6897. if ($value) {
  6898. $value = $this->fromDateTime($value);
  6899. }
  6900. }
  6901. $this->attributes[$key] = $value;
  6902. }
  6903. public function hasSetMutator($key)
  6904. {
  6905. return method_exists($this, 'set' . studly_case($key) . 'Attribute');
  6906. }
  6907. public function getDates()
  6908. {
  6909. $defaults = array(static::CREATED_AT, static::UPDATED_AT);
  6910. return array_merge($this->dates, $defaults);
  6911. }
  6912. public function fromDateTime($value)
  6913. {
  6914. $format = $this->getDateFormat();
  6915. if ($value instanceof DateTime) {
  6916. } elseif (is_numeric($value)) {
  6917. $value = Carbon::createFromTimestamp($value);
  6918. } elseif (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value)) {
  6919. $value = Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
  6920. } elseif (!$value instanceof DateTime) {
  6921. $value = Carbon::createFromFormat($format, $value);
  6922. }
  6923. return $value->format($format);
  6924. }
  6925. protected function asDateTime($value)
  6926. {
  6927. if (is_numeric($value)) {
  6928. return Carbon::createFromTimestamp($value);
  6929. } elseif (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value)) {
  6930. return Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
  6931. } elseif (!$value instanceof DateTime) {
  6932. $format = $this->getDateFormat();
  6933. return Carbon::createFromFormat($format, $value);
  6934. }
  6935. return Carbon::instance($value);
  6936. }
  6937. protected function getDateFormat()
  6938. {
  6939. return $this->getConnection()->getQueryGrammar()->getDateFormat();
  6940. }
  6941. public function replicate()
  6942. {
  6943. $attributes = array_except($this->attributes, array($this->getKeyName()));
  6944. with($instance = new static())->setRawAttributes($attributes);
  6945. return $instance->setRelations($this->relations);
  6946. }
  6947. public function getAttributes()
  6948. {
  6949. return $this->attributes;
  6950. }
  6951. public function setRawAttributes(array $attributes, $sync = false)
  6952. {
  6953. $this->attributes = $attributes;
  6954. if ($sync) {
  6955. $this->syncOriginal();
  6956. }
  6957. }
  6958. public function getOriginal($key = null, $default = null)
  6959. {
  6960. return array_get($this->original, $key, $default);
  6961. }
  6962. public function syncOriginal()
  6963. {
  6964. $this->original = $this->attributes;
  6965. return $this;
  6966. }
  6967. public function isDirty($attribute = null)
  6968. {
  6969. $dirty = $this->getDirty();
  6970. if (is_null($attribute)) {
  6971. return count($dirty) > 0;
  6972. } else {
  6973. return array_key_exists($attribute, $dirty);
  6974. }
  6975. }
  6976. public function getDirty()
  6977. {
  6978. $dirty = array();
  6979. foreach ($this->attributes as $key => $value) {
  6980. if (!array_key_exists($key, $this->original)) {
  6981. $dirty[$key] = $value;
  6982. } elseif ($value !== $this->original[$key] && !$this->originalIsNumericallyEquivalent($key)) {
  6983. $dirty[$key] = $value;
  6984. }
  6985. }
  6986. return $dirty;
  6987. }
  6988. protected function originalIsNumericallyEquivalent($key)
  6989. {
  6990. $current = $this->attributes[$key];
  6991. $original = $this->original[$key];
  6992. return is_numeric($current) && is_numeric($original) && strcmp((string) $current, (string) $original) === 0;
  6993. }
  6994. public function getRelations()
  6995. {
  6996. return $this->relations;
  6997. }
  6998. public function getRelation($relation)
  6999. {
  7000. return $this->relations[$relation];
  7001. }
  7002. public function setRelation($relation, $value)
  7003. {
  7004. $this->relations[$relation] = $value;
  7005. return $this;
  7006. }
  7007. public function setRelations(array $relations)
  7008. {
  7009. $this->relations = $relations;
  7010. return $this;
  7011. }
  7012. public function getConnection()
  7013. {
  7014. return static::resolveConnection($this->connection);
  7015. }
  7016. public function getConnectionName()
  7017. {
  7018. return $this->connection;
  7019. }
  7020. public function setConnection($name)
  7021. {
  7022. $this->connection = $name;
  7023. return $this;
  7024. }
  7025. public static function resolveConnection($connection = null)
  7026. {
  7027. return static::$resolver->connection($connection);
  7028. }
  7029. public static function getConnectionResolver()
  7030. {
  7031. return static::$resolver;
  7032. }
  7033. public static function setConnectionResolver(Resolver $resolver)
  7034. {
  7035. static::$resolver = $resolver;
  7036. }
  7037. public static function unsetConnectionResolver()
  7038. {
  7039. static::$resolver = null;
  7040. }
  7041. public static function getEventDispatcher()
  7042. {
  7043. return static::$dispatcher;
  7044. }
  7045. public static function setEventDispatcher(Dispatcher $dispatcher)
  7046. {
  7047. static::$dispatcher = $dispatcher;
  7048. }
  7049. public static function unsetEventDispatcher()
  7050. {
  7051. static::$dispatcher = null;
  7052. }
  7053. public function getMutatedAttributes()
  7054. {
  7055. $class = get_class($this);
  7056. if (isset(static::$mutatorCache[$class])) {
  7057. return static::$mutatorCache[get_class($this)];
  7058. }
  7059. return array();
  7060. }
  7061. public function __get($key)
  7062. {
  7063. return $this->getAttribute($key);
  7064. }
  7065. public function __set($key, $value)
  7066. {
  7067. $this->setAttribute($key, $value);
  7068. }
  7069. public function offsetExists($offset)
  7070. {
  7071. return isset($this->{$offset});
  7072. }
  7073. public function offsetGet($offset)
  7074. {
  7075. return $this->{$offset};
  7076. }
  7077. public function offsetSet($offset, $value)
  7078. {
  7079. $this->{$offset} = $value;
  7080. }
  7081. public function offsetUnset($offset)
  7082. {
  7083. unset($this->{$offset});
  7084. }
  7085. public function __isset($key)
  7086. {
  7087. return isset($this->attributes[$key]) || isset($this->relations[$key]) || $this->hasGetMutator($key) && !is_null($this->getAttributeValue($key));
  7088. }
  7089. public function __unset($key)
  7090. {
  7091. unset($this->attributes[$key]);
  7092. unset($this->relations[$key]);
  7093. }
  7094. public function __call($method, $parameters)
  7095. {
  7096. if (in_array($method, array('increment', 'decrement'))) {
  7097. return call_user_func_array(array($this, $method), $parameters);
  7098. }
  7099. $query = $this->newQuery();
  7100. return call_user_func_array(array($query, $method), $parameters);
  7101. }
  7102. public static function __callStatic($method, $parameters)
  7103. {
  7104. $instance = new static();
  7105. return call_user_func_array(array($instance, $method), $parameters);
  7106. }
  7107. public function __toString()
  7108. {
  7109. return $this->toJson();
  7110. }
  7111. public function __wakeup()
  7112. {
  7113. $this->bootIfNotBooted();
  7114. }
  7115. }
  7116. namespace Illuminate\Support\Contracts;
  7117. interface ArrayableInterface
  7118. {
  7119. public function toArray();
  7120. }
  7121. namespace Illuminate\Support\Contracts;
  7122. interface JsonableInterface
  7123. {
  7124. public function toJson($options = 0);
  7125. }
  7126. namespace Illuminate\Database;
  7127. use Illuminate\Database\Connectors\ConnectionFactory;
  7128. class DatabaseManager implements ConnectionResolverInterface
  7129. {
  7130. protected $app;
  7131. protected $factory;
  7132. protected $connections = array();
  7133. protected $extensions = array();
  7134. public function __construct($app, ConnectionFactory $factory)
  7135. {
  7136. $this->app = $app;
  7137. $this->factory = $factory;
  7138. }
  7139. public function connection($name = null)
  7140. {
  7141. $name = $name ?: $this->getDefaultConnection();
  7142. if (!isset($this->connections[$name])) {
  7143. $connection = $this->makeConnection($name);
  7144. $this->connections[$name] = $this->prepare($connection);
  7145. }
  7146. return $this->connections[$name];
  7147. }
  7148. public function reconnect($name = null)
  7149. {
  7150. $name = $name ?: $this->getDefaultConnection();
  7151. $this->disconnect($name);
  7152. return $this->connection($name);
  7153. }
  7154. public function disconnect($name = null)
  7155. {
  7156. $name = $name ?: $this->getDefaultConnection();
  7157. unset($this->connections[$name]);
  7158. }
  7159. protected function makeConnection($name)
  7160. {
  7161. $config = $this->getConfig($name);
  7162. if (isset($this->extensions[$name])) {
  7163. return call_user_func($this->extensions[$name], $config, $name);
  7164. }
  7165. $driver = $config['driver'];
  7166. if (isset($this->extensions[$driver])) {
  7167. return call_user_func($this->extensions[$driver], $config, $name);
  7168. }
  7169. return $this->factory->make($config, $name);
  7170. }
  7171. protected function prepare(Connection $connection)
  7172. {
  7173. $connection->setFetchMode($this->app['config']['database.fetch']);
  7174. if ($this->app->bound('events')) {
  7175. $connection->setEventDispatcher($this->app['events']);
  7176. }
  7177. $app = $this->app;
  7178. $connection->setCacheManager(function () use($app) {
  7179. return $app['cache'];
  7180. });
  7181. $connection->setPaginator(function () use($app) {
  7182. return $app['paginator'];
  7183. });
  7184. return $connection;
  7185. }
  7186. protected function getConfig($name)
  7187. {
  7188. $name = $name ?: $this->getDefaultConnection();
  7189. $connections = $this->app['config']['database.connections'];
  7190. if (is_null($config = array_get($connections, $name))) {
  7191. throw new \InvalidArgumentException("Database [{$name}] not configured.");
  7192. }
  7193. return $config;
  7194. }
  7195. public function getDefaultConnection()
  7196. {
  7197. return $this->app['config']['database.default'];
  7198. }
  7199. public function setDefaultConnection($name)
  7200. {
  7201. $this->app['config']['database.default'] = $name;
  7202. }
  7203. public function extend($name, $resolver)
  7204. {
  7205. $this->extensions[$name] = $resolver;
  7206. }
  7207. public function getConnections()
  7208. {
  7209. return $this->connections;
  7210. }
  7211. public function __call($method, $parameters)
  7212. {
  7213. return call_user_func_array(array($this->connection(), $method), $parameters);
  7214. }
  7215. }
  7216. namespace Illuminate\Database;
  7217. interface ConnectionResolverInterface
  7218. {
  7219. public function connection($name = null);
  7220. public function getDefaultConnection();
  7221. public function setDefaultConnection($name);
  7222. }
  7223. namespace Illuminate\Database\Connectors;
  7224. use PDO;
  7225. use Illuminate\Container\Container;
  7226. use Illuminate\Database\MySqlConnection;
  7227. use Illuminate\Database\SQLiteConnection;
  7228. use Illuminate\Database\PostgresConnection;
  7229. use Illuminate\Database\SqlServerConnection;
  7230. class ConnectionFactory
  7231. {
  7232. protected $container;
  7233. public function __construct(Container $container)
  7234. {
  7235. $this->container = $container;
  7236. }
  7237. public function make(array $config, $name = null)
  7238. {
  7239. $config = $this->parseConfig($config, $name);
  7240. if (isset($config['read'])) {
  7241. return $this->createReadWriteConnection($config);
  7242. } else {
  7243. return $this->createSingleConnection($config);
  7244. }
  7245. }
  7246. protected function createSingleConnection(array $config)
  7247. {
  7248. $pdo = $this->createConnector($config)->connect($config);
  7249. return $this->createConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config);
  7250. }
  7251. protected function createReadWriteConnection(array $config)
  7252. {
  7253. $connection = $this->createSingleConnection($this->getWriteConfig($config));
  7254. return $connection->setReadPdo($this->createReadPdo($config));
  7255. }
  7256. protected function createReadPdo(array $config)
  7257. {
  7258. $readConfig = $this->getReadConfig($config);
  7259. return $this->createConnector($readConfig)->connect($readConfig);
  7260. }
  7261. protected function getReadConfig(array $config)
  7262. {
  7263. $readConfig = $this->getReadWriteConfig($config, 'read');
  7264. return $this->mergeReadWriteConfig($config, $readConfig);
  7265. }
  7266. protected function getWriteConfig(array $config)
  7267. {
  7268. $writeConfig = $this->getReadWriteConfig($config, 'write');
  7269. return $this->mergeReadWriteConfig($config, $writeConfig);
  7270. }
  7271. protected function getReadWriteConfig(array $config, $type)
  7272. {
  7273. if (isset($config[$type][0])) {
  7274. return $config[$type][array_rand($config[$type])];
  7275. } else {
  7276. return $config[$type];
  7277. }
  7278. }
  7279. protected function mergeReadWriteConfig(array $config, array $merge)
  7280. {
  7281. return array_except(array_merge($config, $merge), array('read', 'write'));
  7282. }
  7283. protected function parseConfig(array $config, $name)
  7284. {
  7285. return array_add(array_add($config, 'prefix', ''), 'name', $name);
  7286. }
  7287. public function createConnector(array $config)
  7288. {
  7289. if (!isset($config['driver'])) {
  7290. throw new \InvalidArgumentException('A driver must be specified.');
  7291. }
  7292. if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
  7293. return $this->container->make($key);
  7294. }
  7295. switch ($config['driver']) {
  7296. case 'mysql':
  7297. return new MySqlConnector();
  7298. case 'pgsql':
  7299. return new PostgresConnector();
  7300. case 'sqlite':
  7301. return new SQLiteConnector();
  7302. case 'sqlsrv':
  7303. return new SqlServerConnector();
  7304. }
  7305. throw new \InvalidArgumentException("Unsupported driver [{$config['driver']}]");
  7306. }
  7307. protected function createConnection($driver, PDO $connection, $database, $prefix = '', array $config = array())
  7308. {
  7309. if ($this->container->bound($key = "db.connection.{$driver}")) {
  7310. return $this->container->make($key, array($connection, $database, $prefix, $config));
  7311. }
  7312. switch ($driver) {
  7313. case 'mysql':
  7314. return new MySqlConnection($connection, $database, $prefix, $config);
  7315. case 'pgsql':
  7316. return new PostgresConnection($connection, $database, $prefix, $config);
  7317. case 'sqlite':
  7318. return new SQLiteConnection($connection, $database, $prefix, $config);
  7319. case 'sqlsrv':
  7320. return new SqlServerConnection($connection, $database, $prefix, $config);
  7321. }
  7322. throw new \InvalidArgumentException("Unsupported driver [{$driver}]");
  7323. }
  7324. }
  7325. namespace Illuminate\Session;
  7326. use Closure;
  7327. use Carbon\Carbon;
  7328. use Symfony\Component\HttpFoundation\Cookie;
  7329. use Symfony\Component\HttpFoundation\Request;
  7330. use Symfony\Component\HttpFoundation\Response;
  7331. use Symfony\Component\HttpKernel\HttpKernelInterface;
  7332. class Middleware implements HttpKernelInterface
  7333. {
  7334. protected $app;
  7335. protected $manager;
  7336. protected $reject;
  7337. public function __construct(HttpKernelInterface $app, SessionManager $manager, Closure $reject = null)
  7338. {
  7339. $this->app = $app;
  7340. $this->reject = $reject;
  7341. $this->manager = $manager;
  7342. }
  7343. public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  7344. {
  7345. $this->checkRequestForArraySessions($request);
  7346. if ($this->sessionConfigured()) {
  7347. $session = $this->startSession($request);
  7348. $request->setSession($session);
  7349. }
  7350. $response = $this->app->handle($request, $type, $catch);
  7351. if ($this->sessionConfigured()) {
  7352. $this->closeSession($session);
  7353. $this->addCookieToResponse($response, $session);
  7354. }
  7355. return $response;
  7356. }
  7357. public function checkRequestForArraySessions(Request $request)
  7358. {
  7359. if (is_null($this->reject)) {
  7360. return;
  7361. }
  7362. if (call_user_func($this->reject, $request)) {
  7363. $this->manager->setDefaultDriver('array');
  7364. }
  7365. }
  7366. protected function startSession(Request $request)
  7367. {
  7368. with($session = $this->getSession($request))->setRequestOnHandler($request);
  7369. $session->start();
  7370. return $session;
  7371. }
  7372. protected function closeSession(SessionInterface $session)
  7373. {
  7374. $session->save();
  7375. $this->collectGarbage($session);
  7376. }
  7377. protected function getUrl(Request $request)
  7378. {
  7379. $url = rtrim(preg_replace('/\\?.*/', '', $request->getUri()), '/');
  7380. return $request->getQueryString() ? $url . '?' . $request->getQueryString() : $url;
  7381. }
  7382. protected function collectGarbage(SessionInterface $session)
  7383. {
  7384. $config = $this->manager->getSessionConfig();
  7385. if ($this->configHitsLottery($config)) {
  7386. $session->getHandler()->gc($this->getLifetimeSeconds());
  7387. }
  7388. }
  7389. protected function configHitsLottery(array $config)
  7390. {
  7391. return mt_rand(1, $config['lottery'][1]) <= $config['lottery'][0];
  7392. }
  7393. protected function addCookieToResponse(Response $response, SessionInterface $session)
  7394. {
  7395. $s = $session;
  7396. if ($this->sessionIsPersistent($c = $this->manager->getSessionConfig())) {
  7397. $secure = array_get($c, 'secure', false);
  7398. $response->headers->setCookie(new Cookie($s->getName(), $s->getId(), $this->getCookieLifetime(), $c['path'], $c['domain'], $secure));
  7399. }
  7400. }
  7401. protected function getLifetimeSeconds()
  7402. {
  7403. return array_get($this->manager->getSessionConfig(), 'lifetime') * 60;
  7404. }
  7405. protected function getCookieLifetime()
  7406. {
  7407. $config = $this->manager->getSessionConfig();
  7408. return $config['expire_on_close'] ? 0 : Carbon::now()->addMinutes($config['lifetime']);
  7409. }
  7410. protected function sessionConfigured()
  7411. {
  7412. return !is_null(array_get($this->manager->getSessionConfig(), 'driver'));
  7413. }
  7414. protected function sessionIsPersistent(array $config = null)
  7415. {
  7416. $config = $config ?: $this->manager->getSessionConfig();
  7417. return !in_array($config['driver'], array(null, 'array'));
  7418. }
  7419. public function getSession(Request $request)
  7420. {
  7421. $session = $this->manager->driver();
  7422. $session->setId($request->cookies->get($session->getName()));
  7423. return $session;
  7424. }
  7425. }
  7426. namespace Illuminate\Session;
  7427. use SessionHandlerInterface;
  7428. use Symfony\Component\HttpFoundation\Request;
  7429. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  7430. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  7431. class Store implements SessionInterface
  7432. {
  7433. protected $id;
  7434. protected $name;
  7435. protected $attributes = array();
  7436. protected $bags = array();
  7437. protected $metaBag;
  7438. protected $bagData = array();
  7439. protected $handler;
  7440. protected $started = false;
  7441. public function __construct($name, SessionHandlerInterface $handler, $id = null)
  7442. {
  7443. $this->name = $name;
  7444. $this->handler = $handler;
  7445. $this->metaBag = new MetadataBag();
  7446. $this->setId($id ?: $this->generateSessionId());
  7447. }
  7448. public function start()
  7449. {
  7450. $this->loadSession();
  7451. if (!$this->has('_token')) {
  7452. $this->regenerateToken();
  7453. }
  7454. return $this->started = true;
  7455. }
  7456. protected function loadSession()
  7457. {
  7458. $this->attributes = $this->readFromHandler();
  7459. foreach (array_merge($this->bags, array($this->metaBag)) as $bag) {
  7460. $this->initializeLocalBag($bag);
  7461. $bag->initialize($this->bagData[$bag->getStorageKey()]);
  7462. }
  7463. }
  7464. protected function readFromHandler()
  7465. {
  7466. $data = $this->handler->read($this->getId());
  7467. return $data ? unserialize($data) : array();
  7468. }
  7469. protected function initializeLocalBag($bag)
  7470. {
  7471. $this->bagData[$bag->getStorageKey()] = $this->get($bag->getStorageKey(), array());
  7472. $this->forget($bag->getStorageKey());
  7473. }
  7474. public function getId()
  7475. {
  7476. return $this->id;
  7477. }
  7478. public function setId($id)
  7479. {
  7480. $this->id = $id ?: $this->generateSessionId();
  7481. }
  7482. protected function generateSessionId()
  7483. {
  7484. return sha1(uniqid(true) . str_random(25) . microtime(true));
  7485. }
  7486. public function getName()
  7487. {
  7488. return $this->name;
  7489. }
  7490. public function setName($name)
  7491. {
  7492. $this->name = $name;
  7493. }
  7494. public function invalidate($lifetime = null)
  7495. {
  7496. $this->attributes = array();
  7497. $this->migrate();
  7498. return true;
  7499. }
  7500. public function migrate($destroy = false, $lifetime = null)
  7501. {
  7502. if ($destroy) {
  7503. $this->handler->destroy($this->getId());
  7504. }
  7505. $this->setExists(false);
  7506. $this->id = $this->generateSessionId();
  7507. return true;
  7508. }
  7509. public function regenerate($destroy = false)
  7510. {
  7511. return $this->migrate($destroy);
  7512. }
  7513. public function save()
  7514. {
  7515. $this->addBagDataToSession();
  7516. $this->ageFlashData();
  7517. $this->handler->write($this->getId(), serialize($this->attributes));
  7518. $this->started = false;
  7519. }
  7520. protected function addBagDataToSession()
  7521. {
  7522. foreach (array_merge($this->bags, array($this->metaBag)) as $bag) {
  7523. $this->put($bag->getStorageKey(), $this->bagData[$bag->getStorageKey()]);
  7524. }
  7525. }
  7526. public function ageFlashData()
  7527. {
  7528. foreach ($this->get('flash.old', array()) as $old) {
  7529. $this->forget($old);
  7530. }
  7531. $this->put('flash.old', $this->get('flash.new', array()));
  7532. $this->put('flash.new', array());
  7533. }
  7534. public function has($name)
  7535. {
  7536. return !is_null($this->get($name));
  7537. }
  7538. public function get($name, $default = null)
  7539. {
  7540. return array_get($this->attributes, $name, $default);
  7541. }
  7542. public function pull($key, $default = null)
  7543. {
  7544. $value = $this->get($key, $default);
  7545. $this->forget($key);
  7546. return $value;
  7547. }
  7548. public function hasOldInput($key = null)
  7549. {
  7550. $old = $this->getOldInput($key);
  7551. return is_null($key) ? count($old) > 0 : !is_null($old);
  7552. }
  7553. public function getOldInput($key = null, $default = null)
  7554. {
  7555. $input = $this->get('_old_input', array());
  7556. if (is_null($key)) {
  7557. return $input;
  7558. }
  7559. return array_get($input, $key, $default);
  7560. }
  7561. public function set($name, $value)
  7562. {
  7563. array_set($this->attributes, $name, $value);
  7564. }
  7565. public function put($key, $value)
  7566. {
  7567. if (!is_array($key)) {
  7568. $key = array($key => $value);
  7569. }
  7570. foreach ($key as $arrayKey => $arrayValue) {
  7571. $this->set($arrayKey, $arrayValue);
  7572. }
  7573. }
  7574. public function push($key, $value)
  7575. {
  7576. $array = $this->get($key, array());
  7577. $array[] = $value;
  7578. $this->put($key, $array);
  7579. }
  7580. public function flash($key, $value)
  7581. {
  7582. $this->put($key, $value);
  7583. $this->push('flash.new', $key);
  7584. $this->removeFromOldFlashData(array($key));
  7585. }
  7586. public function flashInput(array $value)
  7587. {
  7588. $this->flash('_old_input', $value);
  7589. }
  7590. public function reflash()
  7591. {
  7592. $this->mergeNewFlashes($this->get('flash.old', array()));
  7593. $this->put('flash.old', array());
  7594. }
  7595. public function keep($keys = null)
  7596. {
  7597. $keys = is_array($keys) ? $keys : func_get_args();
  7598. $this->mergeNewFlashes($keys);
  7599. $this->removeFromOldFlashData($keys);
  7600. }
  7601. protected function mergeNewFlashes(array $keys)
  7602. {
  7603. $values = array_unique(array_merge($this->get('flash.new', array()), $keys));
  7604. $this->put('flash.new', $values);
  7605. }
  7606. protected function removeFromOldFlashData(array $keys)
  7607. {
  7608. $this->put('flash.old', array_diff($this->get('flash.old', array()), $keys));
  7609. }
  7610. public function all()
  7611. {
  7612. return $this->attributes;
  7613. }
  7614. public function replace(array $attributes)
  7615. {
  7616. foreach ($attributes as $key => $value) {
  7617. $this->put($key, $value);
  7618. }
  7619. }
  7620. public function remove($name)
  7621. {
  7622. return array_pull($this->attributes, $name);
  7623. }
  7624. public function forget($key)
  7625. {
  7626. array_forget($this->attributes, $key);
  7627. }
  7628. public function clear()
  7629. {
  7630. $this->attributes = array();
  7631. foreach ($this->bags as $bag) {
  7632. $bag->clear();
  7633. }
  7634. }
  7635. public function flush()
  7636. {
  7637. $this->clear();
  7638. }
  7639. public function isStarted()
  7640. {
  7641. return $this->started;
  7642. }
  7643. public function registerBag(SessionBagInterface $bag)
  7644. {
  7645. $this->bags[$bag->getStorageKey()] = $bag;
  7646. }
  7647. public function getBag($name)
  7648. {
  7649. return array_get($this->bags, $name, function () {
  7650. throw new \InvalidArgumentException('Bag not registered.');
  7651. });
  7652. }
  7653. public function getMetadataBag()
  7654. {
  7655. return $this->metaBag;
  7656. }
  7657. public function getBagData($name)
  7658. {
  7659. return array_get($this->bagData, $name, array());
  7660. }
  7661. public function token()
  7662. {
  7663. return $this->get('_token');
  7664. }
  7665. public function getToken()
  7666. {
  7667. return $this->token();
  7668. }
  7669. public function regenerateToken()
  7670. {
  7671. $this->put('_token', str_random(40));
  7672. }
  7673. public function setExists($value)
  7674. {
  7675. if ($this->handler instanceof ExistenceAwareInterface) {
  7676. $this->handler->setExists($value);
  7677. }
  7678. }
  7679. public function getHandler()
  7680. {
  7681. return $this->handler;
  7682. }
  7683. public function handlerNeedsRequest()
  7684. {
  7685. return $this->handler instanceof CookieSessionHandler;
  7686. }
  7687. public function setRequestOnHandler(Request $request)
  7688. {
  7689. if ($this->handlerNeedsRequest()) {
  7690. $this->handler->setRequest($request);
  7691. }
  7692. }
  7693. }
  7694. namespace Illuminate\Session;
  7695. use Illuminate\Support\Manager;
  7696. use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
  7697. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
  7698. class SessionManager extends Manager
  7699. {
  7700. protected function callCustomCreator($driver)
  7701. {
  7702. return $this->buildSession(parent::callCustomCreator($driver));
  7703. }
  7704. protected function createArrayDriver()
  7705. {
  7706. return new Store($this->app['config']['session.cookie'], new NullSessionHandler());
  7707. }
  7708. protected function createCookieDriver()
  7709. {
  7710. $lifetime = $this->app['config']['session.lifetime'];
  7711. return $this->buildSession(new CookieSessionHandler($this->app['cookie'], $lifetime));
  7712. }
  7713. protected function createFileDriver()
  7714. {
  7715. return $this->createNativeDriver();
  7716. }
  7717. protected function createNativeDriver()
  7718. {
  7719. $path = $this->app['config']['session.files'];
  7720. return $this->buildSession(new FileSessionHandler($this->app['files'], $path));
  7721. }
  7722. protected function createDatabaseDriver()
  7723. {
  7724. $connection = $this->getDatabaseConnection();
  7725. $table = $connection->getTablePrefix() . $this->app['config']['session.table'];
  7726. return $this->buildSession(new DatabaseSessionHandler($connection, $table));
  7727. }
  7728. protected function getDatabaseConnection()
  7729. {
  7730. $connection = $this->app['config']['session.connection'];
  7731. return $this->app['db']->connection($connection);
  7732. }
  7733. protected function createApcDriver()
  7734. {
  7735. return $this->createCacheBased('apc');
  7736. }
  7737. protected function createMemcachedDriver()
  7738. {
  7739. return $this->createCacheBased('memcached');
  7740. }
  7741. protected function createWincacheDriver()
  7742. {
  7743. return $this->createCacheBased('wincache');
  7744. }
  7745. protected function createRedisDriver()
  7746. {
  7747. $handler = $this->createCacheHandler('redis');
  7748. $handler->getCache()->getStore()->setConnection($this->app['config']['session.connection']);
  7749. return $this->buildSession($handler);
  7750. }
  7751. protected function createCacheBased($driver)
  7752. {
  7753. return $this->buildSession($this->createCacheHandler($driver));
  7754. }
  7755. protected function createCacheHandler($driver)
  7756. {
  7757. $minutes = $this->app['config']['session.lifetime'];
  7758. return new CacheBasedSessionHandler($this->app['cache']->driver($driver), $minutes);
  7759. }
  7760. protected function buildSession($handler)
  7761. {
  7762. return new Store($this->app['config']['session.cookie'], $handler);
  7763. }
  7764. public function getSessionConfig()
  7765. {
  7766. return $this->app['config']['session'];
  7767. }
  7768. public function getDefaultDriver()
  7769. {
  7770. return $this->app['config']['session.driver'];
  7771. }
  7772. public function setDefaultDriver($name)
  7773. {
  7774. $this->app['config']['session.driver'] = $name;
  7775. }
  7776. }
  7777. namespace Illuminate\Support;
  7778. use Closure;
  7779. abstract class Manager
  7780. {
  7781. protected $app;
  7782. protected $customCreators = array();
  7783. protected $drivers = array();
  7784. public function __construct($app)
  7785. {
  7786. $this->app = $app;
  7787. }
  7788. public function driver($driver = null)
  7789. {
  7790. $driver = $driver ?: $this->getDefaultDriver();
  7791. if (!isset($this->drivers[$driver])) {
  7792. $this->drivers[$driver] = $this->createDriver($driver);
  7793. }
  7794. return $this->drivers[$driver];
  7795. }
  7796. protected function createDriver($driver)
  7797. {
  7798. $method = 'create' . ucfirst($driver) . 'Driver';
  7799. if (isset($this->customCreators[$driver])) {
  7800. return $this->callCustomCreator($driver);
  7801. } elseif (method_exists($this, $method)) {
  7802. return $this->{$method}();
  7803. }
  7804. throw new \InvalidArgumentException("Driver [{$driver}] not supported.");
  7805. }
  7806. protected function callCustomCreator($driver)
  7807. {
  7808. return $this->customCreators[$driver]($this->app);
  7809. }
  7810. public function extend($driver, Closure $callback)
  7811. {
  7812. $this->customCreators[$driver] = $callback;
  7813. return $this;
  7814. }
  7815. public function getDrivers()
  7816. {
  7817. return $this->drivers;
  7818. }
  7819. public function __call($method, $parameters)
  7820. {
  7821. return call_user_func_array(array($this->driver(), $method), $parameters);
  7822. }
  7823. }
  7824. namespace Illuminate\Cookie;
  7825. use Symfony\Component\HttpFoundation\Cookie;
  7826. class CookieJar
  7827. {
  7828. protected $path = '/';
  7829. protected $domain = null;
  7830. protected $queued = array();
  7831. public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
  7832. {
  7833. list($path, $domain) = $this->getPathAndDomain($path, $domain);
  7834. $time = $minutes == 0 ? 0 : time() + $minutes * 60;
  7835. return new Cookie($name, $value, $time, $path, $domain, $secure, $httpOnly);
  7836. }
  7837. public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true)
  7838. {
  7839. return $this->make($name, $value, 2628000, $path, $domain, $secure, $httpOnly);
  7840. }
  7841. public function forget($name, $path = null, $domain = null)
  7842. {
  7843. return $this->make($name, null, -2628000, $path, $domain);
  7844. }
  7845. public function hasQueued($key)
  7846. {
  7847. return !is_null($this->queued($key));
  7848. }
  7849. public function queued($key, $default = null)
  7850. {
  7851. return array_get($this->queued, $key, $default);
  7852. }
  7853. public function queue()
  7854. {
  7855. if (head(func_get_args()) instanceof Cookie) {
  7856. $cookie = head(func_get_args());
  7857. } else {
  7858. $cookie = call_user_func_array(array($this, 'make'), func_get_args());
  7859. }
  7860. $this->queued[$cookie->getName()] = $cookie;
  7861. }
  7862. public function unqueue($name)
  7863. {
  7864. unset($this->queued[$name]);
  7865. }
  7866. protected function getPathAndDomain($path, $domain)
  7867. {
  7868. return array($path ?: $this->path, $domain ?: $this->domain);
  7869. }
  7870. public function setDefaultPathAndDomain($path, $domain)
  7871. {
  7872. list($this->path, $this->domain) = array($path, $domain);
  7873. return $this;
  7874. }
  7875. public function getQueuedCookies()
  7876. {
  7877. return $this->queued;
  7878. }
  7879. }
  7880. namespace Illuminate\Cookie;
  7881. use Illuminate\Encryption\Encrypter;
  7882. use Illuminate\Encryption\DecryptException;
  7883. use Symfony\Component\HttpFoundation\Cookie;
  7884. use Symfony\Component\HttpFoundation\Request;
  7885. use Symfony\Component\HttpFoundation\Response;
  7886. use Symfony\Component\HttpKernel\HttpKernelInterface;
  7887. class Guard implements HttpKernelInterface
  7888. {
  7889. protected $app;
  7890. protected $encrypter;
  7891. public function __construct(HttpKernelInterface $app, Encrypter $encrypter)
  7892. {
  7893. $this->app = $app;
  7894. $this->encrypter = $encrypter;
  7895. }
  7896. public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  7897. {
  7898. return $this->encrypt($this->app->handle($this->decrypt($request), $type, $catch));
  7899. }
  7900. protected function decrypt(Request $request)
  7901. {
  7902. foreach ($request->cookies as $key => $c) {
  7903. try {
  7904. $request->cookies->set($key, $this->decryptCookie($c));
  7905. } catch (DecryptException $e) {
  7906. $request->cookies->set($key, null);
  7907. }
  7908. }
  7909. return $request;
  7910. }
  7911. protected function decryptCookie($cookie)
  7912. {
  7913. return is_array($cookie) ? $this->decryptArray($cookie) : $this->encrypter->decrypt($cookie);
  7914. }
  7915. protected function decryptArray(array $cookie)
  7916. {
  7917. $decrypted = array();
  7918. foreach ($cookie as $key => $value) {
  7919. $decrypted[$key] = $this->encrypter->decrypt($value);
  7920. }
  7921. return $decrypted;
  7922. }
  7923. protected function encrypt(Response $response)
  7924. {
  7925. foreach ($response->headers->getCookies() as $key => $c) {
  7926. $encrypted = $this->encrypter->encrypt($c->getValue());
  7927. $response->headers->setCookie($this->duplicate($c, $encrypted));
  7928. }
  7929. return $response;
  7930. }
  7931. protected function duplicate(Cookie $c, $value)
  7932. {
  7933. return new Cookie($c->getName(), $value, $c->getExpiresTime(), $c->getPath(), $c->getDomain(), $c->isSecure(), $c->isHttpOnly());
  7934. }
  7935. }
  7936. namespace Illuminate\Cookie;
  7937. use Symfony\Component\HttpFoundation\Request;
  7938. use Symfony\Component\HttpKernel\HttpKernelInterface;
  7939. class Queue implements HttpKernelInterface
  7940. {
  7941. protected $app;
  7942. protected $cookies;
  7943. public function __construct(HttpKernelInterface $app, CookieJar $cookies)
  7944. {
  7945. $this->app = $app;
  7946. $this->cookies = $cookies;
  7947. }
  7948. public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  7949. {
  7950. $response = $this->app->handle($request, $type, $catch);
  7951. foreach ($this->cookies->getQueuedCookies() as $cookie) {
  7952. $response->headers->setCookie($cookie);
  7953. }
  7954. return $response;
  7955. }
  7956. }
  7957. namespace Illuminate\Encryption;
  7958. use Symfony\Component\Security\Core\Util\StringUtils;
  7959. use Symfony\Component\Security\Core\Util\SecureRandom;
  7960. class DecryptException extends \RuntimeException
  7961. {
  7962. }
  7963. class Encrypter
  7964. {
  7965. protected $key;
  7966. protected $cipher = MCRYPT_RIJNDAEL_128;
  7967. protected $mode = MCRYPT_MODE_CBC;
  7968. protected $block = 16;
  7969. public function __construct($key)
  7970. {
  7971. $this->key = $key;
  7972. }
  7973. public function encrypt($value)
  7974. {
  7975. $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
  7976. $value = base64_encode($this->padAndMcrypt($value, $iv));
  7977. $mac = $this->hash($iv = base64_encode($iv), $value);
  7978. return base64_encode(json_encode(compact('iv', 'value', 'mac')));
  7979. }
  7980. protected function padAndMcrypt($value, $iv)
  7981. {
  7982. $value = $this->addPadding(serialize($value));
  7983. return mcrypt_encrypt($this->cipher, $this->key, $value, $this->mode, $iv);
  7984. }
  7985. public function decrypt($payload)
  7986. {
  7987. $payload = $this->getJsonPayload($payload);
  7988. $value = base64_decode($payload['value']);
  7989. $iv = base64_decode($payload['iv']);
  7990. return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
  7991. }
  7992. protected function mcryptDecrypt($value, $iv)
  7993. {
  7994. return mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv);
  7995. }
  7996. protected function getJsonPayload($payload)
  7997. {
  7998. $payload = json_decode(base64_decode($payload), true);
  7999. if (!$payload || $this->invalidPayload($payload)) {
  8000. throw new DecryptException('Invalid data.');
  8001. }
  8002. if (!$this->validMac($payload)) {
  8003. throw new DecryptException('MAC is invalid.');
  8004. }
  8005. return $payload;
  8006. }
  8007. protected function validMac(array $payload)
  8008. {
  8009. $bytes = with(new SecureRandom())->nextBytes(16);
  8010. $calcMac = hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true);
  8011. return StringUtils::equals(hash_hmac('sha256', $payload['mac'], $bytes, true), $calcMac);
  8012. }
  8013. protected function hash($iv, $value)
  8014. {
  8015. return hash_hmac('sha256', $iv . $value, $this->key);
  8016. }
  8017. protected function addPadding($value)
  8018. {
  8019. $pad = $this->block - strlen($value) % $this->block;
  8020. return $value . str_repeat(chr($pad), $pad);
  8021. }
  8022. protected function stripPadding($value)
  8023. {
  8024. $pad = ord($value[($len = strlen($value)) - 1]);
  8025. return $this->paddingIsValid($pad, $value) ? substr($value, 0, $len - $pad) : $value;
  8026. }
  8027. protected function paddingIsValid($pad, $value)
  8028. {
  8029. $beforePad = strlen($value) - $pad;
  8030. return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
  8031. }
  8032. protected function invalidPayload($data)
  8033. {
  8034. return !is_array($data) || !isset($data['iv']) || !isset($data['value']) || !isset($data['mac']);
  8035. }
  8036. protected function getIvSize()
  8037. {
  8038. return mcrypt_get_iv_size($this->cipher, $this->mode);
  8039. }
  8040. protected function getRandomizer()
  8041. {
  8042. if (defined('MCRYPT_DEV_URANDOM')) {
  8043. return MCRYPT_DEV_URANDOM;
  8044. }
  8045. if (defined('MCRYPT_DEV_RANDOM')) {
  8046. return MCRYPT_DEV_RANDOM;
  8047. }
  8048. mt_srand();
  8049. return MCRYPT_RAND;
  8050. }
  8051. public function setKey($key)
  8052. {
  8053. $this->key = $key;
  8054. }
  8055. public function setCipher($cipher)
  8056. {
  8057. $this->cipher = $cipher;
  8058. $this->updateBlockSize();
  8059. }
  8060. public function setMode($mode)
  8061. {
  8062. $this->mode = $mode;
  8063. $this->updateBlockSize();
  8064. }
  8065. protected function updateBlockSize()
  8066. {
  8067. $this->block = mcrypt_get_iv_size($this->cipher, $this->mode);
  8068. }
  8069. }
  8070. namespace Illuminate\Support\Facades;
  8071. class Log extends Facade
  8072. {
  8073. protected static function getFacadeAccessor()
  8074. {
  8075. return 'log';
  8076. }
  8077. }
  8078. namespace Illuminate\Log;
  8079. use Monolog\Logger;
  8080. use Illuminate\Support\ServiceProvider;
  8081. class LogServiceProvider extends ServiceProvider
  8082. {
  8083. protected $defer = true;
  8084. public function register()
  8085. {
  8086. $logger = new Writer(new Logger($this->app['env']), $this->app['events']);
  8087. $this->app->instance('log', $logger);
  8088. if (isset($this->app['log.setup'])) {
  8089. call_user_func($this->app['log.setup'], $logger);
  8090. }
  8091. }
  8092. public function provides()
  8093. {
  8094. return array('log');
  8095. }
  8096. }
  8097. namespace Illuminate\Log;
  8098. use Closure;
  8099. use Illuminate\Events\Dispatcher;
  8100. use Monolog\Handler\StreamHandler;
  8101. use Monolog\Logger as MonologLogger;
  8102. use Monolog\Formatter\LineFormatter;
  8103. use Monolog\Handler\ErrorLogHandler;
  8104. use Monolog\Handler\RotatingFileHandler;
  8105. use Illuminate\Support\Contracts\JsonableInterface;
  8106. use Illuminate\Support\Contracts\ArrayableInterface;
  8107. class Writer
  8108. {
  8109. protected $monolog;
  8110. protected $levels = array('debug', 'info', 'notice', 'warning', 'error', 'critical', 'alert', 'emergency');
  8111. protected $dispatcher;
  8112. public function __construct(MonologLogger $monolog, Dispatcher $dispatcher = null)
  8113. {
  8114. $this->monolog = $monolog;
  8115. if (isset($dispatcher)) {
  8116. $this->dispatcher = $dispatcher;
  8117. }
  8118. }
  8119. protected function callMonolog($method, $parameters)
  8120. {
  8121. if (is_array($parameters[0])) {
  8122. $parameters[0] = json_encode($parameters[0]);
  8123. }
  8124. return call_user_func_array(array($this->monolog, $method), $parameters);
  8125. }
  8126. public function useFiles($path, $level = 'debug')
  8127. {
  8128. $level = $this->parseLevel($level);
  8129. $this->monolog->pushHandler($handler = new StreamHandler($path, $level));
  8130. $handler->setFormatter($this->getDefaultFormatter());
  8131. }
  8132. public function useDailyFiles($path, $days = 0, $level = 'debug')
  8133. {
  8134. $level = $this->parseLevel($level);
  8135. $this->monolog->pushHandler($handler = new RotatingFileHandler($path, $days, $level));
  8136. $handler->setFormatter($this->getDefaultFormatter());
  8137. }
  8138. public function useErrorLog($level = 'debug', $messageType = ErrorLogHandler::OPERATING_SYSTEM)
  8139. {
  8140. $level = $this->parseLevel($level);
  8141. $this->monolog->pushHandler($handler = new ErrorLogHandler($messageType, $level));
  8142. $handler->setFormatter($this->getDefaultFormatter());
  8143. }
  8144. protected function getDefaultFormatter()
  8145. {
  8146. return new LineFormatter(null, null, true);
  8147. }
  8148. protected function parseLevel($level)
  8149. {
  8150. switch ($level) {
  8151. case 'debug':
  8152. return MonologLogger::DEBUG;
  8153. case 'info':
  8154. return MonologLogger::INFO;
  8155. case 'notice':
  8156. return MonologLogger::NOTICE;
  8157. case 'warning':
  8158. return MonologLogger::WARNING;
  8159. case 'error':
  8160. return MonologLogger::ERROR;
  8161. case 'critical':
  8162. return MonologLogger::CRITICAL;
  8163. case 'alert':
  8164. return MonologLogger::ALERT;
  8165. case 'emergency':
  8166. return MonologLogger::EMERGENCY;
  8167. default:
  8168. throw new \InvalidArgumentException('Invalid log level.');
  8169. }
  8170. }
  8171. public function listen(Closure $callback)
  8172. {
  8173. if (!isset($this->dispatcher)) {
  8174. throw new \RuntimeException('Events dispatcher has not been set.');
  8175. }
  8176. $this->dispatcher->listen('illuminate.log', $callback);
  8177. }
  8178. public function getMonolog()
  8179. {
  8180. return $this->monolog;
  8181. }
  8182. public function getEventDispatcher()
  8183. {
  8184. return $this->dispatcher;
  8185. }
  8186. public function setEventDispatcher(Dispatcher $dispatcher)
  8187. {
  8188. $this->dispatcher = $dispatcher;
  8189. }
  8190. protected function fireLogEvent($level, $message, array $context = array())
  8191. {
  8192. if (isset($this->dispatcher)) {
  8193. $this->dispatcher->fire('illuminate.log', compact('level', 'message', 'context'));
  8194. }
  8195. }
  8196. public function write()
  8197. {
  8198. $level = head(func_get_args());
  8199. return call_user_func_array(array($this, $level), array_slice(func_get_args(), 1));
  8200. }
  8201. public function __call($method, $parameters)
  8202. {
  8203. $this->formatParameters($parameters);
  8204. if (in_array($method, $this->levels)) {
  8205. call_user_func_array(array($this, 'fireLogEvent'), array_merge(array($method), $parameters));
  8206. $method = 'add' . ucfirst($method);
  8207. return $this->callMonolog($method, $parameters);
  8208. }
  8209. throw new \BadMethodCallException("Method [{$method}] does not exist.");
  8210. }
  8211. protected function formatParameters(&$parameters)
  8212. {
  8213. if (isset($parameters[0])) {
  8214. if (is_array($parameters[0])) {
  8215. $parameters[0] = var_export($parameters[0], true);
  8216. } elseif ($parameters[0] instanceof JsonableInterface) {
  8217. $parameters[0] = $parameters[0]->toJson();
  8218. } elseif ($parameters[0] instanceof ArrayableInterface) {
  8219. $parameters[0] = var_export($parameters[0]->toArray(), true);
  8220. }
  8221. }
  8222. }
  8223. }
  8224. namespace Monolog;
  8225. use Monolog\Handler\HandlerInterface;
  8226. use Monolog\Handler\StreamHandler;
  8227. use Psr\Log\LoggerInterface;
  8228. use Psr\Log\InvalidArgumentException;
  8229. class Logger implements LoggerInterface
  8230. {
  8231. const DEBUG = 100;
  8232. const INFO = 200;
  8233. const NOTICE = 250;
  8234. const WARNING = 300;
  8235. const ERROR = 400;
  8236. const CRITICAL = 500;
  8237. const ALERT = 550;
  8238. const EMERGENCY = 600;
  8239. const API = 1;
  8240. protected static $levels = array(100 => 'DEBUG', 200 => 'INFO', 250 => 'NOTICE', 300 => 'WARNING', 400 => 'ERROR', 500 => 'CRITICAL', 550 => 'ALERT', 600 => 'EMERGENCY');
  8241. protected static $timezone;
  8242. protected $name;
  8243. protected $handlers;
  8244. protected $processors;
  8245. public function __construct($name, array $handlers = array(), array $processors = array())
  8246. {
  8247. $this->name = $name;
  8248. $this->handlers = $handlers;
  8249. $this->processors = $processors;
  8250. }
  8251. public function getName()
  8252. {
  8253. return $this->name;
  8254. }
  8255. public function pushHandler(HandlerInterface $handler)
  8256. {
  8257. array_unshift($this->handlers, $handler);
  8258. }
  8259. public function popHandler()
  8260. {
  8261. if (!$this->handlers) {
  8262. throw new \LogicException('You tried to pop from an empty handler stack.');
  8263. }
  8264. return array_shift($this->handlers);
  8265. }
  8266. public function getHandlers()
  8267. {
  8268. return $this->handlers;
  8269. }
  8270. public function pushProcessor($callback)
  8271. {
  8272. if (!is_callable($callback)) {
  8273. throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given');
  8274. }
  8275. array_unshift($this->processors, $callback);
  8276. }
  8277. public function popProcessor()
  8278. {
  8279. if (!$this->processors) {
  8280. throw new \LogicException('You tried to pop from an empty processor stack.');
  8281. }
  8282. return array_shift($this->processors);
  8283. }
  8284. public function getProcessors()
  8285. {
  8286. return $this->processors;
  8287. }
  8288. public function addRecord($level, $message, array $context = array())
  8289. {
  8290. if (!$this->handlers) {
  8291. $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG));
  8292. }
  8293. if (!static::$timezone) {
  8294. static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC');
  8295. }
  8296. $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());
  8297. $handlerKey = null;
  8298. foreach ($this->handlers as $key => $handler) {
  8299. if ($handler->isHandling($record)) {
  8300. $handlerKey = $key;
  8301. break;
  8302. }
  8303. }
  8304. if (null === $handlerKey) {
  8305. return false;
  8306. }
  8307. foreach ($this->processors as $processor) {
  8308. $record = call_user_func($processor, $record);
  8309. }
  8310. while (isset($this->handlers[$handlerKey]) && false === $this->handlers[$handlerKey]->handle($record)) {
  8311. $handlerKey++;
  8312. }
  8313. return true;
  8314. }
  8315. public function addDebug($message, array $context = array())
  8316. {
  8317. return $this->addRecord(static::DEBUG, $message, $context);
  8318. }
  8319. public function addInfo($message, array $context = array())
  8320. {
  8321. return $this->addRecord(static::INFO, $message, $context);
  8322. }
  8323. public function addNotice($message, array $context = array())
  8324. {
  8325. return $this->addRecord(static::NOTICE, $message, $context);
  8326. }
  8327. public function addWarning($message, array $context = array())
  8328. {
  8329. return $this->addRecord(static::WARNING, $message, $context);
  8330. }
  8331. public function addError($message, array $context = array())
  8332. {
  8333. return $this->addRecord(static::ERROR, $message, $context);
  8334. }
  8335. public function addCritical($message, array $context = array())
  8336. {
  8337. return $this->addRecord(static::CRITICAL, $message, $context);
  8338. }
  8339. public function addAlert($message, array $context = array())
  8340. {
  8341. return $this->addRecord(static::ALERT, $message, $context);
  8342. }
  8343. public function addEmergency($message, array $context = array())
  8344. {
  8345. return $this->addRecord(static::EMERGENCY, $message, $context);
  8346. }
  8347. public static function getLevels()
  8348. {
  8349. return array_flip(static::$levels);
  8350. }
  8351. public static function getLevelName($level)
  8352. {
  8353. if (!isset(static::$levels[$level])) {
  8354. throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(static::$levels)));
  8355. }
  8356. return static::$levels[$level];
  8357. }
  8358. public function isHandling($level)
  8359. {
  8360. $record = array('level' => $level);
  8361. foreach ($this->handlers as $handler) {
  8362. if ($handler->isHandling($record)) {
  8363. return true;
  8364. }
  8365. }
  8366. return false;
  8367. }
  8368. public function log($level, $message, array $context = array())
  8369. {
  8370. if (is_string($level) && defined(__CLASS__ . '::' . strtoupper($level))) {
  8371. $level = constant(__CLASS__ . '::' . strtoupper($level));
  8372. }
  8373. return $this->addRecord($level, $message, $context);
  8374. }
  8375. public function debug($message, array $context = array())
  8376. {
  8377. return $this->addRecord(static::DEBUG, $message, $context);
  8378. }
  8379. public function info($message, array $context = array())
  8380. {
  8381. return $this->addRecord(static::INFO, $message, $context);
  8382. }
  8383. public function notice($message, array $context = array())
  8384. {
  8385. return $this->addRecord(static::NOTICE, $message, $context);
  8386. }
  8387. public function warn($message, array $context = array())
  8388. {
  8389. return $this->addRecord(static::WARNING, $message, $context);
  8390. }
  8391. public function warning($message, array $context = array())
  8392. {
  8393. return $this->addRecord(static::WARNING, $message, $context);
  8394. }
  8395. public function err($message, array $context = array())
  8396. {
  8397. return $this->addRecord(static::ERROR, $message, $context);
  8398. }
  8399. public function error($message, array $context = array())
  8400. {
  8401. return $this->addRecord(static::ERROR, $message, $context);
  8402. }
  8403. public function crit($message, array $context = array())
  8404. {
  8405. return $this->addRecord(static::CRITICAL, $message, $context);
  8406. }
  8407. public function critical($message, array $context = array())
  8408. {
  8409. return $this->addRecord(static::CRITICAL, $message, $context);
  8410. }
  8411. public function alert($message, array $context = array())
  8412. {
  8413. return $this->addRecord(static::ALERT, $message, $context);
  8414. }
  8415. public function emerg($message, array $context = array())
  8416. {
  8417. return $this->addRecord(static::EMERGENCY, $message, $context);
  8418. }
  8419. public function emergency($message, array $context = array())
  8420. {
  8421. return $this->addRecord(static::EMERGENCY, $message, $context);
  8422. }
  8423. }
  8424. namespace Psr\Log;
  8425. interface LoggerInterface
  8426. {
  8427. public function emergency($message, array $context = array());
  8428. public function alert($message, array $context = array());
  8429. public function critical($message, array $context = array());
  8430. public function error($message, array $context = array());
  8431. public function warning($message, array $context = array());
  8432. public function notice($message, array $context = array());
  8433. public function info($message, array $context = array());
  8434. public function debug($message, array $context = array());
  8435. public function log($level, $message, array $context = array());
  8436. }
  8437. namespace Monolog\Handler;
  8438. use Monolog\Logger;
  8439. use Monolog\Formatter\FormatterInterface;
  8440. use Monolog\Formatter\LineFormatter;
  8441. abstract class AbstractHandler implements HandlerInterface
  8442. {
  8443. protected $level = Logger::DEBUG;
  8444. protected $bubble = true;
  8445. protected $formatter;
  8446. protected $processors = array();
  8447. public function __construct($level = Logger::DEBUG, $bubble = true)
  8448. {
  8449. $this->level = $level;
  8450. $this->bubble = $bubble;
  8451. }
  8452. public function isHandling(array $record)
  8453. {
  8454. return $record['level'] >= $this->level;
  8455. }
  8456. public function handleBatch(array $records)
  8457. {
  8458. foreach ($records as $record) {
  8459. $this->handle($record);
  8460. }
  8461. }
  8462. public function close()
  8463. {
  8464. }
  8465. public function pushProcessor($callback)
  8466. {
  8467. if (!is_callable($callback)) {
  8468. throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given');
  8469. }
  8470. array_unshift($this->processors, $callback);
  8471. return $this;
  8472. }
  8473. public function popProcessor()
  8474. {
  8475. if (!$this->processors) {
  8476. throw new \LogicException('You tried to pop from an empty processor stack.');
  8477. }
  8478. return array_shift($this->processors);
  8479. }
  8480. public function setFormatter(FormatterInterface $formatter)
  8481. {
  8482. $this->formatter = $formatter;
  8483. return $this;
  8484. }
  8485. public function getFormatter()
  8486. {
  8487. if (!$this->formatter) {
  8488. $this->formatter = $this->getDefaultFormatter();
  8489. }
  8490. return $this->formatter;
  8491. }
  8492. public function setLevel($level)
  8493. {
  8494. $this->level = $level;
  8495. return $this;
  8496. }
  8497. public function getLevel()
  8498. {
  8499. return $this->level;
  8500. }
  8501. public function setBubble($bubble)
  8502. {
  8503. $this->bubble = $bubble;
  8504. return $this;
  8505. }
  8506. public function getBubble()
  8507. {
  8508. return $this->bubble;
  8509. }
  8510. public function __destruct()
  8511. {
  8512. try {
  8513. $this->close();
  8514. } catch (\Exception $e) {
  8515. }
  8516. }
  8517. protected function getDefaultFormatter()
  8518. {
  8519. return new LineFormatter();
  8520. }
  8521. }
  8522. namespace Monolog\Handler;
  8523. abstract class AbstractProcessingHandler extends AbstractHandler
  8524. {
  8525. public function handle(array $record)
  8526. {
  8527. if (!$this->isHandling($record)) {
  8528. return false;
  8529. }
  8530. $record = $this->processRecord($record);
  8531. $record['formatted'] = $this->getFormatter()->format($record);
  8532. $this->write($record);
  8533. return false === $this->bubble;
  8534. }
  8535. protected abstract function write(array $record);
  8536. protected function processRecord(array $record)
  8537. {
  8538. if ($this->processors) {
  8539. foreach ($this->processors as $processor) {
  8540. $record = call_user_func($processor, $record);
  8541. }
  8542. }
  8543. return $record;
  8544. }
  8545. }
  8546. namespace Monolog\Handler;
  8547. use Monolog\Logger;
  8548. class StreamHandler extends AbstractProcessingHandler
  8549. {
  8550. protected $stream;
  8551. protected $url;
  8552. private $errorMessage;
  8553. protected $filePermission;
  8554. public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null)
  8555. {
  8556. parent::__construct($level, $bubble);
  8557. if (is_resource($stream)) {
  8558. $this->stream = $stream;
  8559. } else {
  8560. $this->url = $stream;
  8561. }
  8562. $this->filePermission = $filePermission;
  8563. }
  8564. public function close()
  8565. {
  8566. if (is_resource($this->stream)) {
  8567. fclose($this->stream);
  8568. }
  8569. $this->stream = null;
  8570. }
  8571. protected function write(array $record)
  8572. {
  8573. if (!is_resource($this->stream)) {
  8574. if (!$this->url) {
  8575. throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
  8576. }
  8577. $this->errorMessage = null;
  8578. set_error_handler(array($this, 'customErrorHandler'));
  8579. $this->stream = fopen($this->url, 'a');
  8580. if ($this->filePermission !== null) {
  8581. @chmod($this->url, $this->filePermission);
  8582. }
  8583. restore_error_handler();
  8584. if (!is_resource($this->stream)) {
  8585. $this->stream = null;
  8586. throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $this->errorMessage, $this->url));
  8587. }
  8588. }
  8589. fwrite($this->stream, (string) $record['formatted']);
  8590. }
  8591. private function customErrorHandler($code, $msg)
  8592. {
  8593. $this->errorMessage = preg_replace('{^fopen\\(.*?\\): }', '', $msg);
  8594. }
  8595. }
  8596. namespace Monolog\Handler;
  8597. use Monolog\Logger;
  8598. class RotatingFileHandler extends StreamHandler
  8599. {
  8600. protected $filename;
  8601. protected $maxFiles;
  8602. protected $mustRotate;
  8603. protected $nextRotation;
  8604. protected $filenameFormat;
  8605. protected $dateFormat;
  8606. public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null)
  8607. {
  8608. $this->filename = $filename;
  8609. $this->maxFiles = (int) $maxFiles;
  8610. $this->nextRotation = new \DateTime('tomorrow');
  8611. $this->filenameFormat = '{filename}-{date}';
  8612. $this->dateFormat = 'Y-m-d';
  8613. parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission);
  8614. }
  8615. public function close()
  8616. {
  8617. parent::close();
  8618. if (true === $this->mustRotate) {
  8619. $this->rotate();
  8620. }
  8621. }
  8622. public function setFilenameFormat($filenameFormat, $dateFormat)
  8623. {
  8624. $this->filenameFormat = $filenameFormat;
  8625. $this->dateFormat = $dateFormat;
  8626. $this->url = $this->getTimedFilename();
  8627. $this->close();
  8628. }
  8629. protected function write(array $record)
  8630. {
  8631. if (null === $this->mustRotate) {
  8632. $this->mustRotate = !file_exists($this->url);
  8633. }
  8634. if ($this->nextRotation < $record['datetime']) {
  8635. $this->mustRotate = true;
  8636. $this->close();
  8637. }
  8638. parent::write($record);
  8639. }
  8640. protected function rotate()
  8641. {
  8642. $this->url = $this->getTimedFilename();
  8643. $this->nextRotation = new \DateTime('tomorrow');
  8644. if (0 === $this->maxFiles) {
  8645. return;
  8646. }
  8647. $logFiles = glob($this->getGlobPattern());
  8648. if ($this->maxFiles >= count($logFiles)) {
  8649. return;
  8650. }
  8651. usort($logFiles, function ($a, $b) {
  8652. return strcmp($b, $a);
  8653. });
  8654. foreach (array_slice($logFiles, $this->maxFiles) as $file) {
  8655. if (is_writable($file)) {
  8656. unlink($file);
  8657. }
  8658. }
  8659. }
  8660. protected function getTimedFilename()
  8661. {
  8662. $fileInfo = pathinfo($this->filename);
  8663. $timedFilename = str_replace(array('{filename}', '{date}'), array($fileInfo['filename'], date($this->dateFormat)), $fileInfo['dirname'] . '/' . $this->filenameFormat);
  8664. if (!empty($fileInfo['extension'])) {
  8665. $timedFilename .= '.' . $fileInfo['extension'];
  8666. }
  8667. return $timedFilename;
  8668. }
  8669. protected function getGlobPattern()
  8670. {
  8671. $fileInfo = pathinfo($this->filename);
  8672. $glob = str_replace(array('{filename}', '{date}'), array($fileInfo['filename'], '*'), $fileInfo['dirname'] . '/' . $this->filenameFormat);
  8673. if (!empty($fileInfo['extension'])) {
  8674. $glob .= '.' . $fileInfo['extension'];
  8675. }
  8676. return $glob;
  8677. }
  8678. }
  8679. namespace Monolog\Handler;
  8680. use Monolog\Formatter\FormatterInterface;
  8681. interface HandlerInterface
  8682. {
  8683. public function isHandling(array $record);
  8684. public function handle(array $record);
  8685. public function handleBatch(array $records);
  8686. public function pushProcessor($callback);
  8687. public function popProcessor();
  8688. public function setFormatter(FormatterInterface $formatter);
  8689. public function getFormatter();
  8690. }
  8691. namespace Illuminate\Support\Facades;
  8692. class App extends Facade
  8693. {
  8694. protected static function getFacadeAccessor()
  8695. {
  8696. return 'app';
  8697. }
  8698. }
  8699. namespace Illuminate\Exception;
  8700. use Exception;
  8701. interface ExceptionDisplayerInterface
  8702. {
  8703. public function display(Exception $exception);
  8704. }
  8705. namespace Illuminate\Exception;
  8706. use Exception;
  8707. use Symfony\Component\Debug\ExceptionHandler;
  8708. class SymfonyDisplayer implements ExceptionDisplayerInterface
  8709. {
  8710. protected $symfony;
  8711. public function __construct(ExceptionHandler $symfony)
  8712. {
  8713. $this->symfony = $symfony;
  8714. }
  8715. public function display(Exception $exception)
  8716. {
  8717. return $this->symfony->createResponse($exception);
  8718. }
  8719. }
  8720. namespace Illuminate\Exception;
  8721. use Exception;
  8722. use Whoops\Run;
  8723. use Symfony\Component\HttpFoundation\Response;
  8724. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  8725. class WhoopsDisplayer implements ExceptionDisplayerInterface
  8726. {
  8727. protected $whoops;
  8728. protected $runningInConsole;
  8729. public function __construct(Run $whoops, $runningInConsole)
  8730. {
  8731. $this->whoops = $whoops;
  8732. $this->runningInConsole = $runningInConsole;
  8733. }
  8734. public function display(Exception $exception)
  8735. {
  8736. $status = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500;
  8737. $headers = $exception instanceof HttpExceptionInterface ? $exception->getHeaders() : array();
  8738. return new Response($this->whoops->handleException($exception), $status, $headers);
  8739. }
  8740. }
  8741. namespace Illuminate\Exception;
  8742. use Closure;
  8743. use ErrorException;
  8744. use ReflectionFunction;
  8745. use Illuminate\Support\Contracts\ResponsePreparerInterface;
  8746. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  8747. use Symfony\Component\Debug\Exception\FatalErrorException as FatalError;
  8748. class Handler
  8749. {
  8750. protected $responsePreparer;
  8751. protected $plainDisplayer;
  8752. protected $debugDisplayer;
  8753. protected $debug;
  8754. protected $handlers = array();
  8755. protected $handled = array();
  8756. public function __construct(ResponsePreparerInterface $responsePreparer, ExceptionDisplayerInterface $plainDisplayer, ExceptionDisplayerInterface $debugDisplayer, $debug = true)
  8757. {
  8758. $this->debug = $debug;
  8759. $this->plainDisplayer = $plainDisplayer;
  8760. $this->debugDisplayer = $debugDisplayer;
  8761. $this->responsePreparer = $responsePreparer;
  8762. }
  8763. public function register($environment)
  8764. {
  8765. $this->registerErrorHandler();
  8766. $this->registerExceptionHandler();
  8767. if ($environment != 'testing') {
  8768. $this->registerShutdownHandler();
  8769. }
  8770. }
  8771. protected function registerErrorHandler()
  8772. {
  8773. set_error_handler(array($this, 'handleError'));
  8774. }
  8775. protected function registerExceptionHandler()
  8776. {
  8777. set_exception_handler(array($this, 'handleUncaughtException'));
  8778. }
  8779. protected function registerShutdownHandler()
  8780. {
  8781. register_shutdown_function(array($this, 'handleShutdown'));
  8782. }
  8783. public function handleError($level, $message, $file = '', $line = 0, $context = array())
  8784. {
  8785. if (error_reporting() & $level) {
  8786. throw new ErrorException($message, 0, $level, $file, $line);
  8787. }
  8788. }
  8789. public function handleException($exception)
  8790. {
  8791. $response = $this->callCustomHandlers($exception);
  8792. if (!is_null($response)) {
  8793. return $this->prepareResponse($response);
  8794. }
  8795. return $this->displayException($exception);
  8796. }
  8797. public function handleUncaughtException($exception)
  8798. {
  8799. $this->handleException($exception)->send();
  8800. }
  8801. public function handleShutdown()
  8802. {
  8803. $error = error_get_last();
  8804. if (!is_null($error)) {
  8805. extract($error);
  8806. if (!$this->isFatal($type)) {
  8807. return;
  8808. }
  8809. $this->handleException(new FatalError($message, $type, 0, $file, $line))->send();
  8810. }
  8811. }
  8812. protected function isFatal($type)
  8813. {
  8814. return in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE));
  8815. }
  8816. public function handleConsole($exception)
  8817. {
  8818. return $this->callCustomHandlers($exception, true);
  8819. }
  8820. protected function callCustomHandlers($exception, $fromConsole = false)
  8821. {
  8822. foreach ($this->handlers as $handler) {
  8823. if (!$this->handlesException($handler, $exception)) {
  8824. continue;
  8825. } elseif ($exception instanceof HttpExceptionInterface) {
  8826. $code = $exception->getStatusCode();
  8827. } else {
  8828. $code = 500;
  8829. }
  8830. try {
  8831. $response = $handler($exception, $code, $fromConsole);
  8832. } catch (\Exception $e) {
  8833. $response = $this->formatException($e);
  8834. }
  8835. if (isset($response) && !is_null($response)) {
  8836. return $response;
  8837. }
  8838. }
  8839. }
  8840. protected function displayException($exception)
  8841. {
  8842. $displayer = $this->debug ? $this->debugDisplayer : $this->plainDisplayer;
  8843. return $displayer->display($exception);
  8844. }
  8845. protected function handlesException(Closure $handler, $exception)
  8846. {
  8847. $reflection = new ReflectionFunction($handler);
  8848. return $reflection->getNumberOfParameters() == 0 || $this->hints($reflection, $exception);
  8849. }
  8850. protected function hints(ReflectionFunction $reflection, $exception)
  8851. {
  8852. $parameters = $reflection->getParameters();
  8853. $expected = $parameters[0];
  8854. return !$expected->getClass() || $expected->getClass()->isInstance($exception);
  8855. }
  8856. protected function formatException(\Exception $e)
  8857. {
  8858. if ($this->debug) {
  8859. $location = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
  8860. return 'Error in exception handler: ' . $location;
  8861. }
  8862. return 'Error in exception handler.';
  8863. }
  8864. public function error(Closure $callback)
  8865. {
  8866. array_unshift($this->handlers, $callback);
  8867. }
  8868. public function pushError(Closure $callback)
  8869. {
  8870. $this->handlers[] = $callback;
  8871. }
  8872. protected function prepareResponse($response)
  8873. {
  8874. return $this->responsePreparer->prepareResponse($response);
  8875. }
  8876. public function runningInConsole()
  8877. {
  8878. return php_sapi_name() == 'cli';
  8879. }
  8880. public function setDebug($debug)
  8881. {
  8882. $this->debug = $debug;
  8883. }
  8884. }
  8885. namespace Illuminate\Support\Facades;
  8886. class Route extends Facade
  8887. {
  8888. protected static function getFacadeAccessor()
  8889. {
  8890. return 'router';
  8891. }
  8892. }
  8893. namespace Illuminate\View\Engines;
  8894. use Closure;
  8895. class EngineResolver
  8896. {
  8897. protected $resolvers = array();
  8898. protected $resolved = array();
  8899. public function register($engine, Closure $resolver)
  8900. {
  8901. $this->resolvers[$engine] = $resolver;
  8902. }
  8903. public function resolve($engine)
  8904. {
  8905. if (!isset($this->resolved[$engine])) {
  8906. $this->resolved[$engine] = call_user_func($this->resolvers[$engine]);
  8907. }
  8908. return $this->resolved[$engine];
  8909. }
  8910. }
  8911. namespace Illuminate\View;
  8912. interface ViewFinderInterface
  8913. {
  8914. public function find($view);
  8915. public function addLocation($location);
  8916. public function addNamespace($namespace, $hint);
  8917. public function addExtension($extension);
  8918. }
  8919. namespace Illuminate\View;
  8920. use Illuminate\Filesystem\Filesystem;
  8921. class FileViewFinder implements ViewFinderInterface
  8922. {
  8923. protected $files;
  8924. protected $paths;
  8925. protected $views = array();
  8926. protected $hints = array();
  8927. protected $extensions = array('blade.php', 'php');
  8928. const HINT_PATH_DELIMITER = '::';
  8929. public function __construct(Filesystem $files, array $paths, array $extensions = null)
  8930. {
  8931. $this->files = $files;
  8932. $this->paths = $paths;
  8933. if (isset($extensions)) {
  8934. $this->extensions = $extensions;
  8935. }
  8936. }
  8937. public function find($name)
  8938. {
  8939. if (isset($this->views[$name])) {
  8940. return $this->views[$name];
  8941. }
  8942. if ($this->hasHintInformation($name = trim($name))) {
  8943. return $this->views[$name] = $this->findNamedPathView($name);
  8944. }
  8945. return $this->views[$name] = $this->findInPaths($name, $this->paths);
  8946. }
  8947. protected function findNamedPathView($name)
  8948. {
  8949. list($namespace, $view) = $this->getNamespaceSegments($name);
  8950. return $this->findInPaths($view, $this->hints[$namespace]);
  8951. }
  8952. protected function getNamespaceSegments($name)
  8953. {
  8954. $segments = explode(static::HINT_PATH_DELIMITER, $name);
  8955. if (count($segments) != 2) {
  8956. throw new \InvalidArgumentException("View [{$name}] has an invalid name.");
  8957. }
  8958. if (!isset($this->hints[$segments[0]])) {
  8959. throw new \InvalidArgumentException("No hint path defined for [{$segments[0]}].");
  8960. }
  8961. return $segments;
  8962. }
  8963. protected function findInPaths($name, $paths)
  8964. {
  8965. foreach ((array) $paths as $path) {
  8966. foreach ($this->getPossibleViewFiles($name) as $file) {
  8967. if ($this->files->exists($viewPath = $path . '/' . $file)) {
  8968. return $viewPath;
  8969. }
  8970. }
  8971. }
  8972. throw new \InvalidArgumentException("View [{$name}] not found.");
  8973. }
  8974. protected function getPossibleViewFiles($name)
  8975. {
  8976. return array_map(function ($extension) use($name) {
  8977. return str_replace('.', '/', $name) . '.' . $extension;
  8978. }, $this->extensions);
  8979. }
  8980. public function addLocation($location)
  8981. {
  8982. $this->paths[] = $location;
  8983. }
  8984. public function addNamespace($namespace, $hints)
  8985. {
  8986. $hints = (array) $hints;
  8987. if (isset($this->hints[$namespace])) {
  8988. $hints = array_merge($this->hints[$namespace], $hints);
  8989. }
  8990. $this->hints[$namespace] = $hints;
  8991. }
  8992. public function prependNamespace($namespace, $hints)
  8993. {
  8994. $hints = (array) $hints;
  8995. if (isset($this->hints[$namespace])) {
  8996. $hints = array_merge($hints, $this->hints[$namespace]);
  8997. }
  8998. $this->hints[$namespace] = $hints;
  8999. }
  9000. public function addExtension($extension)
  9001. {
  9002. if (($index = array_search($extension, $this->extensions)) !== false) {
  9003. unset($this->extensions[$index]);
  9004. }
  9005. array_unshift($this->extensions, $extension);
  9006. }
  9007. public function hasHintInformation($name)
  9008. {
  9009. return strpos($name, static::HINT_PATH_DELIMITER) > 0;
  9010. }
  9011. public function getFilesystem()
  9012. {
  9013. return $this->files;
  9014. }
  9015. public function getPaths()
  9016. {
  9017. return $this->paths;
  9018. }
  9019. public function getHints()
  9020. {
  9021. return $this->hints;
  9022. }
  9023. public function getExtensions()
  9024. {
  9025. return $this->extensions;
  9026. }
  9027. }
  9028. namespace Illuminate\Support\Contracts;
  9029. interface MessageProviderInterface
  9030. {
  9031. public function getMessageBag();
  9032. }
  9033. namespace Illuminate\Support;
  9034. use Countable;
  9035. use JsonSerializable;
  9036. use Illuminate\Support\Contracts\JsonableInterface;
  9037. use Illuminate\Support\Contracts\ArrayableInterface;
  9038. use Illuminate\Support\Contracts\MessageProviderInterface;
  9039. class MessageBag implements ArrayableInterface, Countable, JsonableInterface, MessageProviderInterface, JsonSerializable
  9040. {
  9041. protected $messages = array();
  9042. protected $format = ':message';
  9043. public function __construct(array $messages = array())
  9044. {
  9045. foreach ($messages as $key => $value) {
  9046. $this->messages[$key] = (array) $value;
  9047. }
  9048. }
  9049. public function add($key, $message)
  9050. {
  9051. if ($this->isUnique($key, $message)) {
  9052. $this->messages[$key][] = $message;
  9053. }
  9054. return $this;
  9055. }
  9056. public function merge($messages)
  9057. {
  9058. if ($messages instanceof MessageProviderInterface) {
  9059. $messages = $messages->getMessageBag()->getMessages();
  9060. }
  9061. $this->messages = array_merge_recursive($this->messages, $messages);
  9062. return $this;
  9063. }
  9064. protected function isUnique($key, $message)
  9065. {
  9066. $messages = (array) $this->messages;
  9067. return !isset($messages[$key]) || !in_array($message, $messages[$key]);
  9068. }
  9069. public function has($key = null)
  9070. {
  9071. return $this->first($key) !== '';
  9072. }
  9073. public function first($key = null, $format = null)
  9074. {
  9075. $messages = is_null($key) ? $this->all($format) : $this->get($key, $format);
  9076. return count($messages) > 0 ? $messages[0] : '';
  9077. }
  9078. public function get($key, $format = null)
  9079. {
  9080. $format = $this->checkFormat($format);
  9081. if (array_key_exists($key, $this->messages)) {
  9082. return $this->transform($this->messages[$key], $format, $key);
  9083. }
  9084. return array();
  9085. }
  9086. public function all($format = null)
  9087. {
  9088. $format = $this->checkFormat($format);
  9089. $all = array();
  9090. foreach ($this->messages as $key => $messages) {
  9091. $all = array_merge($all, $this->transform($messages, $format, $key));
  9092. }
  9093. return $all;
  9094. }
  9095. protected function transform($messages, $format, $messageKey)
  9096. {
  9097. $messages = (array) $messages;
  9098. foreach ($messages as $key => &$message) {
  9099. $replace = array(':message', ':key');
  9100. $message = str_replace($replace, array($message, $messageKey), $format);
  9101. }
  9102. return $messages;
  9103. }
  9104. protected function checkFormat($format)
  9105. {
  9106. return $format === null ? $this->format : $format;
  9107. }
  9108. public function getMessages()
  9109. {
  9110. return $this->messages;
  9111. }
  9112. public function getMessageBag()
  9113. {
  9114. return $this;
  9115. }
  9116. public function getFormat()
  9117. {
  9118. return $this->format;
  9119. }
  9120. public function setFormat($format = ':message')
  9121. {
  9122. $this->format = $format;
  9123. return $this;
  9124. }
  9125. public function isEmpty()
  9126. {
  9127. return !$this->any();
  9128. }
  9129. public function any()
  9130. {
  9131. return $this->count() > 0;
  9132. }
  9133. public function count()
  9134. {
  9135. return count($this->messages, COUNT_RECURSIVE) - count($this->messages);
  9136. }
  9137. public function toArray()
  9138. {
  9139. return $this->getMessages();
  9140. }
  9141. public function jsonSerialize()
  9142. {
  9143. return $this->toArray();
  9144. }
  9145. public function toJson($options = 0)
  9146. {
  9147. return json_encode($this->toArray(), $options);
  9148. }
  9149. public function __toString()
  9150. {
  9151. return $this->toJson();
  9152. }
  9153. }
  9154. namespace Illuminate\Support\Facades;
  9155. class View extends Facade
  9156. {
  9157. protected static function getFacadeAccessor()
  9158. {
  9159. return 'view';
  9160. }
  9161. }
  9162. namespace Illuminate\Support\Contracts;
  9163. interface RenderableInterface
  9164. {
  9165. public function render();
  9166. }
  9167. namespace Illuminate\View;
  9168. use ArrayAccess;
  9169. use Closure;
  9170. use Illuminate\Support\MessageBag;
  9171. use Illuminate\View\Engines\EngineInterface;
  9172. use Illuminate\Support\Contracts\MessageProviderInterface;
  9173. use Illuminate\Support\Contracts\ArrayableInterface as Arrayable;
  9174. use Illuminate\Support\Contracts\RenderableInterface as Renderable;
  9175. class View implements ArrayAccess, Renderable
  9176. {
  9177. protected $factory;
  9178. protected $engine;
  9179. protected $view;
  9180. protected $data;
  9181. protected $path;
  9182. public function __construct(Factory $factory, EngineInterface $engine, $view, $path, $data = array())
  9183. {
  9184. $this->view = $view;
  9185. $this->path = $path;
  9186. $this->engine = $engine;
  9187. $this->factory = $factory;
  9188. $this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;
  9189. }
  9190. public function render(Closure $callback = null)
  9191. {
  9192. $contents = $this->renderContents();
  9193. $response = isset($callback) ? $callback($this, $contents) : null;
  9194. $this->factory->flushSectionsIfDoneRendering();
  9195. return $response ?: $contents;
  9196. }
  9197. protected function renderContents()
  9198. {
  9199. $this->factory->incrementRender();
  9200. $this->factory->callComposer($this);
  9201. $contents = $this->getContents();
  9202. $this->factory->decrementRender();
  9203. return $contents;
  9204. }
  9205. public function renderSections()
  9206. {
  9207. $env = $this->factory;
  9208. return $this->render(function ($view) use($env) {
  9209. return $env->getSections();
  9210. });
  9211. }
  9212. protected function getContents()
  9213. {
  9214. return $this->engine->get($this->path, $this->gatherData());
  9215. }
  9216. protected function gatherData()
  9217. {
  9218. $data = array_merge($this->factory->getShared(), $this->data);
  9219. foreach ($data as $key => $value) {
  9220. if ($value instanceof Renderable) {
  9221. $data[$key] = $value->render();
  9222. }
  9223. }
  9224. return $data;
  9225. }
  9226. public function with($key, $value = null)
  9227. {
  9228. if (is_array($key)) {
  9229. $this->data = array_merge($this->data, $key);
  9230. } else {
  9231. $this->data[$key] = $value;
  9232. }
  9233. return $this;
  9234. }
  9235. public function nest($key, $view, array $data = array())
  9236. {
  9237. return $this->with($key, $this->factory->make($view, $data));
  9238. }
  9239. public function withErrors($provider)
  9240. {
  9241. if ($provider instanceof MessageProviderInterface) {
  9242. $this->with('errors', $provider->getMessageBag());
  9243. } else {
  9244. $this->with('errors', new MessageBag((array) $provider));
  9245. }
  9246. return $this;
  9247. }
  9248. public function getFactory()
  9249. {
  9250. return $this->factory;
  9251. }
  9252. public function getEngine()
  9253. {
  9254. return $this->engine;
  9255. }
  9256. public function getName()
  9257. {
  9258. return $this->view;
  9259. }
  9260. public function getData()
  9261. {
  9262. return $this->data;
  9263. }
  9264. public function getPath()
  9265. {
  9266. return $this->path;
  9267. }
  9268. public function setPath($path)
  9269. {
  9270. $this->path = $path;
  9271. }
  9272. public function offsetExists($key)
  9273. {
  9274. return array_key_exists($key, $this->data);
  9275. }
  9276. public function offsetGet($key)
  9277. {
  9278. return $this->data[$key];
  9279. }
  9280. public function offsetSet($key, $value)
  9281. {
  9282. $this->with($key, $value);
  9283. }
  9284. public function offsetUnset($key)
  9285. {
  9286. unset($this->data[$key]);
  9287. }
  9288. public function &__get($key)
  9289. {
  9290. return $this->data[$key];
  9291. }
  9292. public function __set($key, $value)
  9293. {
  9294. $this->with($key, $value);
  9295. }
  9296. public function __isset($key)
  9297. {
  9298. return isset($this->data[$key]);
  9299. }
  9300. public function __unset($key)
  9301. {
  9302. unset($this->data[$key]);
  9303. }
  9304. public function __call($method, $parameters)
  9305. {
  9306. if (starts_with($method, 'with')) {
  9307. return $this->with(snake_case(substr($method, 4)), $parameters[0]);
  9308. }
  9309. throw new \BadMethodCallException("Method [{$method}] does not exist on view.");
  9310. }
  9311. public function __toString()
  9312. {
  9313. return $this->render();
  9314. }
  9315. }
  9316. namespace Illuminate\View\Engines;
  9317. interface EngineInterface
  9318. {
  9319. public function get($path, array $data = array());
  9320. }
  9321. namespace Illuminate\View\Engines;
  9322. use Illuminate\View\Exception;
  9323. class PhpEngine implements EngineInterface
  9324. {
  9325. public function get($path, array $data = array())
  9326. {
  9327. return $this->evaluatePath($path, $data);
  9328. }
  9329. protected function evaluatePath($__path, $__data)
  9330. {
  9331. ob_start();
  9332. extract($__data);
  9333. try {
  9334. include $__path;
  9335. } catch (\Exception $e) {
  9336. $this->handleViewException($e);
  9337. }
  9338. return ltrim(ob_get_clean());
  9339. }
  9340. protected function handleViewException($e)
  9341. {
  9342. ob_get_clean();
  9343. throw $e;
  9344. }
  9345. }
  9346. namespace Symfony\Component\HttpFoundation;
  9347. class Response
  9348. {
  9349. const HTTP_CONTINUE = 100;
  9350. const HTTP_SWITCHING_PROTOCOLS = 101;
  9351. const HTTP_PROCESSING = 102;
  9352. const HTTP_OK = 200;
  9353. const HTTP_CREATED = 201;
  9354. const HTTP_ACCEPTED = 202;
  9355. const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
  9356. const HTTP_NO_CONTENT = 204;
  9357. const HTTP_RESET_CONTENT = 205;
  9358. const HTTP_PARTIAL_CONTENT = 206;
  9359. const HTTP_MULTI_STATUS = 207;
  9360. const HTTP_ALREADY_REPORTED = 208;
  9361. const HTTP_IM_USED = 226;
  9362. const HTTP_MULTIPLE_CHOICES = 300;
  9363. const HTTP_MOVED_PERMANENTLY = 301;
  9364. const HTTP_FOUND = 302;
  9365. const HTTP_SEE_OTHER = 303;
  9366. const HTTP_NOT_MODIFIED = 304;
  9367. const HTTP_USE_PROXY = 305;
  9368. const HTTP_RESERVED = 306;
  9369. const HTTP_TEMPORARY_REDIRECT = 307;
  9370. const HTTP_PERMANENTLY_REDIRECT = 308;
  9371. const HTTP_BAD_REQUEST = 400;
  9372. const HTTP_UNAUTHORIZED = 401;
  9373. const HTTP_PAYMENT_REQUIRED = 402;
  9374. const HTTP_FORBIDDEN = 403;
  9375. const HTTP_NOT_FOUND = 404;
  9376. const HTTP_METHOD_NOT_ALLOWED = 405;
  9377. const HTTP_NOT_ACCEPTABLE = 406;
  9378. const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
  9379. const HTTP_REQUEST_TIMEOUT = 408;
  9380. const HTTP_CONFLICT = 409;
  9381. const HTTP_GONE = 410;
  9382. const HTTP_LENGTH_REQUIRED = 411;
  9383. const HTTP_PRECONDITION_FAILED = 412;
  9384. const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
  9385. const HTTP_REQUEST_URI_TOO_LONG = 414;
  9386. const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
  9387. const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
  9388. const HTTP_EXPECTATION_FAILED = 417;
  9389. const HTTP_I_AM_A_TEAPOT = 418;
  9390. const HTTP_UNPROCESSABLE_ENTITY = 422;
  9391. const HTTP_LOCKED = 423;
  9392. const HTTP_FAILED_DEPENDENCY = 424;
  9393. const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;
  9394. const HTTP_UPGRADE_REQUIRED = 426;
  9395. const HTTP_PRECONDITION_REQUIRED = 428;
  9396. const HTTP_TOO_MANY_REQUESTS = 429;
  9397. const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
  9398. const HTTP_INTERNAL_SERVER_ERROR = 500;
  9399. const HTTP_NOT_IMPLEMENTED = 501;
  9400. const HTTP_BAD_GATEWAY = 502;
  9401. const HTTP_SERVICE_UNAVAILABLE = 503;
  9402. const HTTP_GATEWAY_TIMEOUT = 504;
  9403. const HTTP_VERSION_NOT_SUPPORTED = 505;
  9404. const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506;
  9405. const HTTP_INSUFFICIENT_STORAGE = 507;
  9406. const HTTP_LOOP_DETECTED = 508;
  9407. const HTTP_NOT_EXTENDED = 510;
  9408. const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;
  9409. public $headers;
  9410. protected $content;
  9411. protected $version;
  9412. protected $statusCode;
  9413. protected $statusText;
  9414. protected $charset;
  9415. 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');
  9416. public function __construct($content = '', $status = 200, $headers = array())
  9417. {
  9418. $this->headers = new ResponseHeaderBag($headers);
  9419. $this->setContent($content);
  9420. $this->setStatusCode($status);
  9421. $this->setProtocolVersion('1.0');
  9422. if (!$this->headers->has('Date')) {
  9423. $this->setDate(new \DateTime(null, new \DateTimeZone('UTC')));
  9424. }
  9425. }
  9426. public static function create($content = '', $status = 200, $headers = array())
  9427. {
  9428. return new static($content, $status, $headers);
  9429. }
  9430. public function __toString()
  9431. {
  9432. return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText) . '
  9433. ' . $this->headers . '
  9434. ' . $this->getContent();
  9435. }
  9436. public function __clone()
  9437. {
  9438. $this->headers = clone $this->headers;
  9439. }
  9440. public function prepare(Request $request)
  9441. {
  9442. $headers = $this->headers;
  9443. if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
  9444. $this->setContent(null);
  9445. }
  9446. if (!$headers->has('Content-Type')) {
  9447. $format = $request->getRequestFormat();
  9448. if (null !== $format && ($mimeType = $request->getMimeType($format))) {
  9449. $headers->set('Content-Type', $mimeType);
  9450. }
  9451. }
  9452. $charset = $this->charset ?: 'UTF-8';
  9453. if (!$headers->has('Content-Type')) {
  9454. $headers->set('Content-Type', 'text/html; charset=' . $charset);
  9455. } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) {
  9456. $headers->set('Content-Type', $headers->get('Content-Type') . '; charset=' . $charset);
  9457. }
  9458. if ($headers->has('Transfer-Encoding')) {
  9459. $headers->remove('Content-Length');
  9460. }
  9461. if ($request->isMethod('HEAD')) {
  9462. $length = $headers->get('Content-Length');
  9463. $this->setContent(null);
  9464. if ($length) {
  9465. $headers->set('Content-Length', $length);
  9466. }
  9467. }
  9468. if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
  9469. $this->setProtocolVersion('1.1');
  9470. }
  9471. if ('1.0' == $this->getProtocolVersion() && 'no-cache' == $this->headers->get('Cache-Control')) {
  9472. $this->headers->set('pragma', 'no-cache');
  9473. $this->headers->set('expires', -1);
  9474. }
  9475. $this->ensureIEOverSSLCompatibility($request);
  9476. return $this;
  9477. }
  9478. public function sendHeaders()
  9479. {
  9480. if (headers_sent()) {
  9481. return $this;
  9482. }
  9483. header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);
  9484. foreach ($this->headers->allPreserveCase() as $name => $values) {
  9485. foreach ($values as $value) {
  9486. header($name . ': ' . $value, false, $this->statusCode);
  9487. }
  9488. }
  9489. foreach ($this->headers->getCookies() as $cookie) {
  9490. setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
  9491. }
  9492. return $this;
  9493. }
  9494. public function sendContent()
  9495. {
  9496. echo $this->content;
  9497. return $this;
  9498. }
  9499. public function send()
  9500. {
  9501. $this->sendHeaders();
  9502. $this->sendContent();
  9503. if (function_exists('fastcgi_finish_request')) {
  9504. fastcgi_finish_request();
  9505. } elseif ('cli' !== PHP_SAPI) {
  9506. static::closeOutputBuffers(0, true);
  9507. flush();
  9508. }
  9509. return $this;
  9510. }
  9511. public function setContent($content)
  9512. {
  9513. if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) {
  9514. throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content)));
  9515. }
  9516. $this->content = (string) $content;
  9517. return $this;
  9518. }
  9519. public function getContent()
  9520. {
  9521. return $this->content;
  9522. }
  9523. public function setProtocolVersion($version)
  9524. {
  9525. $this->version = $version;
  9526. return $this;
  9527. }
  9528. public function getProtocolVersion()
  9529. {
  9530. return $this->version;
  9531. }
  9532. public function setStatusCode($code, $text = null)
  9533. {
  9534. $this->statusCode = $code = (int) $code;
  9535. if ($this->isInvalid()) {
  9536. throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
  9537. }
  9538. if (null === $text) {
  9539. $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : '';
  9540. return $this;
  9541. }
  9542. if (false === $text) {
  9543. $this->statusText = '';
  9544. return $this;
  9545. }
  9546. $this->statusText = $text;
  9547. return $this;
  9548. }
  9549. public function getStatusCode()
  9550. {
  9551. return $this->statusCode;
  9552. }
  9553. public function setCharset($charset)
  9554. {
  9555. $this->charset = $charset;
  9556. return $this;
  9557. }
  9558. public function getCharset()
  9559. {
  9560. return $this->charset;
  9561. }
  9562. public function isCacheable()
  9563. {
  9564. if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) {
  9565. return false;
  9566. }
  9567. if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
  9568. return false;
  9569. }
  9570. return $this->isValidateable() || $this->isFresh();
  9571. }
  9572. public function isFresh()
  9573. {
  9574. return $this->getTtl() > 0;
  9575. }
  9576. public function isValidateable()
  9577. {
  9578. return $this->headers->has('Last-Modified') || $this->headers->has('ETag');
  9579. }
  9580. public function setPrivate()
  9581. {
  9582. $this->headers->removeCacheControlDirective('public');
  9583. $this->headers->addCacheControlDirective('private');
  9584. return $this;
  9585. }
  9586. public function setPublic()
  9587. {
  9588. $this->headers->addCacheControlDirective('public');
  9589. $this->headers->removeCacheControlDirective('private');
  9590. return $this;
  9591. }
  9592. public function mustRevalidate()
  9593. {
  9594. return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('proxy-revalidate');
  9595. }
  9596. public function getDate()
  9597. {
  9598. return $this->headers->getDate('Date', new \DateTime());
  9599. }
  9600. public function setDate(\DateTime $date)
  9601. {
  9602. $date->setTimezone(new \DateTimeZone('UTC'));
  9603. $this->headers->set('Date', $date->format('D, d M Y H:i:s') . ' GMT');
  9604. return $this;
  9605. }
  9606. public function getAge()
  9607. {
  9608. if (null !== ($age = $this->headers->get('Age'))) {
  9609. return (int) $age;
  9610. }
  9611. return max(time() - $this->getDate()->format('U'), 0);
  9612. }
  9613. public function expire()
  9614. {
  9615. if ($this->isFresh()) {
  9616. $this->headers->set('Age', $this->getMaxAge());
  9617. }
  9618. return $this;
  9619. }
  9620. public function getExpires()
  9621. {
  9622. try {
  9623. return $this->headers->getDate('Expires');
  9624. } catch (\RuntimeException $e) {
  9625. return \DateTime::createFromFormat(DATE_RFC2822, 'Sat, 01 Jan 00 00:00:00 +0000');
  9626. }
  9627. }
  9628. public function setExpires(\DateTime $date = null)
  9629. {
  9630. if (null === $date) {
  9631. $this->headers->remove('Expires');
  9632. } else {
  9633. $date = clone $date;
  9634. $date->setTimezone(new \DateTimeZone('UTC'));
  9635. $this->headers->set('Expires', $date->format('D, d M Y H:i:s') . ' GMT');
  9636. }
  9637. return $this;
  9638. }
  9639. public function getMaxAge()
  9640. {
  9641. if ($this->headers->hasCacheControlDirective('s-maxage')) {
  9642. return (int) $this->headers->getCacheControlDirective('s-maxage');
  9643. }
  9644. if ($this->headers->hasCacheControlDirective('max-age')) {
  9645. return (int) $this->headers->getCacheControlDirective('max-age');
  9646. }
  9647. if (null !== $this->getExpires()) {
  9648. return $this->getExpires()->format('U') - $this->getDate()->format('U');
  9649. }
  9650. }
  9651. public function setMaxAge($value)
  9652. {
  9653. $this->headers->addCacheControlDirective('max-age', $value);
  9654. return $this;
  9655. }
  9656. public function setSharedMaxAge($value)
  9657. {
  9658. $this->setPublic();
  9659. $this->headers->addCacheControlDirective('s-maxage', $value);
  9660. return $this;
  9661. }
  9662. public function getTtl()
  9663. {
  9664. if (null !== ($maxAge = $this->getMaxAge())) {
  9665. return $maxAge - $this->getAge();
  9666. }
  9667. }
  9668. public function setTtl($seconds)
  9669. {
  9670. $this->setSharedMaxAge($this->getAge() + $seconds);
  9671. return $this;
  9672. }
  9673. public function setClientTtl($seconds)
  9674. {
  9675. $this->setMaxAge($this->getAge() + $seconds);
  9676. return $this;
  9677. }
  9678. public function getLastModified()
  9679. {
  9680. return $this->headers->getDate('Last-Modified');
  9681. }
  9682. public function setLastModified(\DateTime $date = null)
  9683. {
  9684. if (null === $date) {
  9685. $this->headers->remove('Last-Modified');
  9686. } else {
  9687. $date = clone $date;
  9688. $date->setTimezone(new \DateTimeZone('UTC'));
  9689. $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s') . ' GMT');
  9690. }
  9691. return $this;
  9692. }
  9693. public function getEtag()
  9694. {
  9695. return $this->headers->get('ETag');
  9696. }
  9697. public function setEtag($etag = null, $weak = false)
  9698. {
  9699. if (null === $etag) {
  9700. $this->headers->remove('Etag');
  9701. } else {
  9702. if (0 !== strpos($etag, '"')) {
  9703. $etag = '"' . $etag . '"';
  9704. }
  9705. $this->headers->set('ETag', (true === $weak ? 'W/' : '') . $etag);
  9706. }
  9707. return $this;
  9708. }
  9709. public function setCache(array $options)
  9710. {
  9711. if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) {
  9712. throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff))));
  9713. }
  9714. if (isset($options['etag'])) {
  9715. $this->setEtag($options['etag']);
  9716. }
  9717. if (isset($options['last_modified'])) {
  9718. $this->setLastModified($options['last_modified']);
  9719. }
  9720. if (isset($options['max_age'])) {
  9721. $this->setMaxAge($options['max_age']);
  9722. }
  9723. if (isset($options['s_maxage'])) {
  9724. $this->setSharedMaxAge($options['s_maxage']);
  9725. }
  9726. if (isset($options['public'])) {
  9727. if ($options['public']) {
  9728. $this->setPublic();
  9729. } else {
  9730. $this->setPrivate();
  9731. }
  9732. }
  9733. if (isset($options['private'])) {
  9734. if ($options['private']) {
  9735. $this->setPrivate();
  9736. } else {
  9737. $this->setPublic();
  9738. }
  9739. }
  9740. return $this;
  9741. }
  9742. public function setNotModified()
  9743. {
  9744. $this->setStatusCode(304);
  9745. $this->setContent(null);
  9746. foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) {
  9747. $this->headers->remove($header);
  9748. }
  9749. return $this;
  9750. }
  9751. public function hasVary()
  9752. {
  9753. return null !== $this->headers->get('Vary');
  9754. }
  9755. public function getVary()
  9756. {
  9757. if (!($vary = $this->headers->get('Vary', null, false))) {
  9758. return array();
  9759. }
  9760. $ret = array();
  9761. foreach ($vary as $item) {
  9762. $ret = array_merge($ret, preg_split('/[\\s,]+/', $item));
  9763. }
  9764. return $ret;
  9765. }
  9766. public function setVary($headers, $replace = true)
  9767. {
  9768. $this->headers->set('Vary', $headers, $replace);
  9769. return $this;
  9770. }
  9771. public function isNotModified(Request $request)
  9772. {
  9773. if (!$request->isMethodSafe()) {
  9774. return false;
  9775. }
  9776. $lastModified = $request->headers->get('If-Modified-Since');
  9777. $notModified = false;
  9778. if ($etags = $request->getEtags()) {
  9779. $notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified);
  9780. } elseif ($lastModified) {
  9781. $notModified = $lastModified == $this->headers->get('Last-Modified');
  9782. }
  9783. if ($notModified) {
  9784. $this->setNotModified();
  9785. }
  9786. return $notModified;
  9787. }
  9788. public function isInvalid()
  9789. {
  9790. return $this->statusCode < 100 || $this->statusCode >= 600;
  9791. }
  9792. public function isInformational()
  9793. {
  9794. return $this->statusCode >= 100 && $this->statusCode < 200;
  9795. }
  9796. public function isSuccessful()
  9797. {
  9798. return $this->statusCode >= 200 && $this->statusCode < 300;
  9799. }
  9800. public function isRedirection()
  9801. {
  9802. return $this->statusCode >= 300 && $this->statusCode < 400;
  9803. }
  9804. public function isClientError()
  9805. {
  9806. return $this->statusCode >= 400 && $this->statusCode < 500;
  9807. }
  9808. public function isServerError()
  9809. {
  9810. return $this->statusCode >= 500 && $this->statusCode < 600;
  9811. }
  9812. public function isOk()
  9813. {
  9814. return 200 === $this->statusCode;
  9815. }
  9816. public function isForbidden()
  9817. {
  9818. return 403 === $this->statusCode;
  9819. }
  9820. public function isNotFound()
  9821. {
  9822. return 404 === $this->statusCode;
  9823. }
  9824. public function isRedirect($location = null)
  9825. {
  9826. return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location'));
  9827. }
  9828. public function isEmpty()
  9829. {
  9830. return in_array($this->statusCode, array(204, 304));
  9831. }
  9832. public static function closeOutputBuffers($targetLevel, $flush)
  9833. {
  9834. $status = ob_get_status(true);
  9835. $level = count($status);
  9836. while ($level-- > $targetLevel && (!empty($status[$level]['del']) || isset($status[$level]['flags']) && $status[$level]['flags'] & PHP_OUTPUT_HANDLER_REMOVABLE && $status[$level]['flags'] & ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE))) {
  9837. if ($flush) {
  9838. ob_end_flush();
  9839. } else {
  9840. ob_end_clean();
  9841. }
  9842. }
  9843. }
  9844. protected function ensureIEOverSSLCompatibility(Request $request)
  9845. {
  9846. if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) {
  9847. if (intval(preg_replace('/(MSIE )(.*?);/', '$2', $match[0])) < 9) {
  9848. $this->headers->remove('Cache-Control');
  9849. }
  9850. }
  9851. }
  9852. }
  9853. namespace Illuminate\Http;
  9854. use ArrayObject;
  9855. use Illuminate\Support\Contracts\JsonableInterface;
  9856. use Illuminate\Support\Contracts\RenderableInterface;
  9857. class Response extends \Symfony\Component\HttpFoundation\Response
  9858. {
  9859. use ResponseTrait;
  9860. public $original;
  9861. public function setContent($content)
  9862. {
  9863. $this->original = $content;
  9864. if ($this->shouldBeJson($content)) {
  9865. $this->headers->set('Content-Type', 'application/json');
  9866. $content = $this->morphToJson($content);
  9867. } elseif ($content instanceof RenderableInterface) {
  9868. $content = $content->render();
  9869. }
  9870. return parent::setContent($content);
  9871. }
  9872. protected function morphToJson($content)
  9873. {
  9874. if ($content instanceof JsonableInterface) {
  9875. return $content->toJson();
  9876. }
  9877. return json_encode($content);
  9878. }
  9879. protected function shouldBeJson($content)
  9880. {
  9881. return $content instanceof JsonableInterface || $content instanceof ArrayObject || is_array($content);
  9882. }
  9883. public function getOriginalContent()
  9884. {
  9885. return $this->original;
  9886. }
  9887. }
  9888. namespace Symfony\Component\HttpFoundation;
  9889. class ResponseHeaderBag extends HeaderBag
  9890. {
  9891. const COOKIES_FLAT = 'flat';
  9892. const COOKIES_ARRAY = 'array';
  9893. const DISPOSITION_ATTACHMENT = 'attachment';
  9894. const DISPOSITION_INLINE = 'inline';
  9895. protected $computedCacheControl = array();
  9896. protected $cookies = array();
  9897. protected $headerNames = array();
  9898. public function __construct(array $headers = array())
  9899. {
  9900. parent::__construct($headers);
  9901. if (!isset($this->headers['cache-control'])) {
  9902. $this->set('Cache-Control', '');
  9903. }
  9904. }
  9905. public function __toString()
  9906. {
  9907. $cookies = '';
  9908. foreach ($this->getCookies() as $cookie) {
  9909. $cookies .= 'Set-Cookie: ' . $cookie . '
  9910. ';
  9911. }
  9912. ksort($this->headerNames);
  9913. return parent::__toString() . $cookies;
  9914. }
  9915. public function allPreserveCase()
  9916. {
  9917. return array_combine($this->headerNames, $this->headers);
  9918. }
  9919. public function replace(array $headers = array())
  9920. {
  9921. $this->headerNames = array();
  9922. parent::replace($headers);
  9923. if (!isset($this->headers['cache-control'])) {
  9924. $this->set('Cache-Control', '');
  9925. }
  9926. }
  9927. public function set($key, $values, $replace = true)
  9928. {
  9929. parent::set($key, $values, $replace);
  9930. $uniqueKey = strtr(strtolower($key), '_', '-');
  9931. $this->headerNames[$uniqueKey] = $key;
  9932. if (in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'))) {
  9933. $computed = $this->computeCacheControlValue();
  9934. $this->headers['cache-control'] = array($computed);
  9935. $this->headerNames['cache-control'] = 'Cache-Control';
  9936. $this->computedCacheControl = $this->parseCacheControl($computed);
  9937. }
  9938. }
  9939. public function remove($key)
  9940. {
  9941. parent::remove($key);
  9942. $uniqueKey = strtr(strtolower($key), '_', '-');
  9943. unset($this->headerNames[$uniqueKey]);
  9944. if ('cache-control' === $uniqueKey) {
  9945. $this->computedCacheControl = array();
  9946. }
  9947. }
  9948. public function hasCacheControlDirective($key)
  9949. {
  9950. return array_key_exists($key, $this->computedCacheControl);
  9951. }
  9952. public function getCacheControlDirective($key)
  9953. {
  9954. return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
  9955. }
  9956. public function setCookie(Cookie $cookie)
  9957. {
  9958. $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
  9959. }
  9960. public function removeCookie($name, $path = '/', $domain = null)
  9961. {
  9962. if (null === $path) {
  9963. $path = '/';
  9964. }
  9965. unset($this->cookies[$domain][$path][$name]);
  9966. if (empty($this->cookies[$domain][$path])) {
  9967. unset($this->cookies[$domain][$path]);
  9968. if (empty($this->cookies[$domain])) {
  9969. unset($this->cookies[$domain]);
  9970. }
  9971. }
  9972. }
  9973. public function getCookies($format = self::COOKIES_FLAT)
  9974. {
  9975. if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) {
  9976. throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY))));
  9977. }
  9978. if (self::COOKIES_ARRAY === $format) {
  9979. return $this->cookies;
  9980. }
  9981. $flattenedCookies = array();
  9982. foreach ($this->cookies as $path) {
  9983. foreach ($path as $cookies) {
  9984. foreach ($cookies as $cookie) {
  9985. $flattenedCookies[] = $cookie;
  9986. }
  9987. }
  9988. }
  9989. return $flattenedCookies;
  9990. }
  9991. public function clearCookie($name, $path = '/', $domain = null)
  9992. {
  9993. $this->setCookie(new Cookie($name, null, 1, $path, $domain));
  9994. }
  9995. public function makeDisposition($disposition, $filename, $filenameFallback = '')
  9996. {
  9997. if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
  9998. throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
  9999. }
  10000. if ('' == $filenameFallback) {
  10001. $filenameFallback = $filename;
  10002. }
  10003. if (!preg_match('/^[\\x20-\\x7e]*$/', $filenameFallback)) {
  10004. throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
  10005. }
  10006. if (false !== strpos($filenameFallback, '%')) {
  10007. throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
  10008. }
  10009. if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
  10010. throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
  10011. }
  10012. $output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
  10013. if ($filename !== $filenameFallback) {
  10014. $output .= sprintf('; filename*=utf-8\'\'%s', rawurlencode($filename));
  10015. }
  10016. return $output;
  10017. }
  10018. protected function computeCacheControlValue()
  10019. {
  10020. if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
  10021. return 'no-cache';
  10022. }
  10023. if (!$this->cacheControl) {
  10024. return 'private, must-revalidate';
  10025. }
  10026. $header = $this->getCacheControlHeader();
  10027. if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
  10028. return $header;
  10029. }
  10030. if (!isset($this->cacheControl['s-maxage'])) {
  10031. return $header . ', private';
  10032. }
  10033. return $header;
  10034. }
  10035. }
  10036. namespace Symfony\Component\HttpFoundation;
  10037. class Cookie
  10038. {
  10039. protected $name;
  10040. protected $value;
  10041. protected $domain;
  10042. protected $expire;
  10043. protected $path;
  10044. protected $secure;
  10045. protected $httpOnly;
  10046. public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true)
  10047. {
  10048. if (preg_match('/[=,;
  10049. ]/', $name)) {
  10050. throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
  10051. }
  10052. if (empty($name)) {
  10053. throw new \InvalidArgumentException('The cookie name cannot be empty.');
  10054. }
  10055. if ($expire instanceof \DateTime) {
  10056. $expire = $expire->format('U');
  10057. } elseif (!is_numeric($expire)) {
  10058. $expire = strtotime($expire);
  10059. if (false === $expire || -1 === $expire) {
  10060. throw new \InvalidArgumentException('The cookie expiration time is not valid.');
  10061. }
  10062. }
  10063. $this->name = $name;
  10064. $this->value = $value;
  10065. $this->domain = $domain;
  10066. $this->expire = $expire;
  10067. $this->path = empty($path) ? '/' : $path;
  10068. $this->secure = (bool) $secure;
  10069. $this->httpOnly = (bool) $httpOnly;
  10070. }
  10071. public function __toString()
  10072. {
  10073. $str = urlencode($this->getName()) . '=';
  10074. if ('' === (string) $this->getValue()) {
  10075. $str .= 'deleted; expires=' . gmdate('D, d-M-Y H:i:s T', time() - 31536001);
  10076. } else {
  10077. $str .= urlencode($this->getValue());
  10078. if ($this->getExpiresTime() !== 0) {
  10079. $str .= '; expires=' . gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime());
  10080. }
  10081. }
  10082. if ($this->path) {
  10083. $str .= '; path=' . $this->path;
  10084. }
  10085. if ($this->getDomain()) {
  10086. $str .= '; domain=' . $this->getDomain();
  10087. }
  10088. if (true === $this->isSecure()) {
  10089. $str .= '; secure';
  10090. }
  10091. if (true === $this->isHttpOnly()) {
  10092. $str .= '; httponly';
  10093. }
  10094. return $str;
  10095. }
  10096. public function getName()
  10097. {
  10098. return $this->name;
  10099. }
  10100. public function getValue()
  10101. {
  10102. return $this->value;
  10103. }
  10104. public function getDomain()
  10105. {
  10106. return $this->domain;
  10107. }
  10108. public function getExpiresTime()
  10109. {
  10110. return $this->expire;
  10111. }
  10112. public function getPath()
  10113. {
  10114. return $this->path;
  10115. }
  10116. public function isSecure()
  10117. {
  10118. return $this->secure;
  10119. }
  10120. public function isHttpOnly()
  10121. {
  10122. return $this->httpOnly;
  10123. }
  10124. public function isCleared()
  10125. {
  10126. return $this->expire < time();
  10127. }
  10128. }
  10129. namespace Whoops;
  10130. use Whoops\Handler\HandlerInterface;
  10131. use Whoops\Handler\Handler;
  10132. use Whoops\Handler\CallbackHandler;
  10133. use Whoops\Exception\Inspector;
  10134. use Whoops\Exception\ErrorException;
  10135. use InvalidArgumentException;
  10136. use Exception;
  10137. class Run
  10138. {
  10139. const EXCEPTION_HANDLER = 'handleException';
  10140. const ERROR_HANDLER = 'handleError';
  10141. const SHUTDOWN_HANDLER = 'handleShutdown';
  10142. protected $isRegistered;
  10143. protected $allowQuit = true;
  10144. protected $sendOutput = true;
  10145. protected $sendHttpCode = 500;
  10146. protected $handlerStack = array();
  10147. protected $silencedPatterns = array();
  10148. public function pushHandler($handler)
  10149. {
  10150. if (is_callable($handler)) {
  10151. $handler = new CallbackHandler($handler);
  10152. }
  10153. if (!$handler instanceof HandlerInterface) {
  10154. throw new InvalidArgumentException('Argument to ' . __METHOD__ . ' must be a callable, or instance of' . 'Whoops\\Handler\\HandlerInterface');
  10155. }
  10156. $this->handlerStack[] = $handler;
  10157. return $this;
  10158. }
  10159. public function popHandler()
  10160. {
  10161. return array_pop($this->handlerStack);
  10162. }
  10163. public function getHandlers()
  10164. {
  10165. return $this->handlerStack;
  10166. }
  10167. public function clearHandlers()
  10168. {
  10169. $this->handlerStack = array();
  10170. return $this;
  10171. }
  10172. protected function getInspector(Exception $exception)
  10173. {
  10174. return new Inspector($exception);
  10175. }
  10176. public function register()
  10177. {
  10178. if (!$this->isRegistered) {
  10179. class_exists('\\Whoops\\Exception\\ErrorException');
  10180. class_exists('\\Whoops\\Exception\\FrameCollection');
  10181. class_exists('\\Whoops\\Exception\\Frame');
  10182. class_exists('\\Whoops\\Exception\\Inspector');
  10183. set_error_handler(array($this, self::ERROR_HANDLER));
  10184. set_exception_handler(array($this, self::EXCEPTION_HANDLER));
  10185. register_shutdown_function(array($this, self::SHUTDOWN_HANDLER));
  10186. $this->isRegistered = true;
  10187. }
  10188. return $this;
  10189. }
  10190. public function unregister()
  10191. {
  10192. if ($this->isRegistered) {
  10193. restore_exception_handler();
  10194. restore_error_handler();
  10195. $this->isRegistered = false;
  10196. }
  10197. return $this;
  10198. }
  10199. public function allowQuit($exit = null)
  10200. {
  10201. if (func_num_args() == 0) {
  10202. return $this->allowQuit;
  10203. }
  10204. return $this->allowQuit = (bool) $exit;
  10205. }
  10206. public function silenceErrorsInPaths($patterns, $levels = 10240)
  10207. {
  10208. $this->silencedPatterns = array_merge($this->silencedPatterns, array_map(function ($pattern) use($levels) {
  10209. return array('pattern' => $pattern, 'levels' => $levels);
  10210. }, (array) $patterns));
  10211. return $this;
  10212. }
  10213. public function sendHttpCode($code = null)
  10214. {
  10215. if (func_num_args() == 0) {
  10216. return $this->sendHttpCode;
  10217. }
  10218. if (!$code) {
  10219. return $this->sendHttpCode = false;
  10220. }
  10221. if ($code === true) {
  10222. $code = 500;
  10223. }
  10224. if ($code < 400 || 600 <= $code) {
  10225. throw new InvalidArgumentException("Invalid status code '{$code}', must be 4xx or 5xx");
  10226. }
  10227. return $this->sendHttpCode = $code;
  10228. }
  10229. public function writeToOutput($send = null)
  10230. {
  10231. if (func_num_args() == 0) {
  10232. return $this->sendOutput;
  10233. }
  10234. return $this->sendOutput = (bool) $send;
  10235. }
  10236. public function handleException(Exception $exception)
  10237. {
  10238. $inspector = $this->getInspector($exception);
  10239. ob_start();
  10240. $handlerResponse = null;
  10241. foreach (array_reverse($this->handlerStack) as $handler) {
  10242. $handler->setRun($this);
  10243. $handler->setInspector($inspector);
  10244. $handler->setException($exception);
  10245. $handlerResponse = $handler->handle($exception);
  10246. if (in_array($handlerResponse, array(Handler::LAST_HANDLER, Handler::QUIT))) {
  10247. break;
  10248. }
  10249. }
  10250. $willQuit = $handlerResponse == Handler::QUIT && $this->allowQuit();
  10251. $output = ob_get_clean();
  10252. if ($this->writeToOutput()) {
  10253. if ($willQuit) {
  10254. while (ob_get_level() > 0) {
  10255. ob_end_clean();
  10256. }
  10257. }
  10258. $this->writeToOutputNow($output);
  10259. }
  10260. if ($willQuit) {
  10261. die(1);
  10262. }
  10263. return $output;
  10264. }
  10265. public function handleError($level, $message, $file = null, $line = null)
  10266. {
  10267. if ($level & error_reporting()) {
  10268. foreach ($this->silencedPatterns as $entry) {
  10269. $pathMatches = (bool) preg_match($entry['pattern'], $file);
  10270. $levelMatches = $level & $entry['levels'];
  10271. if ($pathMatches && $levelMatches) {
  10272. return true;
  10273. }
  10274. }
  10275. $exception = new ErrorException($message, $level, 0, $file, $line);
  10276. if ($this->canThrowExceptions) {
  10277. throw $exception;
  10278. } else {
  10279. $this->handleException($exception);
  10280. }
  10281. }
  10282. }
  10283. public function handleShutdown()
  10284. {
  10285. $this->canThrowExceptions = false;
  10286. $error = error_get_last();
  10287. if ($error && $this->isLevelFatal($error['type'])) {
  10288. $this->handleError($error['type'], $error['message'], $error['file'], $error['line']);
  10289. }
  10290. }
  10291. private $canThrowExceptions = true;
  10292. private function writeToOutputNow($output)
  10293. {
  10294. if ($this->sendHttpCode() && \Whoops\Util\Misc::canSendHeaders()) {
  10295. $httpCode = $this->sendHttpCode();
  10296. if (function_exists('http_response_code')) {
  10297. http_response_code($httpCode);
  10298. } else {
  10299. header('X-Ignore-This: 1', true, $httpCode);
  10300. }
  10301. }
  10302. echo $output;
  10303. return $this;
  10304. }
  10305. private static function isLevelFatal($level)
  10306. {
  10307. return in_array($level, array(E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING));
  10308. }
  10309. }
  10310. namespace Whoops\Handler;
  10311. use Whoops\Exception\Inspector;
  10312. use Whoops\Run;
  10313. use Exception;
  10314. interface HandlerInterface
  10315. {
  10316. public function handle();
  10317. public function setRun(Run $run);
  10318. public function setException(Exception $exception);
  10319. public function setInspector(Inspector $inspector);
  10320. }
  10321. namespace Whoops\Handler;
  10322. use Whoops\Handler\HandlerInterface;
  10323. use Whoops\Exception\Inspector;
  10324. use Whoops\Run;
  10325. use Exception;
  10326. abstract class Handler implements HandlerInterface
  10327. {
  10328. const DONE = 16;
  10329. const LAST_HANDLER = 32;
  10330. const QUIT = 48;
  10331. private $run;
  10332. private $inspector;
  10333. private $exception;
  10334. public function setRun(Run $run)
  10335. {
  10336. $this->run = $run;
  10337. }
  10338. protected function getRun()
  10339. {
  10340. return $this->run;
  10341. }
  10342. public function setInspector(Inspector $inspector)
  10343. {
  10344. $this->inspector = $inspector;
  10345. }
  10346. protected function getInspector()
  10347. {
  10348. return $this->inspector;
  10349. }
  10350. public function setException(Exception $exception)
  10351. {
  10352. $this->exception = $exception;
  10353. }
  10354. protected function getException()
  10355. {
  10356. return $this->exception;
  10357. }
  10358. }
  10359. namespace Whoops\Handler;
  10360. use Whoops\Handler\Handler;
  10361. use Whoops\Util\TemplateHelper;
  10362. use InvalidArgumentException;
  10363. use RuntimeException;
  10364. class PrettyPageHandler extends Handler
  10365. {
  10366. private $searchPaths = array();
  10367. private $resourceCache = array();
  10368. private $customCss = null;
  10369. private $extraTables = array();
  10370. private $handleUnconditionally = false;
  10371. private $pageTitle = 'Whoops! There was an error.';
  10372. protected $editor;
  10373. 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');
  10374. public function __construct()
  10375. {
  10376. if (ini_get('xdebug.file_link_format') || extension_loaded('xdebug')) {
  10377. $this->editors['xdebug'] = function ($file, $line) {
  10378. return str_replace(array('%f', '%l'), array($file, $line), ini_get('xdebug.file_link_format'));
  10379. };
  10380. }
  10381. $this->searchPaths[] = '/home/hristraining/website/greenWeb/vendor/filp/whoops/src/Whoops/Handler' . '/../Resources';
  10382. }
  10383. public function handle()
  10384. {
  10385. if (!$this->handleUnconditionally()) {
  10386. if (php_sapi_name() === 'cli') {
  10387. if (isset($_ENV['whoops-test'])) {
  10388. throw new \Exception('Use handleUnconditionally instead of whoops-test' . ' environment variable');
  10389. }
  10390. return Handler::DONE;
  10391. }
  10392. }
  10393. $helper = new TemplateHelper();
  10394. $templateFile = $this->getResource('views/layout.html.php');
  10395. $cssFile = $this->getResource('css/whoops.base.css');
  10396. $zeptoFile = $this->getResource('js/zepto.min.js');
  10397. $jsFile = $this->getResource('js/whoops.base.js');
  10398. if ($this->customCss) {
  10399. $customCssFile = $this->getResource($this->customCss);
  10400. }
  10401. $inspector = $this->getInspector();
  10402. $frames = $inspector->getFrames();
  10403. $vars = array('page_title' => $this->getPageTitle(), 'stylesheet' => file_get_contents($cssFile), 'zepto' => file_get_contents($zeptoFile), 'javascript' => file_get_contents($jsFile), 'header' => $this->getResource('views/header.html.php'), 'frame_list' => $this->getResource('views/frame_list.html.php'), 'frame_code' => $this->getResource('views/frame_code.html.php'), 'env_details' => $this->getResource('views/env_details.html.php'), 'title' => $this->getPageTitle(), 'name' => explode('\\', $inspector->getExceptionName()), 'message' => $inspector->getException()->getMessage(), 'frames' => $frames, 'has_frames' => !!count($frames), 'handler' => $this, 'handlers' => $this->getRun()->getHandlers(), 'tables' => array('Server/Request Data' => $_SERVER, 'GET Data' => $_GET, 'POST Data' => $_POST, 'Files' => $_FILES, 'Cookies' => $_COOKIE, 'Session' => isset($_SESSION) ? $_SESSION : array(), 'Environment Variables' => $_ENV));
  10404. if (isset($customCssFile)) {
  10405. $vars['stylesheet'] .= file_get_contents($customCssFile);
  10406. }
  10407. $extraTables = array_map(function ($table) {
  10408. return $table instanceof \Closure ? $table() : $table;
  10409. }, $this->getDataTables());
  10410. $vars['tables'] = array_merge($extraTables, $vars['tables']);
  10411. $helper->setVariables($vars);
  10412. $helper->render($templateFile);
  10413. return Handler::QUIT;
  10414. }
  10415. public function addDataTable($label, array $data)
  10416. {
  10417. $this->extraTables[$label] = $data;
  10418. }
  10419. public function addDataTableCallback($label, $callback)
  10420. {
  10421. if (!is_callable($callback)) {
  10422. throw new InvalidArgumentException('Expecting callback argument to be callable');
  10423. }
  10424. $this->extraTables[$label] = function () use($callback) {
  10425. try {
  10426. $result = call_user_func($callback);
  10427. return is_array($result) || $result instanceof \Traversable ? $result : array();
  10428. } catch (\Exception $e) {
  10429. return array();
  10430. }
  10431. };
  10432. }
  10433. public function getDataTables($label = null)
  10434. {
  10435. if ($label !== null) {
  10436. return isset($this->extraTables[$label]) ? $this->extraTables[$label] : array();
  10437. }
  10438. return $this->extraTables;
  10439. }
  10440. public function handleUnconditionally($value = null)
  10441. {
  10442. if (func_num_args() == 0) {
  10443. return $this->handleUnconditionally;
  10444. }
  10445. $this->handleUnconditionally = (bool) $value;
  10446. }
  10447. public function addEditor($identifier, $resolver)
  10448. {
  10449. $this->editors[$identifier] = $resolver;
  10450. }
  10451. public function setEditor($editor)
  10452. {
  10453. if (!is_callable($editor) && !isset($this->editors[$editor])) {
  10454. throw new InvalidArgumentException("Unknown editor identifier: {$editor}. Known editors:" . implode(',', array_keys($this->editors)));
  10455. }
  10456. $this->editor = $editor;
  10457. }
  10458. public function getEditorHref($filePath, $line)
  10459. {
  10460. if ($this->editor === null) {
  10461. return false;
  10462. }
  10463. $editor = $this->editor;
  10464. if (is_string($editor)) {
  10465. $editor = $this->editors[$editor];
  10466. }
  10467. if (is_callable($editor)) {
  10468. $editor = call_user_func($editor, $filePath, $line);
  10469. }
  10470. if (!is_string($editor)) {
  10471. throw new InvalidArgumentException(__METHOD__ . ' should always resolve to a string; got something else instead');
  10472. }
  10473. $editor = str_replace('%line', rawurlencode($line), $editor);
  10474. $editor = str_replace('%file', rawurlencode($filePath), $editor);
  10475. return $editor;
  10476. }
  10477. public function setPageTitle($title)
  10478. {
  10479. $this->pageTitle = (string) $title;
  10480. }
  10481. public function getPageTitle()
  10482. {
  10483. return $this->pageTitle;
  10484. }
  10485. public function addResourcePath($path)
  10486. {
  10487. if (!is_dir($path)) {
  10488. throw new InvalidArgumentException("'{$path}' is not a valid directory");
  10489. }
  10490. array_unshift($this->searchPaths, $path);
  10491. }
  10492. public function addCustomCss($name)
  10493. {
  10494. $this->customCss = $name;
  10495. }
  10496. public function getResourcePaths()
  10497. {
  10498. return $this->searchPaths;
  10499. }
  10500. protected function getResource($resource)
  10501. {
  10502. if (isset($this->resourceCache[$resource])) {
  10503. return $this->resourceCache[$resource];
  10504. }
  10505. foreach ($this->searchPaths as $path) {
  10506. $fullPath = $path . "/{$resource}";
  10507. if (is_file($fullPath)) {
  10508. $this->resourceCache[$resource] = $fullPath;
  10509. return $fullPath;
  10510. }
  10511. }
  10512. throw new RuntimeException("Could not find resource '{$resource}' in any resource paths." . '(searched: ' . join(', ', $this->searchPaths) . ')');
  10513. }
  10514. public function getResourcesPath()
  10515. {
  10516. $allPaths = $this->getResourcePaths();
  10517. return end($allPaths) ?: null;
  10518. }
  10519. public function setResourcesPath($resourcesPath)
  10520. {
  10521. $this->addResourcePath($resourcesPath);
  10522. }
  10523. }
  10524. namespace Whoops\Handler;
  10525. use Whoops\Handler\Handler;
  10526. use Whoops\Exception\Formatter;
  10527. class JsonResponseHandler extends Handler
  10528. {
  10529. private $returnFrames = false;
  10530. private $onlyForAjaxRequests = false;
  10531. public function addTraceToOutput($returnFrames = null)
  10532. {
  10533. if (func_num_args() == 0) {
  10534. return $this->returnFrames;
  10535. }
  10536. $this->returnFrames = (bool) $returnFrames;
  10537. return $this;
  10538. }
  10539. public function onlyForAjaxRequests($onlyForAjaxRequests = null)
  10540. {
  10541. if (func_num_args() == 0) {
  10542. return $this->onlyForAjaxRequests;
  10543. }
  10544. $this->onlyForAjaxRequests = (bool) $onlyForAjaxRequests;
  10545. }
  10546. private function isAjaxRequest()
  10547. {
  10548. return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
  10549. }
  10550. public function handle()
  10551. {
  10552. if ($this->onlyForAjaxRequests() && !$this->isAjaxRequest()) {
  10553. return Handler::DONE;
  10554. }
  10555. $response = array('error' => Formatter::formatExceptionAsDataArray($this->getInspector(), $this->addTraceToOutput()));
  10556. if (\Whoops\Util\Misc::canSendHeaders()) {
  10557. header('Content-Type: application/json');
  10558. }
  10559. echo json_encode($response);
  10560. return Handler::QUIT;
  10561. }
  10562. }
  10563. namespace Stack;
  10564. use Symfony\Component\HttpKernel\HttpKernelInterface;
  10565. class Builder
  10566. {
  10567. private $specs;
  10568. public function __construct()
  10569. {
  10570. $this->specs = new \SplStack();
  10571. }
  10572. public function unshift()
  10573. {
  10574. if (func_num_args() === 0) {
  10575. throw new \InvalidArgumentException('Missing argument(s) when calling unshift');
  10576. }
  10577. $spec = func_get_args();
  10578. $this->specs->unshift($spec);
  10579. return $this;
  10580. }
  10581. public function push()
  10582. {
  10583. if (func_num_args() === 0) {
  10584. throw new \InvalidArgumentException('Missing argument(s) when calling push');
  10585. }
  10586. $spec = func_get_args();
  10587. $this->specs->push($spec);
  10588. return $this;
  10589. }
  10590. public function resolve(HttpKernelInterface $app)
  10591. {
  10592. $middlewares = array($app);
  10593. foreach ($this->specs as $spec) {
  10594. $args = $spec;
  10595. $firstArg = array_shift($args);
  10596. if (is_callable($firstArg)) {
  10597. $app = $firstArg($app);
  10598. } else {
  10599. $kernelClass = $firstArg;
  10600. array_unshift($args, $app);
  10601. $reflection = new \ReflectionClass($kernelClass);
  10602. $app = $reflection->newInstanceArgs($args);
  10603. }
  10604. array_unshift($middlewares, $app);
  10605. }
  10606. return new StackedHttpKernel($app, $middlewares);
  10607. }
  10608. }
  10609. namespace Stack;
  10610. use Symfony\Component\HttpKernel\HttpKernelInterface;
  10611. use Symfony\Component\HttpKernel\TerminableInterface;
  10612. use Symfony\Component\HttpFoundation\Request;
  10613. use Symfony\Component\HttpFoundation\Response;
  10614. class StackedHttpKernel implements HttpKernelInterface, TerminableInterface
  10615. {
  10616. private $app;
  10617. private $middlewares = array();
  10618. public function __construct(HttpKernelInterface $app, array $middlewares)
  10619. {
  10620. $this->app = $app;
  10621. $this->middlewares = $middlewares;
  10622. }
  10623. public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  10624. {
  10625. return $this->app->handle($request, $type, $catch);
  10626. }
  10627. public function terminate(Request $request, Response $response)
  10628. {
  10629. foreach ($this->middlewares as $kernel) {
  10630. if ($kernel instanceof TerminableInterface) {
  10631. $kernel->terminate($request, $response);
  10632. }
  10633. }
  10634. }
  10635. }