PageRenderTime 57ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 2ms

/bootstrap/compiled.php

https://github.com/edubuc/starter-kit-fr
PHP | 10076 lines | 9977 code | 99 blank | 0 comment | 806 complexity | 8995d61a038fe62ec7e519b7dea5514c MD5 | raw file
  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. }
  17. public static function normalizeClass($class)
  18. {
  19. if ($class[0] == '\\') {
  20. $class = substr($class, 1);
  21. }
  22. return str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $class) . '.php';
  23. }
  24. public static function register()
  25. {
  26. if (!static::$registered) {
  27. spl_autoload_register(array('\\Illuminate\\Support\\ClassLoader', 'load'));
  28. static::$registered = true;
  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, ArrayAccess, ReflectionParameter;
  54. class BindingResolutionException extends \Exception
  55. {
  56. }
  57. class Container implements ArrayAccess
  58. {
  59. protected $bindings = array();
  60. protected $instances = array();
  61. protected $aliases = array();
  62. protected $resolvingCallbacks = array();
  63. public function bound($abstract)
  64. {
  65. return isset($this[$abstract]) or isset($this->instances[$abstract]);
  66. }
  67. public function bind($abstract, $concrete = null, $shared = false)
  68. {
  69. if (is_array($abstract)) {
  70. list($abstract, $alias) = $this->extractAlias($abstract);
  71. $this->alias($abstract, $alias);
  72. }
  73. unset($this->instances[$abstract]);
  74. if (is_null($concrete)) {
  75. $concrete = $abstract;
  76. }
  77. if (!$concrete instanceof Closure) {
  78. $concrete = function ($c) use($abstract, $concrete) {
  79. $method = $abstract == $concrete ? 'build' : 'make';
  80. return $c->{$method}($concrete);
  81. };
  82. }
  83. $this->bindings[$abstract] = compact('concrete', 'shared');
  84. }
  85. public function bindIf($abstract, $concrete = null, $shared = false)
  86. {
  87. if (!$this->bound($abstract)) {
  88. $this->bind($abstract, $concrete, $shared);
  89. }
  90. }
  91. public function singleton($abstract, $concrete = null)
  92. {
  93. return $this->bind($abstract, $concrete, true);
  94. }
  95. public function share(Closure $closure)
  96. {
  97. return function ($container) use($closure) {
  98. static $object;
  99. if (is_null($object)) {
  100. $object = $closure($container);
  101. }
  102. return $object;
  103. };
  104. }
  105. public function extend($abstract, Closure $closure)
  106. {
  107. if (!isset($this->bindings[$abstract])) {
  108. throw new \InvalidArgumentException("Type {$abstract} is not bound.");
  109. }
  110. $resolver = $this->bindings[$abstract]['concrete'];
  111. $this->bind($abstract, function ($container) use($resolver, $closure) {
  112. return $closure($resolver($container), $container);
  113. }, $this->isShared($abstract));
  114. }
  115. public function instance($abstract, $instance)
  116. {
  117. if (is_array($abstract)) {
  118. list($abstract, $alias) = $this->extractAlias($abstract);
  119. $this->alias($abstract, $alias);
  120. }
  121. $this->instances[$abstract] = $instance;
  122. }
  123. public function alias($abstract, $alias)
  124. {
  125. $this->aliases[$alias] = $abstract;
  126. }
  127. protected function extractAlias(array $definition)
  128. {
  129. return array(key($definition), current($definition));
  130. }
  131. public function make($abstract, $parameters = array())
  132. {
  133. $abstract = $this->getAlias($abstract);
  134. if (isset($this->instances[$abstract])) {
  135. return $this->instances[$abstract];
  136. }
  137. $concrete = $this->getConcrete($abstract);
  138. if ($this->isBuildable($concrete, $abstract)) {
  139. $object = $this->build($concrete, $parameters);
  140. } else {
  141. $object = $this->make($concrete, $parameters);
  142. }
  143. if ($this->isShared($abstract)) {
  144. $this->instances[$abstract] = $object;
  145. }
  146. $this->fireResolvingCallbacks($object);
  147. return $object;
  148. }
  149. protected function getConcrete($abstract)
  150. {
  151. if (!isset($this->bindings[$abstract])) {
  152. return $abstract;
  153. } else {
  154. return $this->bindings[$abstract]['concrete'];
  155. }
  156. }
  157. public function build($concrete, $parameters = array())
  158. {
  159. if ($concrete instanceof Closure) {
  160. return $concrete($this, $parameters);
  161. }
  162. $reflector = new \ReflectionClass($concrete);
  163. if (!$reflector->isInstantiable()) {
  164. $message = "Target [{$concrete}] is not instantiable.";
  165. throw new BindingResolutionException($message);
  166. }
  167. $constructor = $reflector->getConstructor();
  168. if (is_null($constructor)) {
  169. return new $concrete();
  170. }
  171. $parameters = $constructor->getParameters();
  172. $dependencies = $this->getDependencies($parameters);
  173. return $reflector->newInstanceArgs($dependencies);
  174. }
  175. protected function getDependencies($parameters)
  176. {
  177. $dependencies = array();
  178. foreach ($parameters as $parameter) {
  179. $dependency = $parameter->getClass();
  180. if (is_null($dependency)) {
  181. $dependencies[] = $this->resolveNonClass($parameter);
  182. } else {
  183. $dependencies[] = $this->make($dependency->name);
  184. }
  185. }
  186. return (array) $dependencies;
  187. }
  188. protected function resolveNonClass(ReflectionParameter $parameter)
  189. {
  190. if ($parameter->isDefaultValueAvailable()) {
  191. return $parameter->getDefaultValue();
  192. } else {
  193. $message = "Unresolvable dependency resolving [{$parameter}].";
  194. throw new BindingResolutionException($message);
  195. }
  196. }
  197. public function resolving(Closure $callback)
  198. {
  199. $this->resolvingCallbacks[] = $callback;
  200. }
  201. protected function fireResolvingCallbacks($object)
  202. {
  203. foreach ($this->resolvingCallbacks as $callback) {
  204. call_user_func($callback, $object);
  205. }
  206. }
  207. protected function isShared($abstract)
  208. {
  209. $set = isset($this->bindings[$abstract]['shared']);
  210. return $set and $this->bindings[$abstract]['shared'] === true;
  211. }
  212. protected function isBuildable($concrete, $abstract)
  213. {
  214. return $concrete === $abstract or $concrete instanceof Closure;
  215. }
  216. protected function getAlias($abstract)
  217. {
  218. return isset($this->aliases[$abstract]) ? $this->aliases[$abstract] : $abstract;
  219. }
  220. public function getBindings()
  221. {
  222. return $this->bindings;
  223. }
  224. public function offsetExists($key)
  225. {
  226. return isset($this->bindings[$key]);
  227. }
  228. public function offsetGet($key)
  229. {
  230. return $this->make($key);
  231. }
  232. public function offsetSet($key, $value)
  233. {
  234. if (!$value instanceof Closure) {
  235. $value = function () use($value) {
  236. return $value;
  237. };
  238. }
  239. $this->bind($key, $value);
  240. }
  241. public function offsetUnset($key)
  242. {
  243. unset($this->bindings[$key]);
  244. }
  245. }
  246. namespace Symfony\Component\HttpKernel;
  247. use Symfony\Component\HttpFoundation\Request;
  248. use Symfony\Component\HttpFoundation\Response;
  249. interface HttpKernelInterface
  250. {
  251. const MASTER_REQUEST = 1;
  252. const SUB_REQUEST = 2;
  253. public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
  254. }
  255. namespace Illuminate\Support\Contracts;
  256. interface ResponsePreparerInterface
  257. {
  258. public function prepareResponse($value);
  259. }
  260. namespace Illuminate\Foundation;
  261. use Closure;
  262. use Illuminate\Http\Request;
  263. use Illuminate\Http\Response;
  264. use Illuminate\Routing\Route;
  265. use Illuminate\Routing\Router;
  266. use Illuminate\Config\FileLoader;
  267. use Illuminate\Container\Container;
  268. use Illuminate\Filesystem\Filesystem;
  269. use Illuminate\Support\Facades\Facade;
  270. use Illuminate\Support\ServiceProvider;
  271. use Illuminate\Events\EventServiceProvider;
  272. use Illuminate\Foundation\ProviderRepository;
  273. use Illuminate\Routing\RoutingServiceProvider;
  274. use Illuminate\Exception\ExceptionServiceProvider;
  275. use Symfony\Component\HttpFoundation\JsonResponse;
  276. use Symfony\Component\HttpKernel\HttpKernelInterface;
  277. use Symfony\Component\HttpFoundation\StreamedResponse;
  278. use Symfony\Component\HttpKernel\Exception\HttpException;
  279. use Illuminate\Support\Contracts\ResponsePreparerInterface;
  280. use Symfony\Component\HttpKernel\Exception\FatalErrorException;
  281. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  282. use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
  283. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  284. use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirect;
  285. class Application extends Container implements HttpKernelInterface, ResponsePreparerInterface
  286. {
  287. const VERSION = '4.0.0';
  288. protected $booted = false;
  289. protected $bootingCallbacks = array();
  290. protected $bootedCallbacks = array();
  291. protected $shutdownCallbacks = array();
  292. protected $serviceProviders = array();
  293. protected $loadedProviders = array();
  294. protected $deferredServices = array();
  295. public function __construct(Request $request = null)
  296. {
  297. $this['request'] = $this->createRequest($request);
  298. $this->register(new ExceptionServiceProvider($this));
  299. $this->register(new RoutingServiceProvider($this));
  300. $this->register(new EventServiceProvider($this));
  301. }
  302. protected function createRequest(Request $request = null)
  303. {
  304. return $request ?: Request::createFromGlobals();
  305. }
  306. public function setRequestForConsoleEnvironment()
  307. {
  308. $url = $this['config']->get('app.url', 'http://localhost');
  309. $this->instance('request', Request::create($url, 'GET', array(), array(), array(), $_SERVER));
  310. }
  311. public function redirectIfTrailingSlash()
  312. {
  313. if ($this->runningInConsole()) {
  314. return;
  315. }
  316. $path = $this['request']->getPathInfo();
  317. if ($path != '/' and ends_with($path, '/') and !ends_with($path, '//')) {
  318. with(new SymfonyRedirect($this['request']->fullUrl(), 301))->send();
  319. die;
  320. }
  321. }
  322. public function bindInstallPaths(array $paths)
  323. {
  324. $this->instance('path', realpath($paths['app']));
  325. foreach (array_except($paths, array('app')) as $key => $value) {
  326. $this->instance("path.{$key}", realpath($value));
  327. }
  328. }
  329. public static function getBootstrapFile()
  330. {
  331. return 'C:\\wamp\\www\\starter-kit-fr\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation' . '/start.php';
  332. }
  333. public function startExceptionHandling()
  334. {
  335. $this['exception']->register($this->environment());
  336. $this['exception']->setDebug($this['config']['app.debug']);
  337. }
  338. public function environment()
  339. {
  340. return $this['env'];
  341. }
  342. public function detectEnvironment($environments)
  343. {
  344. $base = $this['request']->getHost();
  345. $arguments = $this['request']->server->get('argv');
  346. if ($this->runningInConsole()) {
  347. return $this->detectConsoleEnvironment($base, $environments, $arguments);
  348. }
  349. return $this->detectWebEnvironment($base, $environments);
  350. }
  351. protected function detectWebEnvironment($base, $environments)
  352. {
  353. if ($environments instanceof Closure) {
  354. return $this['env'] = call_user_func($environments);
  355. }
  356. foreach ($environments as $environment => $hosts) {
  357. foreach ((array) $hosts as $host) {
  358. if (str_is($host, $base) or $this->isMachine($host)) {
  359. return $this['env'] = $environment;
  360. }
  361. }
  362. }
  363. return $this['env'] = 'production';
  364. }
  365. protected function detectConsoleEnvironment($base, $environments, $arguments)
  366. {
  367. foreach ($arguments as $key => $value) {
  368. if (starts_with($value, '--env=')) {
  369. $segments = array_slice(explode('=', $value), 1);
  370. return $this['env'] = head($segments);
  371. }
  372. }
  373. return $this->detectWebEnvironment($base, $environments);
  374. }
  375. protected function isMachine($name)
  376. {
  377. return str_is($name, gethostname());
  378. }
  379. public function runningInConsole()
  380. {
  381. return php_sapi_name() == 'cli';
  382. }
  383. public function runningUnitTests()
  384. {
  385. return $this['env'] == 'testing';
  386. }
  387. public function register($provider, $options = array())
  388. {
  389. if (is_string($provider)) {
  390. $provider = $this->resolveProviderClass($provider);
  391. }
  392. $provider->register();
  393. foreach ($options as $key => $value) {
  394. $this[$key] = $value;
  395. }
  396. $this->serviceProviders[] = $provider;
  397. $this->loadedProviders[get_class($provider)] = true;
  398. }
  399. protected function resolveProviderClass($provider)
  400. {
  401. return new $provider($this);
  402. }
  403. public function loadDeferredProviders()
  404. {
  405. foreach (array_unique($this->deferredServices) as $provider) {
  406. $this->register($instance = new $provider($this));
  407. if ($this->booted) {
  408. $instance->boot();
  409. }
  410. }
  411. $this->deferredServices = array();
  412. }
  413. protected function loadDeferredProvider($service)
  414. {
  415. $provider = $this->deferredServices[$service];
  416. if (!isset($this->loadedProviders[$provider])) {
  417. $this->register($instance = new $provider($this));
  418. unset($this->deferredServices[$service]);
  419. $this->setupDeferredBoot($instance);
  420. }
  421. }
  422. protected function setupDeferredBoot($instance)
  423. {
  424. if ($this->booted) {
  425. return $instance->boot();
  426. }
  427. $this->booting(function () use($instance) {
  428. $instance->boot();
  429. });
  430. }
  431. public function make($abstract, $parameters = array())
  432. {
  433. if (isset($this->deferredServices[$abstract])) {
  434. $this->loadDeferredProvider($abstract);
  435. }
  436. return parent::make($abstract, $parameters);
  437. }
  438. public function before($callback)
  439. {
  440. return $this['router']->before($callback);
  441. }
  442. public function after($callback)
  443. {
  444. return $this['router']->after($callback);
  445. }
  446. public function close($callback)
  447. {
  448. return $this['router']->close($callback);
  449. }
  450. public function finish($callback)
  451. {
  452. $this['router']->finish($callback);
  453. }
  454. public function shutdown($callback = null)
  455. {
  456. if (is_null($callback)) {
  457. $this->fireAppCallbacks($this->shutdownCallbacks);
  458. } else {
  459. $this->shutdownCallbacks[] = $callback;
  460. }
  461. }
  462. public function run()
  463. {
  464. $response = $this->dispatch($this['request']);
  465. $this['router']->callCloseFilter($this['request'], $response);
  466. $response->send();
  467. $this['router']->callFinishFilter($this['request'], $response);
  468. }
  469. public function dispatch(Request $request)
  470. {
  471. if ($this->isDownForMaintenance()) {
  472. $response = $this['events']->until('illuminate.app.down');
  473. return $this->prepareResponse($response, $request);
  474. } else {
  475. return $this['router']->dispatch($this->prepareRequest($request));
  476. }
  477. }
  478. public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
  479. {
  480. $this->instance('request', $request);
  481. Facade::clearResolvedInstance('request');
  482. return $this->dispatch($request);
  483. }
  484. public function boot()
  485. {
  486. if ($this->booted) {
  487. return;
  488. }
  489. foreach ($this->serviceProviders as $provider) {
  490. $provider->boot();
  491. }
  492. $this->fireAppCallbacks($this->bootingCallbacks);
  493. $this->booted = true;
  494. $this->fireAppCallbacks($this->bootedCallbacks);
  495. }
  496. public function booting($callback)
  497. {
  498. $this->bootingCallbacks[] = $callback;
  499. }
  500. public function booted($callback)
  501. {
  502. $this->bootedCallbacks[] = $callback;
  503. }
  504. protected function fireAppCallbacks(array $callbacks)
  505. {
  506. foreach ($callbacks as $callback) {
  507. call_user_func($callback, $this);
  508. }
  509. }
  510. public function prepareRequest(Request $request)
  511. {
  512. if (isset($this['session'])) {
  513. $request->setSessionStore($this['session']);
  514. }
  515. return $request;
  516. }
  517. public function prepareResponse($value)
  518. {
  519. if (!$value instanceof SymfonyResponse) {
  520. $value = new Response($value);
  521. }
  522. return $value->prepare($this['request']);
  523. }
  524. public function isDownForMaintenance()
  525. {
  526. return file_exists($this['path.storage'] . '/meta/down');
  527. }
  528. public function down(Closure $callback)
  529. {
  530. $this['events']->listen('illuminate.app.down', $callback);
  531. }
  532. public function abort($code, $message = '', array $headers = array())
  533. {
  534. if ($code == 404) {
  535. throw new NotFoundHttpException($message);
  536. } else {
  537. throw new HttpException($code, $message, null, $headers);
  538. }
  539. }
  540. public function missing(Closure $callback)
  541. {
  542. $this->error(function (NotFoundHttpException $e) use($callback) {
  543. return call_user_func($callback, $e);
  544. });
  545. }
  546. public function error(Closure $callback)
  547. {
  548. $this['exception']->error($callback);
  549. }
  550. public function fatal(Closure $callback)
  551. {
  552. $this->error(function (FatalErrorException $e) use($callback) {
  553. return call_user_func($callback, $e);
  554. });
  555. }
  556. public function getConfigLoader()
  557. {
  558. return new FileLoader(new Filesystem(), $this['path'] . '/config');
  559. }
  560. public function getProviderRepository()
  561. {
  562. $manifest = $this['config']['app.manifest'];
  563. return new ProviderRepository(new Filesystem(), $manifest);
  564. }
  565. public function setLocale($locale)
  566. {
  567. $this['config']->set('app.locale', $locale);
  568. $this['translator']->setLocale($locale);
  569. $this['events']->fire('locale.changed', array($locale));
  570. }
  571. public function getLoadedProviders()
  572. {
  573. return $this->loadedProviders;
  574. }
  575. public function setDeferredServices(array $services)
  576. {
  577. $this->deferredServices = $services;
  578. }
  579. public function __get($key)
  580. {
  581. return $this[$key];
  582. }
  583. public function __set($key, $value)
  584. {
  585. $this[$key] = $value;
  586. }
  587. }
  588. namespace Illuminate\Http;
  589. use Illuminate\Session\Store as SessionStore;
  590. use Symfony\Component\HttpFoundation\ParameterBag;
  591. class Request extends \Symfony\Component\HttpFoundation\Request
  592. {
  593. protected $json;
  594. protected $sessionStore;
  595. public function instance()
  596. {
  597. return $this;
  598. }
  599. public function root()
  600. {
  601. return rtrim($this->getSchemeAndHttpHost() . $this->getBaseUrl(), '/');
  602. }
  603. public function url()
  604. {
  605. return rtrim(preg_replace('/\\?.*/', '', $this->getUri()), '/');
  606. }
  607. public function fullUrl()
  608. {
  609. $query = $this->getQueryString();
  610. return $query ? $this->url() . '?' . $query : $this->url();
  611. }
  612. public function path()
  613. {
  614. $pattern = trim($this->getPathInfo(), '/');
  615. return $pattern == '' ? '/' : $pattern;
  616. }
  617. public function segment($index, $default = null)
  618. {
  619. $segments = explode('/', trim($this->getPathInfo(), '/'));
  620. $segments = array_filter($segments, function ($v) {
  621. return $v != '';
  622. });
  623. return array_get($segments, $index - 1, $default);
  624. }
  625. public function segments()
  626. {
  627. $path = $this->path();
  628. return $path == '/' ? array() : explode('/', $path);
  629. }
  630. public function is($pattern)
  631. {
  632. foreach (func_get_args() as $pattern) {
  633. if (str_is($pattern, $this->path())) {
  634. return true;
  635. }
  636. }
  637. return false;
  638. }
  639. public function ajax()
  640. {
  641. return $this->isXmlHttpRequest();
  642. }
  643. public function secure()
  644. {
  645. return $this->isSecure();
  646. }
  647. public function has($key)
  648. {
  649. if (count(func_get_args()) > 1) {
  650. foreach (func_get_args() as $value) {
  651. if (!$this->has($value)) {
  652. return false;
  653. }
  654. }
  655. return true;
  656. }
  657. if (is_array($this->input($key))) {
  658. return true;
  659. }
  660. return trim((string) $this->input($key)) !== '';
  661. }
  662. public function all()
  663. {
  664. return $this->input() + $this->files->all();
  665. }
  666. public function input($key = null, $default = null)
  667. {
  668. $input = $this->getInputSource()->all() + $this->query->all();
  669. return array_get($input, $key, $default);
  670. }
  671. public function only($keys)
  672. {
  673. $keys = is_array($keys) ? $keys : func_get_args();
  674. return array_only($this->input(), $keys) + array_fill_keys($keys, null);
  675. }
  676. public function except($keys)
  677. {
  678. $keys = is_array($keys) ? $keys : func_get_args();
  679. $results = $this->input();
  680. foreach ($keys as $key) {
  681. array_forget($results, $key);
  682. }
  683. return $results;
  684. }
  685. public function query($key = null, $default = null)
  686. {
  687. return $this->retrieveItem('query', $key, $default);
  688. }
  689. public function cookie($key = null, $default = null)
  690. {
  691. return $this->retrieveItem('cookies', $key, $default);
  692. }
  693. public function file($key = null, $default = null)
  694. {
  695. return $this->retrieveItem('files', $key, $default);
  696. }
  697. public function hasFile($key)
  698. {
  699. return $this->files->has($key) and !is_null($this->file($key));
  700. }
  701. public function header($key = null, $default = null)
  702. {
  703. return $this->retrieveItem('headers', $key, $default);
  704. }
  705. public function server($key = null, $default = null)
  706. {
  707. return $this->retrieveItem('server', $key, $default);
  708. }
  709. public function old($key = null, $default = null)
  710. {
  711. return $this->getSessionStore()->getOldInput($key, $default);
  712. }
  713. public function flash($filter = null, $keys = array())
  714. {
  715. $flash = !is_null($filter) ? $this->{$filter}($keys) : $this->input();
  716. $this->getSessionStore()->flashInput($flash);
  717. }
  718. public function flashOnly($keys)
  719. {
  720. $keys = is_array($keys) ? $keys : func_get_args();
  721. return $this->flash('only', $keys);
  722. }
  723. public function flashExcept($keys)
  724. {
  725. $keys = is_array($keys) ? $keys : func_get_args();
  726. return $this->flash('except', $keys);
  727. }
  728. public function flush()
  729. {
  730. $this->getSessionStore()->flashInput(array());
  731. }
  732. protected function retrieveItem($source, $key, $default)
  733. {
  734. if (is_null($key)) {
  735. return $this->{$source}->all();
  736. } else {
  737. return $this->{$source}->get($key, $default, true);
  738. }
  739. }
  740. public function merge(array $input)
  741. {
  742. $this->getInputSource()->add($input);
  743. }
  744. public function replace(array $input)
  745. {
  746. $this->getInputSource()->replace($input);
  747. }
  748. public function json($key = null, $default = null)
  749. {
  750. if (!isset($this->json)) {
  751. $this->json = new ParameterBag((array) json_decode($this->getContent(), true));
  752. }
  753. if (is_null($key)) {
  754. return $this->json;
  755. }
  756. return array_get($this->json->all(), $key, $default);
  757. }
  758. protected function getInputSource()
  759. {
  760. if ($this->isJson()) {
  761. return $this->json();
  762. }
  763. return $this->getMethod() == 'GET' ? $this->query : $this->request;
  764. }
  765. public function isJson()
  766. {
  767. return str_contains($this->header('CONTENT_TYPE'), '/json');
  768. }
  769. public function wantsJson()
  770. {
  771. $acceptable = $this->getAcceptableContentTypes();
  772. return isset($acceptable[0]) and $acceptable[0] == 'application/json';
  773. }
  774. public function getSessionStore()
  775. {
  776. if (!isset($this->sessionStore)) {
  777. throw new \RuntimeException('Session store not set on request.');
  778. }
  779. return $this->sessionStore;
  780. }
  781. public function setSessionStore(SessionStore $session)
  782. {
  783. $this->sessionStore = $session;
  784. }
  785. public function hasSessionStore()
  786. {
  787. return isset($this->sessionStore);
  788. }
  789. }
  790. namespace Symfony\Component\HttpFoundation;
  791. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  792. class Request
  793. {
  794. const HEADER_CLIENT_IP = 'client_ip';
  795. const HEADER_CLIENT_HOST = 'client_host';
  796. const HEADER_CLIENT_PROTO = 'client_proto';
  797. const HEADER_CLIENT_PORT = 'client_port';
  798. protected static $trustedProxies = array();
  799. 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');
  800. protected static $httpMethodParameterOverride = false;
  801. public $attributes;
  802. public $request;
  803. public $query;
  804. public $server;
  805. public $files;
  806. public $cookies;
  807. public $headers;
  808. protected $content;
  809. protected $languages;
  810. protected $charsets;
  811. protected $acceptableContentTypes;
  812. protected $pathInfo;
  813. protected $requestUri;
  814. protected $baseUrl;
  815. protected $basePath;
  816. protected $method;
  817. protected $format;
  818. protected $session;
  819. protected $locale;
  820. protected $defaultLocale = 'en';
  821. protected static $formats;
  822. public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
  823. {
  824. $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
  825. }
  826. public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
  827. {
  828. $this->request = new ParameterBag($request);
  829. $this->query = new ParameterBag($query);
  830. $this->attributes = new ParameterBag($attributes);
  831. $this->cookies = new ParameterBag($cookies);
  832. $this->files = new FileBag($files);
  833. $this->server = new ServerBag($server);
  834. $this->headers = new HeaderBag($this->server->getHeaders());
  835. $this->content = $content;
  836. $this->languages = null;
  837. $this->charsets = null;
  838. $this->acceptableContentTypes = null;
  839. $this->pathInfo = null;
  840. $this->requestUri = null;
  841. $this->baseUrl = null;
  842. $this->basePath = null;
  843. $this->method = null;
  844. $this->format = null;
  845. }
  846. public static function createFromGlobals()
  847. {
  848. $request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
  849. 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'))) {
  850. parse_str($request->getContent(), $data);
  851. $request->request = new ParameterBag($data);
  852. }
  853. return $request;
  854. }
  855. public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
  856. {
  857. $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);
  858. $server['PATH_INFO'] = '';
  859. $server['REQUEST_METHOD'] = strtoupper($method);
  860. $components = parse_url($uri);
  861. if (isset($components['host'])) {
  862. $server['SERVER_NAME'] = $components['host'];
  863. $server['HTTP_HOST'] = $components['host'];
  864. }
  865. if (isset($components['scheme'])) {
  866. if ('https' === $components['scheme']) {
  867. $server['HTTPS'] = 'on';
  868. $server['SERVER_PORT'] = 443;
  869. } else {
  870. unset($server['HTTPS']);
  871. $server['SERVER_PORT'] = 80;
  872. }
  873. }
  874. if (isset($components['port'])) {
  875. $server['SERVER_PORT'] = $components['port'];
  876. $server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $components['port'];
  877. }
  878. if (isset($components['user'])) {
  879. $server['PHP_AUTH_USER'] = $components['user'];
  880. }
  881. if (isset($components['pass'])) {
  882. $server['PHP_AUTH_PW'] = $components['pass'];
  883. }
  884. if (!isset($components['path'])) {
  885. $components['path'] = '/';
  886. }
  887. switch (strtoupper($method)) {
  888. case 'POST':
  889. case 'PUT':
  890. case 'DELETE':
  891. if (!isset($server['CONTENT_TYPE'])) {
  892. $server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
  893. }
  894. case 'PATCH':
  895. $request = $parameters;
  896. $query = array();
  897. break;
  898. default:
  899. $request = array();
  900. $query = $parameters;
  901. break;
  902. }
  903. if (isset($components['query'])) {
  904. parse_str(html_entity_decode($components['query']), $qs);
  905. $query = array_replace($qs, $query);
  906. }
  907. $queryString = http_build_query($query, '', '&');
  908. $server['REQUEST_URI'] = $components['path'] . ('' !== $queryString ? '?' . $queryString : '');
  909. $server['QUERY_STRING'] = $queryString;
  910. return new static($query, $request, array(), $cookies, $files, $server, $content);
  911. }
  912. public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
  913. {
  914. $dup = clone $this;
  915. if ($query !== null) {
  916. $dup->query = new ParameterBag($query);
  917. }
  918. if ($request !== null) {
  919. $dup->request = new ParameterBag($request);
  920. }
  921. if ($attributes !== null) {
  922. $dup->attributes = new ParameterBag($attributes);
  923. }
  924. if ($cookies !== null) {
  925. $dup->cookies = new ParameterBag($cookies);
  926. }
  927. if ($files !== null) {
  928. $dup->files = new FileBag($files);
  929. }
  930. if ($server !== null) {
  931. $dup->server = new ServerBag($server);
  932. $dup->headers = new HeaderBag($dup->server->getHeaders());
  933. }
  934. $dup->languages = null;
  935. $dup->charsets = null;
  936. $dup->acceptableContentTypes = null;
  937. $dup->pathInfo = null;
  938. $dup->requestUri = null;
  939. $dup->baseUrl = null;
  940. $dup->basePath = null;
  941. $dup->method = null;
  942. $dup->format = null;
  943. return $dup;
  944. }
  945. public function __clone()
  946. {
  947. $this->query = clone $this->query;
  948. $this->request = clone $this->request;
  949. $this->attributes = clone $this->attributes;
  950. $this->cookies = clone $this->cookies;
  951. $this->files = clone $this->files;
  952. $this->server = clone $this->server;
  953. $this->headers = clone $this->headers;
  954. }
  955. public function __toString()
  956. {
  957. return sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL')) . '
  958. ' . $this->headers . '
  959. ' . $this->getContent();
  960. }
  961. public function overrideGlobals()
  962. {
  963. $_GET = $this->query->all();
  964. $_POST = $this->request->all();
  965. $_SERVER = $this->server->all();
  966. $_COOKIE = $this->cookies->all();
  967. foreach ($this->headers->all() as $key => $value) {
  968. $key = strtoupper(str_replace('-', '_', $key));
  969. if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
  970. $_SERVER[$key] = implode(', ', $value);
  971. } else {
  972. $_SERVER['HTTP_' . $key] = implode(', ', $value);
  973. }
  974. }
  975. $request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE);
  976. $requestOrder = ini_get('request_order') ?: ini_get('variable_order');
  977. $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
  978. $_REQUEST = array();
  979. foreach (str_split($requestOrder) as $order) {
  980. $_REQUEST = array_merge($_REQUEST, $request[$order]);
  981. }
  982. }
  983. public static function setTrustedProxies(array $proxies)
  984. {
  985. self::$trustedProxies = $proxies;
  986. }
  987. public static function getTrustedProxies()
  988. {
  989. return self::$trustedProxies;
  990. }
  991. public static function setTrustedHeaderName($key, $value)
  992. {
  993. if (!array_key_exists($key, self::$trustedHeaders)) {
  994. throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
  995. }
  996. self::$trustedHeaders[$key] = $value;
  997. }
  998. public static function getTrustedHeaderName($key)
  999. {
  1000. if (!array_key_exists($key, self::$trustedHeaders)) {
  1001. throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key));
  1002. }
  1003. return self::$trustedHeaders[$key];
  1004. }
  1005. public static function normalizeQueryString($qs)
  1006. {
  1007. if ('' == $qs) {
  1008. return '';
  1009. }
  1010. $parts = array();
  1011. $order = array();
  1012. foreach (explode('&', $qs) as $param) {
  1013. if ('' === $param || '=' === $param[0]) {
  1014. continue;
  1015. }
  1016. $keyValuePair = explode('=', $param, 2);
  1017. $parts[] = isset($keyValuePair[1]) ? rawurlencode(urldecode($keyValuePair[0])) . '=' . rawurlencode(urldecode($keyValuePair[1])) : rawurlencode(urldecode($keyValuePair[0]));
  1018. $order[] = urldecode($keyValuePair[0]);
  1019. }
  1020. array_multisort($order, SORT_ASC, $parts);
  1021. return implode('&', $parts);
  1022. }
  1023. public static function enableHttpMethodParameterOverride()
  1024. {
  1025. self::$httpMethodParameterOverride = true;
  1026. }
  1027. public static function getHttpMethodParameterOverride()
  1028. {
  1029. return self::$httpMethodParameterOverride;
  1030. }
  1031. public function get($key, $default = null, $deep = false)
  1032. {
  1033. return $this->query->get($key, $this->attributes->get($key, $this->request->get($key, $default, $deep), $deep), $deep);
  1034. }
  1035. public function getSession()
  1036. {
  1037. return $this->session;
  1038. }
  1039. public function hasPreviousSession()
  1040. {
  1041. return $this->hasSession() && $this->cookies->has($this->session->getName());
  1042. }
  1043. public function hasSession()
  1044. {
  1045. return null !== $this->session;
  1046. }
  1047. public function setSession(SessionInterface $session)
  1048. {
  1049. $this->session = $session;
  1050. }
  1051. public function getClientIps()
  1052. {
  1053. $ip = $this->server->get('REMOTE_ADDR');
  1054. if (!self::$trustedProxies) {
  1055. return array($ip);
  1056. }
  1057. if (!self::$trustedHeaders[self::HEADER_CLIENT_IP] || !$this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
  1058. return array($ip);
  1059. }
  1060. $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
  1061. $clientIps[] = $ip;
  1062. $trustedProxies = !self::$trustedProxies ? array($ip) : self::$trustedProxies;
  1063. $ip = $clientIps[0];
  1064. foreach ($clientIps as $key => $clientIp) {
  1065. if (IpUtils::checkIp($clientIp, $trustedProxies)) {
  1066. unset($clientIps[$key]);
  1067. continue;
  1068. }
  1069. }
  1070. return $clientIps ? array_reverse($clientIps) : array($ip);
  1071. }
  1072. public function getClientIp()
  1073. {
  1074. $ipAddresses = $this->getClientIps();
  1075. return $ipAddresses[0];
  1076. }
  1077. public function getScriptName()
  1078. {
  1079. return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
  1080. }
  1081. public function getPathInfo()
  1082. {
  1083. if (null === $this->pathInfo) {
  1084. $this->pathInfo = $this->preparePathInfo();
  1085. }
  1086. return $this->pathInfo;
  1087. }
  1088. public function getBasePath()
  1089. {
  1090. if (null === $this->basePath) {
  1091. $this->basePath = $this->prepareBasePath();
  1092. }
  1093. return $this->basePath;
  1094. }
  1095. public function getBaseUrl()
  1096. {
  1097. if (null === $this->baseUrl) {
  1098. $this->baseUrl = $this->prepareBaseUrl();
  1099. }
  1100. return $this->baseUrl;
  1101. }
  1102. public function getScheme()
  1103. {
  1104. return $this->isSecure() ? 'https' : 'http';
  1105. }
  1106. public function getPort()
  1107. {
  1108. if (self::$trustedProxies) {
  1109. if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && ($port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT]))) {
  1110. return $port;
  1111. }
  1112. if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && 'https' === $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO], 'http')) {
  1113. return 443;
  1114. }
  1115. }
  1116. return $this->server->get('SERVER_PORT');
  1117. }
  1118. public function getUser()
  1119. {
  1120. return $this->server->get('PHP_AUTH_USER');
  1121. }
  1122. public function getPassword()
  1123. {
  1124. return $this->server->get('PHP_AUTH_PW');
  1125. }
  1126. public function getUserInfo()
  1127. {
  1128. $userinfo = $this->getUser();
  1129. $pass = $this->getPassword();
  1130. if ('' != $pass) {
  1131. $userinfo .= ":{$pass}";
  1132. }
  1133. return $userinfo;
  1134. }
  1135. public function getHttpHost()
  1136. {
  1137. $scheme = $this->getScheme();
  1138. $port = $this->getPort();
  1139. if ('http' == $scheme && $port == 80 || 'https' == $scheme && $port == 443) {
  1140. return $this->getHost();
  1141. }
  1142. return $this->getHost() . ':' . $port;
  1143. }
  1144. public function getRequestUri()
  1145. {
  1146. if (null === $this->requestUri) {
  1147. $this->requestUri = $this->prepareRequestUri();
  1148. }
  1149. return $this->requestUri;
  1150. }
  1151. public function getSchemeAndHttpHost()
  1152. {
  1153. return $this->getScheme() . '://' . $this->getHttpHost();
  1154. }
  1155. public function getUri()
  1156. {
  1157. if (null !== ($qs = $this->getQueryString())) {
  1158. $qs = '?' . $qs;
  1159. }
  1160. return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $this->getPathInfo() . $qs;
  1161. }
  1162. public function getUriForPath($path)
  1163. {
  1164. return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $path;
  1165. }
  1166. public function getQueryString()
  1167. {
  1168. $qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
  1169. return '' === $qs ? null : $qs;
  1170. }
  1171. public function isSecure()
  1172. {
  1173. if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && ($proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO]))) {
  1174. return in_array(strtolower($proto), array('https', 'on', '1'));
  1175. }
  1176. return 'on' == strtolower($this->server->get('HTTPS')) || 1 == $this->server->get('HTTPS');
  1177. }
  1178. public function getHost()
  1179. {
  1180. if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && ($host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST]))) {
  1181. $elements = explode(',', $host);
  1182. $host = $elements[count($elements) - 1];
  1183. } elseif (!($host = $this->headers->get('HOST'))) {
  1184. if (!($host = $this->server->get('SERVER_NAME'))) {
  1185. $host = $this->server->get('SERVER_ADDR', '');
  1186. }
  1187. }
  1188. $host = strtolower(preg_replace('/:\\d+$/', '', trim($host)));
  1189. if ($host && !preg_match('/^\\[?(?:[a-zA-Z0-9-:\\]_]+\\.?)+$/', $host)) {
  1190. throw new \UnexpectedValueException('Invalid Host');
  1191. }
  1192. return $host;
  1193. }
  1194. public function setMethod($method)
  1195. {
  1196. $this->method = null;
  1197. $this->server->set('REQUEST_METHOD', $method);
  1198. }
  1199. public function getMethod()
  1200. {
  1201. if (null === $this->method) {
  1202. $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
  1203. if ('POST' === $this->method) {
  1204. if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
  1205. $this->method = strtoupper($method);
  1206. } elseif (self::$httpMethodParameterOverride) {
  1207. $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
  1208. }
  1209. }
  1210. }
  1211. return $this->method;
  1212. }
  1213. public function getRealMethod()
  1214. {
  1215. return strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
  1216. }
  1217. public function getMimeType($format)
  1218. {
  1219. if (null === static::$formats) {
  1220. static::initializeFormats();
  1221. }
  1222. return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
  1223. }
  1224. public function getFormat($mimeType)
  1225. {
  1226. if (false !== ($pos = strpos($mimeType, ';'))) {
  1227. $mimeType = substr($mimeType, 0, $pos);
  1228. }
  1229. if (null === static::$formats) {
  1230. static::initializeFormats();
  1231. }
  1232. foreach (static::$formats as $format => $mimeTypes) {
  1233. if (in_array($mimeType, (array) $mimeTypes)) {
  1234. return $format;
  1235. }
  1236. }
  1237. return null;
  1238. }
  1239. public function setFormat($format, $mimeTypes)
  1240. {
  1241. if (null === static::$formats) {
  1242. static::initializeFormats();
  1243. }
  1244. static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
  1245. }
  1246. public function getRequestFormat($default = 'html')
  1247. {
  1248. if (null === $this->format) {
  1249. $this->format = $this->get('_format', $default);
  1250. }
  1251. return $this->format;
  1252. }
  1253. public function setRequestFormat($format)
  1254. {
  1255. $this->format = $format;
  1256. }
  1257. public function getContentType()
  1258. {
  1259. return $this->getFormat($this->headers->get('CONTENT_TYPE'));
  1260. }
  1261. public function setDefaultLocale($locale)
  1262. {
  1263. $this->defaultLocale = $locale;
  1264. if (null === $this->locale) {
  1265. $this->setPhpDefaultLocale($locale);
  1266. }
  1267. }
  1268. public function setLocale($locale)
  1269. {
  1270. $this->setPhpDefaultLocale($this->locale = $locale);
  1271. }
  1272. public function getLocale()
  1273. {
  1274. return null === $this->locale ? $this->defaultLocale : $this->locale;
  1275. }
  1276. public function isMethod($method)
  1277. {
  1278. return $this->getMethod() === strtoupper($method);
  1279. }
  1280. public function isMethodSafe()
  1281. {
  1282. return in_array($this->getMethod(), array('GET', 'HEAD'));
  1283. }
  1284. public function getContent($asResource = false)
  1285. {
  1286. if (false === $this->content || true === $asResource && null !== $this->content) {
  1287. throw new \LogicException('getContent() can only be called once when using the resource return type.');
  1288. }
  1289. if (true === $asResource) {
  1290. $this->content = false;
  1291. return fopen('php://input', 'rb');
  1292. }
  1293. if (null === $this->content) {
  1294. $this->content = file_get_contents('php://input');
  1295. }
  1296. return $this->content;
  1297. }
  1298. public function getETags()
  1299. {
  1300. return preg_split('/\\s*,\\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
  1301. }
  1302. public function isNoCache()
  1303. {
  1304. return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
  1305. }
  1306. public function getPreferredLanguage(array $locales = null)
  1307. {
  1308. $preferredLanguages = $this->getLanguages();
  1309. if (empty($locales)) {
  1310. return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null;
  1311. }
  1312. if (!$preferredLanguages) {
  1313. return $locales[0];
  1314. }
  1315. $extendedPreferredLanguages = array();
  1316. foreach ($preferredLanguages as $language) {
  1317. $extendedPreferredLanguages[] = $language;
  1318. if (false !== ($position = strpos($language, '_'))) {
  1319. $superLanguage = substr($language, 0, $position);
  1320. if (!in_array($superLanguage, $preferredLanguages)) {
  1321. $extendedPreferredLanguages[] = $superLanguage;
  1322. }
  1323. }
  1324. }
  1325. $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
  1326. return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
  1327. }
  1328. public function getLanguages()
  1329. {
  1330. if (null !== $this->languages) {
  1331. return $this->languages;
  1332. }
  1333. $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
  1334. $this->languages = array();
  1335. foreach (array_keys($languages) as $lang) {
  1336. if (strstr($lang, '-')) {
  1337. $codes = explode('-', $lang);
  1338. if ($codes[0] == 'i') {
  1339. if (count($codes) > 1) {
  1340. $lang = $codes[1];
  1341. }
  1342. } else {
  1343. for ($i = 0, $max = count($codes); $i < $max; $i++) {
  1344. if ($i == 0) {
  1345. $lang = strtolower($codes[0]);
  1346. } else {
  1347. $lang .= '_' . strtoupper($codes[$i]);
  1348. }
  1349. }
  1350. }
  1351. }
  1352. $this->languages[] = $lang;
  1353. }
  1354. return $this->languages;
  1355. }
  1356. public function getCharsets()
  1357. {
  1358. if (null !== $this->charsets) {
  1359. return $this->charsets;
  1360. }
  1361. return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
  1362. }
  1363. public function getAcceptableContentTypes()
  1364. {
  1365. if (null !== $this->acceptableContentTypes) {
  1366. return $this->acceptableContentTypes;
  1367. }
  1368. return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
  1369. }
  1370. public function isXmlHttpRequest()
  1371. {
  1372. return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
  1373. }
  1374. protected function prepareRequestUri()
  1375. {
  1376. $requestUri = '';
  1377. if ($this->headers->has('X_ORIGINAL_URL')) {
  1378. $requestUri = $this->headers->get('X_ORIGINAL_URL');
  1379. $this->headers->remove('X_ORIGINAL_URL');
  1380. $this->server->remove('HTTP_X_ORIGINAL_URL');
  1381. $this->server->remove('UNENCODED_URL');
  1382. $this->server->remove('IIS_WasUrlRewritten');
  1383. } elseif ($this->headers->has('X_REWRITE_URL')) {
  1384. $requestUri = $this->headers->get('X_REWRITE_URL');
  1385. $this->headers->remove('X_REWRITE_URL');
  1386. } elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
  1387. $requestUri = $this->server->get('UNENCODED_URL');
  1388. $this->server->remove('UNENCODED_URL');
  1389. $this->server->remove('IIS_WasUrlRewritten');
  1390. } elseif ($this->server->has('REQUEST_URI')) {
  1391. $requestUri = $this->server->get('REQUEST_URI');
  1392. $schemeAndHttpHost = $this->getSchemeAndHttpHost();
  1393. if (strpos($requestUri, $schemeAndHttpHost) === 0) {
  1394. $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
  1395. }
  1396. } elseif ($this->server->has('ORIG_PATH_INFO')) {
  1397. $requestUri = $this->server->get('ORIG_PATH_INFO');
  1398. if ('' != $this->server->get('QUERY_STRING')) {
  1399. $requestUri .= '?' . $this->server->get('QUERY_STRING');
  1400. }
  1401. $this->server->remove('ORIG_PATH_INFO');
  1402. }
  1403. $this->server->set('REQUEST_URI', $requestUri);
  1404. return $requestUri;
  1405. }
  1406. protected function prepareBaseUrl()
  1407. {
  1408. $filename = basename($this->server->get('SCRIPT_FILENAME'));
  1409. if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
  1410. $baseUrl = $this->server->get('SCRIPT_NAME');
  1411. } elseif (basename($this->server->get('PHP_SELF')) === $filename) {
  1412. $baseUrl = $this->server->get('PHP_SELF');
  1413. } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
  1414. $baseUrl = $this->server->get('ORIG_SCRIPT_NAME');
  1415. } else {
  1416. $path = $this->server->get('PHP_SELF', '');
  1417. $file = $this->server->get('SCRIPT_FILENAME', '');
  1418. $segs = explode('/', trim($file, '/'));
  1419. $segs = array_reverse($segs);
  1420. $index = 0;
  1421. $last = count($segs);
  1422. $baseUrl = '';
  1423. do {
  1424. $seg = $segs[$index];
  1425. $baseUrl = '/' . $seg . $baseUrl;
  1426. ++$index;
  1427. } while ($last > $index && false !== ($pos = strpos($path, $baseUrl)) && 0 != $pos);
  1428. }
  1429. $requestUri = $this->getRequestUri();
  1430. if ($baseUrl && false !== ($prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl))) {
  1431. return $prefix;
  1432. }
  1433. if ($baseUrl && false !== ($prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl)))) {
  1434. return rtrim($prefix, '/');
  1435. }
  1436. $truncatedRequestUri = $requestUri;
  1437. if (($pos = strpos($requestUri, '?')) !== false) {
  1438. $truncatedRequestUri = substr($requestUri, 0, $pos);
  1439. }
  1440. $basename = basename($baseUrl);
  1441. if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
  1442. return '';
  1443. }
  1444. if (strlen($requestUri) >= strlen($baseUrl) && (false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0)) {
  1445. $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
  1446. }
  1447. return rtrim($baseUrl, '/');
  1448. }
  1449. protected function prepareBasePath()
  1450. {
  1451. $filename = basename($this->server->get('SCRIPT_FILENAME'));
  1452. $baseUrl = $this->getBaseUrl();
  1453. if (empty($baseUrl)) {
  1454. return '';
  1455. }
  1456. if (basename($baseUrl) === $filename) {
  1457. $basePath = dirname($baseUrl);
  1458. } else {
  1459. $basePath = $baseUrl;
  1460. }
  1461. if ('\\' === DIRECTORY_SEPARATOR) {
  1462. $basePath = str_replace('\\', '/', $basePath);
  1463. }
  1464. return rtrim($basePath, '/');
  1465. }
  1466. protected function preparePathInfo()
  1467. {
  1468. $baseUrl = $this->getBaseUrl();
  1469. if (null === ($requestUri = $this->getRequestUri())) {
  1470. return '/';
  1471. }
  1472. $pathInfo = '/';
  1473. if ($pos = strpos($requestUri, '?')) {
  1474. $requestUri = substr($requestUri, 0, $pos);
  1475. }
  1476. if (null !== $baseUrl && false === ($pathInfo = substr($requestUri, strlen($baseUrl)))) {
  1477. return '/';
  1478. } elseif (null === $baseUrl) {
  1479. return $requestUri;
  1480. }
  1481. return (string) $pathInfo;
  1482. }
  1483. protected static function initializeFormats()
  1484. {
  1485. 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'));
  1486. }
  1487. private function setPhpDefaultLocale($locale)
  1488. {
  1489. try {
  1490. if (class_exists('Locale', false)) {
  1491. \Locale::setDefault($locale);
  1492. }
  1493. } catch (\Exception $e) {
  1494. }
  1495. }
  1496. private function getUrlencodedPrefix($string, $prefix)
  1497. {
  1498. if (0 !== strpos(rawurldecode($string), $prefix)) {
  1499. return false;
  1500. }
  1501. $len = strlen($prefix);
  1502. if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
  1503. return $match[0];
  1504. }
  1505. return false;
  1506. }
  1507. }
  1508. namespace Symfony\Component\HttpFoundation;
  1509. class ParameterBag implements \IteratorAggregate, \Countable
  1510. {
  1511. protected $parameters;
  1512. public function __construct(array $parameters = array())
  1513. {
  1514. $this->parameters = $parameters;
  1515. }
  1516. public function all()
  1517. {
  1518. return $this->parameters;
  1519. }
  1520. public function keys()
  1521. {
  1522. return array_keys($this->parameters);
  1523. }
  1524. public function replace(array $parameters = array())
  1525. {
  1526. $this->parameters = $parameters;
  1527. }
  1528. public function add(array $parameters = array())
  1529. {
  1530. $this->parameters = array_replace($this->parameters, $parameters);
  1531. }
  1532. public function get($path, $default = null, $deep = false)
  1533. {
  1534. if (!$deep || false === ($pos = strpos($path, '['))) {
  1535. return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default;
  1536. }
  1537. $root = substr($path, 0, $pos);
  1538. if (!array_key_exists($root, $this->parameters)) {
  1539. return $default;
  1540. }
  1541. $value = $this->parameters[$root];
  1542. $currentKey = null;
  1543. for ($i = $pos, $c = strlen($path); $i < $c; $i++) {
  1544. $char = $path[$i];
  1545. if ('[' === $char) {
  1546. if (null !== $currentKey) {
  1547. throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i));
  1548. }
  1549. $currentKey = '';
  1550. } elseif (']' === $char) {
  1551. if (null === $currentKey) {
  1552. throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i));
  1553. }
  1554. if (!is_array($value) || !array_key_exists($currentKey, $value)) {
  1555. return $default;
  1556. }
  1557. $value = $value[$currentKey];
  1558. $currentKey = null;
  1559. } else {
  1560. if (null === $currentKey) {
  1561. throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i));
  1562. }
  1563. $currentKey .= $char;
  1564. }
  1565. }
  1566. if (null !== $currentKey) {
  1567. throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".'));
  1568. }
  1569. return $value;
  1570. }
  1571. public function set($key, $value)
  1572. {
  1573. $this->parameters[$key] = $value;
  1574. }
  1575. public function has($key)
  1576. {
  1577. return array_key_exists($key, $this->parameters);
  1578. }
  1579. public function remove($key)
  1580. {
  1581. unset($this->parameters[$key]);
  1582. }
  1583. public function getAlpha($key, $default = '', $deep = false)
  1584. {
  1585. return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep));
  1586. }
  1587. public function getAlnum($key, $default = '', $deep = false)
  1588. {
  1589. return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep));
  1590. }
  1591. public function getDigits($key, $default = '', $deep = false)
  1592. {
  1593. return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT));
  1594. }
  1595. public function getInt($key, $default = 0, $deep = false)
  1596. {
  1597. return (int) $this->get($key, $default, $deep);
  1598. }
  1599. public function filter($key, $default = null, $deep = false, $filter = FILTER_DEFAULT, $options = array())
  1600. {
  1601. $value = $this->get($key, $default, $deep);
  1602. if (!is_array($options) && $options) {
  1603. $options = array('flags' => $options);
  1604. }
  1605. if (is_array($value) && !isset($options['flags'])) {
  1606. $options['flags'] = FILTER_REQUIRE_ARRAY;
  1607. }
  1608. return filter_var($value, $filter, $options);
  1609. }
  1610. public function getIterator()
  1611. {
  1612. return new \ArrayIterator($this->parameters);
  1613. }
  1614. public function count()
  1615. {
  1616. return count($this->parameters);
  1617. }
  1618. }
  1619. namespace Symfony\Component\HttpFoundation;
  1620. use Symfony\Component\HttpFoundation\File\UploadedFile;
  1621. class FileBag extends ParameterBag
  1622. {
  1623. private static $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
  1624. public function __construct(array $parameters = array())
  1625. {
  1626. $this->replace($parameters);
  1627. }
  1628. public function replace(array $files = array())
  1629. {
  1630. $this->parameters = array();
  1631. $this->add($files);
  1632. }
  1633. public function set($key, $value)
  1634. {
  1635. if (!is_array($value) && !$value instanceof UploadedFile) {
  1636. throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
  1637. }
  1638. parent::set($key, $this->convertFileInformation($value));
  1639. }
  1640. public function add(array $files = array())
  1641. {
  1642. foreach ($files as $key => $file) {
  1643. $this->set($key, $file);
  1644. }
  1645. }
  1646. protected function convertFileInformation($file)
  1647. {
  1648. if ($file instanceof UploadedFile) {
  1649. return $file;
  1650. }
  1651. $file = $this->fixPhpFilesArray($file);
  1652. if (is_array($file)) {
  1653. $keys = array_keys($file);
  1654. sort($keys);
  1655. if ($keys == self::$fileKeys) {
  1656. if (UPLOAD_ERR_NO_FILE == $file['error']) {
  1657. $file = null;
  1658. } else {
  1659. $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
  1660. }
  1661. } else {
  1662. $file = array_map(array($this, 'convertFileInformation'), $file);
  1663. }
  1664. }
  1665. return $file;
  1666. }
  1667. protected function fixPhpFilesArray($data)
  1668. {
  1669. if (!is_array($data)) {
  1670. return $data;
  1671. }
  1672. $keys = array_keys($data);
  1673. sort($keys);
  1674. if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
  1675. return $data;
  1676. }
  1677. $files = $data;
  1678. foreach (self::$fileKeys as $k) {
  1679. unset($files[$k]);
  1680. }
  1681. foreach (array_keys($data['name']) as $key) {
  1682. $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]));
  1683. }
  1684. return $files;
  1685. }
  1686. }
  1687. namespace Symfony\Component\HttpFoundation;
  1688. class ServerBag extends ParameterBag
  1689. {
  1690. public function getHeaders()
  1691. {
  1692. $headers = array();
  1693. $contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
  1694. foreach ($this->parameters as $key => $value) {
  1695. if (0 === strpos($key, 'HTTP_')) {
  1696. $headers[substr($key, 5)] = $value;
  1697. } elseif (isset($contentHeaders[$key])) {
  1698. $headers[$key] = $value;
  1699. }
  1700. }
  1701. if (isset($this->parameters['PHP_AUTH_USER'])) {
  1702. $headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER'];
  1703. $headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
  1704. } else {
  1705. $authorizationHeader = null;
  1706. if (isset($this->parameters['HTTP_AUTHORIZATION'])) {
  1707. $authorizationHeader = $this->parameters['HTTP_AUTHORIZATION'];
  1708. } elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
  1709. $authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION'];
  1710. }
  1711. if (null !== $authorizationHeader && 0 === stripos($authorizationHeader, 'basic')) {
  1712. $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)));
  1713. if (count($exploded) == 2) {
  1714. list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
  1715. }
  1716. }
  1717. }
  1718. if (isset($headers['PHP_AUTH_USER'])) {
  1719. $headers['AUTHORIZATION'] = 'Basic ' . base64_encode($headers['PHP_AUTH_USER'] . ':' . $headers['PHP_AUTH_PW']);
  1720. }
  1721. return $headers;
  1722. }
  1723. }
  1724. namespace Symfony\Component\HttpFoundation;
  1725. class HeaderBag implements \IteratorAggregate, \Countable
  1726. {
  1727. protected $headers;
  1728. protected $cacheControl;
  1729. public function __construct(array $headers = array())
  1730. {
  1731. $this->cacheControl = array();
  1732. $this->headers = array();
  1733. foreach ($headers as $key => $values) {
  1734. $this->set($key, $values);
  1735. }
  1736. }
  1737. public function __toString()
  1738. {
  1739. if (!$this->headers) {
  1740. return '';
  1741. }
  1742. $max = max(array_map('strlen', array_keys($this->headers))) + 1;
  1743. $content = '';
  1744. ksort($this->headers);
  1745. foreach ($this->headers as $name => $values) {
  1746. $name = implode('-', array_map('ucfirst', explode('-', $name)));
  1747. foreach ($values as $value) {
  1748. $content .= sprintf("%-{$max}s %s\r\n", $name . ':', $value);
  1749. }
  1750. }
  1751. return $content;
  1752. }
  1753. public function all()
  1754. {
  1755. return $this->headers;
  1756. }
  1757. public function keys()
  1758. {
  1759. return array_keys($this->headers);
  1760. }
  1761. public function replace(array $headers = array())
  1762. {
  1763. $this->headers = array();
  1764. $this->add($headers);
  1765. }
  1766. public function add(array $headers)
  1767. {
  1768. foreach ($headers as $key => $values) {
  1769. $this->set($key, $values);
  1770. }
  1771. }
  1772. public function get($key, $default = null, $first = true)
  1773. {
  1774. $key = strtr(strtolower($key), '_', '-');
  1775. if (!array_key_exists($key, $this->headers)) {
  1776. if (null === $default) {
  1777. return $first ? null : array();
  1778. }
  1779. return $first ? $default : array($default);
  1780. }
  1781. if ($first) {
  1782. return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
  1783. }
  1784. return $this->headers[$key];
  1785. }
  1786. public function set($key, $values, $replace = true)
  1787. {
  1788. $key = strtr(strtolower($key), '_', '-');
  1789. $values = array_values((array) $values);
  1790. if (true === $replace || !isset($this->headers[$key])) {
  1791. $this->headers[$key] = $values;
  1792. } else {
  1793. $this->headers[$key] = array_merge($this->headers[$key], $values);
  1794. }
  1795. if ('cache-control' === $key) {
  1796. $this->cacheControl = $this->parseCacheControl($values[0]);
  1797. }
  1798. }
  1799. public function has($key)
  1800. {
  1801. return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers);
  1802. }
  1803. public function contains($key, $value)
  1804. {
  1805. return in_array($value, $this->get($key, null, false));
  1806. }
  1807. public function remove($key)
  1808. {
  1809. $key = strtr(strtolower($key), '_', '-');
  1810. unset($this->headers[$key]);
  1811. if ('cache-control' === $key) {
  1812. $this->cacheControl = array();
  1813. }
  1814. }
  1815. public function getDate($key, \DateTime $default = null)
  1816. {
  1817. if (null === ($value = $this->get($key))) {
  1818. return $default;
  1819. }
  1820. if (false === ($date = \DateTime::createFromFormat(DATE_RFC2822, $value))) {
  1821. throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
  1822. }
  1823. return $date;
  1824. }
  1825. public function addCacheControlDirective($key, $value = true)
  1826. {
  1827. $this->cacheControl[$key] = $value;
  1828. $this->set('Cache-Control', $this->getCacheControlHeader());
  1829. }
  1830. public function hasCacheControlDirective($key)
  1831. {
  1832. return array_key_exists($key, $this->cacheControl);
  1833. }
  1834. public function getCacheControlDirective($key)
  1835. {
  1836. return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
  1837. }
  1838. public function removeCacheControlDirective($key)
  1839. {
  1840. unset($this->cacheControl[$key]);
  1841. $this->set('Cache-Control', $this->getCacheControlHeader());
  1842. }
  1843. public function getIterator()
  1844. {
  1845. return new \ArrayIterator($this->headers);
  1846. }
  1847. public function count()
  1848. {
  1849. return count($this->headers);
  1850. }
  1851. protected function getCacheControlHeader()
  1852. {
  1853. $parts = array();
  1854. ksort($this->cacheControl);
  1855. foreach ($this->cacheControl as $key => $value) {
  1856. if (true === $value) {
  1857. $parts[] = $key;
  1858. } else {
  1859. if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
  1860. $value = '"' . $value . '"';
  1861. }
  1862. $parts[] = "{$key}={$value}";
  1863. }
  1864. }
  1865. return implode(', ', $parts);
  1866. }
  1867. protected function parseCacheControl($header)
  1868. {
  1869. $cacheControl = array();
  1870. preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\\s*(?:=(?:"([^"]*)"|([^ \\t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
  1871. foreach ($matches as $match) {
  1872. $cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
  1873. }
  1874. return $cacheControl;
  1875. }
  1876. }
  1877. namespace Symfony\Component\HttpFoundation\Session;
  1878. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  1879. interface SessionInterface
  1880. {
  1881. public function start();
  1882. public function getId();
  1883. public function setId($id);
  1884. public function getName();
  1885. public function setName($name);
  1886. public function invalidate($lifetime = null);
  1887. public function migrate($destroy = false, $lifetime = null);
  1888. public function save();
  1889. public function has($name);
  1890. public function get($name, $default = null);
  1891. public function set($name, $value);
  1892. public function all();
  1893. public function replace(array $attributes);
  1894. public function remove($name);
  1895. public function clear();
  1896. public function isStarted();
  1897. public function registerBag(SessionBagInterface $bag);
  1898. public function getBag($name);
  1899. public function getMetadataBag();
  1900. }
  1901. namespace Symfony\Component\HttpFoundation\Session\Storage;
  1902. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  1903. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  1904. interface SessionStorageInterface
  1905. {
  1906. public function start();
  1907. public function isStarted();
  1908. public function getId();
  1909. public function setId($id);
  1910. public function getName();
  1911. public function setName($name);
  1912. public function regenerate($destroy = false, $lifetime = null);
  1913. public function save();
  1914. public function clear();
  1915. public function getBag($name);
  1916. public function registerBag(SessionBagInterface $bag);
  1917. public function getMetadataBag();
  1918. }
  1919. namespace Symfony\Component\HttpFoundation\Session;
  1920. interface SessionBagInterface
  1921. {
  1922. public function getName();
  1923. public function initialize(array &$array);
  1924. public function getStorageKey();
  1925. public function clear();
  1926. }
  1927. namespace Symfony\Component\HttpFoundation\Session\Attribute;
  1928. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  1929. interface AttributeBagInterface extends SessionBagInterface
  1930. {
  1931. public function has($name);
  1932. public function get($name, $default = null);
  1933. public function set($name, $value);
  1934. public function all();
  1935. public function replace(array $attributes);
  1936. public function remove($name);
  1937. }
  1938. namespace Symfony\Component\HttpFoundation\Session;
  1939. use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
  1940. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
  1941. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  1942. use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
  1943. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  1944. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  1945. use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
  1946. class Session implements SessionInterface, \IteratorAggregate, \Countable
  1947. {
  1948. protected $storage;
  1949. private $flashName;
  1950. private $attributeName;
  1951. public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
  1952. {
  1953. $this->storage = $storage ?: new NativeSessionStorage();
  1954. $attributes = $attributes ?: new AttributeBag();
  1955. $this->attributeName = $attributes->getName();
  1956. $this->registerBag($attributes);
  1957. $flashes = $flashes ?: new FlashBag();
  1958. $this->flashName = $flashes->getName();
  1959. $this->registerBag($flashes);
  1960. }
  1961. public function start()
  1962. {
  1963. return $this->storage->start();
  1964. }
  1965. public function has($name)
  1966. {
  1967. return $this->storage->getBag($this->attributeName)->has($name);
  1968. }
  1969. public function get($name, $default = null)
  1970. {
  1971. return $this->storage->getBag($this->attributeName)->get($name, $default);
  1972. }
  1973. public function set($name, $value)
  1974. {
  1975. $this->storage->getBag($this->attributeName)->set($name, $value);
  1976. }
  1977. public function all()
  1978. {
  1979. return $this->storage->getBag($this->attributeName)->all();
  1980. }
  1981. public function replace(array $attributes)
  1982. {
  1983. $this->storage->getBag($this->attributeName)->replace($attributes);
  1984. }
  1985. public function remove($name)
  1986. {
  1987. return $this->storage->getBag($this->attributeName)->remove($name);
  1988. }
  1989. public function clear()
  1990. {
  1991. $this->storage->getBag($this->attributeName)->clear();
  1992. }
  1993. public function isStarted()
  1994. {
  1995. return $this->storage->isStarted();
  1996. }
  1997. public function getIterator()
  1998. {
  1999. return new \ArrayIterator($this->storage->getBag($this->attributeName)->all());
  2000. }
  2001. public function count()
  2002. {
  2003. return count($this->storage->getBag($this->attributeName)->all());
  2004. }
  2005. public function invalidate($lifetime = null)
  2006. {
  2007. $this->storage->clear();
  2008. return $this->migrate(true, $lifetime);
  2009. }
  2010. public function migrate($destroy = false, $lifetime = null)
  2011. {
  2012. return $this->storage->regenerate($destroy, $lifetime);
  2013. }
  2014. public function save()
  2015. {
  2016. $this->storage->save();
  2017. }
  2018. public function getId()
  2019. {
  2020. return $this->storage->getId();
  2021. }
  2022. public function setId($id)
  2023. {
  2024. $this->storage->setId($id);
  2025. }
  2026. public function getName()
  2027. {
  2028. return $this->storage->getName();
  2029. }
  2030. public function setName($name)
  2031. {
  2032. $this->storage->setName($name);
  2033. }
  2034. public function getMetadataBag()
  2035. {
  2036. return $this->storage->getMetadataBag();
  2037. }
  2038. public function registerBag(SessionBagInterface $bag)
  2039. {
  2040. $this->storage->registerBag($bag);
  2041. }
  2042. public function getBag($name)
  2043. {
  2044. return $this->storage->getBag($name);
  2045. }
  2046. public function getFlashBag()
  2047. {
  2048. return $this->getBag($this->flashName);
  2049. }
  2050. }
  2051. namespace Symfony\Component\HttpFoundation\Session\Storage;
  2052. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  2053. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
  2054. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  2055. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
  2056. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
  2057. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
  2058. class NativeSessionStorage implements SessionStorageInterface
  2059. {
  2060. protected $bags;
  2061. protected $started = false;
  2062. protected $closed = false;
  2063. protected $saveHandler;
  2064. protected $metadataBag;
  2065. public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
  2066. {
  2067. session_cache_limiter('');
  2068. ini_set('session.use_cookies', 1);
  2069. if (version_compare(phpversion(), '5.4.0', '>=')) {
  2070. session_register_shutdown();
  2071. } else {
  2072. register_shutdown_function('session_write_close');
  2073. }
  2074. $this->setMetadataBag($metaBag);
  2075. $this->setOptions($options);
  2076. $this->setSaveHandler($handler);
  2077. }
  2078. public function getSaveHandler()
  2079. {
  2080. return $this->saveHandler;
  2081. }
  2082. public function start()
  2083. {
  2084. if ($this->started && !$this->closed) {
  2085. return true;
  2086. }
  2087. if (version_compare(phpversion(), '5.4.0', '>=') && \PHP_SESSION_ACTIVE === session_status()) {
  2088. throw new \RuntimeException('Failed to start the session: already started by PHP.');
  2089. }
  2090. if (version_compare(phpversion(), '5.4.0', '<') && isset($_SESSION) && session_id()) {
  2091. throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
  2092. }
  2093. if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
  2094. throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
  2095. }
  2096. if (!session_start()) {
  2097. throw new \RuntimeException('Failed to start the session');
  2098. }
  2099. $this->loadSession();
  2100. if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
  2101. $this->saveHandler->setActive(true);
  2102. }
  2103. return true;
  2104. }
  2105. public function getId()
  2106. {
  2107. if (!$this->started) {
  2108. return '';
  2109. }
  2110. return $this->saveHandler->getId();
  2111. }
  2112. public function setId($id)
  2113. {
  2114. $this->saveHandler->setId($id);
  2115. }
  2116. public function getName()
  2117. {
  2118. return $this->saveHandler->getName();
  2119. }
  2120. public function setName($name)
  2121. {
  2122. $this->saveHandler->setName($name);
  2123. }
  2124. public function regenerate($destroy = false, $lifetime = null)
  2125. {
  2126. if (null !== $lifetime) {
  2127. ini_set('session.cookie_lifetime', $lifetime);
  2128. }
  2129. if ($destroy) {
  2130. $this->metadataBag->stampNew();
  2131. }
  2132. return session_regenerate_id($destroy);
  2133. }
  2134. public function save()
  2135. {
  2136. session_write_close();
  2137. if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
  2138. $this->saveHandler->setActive(false);
  2139. }
  2140. $this->closed = true;
  2141. }
  2142. public function clear()
  2143. {
  2144. foreach ($this->bags as $bag) {
  2145. $bag->clear();
  2146. }
  2147. $_SESSION = array();
  2148. $this->loadSession();
  2149. }
  2150. public function registerBag(SessionBagInterface $bag)
  2151. {
  2152. $this->bags[$bag->getName()] = $bag;
  2153. }
  2154. public function getBag($name)
  2155. {
  2156. if (!isset($this->bags[$name])) {
  2157. throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
  2158. }
  2159. if ($this->saveHandler->isActive() && !$this->started) {
  2160. $this->loadSession();
  2161. } elseif (!$this->started) {
  2162. $this->start();
  2163. }
  2164. return $this->bags[$name];
  2165. }
  2166. public function setMetadataBag(MetadataBag $metaBag = null)
  2167. {
  2168. if (null === $metaBag) {
  2169. $metaBag = new MetadataBag();
  2170. }
  2171. $this->metadataBag = $metaBag;
  2172. }
  2173. public function getMetadataBag()
  2174. {
  2175. return $this->metadataBag;
  2176. }
  2177. public function isStarted()
  2178. {
  2179. return $this->started;
  2180. }
  2181. public function setOptions(array $options)
  2182. {
  2183. $validOptions = array_flip(array('cache_limiter', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', 'hash_function', 'name', 'referer_check', 'serialize_handler', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'));
  2184. foreach ($options as $key => $value) {
  2185. if (isset($validOptions[$key])) {
  2186. ini_set('session.' . $key, $value);
  2187. }
  2188. }
  2189. }
  2190. public function setSaveHandler($saveHandler = null)
  2191. {
  2192. if (!$saveHandler instanceof AbstractProxy && !$saveHandler instanceof NativeSessionHandler && !$saveHandler instanceof \SessionHandlerInterface && null !== $saveHandler) {
  2193. throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \\SessionHandlerInterface; or be null.');
  2194. }
  2195. if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
  2196. $saveHandler = new SessionHandlerProxy($saveHandler);
  2197. } elseif (!$saveHandler instanceof AbstractProxy) {
  2198. $saveHandler = version_compare(phpversion(), '5.4.0', '>=') ? new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy();
  2199. }
  2200. $this->saveHandler = $saveHandler;
  2201. if ($this->saveHandler instanceof \SessionHandlerInterface) {
  2202. if (version_compare(phpversion(), '5.4.0', '>=')) {
  2203. session_set_save_handler($this->saveHandler, false);
  2204. } else {
  2205. session_set_save_handler(array($this->saveHandler, 'open'), array($this->saveHandler, 'close'), array($this->saveHandler, 'read'), array($this->saveHandler, 'write'), array($this->saveHandler, 'destroy'), array($this->saveHandler, 'gc'));
  2206. }
  2207. }
  2208. }
  2209. protected function loadSession(array &$session = null)
  2210. {
  2211. if (null === $session) {
  2212. $session =& $_SESSION;
  2213. }
  2214. $bags = array_merge($this->bags, array($this->metadataBag));
  2215. foreach ($bags as $bag) {
  2216. $key = $bag->getStorageKey();
  2217. $session[$key] = isset($session[$key]) ? $session[$key] : array();
  2218. $bag->initialize($session[$key]);
  2219. }
  2220. $this->started = true;
  2221. $this->closed = false;
  2222. }
  2223. }
  2224. namespace Symfony\Component\HttpFoundation\Session\Attribute;
  2225. class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable
  2226. {
  2227. private $name = 'attributes';
  2228. private $storageKey;
  2229. protected $attributes = array();
  2230. public function __construct($storageKey = '_sf2_attributes')
  2231. {
  2232. $this->storageKey = $storageKey;
  2233. }
  2234. public function getName()
  2235. {
  2236. return $this->name;
  2237. }
  2238. public function setName($name)
  2239. {
  2240. $this->name = $name;
  2241. }
  2242. public function initialize(array &$attributes)
  2243. {
  2244. $this->attributes =& $attributes;
  2245. }
  2246. public function getStorageKey()
  2247. {
  2248. return $this->storageKey;
  2249. }
  2250. public function has($name)
  2251. {
  2252. return array_key_exists($name, $this->attributes);
  2253. }
  2254. public function get($name, $default = null)
  2255. {
  2256. return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
  2257. }
  2258. public function set($name, $value)
  2259. {
  2260. $this->attributes[$name] = $value;
  2261. }
  2262. public function all()
  2263. {
  2264. return $this->attributes;
  2265. }
  2266. public function replace(array $attributes)
  2267. {
  2268. $this->attributes = array();
  2269. foreach ($attributes as $key => $value) {
  2270. $this->set($key, $value);
  2271. }
  2272. }
  2273. public function remove($name)
  2274. {
  2275. $retval = null;
  2276. if (array_key_exists($name, $this->attributes)) {
  2277. $retval = $this->attributes[$name];
  2278. unset($this->attributes[$name]);
  2279. }
  2280. return $retval;
  2281. }
  2282. public function clear()
  2283. {
  2284. $return = $this->attributes;
  2285. $this->attributes = array();
  2286. return $return;
  2287. }
  2288. public function getIterator()
  2289. {
  2290. return new \ArrayIterator($this->attributes);
  2291. }
  2292. public function count()
  2293. {
  2294. return count($this->attributes);
  2295. }
  2296. }
  2297. namespace Symfony\Component\HttpFoundation\Session\Flash;
  2298. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  2299. interface FlashBagInterface extends SessionBagInterface
  2300. {
  2301. public function add($type, $message);
  2302. public function set($type, $message);
  2303. public function peek($type, array $default = array());
  2304. public function peekAll();
  2305. public function get($type, array $default = array());
  2306. public function all();
  2307. public function setAll(array $messages);
  2308. public function has($type);
  2309. public function keys();
  2310. }
  2311. namespace Symfony\Component\HttpFoundation\Session\Flash;
  2312. class FlashBag implements FlashBagInterface, \IteratorAggregate
  2313. {
  2314. private $name = 'flashes';
  2315. private $flashes = array();
  2316. private $storageKey;
  2317. public function __construct($storageKey = '_sf2_flashes')
  2318. {
  2319. $this->storageKey = $storageKey;
  2320. }
  2321. public function getName()
  2322. {
  2323. return $this->name;
  2324. }
  2325. public function setName($name)
  2326. {
  2327. $this->name = $name;
  2328. }
  2329. public function initialize(array &$flashes)
  2330. {
  2331. $this->flashes =& $flashes;
  2332. }
  2333. public function add($type, $message)
  2334. {
  2335. $this->flashes[$type][] = $message;
  2336. }
  2337. public function peek($type, array $default = array())
  2338. {
  2339. return $this->has($type) ? $this->flashes[$type] : $default;
  2340. }
  2341. public function peekAll()
  2342. {
  2343. return $this->flashes;
  2344. }
  2345. public function get($type, array $default = array())
  2346. {
  2347. if (!$this->has($type)) {
  2348. return $default;
  2349. }
  2350. $return = $this->flashes[$type];
  2351. unset($this->flashes[$type]);
  2352. return $return;
  2353. }
  2354. public function all()
  2355. {
  2356. $return = $this->peekAll();
  2357. $this->flashes = array();
  2358. return $return;
  2359. }
  2360. public function set($type, $messages)
  2361. {
  2362. $this->flashes[$type] = (array) $messages;
  2363. }
  2364. public function setAll(array $messages)
  2365. {
  2366. $this->flashes = $messages;
  2367. }
  2368. public function has($type)
  2369. {
  2370. return array_key_exists($type, $this->flashes) && $this->flashes[$type];
  2371. }
  2372. public function keys()
  2373. {
  2374. return array_keys($this->flashes);
  2375. }
  2376. public function getStorageKey()
  2377. {
  2378. return $this->storageKey;
  2379. }
  2380. public function clear()
  2381. {
  2382. return $this->all();
  2383. }
  2384. public function getIterator()
  2385. {
  2386. return new \ArrayIterator($this->all());
  2387. }
  2388. }
  2389. namespace Symfony\Component\HttpFoundation\Session\Flash;
  2390. class AutoExpireFlashBag implements FlashBagInterface
  2391. {
  2392. private $name = 'flashes';
  2393. private $flashes = array();
  2394. private $storageKey;
  2395. public function __construct($storageKey = '_sf2_flashes')
  2396. {
  2397. $this->storageKey = $storageKey;
  2398. $this->flashes = array('display' => array(), 'new' => array());
  2399. }
  2400. public function getName()
  2401. {
  2402. return $this->name;
  2403. }
  2404. public function setName($name)
  2405. {
  2406. $this->name = $name;
  2407. }
  2408. public function initialize(array &$flashes)
  2409. {
  2410. $this->flashes =& $flashes;
  2411. $this->flashes['display'] = array_key_exists('new', $this->flashes) ? $this->flashes['new'] : array();
  2412. $this->flashes['new'] = array();
  2413. }
  2414. public function add($type, $message)
  2415. {
  2416. $this->flashes['new'][$type][] = $message;
  2417. }
  2418. public function peek($type, array $default = array())
  2419. {
  2420. return $this->has($type) ? $this->flashes['display'][$type] : $default;
  2421. }
  2422. public function peekAll()
  2423. {
  2424. return array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : array();
  2425. }
  2426. public function get($type, array $default = array())
  2427. {
  2428. $return = $default;
  2429. if (!$this->has($type)) {
  2430. return $return;
  2431. }
  2432. if (isset($this->flashes['display'][$type])) {
  2433. $return = $this->flashes['display'][$type];
  2434. unset($this->flashes['display'][$type]);
  2435. }
  2436. return $return;
  2437. }
  2438. public function all()
  2439. {
  2440. $return = $this->flashes['display'];
  2441. $this->flashes = array('new' => array(), 'display' => array());
  2442. return $return;
  2443. }
  2444. public function setAll(array $messages)
  2445. {
  2446. $this->flashes['new'] = $messages;
  2447. }
  2448. public function set($type, $messages)
  2449. {
  2450. $this->flashes['new'][$type] = (array) $messages;
  2451. }
  2452. public function has($type)
  2453. {
  2454. return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
  2455. }
  2456. public function keys()
  2457. {
  2458. return array_keys($this->flashes['display']);
  2459. }
  2460. public function getStorageKey()
  2461. {
  2462. return $this->storageKey;
  2463. }
  2464. public function clear()
  2465. {
  2466. return $this->all();
  2467. }
  2468. }
  2469. namespace Symfony\Component\HttpFoundation\Session\Storage;
  2470. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  2471. class MetadataBag implements SessionBagInterface
  2472. {
  2473. const CREATED = 'c';
  2474. const UPDATED = 'u';
  2475. const LIFETIME = 'l';
  2476. private $name = '__metadata';
  2477. private $storageKey;
  2478. protected $meta = array();
  2479. private $lastUsed;
  2480. public function __construct($storageKey = '_sf2_meta')
  2481. {
  2482. $this->storageKey = $storageKey;
  2483. $this->meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0);
  2484. }
  2485. public function initialize(array &$array)
  2486. {
  2487. $this->meta =& $array;
  2488. if (isset($array[self::CREATED])) {
  2489. $this->lastUsed = $this->meta[self::UPDATED];
  2490. $this->meta[self::UPDATED] = time();
  2491. } else {
  2492. $this->stampCreated();
  2493. }
  2494. }
  2495. public function getLifetime()
  2496. {
  2497. return $this->meta[self::LIFETIME];
  2498. }
  2499. public function stampNew($lifetime = null)
  2500. {
  2501. $this->stampCreated($lifetime);
  2502. }
  2503. public function getStorageKey()
  2504. {
  2505. return $this->storageKey;
  2506. }
  2507. public function getCreated()
  2508. {
  2509. return $this->meta[self::CREATED];
  2510. }
  2511. public function getLastUsed()
  2512. {
  2513. return $this->lastUsed;
  2514. }
  2515. public function clear()
  2516. {
  2517. }
  2518. public function getName()
  2519. {
  2520. return $this->name;
  2521. }
  2522. public function setName($name)
  2523. {
  2524. $this->name = $name;
  2525. }
  2526. private function stampCreated($lifetime = null)
  2527. {
  2528. $timeStamp = time();
  2529. $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
  2530. $this->meta[self::LIFETIME] = null === $lifetime ? ini_get('session.cookie_lifetime') : $lifetime;
  2531. }
  2532. }
  2533. namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
  2534. if (version_compare(phpversion(), '5.4.0', '>=')) {
  2535. class NativeSessionHandler extends \SessionHandler
  2536. {
  2537. }
  2538. } else {
  2539. class NativeSessionHandler
  2540. {
  2541. }
  2542. }
  2543. namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
  2544. abstract class AbstractProxy
  2545. {
  2546. protected $wrapper = false;
  2547. protected $active = false;
  2548. protected $saveHandlerName;
  2549. public function getSaveHandlerName()
  2550. {
  2551. return $this->saveHandlerName;
  2552. }
  2553. public function isSessionHandlerInterface()
  2554. {
  2555. return $this instanceof \SessionHandlerInterface;
  2556. }
  2557. public function isWrapper()
  2558. {
  2559. return $this->wrapper;
  2560. }
  2561. public function isActive()
  2562. {
  2563. if (version_compare(phpversion(), '5.4.0', '>=')) {
  2564. return $this->active = \PHP_SESSION_ACTIVE === session_status();
  2565. }
  2566. return $this->active;
  2567. }
  2568. public function setActive($flag)
  2569. {
  2570. if (version_compare(phpversion(), '5.4.0', '>=')) {
  2571. throw new \LogicException('This method is disabled in PHP 5.4.0+');
  2572. }
  2573. $this->active = (bool) $flag;
  2574. }
  2575. public function getId()
  2576. {
  2577. return session_id();
  2578. }
  2579. public function setId($id)
  2580. {
  2581. if ($this->isActive()) {
  2582. throw new \LogicException('Cannot change the ID of an active session');
  2583. }
  2584. session_id($id);
  2585. }
  2586. public function getName()
  2587. {
  2588. return session_name();
  2589. }
  2590. public function setName($name)
  2591. {
  2592. if ($this->isActive()) {
  2593. throw new \LogicException('Cannot change the name of an active session');
  2594. }
  2595. session_name($name);
  2596. }
  2597. }
  2598. namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
  2599. class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface
  2600. {
  2601. protected $handler;
  2602. public function __construct(\SessionHandlerInterface $handler)
  2603. {
  2604. $this->handler = $handler;
  2605. $this->wrapper = $handler instanceof \SessionHandler;
  2606. $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user';
  2607. }
  2608. public function open($savePath, $sessionName)
  2609. {
  2610. $return = (bool) $this->handler->open($savePath, $sessionName);
  2611. if (true === $return) {
  2612. $this->active = true;
  2613. }
  2614. return $return;
  2615. }
  2616. public function close()
  2617. {
  2618. $this->active = false;
  2619. return (bool) $this->handler->close();
  2620. }
  2621. public function read($id)
  2622. {
  2623. return (string) $this->handler->read($id);
  2624. }
  2625. public function write($id, $data)
  2626. {
  2627. return (bool) $this->handler->write($id, $data);
  2628. }
  2629. public function destroy($id)
  2630. {
  2631. return (bool) $this->handler->destroy($id);
  2632. }
  2633. public function gc($maxlifetime)
  2634. {
  2635. return (bool) $this->handler->gc($maxlifetime);
  2636. }
  2637. }
  2638. namespace Symfony\Component\HttpFoundation;
  2639. class AcceptHeaderItem
  2640. {
  2641. private $value;
  2642. private $quality = 1.0;
  2643. private $index = 0;
  2644. private $attributes = array();
  2645. public function __construct($value, array $attributes = array())
  2646. {
  2647. $this->value = $value;
  2648. foreach ($attributes as $name => $value) {
  2649. $this->setAttribute($name, $value);
  2650. }
  2651. }
  2652. public static function fromString($itemValue)
  2653. {
  2654. $bits = preg_split('/\\s*(?:;*("[^"]+");*|;*(\'[^\']+\');*|;+)\\s*/', $itemValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
  2655. $value = array_shift($bits);
  2656. $attributes = array();
  2657. $lastNullAttribute = null;
  2658. foreach ($bits as $bit) {
  2659. if (($start = substr($bit, 0, 1)) === ($end = substr($bit, -1)) && ($start === '"' || $start === '\'')) {
  2660. $attributes[$lastNullAttribute] = substr($bit, 1, -1);
  2661. } elseif ('=' === $end) {
  2662. $lastNullAttribute = $bit = substr($bit, 0, -1);
  2663. $attributes[$bit] = null;
  2664. } else {
  2665. $parts = explode('=', $bit);
  2666. $attributes[$parts[0]] = isset($parts[1]) && strlen($parts[1]) > 0 ? $parts[1] : '';
  2667. }
  2668. }
  2669. return new self(($start = substr($value, 0, 1)) === ($end = substr($value, -1)) && ($start === '"' || $start === '\'') ? substr($value, 1, -1) : $value, $attributes);
  2670. }
  2671. public function __toString()
  2672. {
  2673. $string = $this->value . ($this->quality < 1 ? ';q=' . $this->quality : '');
  2674. if (count($this->attributes) > 0) {
  2675. $string .= ';' . implode(';', array_map(function ($name, $value) {
  2676. return sprintf(preg_match('/[,;=]/', $value) ? '%s="%s"' : '%s=%s', $name, $value);
  2677. }, array_keys($this->attributes), $this->attributes));
  2678. }
  2679. return $string;
  2680. }
  2681. public function setValue($value)
  2682. {
  2683. $this->value = $value;
  2684. return $this;
  2685. }
  2686. public function getValue()
  2687. {
  2688. return $this->value;
  2689. }
  2690. public function setQuality($quality)
  2691. {
  2692. $this->quality = $quality;
  2693. return $this;
  2694. }
  2695. public function getQuality()
  2696. {
  2697. return $this->quality;
  2698. }
  2699. public function setIndex($index)
  2700. {
  2701. $this->index = $index;
  2702. return $this;
  2703. }
  2704. public function getIndex()
  2705. {
  2706. return $this->index;
  2707. }
  2708. public function hasAttribute($name)
  2709. {
  2710. return isset($this->attributes[$name]);
  2711. }
  2712. public function getAttribute($name, $default = null)
  2713. {
  2714. return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
  2715. }
  2716. public function getAttributes()
  2717. {
  2718. return $this->attributes;
  2719. }
  2720. public function setAttribute($name, $value)
  2721. {
  2722. if ('q' === $name) {
  2723. $this->quality = (double) $value;
  2724. } else {
  2725. $this->attributes[$name] = (string) $value;
  2726. }
  2727. return $this;
  2728. }
  2729. }
  2730. namespace Symfony\Component\HttpFoundation;
  2731. class AcceptHeader
  2732. {
  2733. private $items = array();
  2734. private $sorted = true;
  2735. public function __construct(array $items)
  2736. {
  2737. foreach ($items as $item) {
  2738. $this->add($item);
  2739. }
  2740. }
  2741. public static function fromString($headerValue)
  2742. {
  2743. $index = 0;
  2744. return new self(array_map(function ($itemValue) use(&$index) {
  2745. $item = AcceptHeaderItem::fromString($itemValue);
  2746. $item->setIndex($index++);
  2747. return $item;
  2748. }, preg_split('/\\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
  2749. }
  2750. public function __toString()
  2751. {
  2752. return implode(',', $this->items);
  2753. }
  2754. public function has($value)
  2755. {
  2756. return isset($this->items[$value]);
  2757. }
  2758. public function get($value)
  2759. {
  2760. return isset($this->items[$value]) ? $this->items[$value] : null;
  2761. }
  2762. public function add(AcceptHeaderItem $item)
  2763. {
  2764. $this->items[$item->getValue()] = $item;
  2765. $this->sorted = false;
  2766. return $this;
  2767. }
  2768. public function all()
  2769. {
  2770. $this->sort();
  2771. return $this->items;
  2772. }
  2773. public function filter($pattern)
  2774. {
  2775. return new self(array_filter($this->items, function (AcceptHeaderItem $item) use($pattern) {
  2776. return preg_match($pattern, $item->getValue());
  2777. }));
  2778. }
  2779. public function first()
  2780. {
  2781. $this->sort();
  2782. return !empty($this->items) ? reset($this->items) : null;
  2783. }
  2784. private function sort()
  2785. {
  2786. if (!$this->sorted) {
  2787. uasort($this->items, function ($a, $b) {
  2788. $qA = $a->getQuality();
  2789. $qB = $b->getQuality();
  2790. if ($qA === $qB) {
  2791. return $a->getIndex() > $b->getIndex() ? 1 : -1;
  2792. }
  2793. return $qA > $qB ? -1 : 1;
  2794. });
  2795. $this->sorted = true;
  2796. }
  2797. }
  2798. }
  2799. namespace Symfony\Component\Debug;
  2800. use Symfony\Component\HttpFoundation\Response;
  2801. use Symfony\Component\Debug\Exception\FlattenException;
  2802. if (!defined('ENT_SUBSTITUTE')) {
  2803. define('ENT_SUBSTITUTE', 8);
  2804. }
  2805. class ExceptionHandler
  2806. {
  2807. private $debug;
  2808. private $charset;
  2809. public function __construct($debug = true, $charset = 'UTF-8')
  2810. {
  2811. $this->debug = $debug;
  2812. $this->charset = $charset;
  2813. }
  2814. public static function register($debug = true)
  2815. {
  2816. $handler = new static($debug);
  2817. set_exception_handler(array($handler, 'handle'));
  2818. return $handler;
  2819. }
  2820. public function handle(\Exception $exception)
  2821. {
  2822. if (class_exists('Symfony\\Component\\HttpFoundation\\Response')) {
  2823. $this->createResponse($exception)->send();
  2824. } else {
  2825. $this->sendPhpResponse($exception);
  2826. }
  2827. }
  2828. public function sendPhpResponse($exception)
  2829. {
  2830. if (!$exception instanceof FlattenException) {
  2831. $exception = FlattenException::create($exception);
  2832. }
  2833. header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
  2834. foreach ($exception->getHeaders() as $name => $value) {
  2835. header($name . ': ' . $value, false);
  2836. }
  2837. echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
  2838. }
  2839. public function createResponse($exception)
  2840. {
  2841. if (!$exception instanceof FlattenException) {
  2842. $exception = FlattenException::create($exception);
  2843. }
  2844. return new Response($this->decorate($this->getContent($exception), $this->getStylesheet($exception)), $exception->getStatusCode(), $exception->getHeaders());
  2845. }
  2846. public function getContent(FlattenException $exception)
  2847. {
  2848. switch ($exception->getStatusCode()) {
  2849. case 404:
  2850. $title = 'Sorry, the page you are looking for could not be found.';
  2851. break;
  2852. default:
  2853. $title = 'Whoops, looks like something went wrong.';
  2854. }
  2855. $content = '';
  2856. if ($this->debug) {
  2857. try {
  2858. $count = count($exception->getAllPrevious());
  2859. $total = $count + 1;
  2860. foreach ($exception->toArray() as $position => $e) {
  2861. $ind = $count - $position + 1;
  2862. $class = $this->abbrClass($e['class']);
  2863. $message = nl2br($e['message']);
  2864. $content .= sprintf(' <div class="block_exception clear_fix">
  2865. <h2><span>%d/%d</span> %s: %s</h2>
  2866. </div>
  2867. <div class="block">
  2868. <ol class="traces list_exception">', $ind, $total, $class, $message);
  2869. foreach ($e['trace'] as $trace) {
  2870. $content .= ' <li>';
  2871. if ($trace['function']) {
  2872. $content .= sprintf('at %s%s%s(%s)', $this->abbrClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
  2873. }
  2874. if (isset($trace['file']) && isset($trace['line'])) {
  2875. if ($linkFormat = ini_get('xdebug.file_link_format')) {
  2876. $link = str_replace(array('%f', '%l'), array($trace['file'], $trace['line']), $linkFormat);
  2877. $content .= sprintf(' in <a href="%s" title="Go to source">%s line %s</a>', $link, $trace['file'], $trace['line']);
  2878. } else {
  2879. $content .= sprintf(' in %s line %s', $trace['file'], $trace['line']);
  2880. }
  2881. }
  2882. $content .= '</li>
  2883. ';
  2884. }
  2885. $content .= ' </ol>
  2886. </div>
  2887. ';
  2888. }
  2889. } catch (\Exception $e) {
  2890. if ($this->debug) {
  2891. $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($exception), $exception->getMessage());
  2892. } else {
  2893. $title = 'Whoops, looks like something went wrong.';
  2894. }
  2895. }
  2896. }
  2897. return " <div id=\"sf-resetcontent\" class=\"sf-reset\">\n <h1>{$title}</h1>\n {$content}\n </div>";
  2898. }
  2899. public function getStylesheet(FlattenException $exception)
  2900. {
  2901. return ' .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }
  2902. .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }
  2903. .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }
  2904. .sf-reset .clear_fix { display:inline-block; }
  2905. .sf-reset * html .clear_fix { height:1%; }
  2906. .sf-reset .clear_fix { display:block; }
  2907. .sf-reset, .sf-reset .block { margin: auto }
  2908. .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
  2909. .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
  2910. .sf-reset strong { font-weight:bold; }
  2911. .sf-reset a { color:#6c6159; }
  2912. .sf-reset a img { border:none; }
  2913. .sf-reset a:hover { text-decoration:underline; }
  2914. .sf-reset em { font-style:italic; }
  2915. .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
  2916. .sf-reset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; }
  2917. .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
  2918. .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
  2919. -webkit-border-bottom-right-radius: 16px;
  2920. -webkit-border-bottom-left-radius: 16px;
  2921. -moz-border-radius-bottomright: 16px;
  2922. -moz-border-radius-bottomleft: 16px;
  2923. border-bottom-right-radius: 16px;
  2924. border-bottom-left-radius: 16px;
  2925. border-bottom:1px solid #ccc;
  2926. border-right:1px solid #ccc;
  2927. border-left:1px solid #ccc;
  2928. }
  2929. .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;
  2930. -webkit-border-top-left-radius: 16px;
  2931. -webkit-border-top-right-radius: 16px;
  2932. -moz-border-radius-topleft: 16px;
  2933. -moz-border-radius-topright: 16px;
  2934. border-top-left-radius: 16px;
  2935. border-top-right-radius: 16px;
  2936. border-top:1px solid #ccc;
  2937. border-right:1px solid #ccc;
  2938. border-left:1px solid #ccc;
  2939. overflow: hidden;
  2940. word-wrap: break-word;
  2941. }
  2942. .sf-reset li a { background:none; color:#868686; text-decoration:none; }
  2943. .sf-reset li a:hover { background:none; color:#313131; text-decoration:underline; }
  2944. .sf-reset ol { padding: 10px 0; }
  2945. .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
  2946. -webkit-border-radius: 10px;
  2947. -moz-border-radius: 10px;
  2948. border-radius: 10px;
  2949. border: 1px solid #ccc;
  2950. }';
  2951. }
  2952. private function decorate($content, $css)
  2953. {
  2954. 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>";
  2955. }
  2956. private function abbrClass($class)
  2957. {
  2958. $parts = explode('\\', $class);
  2959. return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
  2960. }
  2961. private function formatArgs(array $args)
  2962. {
  2963. $result = array();
  2964. foreach ($args as $key => $item) {
  2965. if ('object' === $item[0]) {
  2966. $formattedValue = sprintf('<em>object</em>(%s)', $this->abbrClass($item[1]));
  2967. } elseif ('array' === $item[0]) {
  2968. $formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
  2969. } elseif ('string' === $item[0]) {
  2970. $formattedValue = sprintf('\'%s\'', htmlspecialchars($item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset));
  2971. } elseif ('null' === $item[0]) {
  2972. $formattedValue = '<em>null</em>';
  2973. } elseif ('boolean' === $item[0]) {
  2974. $formattedValue = '<em>' . strtolower(var_export($item[1], true)) . '</em>';
  2975. } elseif ('resource' === $item[0]) {
  2976. $formattedValue = '<em>resource</em>';
  2977. } else {
  2978. $formattedValue = str_replace('
  2979. ', '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), true));
  2980. }
  2981. $result[] = is_int($key) ? $formattedValue : sprintf('\'%s\' => %s', $key, $formattedValue);
  2982. }
  2983. return implode(', ', $result);
  2984. }
  2985. }
  2986. namespace Illuminate\Support;
  2987. use ReflectionClass;
  2988. abstract class ServiceProvider
  2989. {
  2990. protected $app;
  2991. protected $defer = false;
  2992. public function __construct($app)
  2993. {
  2994. $this->app = $app;
  2995. }
  2996. public function boot()
  2997. {
  2998. }
  2999. public abstract function register();
  3000. public function package($package, $namespace = null, $path = null)
  3001. {
  3002. $namespace = $this->getPackageNamespace($package, $namespace);
  3003. $path = $path ?: $this->guessPackagePath();
  3004. $config = $path . '/config';
  3005. if ($this->app['files']->isDirectory($config)) {
  3006. $this->app['config']->package($package, $config, $namespace);
  3007. }
  3008. $lang = $path . '/lang';
  3009. if ($this->app['files']->isDirectory($lang)) {
  3010. $this->app['translator']->addNamespace($namespace, $lang);
  3011. }
  3012. $appView = $this->getAppViewPath($package, $namespace);
  3013. if ($this->app['files']->isDirectory($appView)) {
  3014. $this->app['view']->addNamespace($namespace, $appView);
  3015. }
  3016. $view = $path . '/views';
  3017. if ($this->app['files']->isDirectory($view)) {
  3018. $this->app['view']->addNamespace($namespace, $view);
  3019. }
  3020. }
  3021. public function guessPackagePath()
  3022. {
  3023. $reflect = new ReflectionClass($this);
  3024. $chain = $this->getClassChain($reflect);
  3025. $path = $chain[count($chain) - 2]->getFileName();
  3026. return realpath(dirname($path) . '/../../');
  3027. }
  3028. protected function getClassChain(ReflectionClass $reflect)
  3029. {
  3030. $lastName = null;
  3031. while ($reflect !== false) {
  3032. $classes[] = $reflect;
  3033. $reflect = $reflect->getParentClass();
  3034. }
  3035. return $classes;
  3036. }
  3037. protected function getPackageNamespace($package, $namespace)
  3038. {
  3039. if (is_null($namespace)) {
  3040. list($vendor, $namespace) = explode('/', $package);
  3041. }
  3042. return $namespace;
  3043. }
  3044. public function commands()
  3045. {
  3046. $commands = func_get_args();
  3047. $events = $this->app['events'];
  3048. $events->listen('artisan.start', function ($artisan) use($commands) {
  3049. $artisan->resolveCommands($commands);
  3050. });
  3051. }
  3052. protected function getAppViewPath($package, $namespace)
  3053. {
  3054. return $this->app['path'] . "/views/packages/{$package}/{$namespace}";
  3055. }
  3056. public function provides()
  3057. {
  3058. return array();
  3059. }
  3060. public function isDeferred()
  3061. {
  3062. return $this->defer;
  3063. }
  3064. }
  3065. namespace Illuminate\Exception;
  3066. use Closure;
  3067. use Whoops\Handler\PrettyPageHandler;
  3068. use Whoops\Handler\JsonResponseHandler;
  3069. use Illuminate\Support\ServiceProvider;
  3070. use Symfony\Component\HttpFoundation\Response;
  3071. use Symfony\Component\Debug\ExceptionHandler as KernelHandler;
  3072. class ExceptionServiceProvider extends ServiceProvider
  3073. {
  3074. public function register()
  3075. {
  3076. $this->registerDisplayers();
  3077. $this->registerHandler();
  3078. }
  3079. protected function registerDisplayers()
  3080. {
  3081. $this->registerPlainDisplayer();
  3082. $this->registerDebugDisplayer();
  3083. }
  3084. protected function registerHandler()
  3085. {
  3086. $this->app['exception'] = $this->app->share(function ($app) {
  3087. return new Handler($app, $app['exception.plain'], $app['exception.debug']);
  3088. });
  3089. }
  3090. protected function registerPlainDisplayer()
  3091. {
  3092. $this->app['exception.plain'] = $this->app->share(function ($app) {
  3093. $handler = new KernelHandler($app['config']['app.debug']);
  3094. return new SymfonyDisplayer($handler);
  3095. });
  3096. }
  3097. protected function registerDebugDisplayer()
  3098. {
  3099. $this->registerWhoops();
  3100. $this->app['exception.debug'] = $this->app->share(function ($app) {
  3101. return new WhoopsDisplayer($app['whoops'], $app->runningInConsole());
  3102. });
  3103. }
  3104. protected function registerWhoops()
  3105. {
  3106. $this->registerWhoopsHandler();
  3107. $this->app['whoops'] = $this->app->share(function ($app) {
  3108. with($whoops = new \Whoops\Run())->allowQuit(false);
  3109. return $whoops->pushHandler($app['whoops.handler']);
  3110. });
  3111. }
  3112. protected function registerWhoopsHandler()
  3113. {
  3114. if ($this->shouldReturnJson()) {
  3115. $this->app['whoops.handler'] = function () {
  3116. return new JsonResponseHandler();
  3117. };
  3118. } else {
  3119. $this->registerPrettyWhoopsHandler();
  3120. }
  3121. }
  3122. protected function shouldReturnJson()
  3123. {
  3124. $definitely = ($this->app['request']->ajax() or $this->app->runningInConsole());
  3125. return $definitely or $this->app['request']->wantsJson();
  3126. }
  3127. protected function registerPrettyWhoopsHandler()
  3128. {
  3129. $me = $this;
  3130. $this->app['whoops.handler'] = function () use($me) {
  3131. with($handler = new PrettyPageHandler())->setEditor('sublime');
  3132. if (!is_null($path = $me->resourcePath())) {
  3133. $handler->setResourcesPath($path);
  3134. }
  3135. return $handler;
  3136. };
  3137. }
  3138. public function resourcePath()
  3139. {
  3140. if (is_dir($path = $this->getResourcePath())) {
  3141. return $path;
  3142. }
  3143. }
  3144. protected function getResourcePath()
  3145. {
  3146. $base = $this->app['path.base'];
  3147. return $base . '/vendor/laravel/framework/src/Illuminate/Exception/resources';
  3148. }
  3149. }
  3150. namespace Illuminate\Routing;
  3151. use Illuminate\Support\ServiceProvider;
  3152. class RoutingServiceProvider extends ServiceProvider
  3153. {
  3154. public function register()
  3155. {
  3156. $this->registerRouter();
  3157. $this->registerUrlGenerator();
  3158. $this->registerRedirector();
  3159. }
  3160. protected function registerRouter()
  3161. {
  3162. $this->app['router'] = $this->app->share(function ($app) {
  3163. $router = new Router($app);
  3164. if ($app['env'] == 'testing') {
  3165. $router->disableFilters();
  3166. }
  3167. return $router;
  3168. });
  3169. }
  3170. protected function registerUrlGenerator()
  3171. {
  3172. $this->app['url'] = $this->app->share(function ($app) {
  3173. $routes = $app['router']->getRoutes();
  3174. return new UrlGenerator($routes, $app['request']);
  3175. });
  3176. }
  3177. protected function registerRedirector()
  3178. {
  3179. $this->app['redirect'] = $this->app->share(function ($app) {
  3180. $redirector = new Redirector($app['url']);
  3181. if (isset($app['session'])) {
  3182. $redirector->setSession($app['session']);
  3183. }
  3184. return $redirector;
  3185. });
  3186. }
  3187. }
  3188. namespace Illuminate\Events;
  3189. use Illuminate\Support\ServiceProvider;
  3190. class EventServiceProvider extends ServiceProvider
  3191. {
  3192. public function register()
  3193. {
  3194. $this->app['events'] = $this->app->share(function ($app) {
  3195. return new Dispatcher($app);
  3196. });
  3197. }
  3198. }
  3199. namespace Illuminate\Support\Facades;
  3200. use Mockery\MockInterface;
  3201. abstract class Facade
  3202. {
  3203. protected static $app;
  3204. protected static $resolvedInstance;
  3205. public static function swap($instance)
  3206. {
  3207. static::$resolvedInstance[static::getFacadeAccessor()] = $instance;
  3208. static::$app->instance(static::getFacadeAccessor(), $instance);
  3209. }
  3210. public static function shouldReceive()
  3211. {
  3212. $name = static::getFacadeAccessor();
  3213. if (static::isMock()) {
  3214. $mock = static::$resolvedInstance[$name];
  3215. } else {
  3216. static::$resolvedInstance[$name] = $mock = \Mockery::mock(static::getMockableClass($name));
  3217. static::$app->instance($name, $mock);
  3218. }
  3219. return call_user_func_array(array($mock, 'shouldReceive'), func_get_args());
  3220. }
  3221. protected static function isMock()
  3222. {
  3223. $name = static::getFacadeAccessor();
  3224. return isset(static::$resolvedInstance[$name]) and static::$resolvedInstance[$name] instanceof MockInterface;
  3225. }
  3226. protected static function getMockableClass()
  3227. {
  3228. return get_class(static::getFacadeRoot());
  3229. }
  3230. public static function getFacadeRoot()
  3231. {
  3232. return static::resolveFacadeInstance(static::getFacadeAccessor());
  3233. }
  3234. protected static function getFacadeAccessor()
  3235. {
  3236. throw new \RuntimeException('Facade does not implement getFacadeAccessor method.');
  3237. }
  3238. protected static function resolveFacadeInstance($name)
  3239. {
  3240. if (is_object($name)) {
  3241. return $name;
  3242. }
  3243. if (isset(static::$resolvedInstance[$name])) {
  3244. return static::$resolvedInstance[$name];
  3245. }
  3246. return static::$resolvedInstance[$name] = static::$app[$name];
  3247. }
  3248. public static function clearResolvedInstance($name)
  3249. {
  3250. unset(static::$resolvedInstance[$name]);
  3251. }
  3252. public static function clearResolvedInstances()
  3253. {
  3254. static::$resolvedInstance = array();
  3255. }
  3256. public static function getFacadeApplication()
  3257. {
  3258. return static::$app;
  3259. }
  3260. public static function setFacadeApplication($app)
  3261. {
  3262. static::$app = $app;
  3263. }
  3264. public static function __callStatic($method, $args)
  3265. {
  3266. $instance = static::resolveFacadeInstance(static::getFacadeAccessor());
  3267. switch (count($args)) {
  3268. case 0:
  3269. return $instance->{$method}();
  3270. case 1:
  3271. return $instance->{$method}($args[0]);
  3272. case 2:
  3273. return $instance->{$method}($args[0], $args[1]);
  3274. case 3:
  3275. return $instance->{$method}($args[0], $args[1], $args[2]);
  3276. case 4:
  3277. return $instance->{$method}($args[0], $args[1], $args[2], $args[3]);
  3278. default:
  3279. return call_user_func_array(array($instance, $method), $args);
  3280. }
  3281. }
  3282. }
  3283. namespace Illuminate\Support;
  3284. class Str
  3285. {
  3286. protected static $macros = array();
  3287. public static function ascii($value)
  3288. {
  3289. return \Patchwork\Utf8::toAscii($value);
  3290. }
  3291. public static function camel($value)
  3292. {
  3293. return lcfirst(static::studly($value));
  3294. }
  3295. public static function contains($haystack, $needle)
  3296. {
  3297. foreach ((array) $needle as $n) {
  3298. if (strpos($haystack, $n) !== false) {
  3299. return true;
  3300. }
  3301. }
  3302. return false;
  3303. }
  3304. public static function endsWith($haystack, $needles)
  3305. {
  3306. foreach ((array) $needles as $needle) {
  3307. if ($needle == substr($haystack, strlen($haystack) - strlen($needle))) {
  3308. return true;
  3309. }
  3310. }
  3311. return false;
  3312. }
  3313. public static function finish($value, $cap)
  3314. {
  3315. return rtrim($value, $cap) . $cap;
  3316. }
  3317. public static function is($pattern, $value)
  3318. {
  3319. if ($pattern == $value) {
  3320. return true;
  3321. }
  3322. if ($pattern !== '/') {
  3323. $pattern = str_replace('*', '(.*)', $pattern) . '\\z';
  3324. } else {
  3325. $pattern = '/$';
  3326. }
  3327. return (bool) preg_match('#^' . $pattern . '#', $value);
  3328. }
  3329. public static function length($value)
  3330. {
  3331. return mb_strlen($value);
  3332. }
  3333. public static function limit($value, $limit = 100, $end = '...')
  3334. {
  3335. if (mb_strlen($value) <= $limit) {
  3336. return $value;
  3337. }
  3338. return mb_substr($value, 0, $limit, 'UTF-8') . $end;
  3339. }
  3340. public static function lower($value)
  3341. {
  3342. return mb_strtolower($value);
  3343. }
  3344. public static function words($value, $words = 100, $end = '...')
  3345. {
  3346. preg_match('/^\\s*+(?:\\S++\\s*+){1,' . $words . '}/u', $value, $matches);
  3347. if (!isset($matches[0])) {
  3348. return $value;
  3349. }
  3350. if (strlen($value) == strlen($matches[0])) {
  3351. return $value;
  3352. }
  3353. return rtrim($matches[0]) . $end;
  3354. }
  3355. public static function plural($value, $count = 2)
  3356. {
  3357. return Pluralizer::plural($value, $count);
  3358. }
  3359. public static function random($length = 16)
  3360. {
  3361. if (function_exists('openssl_random_pseudo_bytes')) {
  3362. $bytes = openssl_random_pseudo_bytes($length * 2);
  3363. if ($bytes === false) {
  3364. throw new \RuntimeException('Unable to generate random string.');
  3365. }
  3366. return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
  3367. }
  3368. return static::quickRandom($length);
  3369. }
  3370. public static function quickRandom($length = 16)
  3371. {
  3372. $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  3373. return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
  3374. }
  3375. public static function upper($value)
  3376. {
  3377. return mb_strtoupper($value);
  3378. }
  3379. public static function singular($value)
  3380. {
  3381. return Pluralizer::singular($value);
  3382. }
  3383. public static function slug($title, $separator = '-')
  3384. {
  3385. $title = static::ascii($title);
  3386. $title = preg_replace('![^' . preg_quote($separator) . '\\pL\\pN\\s]+!u', '', mb_strtolower($title));
  3387. $flip = $separator == '-' ? '_' : '-';
  3388. $title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title);
  3389. $title = preg_replace('![' . preg_quote($separator) . '\\s]+!u', $separator, $title);
  3390. return trim($title, $separator);
  3391. }
  3392. public static function snake($value, $delimiter = '_')
  3393. {
  3394. $replace = '$1' . $delimiter . '$2';
  3395. return ctype_lower($value) ? $value : strtolower(preg_replace('/(.)([A-Z])/', $replace, $value));
  3396. }
  3397. public static function startsWith($haystack, $needles)
  3398. {
  3399. foreach ((array) $needles as $needle) {
  3400. if (strpos($haystack, $needle) === 0) {
  3401. return true;
  3402. }
  3403. }
  3404. return false;
  3405. }
  3406. public static function studly($value)
  3407. {
  3408. $value = ucwords(str_replace(array('-', '_'), ' ', $value));
  3409. return str_replace(' ', '', $value);
  3410. }
  3411. public static function macro($name, $macro)
  3412. {
  3413. static::$macros[$name] = $macro;
  3414. }
  3415. public static function __callStatic($method, $parameters)
  3416. {
  3417. if (isset(static::$macros[$method])) {
  3418. return call_user_func_array(static::$macros[$method], $parameters);
  3419. }
  3420. throw new \BadMethodCallException("Method {$method} does not exist.");
  3421. }
  3422. }
  3423. namespace Symfony\Component\Debug;
  3424. use Symfony\Component\Debug\Exception\FatalErrorException;
  3425. use Psr\Log\LoggerInterface;
  3426. class ErrorHandler
  3427. {
  3428. const TYPE_DEPRECATION = -100;
  3429. 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');
  3430. private $level;
  3431. private $reservedMemory;
  3432. private $displayErrors;
  3433. private static $loggers = array();
  3434. public static function register($level = null, $displayErrors = true)
  3435. {
  3436. $handler = new static();
  3437. $handler->setLevel($level);
  3438. $handler->setDisplayErrors($displayErrors);
  3439. ini_set('display_errors', 0);
  3440. set_error_handler(array($handler, 'handle'));
  3441. register_shutdown_function(array($handler, 'handleFatal'));
  3442. $handler->reservedMemory = str_repeat('x', 10240);
  3443. return $handler;
  3444. }
  3445. public function setLevel($level)
  3446. {
  3447. $this->level = null === $level ? error_reporting() : $level;
  3448. }
  3449. public function setDisplayErrors($displayErrors)
  3450. {
  3451. $this->displayErrors = $displayErrors;
  3452. }
  3453. public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
  3454. {
  3455. self::$loggers[$channel] = $logger;
  3456. }
  3457. public function handle($level, $message, $file, $line, $context)
  3458. {
  3459. if (0 === $this->level) {
  3460. return false;
  3461. }
  3462. if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
  3463. if (isset(self::$loggers['deprecation'])) {
  3464. if (version_compare(PHP_VERSION, '5.4', '<')) {
  3465. $stack = array_map(function ($row) {
  3466. unset($row['args']);
  3467. return $row;
  3468. }, array_slice(debug_backtrace(false), 0, 10));
  3469. } else {
  3470. $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
  3471. }
  3472. self::$loggers['deprecation']->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack));
  3473. }
  3474. return true;
  3475. }
  3476. if ($this->displayErrors && error_reporting() & $level && $this->level & $level) {
  3477. throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line);
  3478. }
  3479. return false;
  3480. }
  3481. public function handleFatal()
  3482. {
  3483. if (null === ($error = error_get_last())) {
  3484. return;
  3485. }
  3486. unset($this->reservedMemory);
  3487. $type = $error['type'];
  3488. if (0 === $this->level || !in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE))) {
  3489. return;
  3490. }
  3491. if (isset(self::$loggers['emergency'])) {
  3492. $fatal = array('type' => $type, 'file' => $error['file'], 'line' => $error['line']);
  3493. self::$loggers['emergency']->emerg($error['message'], $fatal);
  3494. }
  3495. if (!$this->displayErrors) {
  3496. return;
  3497. }
  3498. $exceptionHandler = set_exception_handler(function () {
  3499. });
  3500. restore_exception_handler();
  3501. if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) {
  3502. $level = isset($this->levels[$type]) ? $this->levels[$type] : $type;
  3503. $message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']);
  3504. $exception = new FatalErrorException($message, 0, $type, $error['file'], $error['line']);
  3505. $exceptionHandler[0]->handle($exception);
  3506. }
  3507. }
  3508. }
  3509. namespace Symfony\Component\HttpKernel\Debug;
  3510. use Symfony\Component\Debug\ErrorHandler as DebugErrorHandler;
  3511. class ErrorHandler extends DebugErrorHandler
  3512. {
  3513. }
  3514. namespace Illuminate\Config;
  3515. use Closure;
  3516. use ArrayAccess;
  3517. use Illuminate\Support\NamespacedItemResolver;
  3518. class Repository extends NamespacedItemResolver implements ArrayAccess
  3519. {
  3520. protected $loader;
  3521. protected $environment;
  3522. protected $items = array();
  3523. protected $packages = array();
  3524. protected $afterLoad = array();
  3525. public function __construct(LoaderInterface $loader, $environment)
  3526. {
  3527. $this->loader = $loader;
  3528. $this->environment = $environment;
  3529. }
  3530. public function has($key)
  3531. {
  3532. $default = microtime(true);
  3533. return $this->get($key, $default) != $default;
  3534. }
  3535. public function hasGroup($key)
  3536. {
  3537. list($namespace, $group, $item) = $this->parseKey($key);
  3538. return $this->loader->exists($group, $namespace);
  3539. }
  3540. public function get($key, $default = null)
  3541. {
  3542. list($namespace, $group, $item) = $this->parseKey($key);
  3543. $collection = $this->getCollection($group, $namespace);
  3544. $this->load($group, $namespace, $collection);
  3545. return array_get($this->items[$collection], $item, $default);
  3546. }
  3547. public function set($key, $value)
  3548. {
  3549. list($namespace, $group, $item) = $this->parseKey($key);
  3550. $collection = $this->getCollection($group, $namespace);
  3551. $this->load($group, $namespace, $collection);
  3552. if (is_null($item)) {
  3553. $this->items[$collection] = $value;
  3554. } else {
  3555. array_set($this->items[$collection], $item, $value);
  3556. }
  3557. }
  3558. protected function load($group, $namespace, $collection)
  3559. {
  3560. $env = $this->environment;
  3561. if (isset($this->items[$collection])) {
  3562. return;
  3563. }
  3564. $items = $this->loader->load($env, $group, $namespace);
  3565. if (isset($this->afterLoad[$namespace])) {
  3566. $items = $this->callAfterLoad($namespace, $group, $items);
  3567. }
  3568. $this->items[$collection] = $items;
  3569. }
  3570. protected function callAfterLoad($namespace, $group, $items)
  3571. {
  3572. $callback = $this->afterLoad[$namespace];
  3573. return call_user_func($callback, $this, $group, $items);
  3574. }
  3575. protected function parseNamespacedSegments($key)
  3576. {
  3577. list($namespace, $item) = explode('::', $key);
  3578. if (in_array($namespace, $this->packages)) {
  3579. return $this->parsePackageSegments($key, $namespace, $item);
  3580. }
  3581. return parent::parseNamespacedSegments($key);
  3582. }
  3583. protected function parsePackageSegments($key, $namespace, $item)
  3584. {
  3585. $itemSegments = explode('.', $item);
  3586. if (!$this->loader->exists($itemSegments[0], $namespace)) {
  3587. return array($namespace, 'config', $item);
  3588. }
  3589. return parent::parseNamespacedSegments($key);
  3590. }
  3591. public function package($package, $hint, $namespace = null)
  3592. {
  3593. $namespace = $this->getPackageNamespace($package, $namespace);
  3594. $this->packages[] = $namespace;
  3595. $this->addNamespace($namespace, $hint);
  3596. $this->afterLoading($namespace, function ($me, $group, $items) use($package) {
  3597. $env = $me->getEnvironment();
  3598. $loader = $me->getLoader();
  3599. return $loader->cascadePackage($env, $package, $group, $items);
  3600. });
  3601. }
  3602. protected function getPackageNamespace($package, $namespace)
  3603. {
  3604. if (is_null($namespace)) {
  3605. list($vendor, $namespace) = explode('/', $package);
  3606. }
  3607. return $namespace;
  3608. }
  3609. public function afterLoading($namespace, Closure $callback)
  3610. {
  3611. $this->afterLoad[$namespace] = $callback;
  3612. }
  3613. protected function getCollection($group, $namespace = null)
  3614. {
  3615. $namespace = $namespace ?: '*';
  3616. return $namespace . '::' . $group;
  3617. }
  3618. public function addNamespace($namespace, $hint)
  3619. {
  3620. return $this->loader->addNamespace($namespace, $hint);
  3621. }
  3622. public function getNamespaces()
  3623. {
  3624. return $this->loader->getNamespaces();
  3625. }
  3626. public function getLoader()
  3627. {
  3628. return $this->loader;
  3629. }
  3630. public function setLoader(LoaderInterface $loader)
  3631. {
  3632. $this->loader = $loader;
  3633. }
  3634. public function getEnvironment()
  3635. {
  3636. return $this->environment;
  3637. }
  3638. public function getAfterLoadCallbacks()
  3639. {
  3640. return $this->afterLoad;
  3641. }
  3642. public function getItems()
  3643. {
  3644. return $this->items;
  3645. }
  3646. public function offsetExists($key)
  3647. {
  3648. return $this->has($key);
  3649. }
  3650. public function offsetGet($key)
  3651. {
  3652. return $this->get($key);
  3653. }
  3654. public function offsetSet($key, $value)
  3655. {
  3656. $this->set($key, $value);
  3657. }
  3658. public function offsetUnset($key)
  3659. {
  3660. $this->set($key, null);
  3661. }
  3662. }
  3663. namespace Illuminate\Support;
  3664. class NamespacedItemResolver
  3665. {
  3666. protected $parsed = array();
  3667. public function parseKey($key)
  3668. {
  3669. if (isset($this->parsed[$key])) {
  3670. return $this->parsed[$key];
  3671. }
  3672. $segments = explode('.', $key);
  3673. if (strpos($key, '::') === false) {
  3674. $parsed = $this->parseBasicSegments($segments);
  3675. } else {
  3676. $parsed = $this->parseNamespacedSegments($key);
  3677. }
  3678. return $this->parsed[$key] = $parsed;
  3679. }
  3680. protected function parseBasicSegments(array $segments)
  3681. {
  3682. $group = $segments[0];
  3683. if (count($segments) == 1) {
  3684. return array(null, $group, null);
  3685. } else {
  3686. $item = implode('.', array_slice($segments, 1));
  3687. return array(null, $group, $item);
  3688. }
  3689. }
  3690. protected function parseNamespacedSegments($key)
  3691. {
  3692. list($namespace, $item) = explode('::', $key);
  3693. $itemSegments = explode('.', $item);
  3694. $groupAndItem = array_slice($this->parseBasicSegments($itemSegments), 1);
  3695. return array_merge(array($namespace), $groupAndItem);
  3696. }
  3697. public function setParsedKey($key, $parsed)
  3698. {
  3699. $this->parsed[$key] = $parsed;
  3700. }
  3701. }
  3702. namespace Illuminate\Config;
  3703. use Illuminate\Filesystem\Filesystem;
  3704. class FileLoader implements LoaderInterface
  3705. {
  3706. protected $files;
  3707. protected $defaultPath;
  3708. protected $hints = array();
  3709. protected $exists = array();
  3710. public function __construct(Filesystem $files, $defaultPath)
  3711. {
  3712. $this->files = $files;
  3713. $this->defaultPath = $defaultPath;
  3714. }
  3715. public function load($environment, $group, $namespace = null)
  3716. {
  3717. $items = array();
  3718. $path = $this->getPath($namespace);
  3719. if (is_null($path)) {
  3720. return $items;
  3721. }
  3722. $file = "{$path}/{$group}.php";
  3723. if ($this->files->exists($file)) {
  3724. $items = $this->files->getRequire($file);
  3725. }
  3726. $file = "{$path}/{$environment}/{$group}.php";
  3727. if ($this->files->exists($file)) {
  3728. $items = $this->mergeEnvironment($items, $file);
  3729. }
  3730. return $items;
  3731. }
  3732. protected function mergeEnvironment(array $items, $file)
  3733. {
  3734. return array_replace_recursive($items, $this->files->getRequire($file));
  3735. }
  3736. public function exists($group, $namespace = null)
  3737. {
  3738. $key = $group . $namespace;
  3739. if (isset($this->exists[$key])) {
  3740. return $this->exists[$key];
  3741. }
  3742. $path = $this->getPath($namespace);
  3743. if (is_null($path)) {
  3744. return $this->exists[$key] = false;
  3745. }
  3746. $file = "{$path}/{$group}.php";
  3747. $exists = $this->files->exists($file);
  3748. return $this->exists[$key] = $exists;
  3749. }
  3750. public function cascadePackage($env, $package, $group, $items)
  3751. {
  3752. $file = "packages/{$package}/{$group}.php";
  3753. if ($this->files->exists($path = $this->defaultPath . '/' . $file)) {
  3754. $items = array_merge($items, $this->getRequire($path));
  3755. }
  3756. $path = $this->getPackagePath($env, $package, $group);
  3757. if ($this->files->exists($path)) {
  3758. $items = array_merge($items, $this->getRequire($path));
  3759. }
  3760. return $items;
  3761. }
  3762. protected function getPackagePath($env, $package, $group)
  3763. {
  3764. $file = "packages/{$package}/{$env}/{$group}.php";
  3765. return $this->defaultPath . '/' . $file;
  3766. }
  3767. protected function getPath($namespace)
  3768. {
  3769. if (is_null($namespace)) {
  3770. return $this->defaultPath;
  3771. } elseif (isset($this->hints[$namespace])) {
  3772. return $this->hints[$namespace];
  3773. }
  3774. }
  3775. public function addNamespace($namespace, $hint)
  3776. {
  3777. $this->hints[$namespace] = $hint;
  3778. }
  3779. public function getNamespaces()
  3780. {
  3781. return $this->hints;
  3782. }
  3783. protected function getRequire($path)
  3784. {
  3785. return $this->files->getRequire($path);
  3786. }
  3787. public function getFilesystem()
  3788. {
  3789. return $this->files;
  3790. }
  3791. }
  3792. namespace Illuminate\Config;
  3793. interface LoaderInterface
  3794. {
  3795. public function load($environment, $group, $namespace = null);
  3796. public function exists($group, $namespace = null);
  3797. public function addNamespace($namespace, $hint);
  3798. public function getNamespaces();
  3799. public function cascadePackage($environment, $package, $group, $items);
  3800. }
  3801. namespace Illuminate\Filesystem;
  3802. use FilesystemIterator;
  3803. use Symfony\Component\Finder\Finder;
  3804. class FileNotFoundException extends \Exception
  3805. {
  3806. }
  3807. class Filesystem
  3808. {
  3809. public function exists($path)
  3810. {
  3811. return file_exists($path);
  3812. }
  3813. public function get($path)
  3814. {
  3815. if ($this->isFile($path)) {
  3816. return file_get_contents($path);
  3817. }
  3818. throw new FileNotFoundException("File does not exist at path {$path}");
  3819. }
  3820. public function getRemote($path)
  3821. {
  3822. return file_get_contents($path);
  3823. }
  3824. public function getRequire($path)
  3825. {
  3826. if ($this->isFile($path)) {
  3827. return require $path;
  3828. }
  3829. throw new FileNotFoundException("File does not exist at path {$path}");
  3830. }
  3831. public function requireOnce($file)
  3832. {
  3833. require_once $file;
  3834. }
  3835. public function put($path, $contents)
  3836. {
  3837. return file_put_contents($path, $contents);
  3838. }
  3839. public function append($path, $data)
  3840. {
  3841. return file_put_contents($path, $data, FILE_APPEND);
  3842. }
  3843. public function delete($path)
  3844. {
  3845. return @unlink($path);
  3846. }
  3847. public function move($path, $target)
  3848. {
  3849. return rename($path, $target);
  3850. }
  3851. public function copy($path, $target)
  3852. {
  3853. return copy($path, $target);
  3854. }
  3855. public function extension($path)
  3856. {
  3857. return pathinfo($path, PATHINFO_EXTENSION);
  3858. }
  3859. public function type($path)
  3860. {
  3861. return filetype($path);
  3862. }
  3863. public function size($path)
  3864. {
  3865. return filesize($path);
  3866. }
  3867. public function lastModified($path)
  3868. {
  3869. return filemtime(realpath($path));
  3870. }
  3871. public function isDirectory($directory)
  3872. {
  3873. return is_dir($directory);
  3874. }
  3875. public function isWritable($path)
  3876. {
  3877. return is_writable($path);
  3878. }
  3879. public function isFile($file)
  3880. {
  3881. return is_file($file);
  3882. }
  3883. public function glob($pattern, $flags = 0)
  3884. {
  3885. return glob($pattern, $flags);
  3886. }
  3887. public function files($directory)
  3888. {
  3889. $glob = glob($directory . '/*');
  3890. if ($glob === false) {
  3891. return array();
  3892. }
  3893. return array_filter($glob, function ($file) {
  3894. return filetype($file) == 'file';
  3895. });
  3896. }
  3897. public function allFiles($directory)
  3898. {
  3899. return iterator_to_array(Finder::create()->files()->in($directory), false);
  3900. }
  3901. public function directories($directory)
  3902. {
  3903. $directories = array();
  3904. foreach (Finder::create()->in($directory)->directories()->depth(0) as $dir) {
  3905. $directories[] = $dir->getRealPath();
  3906. }
  3907. return $directories;
  3908. }
  3909. public function makeDirectory($path, $mode = 511, $recursive = false)
  3910. {
  3911. return mkdir($path, $mode, $recursive);
  3912. }
  3913. public function copyDirectory($directory, $destination, $options = null)
  3914. {
  3915. if (!$this->isDirectory($directory)) {
  3916. return false;
  3917. }
  3918. $options = $options ?: FilesystemIterator::SKIP_DOTS;
  3919. if (!$this->isDirectory($destination)) {
  3920. $this->makeDirectory($destination, 511, true);
  3921. }
  3922. $items = new FilesystemIterator($directory, $options);
  3923. foreach ($items as $item) {
  3924. $target = $destination . '/' . $item->getBasename();
  3925. if ($item->isDir()) {
  3926. $path = $item->getRealPath();
  3927. if (!$this->copyDirectory($path, $target, $options)) {
  3928. return false;
  3929. }
  3930. } else {
  3931. if (!$this->copy($item->getRealPath(), $target)) {
  3932. return false;
  3933. }
  3934. }
  3935. }
  3936. return true;
  3937. }
  3938. public function deleteDirectory($directory, $preserve = false)
  3939. {
  3940. if (!$this->isDirectory($directory)) {
  3941. return;
  3942. }
  3943. $items = new FilesystemIterator($directory);
  3944. foreach ($items as $item) {
  3945. if ($item->isDir()) {
  3946. $this->deleteDirectory($item->getRealPath());
  3947. } else {
  3948. $this->delete($item->getRealPath());
  3949. }
  3950. }
  3951. if (!$preserve) {
  3952. @rmdir($directory);
  3953. }
  3954. }
  3955. public function cleanDirectory($directory)
  3956. {
  3957. return $this->deleteDirectory($directory, true);
  3958. }
  3959. }
  3960. namespace Illuminate\Foundation;
  3961. class AliasLoader
  3962. {
  3963. protected $aliases;
  3964. protected $registered = false;
  3965. protected static $instance;
  3966. public function __construct(array $aliases = array())
  3967. {
  3968. $this->aliases = $aliases;
  3969. }
  3970. public static function getInstance(array $aliases = array())
  3971. {
  3972. if (is_null(static::$instance)) {
  3973. static::$instance = new static($aliases);
  3974. }
  3975. $aliases = array_merge(static::$instance->getAliases(), $aliases);
  3976. static::$instance->setAliases($aliases);
  3977. return static::$instance;
  3978. }
  3979. public function load($alias)
  3980. {
  3981. if (isset($this->aliases[$alias])) {
  3982. return class_alias($this->aliases[$alias], $alias);
  3983. }
  3984. }
  3985. public function alias($class, $alias)
  3986. {
  3987. $this->aliases[$class] = $alias;
  3988. }
  3989. public function register()
  3990. {
  3991. if (!$this->registered) {
  3992. $this->prependToLoaderStack();
  3993. $this->registered = true;
  3994. }
  3995. }
  3996. protected function prependToLoaderStack()
  3997. {
  3998. spl_autoload_register(array($this, 'load'), true, true);
  3999. }
  4000. public function getAliases()
  4001. {
  4002. return $this->aliases;
  4003. }
  4004. public function setAliases(array $aliases)
  4005. {
  4006. $this->aliases = $aliases;
  4007. }
  4008. public function isRegistered()
  4009. {
  4010. return $this->registered;
  4011. }
  4012. public function setRegistered($value)
  4013. {
  4014. $this->registered = $value;
  4015. }
  4016. public static function setInstance($loader)
  4017. {
  4018. static::$instance = $loader;
  4019. }
  4020. }
  4021. namespace Illuminate\Foundation;
  4022. use Illuminate\Filesystem\Filesystem;
  4023. class ProviderRepository
  4024. {
  4025. protected $files;
  4026. protected $manifestPath;
  4027. public function __construct(Filesystem $files, $manifestPath)
  4028. {
  4029. $this->files = $files;
  4030. $this->manifestPath = $manifestPath;
  4031. }
  4032. public function load(Application $app, array $providers)
  4033. {
  4034. $manifest = $this->loadManifest();
  4035. if ($this->shouldRecompile($manifest, $providers)) {
  4036. $manifest = $this->compileManifest($app, $providers);
  4037. }
  4038. if ($app->runningInConsole()) {
  4039. $manifest['eager'] = $manifest['providers'];
  4040. }
  4041. foreach ($manifest['eager'] as $provider) {
  4042. $app->register($this->createProvider($app, $provider));
  4043. }
  4044. $app->setDeferredServices($manifest['deferred']);
  4045. }
  4046. protected function compileManifest(Application $app, $providers)
  4047. {
  4048. $manifest = $this->freshManifest($providers);
  4049. foreach ($providers as $provider) {
  4050. $instance = $this->createProvider($app, $provider);
  4051. if ($instance->isDeferred()) {
  4052. foreach ($instance->provides() as $service) {
  4053. $manifest['deferred'][$service] = $provider;
  4054. }
  4055. } else {
  4056. $manifest['eager'][] = $provider;
  4057. }
  4058. }
  4059. return $this->writeManifest($manifest);
  4060. }
  4061. public function createProvider(Application $app, $provider)
  4062. {
  4063. return new $provider($app);
  4064. }
  4065. public function shouldRecompile($manifest, $providers)
  4066. {
  4067. return is_null($manifest) or $manifest['providers'] != $providers;
  4068. }
  4069. public function loadManifest()
  4070. {
  4071. $path = $this->manifestPath . '/services.json';
  4072. if ($this->files->exists($path)) {
  4073. return json_decode($this->files->get($path), true);
  4074. }
  4075. }
  4076. public function writeManifest($manifest)
  4077. {
  4078. $path = $this->manifestPath . '/services.json';
  4079. $this->files->put($path, json_encode($manifest));
  4080. return $manifest;
  4081. }
  4082. protected function getManifestPath($app)
  4083. {
  4084. return $this->manifestPath;
  4085. }
  4086. protected function freshManifest(array $providers)
  4087. {
  4088. list($eager, $deferred) = array(array(), array());
  4089. return compact('providers', 'eager', 'deferred');
  4090. }
  4091. public function getFilesystem()
  4092. {
  4093. return $this->files;
  4094. }
  4095. }
  4096. namespace Illuminate\Cookie;
  4097. use Illuminate\Support\ServiceProvider;
  4098. class CookieServiceProvider extends ServiceProvider
  4099. {
  4100. public function register()
  4101. {
  4102. $this->app['cookie'] = $this->app->share(function ($app) {
  4103. $cookies = new CookieJar($app['request'], $app['encrypter']);
  4104. $config = $app['config']['session'];
  4105. return $cookies->setDefaultPathAndDomain($config['path'], $config['domain']);
  4106. });
  4107. }
  4108. }
  4109. namespace Illuminate\Database;
  4110. use Illuminate\Database\Eloquent\Model;
  4111. use Illuminate\Support\ServiceProvider;
  4112. use Illuminate\Database\Connectors\ConnectionFactory;
  4113. class DatabaseServiceProvider extends ServiceProvider
  4114. {
  4115. public function boot()
  4116. {
  4117. Model::setConnectionResolver($this->app['db']);
  4118. Model::setEventDispatcher($this->app['events']);
  4119. }
  4120. public function register()
  4121. {
  4122. $this->app['db.factory'] = $this->app->share(function ($app) {
  4123. return new ConnectionFactory($app);
  4124. });
  4125. $this->app['db'] = $this->app->share(function ($app) {
  4126. return new DatabaseManager($app, $app['db.factory']);
  4127. });
  4128. }
  4129. }
  4130. namespace Illuminate\Encryption;
  4131. use Illuminate\Support\ServiceProvider;
  4132. class EncryptionServiceProvider extends ServiceProvider
  4133. {
  4134. public function register()
  4135. {
  4136. $this->app['encrypter'] = $this->app->share(function ($app) {
  4137. return new Encrypter($app['config']['app.key']);
  4138. });
  4139. }
  4140. }
  4141. namespace Illuminate\Filesystem;
  4142. use Illuminate\Support\ServiceProvider;
  4143. class FilesystemServiceProvider extends ServiceProvider
  4144. {
  4145. public function register()
  4146. {
  4147. $this->app['files'] = $this->app->share(function () {
  4148. return new Filesystem();
  4149. });
  4150. }
  4151. }
  4152. namespace Illuminate\Session;
  4153. use Illuminate\Support\ServiceProvider;
  4154. class SessionServiceProvider extends ServiceProvider
  4155. {
  4156. public function boot()
  4157. {
  4158. $this->registerSessionEvents();
  4159. }
  4160. public function register()
  4161. {
  4162. $this->setupDefaultDriver();
  4163. $this->registerSessionManager();
  4164. $this->registerSessionDriver();
  4165. }
  4166. protected function setupDefaultDriver()
  4167. {
  4168. if ($this->app->runningInConsole()) {
  4169. $this->app['config']['session.driver'] = 'array';
  4170. }
  4171. }
  4172. protected function registerSessionManager()
  4173. {
  4174. $this->app['session.manager'] = $this->app->share(function ($app) {
  4175. return new SessionManager($app);
  4176. });
  4177. }
  4178. protected function registerSessionDriver()
  4179. {
  4180. $this->app['session'] = $this->app->share(function ($app) {
  4181. $manager = $app['session.manager'];
  4182. return $manager->driver();
  4183. });
  4184. }
  4185. protected function registerSessionEvents()
  4186. {
  4187. $app = $this->app;
  4188. $config = $app['config']['session'];
  4189. if (!is_null($config['driver'])) {
  4190. $this->registerBootingEvent();
  4191. $this->registerCloseEvent();
  4192. }
  4193. }
  4194. protected function registerBootingEvent()
  4195. {
  4196. $app = $this->app;
  4197. $this->app->booting(function ($app) use($app) {
  4198. $app['session']->start();
  4199. });
  4200. }
  4201. protected function registerCloseEvent()
  4202. {
  4203. if ($this->getDriver() == 'array') {
  4204. return;
  4205. }
  4206. $this->registerCookieToucher();
  4207. $app = $this->app;
  4208. $this->app->close(function () use($app) {
  4209. $app['session']->save();
  4210. });
  4211. }
  4212. protected function registerCookieToucher()
  4213. {
  4214. $me = $this;
  4215. $this->app->close(function () use($me) {
  4216. if (!headers_sent()) {
  4217. $me->touchSessionCookie();
  4218. }
  4219. });
  4220. }
  4221. public function touchSessionCookie()
  4222. {
  4223. $config = $this->app['config']['session'];
  4224. $expire = $this->getExpireTime($config);
  4225. setcookie($config['cookie'], session_id(), $expire, $config['path'], $config['domain']);
  4226. }
  4227. protected function getExpireTime($config)
  4228. {
  4229. return $config['lifetime'] == 0 ? 0 : time() + $config['lifetime'] * 60;
  4230. }
  4231. protected function getDriver()
  4232. {
  4233. return $this->app['config']['session.driver'];
  4234. }
  4235. }
  4236. namespace Illuminate\View;
  4237. use Illuminate\Support\MessageBag;
  4238. use Illuminate\View\Engines\PhpEngine;
  4239. use Illuminate\Support\ServiceProvider;
  4240. use Illuminate\View\Engines\BladeEngine;
  4241. use Illuminate\View\Engines\CompilerEngine;
  4242. use Illuminate\View\Engines\EngineResolver;
  4243. use Illuminate\View\Compilers\BladeCompiler;
  4244. class ViewServiceProvider extends ServiceProvider
  4245. {
  4246. public function register()
  4247. {
  4248. $this->registerEngineResolver();
  4249. $this->registerViewFinder();
  4250. $this->registerEnvironment();
  4251. $this->registerSessionBinder();
  4252. }
  4253. public function registerEngineResolver()
  4254. {
  4255. list($me, $app) = array($this, $this->app);
  4256. $app['view.engine.resolver'] = $app->share(function ($app) use($me) {
  4257. $resolver = new EngineResolver();
  4258. foreach (array('php', 'blade') as $engine) {
  4259. $me->{'register' . ucfirst($engine) . 'Engine'}($resolver);
  4260. }
  4261. return $resolver;
  4262. });
  4263. }
  4264. public function registerPhpEngine($resolver)
  4265. {
  4266. $resolver->register('php', function () {
  4267. return new PhpEngine();
  4268. });
  4269. }
  4270. public function registerBladeEngine($resolver)
  4271. {
  4272. $app = $this->app;
  4273. $resolver->register('blade', function () use($app) {
  4274. $cache = $app['path.storage'] . '/views';
  4275. $compiler = new BladeCompiler($app['files'], $cache);
  4276. return new CompilerEngine($compiler, $app['files']);
  4277. });
  4278. }
  4279. public function registerViewFinder()
  4280. {
  4281. $this->app['view.finder'] = $this->app->share(function ($app) {
  4282. $paths = $app['config']['view.paths'];
  4283. return new FileViewFinder($app['files'], $paths);
  4284. });
  4285. }
  4286. public function registerEnvironment()
  4287. {
  4288. $this->app['view'] = $this->app->share(function ($app) {
  4289. $resolver = $app['view.engine.resolver'];
  4290. $finder = $app['view.finder'];
  4291. $env = new Environment($resolver, $finder, $app['events']);
  4292. $env->setContainer($app);
  4293. $env->share('app', $app);
  4294. return $env;
  4295. });
  4296. }
  4297. protected function registerSessionBinder()
  4298. {
  4299. list($app, $me) = array($this->app, $this);
  4300. $app->booted(function () use($app, $me) {
  4301. if ($me->sessionHasErrors($app)) {
  4302. $errors = $app['session']->get('errors');
  4303. $app['view']->share('errors', $errors);
  4304. } else {
  4305. $app['view']->share('errors', new MessageBag());
  4306. }
  4307. });
  4308. }
  4309. public function sessionHasErrors($app)
  4310. {
  4311. $config = $app['config']['session'];
  4312. if (isset($app['session']) and !is_null($config['driver'])) {
  4313. return $app['session']->has('errors');
  4314. }
  4315. }
  4316. }
  4317. namespace Illuminate\Routing;
  4318. use Closure;
  4319. use Illuminate\Http\Response;
  4320. use Illuminate\Container\Container;
  4321. use Symfony\Component\HttpFoundation\Request;
  4322. use Symfony\Component\Routing\RequestContext;
  4323. use Illuminate\Routing\Controllers\Inspector;
  4324. use Symfony\Component\Routing\RouteCollection;
  4325. use Symfony\Component\Routing\Matcher\UrlMatcher;
  4326. use Symfony\Component\Routing\Exception\ExceptionInterface;
  4327. use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
  4328. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  4329. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  4330. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  4331. use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
  4332. class Router
  4333. {
  4334. protected $routes;
  4335. protected $filters = array();
  4336. protected $patternFilters = array();
  4337. protected $globalFilters = array();
  4338. protected $groupStack = array();
  4339. protected $container;
  4340. protected $inspector;
  4341. protected $patterns = array();
  4342. protected $binders = array();
  4343. protected $currentRequest;
  4344. protected $currentRoute;
  4345. protected $runFilters = true;
  4346. protected $resourceDefaults = array('index', 'create', 'store', 'show', 'edit', 'update', 'destroy');
  4347. public function __construct(Container $container = null)
  4348. {
  4349. $this->container = $container;
  4350. $this->routes = new RouteCollection();
  4351. $this->bind('_missing', function ($v) {
  4352. return explode('/', $v);
  4353. });
  4354. }
  4355. public function get($pattern, $action)
  4356. {
  4357. return $this->createRoute('get', $pattern, $action);
  4358. }
  4359. public function post($pattern, $action)
  4360. {
  4361. return $this->createRoute('post', $pattern, $action);
  4362. }
  4363. public function put($pattern, $action)
  4364. {
  4365. return $this->createRoute('put', $pattern, $action);
  4366. }
  4367. public function patch($pattern, $action)
  4368. {
  4369. return $this->createRoute('patch', $pattern, $action);
  4370. }
  4371. public function delete($pattern, $action)
  4372. {
  4373. return $this->createRoute('delete', $pattern, $action);
  4374. }
  4375. public function options($pattern, $action)
  4376. {
  4377. return $this->createRoute('options', $pattern, $action);
  4378. }
  4379. public function match($method, $pattern, $action)
  4380. {
  4381. return $this->createRoute($method, $pattern, $action);
  4382. }
  4383. public function any($pattern, $action)
  4384. {
  4385. return $this->createRoute('get|post|put|patch|delete', $pattern, $action);
  4386. }
  4387. public function controllers(array $controllers)
  4388. {
  4389. foreach ($controllers as $uri => $name) {
  4390. $this->controller($uri, $name);
  4391. }
  4392. }
  4393. public function controller($uri, $controller, $names = array())
  4394. {
  4395. $routable = $this->getInspector()->getRoutable($controller, $uri);
  4396. foreach ($routable as $method => $routes) {
  4397. foreach ($routes as $route) {
  4398. $this->registerInspected($route, $controller, $method, $names);
  4399. }
  4400. }
  4401. $this->addFallthroughRoute($controller, $uri);
  4402. }
  4403. protected function registerInspected($route, $controller, $method, &$names)
  4404. {
  4405. $action = array('uses' => $controller . '@' . $method);
  4406. $action['as'] = array_pull($names, $method);
  4407. $this->{$route['verb']}($route['uri'], $action);
  4408. }
  4409. protected function addFallthroughRoute($controller, $uri)
  4410. {
  4411. $missing = $this->any($uri . '/{_missing}', $controller . '@missingMethod');
  4412. $missing->where('_missing', '(.*)');
  4413. }
  4414. public function resource($resource, $controller, array $options = array())
  4415. {
  4416. if (str_contains($resource, '/')) {
  4417. $this->prefixedResource($resource, $controller, $options);
  4418. return;
  4419. }
  4420. $base = $this->getBaseResource($resource);
  4421. $defaults = $this->resourceDefaults;
  4422. foreach ($this->getResourceMethods($defaults, $options) as $method) {
  4423. $this->{'addResource' . ucfirst($method)}($resource, $base, $controller);
  4424. }
  4425. }
  4426. protected function prefixedResource($resource, $controller, array $options)
  4427. {
  4428. list($resource, $prefix) = $this->extractResourcePrefix($resource);
  4429. $me = $this;
  4430. return $this->group(array('prefix' => $prefix), function () use($me, $resource, $controller, $options) {
  4431. $me->resource($resource, $controller, $options);
  4432. });
  4433. }
  4434. protected function extractResourcePrefix($resource)
  4435. {
  4436. $segments = explode('/', $resource);
  4437. return array($segments[count($segments) - 1], implode('/', array_slice($segments, 0, -1)));
  4438. }
  4439. protected function getResourceMethods($defaults, $options)
  4440. {
  4441. if (isset($options['only'])) {
  4442. return array_intersect($defaults, $options['only']);
  4443. } elseif (isset($options['except'])) {
  4444. return array_diff($defaults, $options['except']);
  4445. }
  4446. return $defaults;
  4447. }
  4448. protected function addResourceIndex($name, $base, $controller)
  4449. {
  4450. $action = $this->getResourceAction($name, $controller, 'index');
  4451. return $this->get($this->getResourceUri($name), $action);
  4452. }
  4453. protected function addResourceCreate($name, $base, $controller)
  4454. {
  4455. $action = $this->getResourceAction($name, $controller, 'create');
  4456. return $this->get($this->getResourceUri($name) . '/create', $action);
  4457. }
  4458. protected function addResourceStore($name, $base, $controller)
  4459. {
  4460. $action = $this->getResourceAction($name, $controller, 'store');
  4461. return $this->post($this->getResourceUri($name), $action);
  4462. }
  4463. protected function addResourceShow($name, $base, $controller)
  4464. {
  4465. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4466. return $this->get($uri, $this->getResourceAction($name, $controller, 'show'));
  4467. }
  4468. protected function addResourceEdit($name, $base, $controller)
  4469. {
  4470. $uri = $this->getResourceUri($name) . '/{' . $base . '}/edit';
  4471. return $this->get($uri, $this->getResourceAction($name, $controller, 'edit'));
  4472. }
  4473. protected function addResourceUpdate($name, $base, $controller)
  4474. {
  4475. $this->addPutResourceUpdate($name, $base, $controller);
  4476. return $this->addPatchResourceUpdate($name, $base, $controller);
  4477. }
  4478. protected function addPutResourceUpdate($name, $base, $controller)
  4479. {
  4480. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4481. return $this->put($uri, $this->getResourceAction($name, $controller, 'update'));
  4482. }
  4483. protected function addPatchResourceUpdate($name, $base, $controller)
  4484. {
  4485. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4486. $this->patch($uri, $controller . '@update');
  4487. }
  4488. protected function addResourceDestroy($name, $base, $controller)
  4489. {
  4490. $uri = $this->getResourceUri($name) . '/{' . $base . '}';
  4491. return $this->delete($uri, $this->getResourceAction($name, $controller, 'destroy'));
  4492. }
  4493. public function getResourceUri($resource)
  4494. {
  4495. if (!str_contains($resource, '.')) {
  4496. return $resource;
  4497. }
  4498. $segments = explode('.', $resource);
  4499. $nested = $this->getNestedResourceUri($segments);
  4500. $last = $this->getResourceWildcard(last($segments));
  4501. return str_replace('/{' . $last . '}', '', $nested);
  4502. }
  4503. protected function getNestedResourceUri(array $segments)
  4504. {
  4505. $me = $this;
  4506. return implode('/', array_map(function ($s) use($me) {
  4507. return $s . '/{' . $me->getResourceWildcard($s) . '}';
  4508. }, $segments));
  4509. }
  4510. protected function getResourceAction($resource, $controller, $method)
  4511. {
  4512. $name = $resource . '.' . $method;
  4513. $name = $this->getResourceName($resource, $method);
  4514. return array('as' => $name, 'uses' => $controller . '@' . $method);
  4515. }
  4516. protected function getResourceName($resource, $method)
  4517. {
  4518. if (count($this->groupStack) == 0) {
  4519. return $resource . '.' . $method;
  4520. }
  4521. return $this->getResourcePrefix($resource, $method);
  4522. }
  4523. protected function getResourcePrefix($resource, $method)
  4524. {
  4525. $prefix = str_replace('/', '.', $this->getGroupPrefix());
  4526. if ($prefix != '') {
  4527. $prefix .= '.';
  4528. }
  4529. return "{$prefix}{$resource}.{$method}";
  4530. }
  4531. protected function getBaseResource($resource)
  4532. {
  4533. $segments = explode('.', $resource);
  4534. return $this->getResourceWildcard($segments[count($segments) - 1]);
  4535. }
  4536. public function getResourceWildcard($value)
  4537. {
  4538. return str_replace('-', '_', $value);
  4539. }
  4540. public function group(array $attributes, Closure $callback)
  4541. {
  4542. $this->updateGroupStack($attributes);
  4543. call_user_func($callback);
  4544. array_pop($this->groupStack);
  4545. }
  4546. protected function updateGroupStack(array $attributes)
  4547. {
  4548. if (count($this->groupStack) > 0) {
  4549. $last = $this->groupStack[count($this->groupStack) - 1];
  4550. $this->groupStack[] = array_merge_recursive($last, $attributes);
  4551. } else {
  4552. $this->groupStack[] = $attributes;
  4553. }
  4554. }
  4555. protected function createRoute($method, $pattern, $action)
  4556. {
  4557. if (!is_array($action)) {
  4558. $action = $this->parseAction($action);
  4559. }
  4560. $groupCount = count($this->groupStack);
  4561. if ($groupCount > 0) {
  4562. $index = $groupCount - 1;
  4563. $action = $this->mergeGroup($action, $index);
  4564. }
  4565. list($pattern, $optional) = $this->getOptional($pattern);
  4566. if (isset($action['prefix'])) {
  4567. $prefix = $action['prefix'];
  4568. $pattern = $this->addPrefix($pattern, $prefix);
  4569. }
  4570. $route = with(new Route($pattern))->setOptions(array('_call' => $this->getCallback($action)))->setRouter($this)->addRequirements($this->patterns);
  4571. $route->setRequirement('_method', $method);
  4572. $this->setAttributes($route, $action, $optional);
  4573. $name = $this->getName($method, $pattern, $action);
  4574. $this->routes->add($name, $route);
  4575. return $route;
  4576. }
  4577. protected function parseAction($action)
  4578. {
  4579. if ($action instanceof Closure) {
  4580. return array($action);
  4581. } elseif (is_string($action)) {
  4582. return array('uses' => $action);
  4583. }
  4584. throw new \InvalidArgumentException('Unroutable action.');
  4585. }
  4586. protected function mergeGroup($action, $index)
  4587. {
  4588. $prefix = $this->mergeGroupPrefix($action);
  4589. $action = array_merge_recursive($this->groupStack[$index], $action);
  4590. if ($prefix != '') {
  4591. $action['prefix'] = $prefix;
  4592. }
  4593. return $action;
  4594. }
  4595. protected function getGroupPrefix()
  4596. {
  4597. if (count($this->groupStack) > 0) {
  4598. $group = $this->groupStack[count($this->groupStack) - 1];
  4599. if (isset($group['prefix'])) {
  4600. if (is_array($group['prefix'])) {
  4601. return implode('/', $group['prefix']);
  4602. }
  4603. return $group['prefix'];
  4604. }
  4605. }
  4606. return '';
  4607. }
  4608. protected function mergeGroupPrefix($action)
  4609. {
  4610. $prefix = isset($action['prefix']) ? $action['prefix'] : '';
  4611. return trim($this->getGroupPrefix() . '/' . $prefix, '/');
  4612. }
  4613. protected function addPrefix($pattern, $prefix)
  4614. {
  4615. $pattern = trim($prefix, '/') . '/' . ltrim($pattern, '/');
  4616. return trim($pattern, '/');
  4617. }
  4618. protected function setAttributes(Route $route, $action, $optional)
  4619. {
  4620. if (in_array('https', $action)) {
  4621. $route->setRequirement('_scheme', 'https');
  4622. }
  4623. if (in_array('http', $action)) {
  4624. $route->setRequirement('_scheme', 'http');
  4625. }
  4626. if (isset($action['before'])) {
  4627. $route->setBeforeFilters($action['before']);
  4628. }
  4629. if (isset($action['after'])) {
  4630. $route->setAfterFilters($action['after']);
  4631. }
  4632. if (isset($action['uses'])) {
  4633. $route->setOption('_uses', $action['uses']);
  4634. }
  4635. if (isset($action['domain'])) {
  4636. $route->setHost($action['domain']);
  4637. }
  4638. foreach ($optional as $key) {
  4639. $route->setDefault($key, null);
  4640. }
  4641. }
  4642. protected function getOptional($pattern)
  4643. {
  4644. $optional = array();
  4645. preg_match_all('#\\{(\\w+)\\?\\}#', $pattern, $matches);
  4646. foreach ($matches[0] as $key => $value) {
  4647. $optional[] = $name = $matches[1][$key];
  4648. $pattern = str_replace($value, '{' . $name . '}', $pattern);
  4649. }
  4650. return array($pattern, $optional);
  4651. }
  4652. protected function getName($method, $pattern, array $action)
  4653. {
  4654. if (isset($action['as'])) {
  4655. return $action['as'];
  4656. }
  4657. $domain = isset($action['domain']) ? $action['domain'] . ' ' : '';
  4658. return "{$domain}{$method} {$pattern}";
  4659. }
  4660. protected function getCallback(array $action)
  4661. {
  4662. foreach ($action as $key => $attribute) {
  4663. if ($key === 'uses') {
  4664. return $this->createControllerCallback($attribute);
  4665. } elseif ($attribute instanceof Closure) {
  4666. return $attribute;
  4667. }
  4668. }
  4669. }
  4670. protected function createControllerCallback($attribute)
  4671. {
  4672. $ioc = $this->container;
  4673. $me = $this;
  4674. return function () use($me, $ioc, $attribute) {
  4675. list($controller, $method) = explode('@', $attribute);
  4676. $route = $me->getCurrentRoute();
  4677. $args = array_values($route->getParametersWithoutDefaults());
  4678. $instance = $ioc->make($controller);
  4679. return $instance->callAction($ioc, $me, $method, $args);
  4680. };
  4681. }
  4682. public function dispatch(Request $request)
  4683. {
  4684. $this->currentRequest = $request;
  4685. $response = $this->callGlobalFilter($request, 'before');
  4686. if (!is_null($response)) {
  4687. $response = $this->prepare($response, $request);
  4688. } else {
  4689. $this->currentRoute = $route = $this->findRoute($request);
  4690. $response = $route->run($request);
  4691. }
  4692. $this->callAfterFilter($request, $response);
  4693. return $response;
  4694. }
  4695. protected function findRoute(Request $request)
  4696. {
  4697. try {
  4698. $path = $request->getPathInfo();
  4699. $parameters = $this->getUrlMatcher($request)->match($path);
  4700. } catch (ExceptionInterface $e) {
  4701. $this->handleRoutingException($e);
  4702. }
  4703. $route = $this->routes->get($parameters['_route']);
  4704. $route->setParameters($parameters);
  4705. return $route;
  4706. }
  4707. public function before($callback)
  4708. {
  4709. $this->globalFilters['before'][] = $this->buildGlobalFilter($callback);
  4710. }
  4711. public function after($callback)
  4712. {
  4713. $this->globalFilters['after'][] = $this->buildGlobalFilter($callback);
  4714. }
  4715. public function close($callback)
  4716. {
  4717. $this->globalFilters['close'][] = $this->buildGlobalFilter($callback);
  4718. }
  4719. public function finish($callback)
  4720. {
  4721. $this->globalFilters['finish'][] = $this->buildGlobalFilter($callback);
  4722. }
  4723. protected function buildGlobalFilter($callback)
  4724. {
  4725. if (is_string($callback)) {
  4726. $container = $this->container;
  4727. return function () use($callback, $container) {
  4728. $callable = array($container->make($callback), 'filter');
  4729. return call_user_func_array($callable, func_get_args());
  4730. };
  4731. } else {
  4732. return $callback;
  4733. }
  4734. }
  4735. public function filter($name, $callback)
  4736. {
  4737. $this->filters[$name] = $callback;
  4738. }
  4739. public function getFilter($name)
  4740. {
  4741. if (array_key_exists($name, $this->filters)) {
  4742. $filter = $this->filters[$name];
  4743. if (is_string($filter)) {
  4744. return $this->getClassBasedFilter($filter);
  4745. }
  4746. return $filter;
  4747. }
  4748. }
  4749. protected function getClassBasedFilter($filter)
  4750. {
  4751. if (str_contains($filter, '@')) {
  4752. list($class, $method) = explode('@', $filter);
  4753. return array($this->container->make($class), $method);
  4754. }
  4755. return array($this->container->make($filter), 'filter');
  4756. }
  4757. public function when($pattern, $names, $methods = null)
  4758. {
  4759. foreach ((array) $names as $name) {
  4760. if (!is_null($methods)) {
  4761. $methods = array_change_key_case((array) $methods);
  4762. }
  4763. $this->patternFilters[$pattern][] = compact('name', 'methods');
  4764. }
  4765. }
  4766. public function findPatternFilters(Request $request)
  4767. {
  4768. $results = array();
  4769. foreach ($this->patternFilters as $pattern => $filters) {
  4770. if (str_is('/' . $pattern, $request->getPathInfo())) {
  4771. $merge = $this->filterPatternsByMethod($request, $filters);
  4772. $results = array_merge($results, $merge);
  4773. }
  4774. }
  4775. return $results;
  4776. }
  4777. protected function filterPatternsByMethod(Request $request, $filters)
  4778. {
  4779. $results = array();
  4780. $method = strtolower($request->getMethod());
  4781. foreach ($filters as $filter) {
  4782. if (is_null($filter['methods']) or in_array($method, $filter['methods'])) {
  4783. $results[] = $filter['name'];
  4784. }
  4785. }
  4786. return $results;
  4787. }
  4788. protected function callAfterFilter(Request $request, SymfonyResponse $response)
  4789. {
  4790. $this->callGlobalFilter($request, 'after', array($response));
  4791. }
  4792. public function callFinishFilter(Request $request, SymfonyResponse $response)
  4793. {
  4794. $this->callGlobalFilter($request, 'finish', array($response));
  4795. }
  4796. public function callCloseFilter(Request $request, SymfonyResponse $response)
  4797. {
  4798. $this->callGlobalFilter($request, 'close', array($response));
  4799. }
  4800. protected function callGlobalFilter(Request $request, $name, array $parameters = array())
  4801. {
  4802. if (!$this->filtersEnabled()) {
  4803. return;
  4804. }
  4805. array_unshift($parameters, $request);
  4806. if (isset($this->globalFilters[$name])) {
  4807. foreach ($this->globalFilters[$name] as $filter) {
  4808. $response = call_user_func_array($filter, $parameters);
  4809. if (!is_null($response)) {
  4810. return $response;
  4811. }
  4812. }
  4813. }
  4814. }
  4815. public function pattern($key, $pattern)
  4816. {
  4817. $this->patterns[$key] = $pattern;
  4818. }
  4819. public function model($key, $class, Closure $callback = null)
  4820. {
  4821. return $this->bind($key, function ($value) use($class, $callback) {
  4822. if (is_null($value)) {
  4823. return null;
  4824. }
  4825. if (!is_null($model = with(new $class())->find($value))) {
  4826. return $model;
  4827. }
  4828. if ($callback instanceof Closure) {
  4829. return call_user_func($callback);
  4830. }
  4831. throw new NotFoundHttpException();
  4832. });
  4833. }
  4834. public function bind($key, $binder)
  4835. {
  4836. $this->binders[str_replace('-', '_', $key)] = $binder;
  4837. }
  4838. public function hasBinder($key)
  4839. {
  4840. return isset($this->binders[$key]);
  4841. }
  4842. public function performBinding($key, $value, $route)
  4843. {
  4844. return call_user_func($this->binders[$key], $value, $route);
  4845. }
  4846. public function prepare($value, Request $request)
  4847. {
  4848. if (!$value instanceof SymfonyResponse) {
  4849. $value = new Response($value);
  4850. }
  4851. return $value->prepare($request);
  4852. }
  4853. protected function handleRoutingException(\Exception $e)
  4854. {
  4855. if ($e instanceof ResourceNotFoundException) {
  4856. throw new NotFoundHttpException($e->getMessage());
  4857. } elseif ($e instanceof MethodNotAllowedException) {
  4858. $allowed = $e->getAllowedMethods();
  4859. throw new MethodNotAllowedHttpException($allowed, $e->getMessage());
  4860. }
  4861. }
  4862. public function currentRouteName()
  4863. {
  4864. foreach ($this->routes->all() as $name => $route) {
  4865. if ($route === $this->currentRoute) {
  4866. return $name;
  4867. }
  4868. }
  4869. }
  4870. public function currentRouteNamed($name)
  4871. {
  4872. $route = $this->routes->get($name);
  4873. return !is_null($route) and $route === $this->currentRoute;
  4874. }
  4875. public function currentRouteAction()
  4876. {
  4877. $currentRoute = $this->currentRoute;
  4878. if (!is_null($currentRoute)) {
  4879. return $currentRoute->getOption('_uses');
  4880. }
  4881. }
  4882. public function currentRouteUses($action)
  4883. {
  4884. return $this->currentRouteAction() === $action;
  4885. }
  4886. public function filtersEnabled()
  4887. {
  4888. return $this->runFilters;
  4889. }
  4890. public function enableFilters()
  4891. {
  4892. $this->runFilters = true;
  4893. }
  4894. public function disableFilters()
  4895. {
  4896. $this->runFilters = false;
  4897. }
  4898. public function getRoutes()
  4899. {
  4900. return $this->routes;
  4901. }
  4902. public function getRequest()
  4903. {
  4904. return $this->currentRequest;
  4905. }
  4906. public function getCurrentRoute()
  4907. {
  4908. return $this->currentRoute;
  4909. }
  4910. public function setCurrentRoute(Route $route)
  4911. {
  4912. $this->currentRoute = $route;
  4913. }
  4914. public function getFilters()
  4915. {
  4916. return $this->filters;
  4917. }
  4918. public function getGlobalFilters()
  4919. {
  4920. return $this->globalFilters;
  4921. }
  4922. protected function getUrlMatcher(Request $request)
  4923. {
  4924. $context = new RequestContext();
  4925. $context->fromRequest($request);
  4926. return new UrlMatcher($this->routes, $context);
  4927. }
  4928. public function getInspector()
  4929. {
  4930. return $this->inspector ?: new Controllers\Inspector();
  4931. }
  4932. public function setInspector(Inspector $inspector)
  4933. {
  4934. $this->inspector = $inspector;
  4935. }
  4936. public function getContainer()
  4937. {
  4938. return $this->container;
  4939. }
  4940. public function setContainer(Container $container)
  4941. {
  4942. $this->container = $container;
  4943. }
  4944. }
  4945. namespace Symfony\Component\Routing;
  4946. use Symfony\Component\Config\Resource\ResourceInterface;
  4947. class RouteCollection implements \IteratorAggregate, \Countable
  4948. {
  4949. private $routes = array();
  4950. private $resources = array();
  4951. public function __clone()
  4952. {
  4953. foreach ($this->routes as $name => $route) {
  4954. $this->routes[$name] = clone $route;
  4955. }
  4956. }
  4957. public function getIterator()
  4958. {
  4959. return new \ArrayIterator($this->routes);
  4960. }
  4961. public function count()
  4962. {
  4963. return count($this->routes);
  4964. }
  4965. public function add($name, Route $route)
  4966. {
  4967. unset($this->routes[$name]);
  4968. $this->routes[$name] = $route;
  4969. }
  4970. public function all()
  4971. {
  4972. return $this->routes;
  4973. }
  4974. public function get($name)
  4975. {
  4976. return isset($this->routes[$name]) ? $this->routes[$name] : null;
  4977. }
  4978. public function remove($name)
  4979. {
  4980. foreach ((array) $name as $n) {
  4981. unset($this->routes[$n]);
  4982. }
  4983. }
  4984. public function addCollection(RouteCollection $collection)
  4985. {
  4986. foreach ($collection->all() as $name => $route) {
  4987. unset($this->routes[$name]);
  4988. $this->routes[$name] = $route;
  4989. }
  4990. $this->resources = array_merge($this->resources, $collection->getResources());
  4991. }
  4992. public function addPrefix($prefix, array $defaults = array(), array $requirements = array())
  4993. {
  4994. $prefix = trim(trim($prefix), '/');
  4995. if ('' === $prefix) {
  4996. return;
  4997. }
  4998. foreach ($this->routes as $route) {
  4999. $route->setPath('/' . $prefix . $route->getPath());
  5000. $route->addDefaults($defaults);
  5001. $route->addRequirements($requirements);
  5002. }
  5003. }
  5004. public function setHost($pattern, array $defaults = array(), array $requirements = array())
  5005. {
  5006. foreach ($this->routes as $route) {
  5007. $route->setHost($pattern);
  5008. $route->addDefaults($defaults);
  5009. $route->addRequirements($requirements);
  5010. }
  5011. }
  5012. public function addDefaults(array $defaults)
  5013. {
  5014. if ($defaults) {
  5015. foreach ($this->routes as $route) {
  5016. $route->addDefaults($defaults);
  5017. }
  5018. }
  5019. }
  5020. public function addRequirements(array $requirements)
  5021. {
  5022. if ($requirements) {
  5023. foreach ($this->routes as $route) {
  5024. $route->addRequirements($requirements);
  5025. }
  5026. }
  5027. }
  5028. public function addOptions(array $options)
  5029. {
  5030. if ($options) {
  5031. foreach ($this->routes as $route) {
  5032. $route->addOptions($options);
  5033. }
  5034. }
  5035. }
  5036. public function setSchemes($schemes)
  5037. {
  5038. foreach ($this->routes as $route) {
  5039. $route->setSchemes($schemes);
  5040. }
  5041. }
  5042. public function setMethods($methods)
  5043. {
  5044. foreach ($this->routes as $route) {
  5045. $route->setMethods($methods);
  5046. }
  5047. }
  5048. public function getResources()
  5049. {
  5050. return array_unique($this->resources);
  5051. }
  5052. public function addResource(ResourceInterface $resource)
  5053. {
  5054. $this->resources[] = $resource;
  5055. }
  5056. }
  5057. namespace Illuminate\Workbench;
  5058. use Illuminate\Support\ServiceProvider;
  5059. use Illuminate\Workbench\Console\WorkbenchMakeCommand;
  5060. class WorkbenchServiceProvider extends ServiceProvider
  5061. {
  5062. protected $defer = false;
  5063. public function register()
  5064. {
  5065. $this->app['package.creator'] = $this->app->share(function ($app) {
  5066. return new PackageCreator($app['files']);
  5067. });
  5068. $this->app['command.workbench'] = $this->app->share(function ($app) {
  5069. return new WorkbenchMakeCommand($app['package.creator']);
  5070. });
  5071. $this->commands('command.workbench');
  5072. }
  5073. public function provides()
  5074. {
  5075. return array('package.creator', 'command.workbench');
  5076. }
  5077. }
  5078. namespace Illuminate\Events;
  5079. use Illuminate\Container\Container;
  5080. class Dispatcher
  5081. {
  5082. protected $container;
  5083. protected $listeners = array();
  5084. protected $wildcards = array();
  5085. protected $sorted = array();
  5086. public function __construct(Container $container = null)
  5087. {
  5088. $this->container = $container;
  5089. }
  5090. public function listen($event, $listener, $priority = 0)
  5091. {
  5092. if (str_contains($event, '*')) {
  5093. return $this->setupWildcardListen($event, $listener, $priority = 0);
  5094. }
  5095. $this->listeners[$event][$priority][] = $this->makeListener($listener);
  5096. unset($this->sorted[$event]);
  5097. }
  5098. protected function setupWildcardListen($event, $listener, $priority)
  5099. {
  5100. $this->wildcards[$event][] = $listener;
  5101. }
  5102. public function hasListeners($eventName)
  5103. {
  5104. return isset($this->listeners[$eventName]);
  5105. }
  5106. public function queue($event, $payload = array())
  5107. {
  5108. $me = $this;
  5109. $this->listen($event . '_queue', function () use($me, $event, $payload) {
  5110. $me->fire($event, $payload);
  5111. });
  5112. }
  5113. public function subscribe($subscriber)
  5114. {
  5115. $subscriber = $this->resolveSubscriber($subscriber);
  5116. $subscriber->subscribe($this);
  5117. }
  5118. protected function resolveSubscriber($subscriber)
  5119. {
  5120. if (is_string($subscriber)) {
  5121. return $this->container->make($subscriber);
  5122. }
  5123. return $subscriber;
  5124. }
  5125. public function until($event, $payload = array())
  5126. {
  5127. return $this->fire($event, $payload, true);
  5128. }
  5129. public function flush($event)
  5130. {
  5131. $this->fire($event . '_queue');
  5132. }
  5133. public function fire($event, $payload = array(), $halt = false)
  5134. {
  5135. $responses = array();
  5136. if (!is_array($payload)) {
  5137. $payload = array($payload);
  5138. }
  5139. $payload[] = $event;
  5140. foreach ($this->getListeners($event) as $listener) {
  5141. $response = call_user_func_array($listener, $payload);
  5142. if (!is_null($response) and $halt) {
  5143. return $response;
  5144. }
  5145. if ($response === false) {
  5146. break;
  5147. }
  5148. $responses[] = $response;
  5149. }
  5150. return $halt ? null : $responses;
  5151. }
  5152. public function getListeners($eventName)
  5153. {
  5154. $wildcards = $this->getWildcardListeners($eventName);
  5155. if (!isset($this->sorted[$eventName])) {
  5156. $this->sortListeners($eventName);
  5157. }
  5158. return array_merge($this->sorted[$eventName], $wildcards);
  5159. }
  5160. protected function getWildcardListeners($eventName)
  5161. {
  5162. $wildcards = array();
  5163. foreach ($this->wildcards as $key => $listeners) {
  5164. if (str_is($key, $eventName)) {
  5165. $wildcards = array_merge($wildcards, $listeners);
  5166. }
  5167. }
  5168. return $wildcards;
  5169. }
  5170. protected function sortListeners($eventName)
  5171. {
  5172. $this->sorted[$eventName] = array();
  5173. if (isset($this->listeners[$eventName])) {
  5174. krsort($this->listeners[$eventName]);
  5175. $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
  5176. }
  5177. }
  5178. public function makeListener($listener)
  5179. {
  5180. if (is_string($listener)) {
  5181. $listener = $this->createClassListener($listener);
  5182. }
  5183. return $listener;
  5184. }
  5185. public function createClassListener($listener)
  5186. {
  5187. $container = $this->container;
  5188. return function () use($listener, $container) {
  5189. $segments = explode('@', $listener);
  5190. $method = count($segments) == 2 ? $segments[1] : 'handle';
  5191. $callable = array($container->make($segments[0]), $method);
  5192. $data = func_get_args();
  5193. return call_user_func_array($callable, $data);
  5194. };
  5195. }
  5196. public function forget($event)
  5197. {
  5198. unset($this->listeners[$event]);
  5199. unset($this->sorted[$event]);
  5200. }
  5201. }
  5202. namespace Illuminate\Database\Eloquent;
  5203. use Closure;
  5204. use DateTime;
  5205. use Carbon\Carbon;
  5206. use ArrayAccess;
  5207. use Illuminate\Events\Dispatcher;
  5208. use Illuminate\Database\Connection;
  5209. use Illuminate\Database\Eloquent\Collection;
  5210. use Illuminate\Database\Eloquent\Relations\HasOne;
  5211. use Illuminate\Database\Eloquent\Relations\HasMany;
  5212. use Illuminate\Support\Contracts\JsonableInterface;
  5213. use Illuminate\Support\Contracts\ArrayableInterface;
  5214. use Illuminate\Database\Eloquent\Relations\MorphOne;
  5215. use Illuminate\Database\Eloquent\Relations\MorphMany;
  5216. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  5217. use Illuminate\Database\Query\Builder as QueryBuilder;
  5218. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  5219. use Illuminate\Database\ConnectionResolverInterface as Resolver;
  5220. abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterface
  5221. {
  5222. protected $connection;
  5223. protected $table;
  5224. protected $primaryKey = 'id';
  5225. protected $perPage = 15;
  5226. public $incrementing = true;
  5227. public $timestamps = true;
  5228. protected $attributes = array();
  5229. protected $original = array();
  5230. protected $relations = array();
  5231. protected $hidden = array();
  5232. protected $visible = array();
  5233. protected $fillable = array();
  5234. protected $guarded = array('*');
  5235. protected $touches = array();
  5236. protected $with = array();
  5237. public $exists = false;
  5238. protected $softDelete = false;
  5239. public static $snakeAttributes = true;
  5240. protected static $resolver;
  5241. protected static $dispatcher;
  5242. protected static $booted = array();
  5243. protected static $unguarded = false;
  5244. protected static $mutatorCache = array();
  5245. const CREATED_AT = 'created_at';
  5246. const UPDATED_AT = 'updated_at';
  5247. const DELETED_AT = 'deleted_at';
  5248. public function __construct(array $attributes = array())
  5249. {
  5250. if (!isset(static::$booted[get_class($this)])) {
  5251. static::boot();
  5252. static::$booted[get_class($this)] = true;
  5253. }
  5254. $this->fill($attributes);
  5255. }
  5256. protected static function boot()
  5257. {
  5258. $class = get_called_class();
  5259. static::$mutatorCache[$class] = array();
  5260. foreach (get_class_methods($class) as $method) {
  5261. if (preg_match('/^get(.+)Attribute$/', $method, $matches)) {
  5262. if (static::$snakeAttributes) {
  5263. $matches[1] = snake_case($matches[1]);
  5264. }
  5265. static::$mutatorCache[$class][] = lcfirst($matches[1]);
  5266. }
  5267. }
  5268. }
  5269. public static function observe($class)
  5270. {
  5271. $instance = new static();
  5272. $className = get_class($class);
  5273. foreach ($instance->getObservableEvents() as $event) {
  5274. if (method_exists($class, $event)) {
  5275. static::registerModelEvent($event, $className . '@' . $event);
  5276. }
  5277. }
  5278. }
  5279. public function fill(array $attributes)
  5280. {
  5281. foreach ($attributes as $key => $value) {
  5282. $key = $this->removeTableFromKey($key);
  5283. if ($this->isFillable($key)) {
  5284. $this->setAttribute($key, $value);
  5285. } elseif ($this->totallyGuarded()) {
  5286. throw new MassAssignmentException($key);
  5287. }
  5288. }
  5289. return $this;
  5290. }
  5291. public function newInstance($attributes = array(), $exists = false)
  5292. {
  5293. $model = new static((array) $attributes);
  5294. $model->exists = $exists;
  5295. return $model;
  5296. }
  5297. public function newFromBuilder($attributes = array())
  5298. {
  5299. $instance = $this->newInstance(array(), true);
  5300. $instance->setRawAttributes((array) $attributes, true);
  5301. return $instance;
  5302. }
  5303. public static function create(array $attributes)
  5304. {
  5305. $model = new static($attributes);
  5306. $model->save();
  5307. return $model;
  5308. }
  5309. public static function on($connection = null)
  5310. {
  5311. $instance = new static();
  5312. $instance->setConnection($connection);
  5313. return $instance->newQuery();
  5314. }
  5315. public static function all($columns = array('*'))
  5316. {
  5317. $instance = new static();
  5318. return $instance->newQuery()->get($columns);
  5319. }
  5320. public static function find($id, $columns = array('*'))
  5321. {
  5322. $instance = new static();
  5323. if (is_array($id)) {
  5324. return $instance->newQuery()->whereIn($instance->getKeyName(), $id)->get($columns);
  5325. }
  5326. return $instance->newQuery()->find($id, $columns);
  5327. }
  5328. public static function findOrFail($id, $columns = array('*'))
  5329. {
  5330. if (!is_null($model = static::find($id, $columns))) {
  5331. return $model;
  5332. }
  5333. throw new ModelNotFoundException();
  5334. }
  5335. public function load($relations)
  5336. {
  5337. if (is_string($relations)) {
  5338. $relations = func_get_args();
  5339. }
  5340. $query = $this->newQuery()->with($relations);
  5341. $query->eagerLoadRelations(array($this));
  5342. }
  5343. public static function with($relations)
  5344. {
  5345. if (is_string($relations)) {
  5346. $relations = func_get_args();
  5347. }
  5348. $instance = new static();
  5349. return $instance->newQuery()->with($relations);
  5350. }
  5351. public function hasOne($related, $foreignKey = null)
  5352. {
  5353. $foreignKey = $foreignKey ?: $this->getForeignKey();
  5354. $instance = new $related();
  5355. return new HasOne($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey);
  5356. }
  5357. public function morphOne($related, $name, $type = null, $id = null)
  5358. {
  5359. $instance = new $related();
  5360. list($type, $id) = $this->getMorphs($name, $type, $id);
  5361. $table = $instance->getTable();
  5362. return new MorphOne($instance->newQuery(), $this, $table . '.' . $type, $table . '.' . $id);
  5363. }
  5364. public function belongsTo($related, $foreignKey = null)
  5365. {
  5366. list(, $caller) = debug_backtrace(false);
  5367. $relation = $caller['function'];
  5368. if (is_null($foreignKey)) {
  5369. $foreignKey = snake_case($relation) . '_id';
  5370. }
  5371. $instance = new $related();
  5372. $query = $instance->newQuery();
  5373. return new BelongsTo($query, $this, $foreignKey, $relation);
  5374. }
  5375. public function morphTo($name = null, $type = null, $id = null)
  5376. {
  5377. if (is_null($name)) {
  5378. list(, $caller) = debug_backtrace(false);
  5379. $name = snake_case($caller['function']);
  5380. }
  5381. list($type, $id) = $this->getMorphs($name, $type, $id);
  5382. $class = $this->{$type};
  5383. return $this->belongsTo($class, $id);
  5384. }
  5385. public function hasMany($related, $foreignKey = null)
  5386. {
  5387. $foreignKey = $foreignKey ?: $this->getForeignKey();
  5388. $instance = new $related();
  5389. return new HasMany($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey);
  5390. }
  5391. public function morphMany($related, $name, $type = null, $id = null)
  5392. {
  5393. $instance = new $related();
  5394. list($type, $id) = $this->getMorphs($name, $type, $id);
  5395. $table = $instance->getTable();
  5396. return new MorphMany($instance->newQuery(), $this, $table . '.' . $type, $table . '.' . $id);
  5397. }
  5398. public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null)
  5399. {
  5400. $caller = $this->getBelongsToManyCaller();
  5401. $foreignKey = $foreignKey ?: $this->getForeignKey();
  5402. $instance = new $related();
  5403. $otherKey = $otherKey ?: $instance->getForeignKey();
  5404. if (is_null($table)) {
  5405. $table = $this->joiningTable($related);
  5406. }
  5407. $query = $instance->newQuery();
  5408. return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $caller['function']);
  5409. }
  5410. protected function getBelongsToManyCaller()
  5411. {
  5412. $self = __FUNCTION__;
  5413. return array_first(debug_backtrace(false), function ($trace) use($self) {
  5414. $caller = $trace['function'];
  5415. return $caller != 'belongsToMany' and $caller != $self;
  5416. });
  5417. }
  5418. public function joiningTable($related)
  5419. {
  5420. $base = snake_case(class_basename($this));
  5421. $related = snake_case(class_basename($related));
  5422. $models = array($related, $base);
  5423. sort($models);
  5424. return strtolower(implode('_', $models));
  5425. }
  5426. public static function destroy($ids)
  5427. {
  5428. $ids = is_array($ids) ? $ids : func_get_args();
  5429. $instance = new static();
  5430. $key = $instance->getKeyName();
  5431. foreach ($instance->whereIn($key, $ids)->get() as $model) {
  5432. $model->delete();
  5433. }
  5434. }
  5435. public function delete()
  5436. {
  5437. if ($this->exists) {
  5438. if ($this->fireModelEvent('deleting') === false) {
  5439. return false;
  5440. }
  5441. $this->touchOwners();
  5442. $this->performDeleteOnModel();
  5443. $this->exists = false;
  5444. $this->fireModelEvent('deleted', false);
  5445. return true;
  5446. }
  5447. }
  5448. public function forceDelete()
  5449. {
  5450. $softDelete = $this->softDelete;
  5451. $this->softDelete = false;
  5452. $this->delete();
  5453. $this->softDelete = $softDelete;
  5454. }
  5455. protected function performDeleteOnModel()
  5456. {
  5457. $query = $this->newQuery()->where($this->getKeyName(), $this->getKey());
  5458. if ($this->softDelete) {
  5459. $query->update(array(static::DELETED_AT => new DateTime()));
  5460. } else {
  5461. $query->delete();
  5462. }
  5463. }
  5464. public function restore()
  5465. {
  5466. if ($this->softDelete) {
  5467. $this->{static::DELETED_AT} = null;
  5468. return $this->save();
  5469. }
  5470. }
  5471. public static function saving($callback)
  5472. {
  5473. static::registerModelEvent('saving', $callback);
  5474. }
  5475. public static function saved($callback)
  5476. {
  5477. static::registerModelEvent('saved', $callback);
  5478. }
  5479. public static function updating($callback)
  5480. {
  5481. static::registerModelEvent('updating', $callback);
  5482. }
  5483. public static function updated($callback)
  5484. {
  5485. static::registerModelEvent('updated', $callback);
  5486. }
  5487. public static function creating($callback)
  5488. {
  5489. static::registerModelEvent('creating', $callback);
  5490. }
  5491. public static function created($callback)
  5492. {
  5493. static::registerModelEvent('created', $callback);
  5494. }
  5495. public static function deleting($callback)
  5496. {
  5497. static::registerModelEvent('deleting', $callback);
  5498. }
  5499. public static function deleted($callback)
  5500. {
  5501. static::registerModelEvent('deleted', $callback);
  5502. }
  5503. public static function flushEventListeners()
  5504. {
  5505. if (!isset(static::$dispatcher)) {
  5506. return;
  5507. }
  5508. $instance = new static();
  5509. foreach ($instance->getObservableEvents() as $event) {
  5510. static::$dispatcher->forget("eloquent.{$event}: " . get_called_class());
  5511. }
  5512. }
  5513. protected static function registerModelEvent($event, $callback)
  5514. {
  5515. if (isset(static::$dispatcher)) {
  5516. $name = get_called_class();
  5517. static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback);
  5518. }
  5519. }
  5520. public function getObservableEvents()
  5521. {
  5522. return array('creating', 'created', 'updating', 'updated', 'deleting', 'deleted', 'saving', 'saved');
  5523. }
  5524. protected function increment($column, $amount = 1)
  5525. {
  5526. return $this->incrementOrDecrement($column, $amount, 'increment');
  5527. }
  5528. protected function decrement($column, $amount = 1)
  5529. {
  5530. return $this->incrementOrDecrement($column, $amount, 'decrement');
  5531. }
  5532. protected function incrementOrDecrement($column, $amount, $method)
  5533. {
  5534. $query = $this->newQuery();
  5535. if (!$this->exists) {
  5536. return $query->{$method}($column, $amount);
  5537. }
  5538. return $query->where($this->getKeyName(), $this->getKey())->{$method}($column, $amount);
  5539. }
  5540. public function update(array $attributes = array())
  5541. {
  5542. if (!$this->exists) {
  5543. return $this->newQuery()->update($attributes);
  5544. }
  5545. return $this->fill($attributes)->save();
  5546. }
  5547. public function push()
  5548. {
  5549. if (!$this->save()) {
  5550. return false;
  5551. }
  5552. foreach ($this->relations as $models) {
  5553. foreach (Collection::make($models) as $model) {
  5554. if (!$model->push()) {
  5555. return false;
  5556. }
  5557. }
  5558. }
  5559. return true;
  5560. }
  5561. public function save(array $options = array())
  5562. {
  5563. $query = $this->newQueryWithDeleted();
  5564. if ($this->fireModelEvent('saving') === false) {
  5565. return false;
  5566. }
  5567. if ($this->exists) {
  5568. $saved = $this->performUpdate($query);
  5569. } else {
  5570. $saved = $this->performInsert($query);
  5571. }
  5572. if ($saved) {
  5573. $this->finishSave($options);
  5574. }
  5575. return $saved;
  5576. }
  5577. protected function finishSave(array $options)
  5578. {
  5579. $this->syncOriginal();
  5580. $this->fireModelEvent('saved', false);
  5581. if (array_get($options, 'touch', true)) {
  5582. $this->touchOwners();
  5583. }
  5584. }
  5585. protected function performUpdate($query)
  5586. {
  5587. $dirty = $this->getDirty();
  5588. if (count($dirty) > 0) {
  5589. if ($this->fireModelEvent('updating') === false) {
  5590. return false;
  5591. }
  5592. if ($this->timestamps) {
  5593. $this->updateTimestamps();
  5594. $dirty = $this->getDirty();
  5595. }
  5596. $this->setKeysForSaveQuery($query)->update($dirty);
  5597. $this->fireModelEvent('updated', false);
  5598. }
  5599. return true;
  5600. }
  5601. protected function performInsert($query)
  5602. {
  5603. if ($this->fireModelEvent('creating') === false) {
  5604. return false;
  5605. }
  5606. if ($this->timestamps) {
  5607. $this->updateTimestamps();
  5608. }
  5609. $attributes = $this->attributes;
  5610. if ($this->incrementing) {
  5611. $this->insertAndSetId($query, $attributes);
  5612. } else {
  5613. $query->insert($attributes);
  5614. }
  5615. $this->exists = true;
  5616. $this->fireModelEvent('created', false);
  5617. return true;
  5618. }
  5619. protected function insertAndSetId($query, $attributes)
  5620. {
  5621. $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
  5622. $this->setAttribute($keyName, $id);
  5623. }
  5624. public function touchOwners()
  5625. {
  5626. foreach ($this->touches as $relation) {
  5627. $this->{$relation}()->touch();
  5628. }
  5629. }
  5630. public function touches($relation)
  5631. {
  5632. return in_array($relation, $this->touches);
  5633. }
  5634. protected function fireModelEvent($event, $halt = true)
  5635. {
  5636. if (!isset(static::$dispatcher)) {
  5637. return true;
  5638. }
  5639. $event = "eloquent.{$event}: " . get_class($this);
  5640. $method = $halt ? 'until' : 'fire';
  5641. return static::$dispatcher->{$method}($event, $this);
  5642. }
  5643. protected function setKeysForSaveQuery($query)
  5644. {
  5645. $query->where($this->getKeyName(), '=', $this->getKey());
  5646. return $query;
  5647. }
  5648. public function touch()
  5649. {
  5650. $this->updateTimestamps();
  5651. return $this->save();
  5652. }
  5653. protected function updateTimestamps()
  5654. {
  5655. $time = $this->freshTimestamp();
  5656. if (!$this->isDirty(static::UPDATED_AT)) {
  5657. $this->setUpdatedAt($time);
  5658. }
  5659. if (!$this->exists and !$this->isDirty(static::CREATED_AT)) {
  5660. $this->setCreatedAt($time);
  5661. }
  5662. }
  5663. public function setCreatedAt($value)
  5664. {
  5665. $this->{static::CREATED_AT} = $value;
  5666. }
  5667. public function setUpdatedAt($value)
  5668. {
  5669. $this->{static::UPDATED_AT} = $value;
  5670. }
  5671. public function getCreatedAtColumn()
  5672. {
  5673. return static::CREATED_AT;
  5674. }
  5675. public function getUpdatedAtColumn()
  5676. {
  5677. return static::UPDATED_AT;
  5678. }
  5679. public function getDeletedAtColumn()
  5680. {
  5681. return static::DELETED_AT;
  5682. }
  5683. public function getQualifiedDeletedAtColumn()
  5684. {
  5685. return $this->getTable() . '.' . $this->getDeletedAtColumn();
  5686. }
  5687. public function freshTimestamp()
  5688. {
  5689. return new DateTime();
  5690. }
  5691. public function newQuery($excludeDeleted = true)
  5692. {
  5693. $builder = new Builder($this->newBaseQueryBuilder());
  5694. $builder->setModel($this)->with($this->with);
  5695. if ($excludeDeleted and $this->softDelete) {
  5696. $builder->whereNull($this->getQualifiedDeletedAtColumn());
  5697. }
  5698. return $builder;
  5699. }
  5700. public function newQueryWithDeleted()
  5701. {
  5702. return $this->newQuery(false);
  5703. }
  5704. public function trashed()
  5705. {
  5706. return $this->softDelete and !is_null($this->{static::DELETED_AT});
  5707. }
  5708. public static function withTrashed()
  5709. {
  5710. return with(new static())->newQueryWithDeleted();
  5711. }
  5712. public static function onlyTrashed()
  5713. {
  5714. $instance = new static();
  5715. $column = $instance->getQualifiedDeletedAtColumn();
  5716. return $instance->newQueryWithDeleted()->whereNotNull($column);
  5717. }
  5718. protected function newBaseQueryBuilder()
  5719. {
  5720. $conn = $this->getConnection();
  5721. $grammar = $conn->getQueryGrammar();
  5722. return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
  5723. }
  5724. public function newCollection(array $models = array())
  5725. {
  5726. return new Collection($models);
  5727. }
  5728. public function getTable()
  5729. {
  5730. if (isset($this->table)) {
  5731. return $this->table;
  5732. }
  5733. return str_replace('\\', '', snake_case(str_plural(get_class($this))));
  5734. }
  5735. public function setTable($table)
  5736. {
  5737. $this->table = $table;
  5738. }
  5739. public function getKey()
  5740. {
  5741. return $this->getAttribute($this->getKeyName());
  5742. }
  5743. public function getKeyName()
  5744. {
  5745. return $this->primaryKey;
  5746. }
  5747. public function getQualifiedKeyName()
  5748. {
  5749. return $this->getTable() . '.' . $this->getKeyName();
  5750. }
  5751. public function usesTimestamps()
  5752. {
  5753. return $this->timestamps;
  5754. }
  5755. public function isSoftDeleting()
  5756. {
  5757. return $this->softDelete;
  5758. }
  5759. public function setSoftDeleting($enabled)
  5760. {
  5761. $this->softDelete = $enabled;
  5762. }
  5763. protected function getMorphs($name, $type, $id)
  5764. {
  5765. $type = $type ?: $name . '_type';
  5766. $id = $id ?: $name . '_id';
  5767. return array($type, $id);
  5768. }
  5769. public function getPerPage()
  5770. {
  5771. return $this->perPage;
  5772. }
  5773. public function setPerPage($perPage)
  5774. {
  5775. $this->perPage = $perPage;
  5776. }
  5777. public function getForeignKey()
  5778. {
  5779. return snake_case(class_basename($this)) . '_id';
  5780. }
  5781. public function getHidden()
  5782. {
  5783. return $this->hidden;
  5784. }
  5785. public function setHidden(array $hidden)
  5786. {
  5787. $this->hidden = $hidden;
  5788. }
  5789. public function setVisible(array $visible)
  5790. {
  5791. $this->visible = $visible;
  5792. }
  5793. public function getFillable()
  5794. {
  5795. return $this->fillable;
  5796. }
  5797. public function fillable(array $fillable)
  5798. {
  5799. $this->fillable = $fillable;
  5800. return $this;
  5801. }
  5802. public function guard(array $guarded)
  5803. {
  5804. $this->guarded = $guarded;
  5805. return $this;
  5806. }
  5807. public static function unguard()
  5808. {
  5809. static::$unguarded = true;
  5810. }
  5811. public static function reguard()
  5812. {
  5813. static::$unguarded = false;
  5814. }
  5815. public static function setUnguardState($state)
  5816. {
  5817. static::$unguarded = $state;
  5818. }
  5819. public function isFillable($key)
  5820. {
  5821. if (static::$unguarded) {
  5822. return true;
  5823. }
  5824. if (in_array($key, $this->fillable)) {
  5825. return true;
  5826. }
  5827. if ($this->isGuarded($key)) {
  5828. return false;
  5829. }
  5830. return empty($this->fillable) and !starts_with($key, '_');
  5831. }
  5832. public function isGuarded($key)
  5833. {
  5834. return in_array($key, $this->guarded) or $this->guarded == array('*');
  5835. }
  5836. public function totallyGuarded()
  5837. {
  5838. return count($this->fillable) == 0 and $this->guarded == array('*');
  5839. }
  5840. protected function removeTableFromKey($key)
  5841. {
  5842. if (!str_contains($key, '.')) {
  5843. return $key;
  5844. }
  5845. return last(explode('.', $key));
  5846. }
  5847. public function getTouchedRelations()
  5848. {
  5849. return $this->touches;
  5850. }
  5851. public function setTouchedRelations(array $touches)
  5852. {
  5853. $this->touches = $touches;
  5854. }
  5855. public function getIncrementing()
  5856. {
  5857. return $this->incrementing;
  5858. }
  5859. public function setIncrementing($value)
  5860. {
  5861. $this->incrementing = $value;
  5862. }
  5863. public function toJson($options = 0)
  5864. {
  5865. return json_encode($this->toArray(), $options);
  5866. }
  5867. public function toArray()
  5868. {
  5869. $attributes = $this->attributesToArray();
  5870. return array_merge($attributes, $this->relationsToArray());
  5871. }
  5872. public function attributesToArray()
  5873. {
  5874. $attributes = $this->getAccessibleAttributes();
  5875. foreach ($this->getMutatedAttributes() as $key) {
  5876. if (!array_key_exists($key, $attributes)) {
  5877. continue;
  5878. }
  5879. $attributes[$key] = $this->mutateAttribute($key, $attributes[$key]);
  5880. }
  5881. return $attributes;
  5882. }
  5883. protected function getAccessibleAttributes()
  5884. {
  5885. if (count($this->visible) > 0) {
  5886. return array_intersect_key($this->attributes, array_flip($this->visible));
  5887. }
  5888. return array_diff_key($this->attributes, array_flip($this->hidden));
  5889. }
  5890. public function relationsToArray()
  5891. {
  5892. $attributes = array();
  5893. foreach ($this->relations as $key => $value) {
  5894. if (in_array($key, $this->hidden)) {
  5895. continue;
  5896. }
  5897. if ($value instanceof ArrayableInterface) {
  5898. $relation = $value->toArray();
  5899. } elseif (is_null($value)) {
  5900. $relation = $value;
  5901. }
  5902. if (static::$snakeAttributes) {
  5903. $key = snake_case($key);
  5904. }
  5905. if (isset($relation)) {
  5906. $attributes[$key] = $relation;
  5907. }
  5908. }
  5909. return $attributes;
  5910. }
  5911. public function getAttribute($key)
  5912. {
  5913. $inAttributes = array_key_exists($key, $this->attributes);
  5914. if ($inAttributes or $this->hasGetMutator($key)) {
  5915. return $this->getAttributeValue($key);
  5916. }
  5917. if (array_key_exists($key, $this->relations)) {
  5918. return $this->relations[$key];
  5919. }
  5920. $camelKey = camel_case($key);
  5921. if (method_exists($this, $camelKey)) {
  5922. $relations = $this->{$camelKey}()->getResults();
  5923. return $this->relations[$key] = $relations;
  5924. }
  5925. }
  5926. protected function getAttributeValue($key)
  5927. {
  5928. $value = $this->getAttributeFromArray($key);
  5929. if ($this->hasGetMutator($key)) {
  5930. return $this->mutateAttribute($key, $value);
  5931. } elseif (in_array($key, $this->getDates())) {
  5932. if ($value) {
  5933. return $this->asDateTime($value);
  5934. }
  5935. }
  5936. return $value;
  5937. }
  5938. protected function getAttributeFromArray($key)
  5939. {
  5940. if (array_key_exists($key, $this->attributes)) {
  5941. return $this->attributes[$key];
  5942. }
  5943. }
  5944. public function hasGetMutator($key)
  5945. {
  5946. return method_exists($this, 'get' . studly_case($key) . 'Attribute');
  5947. }
  5948. protected function mutateAttribute($key, $value)
  5949. {
  5950. return $this->{'get' . studly_case($key) . 'Attribute'}($value);
  5951. }
  5952. public function setAttribute($key, $value)
  5953. {
  5954. if ($this->hasSetMutator($key)) {
  5955. $method = 'set' . studly_case($key) . 'Attribute';
  5956. return $this->{$method}($value);
  5957. } elseif (in_array($key, $this->getDates())) {
  5958. if ($value) {
  5959. $value = $this->fromDateTime($value);
  5960. }
  5961. }
  5962. $this->attributes[$key] = $value;
  5963. }
  5964. public function hasSetMutator($key)
  5965. {
  5966. return method_exists($this, 'set' . studly_case($key) . 'Attribute');
  5967. }
  5968. public function getDates()
  5969. {
  5970. return array(static::CREATED_AT, static::UPDATED_AT, static::DELETED_AT);
  5971. }
  5972. protected function fromDateTime($value)
  5973. {
  5974. $format = $this->getDateFormat();
  5975. if ($value instanceof DateTime) {
  5976. } elseif (is_numeric($value)) {
  5977. $value = Carbon::createFromTimestamp($value);
  5978. } elseif (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value)) {
  5979. $value = Carbon::createFromFormat('Y-m-d', $value);
  5980. } elseif (!$value instanceof DateTime) {
  5981. $value = Carbon::createFromFormat($format, $value);
  5982. }
  5983. return $value->format($format);
  5984. }
  5985. protected function asDateTime($value)
  5986. {
  5987. if (is_numeric($value)) {
  5988. return Carbon::createFromTimestamp($value);
  5989. } elseif (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value)) {
  5990. return Carbon::createFromFormat('Y-m-d', $value);
  5991. } elseif (!$value instanceof DateTime) {
  5992. $format = $this->getDateFormat();
  5993. return Carbon::createFromFormat($format, $value);
  5994. }
  5995. return Carbon::instance($value);
  5996. }
  5997. protected function getDateFormat()
  5998. {
  5999. return $this->getConnection()->getQueryGrammar()->getDateFormat();
  6000. }
  6001. public function replicate()
  6002. {
  6003. $attributes = array_except($this->attributes, array($this->getKeyName()));
  6004. with($instance = new static())->setRawAttributes($attributes);
  6005. return $instance->setRelations($this->relations);
  6006. }
  6007. public function getAttributes()
  6008. {
  6009. return $this->attributes;
  6010. }
  6011. public function setRawAttributes(array $attributes, $sync = false)
  6012. {
  6013. $this->attributes = $attributes;
  6014. if ($sync) {
  6015. $this->syncOriginal();
  6016. }
  6017. }
  6018. public function getOriginal($key = null, $default = null)
  6019. {
  6020. return array_get($this->original, $key, $default);
  6021. }
  6022. public function syncOriginal()
  6023. {
  6024. $this->original = $this->attributes;
  6025. return $this;
  6026. }
  6027. public function isDirty($attribute)
  6028. {
  6029. return array_key_exists($attribute, $this->getDirty());
  6030. }
  6031. public function getDirty()
  6032. {
  6033. $dirty = array();
  6034. foreach ($this->attributes as $key => $value) {
  6035. if (!array_key_exists($key, $this->original) or $value !== $this->original[$key]) {
  6036. $dirty[$key] = $value;
  6037. }
  6038. }
  6039. return $dirty;
  6040. }
  6041. public function getRelation($relation)
  6042. {
  6043. return $this->relations[$relation];
  6044. }
  6045. public function setRelation($relation, $value)
  6046. {
  6047. $this->relations[$relation] = $value;
  6048. return $this;
  6049. }
  6050. public function setRelations(array $relations)
  6051. {
  6052. $this->relations = $relations;
  6053. return $this;
  6054. }
  6055. public function getConnection()
  6056. {
  6057. return static::resolveConnection($this->connection);
  6058. }
  6059. public function getConnectionName()
  6060. {
  6061. return $this->connection;
  6062. }
  6063. public function setConnection($name)
  6064. {
  6065. $this->connection = $name;
  6066. }
  6067. public static function resolveConnection($connection = null)
  6068. {
  6069. return static::$resolver->connection($connection);
  6070. }
  6071. public static function getConnectionResolver()
  6072. {
  6073. return static::$resolver;
  6074. }
  6075. public static function setConnectionResolver(Resolver $resolver)
  6076. {
  6077. static::$resolver = $resolver;
  6078. }
  6079. public static function getEventDispatcher()
  6080. {
  6081. return static::$dispatcher;
  6082. }
  6083. public static function setEventDispatcher(Dispatcher $dispatcher)
  6084. {
  6085. static::$dispatcher = $dispatcher;
  6086. }
  6087. public static function unsetEventDispatcher()
  6088. {
  6089. static::$dispatcher = null;
  6090. }
  6091. public function getMutatedAttributes()
  6092. {
  6093. $class = get_class($this);
  6094. if (isset(static::$mutatorCache[$class])) {
  6095. return static::$mutatorCache[get_class($this)];
  6096. }
  6097. return array();
  6098. }
  6099. public function __get($key)
  6100. {
  6101. return $this->getAttribute($key);
  6102. }
  6103. public function __set($key, $value)
  6104. {
  6105. $this->setAttribute($key, $value);
  6106. }
  6107. public function offsetExists($offset)
  6108. {
  6109. return isset($this->{$offset});
  6110. }
  6111. public function offsetGet($offset)
  6112. {
  6113. return $this->{$offset};
  6114. }
  6115. public function offsetSet($offset, $value)
  6116. {
  6117. $this->{$offset} = $value;
  6118. }
  6119. public function offsetUnset($offset)
  6120. {
  6121. unset($this->{$offset});
  6122. }
  6123. public function __isset($key)
  6124. {
  6125. return isset($this->attributes[$key]) or isset($this->relations[$key]);
  6126. }
  6127. public function __unset($key)
  6128. {
  6129. unset($this->attributes[$key]);
  6130. unset($this->relations[$key]);
  6131. }
  6132. public function __call($method, $parameters)
  6133. {
  6134. if (in_array($method, array('increment', 'decrement'))) {
  6135. return call_user_func_array(array($this, $method), $parameters);
  6136. }
  6137. $query = $this->newQuery();
  6138. return call_user_func_array(array($query, $method), $parameters);
  6139. }
  6140. public static function __callStatic($method, $parameters)
  6141. {
  6142. $instance = new static();
  6143. return call_user_func_array(array($instance, $method), $parameters);
  6144. }
  6145. public function __toString()
  6146. {
  6147. return $this->toJson();
  6148. }
  6149. }
  6150. namespace Illuminate\Support\Contracts;
  6151. interface ArrayableInterface
  6152. {
  6153. public function toArray();
  6154. }
  6155. namespace Illuminate\Support\Contracts;
  6156. interface JsonableInterface
  6157. {
  6158. public function toJson($options = 0);
  6159. }
  6160. namespace Illuminate\Database;
  6161. use Illuminate\Support\Manager;
  6162. use Illuminate\Database\Connectors\ConnectionFactory;
  6163. class DatabaseManager implements ConnectionResolverInterface
  6164. {
  6165. protected $app;
  6166. protected $factory;
  6167. protected $connections = array();
  6168. protected $extensions = array();
  6169. public function __construct($app, ConnectionFactory $factory)
  6170. {
  6171. $this->app = $app;
  6172. $this->factory = $factory;
  6173. }
  6174. public function connection($name = null)
  6175. {
  6176. $name = $name ?: $this->getDefaultConnection();
  6177. if (!isset($this->connections[$name])) {
  6178. $connection = $this->makeConnection($name);
  6179. $this->connections[$name] = $this->prepare($connection);
  6180. }
  6181. return $this->connections[$name];
  6182. }
  6183. public function reconnect($name = null)
  6184. {
  6185. unset($this->connections[$name]);
  6186. return $this->connection($name);
  6187. }
  6188. protected function makeConnection($name)
  6189. {
  6190. $config = $this->getConfig($name);
  6191. if (isset($this->extensions[$name])) {
  6192. return call_user_func($this->extensions[$name], $config);
  6193. }
  6194. return $this->factory->make($config, $name);
  6195. }
  6196. protected function prepare(Connection $connection)
  6197. {
  6198. $connection->setFetchMode($this->app['config']['database.fetch']);
  6199. if ($this->app->bound('events')) {
  6200. $connection->setEventDispatcher($this->app['events']);
  6201. }
  6202. $app = $this->app;
  6203. $connection->setCacheManager(function () use($app) {
  6204. return $app['cache'];
  6205. });
  6206. $connection->setPaginator(function () use($app) {
  6207. return $app['paginator'];
  6208. });
  6209. return $connection;
  6210. }
  6211. protected function getConfig($name)
  6212. {
  6213. $name = $name ?: $this->getDefaultConnection();
  6214. $connections = $this->app['config']['database.connections'];
  6215. if (is_null($config = array_get($connections, $name))) {
  6216. throw new \InvalidArgumentException("Database [{$name}] not configured.");
  6217. }
  6218. return $config;
  6219. }
  6220. public function getDefaultConnection()
  6221. {
  6222. return $this->app['config']['database.default'];
  6223. }
  6224. public function setDefaultConnection($name)
  6225. {
  6226. $this->app['config']['database.default'] = $name;
  6227. }
  6228. public function extend($name, $resolver)
  6229. {
  6230. $this->extensions[$name] = $resolver;
  6231. }
  6232. public function __call($method, $parameters)
  6233. {
  6234. return call_user_func_array(array($this->connection(), $method), $parameters);
  6235. }
  6236. }
  6237. namespace Illuminate\Database;
  6238. interface ConnectionResolverInterface
  6239. {
  6240. public function connection($name = null);
  6241. public function getDefaultConnection();
  6242. public function setDefaultConnection($name);
  6243. }
  6244. namespace Illuminate\Database\Connectors;
  6245. use PDO;
  6246. use Illuminate\Container\Container;
  6247. use Illuminate\Database\MySqlConnection;
  6248. use Illuminate\Database\SQLiteConnection;
  6249. use Illuminate\Database\PostgresConnection;
  6250. use Illuminate\Database\SqlServerConnection;
  6251. class ConnectionFactory
  6252. {
  6253. protected $container;
  6254. public function __construct(Container $container)
  6255. {
  6256. $this->container = $container;
  6257. }
  6258. public function make(array $config, $name = null)
  6259. {
  6260. $config = $this->parseConfig($config, $name);
  6261. $pdo = $this->createConnector($config)->connect($config);
  6262. return $this->createConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config);
  6263. }
  6264. protected function parseConfig(array $config, $name)
  6265. {
  6266. return array_add(array_add($config, 'prefix', ''), 'name', $name);
  6267. }
  6268. public function createConnector(array $config)
  6269. {
  6270. if (!isset($config['driver'])) {
  6271. throw new \InvalidArgumentException('A driver must be specified.');
  6272. }
  6273. switch ($config['driver']) {
  6274. case 'mysql':
  6275. return new MySqlConnector();
  6276. case 'pgsql':
  6277. return new PostgresConnector();
  6278. case 'sqlite':
  6279. return new SQLiteConnector();
  6280. case 'sqlsrv':
  6281. return new SqlServerConnector();
  6282. }
  6283. throw new \InvalidArgumentException("Unsupported driver [{$config['driver']}]");
  6284. }
  6285. protected function createConnection($driver, PDO $connection, $database, $prefix = '', $config = null)
  6286. {
  6287. if ($this->container->bound($key = "db.connection.{$driver}")) {
  6288. return $this->container->make($key, array($connection, $database, $prefix, $config));
  6289. }
  6290. switch ($driver) {
  6291. case 'mysql':
  6292. return new MySqlConnection($connection, $database, $prefix, $config);
  6293. case 'pgsql':
  6294. return new PostgresConnection($connection, $database, $prefix, $config);
  6295. case 'sqlite':
  6296. return new SQLiteConnection($connection, $database, $prefix, $config);
  6297. case 'sqlsrv':
  6298. return new SqlServerConnection($connection, $database, $prefix, $config);
  6299. }
  6300. throw new \InvalidArgumentException("Unsupported driver [{$driver}]");
  6301. }
  6302. }
  6303. namespace Illuminate\Session;
  6304. use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
  6305. class Store extends SymfonySession
  6306. {
  6307. public function start()
  6308. {
  6309. parent::start();
  6310. if (!$this->has('_token')) {
  6311. $this->put('_token', str_random(40));
  6312. }
  6313. }
  6314. public function save()
  6315. {
  6316. $this->ageFlashData();
  6317. return parent::save();
  6318. }
  6319. protected function ageFlashData()
  6320. {
  6321. foreach ($this->get('flash.old', array()) as $old) {
  6322. $this->forget($old);
  6323. }
  6324. $this->put('flash.old', $this->get('flash.new', array()));
  6325. $this->put('flash.new', array());
  6326. }
  6327. public function has($name)
  6328. {
  6329. return !is_null($this->get($name));
  6330. }
  6331. public function get($name, $default = null)
  6332. {
  6333. return array_get($this->all(), $name, $default);
  6334. }
  6335. public function hasOldInput($key)
  6336. {
  6337. return !is_null($this->getOldInput($key));
  6338. }
  6339. public function getOldInput($key = null, $default = null)
  6340. {
  6341. $input = $this->get('_old_input', array());
  6342. if (is_null($key)) {
  6343. return $input;
  6344. }
  6345. return array_get($input, $key, $default);
  6346. }
  6347. public function getToken()
  6348. {
  6349. return $this->token();
  6350. }
  6351. public function token()
  6352. {
  6353. return $this->get('_token');
  6354. }
  6355. public function put($key, $value)
  6356. {
  6357. $all = $this->all();
  6358. array_set($all, $key, $value);
  6359. $this->replace($all);
  6360. }
  6361. public function push($key, $value)
  6362. {
  6363. $array = $this->get($key, array());
  6364. $array[] = $value;
  6365. $this->put($key, $array);
  6366. }
  6367. public function flash($key, $value)
  6368. {
  6369. $this->put($key, $value);
  6370. $this->push('flash.new', $key);
  6371. $this->removeFromOldFlashData(array($key));
  6372. }
  6373. public function flashInput(array $value)
  6374. {
  6375. return $this->flash('_old_input', $value);
  6376. }
  6377. public function reflash()
  6378. {
  6379. $this->mergeNewFlashes($this->get('flash.old'));
  6380. $this->put('flash.old', array());
  6381. }
  6382. public function keep($keys = null)
  6383. {
  6384. $keys = is_array($keys) ? $keys : func_get_args();
  6385. $this->mergeNewFlashes($keys);
  6386. $this->removeFromOldFlashData($keys);
  6387. }
  6388. protected function mergeNewFlashes(array $keys)
  6389. {
  6390. $values = array_unique(array_merge($this->get('flash.new'), $keys));
  6391. $this->put('flash.new', $values);
  6392. }
  6393. protected function removeFromOldFlashData(array $keys)
  6394. {
  6395. $this->put('flash.old', array_diff($this->get('flash.old', array()), $keys));
  6396. }
  6397. public function forget($key)
  6398. {
  6399. $all = $this->all();
  6400. array_forget($all, $key);
  6401. $this->replace($all);
  6402. }
  6403. public function flush()
  6404. {
  6405. return $this->clear();
  6406. }
  6407. public function regenerate()
  6408. {
  6409. return $this->migrate();
  6410. }
  6411. }
  6412. namespace Illuminate\Session;
  6413. use Illuminate\Support\Manager;
  6414. use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
  6415. use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
  6416. use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
  6417. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
  6418. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
  6419. class SessionManager extends Manager
  6420. {
  6421. protected function callCustomCreator($driver)
  6422. {
  6423. return $this->buildSession(parent::callCustomCreator($driver));
  6424. }
  6425. protected function createArrayDriver()
  6426. {
  6427. return new Store(new MockArraySessionStorage());
  6428. }
  6429. protected function createCookieDriver()
  6430. {
  6431. $lifetime = $this->app['config']['session.lifetime'];
  6432. return $this->buildSession(new CookieSessionHandler($this->app['cookie'], $lifetime));
  6433. }
  6434. protected function createNativeDriver()
  6435. {
  6436. $path = $this->app['config']['session.files'];
  6437. return $this->buildSession(new NativeFileSessionHandler($path));
  6438. }
  6439. protected function createDatabaseDriver()
  6440. {
  6441. $connection = $this->getDatabaseConnection();
  6442. $table = $connection->getTablePrefix() . $this->app['config']['session.table'];
  6443. return $this->buildSession(new PdoSessionHandler($connection->getPdo(), $this->getDatabaseOptions($table)));
  6444. }
  6445. protected function getDatabaseConnection()
  6446. {
  6447. $connection = $this->app['config']['session.connection'];
  6448. return $this->app['db']->connection($connection);
  6449. }
  6450. protected function getDatabaseOptions($table)
  6451. {
  6452. return array('db_table' => $table, 'db_id_col' => 'id', 'db_data_col' => 'payload', 'db_time_col' => 'last_activity');
  6453. }
  6454. protected function createApcDriver()
  6455. {
  6456. return $this->createCacheBased('apc');
  6457. }
  6458. protected function createMemcachedDriver()
  6459. {
  6460. return $this->createCacheBased('memcached');
  6461. }
  6462. protected function createWincacheDriver()
  6463. {
  6464. return $this->createCacheBased('wincache');
  6465. }
  6466. protected function createRedisDriver()
  6467. {
  6468. return $this->createCacheBased('redis');
  6469. }
  6470. protected function createCacheBased($driver)
  6471. {
  6472. $minutes = $this->app['config']['session.lifetime'];
  6473. $handler = new CacheBasedSessionHandler($this->app['cache']->driver($driver), $minutes);
  6474. return $this->buildSession($handler);
  6475. }
  6476. protected function buildSession($handler)
  6477. {
  6478. return new Store(new NativeSessionStorage($this->getOptions(), $handler));
  6479. }
  6480. protected function getOptions()
  6481. {
  6482. $config = $this->app['config']['session'];
  6483. return array('cookie_domain' => $config['domain'], 'cookie_lifetime' => $config['lifetime'] * 60, 'cookie_path' => $config['path'], 'cookie_httponly' => '1', 'name' => $config['cookie'], 'gc_divisor' => $config['lottery'][1], 'gc_probability' => $config['lottery'][0]);
  6484. }
  6485. protected function getDefaultDriver()
  6486. {
  6487. return $this->app['config']['session.driver'];
  6488. }
  6489. }
  6490. namespace Illuminate\Support;
  6491. use Closure;
  6492. abstract class Manager
  6493. {
  6494. protected $app;
  6495. protected $customCreators = array();
  6496. protected $drivers = array();
  6497. public function __construct($app)
  6498. {
  6499. $this->app = $app;
  6500. }
  6501. public function driver($driver = null)
  6502. {
  6503. $driver = $driver ?: $this->getDefaultDriver();
  6504. if (!isset($this->drivers[$driver])) {
  6505. $this->drivers[$driver] = $this->createDriver($driver);
  6506. }
  6507. return $this->drivers[$driver];
  6508. }
  6509. protected function createDriver($driver)
  6510. {
  6511. $method = 'create' . ucfirst($driver) . 'Driver';
  6512. if (isset($this->customCreators[$driver])) {
  6513. return $this->callCustomCreator($driver);
  6514. } elseif (method_exists($this, $method)) {
  6515. return $this->{$method}();
  6516. }
  6517. throw new \InvalidArgumentException("Driver [{$driver}] not supported.");
  6518. }
  6519. protected function callCustomCreator($driver)
  6520. {
  6521. return $this->customCreators[$driver]($this->app);
  6522. }
  6523. public function extend($driver, Closure $callback)
  6524. {
  6525. $this->customCreators[$driver] = $callback;
  6526. }
  6527. public function getDrivers()
  6528. {
  6529. return $this->drivers;
  6530. }
  6531. public function __call($method, $parameters)
  6532. {
  6533. return call_user_func_array(array($this->driver(), $method), $parameters);
  6534. }
  6535. }
  6536. namespace Illuminate\Cookie;
  6537. use Closure;
  6538. use Illuminate\Encryption\Encrypter;
  6539. use Symfony\Component\HttpFoundation\Cookie;
  6540. use Symfony\Component\HttpFoundation\Request;
  6541. use Symfony\Component\HttpFoundation\Response;
  6542. class CookieJar
  6543. {
  6544. protected $request;
  6545. protected $encrypter;
  6546. protected $path = '/';
  6547. protected $domain = null;
  6548. public function __construct(Request $request, Encrypter $encrypter)
  6549. {
  6550. $this->request = $request;
  6551. $this->encrypter = $encrypter;
  6552. }
  6553. public function has($key)
  6554. {
  6555. return !is_null($this->get($key));
  6556. }
  6557. public function get($key, $default = null)
  6558. {
  6559. $value = $this->request->cookies->get($key);
  6560. if (!is_null($value)) {
  6561. return $this->decrypt($value);
  6562. }
  6563. return $default instanceof Closure ? $default() : $default;
  6564. }
  6565. protected function decrypt($value)
  6566. {
  6567. try {
  6568. return $this->encrypter->decrypt($value);
  6569. } catch (\Exception $e) {
  6570. return null;
  6571. }
  6572. }
  6573. public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
  6574. {
  6575. list($path, $domain) = $this->getPathAndDomain($path, $domain);
  6576. $time = $minutes == 0 ? 0 : time() + $minutes * 60;
  6577. $value = $this->encrypter->encrypt($value);
  6578. return new Cookie($name, $value, $time, $path, $domain, $secure, $httpOnly);
  6579. }
  6580. public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true)
  6581. {
  6582. return $this->make($name, $value, 2628000, $path, $domain, $secure, $httpOnly);
  6583. }
  6584. public function forget($name)
  6585. {
  6586. return $this->make($name, null, -2628000);
  6587. }
  6588. protected function getPathAndDomain($path, $domain)
  6589. {
  6590. return array($path ?: $this->path, $domain ?: $this->domain);
  6591. }
  6592. public function setDefaultPathAndDomain($path, $domain)
  6593. {
  6594. list($this->path, $this->domain) = array($path, $domain);
  6595. return $this;
  6596. }
  6597. public function getRequest()
  6598. {
  6599. return $this->request;
  6600. }
  6601. public function getEncrypter()
  6602. {
  6603. return $this->encrypter;
  6604. }
  6605. }
  6606. namespace Illuminate\Encryption;
  6607. class DecryptException extends \RuntimeException
  6608. {
  6609. }
  6610. class Encrypter
  6611. {
  6612. protected $key;
  6613. protected $cipher = 'rijndael-256';
  6614. protected $mode = 'cbc';
  6615. protected $block = 32;
  6616. public function __construct($key)
  6617. {
  6618. $this->key = $key;
  6619. }
  6620. public function encrypt($value)
  6621. {
  6622. $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
  6623. $value = base64_encode($this->padAndMcrypt($value, $iv));
  6624. $iv = base64_encode($iv);
  6625. $mac = $this->hash($value);
  6626. return base64_encode(json_encode(compact('iv', 'value', 'mac')));
  6627. }
  6628. protected function padAndMcrypt($value, $iv)
  6629. {
  6630. $value = $this->addPadding(serialize($value));
  6631. return mcrypt_encrypt($this->cipher, $this->key, $value, $this->mode, $iv);
  6632. }
  6633. public function decrypt($payload)
  6634. {
  6635. $payload = $this->getJsonPayload($payload);
  6636. $value = base64_decode($payload['value']);
  6637. $iv = base64_decode($payload['iv']);
  6638. return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
  6639. }
  6640. protected function mcryptDecrypt($value, $iv)
  6641. {
  6642. return mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv);
  6643. }
  6644. protected function getJsonPayload($payload)
  6645. {
  6646. $payload = json_decode(base64_decode($payload), true);
  6647. if (!$payload or $this->invalidPayload($payload)) {
  6648. throw new DecryptException('Invalid data passed to encrypter.');
  6649. }
  6650. if ($payload['mac'] != $this->hash($payload['value'])) {
  6651. throw new DecryptException('MAC for payload is invalid.');
  6652. }
  6653. return $payload;
  6654. }
  6655. protected function hash($value)
  6656. {
  6657. return hash_hmac('sha256', $value, $this->key);
  6658. }
  6659. protected function addPadding($value)
  6660. {
  6661. $pad = $this->block - strlen($value) % $this->block;
  6662. return $value . str_repeat(chr($pad), $pad);
  6663. }
  6664. protected function stripPadding($value)
  6665. {
  6666. $pad = ord($value[($len = strlen($value)) - 1]);
  6667. return $this->paddingIsValid($pad, $value) ? substr($value, 0, strlen($value) - $pad) : $value;
  6668. }
  6669. protected function paddingIsValid($pad, $value)
  6670. {
  6671. $beforePad = strlen($value) - $pad;
  6672. return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
  6673. }
  6674. protected function invalidPayload(array $data)
  6675. {
  6676. return !isset($data['iv']) or !isset($data['value']) or !isset($data['mac']);
  6677. }
  6678. protected function getIvSize()
  6679. {
  6680. return mcrypt_get_iv_size($this->cipher, $this->mode);
  6681. }
  6682. protected function getRandomizer()
  6683. {
  6684. if (defined('MCRYPT_DEV_URANDOM')) {
  6685. return MCRYPT_DEV_URANDOM;
  6686. }
  6687. if (defined('MCRYPT_DEV_RANDOM')) {
  6688. return MCRYPT_DEV_RANDOM;
  6689. }
  6690. mt_srand();
  6691. return MCRYPT_RAND;
  6692. }
  6693. public function setKey($key)
  6694. {
  6695. $this->key = $key;
  6696. }
  6697. public function setCipher($cipher)
  6698. {
  6699. $this->cipher = $cipher;
  6700. }
  6701. public function setMode($mode)
  6702. {
  6703. $this->mode = $mode;
  6704. }
  6705. }
  6706. namespace Illuminate\Support\Facades;
  6707. class Log extends Facade
  6708. {
  6709. protected static function getFacadeAccessor()
  6710. {
  6711. return 'log';
  6712. }
  6713. }
  6714. namespace Illuminate\Log;
  6715. use Illuminate\Support\ServiceProvider;
  6716. class LogServiceProvider extends ServiceProvider
  6717. {
  6718. protected $defer = true;
  6719. public function register()
  6720. {
  6721. $logger = new Writer(new \Monolog\Logger('log'), $this->app['events']);
  6722. $this->app->instance('log', $logger);
  6723. if (isset($this->app['log.setup'])) {
  6724. call_user_func($this->app['log.setup'], $logger);
  6725. }
  6726. }
  6727. public function provides()
  6728. {
  6729. return array('log');
  6730. }
  6731. }
  6732. namespace Illuminate\Log;
  6733. use Closure;
  6734. use Illuminate\Events\Dispatcher;
  6735. use Monolog\Handler\StreamHandler;
  6736. use Monolog\Logger as MonologLogger;
  6737. use Monolog\Handler\RotatingFileHandler;
  6738. class Writer
  6739. {
  6740. protected $monolog;
  6741. protected $levels = array('debug', 'info', 'notice', 'warning', 'error', 'critical', 'alert', 'emergency');
  6742. protected $dispatcher;
  6743. public function __construct(MonologLogger $monolog, Dispatcher $dispatcher = null)
  6744. {
  6745. $this->monolog = $monolog;
  6746. if (isset($dispatcher)) {
  6747. $this->dispatcher = $dispatcher;
  6748. }
  6749. }
  6750. public function useFiles($path, $level = 'debug')
  6751. {
  6752. $level = $this->parseLevel($level);
  6753. $this->monolog->pushHandler(new StreamHandler($path, $level));
  6754. }
  6755. public function useDailyFiles($path, $days = 0, $level = 'debug')
  6756. {
  6757. $level = $this->parseLevel($level);
  6758. $this->monolog->pushHandler(new RotatingFileHandler($path, $days, $level));
  6759. }
  6760. protected function parseLevel($level)
  6761. {
  6762. switch ($level) {
  6763. case 'debug':
  6764. return MonologLogger::DEBUG;
  6765. case 'info':
  6766. return MonologLogger::INFO;
  6767. case 'notice':
  6768. return MonologLogger::NOTICE;
  6769. case 'warning':
  6770. return MonologLogger::WARNING;
  6771. case 'error':
  6772. return MonologLogger::ERROR;
  6773. case 'critical':
  6774. return MonologLogger::CRITICAL;
  6775. case 'alert':
  6776. return MonologLogger::ALERT;
  6777. case 'emergency':
  6778. return MonologLogger::EMERGENCY;
  6779. default:
  6780. throw new \InvalidArgumentException('Invalid log level.');
  6781. }
  6782. }
  6783. public function getMonolog()
  6784. {
  6785. return $this->monolog;
  6786. }
  6787. public function listen(Closure $callback)
  6788. {
  6789. if (!isset($this->dispatcher)) {
  6790. throw new \RuntimeException('Events dispatcher has not been set.');
  6791. }
  6792. $this->dispatcher->listen('illuminate.log', $callback);
  6793. }
  6794. public function getEventDispatcher()
  6795. {
  6796. return $this->dispatcher;
  6797. }
  6798. public function setEventDispatcher(Dispatcher $dispatcher)
  6799. {
  6800. $this->dispatcher = $dispatcher;
  6801. }
  6802. protected function fireLogEvent($level, $message, array $context = array())
  6803. {
  6804. if (isset($this->dispatcher)) {
  6805. $this->dispatcher->fire('illuminate.log', compact('level', 'message', 'context'));
  6806. }
  6807. }
  6808. public function __call($method, $parameters)
  6809. {
  6810. if (in_array($method, $this->levels)) {
  6811. call_user_func_array(array($this, 'fireLogEvent'), array_merge(array($method), $parameters));
  6812. $method = 'add' . ucfirst($method);
  6813. return call_user_func_array(array($this->monolog, $method), $parameters);
  6814. }
  6815. throw new \BadMethodCallException("Method [{$method}] does not exist.");
  6816. }
  6817. }
  6818. namespace Monolog;
  6819. use Monolog\Handler\HandlerInterface;
  6820. use Monolog\Handler\StreamHandler;
  6821. use Psr\Log\LoggerInterface;
  6822. use Psr\Log\InvalidArgumentException;
  6823. class Logger implements LoggerInterface
  6824. {
  6825. const DEBUG = 100;
  6826. const INFO = 200;
  6827. const NOTICE = 250;
  6828. const WARNING = 300;
  6829. const ERROR = 400;
  6830. const CRITICAL = 500;
  6831. const ALERT = 550;
  6832. const EMERGENCY = 600;
  6833. protected static $levels = array(100 => 'DEBUG', 200 => 'INFO', 250 => 'NOTICE', 300 => 'WARNING', 400 => 'ERROR', 500 => 'CRITICAL', 550 => 'ALERT', 600 => 'EMERGENCY');
  6834. protected static $timezone;
  6835. protected $name;
  6836. protected $handlers;
  6837. protected $processors;
  6838. public function __construct($name, array $handlers = array(), array $processors = array())
  6839. {
  6840. $this->name = $name;
  6841. $this->handlers = $handlers;
  6842. $this->processors = $processors;
  6843. }
  6844. public function getName()
  6845. {
  6846. return $this->name;
  6847. }
  6848. public function pushHandler(HandlerInterface $handler)
  6849. {
  6850. array_unshift($this->handlers, $handler);
  6851. }
  6852. public function popHandler()
  6853. {
  6854. if (!$this->handlers) {
  6855. throw new \LogicException('You tried to pop from an empty handler stack.');
  6856. }
  6857. return array_shift($this->handlers);
  6858. }
  6859. public function pushProcessor($callback)
  6860. {
  6861. if (!is_callable($callback)) {
  6862. throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given');
  6863. }
  6864. array_unshift($this->processors, $callback);
  6865. }
  6866. public function popProcessor()
  6867. {
  6868. if (!$this->processors) {
  6869. throw new \LogicException('You tried to pop from an empty processor stack.');
  6870. }
  6871. return array_shift($this->processors);
  6872. }
  6873. public function addRecord($level, $message, array $context = array())
  6874. {
  6875. if (!$this->handlers) {
  6876. $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG));
  6877. }
  6878. if (!static::$timezone) {
  6879. static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC');
  6880. }
  6881. $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());
  6882. $handlerKey = null;
  6883. foreach ($this->handlers as $key => $handler) {
  6884. if ($handler->isHandling($record)) {
  6885. $handlerKey = $key;
  6886. break;
  6887. }
  6888. }
  6889. if (null === $handlerKey) {
  6890. return false;
  6891. }
  6892. foreach ($this->processors as $processor) {
  6893. $record = call_user_func($processor, $record);
  6894. }
  6895. while (isset($this->handlers[$handlerKey]) && false === $this->handlers[$handlerKey]->handle($record)) {
  6896. $handlerKey++;
  6897. }
  6898. return true;
  6899. }
  6900. public function addDebug($message, array $context = array())
  6901. {
  6902. return $this->addRecord(static::DEBUG, $message, $context);
  6903. }
  6904. public function addInfo($message, array $context = array())
  6905. {
  6906. return $this->addRecord(static::INFO, $message, $context);
  6907. }
  6908. public function addNotice($message, array $context = array())
  6909. {
  6910. return $this->addRecord(static::NOTICE, $message, $context);
  6911. }
  6912. public function addWarning($message, array $context = array())
  6913. {
  6914. return $this->addRecord(static::WARNING, $message, $context);
  6915. }
  6916. public function addError($message, array $context = array())
  6917. {
  6918. return $this->addRecord(static::ERROR, $message, $context);
  6919. }
  6920. public function addCritical($message, array $context = array())
  6921. {
  6922. return $this->addRecord(static::CRITICAL, $message, $context);
  6923. }
  6924. public function addAlert($message, array $context = array())
  6925. {
  6926. return $this->addRecord(static::ALERT, $message, $context);
  6927. }
  6928. public function addEmergency($message, array $context = array())
  6929. {
  6930. return $this->addRecord(static::EMERGENCY, $message, $context);
  6931. }
  6932. public static function getLevels()
  6933. {
  6934. return array_flip(static::$levels);
  6935. }
  6936. public static function getLevelName($level)
  6937. {
  6938. if (!isset(static::$levels[$level])) {
  6939. throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(static::$levels)));
  6940. }
  6941. return static::$levels[$level];
  6942. }
  6943. public function isHandling($level)
  6944. {
  6945. $record = array('level' => $level);
  6946. foreach ($this->handlers as $handler) {
  6947. if ($handler->isHandling($record)) {
  6948. return true;
  6949. }
  6950. }
  6951. return false;
  6952. }
  6953. public function log($level, $message, array $context = array())
  6954. {
  6955. if (is_string($level) && defined(__CLASS__ . '::' . strtoupper($level))) {
  6956. $level = constant(__CLASS__ . '::' . strtoupper($level));
  6957. }
  6958. return $this->addRecord($level, $message, $context);
  6959. }
  6960. public function debug($message, array $context = array())
  6961. {
  6962. return $this->addRecord(static::DEBUG, $message, $context);
  6963. }
  6964. public function info($message, array $context = array())
  6965. {
  6966. return $this->addRecord(static::INFO, $message, $context);
  6967. }
  6968. public function notice($message, array $context = array())
  6969. {
  6970. return $this->addRecord(static::NOTICE, $message, $context);
  6971. }
  6972. public function warn($message, array $context = array())
  6973. {
  6974. return $this->addRecord(static::WARNING, $message, $context);
  6975. }
  6976. public function warning($message, array $context = array())
  6977. {
  6978. return $this->addRecord(static::WARNING, $message, $context);
  6979. }
  6980. public function err($message, array $context = array())
  6981. {
  6982. return $this->addRecord(static::ERROR, $message, $context);
  6983. }
  6984. public function error($message, array $context = array())
  6985. {
  6986. return $this->addRecord(static::ERROR, $message, $context);
  6987. }
  6988. public function crit($message, array $context = array())
  6989. {
  6990. return $this->addRecord(static::CRITICAL, $message, $context);
  6991. }
  6992. public function critical($message, array $context = array())
  6993. {
  6994. return $this->addRecord(static::CRITICAL, $message, $context);
  6995. }
  6996. public function alert($message, array $context = array())
  6997. {
  6998. return $this->addRecord(static::ALERT, $message, $context);
  6999. }
  7000. public function emerg($message, array $context = array())
  7001. {
  7002. return $this->addRecord(static::EMERGENCY, $message, $context);
  7003. }
  7004. public function emergency($message, array $context = array())
  7005. {
  7006. return $this->addRecord(static::EMERGENCY, $message, $context);
  7007. }
  7008. }
  7009. namespace Psr\Log;
  7010. interface LoggerInterface
  7011. {
  7012. public function emergency($message, array $context = array());
  7013. public function alert($message, array $context = array());
  7014. public function critical($message, array $context = array());
  7015. public function error($message, array $context = array());
  7016. public function warning($message, array $context = array());
  7017. public function notice($message, array $context = array());
  7018. public function info($message, array $context = array());
  7019. public function debug($message, array $context = array());
  7020. public function log($level, $message, array $context = array());
  7021. }
  7022. namespace Monolog\Handler;
  7023. use Monolog\Logger;
  7024. use Monolog\Formatter\FormatterInterface;
  7025. use Monolog\Formatter\LineFormatter;
  7026. abstract class AbstractHandler implements HandlerInterface
  7027. {
  7028. protected $level = Logger::DEBUG;
  7029. protected $bubble = false;
  7030. protected $formatter;
  7031. protected $processors = array();
  7032. public function __construct($level = Logger::DEBUG, $bubble = true)
  7033. {
  7034. $this->level = $level;
  7035. $this->bubble = $bubble;
  7036. }
  7037. public function isHandling(array $record)
  7038. {
  7039. return $record['level'] >= $this->level;
  7040. }
  7041. public function handleBatch(array $records)
  7042. {
  7043. foreach ($records as $record) {
  7044. $this->handle($record);
  7045. }
  7046. }
  7047. public function close()
  7048. {
  7049. }
  7050. public function pushProcessor($callback)
  7051. {
  7052. if (!is_callable($callback)) {
  7053. throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given');
  7054. }
  7055. array_unshift($this->processors, $callback);
  7056. }
  7057. public function popProcessor()
  7058. {
  7059. if (!$this->processors) {
  7060. throw new \LogicException('You tried to pop from an empty processor stack.');
  7061. }
  7062. return array_shift($this->processors);
  7063. }
  7064. public function setFormatter(FormatterInterface $formatter)
  7065. {
  7066. $this->formatter = $formatter;
  7067. }
  7068. public function getFormatter()
  7069. {
  7070. if (!$this->formatter) {
  7071. $this->formatter = $this->getDefaultFormatter();
  7072. }
  7073. return $this->formatter;
  7074. }
  7075. public function setLevel($level)
  7076. {
  7077. $this->level = $level;
  7078. }
  7079. public function getLevel()
  7080. {
  7081. return $this->level;
  7082. }
  7083. public function setBubble($bubble)
  7084. {
  7085. $this->bubble = $bubble;
  7086. }
  7087. public function getBubble()
  7088. {
  7089. return $this->bubble;
  7090. }
  7091. public function __destruct()
  7092. {
  7093. try {
  7094. $this->close();
  7095. } catch (\Exception $e) {
  7096. }
  7097. }
  7098. protected function getDefaultFormatter()
  7099. {
  7100. return new LineFormatter();
  7101. }
  7102. }
  7103. namespace Monolog\Handler;
  7104. abstract class AbstractProcessingHandler extends AbstractHandler
  7105. {
  7106. public function handle(array $record)
  7107. {
  7108. if ($record['level'] < $this->level) {
  7109. return false;
  7110. }
  7111. $record = $this->processRecord($record);
  7112. $record['formatted'] = $this->getFormatter()->format($record);
  7113. $this->write($record);
  7114. return false === $this->bubble;
  7115. }
  7116. protected abstract function write(array $record);
  7117. protected function processRecord(array $record)
  7118. {
  7119. if ($this->processors) {
  7120. foreach ($this->processors as $processor) {
  7121. $record = call_user_func($processor, $record);
  7122. }
  7123. }
  7124. return $record;
  7125. }
  7126. }
  7127. namespace Monolog\Handler;
  7128. use Monolog\Logger;
  7129. class StreamHandler extends AbstractProcessingHandler
  7130. {
  7131. protected $stream;
  7132. protected $url;
  7133. public function __construct($stream, $level = Logger::DEBUG, $bubble = true)
  7134. {
  7135. parent::__construct($level, $bubble);
  7136. if (is_resource($stream)) {
  7137. $this->stream = $stream;
  7138. } else {
  7139. $this->url = $stream;
  7140. }
  7141. }
  7142. public function close()
  7143. {
  7144. if (is_resource($this->stream)) {
  7145. fclose($this->stream);
  7146. }
  7147. $this->stream = null;
  7148. }
  7149. protected function write(array $record)
  7150. {
  7151. if (null === $this->stream) {
  7152. if (!$this->url) {
  7153. throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
  7154. }
  7155. $errorMessage = null;
  7156. set_error_handler(function ($code, $msg) use(&$errorMessage) {
  7157. $errorMessage = preg_replace('{^fopen\\(.*?\\): }', '', $msg);
  7158. });
  7159. $this->stream = fopen($this->url, 'a');
  7160. restore_error_handler();
  7161. if (!is_resource($this->stream)) {
  7162. $this->stream = null;
  7163. throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $errorMessage, $this->url));
  7164. }
  7165. }
  7166. fwrite($this->stream, (string) $record['formatted']);
  7167. }
  7168. }
  7169. namespace Monolog\Handler;
  7170. use Monolog\Logger;
  7171. class RotatingFileHandler extends StreamHandler
  7172. {
  7173. protected $filename;
  7174. protected $maxFiles;
  7175. protected $mustRotate;
  7176. protected $nextRotation;
  7177. public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true)
  7178. {
  7179. $this->filename = $filename;
  7180. $this->maxFiles = (int) $maxFiles;
  7181. $this->nextRotation = new \DateTime('tomorrow');
  7182. parent::__construct($this->getTimedFilename(), $level, $bubble);
  7183. }
  7184. public function close()
  7185. {
  7186. parent::close();
  7187. if (true === $this->mustRotate) {
  7188. $this->rotate();
  7189. }
  7190. }
  7191. protected function write(array $record)
  7192. {
  7193. if (null === $this->mustRotate) {
  7194. $this->mustRotate = !file_exists($this->url);
  7195. }
  7196. if ($this->nextRotation < $record['datetime']) {
  7197. $this->mustRotate = true;
  7198. $this->close();
  7199. }
  7200. parent::write($record);
  7201. }
  7202. protected function rotate()
  7203. {
  7204. $this->url = $this->getTimedFilename();
  7205. $this->nextRotation = new \DateTime('tomorrow');
  7206. if (0 === $this->maxFiles) {
  7207. return;
  7208. }
  7209. $fileInfo = pathinfo($this->filename);
  7210. $glob = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '-*';
  7211. if (!empty($fileInfo['extension'])) {
  7212. $glob .= '.' . $fileInfo['extension'];
  7213. }
  7214. $iterator = new \GlobIterator($glob);
  7215. $count = $iterator->count();
  7216. if ($this->maxFiles >= $count) {
  7217. return;
  7218. }
  7219. $array = iterator_to_array($iterator);
  7220. usort($array, function ($a, $b) {
  7221. return strcmp($b->getFilename(), $a->getFilename());
  7222. });
  7223. foreach (array_slice($array, $this->maxFiles) as $file) {
  7224. if ($file->isWritable()) {
  7225. unlink($file->getRealPath());
  7226. }
  7227. }
  7228. }
  7229. protected function getTimedFilename()
  7230. {
  7231. $fileInfo = pathinfo($this->filename);
  7232. $timedFilename = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '-' . date('Y-m-d');
  7233. if (!empty($fileInfo['extension'])) {
  7234. $timedFilename .= '.' . $fileInfo['extension'];
  7235. }
  7236. return $timedFilename;
  7237. }
  7238. }
  7239. namespace Monolog\Handler;
  7240. use Monolog\Formatter\FormatterInterface;
  7241. interface HandlerInterface
  7242. {
  7243. public function isHandling(array $record);
  7244. public function handle(array $record);
  7245. public function handleBatch(array $records);
  7246. public function pushProcessor($callback);
  7247. public function popProcessor();
  7248. public function setFormatter(FormatterInterface $formatter);
  7249. public function getFormatter();
  7250. }
  7251. namespace Illuminate\Support\Facades;
  7252. class App extends Facade
  7253. {
  7254. protected static function getFacadeAccessor()
  7255. {
  7256. return 'app';
  7257. }
  7258. }
  7259. namespace Illuminate\Exception;
  7260. use Exception;
  7261. interface ExceptionDisplayerInterface
  7262. {
  7263. public function display(Exception $exception);
  7264. }
  7265. namespace Illuminate\Exception;
  7266. use Exception;
  7267. use Symfony\Component\Debug\ExceptionHandler;
  7268. class SymfonyDisplayer implements ExceptionDisplayerInterface
  7269. {
  7270. protected $symfony;
  7271. public function __construct(ExceptionHandler $symfony)
  7272. {
  7273. $this->symfony = $symfony;
  7274. }
  7275. public function display(Exception $exception)
  7276. {
  7277. $this->symfony->handle($exception);
  7278. }
  7279. }
  7280. namespace Illuminate\Exception;
  7281. use Exception;
  7282. use Whoops\Run;
  7283. class WhoopsDisplayer implements ExceptionDisplayerInterface
  7284. {
  7285. protected $whoops;
  7286. protected $runningInConsole;
  7287. public function __construct(Run $whoops, $runningInConsole)
  7288. {
  7289. $this->whoops = $whoops;
  7290. $this->runningInConsole = $runningInConsole;
  7291. }
  7292. public function display(Exception $exception)
  7293. {
  7294. if (!$this->runningInConsole and !headers_sent()) {
  7295. header('HTTP/1.1 500 Internal Server Error');
  7296. }
  7297. $this->whoops->handleException($exception);
  7298. }
  7299. }
  7300. namespace Illuminate\Exception;
  7301. use Closure;
  7302. use ErrorException;
  7303. use ReflectionFunction;
  7304. use Illuminate\Support\Contracts\ResponsePreparerInterface;
  7305. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  7306. use Symfony\Component\Debug\Exception\FatalErrorException as FatalError;
  7307. class Handler
  7308. {
  7309. protected $responsePreparer;
  7310. protected $plainDisplayer;
  7311. protected $debugDisplayer;
  7312. protected $debug;
  7313. protected $handlers = array();
  7314. protected $handled = array();
  7315. public function __construct(ResponsePreparerInterface $responsePreparer, ExceptionDisplayerInterface $plainDisplayer, ExceptionDisplayerInterface $debugDisplayer, $debug = true)
  7316. {
  7317. $this->debug = $debug;
  7318. $this->plainDisplayer = $plainDisplayer;
  7319. $this->debugDisplayer = $debugDisplayer;
  7320. $this->responsePreparer = $responsePreparer;
  7321. }
  7322. public function register($environment)
  7323. {
  7324. $this->registerErrorHandler();
  7325. $this->registerExceptionHandler();
  7326. if ($environment != 'testing') {
  7327. $this->registerShutdownHandler();
  7328. }
  7329. }
  7330. protected function registerErrorHandler()
  7331. {
  7332. set_error_handler(array($this, 'handleError'));
  7333. }
  7334. protected function registerExceptionHandler()
  7335. {
  7336. set_exception_handler(array($this, 'handleException'));
  7337. }
  7338. protected function registerShutdownHandler()
  7339. {
  7340. register_shutdown_function(array($this, 'handleShutdown'));
  7341. }
  7342. public function handleError($level, $message, $file, $line, $context)
  7343. {
  7344. if (error_reporting() & $level) {
  7345. $e = new ErrorException($message, $level, 0, $file, $line);
  7346. $this->handleException($e);
  7347. }
  7348. }
  7349. public function handleException($exception)
  7350. {
  7351. $response = $this->callCustomHandlers($exception);
  7352. if (!is_null($response)) {
  7353. $response = $this->prepareResponse($response);
  7354. $response->send();
  7355. } else {
  7356. $this->displayException($exception);
  7357. }
  7358. $this->bail();
  7359. }
  7360. public function handleShutdown()
  7361. {
  7362. $error = error_get_last();
  7363. if (!is_null($error)) {
  7364. extract($error);
  7365. if (!$this->isFatal($type)) {
  7366. return;
  7367. }
  7368. $this->handleException(new FatalError($message, $type, 0, $file, $line));
  7369. }
  7370. }
  7371. protected function isFatal($type)
  7372. {
  7373. return in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE));
  7374. }
  7375. public function handleConsole($exception)
  7376. {
  7377. return $this->callCustomHandlers($exception, true);
  7378. }
  7379. protected function callCustomHandlers($exception, $fromConsole = false)
  7380. {
  7381. foreach ($this->handlers as $handler) {
  7382. if (!$this->handlesException($handler, $exception)) {
  7383. continue;
  7384. } elseif ($exception instanceof HttpExceptionInterface) {
  7385. $code = $exception->getStatusCode();
  7386. } else {
  7387. $code = 500;
  7388. }
  7389. try {
  7390. $response = $handler($exception, $code, $fromConsole);
  7391. } catch (\Exception $e) {
  7392. $response = $this->formatException($e);
  7393. }
  7394. if (isset($response) and !is_null($response)) {
  7395. return $response;
  7396. }
  7397. }
  7398. }
  7399. protected function displayException($exception)
  7400. {
  7401. $displayer = $this->debug ? $this->debugDisplayer : $this->plainDisplayer;
  7402. $displayer->display($exception);
  7403. }
  7404. protected function handlesException(Closure $handler, $exception)
  7405. {
  7406. $reflection = new ReflectionFunction($handler);
  7407. return $reflection->getNumberOfParameters() == 0 or $this->hints($reflection, $exception);
  7408. }
  7409. protected function hints(ReflectionFunction $reflection, $exception)
  7410. {
  7411. $parameters = $reflection->getParameters();
  7412. $expected = $parameters[0];
  7413. return !$expected->getClass() or $expected->getClass()->isInstance($exception);
  7414. }
  7415. protected function formatException(\Exception $e)
  7416. {
  7417. $location = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
  7418. return 'Error in exception handler: ' . $location;
  7419. }
  7420. public function error(Closure $callback)
  7421. {
  7422. array_unshift($this->handlers, $callback);
  7423. }
  7424. protected function prepareResponse($response)
  7425. {
  7426. return $this->responsePreparer->prepareResponse($response);
  7427. }
  7428. protected function bail()
  7429. {
  7430. die(1);
  7431. }
  7432. public function setDebug($debug)
  7433. {
  7434. $this->debug = $debug;
  7435. }
  7436. }
  7437. namespace Illuminate\Support\Facades;
  7438. class Route extends Facade
  7439. {
  7440. public static function is($name)
  7441. {
  7442. return static::$app['router']->currentRouteNamed($name);
  7443. }
  7444. public static function uses($action)
  7445. {
  7446. return static::$app['router']->currentRouteUses($action);
  7447. }
  7448. protected static function getFacadeAccessor()
  7449. {
  7450. return 'router';
  7451. }
  7452. }
  7453. namespace Symfony\Component\Routing;
  7454. class Route implements \Serializable
  7455. {
  7456. private $path = '/';
  7457. private $host = '';
  7458. private $schemes = array();
  7459. private $methods = array();
  7460. private $defaults = array();
  7461. private $requirements = array();
  7462. private $options = array();
  7463. private $compiled;
  7464. public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array())
  7465. {
  7466. $this->setPath($path);
  7467. $this->setDefaults($defaults);
  7468. $this->setRequirements($requirements);
  7469. $this->setOptions($options);
  7470. $this->setHost($host);
  7471. if ($schemes) {
  7472. $this->setSchemes($schemes);
  7473. }
  7474. if ($methods) {
  7475. $this->setMethods($methods);
  7476. }
  7477. }
  7478. public function serialize()
  7479. {
  7480. return serialize(array('path' => $this->path, 'host' => $this->host, 'defaults' => $this->defaults, 'requirements' => $this->requirements, 'options' => $this->options, 'schemes' => $this->schemes, 'methods' => $this->methods));
  7481. }
  7482. public function unserialize($data)
  7483. {
  7484. $data = unserialize($data);
  7485. $this->path = $data['path'];
  7486. $this->host = $data['host'];
  7487. $this->defaults = $data['defaults'];
  7488. $this->requirements = $data['requirements'];
  7489. $this->options = $data['options'];
  7490. $this->schemes = $data['schemes'];
  7491. $this->methods = $data['methods'];
  7492. }
  7493. public function getPattern()
  7494. {
  7495. return $this->path;
  7496. }
  7497. public function setPattern($pattern)
  7498. {
  7499. return $this->setPath($pattern);
  7500. }
  7501. public function getPath()
  7502. {
  7503. return $this->path;
  7504. }
  7505. public function setPath($pattern)
  7506. {
  7507. $this->path = '/' . ltrim(trim($pattern), '/');
  7508. $this->compiled = null;
  7509. return $this;
  7510. }
  7511. public function getHost()
  7512. {
  7513. return $this->host;
  7514. }
  7515. public function setHost($pattern)
  7516. {
  7517. $this->host = (string) $pattern;
  7518. $this->compiled = null;
  7519. return $this;
  7520. }
  7521. public function getSchemes()
  7522. {
  7523. return $this->schemes;
  7524. }
  7525. public function setSchemes($schemes)
  7526. {
  7527. $this->schemes = array_map('strtolower', (array) $schemes);
  7528. if ($this->schemes) {
  7529. $this->requirements['_scheme'] = implode('|', $this->schemes);
  7530. } else {
  7531. unset($this->requirements['_scheme']);
  7532. }
  7533. $this->compiled = null;
  7534. return $this;
  7535. }
  7536. public function getMethods()
  7537. {
  7538. return $this->methods;
  7539. }
  7540. public function setMethods($methods)
  7541. {
  7542. $this->methods = array_map('strtoupper', (array) $methods);
  7543. if ($this->methods) {
  7544. $this->requirements['_method'] = implode('|', $this->methods);
  7545. } else {
  7546. unset($this->requirements['_method']);
  7547. }
  7548. $this->compiled = null;
  7549. return $this;
  7550. }
  7551. public function getOptions()
  7552. {
  7553. return $this->options;
  7554. }
  7555. public function setOptions(array $options)
  7556. {
  7557. $this->options = array('compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler');
  7558. return $this->addOptions($options);
  7559. }
  7560. public function addOptions(array $options)
  7561. {
  7562. foreach ($options as $name => $option) {
  7563. $this->options[$name] = $option;
  7564. }
  7565. $this->compiled = null;
  7566. return $this;
  7567. }
  7568. public function setOption($name, $value)
  7569. {
  7570. $this->options[$name] = $value;
  7571. $this->compiled = null;
  7572. return $this;
  7573. }
  7574. public function getOption($name)
  7575. {
  7576. return isset($this->options[$name]) ? $this->options[$name] : null;
  7577. }
  7578. public function hasOption($name)
  7579. {
  7580. return array_key_exists($name, $this->options);
  7581. }
  7582. public function getDefaults()
  7583. {
  7584. return $this->defaults;
  7585. }
  7586. public function setDefaults(array $defaults)
  7587. {
  7588. $this->defaults = array();
  7589. return $this->addDefaults($defaults);
  7590. }
  7591. public function addDefaults(array $defaults)
  7592. {
  7593. foreach ($defaults as $name => $default) {
  7594. $this->defaults[$name] = $default;
  7595. }
  7596. $this->compiled = null;
  7597. return $this;
  7598. }
  7599. public function getDefault($name)
  7600. {
  7601. return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
  7602. }
  7603. public function hasDefault($name)
  7604. {
  7605. return array_key_exists($name, $this->defaults);
  7606. }
  7607. public function setDefault($name, $default)
  7608. {
  7609. $this->defaults[$name] = $default;
  7610. $this->compiled = null;
  7611. return $this;
  7612. }
  7613. public function getRequirements()
  7614. {
  7615. return $this->requirements;
  7616. }
  7617. public function setRequirements(array $requirements)
  7618. {
  7619. $this->requirements = array();
  7620. return $this->addRequirements($requirements);
  7621. }
  7622. public function addRequirements(array $requirements)
  7623. {
  7624. foreach ($requirements as $key => $regex) {
  7625. $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
  7626. }
  7627. $this->compiled = null;
  7628. return $this;
  7629. }
  7630. public function getRequirement($key)
  7631. {
  7632. return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
  7633. }
  7634. public function hasRequirement($key)
  7635. {
  7636. return array_key_exists($key, $this->requirements);
  7637. }
  7638. public function setRequirement($key, $regex)
  7639. {
  7640. $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
  7641. $this->compiled = null;
  7642. return $this;
  7643. }
  7644. public function compile()
  7645. {
  7646. if (null !== $this->compiled) {
  7647. return $this->compiled;
  7648. }
  7649. $class = $this->getOption('compiler_class');
  7650. return $this->compiled = $class::compile($this);
  7651. }
  7652. private function sanitizeRequirement($key, $regex)
  7653. {
  7654. if (!is_string($regex)) {
  7655. throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key));
  7656. }
  7657. if ('' !== $regex && '^' === $regex[0]) {
  7658. $regex = (string) substr($regex, 1);
  7659. }
  7660. if ('$' === substr($regex, -1)) {
  7661. $regex = substr($regex, 0, -1);
  7662. }
  7663. if ('' === $regex) {
  7664. throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
  7665. }
  7666. if ('_scheme' === $key) {
  7667. $this->setSchemes(explode('|', $regex));
  7668. } elseif ('_method' === $key) {
  7669. $this->setMethods(explode('|', $regex));
  7670. }
  7671. return $regex;
  7672. }
  7673. }
  7674. namespace Illuminate\Routing;
  7675. use Illuminate\Http\Response;
  7676. use Symfony\Component\HttpFoundation\Request;
  7677. use Symfony\Component\Routing\Route as BaseRoute;
  7678. class Route extends BaseRoute
  7679. {
  7680. protected $router;
  7681. protected $parameters;
  7682. protected $parsedParameters;
  7683. public function run(Request $request)
  7684. {
  7685. $this->parsedParameters = null;
  7686. $response = $this->callBeforeFilters($request);
  7687. if (!isset($response)) {
  7688. $response = $this->callCallable();
  7689. } else {
  7690. $fromFilter = true;
  7691. }
  7692. $response = $this->router->prepare($response, $request);
  7693. if (!isset($fromFilter)) {
  7694. $this->callAfterFilters($request, $response);
  7695. }
  7696. return $response;
  7697. }
  7698. protected function callCallable()
  7699. {
  7700. $variables = array_values($this->getParametersWithoutDefaults());
  7701. return call_user_func_array($this->getOption('_call'), $variables);
  7702. }
  7703. protected function callBeforeFilters(Request $request)
  7704. {
  7705. $before = $this->getAllBeforeFilters($request);
  7706. $response = null;
  7707. foreach ($before as $filter) {
  7708. $response = $this->callFilter($filter, $request);
  7709. if (!is_null($response)) {
  7710. return $response;
  7711. }
  7712. }
  7713. }
  7714. protected function getAllBeforeFilters(Request $request)
  7715. {
  7716. $before = $this->getBeforeFilters();
  7717. return array_merge($before, $this->router->findPatternFilters($request));
  7718. }
  7719. protected function callAfterFilters(Request $request, $response)
  7720. {
  7721. foreach ($this->getAfterFilters() as $filter) {
  7722. $this->callFilter($filter, $request, array($response));
  7723. }
  7724. }
  7725. public function callFilter($name, Request $request, array $params = array())
  7726. {
  7727. if (!$this->router->filtersEnabled()) {
  7728. return;
  7729. }
  7730. $merge = array($this->router->getCurrentRoute(), $request);
  7731. $params = array_merge($merge, $params);
  7732. list($name, $params) = $this->parseFilter($name, $params);
  7733. if (!is_null($callable = $this->router->getFilter($name))) {
  7734. return call_user_func_array($callable, $params);
  7735. }
  7736. }
  7737. protected function parseFilter($name, $parameters = array())
  7738. {
  7739. if (str_contains($name, ':')) {
  7740. $segments = explode(':', $name);
  7741. $name = $segments[0];
  7742. $arguments = explode(',', $segments[1]);
  7743. $parameters = array_merge($parameters, $arguments);
  7744. }
  7745. return array($name, $parameters);
  7746. }
  7747. public function getParameter($name, $default = null)
  7748. {
  7749. return array_get($this->getParameters(), $name, $default);
  7750. }
  7751. public function getParameters()
  7752. {
  7753. if (isset($this->parsedParameters)) {
  7754. return $this->parsedParameters;
  7755. }
  7756. $variables = $this->compile()->getVariables();
  7757. $parameters = array();
  7758. foreach ($variables as $variable) {
  7759. $parameters[$variable] = $this->resolveParameter($variable);
  7760. }
  7761. return $this->parsedParameters = $parameters;
  7762. }
  7763. protected function resolveParameter($key)
  7764. {
  7765. $value = $this->parameters[$key];
  7766. if ($this->router->hasBinder($key)) {
  7767. return $this->router->performBinding($key, $value, $this);
  7768. }
  7769. return $value;
  7770. }
  7771. public function getParametersWithoutDefaults()
  7772. {
  7773. $parameters = $this->getParameters();
  7774. foreach ($parameters as $key => $value) {
  7775. if ($this->isMissingDefault($key, $value)) {
  7776. unset($parameters[$key]);
  7777. }
  7778. }
  7779. return $parameters;
  7780. }
  7781. protected function isMissingDefault($key, $value)
  7782. {
  7783. return $this->isOptional($key) and is_null($value);
  7784. }
  7785. public function isOptional($key)
  7786. {
  7787. return array_key_exists($key, $this->getDefaults());
  7788. }
  7789. public function getParameterKeys()
  7790. {
  7791. return $this->compile()->getVariables();
  7792. }
  7793. public function where($name, $expression = null)
  7794. {
  7795. if (is_array($name)) {
  7796. return $this->setArrayOfWheres($name);
  7797. }
  7798. $this->setRequirement($name, $expression);
  7799. return $this;
  7800. }
  7801. protected function setArrayOfWheres(array $wheres)
  7802. {
  7803. foreach ($wheres as $name => $expression) {
  7804. $this->where($name, $expression);
  7805. }
  7806. return $this;
  7807. }
  7808. public function defaults($key, $value)
  7809. {
  7810. $this->setDefault($key, $value);
  7811. return $this;
  7812. }
  7813. public function before()
  7814. {
  7815. $this->setBeforeFilters(func_get_args());
  7816. return $this;
  7817. }
  7818. public function after()
  7819. {
  7820. $this->setAfterFilters(func_get_args());
  7821. return $this;
  7822. }
  7823. public function getAction()
  7824. {
  7825. return $this->getOption('_uses');
  7826. }
  7827. public function getBeforeFilters()
  7828. {
  7829. return $this->getOption('_before') ?: array();
  7830. }
  7831. public function setBeforeFilters($value)
  7832. {
  7833. $filters = is_string($value) ? explode('|', $value) : (array) $value;
  7834. $this->setOption('_before', array_merge($this->getBeforeFilters(), $filters));
  7835. }
  7836. public function getAfterFilters()
  7837. {
  7838. return $this->getOption('_after') ?: array();
  7839. }
  7840. public function setAfterFilters($value)
  7841. {
  7842. $filters = is_string($value) ? explode('|', $value) : (array) $value;
  7843. $this->setOption('_after', array_merge($this->getAfterFilters(), $filters));
  7844. }
  7845. public function setParameters($parameters)
  7846. {
  7847. $this->parameters = $parameters;
  7848. }
  7849. public function setRouter(Router $router)
  7850. {
  7851. $this->router = $router;
  7852. return $this;
  7853. }
  7854. }
  7855. namespace Illuminate\View\Engines;
  7856. use Closure;
  7857. class EngineResolver
  7858. {
  7859. protected $resolvers = array();
  7860. protected $resolved = array();
  7861. public function register($engine, Closure $resolver)
  7862. {
  7863. $this->resolvers[$engine] = $resolver;
  7864. }
  7865. public function resolve($engine)
  7866. {
  7867. if (!isset($this->resolved[$engine])) {
  7868. $this->resolved[$engine] = call_user_func($this->resolvers[$engine]);
  7869. }
  7870. return $this->resolved[$engine];
  7871. }
  7872. }
  7873. namespace Illuminate\View;
  7874. interface ViewFinderInterface
  7875. {
  7876. public function find($view);
  7877. public function addLocation($location);
  7878. public function addNamespace($namespace, $hint);
  7879. public function addExtension($extension);
  7880. }
  7881. namespace Illuminate\View;
  7882. use Illuminate\Filesystem\Filesystem;
  7883. class FileViewFinder implements ViewFinderInterface
  7884. {
  7885. protected $files;
  7886. protected $paths;
  7887. protected $hints = array();
  7888. protected $extensions = array('blade.php', 'php');
  7889. public function __construct(Filesystem $files, array $paths, array $extensions = null)
  7890. {
  7891. $this->files = $files;
  7892. $this->paths = $paths;
  7893. if (isset($extensions)) {
  7894. $this->extensions = $extensions;
  7895. }
  7896. }
  7897. public function find($name)
  7898. {
  7899. if (strpos($name, '::') !== false) {
  7900. return $this->findNamedPathView($name);
  7901. }
  7902. return $this->findInPaths($name, $this->paths);
  7903. }
  7904. protected function findNamedPathView($name)
  7905. {
  7906. list($namespace, $view) = $this->getNamespaceSegments($name);
  7907. return $this->findInPaths($view, $this->hints[$namespace]);
  7908. }
  7909. protected function getNamespaceSegments($name)
  7910. {
  7911. $segments = explode('::', $name);
  7912. if (count($segments) != 2) {
  7913. throw new \InvalidArgumentException("View [{$name}] has an invalid name.");
  7914. }
  7915. if (!isset($this->hints[$segments[0]])) {
  7916. throw new \InvalidArgumentException("No hint path defined for [{$segments[0]}].");
  7917. }
  7918. return $segments;
  7919. }
  7920. protected function findInPaths($name, $paths)
  7921. {
  7922. foreach ((array) $paths as $path) {
  7923. foreach ($this->getPossibleViewFiles($name) as $file) {
  7924. if ($this->files->exists($viewPath = $path . '/' . $file)) {
  7925. return $viewPath;
  7926. }
  7927. }
  7928. }
  7929. throw new \InvalidArgumentException("View [{$name}] not found.");
  7930. }
  7931. protected function getPossibleViewFiles($name)
  7932. {
  7933. return array_map(function ($extension) use($name) {
  7934. return str_replace('.', '/', $name) . '.' . $extension;
  7935. }, $this->extensions);
  7936. }
  7937. public function addLocation($location)
  7938. {
  7939. $this->paths[] = $location;
  7940. }
  7941. public function addNamespace($namespace, $hints)
  7942. {
  7943. $hints = (array) $hints;
  7944. if (isset($this->hints[$namespace])) {
  7945. $hints = array_merge($this->hints[$namespace], $hints);
  7946. }
  7947. $this->hints[$namespace] = $hints;
  7948. }
  7949. public function addExtension($extension)
  7950. {
  7951. if (($index = array_search($extension, $this->extensions)) !== false) {
  7952. unset($this->extensions[$index]);
  7953. }
  7954. array_unshift($this->extensions, $extension);
  7955. }
  7956. public function getFilesystem()
  7957. {
  7958. return $this->files;
  7959. }
  7960. public function getPaths()
  7961. {
  7962. return $this->paths;
  7963. }
  7964. public function getHints()
  7965. {
  7966. return $this->hints;
  7967. }
  7968. public function getExtensions()
  7969. {
  7970. return $this->extensions;
  7971. }
  7972. }
  7973. namespace Illuminate\View;
  7974. use Closure;
  7975. use Illuminate\Events\Dispatcher;
  7976. use Illuminate\Container\Container;
  7977. use Illuminate\View\Engines\EngineResolver;
  7978. use Illuminate\Support\Contracts\ArrayableInterface as Arrayable;
  7979. class Environment
  7980. {
  7981. protected $engines;
  7982. protected $finder;
  7983. protected $events;
  7984. protected $container;
  7985. protected $shared = array();
  7986. protected $names = array();
  7987. protected $extensions = array('blade.php' => 'blade', 'php' => 'php');
  7988. protected $composers = array();
  7989. protected $sections = array();
  7990. protected $sectionStack = array();
  7991. protected $renderCount = 0;
  7992. public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events)
  7993. {
  7994. $this->finder = $finder;
  7995. $this->events = $events;
  7996. $this->engines = $engines;
  7997. $this->share('__env', $this);
  7998. }
  7999. public function make($view, $data = array(), $mergeData = array())
  8000. {
  8001. $path = $this->finder->find($view);
  8002. $data = array_merge($mergeData, $this->parseData($data));
  8003. return new View($this, $this->getEngineFromPath($path), $view, $path, $data);
  8004. }
  8005. protected function parseData($data)
  8006. {
  8007. return $data instanceof Arrayable ? $data->toArray() : $data;
  8008. }
  8009. public function of($view, $data = array())
  8010. {
  8011. return $this->make($this->names[$view], $data);
  8012. }
  8013. public function name($view, $name)
  8014. {
  8015. $this->names[$name] = $view;
  8016. }
  8017. public function exists($view)
  8018. {
  8019. try {
  8020. $this->finder->find($view);
  8021. } catch (\InvalidArgumentException $e) {
  8022. return false;
  8023. }
  8024. return true;
  8025. }
  8026. public function renderEach($view, $data, $iterator, $empty = 'raw|')
  8027. {
  8028. $result = '';
  8029. if (count($data) > 0) {
  8030. foreach ($data as $key => $value) {
  8031. $data = array('key' => $key, $iterator => $value);
  8032. $result .= $this->make($view, $data)->render();
  8033. }
  8034. } else {
  8035. if (starts_with($empty, 'raw|')) {
  8036. $result = substr($empty, 4);
  8037. } else {
  8038. $result = $this->make($empty)->render();
  8039. }
  8040. }
  8041. return $result;
  8042. }
  8043. protected function getEngineFromPath($path)
  8044. {
  8045. $engine = $this->extensions[$this->getExtension($path)];
  8046. return $this->engines->resolve($engine);
  8047. }
  8048. protected function getExtension($path)
  8049. {
  8050. $extensions = array_keys($this->extensions);
  8051. return array_first($extensions, function ($key, $value) use($path) {
  8052. return ends_with($path, $value);
  8053. });
  8054. }
  8055. public function share($key, $value = null)
  8056. {
  8057. if (!is_array($key)) {
  8058. return $this->shared[$key] = $value;
  8059. }
  8060. foreach ($key as $innerKey => $innerValue) {
  8061. $this->share($innerKey, $innerValue);
  8062. }
  8063. }
  8064. public function composer($views, $callback)
  8065. {
  8066. $composers = array();
  8067. foreach ((array) $views as $view) {
  8068. $composers[] = $this->addComposer($view, $callback);
  8069. }
  8070. return $composers;
  8071. }
  8072. protected function addComposer($view, $callback)
  8073. {
  8074. if ($callback instanceof Closure) {
  8075. $this->events->listen('composing: ' . $view, $callback);
  8076. return $callback;
  8077. } elseif (is_string($callback)) {
  8078. return $this->addClassComposer($view, $callback);
  8079. }
  8080. }
  8081. protected function addClassComposer($view, $class)
  8082. {
  8083. $name = 'composing: ' . $view;
  8084. $callback = $this->buildClassComposerCallback($class);
  8085. $this->events->listen($name, $callback);
  8086. return $callback;
  8087. }
  8088. protected function buildClassComposerCallback($class)
  8089. {
  8090. $container = $this->container;
  8091. list($class, $method) = $this->parseClassComposer($class);
  8092. return function () use($class, $method, $container) {
  8093. $callable = array($container->make($class), $method);
  8094. return call_user_func_array($callable, func_get_args());
  8095. };
  8096. }
  8097. protected function parseClassComposer($class)
  8098. {
  8099. return str_contains($class, '@') ? explode('@', $class) : array($class, 'compose');
  8100. }
  8101. public function callComposer(View $view)
  8102. {
  8103. $this->events->fire('composing: ' . $view->getName(), array($view));
  8104. }
  8105. public function startSection($section, $content = '')
  8106. {
  8107. if ($content === '') {
  8108. ob_start() and $this->sectionStack[] = $section;
  8109. } else {
  8110. $this->extendSection($section, $content);
  8111. }
  8112. }
  8113. public function inject($section, $content)
  8114. {
  8115. return $this->startSection($section, $content);
  8116. }
  8117. public function yieldSection()
  8118. {
  8119. return $this->yieldContent($this->stopSection());
  8120. }
  8121. public function stopSection($overwrite = false)
  8122. {
  8123. $last = array_pop($this->sectionStack);
  8124. if ($overwrite) {
  8125. $this->sections[$last] = ob_get_clean();
  8126. } else {
  8127. $this->extendSection($last, ob_get_clean());
  8128. }
  8129. return $last;
  8130. }
  8131. protected function extendSection($section, $content)
  8132. {
  8133. if (isset($this->sections[$section])) {
  8134. $content = str_replace('@parent', $content, $this->sections[$section]);
  8135. $this->sections[$section] = $content;
  8136. } else {
  8137. $this->sections[$section] = $content;
  8138. }
  8139. }
  8140. public function yieldContent($section)
  8141. {
  8142. return isset($this->sections[$section]) ? $this->sections[$section] : '';
  8143. }
  8144. public function flushSections()
  8145. {
  8146. $this->sections = array();
  8147. $this->sectionStack = array();
  8148. }
  8149. public function incrementRender()
  8150. {
  8151. $this->renderCount++;
  8152. }
  8153. public function decrementRender()
  8154. {
  8155. $this->renderCount--;
  8156. }
  8157. public function doneRendering()
  8158. {
  8159. return $this->renderCount == 0;
  8160. }
  8161. public function addLocation($location)
  8162. {
  8163. $this->finder->addLocation($location);
  8164. }
  8165. public function addNamespace($namespace, $hints)
  8166. {
  8167. $this->finder->addNamespace($namespace, $hints);
  8168. }
  8169. public function addExtension($extension, $engine, $resolver = null)
  8170. {
  8171. $this->finder->addExtension($extension);
  8172. if (isset($resolver)) {
  8173. $this->engines->register($engine, $resolver);
  8174. }
  8175. unset($this->extensions[$engine]);
  8176. $this->extensions = array_merge(array($extension => $engine), $this->extensions);
  8177. }
  8178. public function getExtensions()
  8179. {
  8180. return $this->extensions;
  8181. }
  8182. public function getEngineResolver()
  8183. {
  8184. return $this->engines;
  8185. }
  8186. public function getFinder()
  8187. {
  8188. return $this->finder;
  8189. }
  8190. public function getDispatcher()
  8191. {
  8192. return $this->events;
  8193. }
  8194. public function getContainer()
  8195. {
  8196. return $this->container;
  8197. }
  8198. public function setContainer(Container $container)
  8199. {
  8200. $this->container = $container;
  8201. }
  8202. public function getShared()
  8203. {
  8204. return $this->shared;
  8205. }
  8206. public function getSections()
  8207. {
  8208. return $this->sections;
  8209. }
  8210. public function getNames()
  8211. {
  8212. return $this->names;
  8213. }
  8214. }
  8215. namespace Illuminate\Support\Contracts;
  8216. interface MessageProviderInterface
  8217. {
  8218. public function getMessageBag();
  8219. }
  8220. namespace Illuminate\Support;
  8221. use Countable;
  8222. use Illuminate\Support\Contracts\ArrayableInterface;
  8223. use Illuminate\Support\Contracts\JsonableInterface;
  8224. use Illuminate\Support\Contracts\MessageProviderInterface;
  8225. class MessageBag implements ArrayableInterface, Countable, JsonableInterface, MessageProviderInterface
  8226. {
  8227. protected $messages = array();
  8228. protected $format = ':message';
  8229. public function __construct(array $messages = array())
  8230. {
  8231. foreach ($messages as $key => $value) {
  8232. $this->messages[$key] = (array) $value;
  8233. }
  8234. }
  8235. public function add($key, $message)
  8236. {
  8237. if ($this->isUnique($key, $message)) {
  8238. $this->messages[$key][] = $message;
  8239. }
  8240. return $this;
  8241. }
  8242. public function merge(array $messages)
  8243. {
  8244. $this->messages = array_merge_recursive($this->messages, $messages);
  8245. return $this;
  8246. }
  8247. protected function isUnique($key, $message)
  8248. {
  8249. $messages = (array) $this->messages;
  8250. return !isset($messages[$key]) or !in_array($message, $messages[$key]);
  8251. }
  8252. public function has($key = null)
  8253. {
  8254. return $this->first($key) !== '';
  8255. }
  8256. public function first($key = null, $format = null)
  8257. {
  8258. $messages = $this->get($key, $format);
  8259. return count($messages) > 0 ? $messages[0] : '';
  8260. }
  8261. public function get($key, $format = null)
  8262. {
  8263. $format = $this->checkFormat($format);
  8264. if (array_key_exists($key, $this->messages)) {
  8265. return $this->transform($this->messages[$key], $format, $key);
  8266. }
  8267. return array();
  8268. }
  8269. public function all($format = null)
  8270. {
  8271. $format = $this->checkFormat($format);
  8272. $all = array();
  8273. foreach ($this->messages as $key => $messages) {
  8274. $all = array_merge($all, $this->transform($messages, $format, $key));
  8275. }
  8276. return $all;
  8277. }
  8278. protected function transform($messages, $format, $messageKey)
  8279. {
  8280. $messages = (array) $messages;
  8281. foreach ($messages as $key => &$message) {
  8282. $replace = array(':message', ':key');
  8283. $message = str_replace($replace, array($message, $messageKey), $format);
  8284. }
  8285. return $messages;
  8286. }
  8287. protected function checkFormat($format)
  8288. {
  8289. return $format === null ? $this->format : $format;
  8290. }
  8291. public function getMessages()
  8292. {
  8293. return $this->messages;
  8294. }
  8295. public function getMessageBag()
  8296. {
  8297. return $this;
  8298. }
  8299. public function getFormat()
  8300. {
  8301. return $this->format;
  8302. }
  8303. public function setFormat($format = ':message')
  8304. {
  8305. $this->format = $format;
  8306. }
  8307. public function any()
  8308. {
  8309. return $this->count() > 0;
  8310. }
  8311. public function count()
  8312. {
  8313. return count($this->messages);
  8314. }
  8315. public function toArray()
  8316. {
  8317. return $this->getMessages();
  8318. }
  8319. public function toJson($options = 0)
  8320. {
  8321. return json_encode($this->toArray(), $options);
  8322. }
  8323. public function __toString()
  8324. {
  8325. return $this->toJson();
  8326. }
  8327. }
  8328. namespace Symfony\Component\Routing;
  8329. use Symfony\Component\HttpFoundation\Request;
  8330. class RequestContext
  8331. {
  8332. private $baseUrl;
  8333. private $pathInfo;
  8334. private $method;
  8335. private $host;
  8336. private $scheme;
  8337. private $httpPort;
  8338. private $httpsPort;
  8339. private $queryString;
  8340. private $parameters = array();
  8341. public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443, $path = '/', $queryString = '')
  8342. {
  8343. $this->baseUrl = $baseUrl;
  8344. $this->method = strtoupper($method);
  8345. $this->host = $host;
  8346. $this->scheme = strtolower($scheme);
  8347. $this->httpPort = $httpPort;
  8348. $this->httpsPort = $httpsPort;
  8349. $this->pathInfo = $path;
  8350. $this->queryString = $queryString;
  8351. }
  8352. public function fromRequest(Request $request)
  8353. {
  8354. $this->setBaseUrl($request->getBaseUrl());
  8355. $this->setPathInfo($request->getPathInfo());
  8356. $this->setMethod($request->getMethod());
  8357. $this->setHost($request->getHost());
  8358. $this->setScheme($request->getScheme());
  8359. $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
  8360. $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
  8361. $this->setQueryString($request->server->get('QUERY_STRING'));
  8362. }
  8363. public function getBaseUrl()
  8364. {
  8365. return $this->baseUrl;
  8366. }
  8367. public function setBaseUrl($baseUrl)
  8368. {
  8369. $this->baseUrl = $baseUrl;
  8370. }
  8371. public function getPathInfo()
  8372. {
  8373. return $this->pathInfo;
  8374. }
  8375. public function setPathInfo($pathInfo)
  8376. {
  8377. $this->pathInfo = $pathInfo;
  8378. }
  8379. public function getMethod()
  8380. {
  8381. return $this->method;
  8382. }
  8383. public function setMethod($method)
  8384. {
  8385. $this->method = strtoupper($method);
  8386. }
  8387. public function getHost()
  8388. {
  8389. return $this->host;
  8390. }
  8391. public function setHost($host)
  8392. {
  8393. $this->host = $host;
  8394. }
  8395. public function getScheme()
  8396. {
  8397. return $this->scheme;
  8398. }
  8399. public function setScheme($scheme)
  8400. {
  8401. $this->scheme = strtolower($scheme);
  8402. }
  8403. public function getHttpPort()
  8404. {
  8405. return $this->httpPort;
  8406. }
  8407. public function setHttpPort($httpPort)
  8408. {
  8409. $this->httpPort = $httpPort;
  8410. }
  8411. public function getHttpsPort()
  8412. {
  8413. return $this->httpsPort;
  8414. }
  8415. public function setHttpsPort($httpsPort)
  8416. {
  8417. $this->httpsPort = $httpsPort;
  8418. }
  8419. public function getQueryString()
  8420. {
  8421. return $this->queryString;
  8422. }
  8423. public function setQueryString($queryString)
  8424. {
  8425. $this->queryString = $queryString;
  8426. }
  8427. public function getParameters()
  8428. {
  8429. return $this->parameters;
  8430. }
  8431. public function setParameters(array $parameters)
  8432. {
  8433. $this->parameters = $parameters;
  8434. return $this;
  8435. }
  8436. public function getParameter($name)
  8437. {
  8438. return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
  8439. }
  8440. public function hasParameter($name)
  8441. {
  8442. return array_key_exists($name, $this->parameters);
  8443. }
  8444. public function setParameter($name, $parameter)
  8445. {
  8446. $this->parameters[$name] = $parameter;
  8447. }
  8448. }
  8449. namespace Symfony\Component\Routing\Matcher;
  8450. use Symfony\Component\Routing\RequestContextAwareInterface;
  8451. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  8452. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  8453. interface UrlMatcherInterface extends RequestContextAwareInterface
  8454. {
  8455. public function match($pathinfo);
  8456. }
  8457. namespace Symfony\Component\Routing\Matcher;
  8458. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  8459. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  8460. use Symfony\Component\Routing\RouteCollection;
  8461. use Symfony\Component\Routing\RequestContext;
  8462. use Symfony\Component\Routing\Route;
  8463. class UrlMatcher implements UrlMatcherInterface
  8464. {
  8465. const REQUIREMENT_MATCH = 0;
  8466. const REQUIREMENT_MISMATCH = 1;
  8467. const ROUTE_MATCH = 2;
  8468. protected $context;
  8469. protected $allow = array();
  8470. protected $routes;
  8471. public function __construct(RouteCollection $routes, RequestContext $context)
  8472. {
  8473. $this->routes = $routes;
  8474. $this->context = $context;
  8475. }
  8476. public function setContext(RequestContext $context)
  8477. {
  8478. $this->context = $context;
  8479. }
  8480. public function getContext()
  8481. {
  8482. return $this->context;
  8483. }
  8484. public function match($pathinfo)
  8485. {
  8486. $this->allow = array();
  8487. if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
  8488. return $ret;
  8489. }
  8490. throw 0 < count($this->allow) ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) : new ResourceNotFoundException();
  8491. }
  8492. protected function matchCollection($pathinfo, RouteCollection $routes)
  8493. {
  8494. foreach ($routes as $name => $route) {
  8495. $compiledRoute = $route->compile();
  8496. if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
  8497. continue;
  8498. }
  8499. if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
  8500. continue;
  8501. }
  8502. $hostMatches = array();
  8503. if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
  8504. continue;
  8505. }
  8506. if ($req = $route->getRequirement('_method')) {
  8507. if ('HEAD' === ($method = $this->context->getMethod())) {
  8508. $method = 'GET';
  8509. }
  8510. if (!in_array($method, $req = explode('|', strtoupper($req)))) {
  8511. $this->allow = array_merge($this->allow, $req);
  8512. continue;
  8513. }
  8514. }
  8515. $status = $this->handleRouteRequirements($pathinfo, $name, $route);
  8516. if (self::ROUTE_MATCH === $status[0]) {
  8517. return $status[1];
  8518. }
  8519. if (self::REQUIREMENT_MISMATCH === $status[0]) {
  8520. continue;
  8521. }
  8522. return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
  8523. }
  8524. }
  8525. protected function getAttributes(Route $route, $name, array $attributes)
  8526. {
  8527. $attributes['_route'] = $name;
  8528. return $this->mergeDefaults($attributes, $route->getDefaults());
  8529. }
  8530. protected function handleRouteRequirements($pathinfo, $name, Route $route)
  8531. {
  8532. $scheme = $route->getRequirement('_scheme');
  8533. $status = $scheme && $scheme !== $this->context->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
  8534. return array($status, null);
  8535. }
  8536. protected function mergeDefaults($params, $defaults)
  8537. {
  8538. foreach ($params as $key => $value) {
  8539. if (!is_int($key)) {
  8540. $defaults[$key] = $value;
  8541. }
  8542. }
  8543. return $defaults;
  8544. }
  8545. }
  8546. namespace Symfony\Component\Routing;
  8547. interface RequestContextAwareInterface
  8548. {
  8549. public function setContext(RequestContext $context);
  8550. public function getContext();
  8551. }
  8552. namespace Symfony\Component\Routing;
  8553. interface RouteCompilerInterface
  8554. {
  8555. public static function compile(Route $route);
  8556. }
  8557. namespace Symfony\Component\Routing;
  8558. class RouteCompiler implements RouteCompilerInterface
  8559. {
  8560. const REGEX_DELIMITER = '#';
  8561. const SEPARATORS = '/,;.:-_~+*=@|';
  8562. public static function compile(Route $route)
  8563. {
  8564. $staticPrefix = null;
  8565. $hostVariables = array();
  8566. $pathVariables = array();
  8567. $variables = array();
  8568. $tokens = array();
  8569. $regex = null;
  8570. $hostRegex = null;
  8571. $hostTokens = array();
  8572. if ('' !== ($host = $route->getHost())) {
  8573. $result = self::compilePattern($route, $host, true);
  8574. $hostVariables = $result['variables'];
  8575. $variables = array_merge($variables, $hostVariables);
  8576. $hostTokens = $result['tokens'];
  8577. $hostRegex = $result['regex'];
  8578. }
  8579. $path = $route->getPath();
  8580. $result = self::compilePattern($route, $path, false);
  8581. $staticPrefix = $result['staticPrefix'];
  8582. $pathVariables = $result['variables'];
  8583. $variables = array_merge($variables, $pathVariables);
  8584. $tokens = $result['tokens'];
  8585. $regex = $result['regex'];
  8586. return new CompiledRoute($staticPrefix, $regex, $tokens, $pathVariables, $hostRegex, $hostTokens, $hostVariables, array_unique($variables));
  8587. }
  8588. private static function compilePattern(Route $route, $pattern, $isHost)
  8589. {
  8590. $tokens = array();
  8591. $variables = array();
  8592. $matches = array();
  8593. $pos = 0;
  8594. $defaultSeparator = $isHost ? '.' : '/';
  8595. preg_match_all('#\\{\\w+\\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
  8596. foreach ($matches as $match) {
  8597. $varName = substr($match[0][0], 1, -1);
  8598. $precedingText = substr($pattern, $pos, $match[0][1] - $pos);
  8599. $pos = $match[0][1] + strlen($match[0][0]);
  8600. $precedingChar = strlen($precedingText) > 0 ? substr($precedingText, -1) : '';
  8601. $isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar);
  8602. if (is_numeric($varName)) {
  8603. throw new \DomainException(sprintf('Variable name "%s" cannot be numeric in route pattern "%s". Please use a different name.', $varName, $pattern));
  8604. }
  8605. if (in_array($varName, $variables)) {
  8606. throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName));
  8607. }
  8608. if ($isSeparator && strlen($precedingText) > 1) {
  8609. $tokens[] = array('text', substr($precedingText, 0, -1));
  8610. } elseif (!$isSeparator && strlen($precedingText) > 0) {
  8611. $tokens[] = array('text', $precedingText);
  8612. }
  8613. $regexp = $route->getRequirement($varName);
  8614. if (null === $regexp) {
  8615. $followingPattern = (string) substr($pattern, $pos);
  8616. $nextSeparator = self::findNextSeparator($followingPattern);
  8617. $regexp = sprintf('[^%s%s]+', preg_quote($defaultSeparator, self::REGEX_DELIMITER), $defaultSeparator !== $nextSeparator && '' !== $nextSeparator ? preg_quote($nextSeparator, self::REGEX_DELIMITER) : '');
  8618. if ('' !== $nextSeparator && !preg_match('#^\\{\\w+\\}#', $followingPattern) || '' === $followingPattern) {
  8619. $regexp .= '+';
  8620. }
  8621. }
  8622. $tokens[] = array('variable', $isSeparator ? $precedingChar : '', $regexp, $varName);
  8623. $variables[] = $varName;
  8624. }
  8625. if ($pos < strlen($pattern)) {
  8626. $tokens[] = array('text', substr($pattern, $pos));
  8627. }
  8628. $firstOptional = PHP_INT_MAX;
  8629. if (!$isHost) {
  8630. for ($i = count($tokens) - 1; $i >= 0; $i--) {
  8631. $token = $tokens[$i];
  8632. if ('variable' === $token[0] && $route->hasDefault($token[3])) {
  8633. $firstOptional = $i;
  8634. } else {
  8635. break;
  8636. }
  8637. }
  8638. }
  8639. $regexp = '';
  8640. for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) {
  8641. $regexp .= self::computeRegexp($tokens, $i, $firstOptional);
  8642. }
  8643. return array('staticPrefix' => 'text' === $tokens[0][0] ? $tokens[0][1] : '', 'regex' => self::REGEX_DELIMITER . '^' . $regexp . '$' . self::REGEX_DELIMITER . 's', 'tokens' => array_reverse($tokens), 'variables' => $variables);
  8644. }
  8645. private static function findNextSeparator($pattern)
  8646. {
  8647. if ('' == $pattern) {
  8648. return '';
  8649. }
  8650. $pattern = preg_replace('#\\{\\w+\\}#', '', $pattern);
  8651. return isset($pattern[0]) && false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';
  8652. }
  8653. private static function computeRegexp(array $tokens, $index, $firstOptional)
  8654. {
  8655. $token = $tokens[$index];
  8656. if ('text' === $token[0]) {
  8657. return preg_quote($token[1], self::REGEX_DELIMITER);
  8658. } else {
  8659. if (0 === $index && 0 === $firstOptional) {
  8660. return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
  8661. } else {
  8662. $regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
  8663. if ($index >= $firstOptional) {
  8664. $regexp = "(?:{$regexp}";
  8665. $nbTokens = count($tokens);
  8666. if ($nbTokens - 1 == $index) {
  8667. $regexp .= str_repeat(')?', $nbTokens - $firstOptional - (0 === $firstOptional ? 1 : 0));
  8668. }
  8669. }
  8670. return $regexp;
  8671. }
  8672. }
  8673. }
  8674. }
  8675. namespace Symfony\Component\Routing;
  8676. class CompiledRoute
  8677. {
  8678. private $variables;
  8679. private $tokens;
  8680. private $staticPrefix;
  8681. private $regex;
  8682. private $pathVariables;
  8683. private $hostVariables;
  8684. private $hostRegex;
  8685. private $hostTokens;
  8686. public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array())
  8687. {
  8688. $this->staticPrefix = (string) $staticPrefix;
  8689. $this->regex = $regex;
  8690. $this->tokens = $tokens;
  8691. $this->pathVariables = $pathVariables;
  8692. $this->hostRegex = $hostRegex;
  8693. $this->hostTokens = $hostTokens;
  8694. $this->hostVariables = $hostVariables;
  8695. $this->variables = $variables;
  8696. }
  8697. public function getStaticPrefix()
  8698. {
  8699. return $this->staticPrefix;
  8700. }
  8701. public function getRegex()
  8702. {
  8703. return $this->regex;
  8704. }
  8705. public function getHostRegex()
  8706. {
  8707. return $this->hostRegex;
  8708. }
  8709. public function getTokens()
  8710. {
  8711. return $this->tokens;
  8712. }
  8713. public function getHostTokens()
  8714. {
  8715. return $this->hostTokens;
  8716. }
  8717. public function getVariables()
  8718. {
  8719. return $this->variables;
  8720. }
  8721. public function getPathVariables()
  8722. {
  8723. return $this->pathVariables;
  8724. }
  8725. public function getHostVariables()
  8726. {
  8727. return $this->hostVariables;
  8728. }
  8729. }
  8730. namespace Illuminate\Support\Facades;
  8731. class View extends Facade
  8732. {
  8733. protected static function getFacadeAccessor()
  8734. {
  8735. return 'view';
  8736. }
  8737. }
  8738. namespace Illuminate\Support\Contracts;
  8739. interface RenderableInterface
  8740. {
  8741. public function render();
  8742. }
  8743. namespace Illuminate\View;
  8744. use ArrayAccess;
  8745. use Illuminate\View\Engines\EngineInterface;
  8746. use Illuminate\Support\Contracts\ArrayableInterface as Arrayable;
  8747. use Illuminate\Support\Contracts\RenderableInterface as Renderable;
  8748. class View implements ArrayAccess, Renderable
  8749. {
  8750. protected $environment;
  8751. protected $engine;
  8752. protected $view;
  8753. protected $data;
  8754. protected $path;
  8755. public function __construct(Environment $environment, EngineInterface $engine, $view, $path, $data = array())
  8756. {
  8757. $this->view = $view;
  8758. $this->path = $path;
  8759. $this->engine = $engine;
  8760. $this->environment = $environment;
  8761. $this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;
  8762. }
  8763. public function render()
  8764. {
  8765. $env = $this->environment;
  8766. $env->incrementRender();
  8767. $env->callComposer($this);
  8768. $contents = trim($this->getContents());
  8769. $env->decrementRender();
  8770. if ($env->doneRendering()) {
  8771. $env->flushSections();
  8772. }
  8773. return $contents;
  8774. }
  8775. protected function getContents()
  8776. {
  8777. return $this->engine->get($this->path, $this->gatherData());
  8778. }
  8779. protected function gatherData()
  8780. {
  8781. $data = array_merge($this->environment->getShared(), $this->data);
  8782. foreach ($data as $key => $value) {
  8783. if ($value instanceof Renderable) {
  8784. $data[$key] = $value->render();
  8785. }
  8786. }
  8787. return $data;
  8788. }
  8789. public function with($key, $value = null)
  8790. {
  8791. if (is_array($key)) {
  8792. $this->data = array_merge($this->data, $key);
  8793. } else {
  8794. $this->data[$key] = $value;
  8795. }
  8796. return $this;
  8797. }
  8798. public function nest($key, $view, array $data = array())
  8799. {
  8800. return $this->with($key, $this->environment->make($view, $data));
  8801. }
  8802. public function getEnvironment()
  8803. {
  8804. return $this->environment;
  8805. }
  8806. public function getEngine()
  8807. {
  8808. return $this->engine;
  8809. }
  8810. public function getName()
  8811. {
  8812. return $this->view;
  8813. }
  8814. public function getData()
  8815. {
  8816. return $this->data;
  8817. }
  8818. public function getPath()
  8819. {
  8820. return $this->path;
  8821. }
  8822. public function setPath($path)
  8823. {
  8824. $this->path = $path;
  8825. }
  8826. public function offsetExists($key)
  8827. {
  8828. return array_key_exists($key, $this->data);
  8829. }
  8830. public function offsetGet($key)
  8831. {
  8832. return $this->data[$key];
  8833. }
  8834. public function offsetSet($key, $value)
  8835. {
  8836. $this->with($key, $value);
  8837. }
  8838. public function offsetUnset($key)
  8839. {
  8840. unset($this->data[$key]);
  8841. }
  8842. public function __get($key)
  8843. {
  8844. return $this->data[$key];
  8845. }
  8846. public function __set($key, $value)
  8847. {
  8848. $this->with($key, $value);
  8849. }
  8850. public function __isset($key)
  8851. {
  8852. return isset($this->data[$key]);
  8853. }
  8854. public function __unset($key)
  8855. {
  8856. unset($this->data[$key]);
  8857. }
  8858. public function __toString()
  8859. {
  8860. return $this->render();
  8861. }
  8862. }
  8863. namespace Illuminate\View\Engines;
  8864. interface EngineInterface
  8865. {
  8866. public function get($path, array $data = array());
  8867. }
  8868. namespace Illuminate\View\Engines;
  8869. use Illuminate\View\Exception;
  8870. use Illuminate\View\Environment;
  8871. class PhpEngine implements EngineInterface
  8872. {
  8873. public function get($path, array $data = array())
  8874. {
  8875. return $this->evaluatePath($path, $data);
  8876. }
  8877. protected function evaluatePath($__path, $__data)
  8878. {
  8879. ob_start();
  8880. extract($__data);
  8881. try {
  8882. include $__path;
  8883. } catch (\Exception $e) {
  8884. $this->handleViewException($e);
  8885. }
  8886. return ob_get_clean();
  8887. }
  8888. protected function handleViewException($e)
  8889. {
  8890. ob_get_clean();
  8891. throw $e;
  8892. }
  8893. }
  8894. namespace Symfony\Component\HttpFoundation;
  8895. class Response
  8896. {
  8897. public $headers;
  8898. protected $content;
  8899. protected $version;
  8900. protected $statusCode;
  8901. protected $statusText;
  8902. protected $charset;
  8903. 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');
  8904. public function __construct($content = '', $status = 200, $headers = array())
  8905. {
  8906. $this->headers = new ResponseHeaderBag($headers);
  8907. $this->setContent($content);
  8908. $this->setStatusCode($status);
  8909. $this->setProtocolVersion('1.0');
  8910. if (!$this->headers->has('Date')) {
  8911. $this->setDate(new \DateTime(null, new \DateTimeZone('UTC')));
  8912. }
  8913. }
  8914. public static function create($content = '', $status = 200, $headers = array())
  8915. {
  8916. return new static($content, $status, $headers);
  8917. }
  8918. public function __toString()
  8919. {
  8920. return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText) . '
  8921. ' . $this->headers . '
  8922. ' . $this->getContent();
  8923. }
  8924. public function __clone()
  8925. {
  8926. $this->headers = clone $this->headers;
  8927. }
  8928. public function prepare(Request $request)
  8929. {
  8930. $headers = $this->headers;
  8931. if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
  8932. $this->setContent(null);
  8933. }
  8934. if (!$headers->has('Content-Type')) {
  8935. $format = $request->getRequestFormat();
  8936. if (null !== $format && ($mimeType = $request->getMimeType($format))) {
  8937. $headers->set('Content-Type', $mimeType);
  8938. }
  8939. }
  8940. $charset = $this->charset ?: 'UTF-8';
  8941. if (!$headers->has('Content-Type')) {
  8942. $headers->set('Content-Type', 'text/html; charset=' . $charset);
  8943. } elseif (0 === strpos($headers->get('Content-Type'), 'text/') && false === strpos($headers->get('Content-Type'), 'charset')) {
  8944. $headers->set('Content-Type', $headers->get('Content-Type') . '; charset=' . $charset);
  8945. }
  8946. if ($headers->has('Transfer-Encoding')) {
  8947. $headers->remove('Content-Length');
  8948. }
  8949. if ($request->isMethod('HEAD')) {
  8950. $length = $headers->get('Content-Length');
  8951. $this->setContent(null);
  8952. if ($length) {
  8953. $headers->set('Content-Length', $length);
  8954. }
  8955. }
  8956. if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
  8957. $this->setProtocolVersion('1.1');
  8958. }
  8959. if ('1.0' == $this->getProtocolVersion() && 'no-cache' == $this->headers->get('Cache-Control')) {
  8960. $this->headers->set('pragma', 'no-cache');
  8961. $this->headers->set('expires', -1);
  8962. }
  8963. $this->ensureIEOverSSLCompatibility($request);
  8964. return $this;
  8965. }
  8966. public function sendHeaders()
  8967. {
  8968. if (headers_sent()) {
  8969. return $this;
  8970. }
  8971. header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
  8972. foreach ($this->headers->allPreserveCase() as $name => $values) {
  8973. foreach ($values as $value) {
  8974. header($name . ': ' . $value, false);
  8975. }
  8976. }
  8977. foreach ($this->headers->getCookies() as $cookie) {
  8978. setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
  8979. }
  8980. return $this;
  8981. }
  8982. public function sendContent()
  8983. {
  8984. echo $this->content;
  8985. return $this;
  8986. }
  8987. public function send()
  8988. {
  8989. $this->sendHeaders();
  8990. $this->sendContent();
  8991. if (function_exists('fastcgi_finish_request')) {
  8992. fastcgi_finish_request();
  8993. } elseif ('cli' !== PHP_SAPI) {
  8994. $previous = null;
  8995. $obStatus = ob_get_status(1);
  8996. while (($level = ob_get_level()) > 0 && $level !== $previous) {
  8997. $previous = $level;
  8998. if ($obStatus[$level - 1] && isset($obStatus[$level - 1]['del']) && $obStatus[$level - 1]['del']) {
  8999. ob_end_flush();
  9000. }
  9001. }
  9002. flush();
  9003. }
  9004. return $this;
  9005. }
  9006. public function setContent($content)
  9007. {
  9008. if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) {
  9009. throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content)));
  9010. }
  9011. $this->content = (string) $content;
  9012. return $this;
  9013. }
  9014. public function getContent()
  9015. {
  9016. return $this->content;
  9017. }
  9018. public function setProtocolVersion($version)
  9019. {
  9020. $this->version = $version;
  9021. return $this;
  9022. }
  9023. public function getProtocolVersion()
  9024. {
  9025. return $this->version;
  9026. }
  9027. public function setStatusCode($code, $text = null)
  9028. {
  9029. $this->statusCode = $code = (int) $code;
  9030. if ($this->isInvalid()) {
  9031. throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
  9032. }
  9033. if (null === $text) {
  9034. $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : '';
  9035. return $this;
  9036. }
  9037. if (false === $text) {
  9038. $this->statusText = '';
  9039. return $this;
  9040. }
  9041. $this->statusText = $text;
  9042. return $this;
  9043. }
  9044. public function getStatusCode()
  9045. {
  9046. return $this->statusCode;
  9047. }
  9048. public function setCharset($charset)
  9049. {
  9050. $this->charset = $charset;
  9051. return $this;
  9052. }
  9053. public function getCharset()
  9054. {
  9055. return $this->charset;
  9056. }
  9057. public function isCacheable()
  9058. {
  9059. if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) {
  9060. return false;
  9061. }
  9062. if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
  9063. return false;
  9064. }
  9065. return $this->isValidateable() || $this->isFresh();
  9066. }
  9067. public function isFresh()
  9068. {
  9069. return $this->getTtl() > 0;
  9070. }
  9071. public function isValidateable()
  9072. {
  9073. return $this->headers->has('Last-Modified') || $this->headers->has('ETag');
  9074. }
  9075. public function setPrivate()
  9076. {
  9077. $this->headers->removeCacheControlDirective('public');
  9078. $this->headers->addCacheControlDirective('private');
  9079. return $this;
  9080. }
  9081. public function setPublic()
  9082. {
  9083. $this->headers->addCacheControlDirective('public');
  9084. $this->headers->removeCacheControlDirective('private');
  9085. return $this;
  9086. }
  9087. public function mustRevalidate()
  9088. {
  9089. return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('proxy-revalidate');
  9090. }
  9091. public function getDate()
  9092. {
  9093. return $this->headers->getDate('Date', new \DateTime());
  9094. }
  9095. public function setDate(\DateTime $date)
  9096. {
  9097. $date->setTimezone(new \DateTimeZone('UTC'));
  9098. $this->headers->set('Date', $date->format('D, d M Y H:i:s') . ' GMT');
  9099. return $this;
  9100. }
  9101. public function getAge()
  9102. {
  9103. if (null !== ($age = $this->headers->get('Age'))) {
  9104. return (int) $age;
  9105. }
  9106. return max(time() - $this->getDate()->format('U'), 0);
  9107. }
  9108. public function expire()
  9109. {
  9110. if ($this->isFresh()) {
  9111. $this->headers->set('Age', $this->getMaxAge());
  9112. }
  9113. return $this;
  9114. }
  9115. public function getExpires()
  9116. {
  9117. try {
  9118. return $this->headers->getDate('Expires');
  9119. } catch (\RuntimeException $e) {
  9120. return \DateTime::createFromFormat(DATE_RFC2822, 'Sat, 01 Jan 00 00:00:00 +0000');
  9121. }
  9122. }
  9123. public function setExpires(\DateTime $date = null)
  9124. {
  9125. if (null === $date) {
  9126. $this->headers->remove('Expires');
  9127. } else {
  9128. $date = clone $date;
  9129. $date->setTimezone(new \DateTimeZone('UTC'));
  9130. $this->headers->set('Expires', $date->format('D, d M Y H:i:s') . ' GMT');
  9131. }
  9132. return $this;
  9133. }
  9134. public function getMaxAge()
  9135. {
  9136. if ($this->headers->hasCacheControlDirective('s-maxage')) {
  9137. return (int) $this->headers->getCacheControlDirective('s-maxage');
  9138. }
  9139. if ($this->headers->hasCacheControlDirective('max-age')) {
  9140. return (int) $this->headers->getCacheControlDirective('max-age');
  9141. }
  9142. if (null !== $this->getExpires()) {
  9143. return $this->getExpires()->format('U') - $this->getDate()->format('U');
  9144. }
  9145. return null;
  9146. }
  9147. public function setMaxAge($value)
  9148. {
  9149. $this->headers->addCacheControlDirective('max-age', $value);
  9150. return $this;
  9151. }
  9152. public function setSharedMaxAge($value)
  9153. {
  9154. $this->setPublic();
  9155. $this->headers->addCacheControlDirective('s-maxage', $value);
  9156. return $this;
  9157. }
  9158. public function getTtl()
  9159. {
  9160. if (null !== ($maxAge = $this->getMaxAge())) {
  9161. return $maxAge - $this->getAge();
  9162. }
  9163. return null;
  9164. }
  9165. public function setTtl($seconds)
  9166. {
  9167. $this->setSharedMaxAge($this->getAge() + $seconds);
  9168. return $this;
  9169. }
  9170. public function setClientTtl($seconds)
  9171. {
  9172. $this->setMaxAge($this->getAge() + $seconds);
  9173. return $this;
  9174. }
  9175. public function getLastModified()
  9176. {
  9177. return $this->headers->getDate('Last-Modified');
  9178. }
  9179. public function setLastModified(\DateTime $date = null)
  9180. {
  9181. if (null === $date) {
  9182. $this->headers->remove('Last-Modified');
  9183. } else {
  9184. $date = clone $date;
  9185. $date->setTimezone(new \DateTimeZone('UTC'));
  9186. $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s') . ' GMT');
  9187. }
  9188. return $this;
  9189. }
  9190. public function getEtag()
  9191. {
  9192. return $this->headers->get('ETag');
  9193. }
  9194. public function setEtag($etag = null, $weak = false)
  9195. {
  9196. if (null === $etag) {
  9197. $this->headers->remove('Etag');
  9198. } else {
  9199. if (0 !== strpos($etag, '"')) {
  9200. $etag = '"' . $etag . '"';
  9201. }
  9202. $this->headers->set('ETag', (true === $weak ? 'W/' : '') . $etag);
  9203. }
  9204. return $this;
  9205. }
  9206. public function setCache(array $options)
  9207. {
  9208. if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) {
  9209. throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff))));
  9210. }
  9211. if (isset($options['etag'])) {
  9212. $this->setEtag($options['etag']);
  9213. }
  9214. if (isset($options['last_modified'])) {
  9215. $this->setLastModified($options['last_modified']);
  9216. }
  9217. if (isset($options['max_age'])) {
  9218. $this->setMaxAge($options['max_age']);
  9219. }
  9220. if (isset($options['s_maxage'])) {
  9221. $this->setSharedMaxAge($options['s_maxage']);
  9222. }
  9223. if (isset($options['public'])) {
  9224. if ($options['public']) {
  9225. $this->setPublic();
  9226. } else {
  9227. $this->setPrivate();
  9228. }
  9229. }
  9230. if (isset($options['private'])) {
  9231. if ($options['private']) {
  9232. $this->setPrivate();
  9233. } else {
  9234. $this->setPublic();
  9235. }
  9236. }
  9237. return $this;
  9238. }
  9239. public function setNotModified()
  9240. {
  9241. $this->setStatusCode(304);
  9242. $this->setContent(null);
  9243. foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) {
  9244. $this->headers->remove($header);
  9245. }
  9246. return $this;
  9247. }
  9248. public function hasVary()
  9249. {
  9250. return null !== $this->headers->get('Vary');
  9251. }
  9252. public function getVary()
  9253. {
  9254. if (!($vary = $this->headers->get('Vary'))) {
  9255. return array();
  9256. }
  9257. return is_array($vary) ? $vary : preg_split('/[\\s,]+/', $vary);
  9258. }
  9259. public function setVary($headers, $replace = true)
  9260. {
  9261. $this->headers->set('Vary', $headers, $replace);
  9262. return $this;
  9263. }
  9264. public function isNotModified(Request $request)
  9265. {
  9266. if (!$request->isMethodSafe()) {
  9267. return false;
  9268. }
  9269. $lastModified = $request->headers->get('If-Modified-Since');
  9270. $notModified = false;
  9271. if ($etags = $request->getEtags()) {
  9272. $notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified);
  9273. } elseif ($lastModified) {
  9274. $notModified = $lastModified == $this->headers->get('Last-Modified');
  9275. }
  9276. if ($notModified) {
  9277. $this->setNotModified();
  9278. }
  9279. return $notModified;
  9280. }
  9281. public function isInvalid()
  9282. {
  9283. return $this->statusCode < 100 || $this->statusCode >= 600;
  9284. }
  9285. public function isInformational()
  9286. {
  9287. return $this->statusCode >= 100 && $this->statusCode < 200;
  9288. }
  9289. public function isSuccessful()
  9290. {
  9291. return $this->statusCode >= 200 && $this->statusCode < 300;
  9292. }
  9293. public function isRedirection()
  9294. {
  9295. return $this->statusCode >= 300 && $this->statusCode < 400;
  9296. }
  9297. public function isClientError()
  9298. {
  9299. return $this->statusCode >= 400 && $this->statusCode < 500;
  9300. }
  9301. public function isServerError()
  9302. {
  9303. return $this->statusCode >= 500 && $this->statusCode < 600;
  9304. }
  9305. public function isOk()
  9306. {
  9307. return 200 === $this->statusCode;
  9308. }
  9309. public function isForbidden()
  9310. {
  9311. return 403 === $this->statusCode;
  9312. }
  9313. public function isNotFound()
  9314. {
  9315. return 404 === $this->statusCode;
  9316. }
  9317. public function isRedirect($location = null)
  9318. {
  9319. return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location'));
  9320. }
  9321. public function isEmpty()
  9322. {
  9323. return in_array($this->statusCode, array(201, 204, 304));
  9324. }
  9325. protected function ensureIEOverSSLCompatibility(Request $request)
  9326. {
  9327. if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) {
  9328. if (intval(preg_replace('/(MSIE )(.*?);/', '$2', $match[0])) < 9) {
  9329. $this->headers->remove('Cache-Control');
  9330. }
  9331. }
  9332. }
  9333. }
  9334. namespace Illuminate\Http;
  9335. use Symfony\Component\HttpFoundation\Cookie;
  9336. use Illuminate\Support\Contracts\JsonableInterface;
  9337. use Illuminate\Support\Contracts\RenderableInterface;
  9338. class Response extends \Symfony\Component\HttpFoundation\Response
  9339. {
  9340. public $original;
  9341. public function header($key, $value, $replace = true)
  9342. {
  9343. $this->headers->set($key, $value, $replace);
  9344. return $this;
  9345. }
  9346. public function withCookie(Cookie $cookie)
  9347. {
  9348. $this->headers->setCookie($cookie);
  9349. return $this;
  9350. }
  9351. public function setContent($content)
  9352. {
  9353. $this->original = $content;
  9354. if ($this->shouldBeJson($content)) {
  9355. $this->headers->set('Content-Type', 'application/json');
  9356. $content = $this->morphToJson($content);
  9357. } elseif ($content instanceof RenderableInterface) {
  9358. $content = $content->render();
  9359. }
  9360. return parent::setContent($content);
  9361. }
  9362. protected function morphToJson($content)
  9363. {
  9364. if ($content instanceof JsonableInterface) {
  9365. return $content->toJson();
  9366. }
  9367. return json_encode($content);
  9368. }
  9369. protected function shouldBeJson($content)
  9370. {
  9371. return $content instanceof JsonableInterface or is_array($content);
  9372. }
  9373. public function getOriginalContent()
  9374. {
  9375. return $this->original;
  9376. }
  9377. }
  9378. namespace Symfony\Component\HttpFoundation;
  9379. class ResponseHeaderBag extends HeaderBag
  9380. {
  9381. const COOKIES_FLAT = 'flat';
  9382. const COOKIES_ARRAY = 'array';
  9383. const DISPOSITION_ATTACHMENT = 'attachment';
  9384. const DISPOSITION_INLINE = 'inline';
  9385. protected $computedCacheControl = array();
  9386. protected $cookies = array();
  9387. protected $headerNames = array();
  9388. public function __construct(array $headers = array())
  9389. {
  9390. parent::__construct($headers);
  9391. if (!isset($this->headers['cache-control'])) {
  9392. $this->set('Cache-Control', '');
  9393. }
  9394. }
  9395. public function __toString()
  9396. {
  9397. $cookies = '';
  9398. foreach ($this->getCookies() as $cookie) {
  9399. $cookies .= 'Set-Cookie: ' . $cookie . '
  9400. ';
  9401. }
  9402. ksort($this->headerNames);
  9403. return parent::__toString() . $cookies;
  9404. }
  9405. public function allPreserveCase()
  9406. {
  9407. return array_combine($this->headerNames, $this->headers);
  9408. }
  9409. public function replace(array $headers = array())
  9410. {
  9411. $this->headerNames = array();
  9412. parent::replace($headers);
  9413. if (!isset($this->headers['cache-control'])) {
  9414. $this->set('Cache-Control', '');
  9415. }
  9416. }
  9417. public function set($key, $values, $replace = true)
  9418. {
  9419. parent::set($key, $values, $replace);
  9420. $uniqueKey = strtr(strtolower($key), '_', '-');
  9421. $this->headerNames[$uniqueKey] = $key;
  9422. if (in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'))) {
  9423. $computed = $this->computeCacheControlValue();
  9424. $this->headers['cache-control'] = array($computed);
  9425. $this->headerNames['cache-control'] = 'Cache-Control';
  9426. $this->computedCacheControl = $this->parseCacheControl($computed);
  9427. }
  9428. }
  9429. public function remove($key)
  9430. {
  9431. parent::remove($key);
  9432. $uniqueKey = strtr(strtolower($key), '_', '-');
  9433. unset($this->headerNames[$uniqueKey]);
  9434. if ('cache-control' === $uniqueKey) {
  9435. $this->computedCacheControl = array();
  9436. }
  9437. }
  9438. public function hasCacheControlDirective($key)
  9439. {
  9440. return array_key_exists($key, $this->computedCacheControl);
  9441. }
  9442. public function getCacheControlDirective($key)
  9443. {
  9444. return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
  9445. }
  9446. public function setCookie(Cookie $cookie)
  9447. {
  9448. $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
  9449. }
  9450. public function removeCookie($name, $path = '/', $domain = null)
  9451. {
  9452. if (null === $path) {
  9453. $path = '/';
  9454. }
  9455. unset($this->cookies[$domain][$path][$name]);
  9456. if (empty($this->cookies[$domain][$path])) {
  9457. unset($this->cookies[$domain][$path]);
  9458. if (empty($this->cookies[$domain])) {
  9459. unset($this->cookies[$domain]);
  9460. }
  9461. }
  9462. }
  9463. public function getCookies($format = self::COOKIES_FLAT)
  9464. {
  9465. if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) {
  9466. throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY))));
  9467. }
  9468. if (self::COOKIES_ARRAY === $format) {
  9469. return $this->cookies;
  9470. }
  9471. $flattenedCookies = array();
  9472. foreach ($this->cookies as $path) {
  9473. foreach ($path as $cookies) {
  9474. foreach ($cookies as $cookie) {
  9475. $flattenedCookies[] = $cookie;
  9476. }
  9477. }
  9478. }
  9479. return $flattenedCookies;
  9480. }
  9481. public function clearCookie($name, $path = '/', $domain = null)
  9482. {
  9483. $this->setCookie(new Cookie($name, null, 1, $path, $domain));
  9484. }
  9485. public function makeDisposition($disposition, $filename, $filenameFallback = '')
  9486. {
  9487. if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
  9488. throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
  9489. }
  9490. if ('' == $filenameFallback) {
  9491. $filenameFallback = $filename;
  9492. }
  9493. if (!preg_match('/^[\\x20-\\x7e]*$/', $filenameFallback)) {
  9494. throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
  9495. }
  9496. if (false !== strpos($filenameFallback, '%')) {
  9497. throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
  9498. }
  9499. if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
  9500. throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
  9501. }
  9502. $output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
  9503. if ($filename !== $filenameFallback) {
  9504. $output .= sprintf('; filename*=utf-8\'\'%s', rawurlencode($filename));
  9505. }
  9506. return $output;
  9507. }
  9508. protected function computeCacheControlValue()
  9509. {
  9510. if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
  9511. return 'no-cache';
  9512. }
  9513. if (!$this->cacheControl) {
  9514. return 'private, must-revalidate';
  9515. }
  9516. $header = $this->getCacheControlHeader();
  9517. if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
  9518. return $header;
  9519. }
  9520. if (!isset($this->cacheControl['s-maxage'])) {
  9521. return $header . ', private';
  9522. }
  9523. return $header;
  9524. }
  9525. }
  9526. namespace Symfony\Component\HttpFoundation;
  9527. class Cookie
  9528. {
  9529. protected $name;
  9530. protected $value;
  9531. protected $domain;
  9532. protected $expire;
  9533. protected $path;
  9534. protected $secure;
  9535. protected $httpOnly;
  9536. public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true)
  9537. {
  9538. if (preg_match('/[=,;
  9539. ]/', $name)) {
  9540. throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
  9541. }
  9542. if (empty($name)) {
  9543. throw new \InvalidArgumentException('The cookie name cannot be empty.');
  9544. }
  9545. if ($expire instanceof \DateTime) {
  9546. $expire = $expire->format('U');
  9547. } elseif (!is_numeric($expire)) {
  9548. $expire = strtotime($expire);
  9549. if (false === $expire || -1 === $expire) {
  9550. throw new \InvalidArgumentException('The cookie expiration time is not valid.');
  9551. }
  9552. }
  9553. $this->name = $name;
  9554. $this->value = $value;
  9555. $this->domain = $domain;
  9556. $this->expire = $expire;
  9557. $this->path = empty($path) ? '/' : $path;
  9558. $this->secure = (bool) $secure;
  9559. $this->httpOnly = (bool) $httpOnly;
  9560. }
  9561. public function __toString()
  9562. {
  9563. $str = urlencode($this->getName()) . '=';
  9564. if ('' === (string) $this->getValue()) {
  9565. $str .= 'deleted; expires=' . gmdate('D, d-M-Y H:i:s T', time() - 31536001);
  9566. } else {
  9567. $str .= urlencode($this->getValue());
  9568. if ($this->getExpiresTime() !== 0) {
  9569. $str .= '; expires=' . gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime());
  9570. }
  9571. }
  9572. if ($this->path) {
  9573. $str .= '; path=' . $this->path;
  9574. }
  9575. if ($this->getDomain()) {
  9576. $str .= '; domain=' . $this->getDomain();
  9577. }
  9578. if (true === $this->isSecure()) {
  9579. $str .= '; secure';
  9580. }
  9581. if (true === $this->isHttpOnly()) {
  9582. $str .= '; httponly';
  9583. }
  9584. return $str;
  9585. }
  9586. public function getName()
  9587. {
  9588. return $this->name;
  9589. }
  9590. public function getValue()
  9591. {
  9592. return $this->value;
  9593. }
  9594. public function getDomain()
  9595. {
  9596. return $this->domain;
  9597. }
  9598. public function getExpiresTime()
  9599. {
  9600. return $this->expire;
  9601. }
  9602. public function getPath()
  9603. {
  9604. return $this->path;
  9605. }
  9606. public function isSecure()
  9607. {
  9608. return $this->secure;
  9609. }
  9610. public function isHttpOnly()
  9611. {
  9612. return $this->httpOnly;
  9613. }
  9614. public function isCleared()
  9615. {
  9616. return $this->expire < time();
  9617. }
  9618. }
  9619. namespace Whoops;
  9620. use Whoops\Handler\HandlerInterface;
  9621. use Whoops\Handler\Handler;
  9622. use Whoops\Handler\CallbackHandler;
  9623. use Whoops\Exception\Inspector;
  9624. use Whoops\Exception\ErrorException;
  9625. use InvalidArgumentException;
  9626. use Exception;
  9627. class Run
  9628. {
  9629. const EXCEPTION_HANDLER = 'handleException';
  9630. const ERROR_HANDLER = 'handleError';
  9631. const SHUTDOWN_HANDLER = 'handleShutdown';
  9632. protected $isRegistered;
  9633. protected $allowQuit = true;
  9634. protected $sendOutput = true;
  9635. protected $handlerStack = array();
  9636. public function pushHandler($handler)
  9637. {
  9638. if (is_callable($handler)) {
  9639. $handler = new CallbackHandler($handler);
  9640. }
  9641. if (!$handler instanceof HandlerInterface) {
  9642. throw new InvalidArgumentException('Argument to ' . __METHOD__ . ' must be a callable, or instance of' . 'Whoops\\Handler\\HandlerInterface');
  9643. }
  9644. $this->handlerStack[] = $handler;
  9645. return $this;
  9646. }
  9647. public function popHandler()
  9648. {
  9649. return array_pop($this->handlerStack);
  9650. }
  9651. public function getHandlers()
  9652. {
  9653. return $this->handlerStack;
  9654. }
  9655. public function clearHandlers()
  9656. {
  9657. $this->handlerStack = array();
  9658. return $this;
  9659. }
  9660. protected function getInspector(Exception $exception)
  9661. {
  9662. return new Inspector($exception);
  9663. }
  9664. public function register()
  9665. {
  9666. if (!$this->isRegistered) {
  9667. set_error_handler(array($this, self::ERROR_HANDLER));
  9668. set_exception_handler(array($this, self::EXCEPTION_HANDLER));
  9669. register_shutdown_function(array($this, self::SHUTDOWN_HANDLER));
  9670. $this->isRegistered = true;
  9671. }
  9672. return $this;
  9673. }
  9674. public function unregister()
  9675. {
  9676. if ($this->isRegistered) {
  9677. restore_exception_handler();
  9678. restore_error_handler();
  9679. $this->isRegistered = false;
  9680. }
  9681. return $this;
  9682. }
  9683. public function allowQuit($exit = null)
  9684. {
  9685. if (func_num_args() == 0) {
  9686. return $this->allowQuit;
  9687. }
  9688. return $this->allowQuit = (bool) $exit;
  9689. }
  9690. public function writeToOutput($send = null)
  9691. {
  9692. if (func_num_args() == 0) {
  9693. return $this->sendOutput;
  9694. }
  9695. return $this->sendOutput = (bool) $send;
  9696. }
  9697. public function handleException(Exception $exception)
  9698. {
  9699. $inspector = $this->getInspector($exception);
  9700. ob_start();
  9701. for ($i = count($this->handlerStack) - 1; $i >= 0; $i--) {
  9702. $handler = $this->handlerStack[$i];
  9703. $handler->setRun($this);
  9704. $handler->setInspector($inspector);
  9705. $handler->setException($exception);
  9706. $handlerResponse = $handler->handle($exception);
  9707. if (in_array($handlerResponse, array(Handler::LAST_HANDLER, Handler::QUIT))) {
  9708. break;
  9709. }
  9710. }
  9711. $output = ob_get_clean();
  9712. if ($this->allowQuit()) {
  9713. echo $output;
  9714. die;
  9715. } else {
  9716. if ($this->writeToOutput()) {
  9717. echo $output;
  9718. }
  9719. return $output;
  9720. }
  9721. }
  9722. public function handleError($level, $message, $file = null, $line = null)
  9723. {
  9724. if ($level & error_reporting()) {
  9725. $this->handleException(new ErrorException($message, $level, 0, $file, $line));
  9726. }
  9727. }
  9728. public function handleShutdown()
  9729. {
  9730. if ($error = error_get_last()) {
  9731. $this->handleError($error['type'], $error['message'], $error['file'], $error['line']);
  9732. }
  9733. }
  9734. }
  9735. namespace Whoops\Handler;
  9736. use Whoops\Exception\Inspector;
  9737. use Whoops\Run;
  9738. use Exception;
  9739. interface HandlerInterface
  9740. {
  9741. public function handle();
  9742. public function setRun(Run $run);
  9743. public function setException(Exception $exception);
  9744. public function setInspector(Inspector $inspector);
  9745. }
  9746. namespace Whoops\Handler;
  9747. use Whoops\Handler\HandlerInterface;
  9748. use Whoops\Exception\Inspector;
  9749. use Whoops\Run;
  9750. use Exception;
  9751. abstract class Handler implements HandlerInterface
  9752. {
  9753. const DONE = 16;
  9754. const LAST_HANDLER = 32;
  9755. const QUIT = 48;
  9756. private $run;
  9757. private $inspector;
  9758. private $exception;
  9759. public function setRun(Run $run)
  9760. {
  9761. $this->run = $run;
  9762. }
  9763. protected function getRun()
  9764. {
  9765. return $this->run;
  9766. }
  9767. public function setInspector(Inspector $inspector)
  9768. {
  9769. $this->inspector = $inspector;
  9770. }
  9771. protected function getInspector()
  9772. {
  9773. return $this->inspector;
  9774. }
  9775. public function setException(Exception $exception)
  9776. {
  9777. $this->exception = $exception;
  9778. }
  9779. protected function getException()
  9780. {
  9781. return $this->exception;
  9782. }
  9783. }
  9784. namespace Whoops\Handler;
  9785. use Whoops\Handler\Handler;
  9786. use InvalidArgumentException;
  9787. class PrettyPageHandler extends Handler
  9788. {
  9789. private $resourcesPath;
  9790. private $extraTables = array();
  9791. private $pageTitle = 'Whoops! There was an error.';
  9792. protected $editor;
  9793. 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');
  9794. public function __construct()
  9795. {
  9796. if (extension_loaded('xdebug')) {
  9797. $this->editors['xdebug'] = function ($file, $line) {
  9798. return str_replace(array('%f', '%l'), array($file, $line), ini_get('xdebug.file_link_format'));
  9799. };
  9800. }
  9801. }
  9802. public function handle()
  9803. {
  9804. if (php_sapi_name() === 'cli' && !isset($_ENV['whoops-test'])) {
  9805. return Handler::DONE;
  9806. }
  9807. if (!($resources = $this->getResourcesPath())) {
  9808. $resources = 'C:\\wamp\\www\\starter-kit-fr\\vendor\\filp\\whoops\\src\\Whoops\\Handler' . '/../Resources';
  9809. }
  9810. $templateFile = "{$resources}/pretty-template.php";
  9811. $cssFile = "{$resources}/pretty-page.css";
  9812. $inspector = $this->getInspector();
  9813. $frames = $inspector->getFrames();
  9814. $v = (object) array('title' => $this->getPageTitle(), 'name' => explode('\\', $inspector->getExceptionName()), 'message' => $inspector->getException()->getMessage(), 'frames' => $frames, 'hasFrames' => !!count($frames), 'handler' => $this, 'handlers' => $this->getRun()->getHandlers(), 'pageStyle' => file_get_contents($cssFile), 'tables' => array('Server/Request Data' => $_SERVER, 'GET Data' => $_GET, 'POST Data' => $_POST, 'Files' => $_FILES, 'Cookies' => $_COOKIE, 'Session' => isset($_SESSION) ? $_SESSION : array(), 'Environment Variables' => $_ENV));
  9815. $extraTables = array_map(function ($table) {
  9816. return $table instanceof \Closure ? $table() : $table;
  9817. }, $this->getDataTables());
  9818. $v->tables = array_merge($extraTables, $v->tables);
  9819. call_user_func(function () use($templateFile, $v) {
  9820. $e = function ($_, $allowLinks = false) {
  9821. $escaped = htmlspecialchars($_, ENT_QUOTES, 'UTF-8');
  9822. if ($allowLinks) {
  9823. $escaped = preg_replace('@([A-z]+?://([-\\w\\.]+[-\\w])+(:\\d+)?(/([\\w/_\\.#-]*(\\?\\S+)?[^\\.\\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $escaped);
  9824. }
  9825. return $escaped;
  9826. };
  9827. $slug = function ($_) {
  9828. $_ = str_replace(' ', '-', $_);
  9829. $_ = preg_replace('/[^\\w\\d\\-\\_]/i', '', $_);
  9830. return strtolower($_);
  9831. };
  9832. require $templateFile;
  9833. });
  9834. return Handler::QUIT;
  9835. }
  9836. public function addDataTable($label, array $data)
  9837. {
  9838. $this->extraTables[$label] = $data;
  9839. }
  9840. public function addDataTableCallback($label, $callback)
  9841. {
  9842. if (!is_callable($callback)) {
  9843. throw new InvalidArgumentException('Expecting callback argument to be callable');
  9844. }
  9845. $this->extraTables[$label] = function () use($callback) {
  9846. try {
  9847. $result = call_user_func($callback);
  9848. return is_array($result) || $result instanceof \Traversable ? $result : array();
  9849. } catch (\Exception $e) {
  9850. return array();
  9851. }
  9852. };
  9853. }
  9854. public function getDataTables($label = null)
  9855. {
  9856. if ($label !== null) {
  9857. return isset($this->extraTables[$label]) ? $this->extraTables[$label] : array();
  9858. }
  9859. return $this->extraTables;
  9860. }
  9861. public function addEditor($identifier, $resolver)
  9862. {
  9863. $this->editors[$identifier] = $resolver;
  9864. }
  9865. public function setEditor($editor)
  9866. {
  9867. if (!is_callable($editor) && !isset($this->editors[$editor])) {
  9868. throw new InvalidArgumentException("Unknown editor identifier: {$editor}. Known editors:" . implode(',', array_keys($this->editors)));
  9869. }
  9870. $this->editor = $editor;
  9871. }
  9872. public function getEditorHref($filePath, $line)
  9873. {
  9874. if ($this->editor === null) {
  9875. return false;
  9876. }
  9877. $editor = $this->editor;
  9878. if (is_string($editor)) {
  9879. $editor = $this->editors[$editor];
  9880. }
  9881. if (is_callable($editor)) {
  9882. $editor = call_user_func($editor, $filePath, $line);
  9883. }
  9884. if (!is_string($editor)) {
  9885. throw new InvalidArgumentException(__METHOD__ . ' should always resolve to a string; got something else instead');
  9886. }
  9887. $editor = str_replace('%line', rawurlencode($line), $editor);
  9888. $editor = str_replace('%file', rawurlencode($filePath), $editor);
  9889. return $editor;
  9890. }
  9891. public function setPageTitle($title)
  9892. {
  9893. $this->pageTitle = (string) $title;
  9894. }
  9895. public function getPageTitle()
  9896. {
  9897. return $this->pageTitle;
  9898. }
  9899. public function getResourcesPath()
  9900. {
  9901. return $this->resourcesPath;
  9902. }
  9903. public function setResourcesPath($resourcesPath)
  9904. {
  9905. if (!is_dir($resourcesPath)) {
  9906. throw new InvalidArgumentException("{$resourcesPath} is not a valid directory");
  9907. }
  9908. $this->resourcesPath = $resourcesPath;
  9909. }
  9910. }
  9911. namespace Whoops\Handler;
  9912. use Whoops\Handler\Handler;
  9913. class JsonResponseHandler extends Handler
  9914. {
  9915. private $returnFrames = false;
  9916. private $onlyForAjaxRequests = false;
  9917. public function addTraceToOutput($returnFrames = null)
  9918. {
  9919. if (func_num_args() == 0) {
  9920. return $this->returnFrames;
  9921. }
  9922. $this->returnFrames = (bool) $returnFrames;
  9923. }
  9924. public function onlyForAjaxRequests($onlyForAjaxRequests = null)
  9925. {
  9926. if (func_num_args() == 0) {
  9927. return $this->onlyForAjaxRequests;
  9928. }
  9929. $this->onlyForAjaxRequests = (bool) $onlyForAjaxRequests;
  9930. }
  9931. private function isAjaxRequest()
  9932. {
  9933. return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
  9934. }
  9935. public function handle()
  9936. {
  9937. if ($this->onlyForAjaxRequests() && !$this->isAjaxRequest()) {
  9938. return Handler::DONE;
  9939. }
  9940. $exception = $this->getException();
  9941. $response = array('error' => array('type' => get_class($exception), 'message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()));
  9942. if ($this->addTraceToOutput()) {
  9943. $inspector = $this->getInspector();
  9944. $frames = $inspector->getFrames();
  9945. $frameData = array();
  9946. foreach ($frames as $frame) {
  9947. $frameData[] = array('file' => $frame->getFile(), 'line' => $frame->getLine(), 'function' => $frame->getFunction(), 'class' => $frame->getClass(), 'args' => $frame->getArgs());
  9948. }
  9949. $response['error']['trace'] = $frameData;
  9950. }
  9951. echo json_encode($response);
  9952. return Handler::QUIT;
  9953. }
  9954. }