PageRenderTime 171ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/app/cache/dev/classes.php

https://github.com/silvanei/treinaweb-symfony2-basico
PHP | 6458 lines | 6458 code | 0 blank | 0 comment | 781 complexity | 460ab38af96583ae9f2c44d2ac335ce0 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. namespace Monolog\Formatter
  3. {
  4. interface FormatterInterface
  5. {
  6. public function format(array $record);
  7. public function formatBatch(array $records);
  8. }
  9. }
  10. namespace Monolog\Formatter
  11. {
  12. use Exception;
  13. class NormalizerFormatter implements FormatterInterface
  14. {
  15. const SIMPLE_DATE ="Y-m-d H:i:s";
  16. protected $dateFormat;
  17. public function __construct($dateFormat = null)
  18. {
  19. $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE;
  20. }
  21. public function format(array $record)
  22. {
  23. return $this->normalize($record);
  24. }
  25. public function formatBatch(array $records)
  26. {
  27. foreach ($records as $key => $record) {
  28. $records[$key] = $this->format($record);
  29. }
  30. return $records;
  31. }
  32. protected function normalize($data)
  33. {
  34. if (null === $data || is_scalar($data)) {
  35. return $data;
  36. }
  37. if (is_array($data) || $data instanceof \Traversable) {
  38. $normalized = array();
  39. $count = 1;
  40. foreach ($data as $key => $value) {
  41. if ($count++ >= 1000) {
  42. $normalized['...'] ='Over 1000 items, aborting normalization';
  43. break;
  44. }
  45. $normalized[$key] = $this->normalize($value);
  46. }
  47. return $normalized;
  48. }
  49. if ($data instanceof \DateTime) {
  50. return $data->format($this->dateFormat);
  51. }
  52. if (is_object($data)) {
  53. if ($data instanceof Exception) {
  54. return $this->normalizeException($data);
  55. }
  56. return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data, true));
  57. }
  58. if (is_resource($data)) {
  59. return'[resource]';
  60. }
  61. return'[unknown('.gettype($data).')]';
  62. }
  63. protected function normalizeException(Exception $e)
  64. {
  65. $data = array('class'=> get_class($e),'message'=> $e->getMessage(),'file'=> $e->getFile().':'.$e->getLine(),
  66. );
  67. $trace = $e->getTrace();
  68. foreach ($trace as $frame) {
  69. if (isset($frame['file'])) {
  70. $data['trace'][] = $frame['file'].':'.$frame['line'];
  71. } else {
  72. $data['trace'][] = json_encode($frame);
  73. }
  74. }
  75. if ($previous = $e->getPrevious()) {
  76. $data['previous'] = $this->normalizeException($previous);
  77. }
  78. return $data;
  79. }
  80. protected function toJson($data, $ignoreErrors = false)
  81. {
  82. if ($ignoreErrors) {
  83. if (version_compare(PHP_VERSION,'5.4.0','>=')) {
  84. return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
  85. }
  86. return @json_encode($data);
  87. }
  88. if (version_compare(PHP_VERSION,'5.4.0','>=')) {
  89. return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
  90. }
  91. return json_encode($data);
  92. }
  93. }
  94. }
  95. namespace Monolog\Formatter
  96. {
  97. use Exception;
  98. class LineFormatter extends NormalizerFormatter
  99. {
  100. const SIMPLE_FORMAT ="[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
  101. protected $format;
  102. protected $allowInlineLineBreaks;
  103. public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false)
  104. {
  105. $this->format = $format ?: static::SIMPLE_FORMAT;
  106. $this->allowInlineLineBreaks = $allowInlineLineBreaks;
  107. parent::__construct($dateFormat);
  108. }
  109. public function format(array $record)
  110. {
  111. $vars = parent::format($record);
  112. $output = $this->format;
  113. foreach ($vars['extra'] as $var => $val) {
  114. if (false !== strpos($output,'%extra.'.$var.'%')) {
  115. $output = str_replace('%extra.'.$var.'%', $this->replaceNewlines($this->convertToString($val)), $output);
  116. unset($vars['extra'][$var]);
  117. }
  118. }
  119. foreach ($vars as $var => $val) {
  120. if (false !== strpos($output,'%'.$var.'%')) {
  121. $output = str_replace('%'.$var.'%', $this->replaceNewlines($this->convertToString($val)), $output);
  122. }
  123. }
  124. return $output;
  125. }
  126. public function formatBatch(array $records)
  127. {
  128. $message ='';
  129. foreach ($records as $record) {
  130. $message .= $this->format($record);
  131. }
  132. return $message;
  133. }
  134. protected function normalizeException(Exception $e)
  135. {
  136. $previousText ='';
  137. if ($previous = $e->getPrevious()) {
  138. do {
  139. $previousText .=', '.get_class($previous).': '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine();
  140. } while ($previous = $previous->getPrevious());
  141. }
  142. return'[object] ('.get_class($e).': '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')';
  143. }
  144. protected function convertToString($data)
  145. {
  146. if (null === $data || is_bool($data)) {
  147. return var_export($data, true);
  148. }
  149. if (is_scalar($data)) {
  150. return (string) $data;
  151. }
  152. if (version_compare(PHP_VERSION,'5.4.0','>=')) {
  153. return $this->toJson($data, true);
  154. }
  155. return str_replace('\\/','/', @json_encode($data));
  156. }
  157. protected function replaceNewlines($str)
  158. {
  159. if ($this->allowInlineLineBreaks) {
  160. return $str;
  161. }
  162. return preg_replace('{[\r\n]+}',' ', $str);
  163. }
  164. }
  165. }
  166. namespace Monolog\Handler
  167. {
  168. use Monolog\Formatter\FormatterInterface;
  169. interface HandlerInterface
  170. {
  171. public function isHandling(array $record);
  172. public function handle(array $record);
  173. public function handleBatch(array $records);
  174. public function pushProcessor($callback);
  175. public function popProcessor();
  176. public function setFormatter(FormatterInterface $formatter);
  177. public function getFormatter();
  178. }
  179. }
  180. namespace Monolog\Handler
  181. {
  182. use Monolog\Logger;
  183. use Monolog\Formatter\FormatterInterface;
  184. use Monolog\Formatter\LineFormatter;
  185. abstract class AbstractHandler implements HandlerInterface
  186. {
  187. protected $level = Logger::DEBUG;
  188. protected $bubble = true;
  189. protected $formatter;
  190. protected $processors = array();
  191. public function __construct($level = Logger::DEBUG, $bubble = true)
  192. {
  193. $this->level = $level;
  194. $this->bubble = $bubble;
  195. }
  196. public function isHandling(array $record)
  197. {
  198. return $record['level'] >= $this->level;
  199. }
  200. public function handleBatch(array $records)
  201. {
  202. foreach ($records as $record) {
  203. $this->handle($record);
  204. }
  205. }
  206. public function close()
  207. {
  208. }
  209. public function pushProcessor($callback)
  210. {
  211. if (!is_callable($callback)) {
  212. throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given');
  213. }
  214. array_unshift($this->processors, $callback);
  215. return $this;
  216. }
  217. public function popProcessor()
  218. {
  219. if (!$this->processors) {
  220. throw new \LogicException('You tried to pop from an empty processor stack.');
  221. }
  222. return array_shift($this->processors);
  223. }
  224. public function setFormatter(FormatterInterface $formatter)
  225. {
  226. $this->formatter = $formatter;
  227. return $this;
  228. }
  229. public function getFormatter()
  230. {
  231. if (!$this->formatter) {
  232. $this->formatter = $this->getDefaultFormatter();
  233. }
  234. return $this->formatter;
  235. }
  236. public function setLevel($level)
  237. {
  238. $this->level = $level;
  239. return $this;
  240. }
  241. public function getLevel()
  242. {
  243. return $this->level;
  244. }
  245. public function setBubble($bubble)
  246. {
  247. $this->bubble = $bubble;
  248. return $this;
  249. }
  250. public function getBubble()
  251. {
  252. return $this->bubble;
  253. }
  254. public function __destruct()
  255. {
  256. try {
  257. $this->close();
  258. } catch (\Exception $e) {
  259. }
  260. }
  261. protected function getDefaultFormatter()
  262. {
  263. return new LineFormatter();
  264. }
  265. }
  266. }
  267. namespace Monolog\Handler
  268. {
  269. abstract class AbstractProcessingHandler extends AbstractHandler
  270. {
  271. public function handle(array $record)
  272. {
  273. if (!$this->isHandling($record)) {
  274. return false;
  275. }
  276. $record = $this->processRecord($record);
  277. $record['formatted'] = $this->getFormatter()->format($record);
  278. $this->write($record);
  279. return false === $this->bubble;
  280. }
  281. abstract protected function write(array $record);
  282. protected function processRecord(array $record)
  283. {
  284. if ($this->processors) {
  285. foreach ($this->processors as $processor) {
  286. $record = call_user_func($processor, $record);
  287. }
  288. }
  289. return $record;
  290. }
  291. }
  292. }
  293. namespace Monolog\Handler
  294. {
  295. use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
  296. use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
  297. use Monolog\Logger;
  298. class FingersCrossedHandler extends AbstractHandler
  299. {
  300. protected $handler;
  301. protected $activationStrategy;
  302. protected $buffering = true;
  303. protected $bufferSize;
  304. protected $buffer = array();
  305. protected $stopBuffering;
  306. public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true)
  307. {
  308. if (null === $activationStrategy) {
  309. $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING);
  310. }
  311. if (!$activationStrategy instanceof ActivationStrategyInterface) {
  312. $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy);
  313. }
  314. $this->handler = $handler;
  315. $this->activationStrategy = $activationStrategy;
  316. $this->bufferSize = $bufferSize;
  317. $this->bubble = $bubble;
  318. $this->stopBuffering = $stopBuffering;
  319. }
  320. public function isHandling(array $record)
  321. {
  322. return true;
  323. }
  324. public function handle(array $record)
  325. {
  326. if ($this->processors) {
  327. foreach ($this->processors as $processor) {
  328. $record = call_user_func($processor, $record);
  329. }
  330. }
  331. if ($this->buffering) {
  332. $this->buffer[] = $record;
  333. if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) {
  334. array_shift($this->buffer);
  335. }
  336. if ($this->activationStrategy->isHandlerActivated($record)) {
  337. if ($this->stopBuffering) {
  338. $this->buffering = false;
  339. }
  340. if (!$this->handler instanceof HandlerInterface) {
  341. if (!is_callable($this->handler)) {
  342. throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
  343. }
  344. $this->handler = call_user_func($this->handler, $record, $this);
  345. if (!$this->handler instanceof HandlerInterface) {
  346. throw new \RuntimeException("The factory callable should return a HandlerInterface");
  347. }
  348. }
  349. $this->handler->handleBatch($this->buffer);
  350. $this->buffer = array();
  351. }
  352. } else {
  353. $this->handler->handle($record);
  354. }
  355. return false === $this->bubble;
  356. }
  357. public function reset()
  358. {
  359. $this->buffering = true;
  360. }
  361. }
  362. }
  363. namespace Monolog\Handler\FingersCrossed
  364. {
  365. interface ActivationStrategyInterface
  366. {
  367. public function isHandlerActivated(array $record);
  368. }
  369. }
  370. namespace Monolog\Handler\FingersCrossed
  371. {
  372. class ErrorLevelActivationStrategy implements ActivationStrategyInterface
  373. {
  374. private $actionLevel;
  375. public function __construct($actionLevel)
  376. {
  377. $this->actionLevel = $actionLevel;
  378. }
  379. public function isHandlerActivated(array $record)
  380. {
  381. return $record['level'] >= $this->actionLevel;
  382. }
  383. }
  384. }
  385. namespace Monolog\Handler
  386. {
  387. use Monolog\Logger;
  388. class StreamHandler extends AbstractProcessingHandler
  389. {
  390. protected $stream;
  391. protected $url;
  392. private $errorMessage;
  393. protected $filePermission;
  394. public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null)
  395. {
  396. parent::__construct($level, $bubble);
  397. if (is_resource($stream)) {
  398. $this->stream = $stream;
  399. } else {
  400. $this->url = $stream;
  401. }
  402. $this->filePermission = $filePermission;
  403. }
  404. public function close()
  405. {
  406. if (is_resource($this->stream)) {
  407. fclose($this->stream);
  408. }
  409. $this->stream = null;
  410. }
  411. protected function write(array $record)
  412. {
  413. if (!is_resource($this->stream)) {
  414. if (!$this->url) {
  415. throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
  416. }
  417. $this->errorMessage = null;
  418. set_error_handler(array($this,'customErrorHandler'));
  419. $this->stream = fopen($this->url,'a');
  420. if ($this->filePermission !== null) {
  421. @chmod($this->url, $this->filePermission);
  422. }
  423. restore_error_handler();
  424. if (!is_resource($this->stream)) {
  425. $this->stream = null;
  426. throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
  427. }
  428. }
  429. fwrite($this->stream, (string) $record['formatted']);
  430. }
  431. private function customErrorHandler($code, $msg)
  432. {
  433. $this->errorMessage = preg_replace('{^fopen\(.*?\): }','', $msg);
  434. }
  435. }
  436. }
  437. namespace Monolog\Handler
  438. {
  439. use Monolog\Logger;
  440. class TestHandler extends AbstractProcessingHandler
  441. {
  442. protected $records = array();
  443. protected $recordsByLevel = array();
  444. public function getRecords()
  445. {
  446. return $this->records;
  447. }
  448. public function hasEmergency($record)
  449. {
  450. return $this->hasRecord($record, Logger::EMERGENCY);
  451. }
  452. public function hasAlert($record)
  453. {
  454. return $this->hasRecord($record, Logger::ALERT);
  455. }
  456. public function hasCritical($record)
  457. {
  458. return $this->hasRecord($record, Logger::CRITICAL);
  459. }
  460. public function hasError($record)
  461. {
  462. return $this->hasRecord($record, Logger::ERROR);
  463. }
  464. public function hasWarning($record)
  465. {
  466. return $this->hasRecord($record, Logger::WARNING);
  467. }
  468. public function hasNotice($record)
  469. {
  470. return $this->hasRecord($record, Logger::NOTICE);
  471. }
  472. public function hasInfo($record)
  473. {
  474. return $this->hasRecord($record, Logger::INFO);
  475. }
  476. public function hasDebug($record)
  477. {
  478. return $this->hasRecord($record, Logger::DEBUG);
  479. }
  480. public function hasEmergencyRecords()
  481. {
  482. return isset($this->recordsByLevel[Logger::EMERGENCY]);
  483. }
  484. public function hasAlertRecords()
  485. {
  486. return isset($this->recordsByLevel[Logger::ALERT]);
  487. }
  488. public function hasCriticalRecords()
  489. {
  490. return isset($this->recordsByLevel[Logger::CRITICAL]);
  491. }
  492. public function hasErrorRecords()
  493. {
  494. return isset($this->recordsByLevel[Logger::ERROR]);
  495. }
  496. public function hasWarningRecords()
  497. {
  498. return isset($this->recordsByLevel[Logger::WARNING]);
  499. }
  500. public function hasNoticeRecords()
  501. {
  502. return isset($this->recordsByLevel[Logger::NOTICE]);
  503. }
  504. public function hasInfoRecords()
  505. {
  506. return isset($this->recordsByLevel[Logger::INFO]);
  507. }
  508. public function hasDebugRecords()
  509. {
  510. return isset($this->recordsByLevel[Logger::DEBUG]);
  511. }
  512. protected function hasRecord($record, $level)
  513. {
  514. if (!isset($this->recordsByLevel[$level])) {
  515. return false;
  516. }
  517. if (is_array($record)) {
  518. $record = $record['message'];
  519. }
  520. foreach ($this->recordsByLevel[$level] as $rec) {
  521. if ($rec['message'] === $record) {
  522. return true;
  523. }
  524. }
  525. return false;
  526. }
  527. protected function write(array $record)
  528. {
  529. $this->recordsByLevel[$record['level']][] = $record;
  530. $this->records[] = $record;
  531. }
  532. }
  533. }
  534. namespace Psr\Log
  535. {
  536. interface LoggerInterface
  537. {
  538. public function emergency($message, array $context = array());
  539. public function alert($message, array $context = array());
  540. public function critical($message, array $context = array());
  541. public function error($message, array $context = array());
  542. public function warning($message, array $context = array());
  543. public function notice($message, array $context = array());
  544. public function info($message, array $context = array());
  545. public function debug($message, array $context = array());
  546. public function log($level, $message, array $context = array());
  547. }
  548. }
  549. namespace Monolog
  550. {
  551. use Monolog\Handler\HandlerInterface;
  552. use Monolog\Handler\StreamHandler;
  553. use Psr\Log\LoggerInterface;
  554. use Psr\Log\InvalidArgumentException;
  555. class Logger implements LoggerInterface
  556. {
  557. const DEBUG = 100;
  558. const INFO = 200;
  559. const NOTICE = 250;
  560. const WARNING = 300;
  561. const ERROR = 400;
  562. const CRITICAL = 500;
  563. const ALERT = 550;
  564. const EMERGENCY = 600;
  565. const API = 1;
  566. protected static $levels = array(
  567. 100 =>'DEBUG',
  568. 200 =>'INFO',
  569. 250 =>'NOTICE',
  570. 300 =>'WARNING',
  571. 400 =>'ERROR',
  572. 500 =>'CRITICAL',
  573. 550 =>'ALERT',
  574. 600 =>'EMERGENCY',
  575. );
  576. protected static $timezone;
  577. protected $name;
  578. protected $handlers;
  579. protected $processors;
  580. public function __construct($name, array $handlers = array(), array $processors = array())
  581. {
  582. $this->name = $name;
  583. $this->handlers = $handlers;
  584. $this->processors = $processors;
  585. }
  586. public function getName()
  587. {
  588. return $this->name;
  589. }
  590. public function pushHandler(HandlerInterface $handler)
  591. {
  592. array_unshift($this->handlers, $handler);
  593. }
  594. public function popHandler()
  595. {
  596. if (!$this->handlers) {
  597. throw new \LogicException('You tried to pop from an empty handler stack.');
  598. }
  599. return array_shift($this->handlers);
  600. }
  601. public function pushProcessor($callback)
  602. {
  603. if (!is_callable($callback)) {
  604. throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given');
  605. }
  606. array_unshift($this->processors, $callback);
  607. }
  608. public function popProcessor()
  609. {
  610. if (!$this->processors) {
  611. throw new \LogicException('You tried to pop from an empty processor stack.');
  612. }
  613. return array_shift($this->processors);
  614. }
  615. public function addRecord($level, $message, array $context = array())
  616. {
  617. if (!$this->handlers) {
  618. $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG));
  619. }
  620. if (!static::$timezone) {
  621. static::$timezone = new \DateTimeZone(date_default_timezone_get() ?:'UTC');
  622. }
  623. $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(),
  624. );
  625. $handlerKey = null;
  626. foreach ($this->handlers as $key => $handler) {
  627. if ($handler->isHandling($record)) {
  628. $handlerKey = $key;
  629. break;
  630. }
  631. }
  632. if (null === $handlerKey) {
  633. return false;
  634. }
  635. foreach ($this->processors as $processor) {
  636. $record = call_user_func($processor, $record);
  637. }
  638. while (isset($this->handlers[$handlerKey]) &&
  639. false === $this->handlers[$handlerKey]->handle($record)) {
  640. $handlerKey++;
  641. }
  642. return true;
  643. }
  644. public function addDebug($message, array $context = array())
  645. {
  646. return $this->addRecord(static::DEBUG, $message, $context);
  647. }
  648. public function addInfo($message, array $context = array())
  649. {
  650. return $this->addRecord(static::INFO, $message, $context);
  651. }
  652. public function addNotice($message, array $context = array())
  653. {
  654. return $this->addRecord(static::NOTICE, $message, $context);
  655. }
  656. public function addWarning($message, array $context = array())
  657. {
  658. return $this->addRecord(static::WARNING, $message, $context);
  659. }
  660. public function addError($message, array $context = array())
  661. {
  662. return $this->addRecord(static::ERROR, $message, $context);
  663. }
  664. public function addCritical($message, array $context = array())
  665. {
  666. return $this->addRecord(static::CRITICAL, $message, $context);
  667. }
  668. public function addAlert($message, array $context = array())
  669. {
  670. return $this->addRecord(static::ALERT, $message, $context);
  671. }
  672. public function addEmergency($message, array $context = array())
  673. {
  674. return $this->addRecord(static::EMERGENCY, $message, $context);
  675. }
  676. public static function getLevels()
  677. {
  678. return array_flip(static::$levels);
  679. }
  680. public static function getLevelName($level)
  681. {
  682. if (!isset(static::$levels[$level])) {
  683. throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
  684. }
  685. return static::$levels[$level];
  686. }
  687. public function isHandling($level)
  688. {
  689. $record = array('level'=> $level,
  690. );
  691. foreach ($this->handlers as $handler) {
  692. if ($handler->isHandling($record)) {
  693. return true;
  694. }
  695. }
  696. return false;
  697. }
  698. public function log($level, $message, array $context = array())
  699. {
  700. if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) {
  701. $level = constant(__CLASS__.'::'.strtoupper($level));
  702. }
  703. return $this->addRecord($level, $message, $context);
  704. }
  705. public function debug($message, array $context = array())
  706. {
  707. return $this->addRecord(static::DEBUG, $message, $context);
  708. }
  709. public function info($message, array $context = array())
  710. {
  711. return $this->addRecord(static::INFO, $message, $context);
  712. }
  713. public function notice($message, array $context = array())
  714. {
  715. return $this->addRecord(static::NOTICE, $message, $context);
  716. }
  717. public function warn($message, array $context = array())
  718. {
  719. return $this->addRecord(static::WARNING, $message, $context);
  720. }
  721. public function warning($message, array $context = array())
  722. {
  723. return $this->addRecord(static::WARNING, $message, $context);
  724. }
  725. public function err($message, array $context = array())
  726. {
  727. return $this->addRecord(static::ERROR, $message, $context);
  728. }
  729. public function error($message, array $context = array())
  730. {
  731. return $this->addRecord(static::ERROR, $message, $context);
  732. }
  733. public function crit($message, array $context = array())
  734. {
  735. return $this->addRecord(static::CRITICAL, $message, $context);
  736. }
  737. public function critical($message, array $context = array())
  738. {
  739. return $this->addRecord(static::CRITICAL, $message, $context);
  740. }
  741. public function alert($message, array $context = array())
  742. {
  743. return $this->addRecord(static::ALERT, $message, $context);
  744. }
  745. public function emerg($message, array $context = array())
  746. {
  747. return $this->addRecord(static::EMERGENCY, $message, $context);
  748. }
  749. public function emergency($message, array $context = array())
  750. {
  751. return $this->addRecord(static::EMERGENCY, $message, $context);
  752. }
  753. }
  754. }
  755. namespace Sensio\Bundle\FrameworkExtraBundle\Configuration
  756. {
  757. interface ConfigurationInterface
  758. {
  759. public function getAliasName();
  760. public function allowArray();
  761. }
  762. }
  763. namespace Sensio\Bundle\FrameworkExtraBundle\Configuration
  764. {
  765. abstract class ConfigurationAnnotation implements ConfigurationInterface
  766. {
  767. public function __construct(array $values)
  768. {
  769. foreach ($values as $k => $v) {
  770. if (!method_exists($this, $name ='set'.$k)) {
  771. throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, get_class($this)));
  772. }
  773. $this->$name($v);
  774. }
  775. }
  776. }
  777. }
  778. namespace Symfony\Component\EventDispatcher
  779. {
  780. interface EventSubscriberInterface
  781. {
  782. public static function getSubscribedEvents();
  783. }
  784. }
  785. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener
  786. {
  787. use Doctrine\Common\Annotations\Reader;
  788. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  789. use Symfony\Component\HttpKernel\KernelEvents;
  790. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  791. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface;
  792. use Doctrine\Common\Util\ClassUtils;
  793. class ControllerListener implements EventSubscriberInterface
  794. {
  795. protected $reader;
  796. public function __construct(Reader $reader)
  797. {
  798. $this->reader = $reader;
  799. }
  800. public function onKernelController(FilterControllerEvent $event)
  801. {
  802. if (!is_array($controller = $event->getController())) {
  803. return;
  804. }
  805. $className = class_exists('Doctrine\Common\Util\ClassUtils') ? ClassUtils::getClass($controller[0]) : get_class($controller[0]);
  806. $object = new \ReflectionClass($className);
  807. $method = $object->getMethod($controller[1]);
  808. $classConfigurations = $this->getConfigurations($this->reader->getClassAnnotations($object));
  809. $methodConfigurations = $this->getConfigurations($this->reader->getMethodAnnotations($method));
  810. $configurations = array();
  811. foreach (array_merge(array_keys($classConfigurations), array_keys($methodConfigurations)) as $key) {
  812. if (!array_key_exists($key, $classConfigurations)) {
  813. $configurations[$key] = $methodConfigurations[$key];
  814. } elseif (!array_key_exists($key, $methodConfigurations)) {
  815. $configurations[$key] = $classConfigurations[$key];
  816. } else {
  817. if (is_array($classConfigurations[$key])) {
  818. if (!is_array($methodConfigurations[$key])) {
  819. throw new \UnexpectedValueException('Configurations should both be an array or both not be an array');
  820. }
  821. $configurations[$key] = array_merge($classConfigurations[$key], $methodConfigurations[$key]);
  822. } else {
  823. $configurations[$key] = $methodConfigurations[$key];
  824. }
  825. }
  826. }
  827. $request = $event->getRequest();
  828. foreach ($configurations as $key => $attributes) {
  829. $request->attributes->set($key, $attributes);
  830. }
  831. }
  832. protected function getConfigurations(array $annotations)
  833. {
  834. $configurations = array();
  835. foreach ($annotations as $configuration) {
  836. if ($configuration instanceof ConfigurationInterface) {
  837. if ($configuration->allowArray()) {
  838. $configurations['_'.$configuration->getAliasName()][] = $configuration;
  839. } else {
  840. $configurations['_'.$configuration->getAliasName()] = $configuration;
  841. }
  842. }
  843. }
  844. return $configurations;
  845. }
  846. public static function getSubscribedEvents()
  847. {
  848. return array(
  849. KernelEvents::CONTROLLER =>'onKernelController',
  850. );
  851. }
  852. }
  853. }
  854. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener
  855. {
  856. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  857. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  858. use Symfony\Component\HttpKernel\KernelEvents;
  859. use Symfony\Component\HttpFoundation\Response;
  860. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  861. use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
  862. class HttpCacheListener implements EventSubscriberInterface
  863. {
  864. private $lastModifiedDates;
  865. private $etags;
  866. private $expressionLanguage;
  867. public function __construct()
  868. {
  869. $this->lastModifiedDates = new \SplObjectStorage();
  870. $this->etags = new \SplObjectStorage();
  871. }
  872. public function onKernelController(FilterControllerEvent $event)
  873. {
  874. $request = $event->getRequest();
  875. if (!$configuration = $request->attributes->get('_cache')) {
  876. return;
  877. }
  878. $response = new Response();
  879. $lastModifiedDate ='';
  880. if ($configuration->getLastModified()) {
  881. $lastModifiedDate = $this->getExpressionLanguage()->evaluate($configuration->getLastModified(), $request->attributes->all());
  882. $response->setLastModified($lastModifiedDate);
  883. }
  884. $etag ='';
  885. if ($configuration->getETag()) {
  886. $etag = hash('sha256', $this->getExpressionLanguage()->evaluate($configuration->getETag(), $request->attributes->all()));
  887. $response->setETag($etag);
  888. }
  889. if ($response->isNotModified($request)) {
  890. $event->setController(function () use ($response) {
  891. return $response;
  892. });
  893. } else {
  894. if ($etag) {
  895. $this->etags[$request] = $etag;
  896. }
  897. if ($lastModifiedDate) {
  898. $this->lastModifiedDates[$request] = $lastModifiedDate;
  899. }
  900. }
  901. }
  902. public function onKernelResponse(FilterResponseEvent $event)
  903. {
  904. $request = $event->getRequest();
  905. if (!$configuration = $request->attributes->get('_cache')) {
  906. return;
  907. }
  908. $response = $event->getResponse();
  909. if (!$response->isSuccessful()) {
  910. return;
  911. }
  912. if (null !== $configuration->getSMaxAge()) {
  913. $response->setSharedMaxAge($configuration->getSMaxAge());
  914. }
  915. if (null !== $configuration->getMaxAge()) {
  916. $response->setMaxAge($configuration->getMaxAge());
  917. }
  918. if (null !== $configuration->getExpires()) {
  919. $date = \DateTime::createFromFormat('U', strtotime($configuration->getExpires()), new \DateTimeZone('UTC'));
  920. $response->setExpires($date);
  921. }
  922. if (null !== $configuration->getVary()) {
  923. $response->setVary($configuration->getVary());
  924. }
  925. if ($configuration->isPublic()) {
  926. $response->setPublic();
  927. }
  928. if (isset($this->lastModifiedDates[$request])) {
  929. $response->setLastModified($this->lastModifiedDates[$request]);
  930. unset($this->lastModifiedDates[$request]);
  931. }
  932. if (isset($this->etags[$request])) {
  933. $response->setETag($this->etags[$request]);
  934. unset($this->etags[$request]);
  935. }
  936. $event->setResponse($response);
  937. }
  938. public static function getSubscribedEvents()
  939. {
  940. return array(
  941. KernelEvents::CONTROLLER =>'onKernelController',
  942. KernelEvents::RESPONSE =>'onKernelResponse',
  943. );
  944. }
  945. private function getExpressionLanguage()
  946. {
  947. if (null === $this->expressionLanguage) {
  948. if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
  949. throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
  950. }
  951. $this->expressionLanguage = new ExpressionLanguage();
  952. }
  953. return $this->expressionLanguage;
  954. }
  955. }
  956. }
  957. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener
  958. {
  959. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  960. use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager;
  961. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  962. use Symfony\Component\HttpKernel\KernelEvents;
  963. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  964. class ParamConverterListener implements EventSubscriberInterface
  965. {
  966. protected $manager;
  967. public function __construct(ParamConverterManager $manager)
  968. {
  969. $this->manager = $manager;
  970. }
  971. public function onKernelController(FilterControllerEvent $event)
  972. {
  973. $controller = $event->getController();
  974. $request = $event->getRequest();
  975. $configurations = array();
  976. if ($configuration = $request->attributes->get('_converters')) {
  977. foreach (is_array($configuration) ? $configuration : array($configuration) as $configuration) {
  978. $configurations[$configuration->getName()] = $configuration;
  979. }
  980. }
  981. if (is_array($controller)) {
  982. $r = new \ReflectionMethod($controller[0], $controller[1]);
  983. } else {
  984. $r = new \ReflectionFunction($controller);
  985. }
  986. foreach ($r->getParameters() as $param) {
  987. if (!$param->getClass() || $param->getClass()->isInstance($request)) {
  988. continue;
  989. }
  990. $name = $param->getName();
  991. if (!isset($configurations[$name])) {
  992. $configuration = new ParamConverter(array());
  993. $configuration->setName($name);
  994. $configuration->setClass($param->getClass()->getName());
  995. $configurations[$name] = $configuration;
  996. } elseif (null === $configurations[$name]->getClass()) {
  997. $configurations[$name]->setClass($param->getClass()->getName());
  998. }
  999. $configurations[$name]->setIsOptional($param->isOptional());
  1000. }
  1001. $this->manager->apply($request, $configurations);
  1002. }
  1003. public static function getSubscribedEvents()
  1004. {
  1005. return array(
  1006. KernelEvents::CONTROLLER =>'onKernelController',
  1007. );
  1008. }
  1009. }
  1010. }
  1011. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener
  1012. {
  1013. use Sensio\Bundle\FrameworkExtraBundle\Security\ExpressionLanguage;
  1014. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  1015. use Symfony\Component\HttpKernel\KernelEvents;
  1016. use Symfony\Component\HttpFoundation\Request;
  1017. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  1018. use Symfony\Component\ExpressionLanguage\Expression;
  1019. use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
  1020. use Symfony\Component\Security\Core\SecurityContextInterface;
  1021. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  1022. use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
  1023. class SecurityListener implements EventSubscriberInterface
  1024. {
  1025. private $securityContext;
  1026. private $language;
  1027. private $trustResolver;
  1028. private $roleHierarchy;
  1029. public function __construct(SecurityContextInterface $securityContext = null, ExpressionLanguage $language = null, AuthenticationTrustResolverInterface $trustResolver = null, RoleHierarchyInterface $roleHierarchy = null)
  1030. {
  1031. $this->securityContext = $securityContext;
  1032. $this->language = $language;
  1033. $this->trustResolver = $trustResolver;
  1034. $this->roleHierarchy = $roleHierarchy;
  1035. }
  1036. public function onKernelController(FilterControllerEvent $event)
  1037. {
  1038. $request = $event->getRequest();
  1039. if (!$configuration = $request->attributes->get('_security')) {
  1040. return;
  1041. }
  1042. if (null === $this->securityContext || null === $this->trustResolver) {
  1043. throw new \LogicException('To use the @Security tag, you need to install the Symfony Security bundle.');
  1044. }
  1045. if (!$this->language->evaluate($configuration->getExpression(), $this->getVariables($request))) {
  1046. throw new AccessDeniedException(sprintf('Expression "%s" denied access.', $configuration->getExpression()));
  1047. }
  1048. }
  1049. private function getVariables(Request $request)
  1050. {
  1051. $token = $this->securityContext->getToken();
  1052. if (null !== $this->roleHierarchy) {
  1053. $roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
  1054. } else {
  1055. $roles = $token->getRoles();
  1056. }
  1057. $variables = array('token'=> $token,'user'=> $token->getUser(),'object'=> $request,'request'=> $request,'roles'=> array_map(function ($role) { return $role->getRole(); }, $roles),'trust_resolver'=> $this->trustResolver,'security_context'=> $this->securityContext,
  1058. );
  1059. return array_merge($request->attributes->all(), $variables);
  1060. }
  1061. public static function getSubscribedEvents()
  1062. {
  1063. return array(KernelEvents::CONTROLLER =>'onKernelController');
  1064. }
  1065. }
  1066. }
  1067. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener
  1068. {
  1069. use Symfony\Component\DependencyInjection\ContainerInterface;
  1070. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  1071. use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
  1072. use Symfony\Component\HttpKernel\KernelEvents;
  1073. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  1074. use Symfony\Component\HttpFoundation\StreamedResponse;
  1075. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  1076. class TemplateListener implements EventSubscriberInterface
  1077. {
  1078. protected $container;
  1079. public function __construct(ContainerInterface $container)
  1080. {
  1081. $this->container = $container;
  1082. }
  1083. public function onKernelController(FilterControllerEvent $event)
  1084. {
  1085. if (!is_array($controller = $event->getController())) {
  1086. return;
  1087. }
  1088. $request = $event->getRequest();
  1089. if (!$configuration = $request->attributes->get('_template')) {
  1090. return;
  1091. }
  1092. if (!$configuration->getTemplate()) {
  1093. $guesser = $this->container->get('sensio_framework_extra.view.guesser');
  1094. $configuration->setTemplate($guesser->guessTemplateName($controller, $request, $configuration->getEngine()));
  1095. }
  1096. $request->attributes->set('_template', $configuration->getTemplate());
  1097. $request->attributes->set('_template_vars', $configuration->getVars());
  1098. $request->attributes->set('_template_streamable', $configuration->isStreamable());
  1099. if (!$configuration->getVars()) {
  1100. $r = new \ReflectionObject($controller[0]);
  1101. $vars = array();
  1102. foreach ($r->getMethod($controller[1])->getParameters() as $param) {
  1103. $vars[] = $param->getName();
  1104. }
  1105. $request->attributes->set('_template_default_vars', $vars);
  1106. }
  1107. }
  1108. public function onKernelView(GetResponseForControllerResultEvent $event)
  1109. {
  1110. $request = $event->getRequest();
  1111. $parameters = $event->getControllerResult();
  1112. $templating = $this->container->get('templating');
  1113. if (null === $parameters) {
  1114. if (!$vars = $request->attributes->get('_template_vars')) {
  1115. if (!$vars = $request->attributes->get('_template_default_vars')) {
  1116. return;
  1117. }
  1118. }
  1119. $parameters = array();
  1120. foreach ($vars as $var) {
  1121. $parameters[$var] = $request->attributes->get($var);
  1122. }
  1123. }
  1124. if (!is_array($parameters)) {
  1125. return $parameters;
  1126. }
  1127. if (!$template = $request->attributes->get('_template')) {
  1128. return $parameters;
  1129. }
  1130. if (!$request->attributes->get('_template_streamable')) {
  1131. $event->setResponse($templating->renderResponse($template, $parameters));
  1132. } else {
  1133. $callback = function () use ($templating, $template, $parameters) {
  1134. return $templating->stream($template, $parameters);
  1135. };
  1136. $event->setResponse(new StreamedResponse($callback));
  1137. }
  1138. }
  1139. public static function getSubscribedEvents()
  1140. {
  1141. return array(
  1142. KernelEvents::CONTROLLER => array('onKernelController', -128),
  1143. KernelEvents::VIEW =>'onKernelView',
  1144. );
  1145. }
  1146. }
  1147. }
  1148. namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter
  1149. {
  1150. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  1151. use Symfony\Component\HttpFoundation\Request;
  1152. interface ParamConverterInterface
  1153. {
  1154. public function apply(Request $request, ParamConverter $configuration);
  1155. public function supports(ParamConverter $configuration);
  1156. }
  1157. }
  1158. namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter
  1159. {
  1160. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  1161. use Symfony\Component\HttpFoundation\Request;
  1162. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  1163. use DateTime;
  1164. class DateTimeParamConverter implements ParamConverterInterface
  1165. {
  1166. public function apply(Request $request, ParamConverter $configuration)
  1167. {
  1168. $param = $configuration->getName();
  1169. if (!$request->attributes->has($param)) {
  1170. return false;
  1171. }
  1172. $options = $configuration->getOptions();
  1173. $value = $request->attributes->get($param);
  1174. if (!$value && $configuration->isOptional()) {
  1175. return false;
  1176. }
  1177. $date = isset($options['format'])
  1178. ? DateTime::createFromFormat($options['format'], $value)
  1179. : new DateTime($value);
  1180. if (!$date) {
  1181. throw new NotFoundHttpException('Invalid date given.');
  1182. }
  1183. $request->attributes->set($param, $date);
  1184. return true;
  1185. }
  1186. public function supports(ParamConverter $configuration)
  1187. {
  1188. if (null === $configuration->getClass()) {
  1189. return false;
  1190. }
  1191. return"DateTime"=== $configuration->getClass();
  1192. }
  1193. }
  1194. }
  1195. namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter
  1196. {
  1197. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  1198. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  1199. use Symfony\Component\HttpFoundation\Request;
  1200. use Doctrine\Common\Persistence\ManagerRegistry;
  1201. use Doctrine\ORM\NoResultException;
  1202. class DoctrineParamConverter implements ParamConverterInterface
  1203. {
  1204. protected $registry;
  1205. public function __construct(ManagerRegistry $registry = null)
  1206. {
  1207. $this->registry = $registry;
  1208. }
  1209. public function apply(Request $request, ParamConverter $configuration)
  1210. {
  1211. $name = $configuration->getName();
  1212. $class = $configuration->getClass();
  1213. $options = $this->getOptions($configuration);
  1214. if (null === $request->attributes->get($name, false)) {
  1215. $configuration->setIsOptional(true);
  1216. }
  1217. if (false === $object = $this->find($class, $request, $options, $name)) {
  1218. if (false === $object = $this->findOneBy($class, $request, $options)) {
  1219. if ($configuration->isOptional()) {
  1220. $object = null;
  1221. } else {
  1222. throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.');
  1223. }
  1224. }
  1225. }
  1226. if (null === $object && false === $configuration->isOptional()) {
  1227. throw new NotFoundHttpException(sprintf('%s object not found.', $class));
  1228. }
  1229. $request->attributes->set($name, $object);
  1230. return true;
  1231. }
  1232. protected function find($class, Request $request, $options, $name)
  1233. {
  1234. if ($options['mapping'] || $options['exclude']) {
  1235. return false;
  1236. }
  1237. $id = $this->getIdentifier($request, $options, $name);
  1238. if (false === $id || null === $id) {
  1239. return false;
  1240. }
  1241. if (isset($options['repository_method'])) {
  1242. $method = $options['repository_method'];
  1243. } else {
  1244. $method ='find';
  1245. }
  1246. try {
  1247. return $this->getManager($options['entity_manager'], $class)->getRepository($class)->$method($id);
  1248. } catch (NoResultException $e) {
  1249. return null;
  1250. }
  1251. }
  1252. protected function getIdentifier(Request $request, $options, $name)
  1253. {
  1254. if (isset($options['id'])) {
  1255. if (!is_array($options['id'])) {
  1256. $name = $options['id'];
  1257. } elseif (is_array($options['id'])) {
  1258. $id = array();
  1259. foreach ($options['id'] as $field) {
  1260. $id[$field] = $request->attributes->get($field);
  1261. }
  1262. return $id;
  1263. }
  1264. }
  1265. if ($request->attributes->has($name)) {
  1266. return $request->attributes->get($name);
  1267. }
  1268. if ($request->attributes->has('id')) {
  1269. return $request->attributes->get('id');
  1270. }
  1271. return false;
  1272. }
  1273. protected function findOneBy($class, Request $request, $options)
  1274. {
  1275. if (!$options['mapping']) {
  1276. $keys = $request->attributes->keys();
  1277. $options['mapping'] = $keys ? array_combine($keys, $keys) : array();
  1278. }
  1279. foreach ($options['exclude'] as $exclude) {
  1280. unset($options['mapping'][$exclude]);
  1281. }
  1282. if (!$options['mapping']) {
  1283. return false;
  1284. }
  1285. $criteria = array();
  1286. $em = $this->getManager($options['entity_manager'], $class);
  1287. $metadata = $em->getClassMetadata($class);
  1288. foreach ($options['mapping'] as $attribute => $field) {
  1289. if ($metadata->hasField($field) || ($metadata->hasAssociation($field) && $metadata->isSingleValuedAssociation($field))) {
  1290. $criteria[$field] = $request->attributes->get($attribute);
  1291. }
  1292. }
  1293. if ($options['strip_null']) {
  1294. $criteria = array_filter($criteria, function ($value) { return !is_null($value); });
  1295. }
  1296. if (!$criteria) {
  1297. return false;
  1298. }
  1299. if (isset($options['repository_method'])) {
  1300. $method = $options['repository_method'];
  1301. } else {
  1302. $method ='findOneBy';
  1303. }
  1304. try {
  1305. return $em->getRepository($class)->$method($criteria);
  1306. } catch (NoResultException $e) {
  1307. return null;
  1308. }
  1309. }
  1310. public function supports(ParamConverter $configuration)
  1311. {
  1312. if (null === $this->registry || !count($this->registry->getManagers())) {
  1313. return false;
  1314. }
  1315. if (null === $configuration->getClass()) {
  1316. return false;
  1317. }
  1318. $options = $this->getOptions($configuration);
  1319. $em = $this->getManager($options['entity_manager'], $configuration->getClass());
  1320. if (null === $em) {
  1321. return false;
  1322. }
  1323. return ! $em->getMetadataFactory()->isTransient($configuration->getClass());
  1324. }
  1325. protected function getOptions(ParamConverter $configuration)
  1326. {
  1327. return array_replace(array('entity_manager'=> null,'exclude'=> array(),'mapping'=> array(),'strip_null'=> false,
  1328. ), $configuration->getOptions());
  1329. }
  1330. private function getManager($name, $class)
  1331. {
  1332. if (null === $name) {
  1333. return $this->registry->getManagerForClass($class);
  1334. }
  1335. return $this->registry->getManager($name);
  1336. }
  1337. }
  1338. }
  1339. namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter
  1340. {
  1341. use Symfony\Component\HttpFoundation\Request;
  1342. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface;
  1343. class ParamConverterManager
  1344. {
  1345. protected $converters = array();
  1346. protected $namedConverters = array();
  1347. public function apply(Request $request, $configurations)
  1348. {
  1349. if (is_object($configurations)) {
  1350. $configurations = array($configurations);
  1351. }
  1352. foreach ($configurations as $configuration) {
  1353. $this->applyConverter($request, $configuration);
  1354. }
  1355. }
  1356. protected function applyConverter(Request $request, ConfigurationInterface $configuration)
  1357. {
  1358. $value = $request->attributes->get($configuration->getName());
  1359. $className = $configuration->getClass();
  1360. if (is_object($value) && $value instanceof $className) {
  1361. return;
  1362. }
  1363. if ($converterName = $configuration->getConverter()) {
  1364. if (!isset($this->namedConverters[$converterName])) {
  1365. throw new \RuntimeException(sprintf("No converter named '%s' found for conversion of parameter '%s'.",
  1366. $converterName, $configuration->getName()
  1367. ));
  1368. }
  1369. $converter = $this->namedConverters[$converterName];
  1370. if (!$converter->supports($configuration)) {
  1371. throw new \RuntimeException(sprintf("Converter '%s' does not support conversion of parameter '%s'.",
  1372. $converterName, $configuration->getName()
  1373. ));
  1374. }
  1375. $converter->apply($request, $configuration);
  1376. return;
  1377. }
  1378. foreach ($this->all() as $converter) {
  1379. if ($converter->supports($configuration)) {
  1380. if ($converter->apply($request, $configuration)) {
  1381. return;
  1382. }
  1383. }
  1384. }
  1385. }
  1386. public function add(ParamConverterInterface $converter, $priority = 0, $name = null)
  1387. {
  1388. if ($priority !== null) {
  1389. if (!isset($this->converters[$priority])) {
  1390. $this->converters[$priority] = array();
  1391. }
  1392. $this->converters[$priority][] = $converter;
  1393. }
  1394. if (null !== $name) {
  1395. $this->namedConverters[$name] = $converter;
  1396. }
  1397. }
  1398. public function all()
  1399. {
  1400. krsort($this->converters);
  1401. $converters = array();
  1402. foreach ($this->converters as $all) {
  1403. $converters = array_merge($converters, $all);
  1404. }
  1405. return $converters;
  1406. }
  1407. }
  1408. }
  1409. namespace Symfony\Component\HttpKernel\Log
  1410. {
  1411. interface DebugLoggerInterface
  1412. {
  1413. public function getLogs();
  1414. public function countErrors();
  1415. }
  1416. }
  1417. namespace Symfony\Bridge\Monolog\Handler
  1418. {
  1419. use Monolog\Logger;
  1420. use Monolog\Handler\TestHandler;
  1421. use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
  1422. class DebugHandler extends TestHandler implements DebugLoggerInterface
  1423. {
  1424. public function getLogs()
  1425. {
  1426. $records = array();
  1427. foreach ($this->records as $record) {
  1428. $records[] = array('timestamp'=> $record['datetime']->getTimestamp(),'message'=> $record['message'],'priority'=> $record['level'],'priorityName'=> $record['level_name'],'context'=> $record['context'],
  1429. );
  1430. }
  1431. return $records;
  1432. }
  1433. public function countErrors()
  1434. {
  1435. $cnt = 0;
  1436. $levels = array(Logger::ERROR, Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY);
  1437. foreach ($levels as $level) {
  1438. if (isset($this->recordsByLevel[$level])) {
  1439. $cnt += count($this->recordsByLevel[$level]);
  1440. }
  1441. }
  1442. return $cnt;
  1443. }
  1444. }
  1445. }
  1446. namespace Symfony\Component\HttpKernel\Log
  1447. {
  1448. use Psr\Log\LoggerInterface as PsrLogger;
  1449. interface LoggerInterface extends PsrLogger
  1450. {
  1451. public function emerg($message, array $context = array());
  1452. public function crit($message, array $context = array());
  1453. public function err($message, array $context = array());
  1454. public function warn($message, array $context = array());
  1455. }
  1456. }
  1457. namespace Symfony\Bridge\Monolog
  1458. {
  1459. use Monolog\Logger as BaseLogger;
  1460. use Symfony\Component\HttpKernel\Log\LoggerInterface;
  1461. use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
  1462. class Logger extends BaseLogger implements LoggerInterface, DebugLoggerInterface
  1463. {
  1464. public function emerg($message, array $context = array())
  1465. {
  1466. return parent::addRecord(BaseLogger::EMERGENCY, $message, $context);
  1467. }
  1468. public function crit($message, array $context = array())
  1469. {
  1470. return parent::addRecord(BaseLogger::CRITICAL, $message, $context);
  1471. }
  1472. public function err($message, array $context = array())
  1473. {
  1474. return parent::addRecord(BaseLogger::ERROR, $message, $context);
  1475. }
  1476. public function warn($message, array $context = array())
  1477. {
  1478. return parent::addRecord(BaseLogger::WARNING, $message, $context);
  1479. }
  1480. public function getLogs()
  1481. {
  1482. if ($logger = $this->getDebugLogger()) {
  1483. return $logger->getLogs();
  1484. }
  1485. return array();
  1486. }
  1487. public function countErrors()
  1488. {
  1489. if ($logger = $this->getDebugLogger()) {
  1490. return $logger->countErrors();
  1491. }
  1492. return 0;
  1493. }
  1494. private function getDebugLogger()
  1495. {
  1496. foreach ($this->handlers as $handler) {
  1497. if ($handler instanceof DebugLoggerInterface) {
  1498. return $handler;
  1499. }
  1500. }
  1501. }
  1502. }
  1503. }
  1504. namespace Assetic
  1505. {
  1506. interface ValueSupplierInterface
  1507. {
  1508. public function getValues();
  1509. }
  1510. }
  1511. namespace Symfony\Bundle\AsseticBundle
  1512. {
  1513. use Assetic\ValueSupplierInterface;
  1514. use Symfony\Component\DependencyInjection\ContainerInterface;
  1515. class DefaultValueSupplier implements ValueSupplierInterface
  1516. {
  1517. protected $container;
  1518. public function __construct(ContainerInterface $container)
  1519. {
  1520. $this->container = $container;
  1521. }
  1522. public function getValues()
  1523. {
  1524. if (!$this->container->isScopeActive('request')) {
  1525. return array();
  1526. }
  1527. $request = $this->container->get('request');
  1528. return array('locale'=> $request->getLocale(),'env'=> $this->container->getParameter('kernel.environment'),
  1529. );
  1530. }
  1531. }
  1532. }
  1533. namespace Assetic\Factory
  1534. {
  1535. use Assetic\Asset\AssetCollection;
  1536. use Assetic\Asset\AssetCollectionInterface;
  1537. use Assetic\Asset\AssetInterface;
  1538. use Assetic\Asset\AssetReference;
  1539. use Assetic\Asset\FileAsset;
  1540. use Assetic\Asset\GlobAsset;
  1541. use Assetic\Asset\HttpAsset;
  1542. use Assetic\AssetManager;
  1543. use Assetic\Factory\Worker\WorkerInterface;
  1544. use Assetic\FilterManager;
  1545. class AssetFactory
  1546. {
  1547. private $root;
  1548. private $debug;
  1549. private $output;
  1550. private $workers;
  1551. private $am;
  1552. private $fm;
  1553. public function __construct($root, $debug = false)
  1554. {
  1555. $this->root = rtrim($root,'/');
  1556. $this->debug = $debug;
  1557. $this->output ='assetic/*';
  1558. $this->workers = array();
  1559. }
  1560. public function setDebug($debug)
  1561. {
  1562. $this->debug = $debug;
  1563. }
  1564. public function isDebug()
  1565. {
  1566. return $this->debug;
  1567. }
  1568. public function setDefaultOutput($output)
  1569. {
  1570. $this->output = $output;
  1571. }
  1572. public function addWorker(WorkerInterface $worker)
  1573. {
  1574. $this->workers[] = $worker;
  1575. }
  1576. public function getAssetManager()
  1577. {
  1578. return $this->am;
  1579. }
  1580. public function setAssetManager(AssetManager $am)
  1581. {
  1582. $this->am = $am;
  1583. }
  1584. public function getFilterManager()
  1585. {
  1586. return $this->fm;
  1587. }
  1588. public function setFilterManager(FilterManager $fm)
  1589. {
  1590. $this->fm = $fm;
  1591. }
  1592. public function createAsset($inputs = array(), $filters = array(), array $options = array())
  1593. {
  1594. if (!is_array($inputs)) {
  1595. $inputs = array($inputs);
  1596. }
  1597. if (!is_array($filters)) {
  1598. $filters = array($filters);
  1599. }
  1600. if (!isset($options['output'])) {
  1601. $options['output'] = $this->output;
  1602. }
  1603. if (!isset($options['vars'])) {
  1604. $options['vars'] = array();
  1605. }
  1606. if (!isset($options['debug'])) {
  1607. $options['debug'] = $this->debug;
  1608. }
  1609. if (!isset($options['root'])) {
  1610. $options['root'] = array($this->root);
  1611. } else {
  1612. if (!is_array($options['root'])) {
  1613. $options['root'] = array($options['root']);
  1614. }
  1615. $options['root'][] = $this->root;
  1616. }
  1617. if (!isset($options['name'])) {
  1618. $options['name'] = $this->generateAssetName($inputs, $filters, $options);
  1619. }
  1620. $asset = $this->createAssetCollection(array(), $options);
  1621. $extensions = array();
  1622. foreach ($inputs as $input) {
  1623. if (is_array($input)) {
  1624. $asset->add(call_user_func_array(array($this,'createAsset'), $input));
  1625. } else {
  1626. $asset->add($this->parseInput($input, $options));
  1627. $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true;
  1628. }
  1629. }
  1630. foreach ($filters as $filter) {
  1631. if ('?'!= $filter[0]) {
  1632. $asset->ensureFilter($this->getFilter($filter));
  1633. } elseif (!$options['debug']) {
  1634. $asset->ensureFilter($this->getFilter(substr($filter, 1)));
  1635. }
  1636. }
  1637. if (!empty($options['vars'])) {
  1638. $toAdd = array();
  1639. foreach ($options['vars'] as $var) {
  1640. if (false !== strpos($options['output'],'{'.$var.'}')) {
  1641. continue;
  1642. }
  1643. $toAdd[] ='{'.$var.'}';
  1644. }
  1645. if ($toAdd) {
  1646. $options['output'] = str_replace('*','*.'.implode('.', $toAdd), $options['output']);
  1647. }
  1648. }
  1649. if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) {
  1650. $options['output'] .='.'.$extension;
  1651. }
  1652. $asset->setTargetPath(str_replace('*', $options['name'], $options['output']));
  1653. return $this->applyWorkers($asset);
  1654. }
  1655. public function generateAssetName($inputs, $filters, $options = array())
  1656. {
  1657. foreach (array_diff(array_keys($options), array('output','debug','root')) as $key) {
  1658. unset($options[$key]);
  1659. }
  1660. ksort($options);
  1661. return substr(sha1(serialize($inputs).serialize($filters).serialize($options)), 0, 7);
  1662. }
  1663. protected function parseInput($input, array $options = array())
  1664. {
  1665. if ('@'== $input[0]) {
  1666. return $this->createAssetReference(substr($input, 1));
  1667. }
  1668. if (false !== strpos($input,'://') || 0 === strpos($input,'//')) {
  1669. return $this->createHttpAsset($input, $options['vars']);
  1670. }
  1671. if (self::isAbsolutePath($input)) {
  1672. if ($root = self::findRootDir($input, $options['root'])) {
  1673. $path = ltrim(substr($input, strlen($root)),'/');
  1674. } else {
  1675. $path = null;
  1676. }
  1677. } else {
  1678. $root = $this->root;
  1679. $path = $input;
  1680. $input = $this->root.'/'.$path;
  1681. }
  1682. if (false !== strpos($input,'*')) {
  1683. return $this->createGlobAsset($input, $root, $options['vars']);
  1684. }
  1685. return $this->createFileAsset($input, $root, $path, $options['vars']);
  1686. }
  1687. protected function createAssetCollection(array $assets = array(), array $options = array())
  1688. {
  1689. return new AssetCollection($assets, array(), null, isset($options['vars']) ? $options['vars'] : array());
  1690. }
  1691. protected function createAssetReference($name)
  1692. {
  1693. if (!$this->am) {
  1694. throw new \LogicException('There is no asset manager.');
  1695. }
  1696. return new AssetReference($this->am, $name);
  1697. }
  1698. protected function createHttpAsset($sourceUrl, $vars)
  1699. {
  1700. return new HttpAsset($sourceUrl, array(), false, $vars);
  1701. }
  1702. protected function createGlobAsset($glob, $root = null, $vars)
  1703. {
  1704. return new GlobAsset($glob, array(), $root, $vars);
  1705. }
  1706. protected function createFileAsset($source, $root = null, $path = null, $vars)
  1707. {
  1708. return new FileAsset($source, array(), $root, $path, $vars);
  1709. }
  1710. protected function getFilter($name)
  1711. {
  1712. if (!$this->fm) {
  1713. throw new \LogicException('There is no filter manager.');
  1714. }
  1715. return $this->fm->get($name);
  1716. }
  1717. private function applyWorkers(AssetCollectionInterface $asset)
  1718. {
  1719. foreach ($asset as $leaf) {
  1720. foreach ($this->workers as $worker) {
  1721. $retval = $worker->process($leaf);
  1722. if ($retval instanceof AssetInterface && $leaf !== $retval) {
  1723. $asset->replaceLeaf($leaf, $retval);
  1724. }
  1725. }
  1726. }
  1727. foreach ($this->workers as $worker) {
  1728. $retval = $worker->process($asset);
  1729. if ($retval instanceof AssetInterface) {
  1730. $asset = $retval;
  1731. }
  1732. }
  1733. return $asset instanceof AssetCollectionInterface ? $asset : $this->createAssetCollection(array($asset));
  1734. }
  1735. private static function isAbsolutePath($path)
  1736. {
  1737. return'/'== $path[0] ||'\\'== $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] ==':'&& ('\\'== $path[2] ||'/'== $path[2]));
  1738. }
  1739. private static function findRootDir($path, array $roots)
  1740. {
  1741. foreach ($roots as $root) {
  1742. if (0 === strpos($path, $root)) {
  1743. return $root;
  1744. }
  1745. }
  1746. }
  1747. }
  1748. }
  1749. namespace Symfony\Bundle\AsseticBundle\Factory
  1750. {
  1751. use Assetic\Factory\AssetFactory as BaseAssetFactory;
  1752. use Symfony\Component\DependencyInjection\ContainerInterface;
  1753. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  1754. use Symfony\Component\HttpKernel\KernelInterface;
  1755. class AssetFactory extends BaseAssetFactory
  1756. {
  1757. private $kernel;
  1758. private $container;
  1759. private $parameterBag;
  1760. public function __construct(KernelInterface $kernel, ContainerInterface $container, ParameterBagInterface $parameterBag, $baseDir, $debug = false)
  1761. {
  1762. $this->kernel = $kernel;
  1763. $this->container = $container;
  1764. $this->parameterBag = $parameterBag;
  1765. parent::__construct($baseDir, $debug);
  1766. }
  1767. protected function parseInput($input, array $options = array())
  1768. {
  1769. $input = $this->parameterBag->resolveValue($input);
  1770. if ('@'== $input[0] && false !== strpos($input,'/')) {
  1771. $bundle = substr($input, 1);
  1772. if (false !== $pos = strpos($bundle,'/')) {
  1773. $bundle = substr($bundle, 0, $pos);
  1774. }
  1775. $options['root'] = array($this->kernel->getBundle($bundle)->getPath());
  1776. if (false !== $pos = strpos($input,'*')) {
  1777. list($before, $after) = explode('*', $input, 2);
  1778. $input = $this->kernel->locateResource($before).'*'.$after;
  1779. } else {
  1780. $input = $this->kernel->locateResource($input);
  1781. }
  1782. }
  1783. return parent::parseInput($input, $options);
  1784. }
  1785. protected function createAssetReference($name)
  1786. {
  1787. if (!$this->getAssetManager()) {
  1788. $this->setAssetManager($this->container->get('assetic.asset_manager'));
  1789. }
  1790. return parent::createAssetReference($name);
  1791. }
  1792. protected function getFilter($name)
  1793. {
  1794. if (!$this->getFilterManager()) {
  1795. $this->setFilterManager($this->container->get('assetic.filter_manager'));
  1796. }
  1797. return parent::getFilter($name);
  1798. }
  1799. }
  1800. }
  1801. namespace Symfony\Bundle\FrameworkBundle\Controller
  1802. {
  1803. use Symfony\Component\HttpKernel\KernelInterface;
  1804. class ControllerNameParser
  1805. {
  1806. protected $kernel;
  1807. public function __construct(KernelInterface $kernel)
  1808. {
  1809. $this->kernel = $kernel;
  1810. }
  1811. public function parse($controller)
  1812. {
  1813. if (3 != count($parts = explode(':', $controller))) {
  1814. throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "a:b:c" controller string.', $controller));
  1815. }
  1816. list($bundle, $controller, $action) = $parts;
  1817. $controller = str_replace('/','\\', $controller);
  1818. $bundles = array();
  1819. foreach ($this->kernel->getBundle($bundle, false) as $b) {
  1820. $try = $b->getNamespace().'\\Controller\\'.$controller.'Controller';
  1821. if (class_exists($try)) {
  1822. return $try.'::'.$action.'Action';
  1823. }
  1824. $bundles[] = $b->getName();
  1825. $msg = sprintf('Unable to find controller "%s:%s" - class "%s" does not exist.', $bundle, $controller, $try);
  1826. }
  1827. if (count($bundles) > 1) {
  1828. $msg = sprintf('Unable to find controller "%s:%s" in bundles %s.', $bundle, $controller, implode(', ', $bundles));
  1829. }
  1830. throw new \InvalidArgumentException($msg);
  1831. }
  1832. public function build($controller)
  1833. {
  1834. if (0 === preg_match('#^(.*?\\\\Controller\\\\(.+)Controller)::(.+)Action$#', $controller, $match)) {
  1835. throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "class::method" string.', $controller));
  1836. }
  1837. $className = $match[1];
  1838. $controllerName = $match[2];
  1839. $actionName = $match[3];
  1840. foreach ($this->kernel->getBundles() as $name => $bundle) {
  1841. if (0 !== strpos($className, $bundle->getNamespace())) {
  1842. continue;
  1843. }
  1844. return sprintf('%s:%s:%s', $name, $controllerName, $actionName);
  1845. }
  1846. throw new \InvalidArgumentException(sprintf('Unable to find a bundle that defines controller "%s".', $controller));
  1847. }
  1848. }
  1849. }
  1850. namespace Symfony\Component\HttpKernel\Controller
  1851. {
  1852. use Symfony\Component\HttpFoundation\Request;
  1853. interface ControllerResolverInterface
  1854. {
  1855. public function getController(Request $request);
  1856. public function getArguments(Request $request, $controller);
  1857. }
  1858. }
  1859. namespace Symfony\Component\HttpKernel\Controller
  1860. {
  1861. use Psr\Log\LoggerInterface;
  1862. use Symfony\Component\HttpFoundation\Request;
  1863. class ControllerResolver implements ControllerResolverInterface
  1864. {
  1865. private $logger;
  1866. public function __construct(LoggerInterface $logger = null)
  1867. {
  1868. $this->logger = $logger;
  1869. }
  1870. public function getController(Request $request)
  1871. {
  1872. if (!$controller = $request->attributes->get('_controller')) {
  1873. if (null !== $this->logger) {
  1874. $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing');
  1875. }
  1876. return false;
  1877. }
  1878. if (is_array($controller)) {
  1879. return $controller;
  1880. }
  1881. if (is_object($controller)) {
  1882. if (method_exists($controller,'__invoke')) {
  1883. return $controller;
  1884. }
  1885. throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', get_class($controller), $request->getPathInfo()));
  1886. }
  1887. if (false === strpos($controller,':')) {
  1888. if (method_exists($controller,'__invoke')) {
  1889. return new $controller();
  1890. } elseif (function_exists($controller)) {
  1891. return $controller;
  1892. }
  1893. }
  1894. $callable = $this->createController($controller);
  1895. if (!is_callable($callable)) {
  1896. throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', $controller, $request->getPathInfo()));
  1897. }
  1898. return $callable;
  1899. }
  1900. public function getArguments(Request $request, $controller)
  1901. {
  1902. if (is_array($controller)) {
  1903. $r = new \ReflectionMethod($controller[0], $controller[1]);
  1904. } elseif (is_object($controller) && !$controller instanceof \Closure) {
  1905. $r = new \ReflectionObject($controller);
  1906. $r = $r->getMethod('__invoke');
  1907. } else {
  1908. $r = new \ReflectionFunction($controller);
  1909. }
  1910. return $this->doGetArguments($request, $controller, $r->getParameters());
  1911. }
  1912. protected function doGetArguments(Request $request, $controller, array $parameters)
  1913. {
  1914. $attributes = $request->attributes->all();
  1915. $arguments = array();
  1916. foreach ($parameters as $param) {
  1917. if (array_key_exists($param->name, $attributes)) {
  1918. $arguments[] = $attributes[$param->name];
  1919. } elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
  1920. $arguments[] = $request;
  1921. } elseif ($param->isDefaultValueAvailable()) {
  1922. $arguments[] = $param->getDefaultValue();
  1923. } else {
  1924. if (is_array($controller)) {
  1925. $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
  1926. } elseif (is_object($controller)) {
  1927. $repr = get_class($controller);
  1928. } else {
  1929. $repr = $controller;
  1930. }
  1931. throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
  1932. }
  1933. }
  1934. return $arguments;
  1935. }
  1936. protected function createController($controller)
  1937. {
  1938. if (false === strpos($controller,'::')) {
  1939. throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller));
  1940. }
  1941. list($class, $method) = explode('::', $controller, 2);
  1942. if (!class_exists($class)) {
  1943. throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
  1944. }
  1945. return array(new $class(), $method);
  1946. }
  1947. }
  1948. }
  1949. namespace Symfony\Bundle\FrameworkBundle\Controller
  1950. {
  1951. use Psr\Log\LoggerInterface;
  1952. use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
  1953. use Symfony\Component\DependencyInjection\ContainerInterface;
  1954. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  1955. class ControllerResolver extends BaseControllerResolver
  1956. {
  1957. protected $container;
  1958. protected $parser;
  1959. public function __construct(ContainerInterface $container, ControllerNameParser $parser, LoggerInterface $logger = null)
  1960. {
  1961. $this->container = $container;
  1962. $this->parser = $parser;
  1963. parent::__construct($logger);
  1964. }
  1965. protected function createController($controller)
  1966. {
  1967. if (false === strpos($controller,'::')) {
  1968. $count = substr_count($controller,':');
  1969. if (2 == $count) {
  1970. $controller = $this->parser->parse($controller);
  1971. } elseif (1 == $count) {
  1972. list($service, $method) = explode(':', $controller, 2);
  1973. return array($this->container->get($service), $method);
  1974. } else {
  1975. throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller));
  1976. }
  1977. }
  1978. list($class, $method) = explode('::', $controller, 2);
  1979. if (!class_exists($class)) {
  1980. throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
  1981. }
  1982. $controller = new $class();
  1983. if ($controller instanceof ContainerAwareInterface) {
  1984. $controller->setContainer($this->container);
  1985. }
  1986. return array($controller, $method);
  1987. }
  1988. }
  1989. }
  1990. namespace Symfony\Component\HttpKernel\EventListener
  1991. {
  1992. use Symfony\Component\HttpKernel\HttpKernelInterface;
  1993. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  1994. use Symfony\Component\HttpKernel\KernelEvents;
  1995. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  1996. abstract class SessionListener implements EventSubscriberInterface
  1997. {
  1998. public function onKernelRequest(GetResponseEvent $event)
  1999. {
  2000. if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
  2001. return;
  2002. }
  2003. $request = $event->getRequest();
  2004. $session = $this->getSession();
  2005. if (null === $session || $request->hasSession()) {
  2006. return;
  2007. }
  2008. $request->setSession($session);
  2009. }
  2010. public static function getSubscribedEvents()
  2011. {
  2012. return array(
  2013. KernelEvents::REQUEST => array('onKernelRequest', 128),
  2014. );
  2015. }
  2016. abstract protected function getSession();
  2017. }
  2018. }
  2019. namespace Symfony\Bundle\FrameworkBundle\EventListener
  2020. {
  2021. use Symfony\Component\HttpKernel\EventListener\SessionListener as BaseSessionListener;
  2022. use Symfony\Component\DependencyInjection\ContainerInterface;
  2023. class SessionListener extends BaseSessionListener
  2024. {
  2025. private $container;
  2026. public function __construct(ContainerInterface $container)
  2027. {
  2028. $this->container = $container;
  2029. }
  2030. protected function getSession()
  2031. {
  2032. if (!$this->container->has('session')) {
  2033. return;
  2034. }
  2035. return $this->container->get('session');
  2036. }
  2037. }
  2038. }
  2039. namespace Symfony\Component\Routing\Matcher
  2040. {
  2041. interface RedirectableUrlMatcherInterface
  2042. {
  2043. public function redirect($path, $route, $scheme = null);
  2044. }
  2045. }
  2046. namespace Symfony\Component\Routing
  2047. {
  2048. interface RequestContextAwareInterface
  2049. {
  2050. public function setContext(RequestContext $context);
  2051. public function getContext();
  2052. }
  2053. }
  2054. namespace Symfony\Component\Routing\Matcher
  2055. {
  2056. use Symfony\Component\Routing\RequestContextAwareInterface;
  2057. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  2058. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  2059. interface UrlMatcherInterface extends RequestContextAwareInterface
  2060. {
  2061. public function match($pathinfo);
  2062. }
  2063. }
  2064. namespace Symfony\Component\Routing\Matcher
  2065. {
  2066. use Symfony\Component\HttpFoundation\Request;
  2067. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  2068. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  2069. interface RequestMatcherInterface
  2070. {
  2071. public function matchRequest(Request $request);
  2072. }
  2073. }
  2074. namespace Symfony\Component\Routing\Matcher
  2075. {
  2076. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  2077. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  2078. use Symfony\Component\Routing\RouteCollection;
  2079. use Symfony\Component\Routing\RequestContext;
  2080. use Symfony\Component\Routing\Route;
  2081. use Symfony\Component\HttpFoundation\Request;
  2082. use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
  2083. class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
  2084. {
  2085. const REQUIREMENT_MATCH = 0;
  2086. const REQUIREMENT_MISMATCH = 1;
  2087. const ROUTE_MATCH = 2;
  2088. protected $context;
  2089. protected $allow = array();
  2090. protected $routes;
  2091. protected $request;
  2092. protected $expressionLanguage;
  2093. public function __construct(RouteCollection $routes, RequestContext $context)
  2094. {
  2095. $this->routes = $routes;
  2096. $this->context = $context;
  2097. }
  2098. public function setContext(RequestContext $context)
  2099. {
  2100. $this->context = $context;
  2101. }
  2102. public function getContext()
  2103. {
  2104. return $this->context;
  2105. }
  2106. public function match($pathinfo)
  2107. {
  2108. $this->allow = array();
  2109. if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
  2110. return $ret;
  2111. }
  2112. throw 0 < count($this->allow)
  2113. ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow)))
  2114. : new ResourceNotFoundException();
  2115. }
  2116. public function matchRequest(Request $request)
  2117. {
  2118. $this->request = $request;
  2119. $ret = $this->match($request->getPathInfo());
  2120. $this->request = null;
  2121. return $ret;
  2122. }
  2123. protected function matchCollection($pathinfo, RouteCollection $routes)
  2124. {
  2125. foreach ($routes as $name => $route) {
  2126. $compiledRoute = $route->compile();
  2127. if (''!== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
  2128. continue;
  2129. }
  2130. if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
  2131. continue;
  2132. }
  2133. $hostMatches = array();
  2134. if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
  2135. continue;
  2136. }
  2137. if ($req = $route->getRequirement('_method')) {
  2138. if ('HEAD'=== $method = $this->context->getMethod()) {
  2139. $method ='GET';
  2140. }
  2141. if (!in_array($method, $req = explode('|', strtoupper($req)))) {
  2142. $this->allow = array_merge($this->allow, $req);
  2143. continue;
  2144. }
  2145. }
  2146. $status = $this->handleRouteRequirements($pathinfo, $name, $route);
  2147. if (self::ROUTE_MATCH === $status[0]) {
  2148. return $status[1];
  2149. }
  2150. if (self::REQUIREMENT_MISMATCH === $status[0]) {
  2151. continue;
  2152. }
  2153. return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
  2154. }
  2155. }
  2156. protected function getAttributes(Route $route, $name, array $attributes)
  2157. {
  2158. $attributes['_route'] = $name;
  2159. return $this->mergeDefaults($attributes, $route->getDefaults());
  2160. }
  2161. protected function handleRouteRequirements($pathinfo, $name, Route $route)
  2162. {
  2163. if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context'=> $this->context,'request'=> $this->request))) {
  2164. return array(self::REQUIREMENT_MISMATCH, null);
  2165. }
  2166. $scheme = $route->getRequirement('_scheme');
  2167. $status = $scheme && $scheme !== $this->context->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
  2168. return array($status, null);
  2169. }
  2170. protected function mergeDefaults($params, $defaults)
  2171. {
  2172. foreach ($params as $key => $value) {
  2173. if (!is_int($key)) {
  2174. $defaults[$key] = $value;
  2175. }
  2176. }
  2177. return $defaults;
  2178. }
  2179. protected function getExpressionLanguage()
  2180. {
  2181. if (null === $this->expressionLanguage) {
  2182. if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
  2183. throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
  2184. }
  2185. $this->expressionLanguage = new ExpressionLanguage();
  2186. }
  2187. return $this->expressionLanguage;
  2188. }
  2189. }
  2190. }
  2191. namespace Symfony\Component\Routing\Matcher
  2192. {
  2193. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  2194. use Symfony\Component\Routing\Route;
  2195. abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
  2196. {
  2197. public function match($pathinfo)
  2198. {
  2199. try {
  2200. $parameters = parent::match($pathinfo);
  2201. } catch (ResourceNotFoundException $e) {
  2202. if ('/'=== substr($pathinfo, -1) || !in_array($this->context->getMethod(), array('HEAD','GET'))) {
  2203. throw $e;
  2204. }
  2205. try {
  2206. parent::match($pathinfo.'/');
  2207. return $this->redirect($pathinfo.'/', null);
  2208. } catch (ResourceNotFoundException $e2) {
  2209. throw $e;
  2210. }
  2211. }
  2212. return $parameters;
  2213. }
  2214. protected function handleRouteRequirements($pathinfo, $name, Route $route)
  2215. {
  2216. if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context'=> $this->context,'request'=> $this->request))) {
  2217. return array(self::REQUIREMENT_MISMATCH, null);
  2218. }
  2219. $scheme = $route->getRequirement('_scheme');
  2220. if ($scheme && $this->context->getScheme() !== $scheme) {
  2221. return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, $scheme));
  2222. }
  2223. return array(self::REQUIREMENT_MATCH, null);
  2224. }
  2225. }
  2226. }
  2227. namespace Symfony\Bundle\FrameworkBundle\Routing
  2228. {
  2229. use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher;
  2230. class RedirectableUrlMatcher extends BaseMatcher
  2231. {
  2232. public function redirect($path, $route, $scheme = null)
  2233. {
  2234. return array('_controller'=>'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction','path'=> $path,'permanent'=> true,'scheme'=> $scheme,'httpPort'=> $this->context->getHttpPort(),'httpsPort'=> $this->context->getHttpsPort(),'_route'=> $route,
  2235. );
  2236. }
  2237. }
  2238. }
  2239. namespace Symfony\Component\Routing\Generator
  2240. {
  2241. use Symfony\Component\Routing\Exception\InvalidParameterException;
  2242. use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
  2243. use Symfony\Component\Routing\Exception\RouteNotFoundException;
  2244. use Symfony\Component\Routing\RequestContextAwareInterface;
  2245. interface UrlGeneratorInterface extends RequestContextAwareInterface
  2246. {
  2247. const ABSOLUTE_URL = true;
  2248. const ABSOLUTE_PATH = false;
  2249. const RELATIVE_PATH ='relative';
  2250. const NETWORK_PATH ='network';
  2251. public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH);
  2252. }
  2253. }
  2254. namespace Symfony\Component\Routing
  2255. {
  2256. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  2257. use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
  2258. interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
  2259. {
  2260. public function getRouteCollection();
  2261. }
  2262. }
  2263. namespace Symfony\Component\HttpKernel\CacheWarmer
  2264. {
  2265. interface WarmableInterface
  2266. {
  2267. public function warmUp($cacheDir);
  2268. }
  2269. }
  2270. namespace Symfony\Component\Routing
  2271. {
  2272. use Symfony\Component\Config\Loader\LoaderInterface;
  2273. use Symfony\Component\Config\ConfigCache;
  2274. use Psr\Log\LoggerInterface;
  2275. use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
  2276. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  2277. use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
  2278. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  2279. use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
  2280. use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
  2281. use Symfony\Component\HttpFoundation\Request;
  2282. class Router implements RouterInterface, RequestMatcherInterface
  2283. {
  2284. protected $matcher;
  2285. protected $generator;
  2286. protected $context;
  2287. protected $loader;
  2288. protected $collection;
  2289. protected $resource;
  2290. protected $options = array();
  2291. protected $logger;
  2292. public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
  2293. {
  2294. $this->loader = $loader;
  2295. $this->resource = $resource;
  2296. $this->logger = $logger;
  2297. $this->context = $context ?: new RequestContext();
  2298. $this->setOptions($options);
  2299. }
  2300. public function setOptions(array $options)
  2301. {
  2302. $this->options = array('cache_dir'=> null,'debug'=> false,'generator_class'=>'Symfony\\Component\\Routing\\Generator\\UrlGenerator','generator_base_class'=>'Symfony\\Component\\Routing\\Generator\\UrlGenerator','generator_dumper_class'=>'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper','generator_cache_class'=>'ProjectUrlGenerator','matcher_class'=>'Symfony\\Component\\Routing\\Matcher\\UrlMatcher','matcher_base_class'=>'Symfony\\Component\\Routing\\Matcher\\UrlMatcher','matcher_dumper_class'=>'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper','matcher_cache_class'=>'ProjectUrlMatcher','resource_type'=> null,'strict_requirements'=> true,
  2303. );
  2304. $invalid = array();
  2305. foreach ($options as $key => $value) {
  2306. if (array_key_exists($key, $this->options)) {
  2307. $this->options[$key] = $value;
  2308. } else {
  2309. $invalid[] = $key;
  2310. }
  2311. }
  2312. if ($invalid) {
  2313. throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('", "', $invalid)));
  2314. }
  2315. }
  2316. public function setOption($key, $value)
  2317. {
  2318. if (!array_key_exists($key, $this->options)) {
  2319. throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
  2320. }
  2321. $this->options[$key] = $value;
  2322. }
  2323. public function getOption($key)
  2324. {
  2325. if (!array_key_exists($key, $this->options)) {
  2326. throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
  2327. }
  2328. return $this->options[$key];
  2329. }
  2330. public function getRouteCollection()
  2331. {
  2332. if (null === $this->collection) {
  2333. $this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
  2334. }
  2335. return $this->collection;
  2336. }
  2337. public function setContext(RequestContext $context)
  2338. {
  2339. $this->context = $context;
  2340. if (null !== $this->matcher) {
  2341. $this->getMatcher()->setContext($context);
  2342. }
  2343. if (null !== $this->generator) {
  2344. $this->getGenerator()->setContext($context);
  2345. }
  2346. }
  2347. public function getContext()
  2348. {
  2349. return $this->context;
  2350. }
  2351. public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
  2352. {
  2353. return $this->getGenerator()->generate($name, $parameters, $referenceType);
  2354. }
  2355. public function match($pathinfo)
  2356. {
  2357. return $this->getMatcher()->match($pathinfo);
  2358. }
  2359. public function matchRequest(Request $request)
  2360. {
  2361. $matcher = $this->getMatcher();
  2362. if (!$matcher instanceof RequestMatcherInterface) {
  2363. return $matcher->match($request->getPathInfo());
  2364. }
  2365. return $matcher->matchRequest($request);
  2366. }
  2367. public function getMatcher()
  2368. {
  2369. if (null !== $this->matcher) {
  2370. return $this->matcher;
  2371. }
  2372. if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
  2373. return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
  2374. }
  2375. $class = $this->options['matcher_cache_class'];
  2376. $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
  2377. if (!$cache->isFresh()) {
  2378. $dumper = $this->getMatcherDumperInstance();
  2379. $options = array('class'=> $class,'base_class'=> $this->options['matcher_base_class'],
  2380. );
  2381. $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
  2382. }
  2383. require_once $cache;
  2384. return $this->matcher = new $class($this->context);
  2385. }
  2386. public function getGenerator()
  2387. {
  2388. if (null !== $this->generator) {
  2389. return $this->generator;
  2390. }
  2391. if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
  2392. $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
  2393. } else {
  2394. $class = $this->options['generator_cache_class'];
  2395. $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
  2396. if (!$cache->isFresh()) {
  2397. $dumper = $this->getGeneratorDumperInstance();
  2398. $options = array('class'=> $class,'base_class'=> $this->options['generator_base_class'],
  2399. );
  2400. $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
  2401. }
  2402. require_once $cache;
  2403. $this->generator = new $class($this->context, $this->logger);
  2404. }
  2405. if ($this->generator instanceof ConfigurableRequirementsInterface) {
  2406. $this->generator->setStrictRequirements($this->options['strict_requirements']);
  2407. }
  2408. return $this->generator;
  2409. }
  2410. protected function getGeneratorDumperInstance()
  2411. {
  2412. return new $this->options['generator_dumper_class']($this->getRouteCollection());
  2413. }
  2414. protected function getMatcherDumperInstance()
  2415. {
  2416. return new $this->options['matcher_dumper_class']($this->getRouteCollection());
  2417. }
  2418. }
  2419. }
  2420. namespace Symfony\Bundle\FrameworkBundle\Routing
  2421. {
  2422. use Symfony\Component\Routing\Router as BaseRouter;
  2423. use Symfony\Component\Routing\RequestContext;
  2424. use Symfony\Component\DependencyInjection\ContainerInterface;
  2425. use Symfony\Component\Routing\RouteCollection;
  2426. use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
  2427. use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
  2428. use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  2429. class Router extends BaseRouter implements WarmableInterface
  2430. {
  2431. private $container;
  2432. public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null)
  2433. {
  2434. $this->container = $container;
  2435. $this->resource = $resource;
  2436. $this->context = $context ?: new RequestContext();
  2437. $this->setOptions($options);
  2438. }
  2439. public function getRouteCollection()
  2440. {
  2441. if (null === $this->collection) {
  2442. $this->collection = $this->container->get('routing.loader')->load($this->resource, $this->options['resource_type']);
  2443. $this->resolveParameters($this->collection);
  2444. }
  2445. return $this->collection;
  2446. }
  2447. public function warmUp($cacheDir)
  2448. {
  2449. $currentDir = $this->getOption('cache_dir');
  2450. $this->setOption('cache_dir', $cacheDir);
  2451. $this->getMatcher();
  2452. $this->getGenerator();
  2453. $this->setOption('cache_dir', $currentDir);
  2454. }
  2455. private function resolveParameters(RouteCollection $collection)
  2456. {
  2457. foreach ($collection as $route) {
  2458. foreach ($route->getDefaults() as $name => $value) {
  2459. $route->setDefault($name, $this->resolve($value));
  2460. }
  2461. foreach ($route->getRequirements() as $name => $value) {
  2462. $route->setRequirement($name, $this->resolve($value));
  2463. }
  2464. $route->setPath($this->resolve($route->getPath()));
  2465. $route->setHost($this->resolve($route->getHost()));
  2466. }
  2467. }
  2468. private function resolve($value)
  2469. {
  2470. if (is_array($value)) {
  2471. foreach ($value as $key => $val) {
  2472. $value[$key] = $this->resolve($val);
  2473. }
  2474. return $value;
  2475. }
  2476. if (!is_string($value)) {
  2477. return $value;
  2478. }
  2479. $container = $this->container;
  2480. $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) {
  2481. if (!isset($match[1])) {
  2482. return'%%';
  2483. }
  2484. $resolved = $container->getParameter($match[1]);
  2485. if (is_string($resolved) || is_numeric($resolved)) {
  2486. return (string) $resolved;
  2487. }
  2488. throw new RuntimeException(sprintf('The container parameter "%s", used in the route configuration value "%s", '.'must be a string or numeric, but it is of type %s.',
  2489. $match[1],
  2490. $value,
  2491. gettype($resolved)
  2492. )
  2493. );
  2494. }, $value);
  2495. return str_replace('%%','%', $escapedValue);
  2496. }
  2497. }
  2498. }
  2499. namespace Symfony\Bundle\FrameworkBundle\Templating
  2500. {
  2501. use Symfony\Component\DependencyInjection\ContainerInterface;
  2502. use Symfony\Component\HttpFoundation\Session\Session;
  2503. use Symfony\Component\Security\Core\SecurityContext;
  2504. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  2505. use Symfony\Component\HttpFoundation\Request;
  2506. class GlobalVariables
  2507. {
  2508. protected $container;
  2509. public function __construct(ContainerInterface $container)
  2510. {
  2511. $this->container = $container;
  2512. }
  2513. public function getSecurity()
  2514. {
  2515. if ($this->container->has('security.context')) {
  2516. return $this->container->get('security.context');
  2517. }
  2518. }
  2519. public function getUser()
  2520. {
  2521. if (!$security = $this->getSecurity()) {
  2522. return;
  2523. }
  2524. if (!$token = $security->getToken()) {
  2525. return;
  2526. }
  2527. $user = $token->getUser();
  2528. if (!is_object($user)) {
  2529. return;
  2530. }
  2531. return $user;
  2532. }
  2533. public function getRequest()
  2534. {
  2535. if ($this->container->has('request_stack')) {
  2536. return $this->container->get('request_stack')->getCurrentRequest();
  2537. }
  2538. }
  2539. public function getSession()
  2540. {
  2541. if ($request = $this->getRequest()) {
  2542. return $request->getSession();
  2543. }
  2544. }
  2545. public function getEnvironment()
  2546. {
  2547. return $this->container->getParameter('kernel.environment');
  2548. }
  2549. public function getDebug()
  2550. {
  2551. return (bool) $this->container->getParameter('kernel.debug');
  2552. }
  2553. }
  2554. }
  2555. namespace Symfony\Component\Config
  2556. {
  2557. interface FileLocatorInterface
  2558. {
  2559. public function locate($name, $currentPath = null, $first = true);
  2560. }
  2561. }
  2562. namespace Symfony\Bundle\FrameworkBundle\Templating\Loader
  2563. {
  2564. use Symfony\Component\Config\FileLocatorInterface;
  2565. use Symfony\Component\Templating\TemplateReferenceInterface;
  2566. class TemplateLocator implements FileLocatorInterface
  2567. {
  2568. protected $locator;
  2569. protected $cache;
  2570. public function __construct(FileLocatorInterface $locator, $cacheDir = null)
  2571. {
  2572. if (null !== $cacheDir && is_file($cache = $cacheDir.'/templates.php')) {
  2573. $this->cache = require $cache;
  2574. }
  2575. $this->locator = $locator;
  2576. }
  2577. protected function getCacheKey($template)
  2578. {
  2579. return $template->getLogicalName();
  2580. }
  2581. public function locate($template, $currentPath = null, $first = true)
  2582. {
  2583. if (!$template instanceof TemplateReferenceInterface) {
  2584. throw new \InvalidArgumentException('The template must be an instance of TemplateReferenceInterface.');
  2585. }
  2586. $key = $this->getCacheKey($template);
  2587. if (isset($this->cache[$key])) {
  2588. return $this->cache[$key];
  2589. }
  2590. try {
  2591. return $this->cache[$key] = $this->locator->locate($template->getPath(), $currentPath);
  2592. } catch (\InvalidArgumentException $e) {
  2593. throw new \InvalidArgumentException(sprintf('Unable to find template "%s" : "%s".', $template, $e->getMessage()), 0, $e);
  2594. }
  2595. }
  2596. }
  2597. }
  2598. namespace Symfony\Component\Templating
  2599. {
  2600. interface TemplateNameParserInterface
  2601. {
  2602. public function parse($name);
  2603. }
  2604. }
  2605. namespace Symfony\Bundle\FrameworkBundle\Templating
  2606. {
  2607. use Symfony\Component\Templating\TemplateNameParserInterface;
  2608. use Symfony\Component\Templating\TemplateReferenceInterface;
  2609. use Symfony\Component\HttpKernel\KernelInterface;
  2610. class TemplateNameParser implements TemplateNameParserInterface
  2611. {
  2612. protected $kernel;
  2613. protected $cache = array();
  2614. public function __construct(KernelInterface $kernel)
  2615. {
  2616. $this->kernel = $kernel;
  2617. }
  2618. public function parse($name)
  2619. {
  2620. if ($name instanceof TemplateReferenceInterface) {
  2621. return $name;
  2622. } elseif (isset($this->cache[$name])) {
  2623. return $this->cache[$name];
  2624. }
  2625. $name = str_replace(':/',':', preg_replace('#/{2,}#','/', strtr($name,'\\','/')));
  2626. if (false !== strpos($name,'..')) {
  2627. throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name));
  2628. }
  2629. if (!preg_match('/^([^:]*):([^:]*):(.+)\.([^\.]+)\.([^\.]+)$/', $name, $matches)) {
  2630. throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.format.engine").', $name));
  2631. }
  2632. $template = new TemplateReference($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]);
  2633. if ($template->get('bundle')) {
  2634. try {
  2635. $this->kernel->getBundle($template->get('bundle'));
  2636. } catch (\Exception $e) {
  2637. throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid.', $name), 0, $e);
  2638. }
  2639. }
  2640. return $this->cache[$name] = $template;
  2641. }
  2642. }
  2643. }
  2644. namespace Symfony\Component\Templating
  2645. {
  2646. interface TemplateReferenceInterface
  2647. {
  2648. public function all();
  2649. public function set($name, $value);
  2650. public function get($name);
  2651. public function getPath();
  2652. public function getLogicalName();
  2653. public function __toString();
  2654. }
  2655. }
  2656. namespace Symfony\Component\Templating
  2657. {
  2658. class TemplateReference implements TemplateReferenceInterface
  2659. {
  2660. protected $parameters;
  2661. public function __construct($name = null, $engine = null)
  2662. {
  2663. $this->parameters = array('name'=> $name,'engine'=> $engine,
  2664. );
  2665. }
  2666. public function __toString()
  2667. {
  2668. return $this->getLogicalName();
  2669. }
  2670. public function set($name, $value)
  2671. {
  2672. if (array_key_exists($name, $this->parameters)) {
  2673. $this->parameters[$name] = $value;
  2674. } else {
  2675. throw new \InvalidArgumentException(sprintf('The template does not support the "%s" parameter.', $name));
  2676. }
  2677. return $this;
  2678. }
  2679. public function get($name)
  2680. {
  2681. if (array_key_exists($name, $this->parameters)) {
  2682. return $this->parameters[$name];
  2683. }
  2684. throw new \InvalidArgumentException(sprintf('The template does not support the "%s" parameter.', $name));
  2685. }
  2686. public function all()
  2687. {
  2688. return $this->parameters;
  2689. }
  2690. public function getPath()
  2691. {
  2692. return $this->parameters['name'];
  2693. }
  2694. public function getLogicalName()
  2695. {
  2696. return $this->parameters['name'];
  2697. }
  2698. }
  2699. }
  2700. namespace Symfony\Bundle\FrameworkBundle\Templating
  2701. {
  2702. use Symfony\Component\Templating\TemplateReference as BaseTemplateReference;
  2703. class TemplateReference extends BaseTemplateReference
  2704. {
  2705. public function __construct($bundle = null, $controller = null, $name = null, $format = null, $engine = null)
  2706. {
  2707. $this->parameters = array('bundle'=> $bundle,'controller'=> $controller,'name'=> $name,'format'=> $format,'engine'=> $engine,
  2708. );
  2709. }
  2710. public function getPath()
  2711. {
  2712. $controller = str_replace('\\','/', $this->get('controller'));
  2713. $path = (empty($controller) ?'': $controller.'/').$this->get('name').'.'.$this->get('format').'.'.$this->get('engine');
  2714. return empty($this->parameters['bundle']) ?'views/'.$path :'@'.$this->get('bundle').'/Resources/views/'.$path;
  2715. }
  2716. public function getLogicalName()
  2717. {
  2718. return sprintf('%s:%s:%s.%s.%s', $this->parameters['bundle'], $this->parameters['controller'], $this->parameters['name'], $this->parameters['format'], $this->parameters['engine']);
  2719. }
  2720. }
  2721. }
  2722. namespace Symfony\Bundle\SecurityBundle\Security
  2723. {
  2724. use Symfony\Component\Security\Http\Firewall\ExceptionListener;
  2725. class FirewallContext
  2726. {
  2727. private $listeners;
  2728. private $exceptionListener;
  2729. public function __construct(array $listeners, ExceptionListener $exceptionListener = null)
  2730. {
  2731. $this->listeners = $listeners;
  2732. $this->exceptionListener = $exceptionListener;
  2733. }
  2734. public function getContext()
  2735. {
  2736. return array($this->listeners, $this->exceptionListener);
  2737. }
  2738. }
  2739. }
  2740. namespace Symfony\Component\Security\Http
  2741. {
  2742. use Symfony\Component\HttpFoundation\Request;
  2743. interface FirewallMapInterface
  2744. {
  2745. public function getListeners(Request $request);
  2746. }
  2747. }
  2748. namespace Symfony\Bundle\SecurityBundle\Security
  2749. {
  2750. use Symfony\Component\Security\Http\FirewallMapInterface;
  2751. use Symfony\Component\HttpFoundation\Request;
  2752. use Symfony\Component\DependencyInjection\ContainerInterface;
  2753. class FirewallMap implements FirewallMapInterface
  2754. {
  2755. protected $container;
  2756. protected $map;
  2757. public function __construct(ContainerInterface $container, array $map)
  2758. {
  2759. $this->container = $container;
  2760. $this->map = $map;
  2761. }
  2762. public function getListeners(Request $request)
  2763. {
  2764. foreach ($this->map as $contextId => $requestMatcher) {
  2765. if (null === $requestMatcher || $requestMatcher->matches($request)) {
  2766. return $this->container->get($contextId)->getContext();
  2767. }
  2768. }
  2769. return array(array(), null);
  2770. }
  2771. }
  2772. }
  2773. namespace Symfony\Component\Config
  2774. {
  2775. class FileLocator implements FileLocatorInterface
  2776. {
  2777. protected $paths;
  2778. public function __construct($paths = array())
  2779. {
  2780. $this->paths = (array) $paths;
  2781. }
  2782. public function locate($name, $currentPath = null, $first = true)
  2783. {
  2784. if ($this->isAbsolutePath($name)) {
  2785. if (!file_exists($name)) {
  2786. throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name));
  2787. }
  2788. return $name;
  2789. }
  2790. $filepaths = array();
  2791. if (null !== $currentPath && file_exists($file = $currentPath.DIRECTORY_SEPARATOR.$name)) {
  2792. if (true === $first) {
  2793. return $file;
  2794. }
  2795. $filepaths[] = $file;
  2796. }
  2797. foreach ($this->paths as $path) {
  2798. if (file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
  2799. if (true === $first) {
  2800. return $file;
  2801. }
  2802. $filepaths[] = $file;
  2803. }
  2804. }
  2805. if (!$filepaths) {
  2806. throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s%s).', $name, null !== $currentPath ? $currentPath.', ':'', implode(', ', $this->paths)));
  2807. }
  2808. return array_values(array_unique($filepaths));
  2809. }
  2810. private function isAbsolutePath($file)
  2811. {
  2812. if ($file[0] =='/'|| $file[0] =='\\'|| (strlen($file) > 3 && ctype_alpha($file[0])
  2813. && $file[1] ==':'&& ($file[2] =='\\'|| $file[2] =='/')
  2814. )
  2815. || null !== parse_url($file, PHP_URL_SCHEME)
  2816. ) {
  2817. return true;
  2818. }
  2819. return false;
  2820. }
  2821. }
  2822. }
  2823. namespace Symfony\Component\EventDispatcher
  2824. {
  2825. interface EventDispatcherInterface
  2826. {
  2827. public function dispatch($eventName, Event $event = null);
  2828. public function addListener($eventName, $listener, $priority = 0);
  2829. public function addSubscriber(EventSubscriberInterface $subscriber);
  2830. public function removeListener($eventName, $listener);
  2831. public function removeSubscriber(EventSubscriberInterface $subscriber);
  2832. public function getListeners($eventName = null);
  2833. public function hasListeners($eventName = null);
  2834. }
  2835. }
  2836. namespace Symfony\Component\EventDispatcher
  2837. {
  2838. class EventDispatcher implements EventDispatcherInterface
  2839. {
  2840. private $listeners = array();
  2841. private $sorted = array();
  2842. public function dispatch($eventName, Event $event = null)
  2843. {
  2844. if (null === $event) {
  2845. $event = new Event();
  2846. }
  2847. $event->setDispatcher($this);
  2848. $event->setName($eventName);
  2849. if (!isset($this->listeners[$eventName])) {
  2850. return $event;
  2851. }
  2852. $this->doDispatch($this->getListeners($eventName), $eventName, $event);
  2853. return $event;
  2854. }
  2855. public function getListeners($eventName = null)
  2856. {
  2857. if (null !== $eventName) {
  2858. if (!isset($this->sorted[$eventName])) {
  2859. $this->sortListeners($eventName);
  2860. }
  2861. return $this->sorted[$eventName];
  2862. }
  2863. foreach (array_keys($this->listeners) as $eventName) {
  2864. if (!isset($this->sorted[$eventName])) {
  2865. $this->sortListeners($eventName);
  2866. }
  2867. }
  2868. return $this->sorted;
  2869. }
  2870. public function hasListeners($eventName = null)
  2871. {
  2872. return (bool) count($this->getListeners($eventName));
  2873. }
  2874. public function addListener($eventName, $listener, $priority = 0)
  2875. {
  2876. $this->listeners[$eventName][$priority][] = $listener;
  2877. unset($this->sorted[$eventName]);
  2878. }
  2879. public function removeListener($eventName, $listener)
  2880. {
  2881. if (!isset($this->listeners[$eventName])) {
  2882. return;
  2883. }
  2884. foreach ($this->listeners[$eventName] as $priority => $listeners) {
  2885. if (false !== ($key = array_search($listener, $listeners, true))) {
  2886. unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
  2887. }
  2888. }
  2889. }
  2890. public function addSubscriber(EventSubscriberInterface $subscriber)
  2891. {
  2892. foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
  2893. if (is_string($params)) {
  2894. $this->addListener($eventName, array($subscriber, $params));
  2895. } elseif (is_string($params[0])) {
  2896. $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
  2897. } else {
  2898. foreach ($params as $listener) {
  2899. $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
  2900. }
  2901. }
  2902. }
  2903. }
  2904. public function removeSubscriber(EventSubscriberInterface $subscriber)
  2905. {
  2906. foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
  2907. if (is_array($params) && is_array($params[0])) {
  2908. foreach ($params as $listener) {
  2909. $this->removeListener($eventName, array($subscriber, $listener[0]));
  2910. }
  2911. } else {
  2912. $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
  2913. }
  2914. }
  2915. }
  2916. protected function doDispatch($listeners, $eventName, Event $event)
  2917. {
  2918. foreach ($listeners as $listener) {
  2919. call_user_func($listener, $event, $eventName, $this);
  2920. if ($event->isPropagationStopped()) {
  2921. break;
  2922. }
  2923. }
  2924. }
  2925. private function sortListeners($eventName)
  2926. {
  2927. $this->sorted[$eventName] = array();
  2928. if (isset($this->listeners[$eventName])) {
  2929. krsort($this->listeners[$eventName]);
  2930. $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
  2931. }
  2932. }
  2933. }
  2934. }
  2935. namespace Symfony\Component\EventDispatcher
  2936. {
  2937. use Symfony\Component\DependencyInjection\ContainerInterface;
  2938. class ContainerAwareEventDispatcher extends EventDispatcher
  2939. {
  2940. private $container;
  2941. private $listenerIds = array();
  2942. private $listeners = array();
  2943. public function __construct(ContainerInterface $container)
  2944. {
  2945. $this->container = $container;
  2946. }
  2947. public function addListenerService($eventName, $callback, $priority = 0)
  2948. {
  2949. if (!is_array($callback) || 2 !== count($callback)) {
  2950. throw new \InvalidArgumentException('Expected an array("service", "method") argument');
  2951. }
  2952. $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority);
  2953. }
  2954. public function removeListener($eventName, $listener)
  2955. {
  2956. $this->lazyLoad($eventName);
  2957. if (isset($this->listeners[$eventName])) {
  2958. foreach ($this->listeners[$eventName] as $key => $l) {
  2959. foreach ($this->listenerIds[$eventName] as $i => $args) {
  2960. list($serviceId, $method, $priority) = $args;
  2961. if ($key === $serviceId.'.'.$method) {
  2962. if ($listener === array($l, $method)) {
  2963. unset($this->listeners[$eventName][$key]);
  2964. if (empty($this->listeners[$eventName])) {
  2965. unset($this->listeners[$eventName]);
  2966. }
  2967. unset($this->listenerIds[$eventName][$i]);
  2968. if (empty($this->listenerIds[$eventName])) {
  2969. unset($this->listenerIds[$eventName]);
  2970. }
  2971. }
  2972. }
  2973. }
  2974. }
  2975. }
  2976. parent::removeListener($eventName, $listener);
  2977. }
  2978. public function hasListeners($eventName = null)
  2979. {
  2980. if (null === $eventName) {
  2981. return (bool) count($this->listenerIds) || (bool) count($this->listeners);
  2982. }
  2983. if (isset($this->listenerIds[$eventName])) {
  2984. return true;
  2985. }
  2986. return parent::hasListeners($eventName);
  2987. }
  2988. public function getListeners($eventName = null)
  2989. {
  2990. if (null === $eventName) {
  2991. foreach (array_keys($this->listenerIds) as $serviceEventName) {
  2992. $this->lazyLoad($serviceEventName);
  2993. }
  2994. } else {
  2995. $this->lazyLoad($eventName);
  2996. }
  2997. return parent::getListeners($eventName);
  2998. }
  2999. public function addSubscriberService($serviceId, $class)
  3000. {
  3001. foreach ($class::getSubscribedEvents() as $eventName => $params) {
  3002. if (is_string($params)) {
  3003. $this->listenerIds[$eventName][] = array($serviceId, $params, 0);
  3004. } elseif (is_string($params[0])) {
  3005. $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0);
  3006. } else {
  3007. foreach ($params as $listener) {
  3008. $this->listenerIds[$eventName][] = array($serviceId, $listener[0], isset($listener[1]) ? $listener[1] : 0);
  3009. }
  3010. }
  3011. }
  3012. }
  3013. public function dispatch($eventName, Event $event = null)
  3014. {
  3015. $this->lazyLoad($eventName);
  3016. return parent::dispatch($eventName, $event);
  3017. }
  3018. public function getContainer()
  3019. {
  3020. return $this->container;
  3021. }
  3022. protected function lazyLoad($eventName)
  3023. {
  3024. if (isset($this->listenerIds[$eventName])) {
  3025. foreach ($this->listenerIds[$eventName] as $args) {
  3026. list($serviceId, $method, $priority) = $args;
  3027. $listener = $this->container->get($serviceId);
  3028. $key = $serviceId.'.'.$method;
  3029. if (!isset($this->listeners[$eventName][$key])) {
  3030. $this->addListener($eventName, array($listener, $method), $priority);
  3031. } elseif ($listener !== $this->listeners[$eventName][$key]) {
  3032. parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method));
  3033. $this->addListener($eventName, array($listener, $method), $priority);
  3034. }
  3035. $this->listeners[$eventName][$key] = $listener;
  3036. }
  3037. }
  3038. }
  3039. }
  3040. }
  3041. namespace Symfony\Component\EventDispatcher
  3042. {
  3043. class Event
  3044. {
  3045. private $propagationStopped = false;
  3046. private $dispatcher;
  3047. private $name;
  3048. public function isPropagationStopped()
  3049. {
  3050. return $this->propagationStopped;
  3051. }
  3052. public function stopPropagation()
  3053. {
  3054. $this->propagationStopped = true;
  3055. }
  3056. public function setDispatcher(EventDispatcherInterface $dispatcher)
  3057. {
  3058. $this->dispatcher = $dispatcher;
  3059. }
  3060. public function getDispatcher()
  3061. {
  3062. return $this->dispatcher;
  3063. }
  3064. public function getName()
  3065. {
  3066. return $this->name;
  3067. }
  3068. public function setName($name)
  3069. {
  3070. $this->name = $name;
  3071. }
  3072. }
  3073. }
  3074. namespace Symfony\Component\HttpFoundation
  3075. {
  3076. interface RequestMatcherInterface
  3077. {
  3078. public function matches(Request $request);
  3079. }
  3080. }
  3081. namespace Symfony\Component\HttpFoundation
  3082. {
  3083. class RequestMatcher implements RequestMatcherInterface
  3084. {
  3085. private $path;
  3086. private $host;
  3087. private $methods = array();
  3088. private $ips = array();
  3089. private $attributes = array();
  3090. public function __construct($path = null, $host = null, $methods = null, $ips = null, array $attributes = array())
  3091. {
  3092. $this->matchPath($path);
  3093. $this->matchHost($host);
  3094. $this->matchMethod($methods);
  3095. $this->matchIps($ips);
  3096. foreach ($attributes as $k => $v) {
  3097. $this->matchAttribute($k, $v);
  3098. }
  3099. }
  3100. public function matchHost($regexp)
  3101. {
  3102. $this->host = $regexp;
  3103. }
  3104. public function matchPath($regexp)
  3105. {
  3106. $this->path = $regexp;
  3107. }
  3108. public function matchIp($ip)
  3109. {
  3110. $this->matchIps($ip);
  3111. }
  3112. public function matchIps($ips)
  3113. {
  3114. $this->ips = (array) $ips;
  3115. }
  3116. public function matchMethod($method)
  3117. {
  3118. $this->methods = array_map('strtoupper', (array) $method);
  3119. }
  3120. public function matchAttribute($key, $regexp)
  3121. {
  3122. $this->attributes[$key] = $regexp;
  3123. }
  3124. public function matches(Request $request)
  3125. {
  3126. if ($this->methods && !in_array($request->getMethod(), $this->methods)) {
  3127. return false;
  3128. }
  3129. foreach ($this->attributes as $key => $pattern) {
  3130. if (!preg_match('{'.$pattern.'}', $request->attributes->get($key))) {
  3131. return false;
  3132. }
  3133. }
  3134. if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getPathInfo()))) {
  3135. return false;
  3136. }
  3137. if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getHost())) {
  3138. return false;
  3139. }
  3140. if (IpUtils::checkIp($request->getClientIp(), $this->ips)) {
  3141. return true;
  3142. }
  3143. return count($this->ips) === 0;
  3144. }
  3145. }
  3146. }
  3147. namespace Symfony\Component\HttpFoundation\Session
  3148. {
  3149. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  3150. interface SessionInterface
  3151. {
  3152. public function start();
  3153. public function getId();
  3154. public function setId($id);
  3155. public function getName();
  3156. public function setName($name);
  3157. public function invalidate($lifetime = null);
  3158. public function migrate($destroy = false, $lifetime = null);
  3159. public function save();
  3160. public function has($name);
  3161. public function get($name, $default = null);
  3162. public function set($name, $value);
  3163. public function all();
  3164. public function replace(array $attributes);
  3165. public function remove($name);
  3166. public function clear();
  3167. public function isStarted();
  3168. public function registerBag(SessionBagInterface $bag);
  3169. public function getBag($name);
  3170. public function getMetadataBag();
  3171. }
  3172. }
  3173. namespace Symfony\Component\HttpFoundation\Session
  3174. {
  3175. use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
  3176. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
  3177. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  3178. use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
  3179. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  3180. use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
  3181. class Session implements SessionInterface, \IteratorAggregate, \Countable
  3182. {
  3183. protected $storage;
  3184. private $flashName;
  3185. private $attributeName;
  3186. public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
  3187. {
  3188. $this->storage = $storage ?: new NativeSessionStorage();
  3189. $attributes = $attributes ?: new AttributeBag();
  3190. $this->attributeName = $attributes->getName();
  3191. $this->registerBag($attributes);
  3192. $flashes = $flashes ?: new FlashBag();
  3193. $this->flashName = $flashes->getName();
  3194. $this->registerBag($flashes);
  3195. }
  3196. public function start()
  3197. {
  3198. return $this->storage->start();
  3199. }
  3200. public function has($name)
  3201. {
  3202. return $this->storage->getBag($this->attributeName)->has($name);
  3203. }
  3204. public function get($name, $default = null)
  3205. {
  3206. return $this->storage->getBag($this->attributeName)->get($name, $default);
  3207. }
  3208. public function set($name, $value)
  3209. {
  3210. $this->storage->getBag($this->attributeName)->set($name, $value);
  3211. }
  3212. public function all()
  3213. {
  3214. return $this->storage->getBag($this->attributeName)->all();
  3215. }
  3216. public function replace(array $attributes)
  3217. {
  3218. $this->storage->getBag($this->attributeName)->replace($attributes);
  3219. }
  3220. public function remove($name)
  3221. {
  3222. return $this->storage->getBag($this->attributeName)->remove($name);
  3223. }
  3224. public function clear()
  3225. {
  3226. $this->storage->getBag($this->attributeName)->clear();
  3227. }
  3228. public function isStarted()
  3229. {
  3230. return $this->storage->isStarted();
  3231. }
  3232. public function getIterator()
  3233. {
  3234. return new \ArrayIterator($this->storage->getBag($this->attributeName)->all());
  3235. }
  3236. public function count()
  3237. {
  3238. return count($this->storage->getBag($this->attributeName)->all());
  3239. }
  3240. public function invalidate($lifetime = null)
  3241. {
  3242. $this->storage->clear();
  3243. return $this->migrate(true, $lifetime);
  3244. }
  3245. public function migrate($destroy = false, $lifetime = null)
  3246. {
  3247. return $this->storage->regenerate($destroy, $lifetime);
  3248. }
  3249. public function save()
  3250. {
  3251. $this->storage->save();
  3252. }
  3253. public function getId()
  3254. {
  3255. return $this->storage->getId();
  3256. }
  3257. public function setId($id)
  3258. {
  3259. $this->storage->setId($id);
  3260. }
  3261. public function getName()
  3262. {
  3263. return $this->storage->getName();
  3264. }
  3265. public function setName($name)
  3266. {
  3267. $this->storage->setName($name);
  3268. }
  3269. public function getMetadataBag()
  3270. {
  3271. return $this->storage->getMetadataBag();
  3272. }
  3273. public function registerBag(SessionBagInterface $bag)
  3274. {
  3275. $this->storage->registerBag($bag);
  3276. }
  3277. public function getBag($name)
  3278. {
  3279. return $this->storage->getBag($name);
  3280. }
  3281. public function getFlashBag()
  3282. {
  3283. return $this->getBag($this->flashName);
  3284. }
  3285. }
  3286. }
  3287. namespace Symfony\Component\HttpFoundation\Session\Storage\Handler
  3288. {
  3289. if (version_compare(phpversion(),'5.4.0','>=')) {
  3290. class NativeSessionHandler extends \SessionHandler {}
  3291. } else {
  3292. class NativeSessionHandler {}
  3293. }
  3294. }
  3295. namespace Symfony\Component\HttpFoundation\Session\Storage\Handler
  3296. {
  3297. class NativeFileSessionHandler extends NativeSessionHandler
  3298. {
  3299. public function __construct($savePath = null)
  3300. {
  3301. if (null === $savePath) {
  3302. $savePath = ini_get('session.save_path');
  3303. }
  3304. $baseDir = $savePath;
  3305. if ($count = substr_count($savePath,';')) {
  3306. if ($count > 2) {
  3307. throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath));
  3308. }
  3309. $baseDir = ltrim(strrchr($savePath,';'),';');
  3310. }
  3311. if ($baseDir && !is_dir($baseDir)) {
  3312. mkdir($baseDir, 0777, true);
  3313. }
  3314. ini_set('session.save_path', $savePath);
  3315. ini_set('session.save_handler','files');
  3316. }
  3317. }
  3318. }
  3319. namespace Symfony\Component\HttpFoundation\Session\Storage
  3320. {
  3321. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  3322. interface SessionStorageInterface
  3323. {
  3324. public function start();
  3325. public function isStarted();
  3326. public function getId();
  3327. public function setId($id);
  3328. public function getName();
  3329. public function setName($name);
  3330. public function regenerate($destroy = false, $lifetime = null);
  3331. public function save();
  3332. public function clear();
  3333. public function getBag($name);
  3334. public function registerBag(SessionBagInterface $bag);
  3335. public function getMetadataBag();
  3336. }
  3337. }
  3338. namespace Symfony\Component\HttpFoundation\Session\Storage
  3339. {
  3340. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  3341. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
  3342. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
  3343. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
  3344. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
  3345. class NativeSessionStorage implements SessionStorageInterface
  3346. {
  3347. protected $bags;
  3348. protected $started = false;
  3349. protected $closed = false;
  3350. protected $saveHandler;
  3351. protected $metadataBag;
  3352. public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
  3353. {
  3354. session_cache_limiter(''); ini_set('session.use_cookies', 1);
  3355. if (version_compare(phpversion(),'5.4.0','>=')) {
  3356. session_register_shutdown();
  3357. } else {
  3358. register_shutdown_function('session_write_close');
  3359. }
  3360. $this->setMetadataBag($metaBag);
  3361. $this->setOptions($options);
  3362. $this->setSaveHandler($handler);
  3363. }
  3364. public function getSaveHandler()
  3365. {
  3366. return $this->saveHandler;
  3367. }
  3368. public function start()
  3369. {
  3370. if ($this->started && !$this->closed) {
  3371. return true;
  3372. }
  3373. if (version_compare(phpversion(),'5.4.0','>=') && \PHP_SESSION_ACTIVE === session_status()) {
  3374. throw new \RuntimeException('Failed to start the session: already started by PHP.');
  3375. }
  3376. if (version_compare(phpversion(),'5.4.0','<') && isset($_SESSION) && session_id()) {
  3377. throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
  3378. }
  3379. if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
  3380. throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
  3381. }
  3382. if (!session_start()) {
  3383. throw new \RuntimeException('Failed to start the session');
  3384. }
  3385. $this->loadSession();
  3386. if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
  3387. $this->saveHandler->setActive(true);
  3388. }
  3389. return true;
  3390. }
  3391. public function getId()
  3392. {
  3393. if (!$this->started && !$this->closed) {
  3394. return''; }
  3395. return $this->saveHandler->getId();
  3396. }
  3397. public function setId($id)
  3398. {
  3399. $this->saveHandler->setId($id);
  3400. }
  3401. public function getName()
  3402. {
  3403. return $this->saveHandler->getName();
  3404. }
  3405. public function setName($name)
  3406. {
  3407. $this->saveHandler->setName($name);
  3408. }
  3409. public function regenerate($destroy = false, $lifetime = null)
  3410. {
  3411. if (null !== $lifetime) {
  3412. ini_set('session.cookie_lifetime', $lifetime);
  3413. }
  3414. if ($destroy) {
  3415. $this->metadataBag->stampNew();
  3416. }
  3417. $ret = session_regenerate_id($destroy);
  3418. if ('files'=== $this->getSaveHandler()->getSaveHandlerName()) {
  3419. session_write_close();
  3420. if (isset($_SESSION)) {
  3421. $backup = $_SESSION;
  3422. session_start();
  3423. $_SESSION = $backup;
  3424. } else {
  3425. session_start();
  3426. }
  3427. $this->loadSession();
  3428. }
  3429. return $ret;
  3430. }
  3431. public function save()
  3432. {
  3433. session_write_close();
  3434. if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
  3435. $this->saveHandler->setActive(false);
  3436. }
  3437. $this->closed = true;
  3438. $this->started = false;
  3439. }
  3440. public function clear()
  3441. {
  3442. foreach ($this->bags as $bag) {
  3443. $bag->clear();
  3444. }
  3445. $_SESSION = array();
  3446. $this->loadSession();
  3447. }
  3448. public function registerBag(SessionBagInterface $bag)
  3449. {
  3450. $this->bags[$bag->getName()] = $bag;
  3451. }
  3452. public function getBag($name)
  3453. {
  3454. if (!isset($this->bags[$name])) {
  3455. throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
  3456. }
  3457. if ($this->saveHandler->isActive() && !$this->started) {
  3458. $this->loadSession();
  3459. } elseif (!$this->started) {
  3460. $this->start();
  3461. }
  3462. return $this->bags[$name];
  3463. }
  3464. public function setMetadataBag(MetadataBag $metaBag = null)
  3465. {
  3466. if (null === $metaBag) {
  3467. $metaBag = new MetadataBag();
  3468. }
  3469. $this->metadataBag = $metaBag;
  3470. }
  3471. public function getMetadataBag()
  3472. {
  3473. return $this->metadataBag;
  3474. }
  3475. public function isStarted()
  3476. {
  3477. return $this->started;
  3478. }
  3479. public function setOptions(array $options)
  3480. {
  3481. $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',
  3482. ));
  3483. foreach ($options as $key => $value) {
  3484. if (isset($validOptions[$key])) {
  3485. ini_set('session.'.$key, $value);
  3486. }
  3487. }
  3488. }
  3489. public function setSaveHandler($saveHandler = null)
  3490. {
  3491. if (!$saveHandler instanceof AbstractProxy &&
  3492. !$saveHandler instanceof NativeSessionHandler &&
  3493. !$saveHandler instanceof \SessionHandlerInterface &&
  3494. null !== $saveHandler) {
  3495. throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.');
  3496. }
  3497. if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
  3498. $saveHandler = new SessionHandlerProxy($saveHandler);
  3499. } elseif (!$saveHandler instanceof AbstractProxy) {
  3500. $saveHandler = version_compare(phpversion(),'5.4.0','>=') ?
  3501. new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy();
  3502. }
  3503. $this->saveHandler = $saveHandler;
  3504. if ($this->saveHandler instanceof \SessionHandlerInterface) {
  3505. if (version_compare(phpversion(),'5.4.0','>=')) {
  3506. session_set_save_handler($this->saveHandler, false);
  3507. } else {
  3508. session_set_save_handler(
  3509. array($this->saveHandler,'open'),
  3510. array($this->saveHandler,'close'),
  3511. array($this->saveHandler,'read'),
  3512. array($this->saveHandler,'write'),
  3513. array($this->saveHandler,'destroy'),
  3514. array($this->saveHandler,'gc')
  3515. );
  3516. }
  3517. }
  3518. }
  3519. protected function loadSession(array &$session = null)
  3520. {
  3521. if (null === $session) {
  3522. $session = &$_SESSION;
  3523. }
  3524. $bags = array_merge($this->bags, array($this->metadataBag));
  3525. foreach ($bags as $bag) {
  3526. $key = $bag->getStorageKey();
  3527. $session[$key] = isset($session[$key]) ? $session[$key] : array();
  3528. $bag->initialize($session[$key]);
  3529. }
  3530. $this->started = true;
  3531. $this->closed = false;
  3532. }
  3533. }
  3534. }
  3535. namespace Symfony\Component\HttpFoundation\Session\Storage
  3536. {
  3537. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
  3538. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
  3539. class PhpBridgeSessionStorage extends NativeSessionStorage
  3540. {
  3541. public function __construct($handler = null, MetadataBag $metaBag = null)
  3542. {
  3543. $this->setMetadataBag($metaBag);
  3544. $this->setSaveHandler($handler);
  3545. }
  3546. public function start()
  3547. {
  3548. if ($this->started && !$this->closed) {
  3549. return true;
  3550. }
  3551. $this->loadSession();
  3552. if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
  3553. $this->saveHandler->setActive(true);
  3554. }
  3555. return true;
  3556. }
  3557. public function clear()
  3558. {
  3559. foreach ($this->bags as $bag) {
  3560. $bag->clear();
  3561. }
  3562. $this->loadSession();
  3563. }
  3564. }
  3565. }
  3566. namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy
  3567. {
  3568. abstract class AbstractProxy
  3569. {
  3570. protected $wrapper = false;
  3571. protected $active = false;
  3572. protected $saveHandlerName;
  3573. public function getSaveHandlerName()
  3574. {
  3575. return $this->saveHandlerName;
  3576. }
  3577. public function isSessionHandlerInterface()
  3578. {
  3579. return ($this instanceof \SessionHandlerInterface);
  3580. }
  3581. public function isWrapper()
  3582. {
  3583. return $this->wrapper;
  3584. }
  3585. public function isActive()
  3586. {
  3587. if (version_compare(phpversion(),'5.4.0','>=')) {
  3588. return $this->active = \PHP_SESSION_ACTIVE === session_status();
  3589. }
  3590. return $this->active;
  3591. }
  3592. public function setActive($flag)
  3593. {
  3594. if (version_compare(phpversion(),'5.4.0','>=')) {
  3595. throw new \LogicException('This method is disabled in PHP 5.4.0+');
  3596. }
  3597. $this->active = (bool) $flag;
  3598. }
  3599. public function getId()
  3600. {
  3601. return session_id();
  3602. }
  3603. public function setId($id)
  3604. {
  3605. if ($this->isActive()) {
  3606. throw new \LogicException('Cannot change the ID of an active session');
  3607. }
  3608. session_id($id);
  3609. }
  3610. public function getName()
  3611. {
  3612. return session_name();
  3613. }
  3614. public function setName($name)
  3615. {
  3616. if ($this->isActive()) {
  3617. throw new \LogicException('Cannot change the name of an active session');
  3618. }
  3619. session_name($name);
  3620. }
  3621. }
  3622. }
  3623. namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy
  3624. {
  3625. class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface
  3626. {
  3627. protected $handler;
  3628. public function __construct(\SessionHandlerInterface $handler)
  3629. {
  3630. $this->handler = $handler;
  3631. $this->wrapper = ($handler instanceof \SessionHandler);
  3632. $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') :'user';
  3633. }
  3634. public function open($savePath, $sessionName)
  3635. {
  3636. $return = (bool) $this->handler->open($savePath, $sessionName);
  3637. if (true === $return) {
  3638. $this->active = true;
  3639. }
  3640. return $return;
  3641. }
  3642. public function close()
  3643. {
  3644. $this->active = false;
  3645. return (bool) $this->handler->close();
  3646. }
  3647. public function read($sessionId)
  3648. {
  3649. return (string) $this->handler->read($sessionId);
  3650. }
  3651. public function write($sessionId, $data)
  3652. {
  3653. return (bool) $this->handler->write($sessionId, $data);
  3654. }
  3655. public function destroy($sessionId)
  3656. {
  3657. return (bool) $this->handler->destroy($sessionId);
  3658. }
  3659. public function gc($maxlifetime)
  3660. {
  3661. return (bool) $this->handler->gc($maxlifetime);
  3662. }
  3663. }
  3664. }
  3665. namespace Symfony\Component\HttpKernel\Config
  3666. {
  3667. use Symfony\Component\Config\FileLocator as BaseFileLocator;
  3668. use Symfony\Component\HttpKernel\KernelInterface;
  3669. class FileLocator extends BaseFileLocator
  3670. {
  3671. private $kernel;
  3672. private $path;
  3673. public function __construct(KernelInterface $kernel, $path = null, array $paths = array())
  3674. {
  3675. $this->kernel = $kernel;
  3676. if (null !== $path) {
  3677. $this->path = $path;
  3678. $paths[] = $path;
  3679. }
  3680. parent::__construct($paths);
  3681. }
  3682. public function locate($file, $currentPath = null, $first = true)
  3683. {
  3684. if ('@'=== $file[0]) {
  3685. return $this->kernel->locateResource($file, $this->path, $first);
  3686. }
  3687. return parent::locate($file, $currentPath, $first);
  3688. }
  3689. }
  3690. }
  3691. namespace Symfony\Component\HttpKernel\EventListener
  3692. {
  3693. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  3694. use Symfony\Component\HttpKernel\KernelEvents;
  3695. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  3696. class ResponseListener implements EventSubscriberInterface
  3697. {
  3698. private $charset;
  3699. public function __construct($charset)
  3700. {
  3701. $this->charset = $charset;
  3702. }
  3703. public function onKernelResponse(FilterResponseEvent $event)
  3704. {
  3705. if (!$event->isMasterRequest()) {
  3706. return;
  3707. }
  3708. $response = $event->getResponse();
  3709. if (null === $response->getCharset()) {
  3710. $response->setCharset($this->charset);
  3711. }
  3712. $response->prepare($event->getRequest());
  3713. }
  3714. public static function getSubscribedEvents()
  3715. {
  3716. return array(
  3717. KernelEvents::RESPONSE =>'onKernelResponse',
  3718. );
  3719. }
  3720. }
  3721. }
  3722. namespace Symfony\Component\HttpKernel\EventListener
  3723. {
  3724. use Psr\Log\LoggerInterface;
  3725. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  3726. use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
  3727. use Symfony\Component\HttpKernel\KernelEvents;
  3728. use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
  3729. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  3730. use Symfony\Component\HttpFoundation\RequestStack;
  3731. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  3732. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  3733. use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
  3734. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  3735. use Symfony\Component\Routing\RequestContext;
  3736. use Symfony\Component\Routing\RequestContextAwareInterface;
  3737. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  3738. use Symfony\Component\HttpFoundation\Request;
  3739. class RouterListener implements EventSubscriberInterface
  3740. {
  3741. private $matcher;
  3742. private $context;
  3743. private $logger;
  3744. private $request;
  3745. private $requestStack;
  3746. public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null, RequestStack $requestStack = null)
  3747. {
  3748. if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
  3749. throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
  3750. }
  3751. if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
  3752. throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
  3753. }
  3754. $this->matcher = $matcher;
  3755. $this->context = $context ?: $matcher->getContext();
  3756. $this->requestStack = $requestStack;
  3757. $this->logger = $logger;
  3758. }
  3759. public function setRequest(Request $request = null)
  3760. {
  3761. if (null !== $request && $this->request !== $request) {
  3762. $this->context->fromRequest($request);
  3763. }
  3764. $this->request = $request;
  3765. }
  3766. public function onKernelFinishRequest(FinishRequestEvent $event)
  3767. {
  3768. if (null === $this->requestStack) {
  3769. return; }
  3770. $this->setRequest($this->requestStack->getParentRequest());
  3771. }
  3772. public function onKernelRequest(GetResponseEvent $event)
  3773. {
  3774. $request = $event->getRequest();
  3775. if (null !== $this->requestStack) {
  3776. $this->setRequest($request);
  3777. }
  3778. if ($request->attributes->has('_controller')) {
  3779. return;
  3780. }
  3781. try {
  3782. if ($this->matcher instanceof RequestMatcherInterface) {
  3783. $parameters = $this->matcher->matchRequest($request);
  3784. } else {
  3785. $parameters = $this->matcher->match($request->getPathInfo());
  3786. }
  3787. if (null !== $this->logger) {
  3788. $this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters)));
  3789. }
  3790. $request->attributes->add($parameters);
  3791. unset($parameters['_route']);
  3792. unset($parameters['_controller']);
  3793. $request->attributes->set('_route_params', $parameters);
  3794. } catch (ResourceNotFoundException $e) {
  3795. $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
  3796. if ($referer = $request->headers->get('referer')) {
  3797. $message .= sprintf(' (from "%s")', $referer);
  3798. }
  3799. throw new NotFoundHttpException($message, $e);
  3800. } catch (MethodNotAllowedException $e) {
  3801. $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods()));
  3802. throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e);
  3803. }
  3804. }
  3805. private function parametersToString(array $parameters)
  3806. {
  3807. $pieces = array();
  3808. foreach ($parameters as $key => $val) {
  3809. $pieces[] = sprintf('"%s": "%s"', $key, (is_string($val) ? $val : json_encode($val)));
  3810. }
  3811. return implode(', ', $pieces);
  3812. }
  3813. public static function getSubscribedEvents()
  3814. {
  3815. return array(
  3816. KernelEvents::REQUEST => array(array('onKernelRequest', 32)),
  3817. KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)),
  3818. );
  3819. }
  3820. }
  3821. }
  3822. namespace Symfony\Component\HttpKernel\Event
  3823. {
  3824. use Symfony\Component\HttpKernel\HttpKernelInterface;
  3825. use Symfony\Component\HttpFoundation\Request;
  3826. use Symfony\Component\EventDispatcher\Event;
  3827. class KernelEvent extends Event
  3828. {
  3829. private $kernel;
  3830. private $request;
  3831. private $requestType;
  3832. public function __construct(HttpKernelInterface $kernel, Request $request, $requestType)
  3833. {
  3834. $this->kernel = $kernel;
  3835. $this->request = $request;
  3836. $this->requestType = $requestType;
  3837. }
  3838. public function getKernel()
  3839. {
  3840. return $this->kernel;
  3841. }
  3842. public function getRequest()
  3843. {
  3844. return $this->request;
  3845. }
  3846. public function getRequestType()
  3847. {
  3848. return $this->requestType;
  3849. }
  3850. public function isMasterRequest()
  3851. {
  3852. return HttpKernelInterface::MASTER_REQUEST === $this->requestType;
  3853. }
  3854. }
  3855. }
  3856. namespace Symfony\Component\HttpKernel\Event
  3857. {
  3858. use Symfony\Component\HttpKernel\HttpKernelInterface;
  3859. use Symfony\Component\HttpFoundation\Request;
  3860. class FilterControllerEvent extends KernelEvent
  3861. {
  3862. private $controller;
  3863. public function __construct(HttpKernelInterface $kernel, $controller, Request $request, $requestType)
  3864. {
  3865. parent::__construct($kernel, $request, $requestType);
  3866. $this->setController($controller);
  3867. }
  3868. public function getController()
  3869. {
  3870. return $this->controller;
  3871. }
  3872. public function setController($controller)
  3873. {
  3874. if (!is_callable($controller)) {
  3875. throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller)));
  3876. }
  3877. $this->controller = $controller;
  3878. }
  3879. private function varToString($var)
  3880. {
  3881. if (is_object($var)) {
  3882. return sprintf('Object(%s)', get_class($var));
  3883. }
  3884. if (is_array($var)) {
  3885. $a = array();
  3886. foreach ($var as $k => $v) {
  3887. $a[] = sprintf('%s => %s', $k, $this->varToString($v));
  3888. }
  3889. return sprintf("Array(%s)", implode(', ', $a));
  3890. }
  3891. if (is_resource($var)) {
  3892. return sprintf('Resource(%s)', get_resource_type($var));
  3893. }
  3894. if (null === $var) {
  3895. return'null';
  3896. }
  3897. if (false === $var) {
  3898. return'false';
  3899. }
  3900. if (true === $var) {
  3901. return'true';
  3902. }
  3903. return (string) $var;
  3904. }
  3905. }
  3906. }
  3907. namespace Symfony\Component\HttpKernel\Event
  3908. {
  3909. use Symfony\Component\HttpKernel\HttpKernelInterface;
  3910. use Symfony\Component\HttpFoundation\Request;
  3911. use Symfony\Component\HttpFoundation\Response;
  3912. class FilterResponseEvent extends KernelEvent
  3913. {
  3914. private $response;
  3915. public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, Response $response)
  3916. {
  3917. parent::__construct($kernel, $request, $requestType);
  3918. $this->setResponse($response);
  3919. }
  3920. public function getResponse()
  3921. {
  3922. return $this->response;
  3923. }
  3924. public function setResponse(Response $response)
  3925. {
  3926. $this->response = $response;
  3927. }
  3928. }
  3929. }
  3930. namespace Symfony\Component\HttpKernel\Event
  3931. {
  3932. use Symfony\Component\HttpFoundation\Response;
  3933. class GetResponseEvent extends KernelEvent
  3934. {
  3935. private $response;
  3936. public function getResponse()
  3937. {
  3938. return $this->response;
  3939. }
  3940. public function setResponse(Response $response)
  3941. {
  3942. $this->response = $response;
  3943. $this->stopPropagation();
  3944. }
  3945. public function hasResponse()
  3946. {
  3947. return null !== $this->response;
  3948. }
  3949. }
  3950. }
  3951. namespace Symfony\Component\HttpKernel\Event
  3952. {
  3953. use Symfony\Component\HttpKernel\HttpKernelInterface;
  3954. use Symfony\Component\HttpFoundation\Request;
  3955. class GetResponseForControllerResultEvent extends GetResponseEvent
  3956. {
  3957. private $controllerResult;
  3958. public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, $controllerResult)
  3959. {
  3960. parent::__construct($kernel, $request, $requestType);
  3961. $this->controllerResult = $controllerResult;
  3962. }
  3963. public function getControllerResult()
  3964. {
  3965. return $this->controllerResult;
  3966. }
  3967. public function setControllerResult($controllerResult)
  3968. {
  3969. $this->controllerResult = $controllerResult;
  3970. }
  3971. }
  3972. }
  3973. namespace Symfony\Component\HttpKernel\Event
  3974. {
  3975. use Symfony\Component\HttpKernel\HttpKernelInterface;
  3976. use Symfony\Component\HttpFoundation\Request;
  3977. class GetResponseForExceptionEvent extends GetResponseEvent
  3978. {
  3979. private $exception;
  3980. public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e)
  3981. {
  3982. parent::__construct($kernel, $request, $requestType);
  3983. $this->setException($e);
  3984. }
  3985. public function getException()
  3986. {
  3987. return $this->exception;
  3988. }
  3989. public function setException(\Exception $exception)
  3990. {
  3991. $this->exception = $exception;
  3992. }
  3993. }
  3994. }
  3995. namespace Symfony\Component\HttpKernel
  3996. {
  3997. final class KernelEvents
  3998. {
  3999. const REQUEST ='kernel.request';
  4000. const EXCEPTION ='kernel.exception';
  4001. const VIEW ='kernel.view';
  4002. const CONTROLLER ='kernel.controller';
  4003. const RESPONSE ='kernel.response';
  4004. const TERMINATE ='kernel.terminate';
  4005. const FINISH_REQUEST ='kernel.finish_request';
  4006. }
  4007. }
  4008. namespace Symfony\Component\Routing\Generator
  4009. {
  4010. interface ConfigurableRequirementsInterface
  4011. {
  4012. public function setStrictRequirements($enabled);
  4013. public function isStrictRequirements();
  4014. }
  4015. }
  4016. namespace Symfony\Component\Routing\Generator
  4017. {
  4018. use Symfony\Component\Routing\RouteCollection;
  4019. use Symfony\Component\Routing\RequestContext;
  4020. use Symfony\Component\Routing\Exception\InvalidParameterException;
  4021. use Symfony\Component\Routing\Exception\RouteNotFoundException;
  4022. use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
  4023. use Psr\Log\LoggerInterface;
  4024. class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface
  4025. {
  4026. protected $routes;
  4027. protected $context;
  4028. protected $strictRequirements = true;
  4029. protected $logger;
  4030. protected $decodedChars = array('%2F'=>'/','%40'=>'@','%3A'=>':','%3B'=>';','%2C'=>',','%3D'=>'=','%2B'=>'+','%21'=>'!','%2A'=>'*','%7C'=>'|',
  4031. );
  4032. public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null)
  4033. {
  4034. $this->routes = $routes;
  4035. $this->context = $context;
  4036. $this->logger = $logger;
  4037. }
  4038. public function setContext(RequestContext $context)
  4039. {
  4040. $this->context = $context;
  4041. }
  4042. public function getContext()
  4043. {
  4044. return $this->context;
  4045. }
  4046. public function setStrictRequirements($enabled)
  4047. {
  4048. $this->strictRequirements = null === $enabled ? null : (bool) $enabled;
  4049. }
  4050. public function isStrictRequirements()
  4051. {
  4052. return $this->strictRequirements;
  4053. }
  4054. public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
  4055. {
  4056. if (null === $route = $this->routes->get($name)) {
  4057. throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
  4058. }
  4059. $compiledRoute = $route->compile();
  4060. return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens());
  4061. }
  4062. protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens)
  4063. {
  4064. $variables = array_flip($variables);
  4065. $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
  4066. if ($diff = array_diff_key($variables, $mergedParams)) {
  4067. throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name));
  4068. }
  4069. $url ='';
  4070. $optional = true;
  4071. foreach ($tokens as $token) {
  4072. if ('variable'=== $token[0]) {
  4073. if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) {
  4074. if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) {
  4075. $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]);
  4076. if ($this->strictRequirements) {
  4077. throw new InvalidParameterException($message);
  4078. }
  4079. if ($this->logger) {
  4080. $this->logger->error($message);
  4081. }
  4082. return;
  4083. }
  4084. $url = $token[1].$mergedParams[$token[3]].$url;
  4085. $optional = false;
  4086. }
  4087. } else {
  4088. $url = $token[1].$url;
  4089. $optional = false;
  4090. }
  4091. }
  4092. if (''=== $url) {
  4093. $url ='/';
  4094. }
  4095. $url = strtr(rawurlencode($url), $this->decodedChars);
  4096. $url = strtr($url, array('/../'=>'/%2E%2E/','/./'=>'/%2E/'));
  4097. if ('/..'=== substr($url, -3)) {
  4098. $url = substr($url, 0, -2).'%2E%2E';
  4099. } elseif ('/.'=== substr($url, -2)) {
  4100. $url = substr($url, 0, -1).'%2E';
  4101. }
  4102. $schemeAuthority ='';
  4103. if ($host = $this->context->getHost()) {
  4104. $scheme = $this->context->getScheme();
  4105. if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) {
  4106. $referenceType = self::ABSOLUTE_URL;
  4107. $scheme = $req;
  4108. }
  4109. if ($hostTokens) {
  4110. $routeHost ='';
  4111. foreach ($hostTokens as $token) {
  4112. if ('variable'=== $token[0]) {
  4113. if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) {
  4114. $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]);
  4115. if ($this->strictRequirements) {
  4116. throw new InvalidParameterException($message);
  4117. }
  4118. if ($this->logger) {
  4119. $this->logger->error($message);
  4120. }
  4121. return;
  4122. }
  4123. $routeHost = $token[1].$mergedParams[$token[3]].$routeHost;
  4124. } else {
  4125. $routeHost = $token[1].$routeHost;
  4126. }
  4127. }
  4128. if ($routeHost !== $host) {
  4129. $host = $routeHost;
  4130. if (self::ABSOLUTE_URL !== $referenceType) {
  4131. $referenceType = self::NETWORK_PATH;
  4132. }
  4133. }
  4134. }
  4135. if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) {
  4136. $port ='';
  4137. if ('http'=== $scheme && 80 != $this->context->getHttpPort()) {
  4138. $port =':'.$this->context->getHttpPort();
  4139. } elseif ('https'=== $scheme && 443 != $this->context->getHttpsPort()) {
  4140. $port =':'.$this->context->getHttpsPort();
  4141. }
  4142. $schemeAuthority = self::NETWORK_PATH === $referenceType ?'//': "$scheme://";
  4143. $schemeAuthority .= $host.$port;
  4144. }
  4145. }
  4146. if (self::RELATIVE_PATH === $referenceType) {
  4147. $url = self::getRelativePath($this->context->getPathInfo(), $url);
  4148. } else {
  4149. $url = $schemeAuthority.$this->context->getBaseUrl().$url;
  4150. }
  4151. $extra = array_diff_key($parameters, $variables, $defaults);
  4152. if ($extra && $query = http_build_query($extra,'','&')) {
  4153. $url .='?'.$query;
  4154. }
  4155. return $url;
  4156. }
  4157. public static function getRelativePath($basePath, $targetPath)
  4158. {
  4159. if ($basePath === $targetPath) {
  4160. return'';
  4161. }
  4162. $sourceDirs = explode('/', isset($basePath[0]) &&'/'=== $basePath[0] ? substr($basePath, 1) : $basePath);
  4163. $targetDirs = explode('/', isset($targetPath[0]) &&'/'=== $targetPath[0] ? substr($targetPath, 1) : $targetPath);
  4164. array_pop($sourceDirs);
  4165. $targetFile = array_pop($targetDirs);
  4166. foreach ($sourceDirs as $i => $dir) {
  4167. if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
  4168. unset($sourceDirs[$i], $targetDirs[$i]);
  4169. } else {
  4170. break;
  4171. }
  4172. }
  4173. $targetDirs[] = $targetFile;
  4174. $path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs);
  4175. return''=== $path ||'/'=== $path[0]
  4176. || false !== ($colonPos = strpos($path,':')) && ($colonPos < ($slashPos = strpos($path,'/')) || false === $slashPos)
  4177. ? "./$path" : $path;
  4178. }
  4179. }
  4180. }
  4181. namespace Symfony\Component\Routing
  4182. {
  4183. use Symfony\Component\HttpFoundation\Request;
  4184. class RequestContext
  4185. {
  4186. private $baseUrl;
  4187. private $pathInfo;
  4188. private $method;
  4189. private $host;
  4190. private $scheme;
  4191. private $httpPort;
  4192. private $httpsPort;
  4193. private $queryString;
  4194. private $parameters = array();
  4195. public function __construct($baseUrl ='', $method ='GET', $host ='localhost', $scheme ='http', $httpPort = 80, $httpsPort = 443, $path ='/', $queryString ='')
  4196. {
  4197. $this->baseUrl = $baseUrl;
  4198. $this->method = strtoupper($method);
  4199. $this->host = $host;
  4200. $this->scheme = strtolower($scheme);
  4201. $this->httpPort = $httpPort;
  4202. $this->httpsPort = $httpsPort;
  4203. $this->pathInfo = $path;
  4204. $this->queryString = $queryString;
  4205. }
  4206. public function fromRequest(Request $request)
  4207. {
  4208. $this->setBaseUrl($request->getBaseUrl());
  4209. $this->setPathInfo($request->getPathInfo());
  4210. $this->setMethod($request->getMethod());
  4211. $this->setHost($request->getHost());
  4212. $this->setScheme($request->getScheme());
  4213. $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
  4214. $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
  4215. $this->setQueryString($request->server->get('QUERY_STRING'));
  4216. }
  4217. public function getBaseUrl()
  4218. {
  4219. return $this->baseUrl;
  4220. }
  4221. public function setBaseUrl($baseUrl)
  4222. {
  4223. $this->baseUrl = $baseUrl;
  4224. }
  4225. public function getPathInfo()
  4226. {
  4227. return $this->pathInfo;
  4228. }
  4229. public function setPathInfo($pathInfo)
  4230. {
  4231. $this->pathInfo = $pathInfo;
  4232. }
  4233. public function getMethod()
  4234. {
  4235. return $this->method;
  4236. }
  4237. public function setMethod($method)
  4238. {
  4239. $this->method = strtoupper($method);
  4240. }
  4241. public function getHost()
  4242. {
  4243. return $this->host;
  4244. }
  4245. public function setHost($host)
  4246. {
  4247. $this->host = $host;
  4248. }
  4249. public function getScheme()
  4250. {
  4251. return $this->scheme;
  4252. }
  4253. public function setScheme($scheme)
  4254. {
  4255. $this->scheme = strtolower($scheme);
  4256. }
  4257. public function getHttpPort()
  4258. {
  4259. return $this->httpPort;
  4260. }
  4261. public function setHttpPort($httpPort)
  4262. {
  4263. $this->httpPort = $httpPort;
  4264. }
  4265. public function getHttpsPort()
  4266. {
  4267. return $this->httpsPort;
  4268. }
  4269. public function setHttpsPort($httpsPort)
  4270. {
  4271. $this->httpsPort = $httpsPort;
  4272. }
  4273. public function getQueryString()
  4274. {
  4275. return $this->queryString;
  4276. }
  4277. public function setQueryString($queryString)
  4278. {
  4279. $this->queryString = $queryString;
  4280. }
  4281. public function getParameters()
  4282. {
  4283. return $this->parameters;
  4284. }
  4285. public function setParameters(array $parameters)
  4286. {
  4287. $this->parameters = $parameters;
  4288. return $this;
  4289. }
  4290. public function getParameter($name)
  4291. {
  4292. return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
  4293. }
  4294. public function hasParameter($name)
  4295. {
  4296. return array_key_exists($name, $this->parameters);
  4297. }
  4298. public function setParameter($name, $parameter)
  4299. {
  4300. $this->parameters[$name] = $parameter;
  4301. }
  4302. }
  4303. }
  4304. namespace Symfony\Component\Security\Core\Authentication
  4305. {
  4306. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4307. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  4308. interface AuthenticationManagerInterface
  4309. {
  4310. public function authenticate(TokenInterface $token);
  4311. }
  4312. }
  4313. namespace Symfony\Component\Security\Core\Authentication
  4314. {
  4315. use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
  4316. use Symfony\Component\Security\Core\Event\AuthenticationEvent;
  4317. use Symfony\Component\Security\Core\AuthenticationEvents;
  4318. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  4319. use Symfony\Component\Security\Core\Exception\AccountStatusException;
  4320. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  4321. use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
  4322. use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
  4323. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4324. class AuthenticationProviderManager implements AuthenticationManagerInterface
  4325. {
  4326. private $providers;
  4327. private $eraseCredentials;
  4328. private $eventDispatcher;
  4329. public function __construct(array $providers, $eraseCredentials = true)
  4330. {
  4331. if (!$providers) {
  4332. throw new \InvalidArgumentException('You must at least add one authentication provider.');
  4333. }
  4334. $this->providers = $providers;
  4335. $this->eraseCredentials = (bool) $eraseCredentials;
  4336. }
  4337. public function setEventDispatcher(EventDispatcherInterface $dispatcher)
  4338. {
  4339. $this->eventDispatcher = $dispatcher;
  4340. }
  4341. public function authenticate(TokenInterface $token)
  4342. {
  4343. $lastException = null;
  4344. $result = null;
  4345. foreach ($this->providers as $provider) {
  4346. if (!$provider->supports($token)) {
  4347. continue;
  4348. }
  4349. try {
  4350. $result = $provider->authenticate($token);
  4351. if (null !== $result) {
  4352. break;
  4353. }
  4354. } catch (AccountStatusException $e) {
  4355. $e->setToken($token);
  4356. throw $e;
  4357. } catch (AuthenticationException $e) {
  4358. $lastException = $e;
  4359. }
  4360. }
  4361. if (null !== $result) {
  4362. if (true === $this->eraseCredentials) {
  4363. $result->eraseCredentials();
  4364. }
  4365. if (null !== $this->eventDispatcher) {
  4366. $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($result));
  4367. }
  4368. return $result;
  4369. }
  4370. if (null === $lastException) {
  4371. $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', get_class($token)));
  4372. }
  4373. if (null !== $this->eventDispatcher) {
  4374. $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_FAILURE, new AuthenticationFailureEvent($token, $lastException));
  4375. }
  4376. $lastException->setToken($token);
  4377. throw $lastException;
  4378. }
  4379. }
  4380. }
  4381. namespace Symfony\Component\Security\Core\Authorization
  4382. {
  4383. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4384. interface AccessDecisionManagerInterface
  4385. {
  4386. public function decide(TokenInterface $token, array $attributes, $object = null);
  4387. public function supportsAttribute($attribute);
  4388. public function supportsClass($class);
  4389. }
  4390. }
  4391. namespace Symfony\Component\Security\Core\Authorization
  4392. {
  4393. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  4394. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4395. class AccessDecisionManager implements AccessDecisionManagerInterface
  4396. {
  4397. private $voters;
  4398. private $strategy;
  4399. private $allowIfAllAbstainDecisions;
  4400. private $allowIfEqualGrantedDeniedDecisions;
  4401. public function __construct(array $voters, $strategy ='affirmative', $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
  4402. {
  4403. if (!$voters) {
  4404. throw new \InvalidArgumentException('You must at least add one voter.');
  4405. }
  4406. $strategyMethod ='decide'.ucfirst($strategy);
  4407. if (!is_callable(array($this, $strategyMethod))) {
  4408. throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy));
  4409. }
  4410. $this->voters = $voters;
  4411. $this->strategy = $strategyMethod;
  4412. $this->allowIfAllAbstainDecisions = (bool) $allowIfAllAbstainDecisions;
  4413. $this->allowIfEqualGrantedDeniedDecisions = (bool) $allowIfEqualGrantedDeniedDecisions;
  4414. }
  4415. public function decide(TokenInterface $token, array $attributes, $object = null)
  4416. {
  4417. return $this->{$this->strategy}($token, $attributes, $object);
  4418. }
  4419. public function supportsAttribute($attribute)
  4420. {
  4421. foreach ($this->voters as $voter) {
  4422. if ($voter->supportsAttribute($attribute)) {
  4423. return true;
  4424. }
  4425. }
  4426. return false;
  4427. }
  4428. public function supportsClass($class)
  4429. {
  4430. foreach ($this->voters as $voter) {
  4431. if ($voter->supportsClass($class)) {
  4432. return true;
  4433. }
  4434. }
  4435. return false;
  4436. }
  4437. private function decideAffirmative(TokenInterface $token, array $attributes, $object = null)
  4438. {
  4439. $deny = 0;
  4440. foreach ($this->voters as $voter) {
  4441. $result = $voter->vote($token, $object, $attributes);
  4442. switch ($result) {
  4443. case VoterInterface::ACCESS_GRANTED:
  4444. return true;
  4445. case VoterInterface::ACCESS_DENIED:
  4446. ++$deny;
  4447. break;
  4448. default:
  4449. break;
  4450. }
  4451. }
  4452. if ($deny > 0) {
  4453. return false;
  4454. }
  4455. return $this->allowIfAllAbstainDecisions;
  4456. }
  4457. private function decideConsensus(TokenInterface $token, array $attributes, $object = null)
  4458. {
  4459. $grant = 0;
  4460. $deny = 0;
  4461. $abstain = 0;
  4462. foreach ($this->voters as $voter) {
  4463. $result = $voter->vote($token, $object, $attributes);
  4464. switch ($result) {
  4465. case VoterInterface::ACCESS_GRANTED:
  4466. ++$grant;
  4467. break;
  4468. case VoterInterface::ACCESS_DENIED:
  4469. ++$deny;
  4470. break;
  4471. default:
  4472. ++$abstain;
  4473. break;
  4474. }
  4475. }
  4476. if ($grant > $deny) {
  4477. return true;
  4478. }
  4479. if ($deny > $grant) {
  4480. return false;
  4481. }
  4482. if ($grant == $deny && $grant != 0) {
  4483. return $this->allowIfEqualGrantedDeniedDecisions;
  4484. }
  4485. return $this->allowIfAllAbstainDecisions;
  4486. }
  4487. private function decideUnanimous(TokenInterface $token, array $attributes, $object = null)
  4488. {
  4489. $grant = 0;
  4490. foreach ($attributes as $attribute) {
  4491. foreach ($this->voters as $voter) {
  4492. $result = $voter->vote($token, $object, array($attribute));
  4493. switch ($result) {
  4494. case VoterInterface::ACCESS_GRANTED:
  4495. ++$grant;
  4496. break;
  4497. case VoterInterface::ACCESS_DENIED:
  4498. return false;
  4499. default:
  4500. break;
  4501. }
  4502. }
  4503. }
  4504. if ($grant > 0) {
  4505. return true;
  4506. }
  4507. return $this->allowIfAllAbstainDecisions;
  4508. }
  4509. }
  4510. }
  4511. namespace Symfony\Component\Security\Core\Authorization\Voter
  4512. {
  4513. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4514. interface VoterInterface
  4515. {
  4516. const ACCESS_GRANTED = 1;
  4517. const ACCESS_ABSTAIN = 0;
  4518. const ACCESS_DENIED = -1;
  4519. public function supportsAttribute($attribute);
  4520. public function supportsClass($class);
  4521. public function vote(TokenInterface $token, $object, array $attributes);
  4522. }
  4523. }
  4524. namespace Symfony\Component\Security\Core
  4525. {
  4526. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4527. interface SecurityContextInterface
  4528. {
  4529. const ACCESS_DENIED_ERROR ='_security.403_error';
  4530. const AUTHENTICATION_ERROR ='_security.last_error';
  4531. const LAST_USERNAME ='_security.last_username';
  4532. public function getToken();
  4533. public function setToken(TokenInterface $token = null);
  4534. public function isGranted($attributes, $object = null);
  4535. }
  4536. }
  4537. namespace Symfony\Component\Security\Core
  4538. {
  4539. use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
  4540. use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
  4541. use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
  4542. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4543. class SecurityContext implements SecurityContextInterface
  4544. {
  4545. private $token;
  4546. private $accessDecisionManager;
  4547. private $authenticationManager;
  4548. private $alwaysAuthenticate;
  4549. public function __construct(AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, $alwaysAuthenticate = false)
  4550. {
  4551. $this->authenticationManager = $authenticationManager;
  4552. $this->accessDecisionManager = $accessDecisionManager;
  4553. $this->alwaysAuthenticate = $alwaysAuthenticate;
  4554. }
  4555. final public function isGranted($attributes, $object = null)
  4556. {
  4557. if (null === $this->token) {
  4558. throw new AuthenticationCredentialsNotFoundException('The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
  4559. }
  4560. if ($this->alwaysAuthenticate || !$this->token->isAuthenticated()) {
  4561. $this->token = $this->authenticationManager->authenticate($this->token);
  4562. }
  4563. if (!is_array($attributes)) {
  4564. $attributes = array($attributes);
  4565. }
  4566. return $this->accessDecisionManager->decide($this->token, $attributes, $object);
  4567. }
  4568. public function getToken()
  4569. {
  4570. return $this->token;
  4571. }
  4572. public function setToken(TokenInterface $token = null)
  4573. {
  4574. $this->token = $token;
  4575. }
  4576. }
  4577. }
  4578. namespace Symfony\Component\Security\Core\User
  4579. {
  4580. use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  4581. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  4582. interface UserProviderInterface
  4583. {
  4584. public function loadUserByUsername($username);
  4585. public function refreshUser(UserInterface $user);
  4586. public function supportsClass($class);
  4587. }
  4588. }
  4589. namespace Symfony\Component\Security\Http
  4590. {
  4591. use Symfony\Component\HttpFoundation\Request;
  4592. interface AccessMapInterface
  4593. {
  4594. public function getPatterns(Request $request);
  4595. }
  4596. }
  4597. namespace Symfony\Component\Security\Http
  4598. {
  4599. use Symfony\Component\HttpFoundation\RequestMatcherInterface;
  4600. use Symfony\Component\HttpFoundation\Request;
  4601. class AccessMap implements AccessMapInterface
  4602. {
  4603. private $map = array();
  4604. public function add(RequestMatcherInterface $requestMatcher, array $attributes = array(), $channel = null)
  4605. {
  4606. $this->map[] = array($requestMatcher, $attributes, $channel);
  4607. }
  4608. public function getPatterns(Request $request)
  4609. {
  4610. foreach ($this->map as $elements) {
  4611. if (null === $elements[0] || $elements[0]->matches($request)) {
  4612. return array($elements[1], $elements[2]);
  4613. }
  4614. }
  4615. return array(null, null);
  4616. }
  4617. }
  4618. }
  4619. namespace Symfony\Component\Security\Http
  4620. {
  4621. use Symfony\Component\HttpKernel\KernelEvents;
  4622. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  4623. use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
  4624. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  4625. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4626. class Firewall implements EventSubscriberInterface
  4627. {
  4628. private $map;
  4629. private $dispatcher;
  4630. private $exceptionListeners;
  4631. public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher)
  4632. {
  4633. $this->map = $map;
  4634. $this->dispatcher = $dispatcher;
  4635. $this->exceptionListeners = new \SplObjectStorage();
  4636. }
  4637. public function onKernelRequest(GetResponseEvent $event)
  4638. {
  4639. if (!$event->isMasterRequest()) {
  4640. return;
  4641. }
  4642. list($listeners, $exceptionListener) = $this->map->getListeners($event->getRequest());
  4643. if (null !== $exceptionListener) {
  4644. $this->exceptionListeners[$event->getRequest()] = $exceptionListener;
  4645. $exceptionListener->register($this->dispatcher);
  4646. }
  4647. foreach ($listeners as $listener) {
  4648. $listener->handle($event);
  4649. if ($event->hasResponse()) {
  4650. break;
  4651. }
  4652. }
  4653. }
  4654. public function onKernelFinishRequest(FinishRequestEvent $event)
  4655. {
  4656. $request = $event->getRequest();
  4657. if (isset($this->exceptionListeners[$request])) {
  4658. $this->exceptionListeners[$request]->unregister($this->dispatcher);
  4659. unset($this->exceptionListeners[$request]);
  4660. }
  4661. }
  4662. public static function getSubscribedEvents()
  4663. {
  4664. return array(
  4665. KernelEvents::REQUEST => array('onKernelRequest', 8),
  4666. KernelEvents::FINISH_REQUEST =>'onKernelFinishRequest',
  4667. );
  4668. }
  4669. }
  4670. }
  4671. namespace
  4672. {
  4673. class Twig_Environment
  4674. {
  4675. const VERSION ='1.15.1';
  4676. protected $charset;
  4677. protected $loader;
  4678. protected $debug;
  4679. protected $autoReload;
  4680. protected $cache;
  4681. protected $lexer;
  4682. protected $parser;
  4683. protected $compiler;
  4684. protected $baseTemplateClass;
  4685. protected $extensions;
  4686. protected $parsers;
  4687. protected $visitors;
  4688. protected $filters;
  4689. protected $tests;
  4690. protected $functions;
  4691. protected $globals;
  4692. protected $runtimeInitialized;
  4693. protected $extensionInitialized;
  4694. protected $loadedTemplates;
  4695. protected $strictVariables;
  4696. protected $unaryOperators;
  4697. protected $binaryOperators;
  4698. protected $templateClassPrefix ='__TwigTemplate_';
  4699. protected $functionCallbacks;
  4700. protected $filterCallbacks;
  4701. protected $staging;
  4702. public function __construct(Twig_LoaderInterface $loader = null, $options = array())
  4703. {
  4704. if (null !== $loader) {
  4705. $this->setLoader($loader);
  4706. }
  4707. $options = array_merge(array('debug'=> false,'charset'=>'UTF-8','base_template_class'=>'Twig_Template','strict_variables'=> false,'autoescape'=>'html','cache'=> false,'auto_reload'=> null,'optimizations'=> -1,
  4708. ), $options);
  4709. $this->debug = (bool) $options['debug'];
  4710. $this->charset = strtoupper($options['charset']);
  4711. $this->baseTemplateClass = $options['base_template_class'];
  4712. $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
  4713. $this->strictVariables = (bool) $options['strict_variables'];
  4714. $this->runtimeInitialized = false;
  4715. $this->setCache($options['cache']);
  4716. $this->functionCallbacks = array();
  4717. $this->filterCallbacks = array();
  4718. $this->addExtension(new Twig_Extension_Core());
  4719. $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
  4720. $this->addExtension(new Twig_Extension_Optimizer($options['optimizations']));
  4721. $this->extensionInitialized = false;
  4722. $this->staging = new Twig_Extension_Staging();
  4723. }
  4724. public function getBaseTemplateClass()
  4725. {
  4726. return $this->baseTemplateClass;
  4727. }
  4728. public function setBaseTemplateClass($class)
  4729. {
  4730. $this->baseTemplateClass = $class;
  4731. }
  4732. public function enableDebug()
  4733. {
  4734. $this->debug = true;
  4735. }
  4736. public function disableDebug()
  4737. {
  4738. $this->debug = false;
  4739. }
  4740. public function isDebug()
  4741. {
  4742. return $this->debug;
  4743. }
  4744. public function enableAutoReload()
  4745. {
  4746. $this->autoReload = true;
  4747. }
  4748. public function disableAutoReload()
  4749. {
  4750. $this->autoReload = false;
  4751. }
  4752. public function isAutoReload()
  4753. {
  4754. return $this->autoReload;
  4755. }
  4756. public function enableStrictVariables()
  4757. {
  4758. $this->strictVariables = true;
  4759. }
  4760. public function disableStrictVariables()
  4761. {
  4762. $this->strictVariables = false;
  4763. }
  4764. public function isStrictVariables()
  4765. {
  4766. return $this->strictVariables;
  4767. }
  4768. public function getCache()
  4769. {
  4770. return $this->cache;
  4771. }
  4772. public function setCache($cache)
  4773. {
  4774. $this->cache = $cache ? $cache : false;
  4775. }
  4776. public function getCacheFilename($name)
  4777. {
  4778. if (false === $this->cache) {
  4779. return false;
  4780. }
  4781. $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
  4782. return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php';
  4783. }
  4784. public function getTemplateClass($name, $index = null)
  4785. {
  4786. return $this->templateClassPrefix.hash('sha256', $this->getLoader()->getCacheKey($name)).(null === $index ?'':'_'.$index);
  4787. }
  4788. public function getTemplateClassPrefix()
  4789. {
  4790. return $this->templateClassPrefix;
  4791. }
  4792. public function render($name, array $context = array())
  4793. {
  4794. return $this->loadTemplate($name)->render($context);
  4795. }
  4796. public function display($name, array $context = array())
  4797. {
  4798. $this->loadTemplate($name)->display($context);
  4799. }
  4800. public function loadTemplate($name, $index = null)
  4801. {
  4802. $cls = $this->getTemplateClass($name, $index);
  4803. if (isset($this->loadedTemplates[$cls])) {
  4804. return $this->loadedTemplates[$cls];
  4805. }
  4806. if (!class_exists($cls, false)) {
  4807. if (false === $cache = $this->getCacheFilename($name)) {
  4808. eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name));
  4809. } else {
  4810. if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
  4811. $this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name));
  4812. }
  4813. require_once $cache;
  4814. }
  4815. }
  4816. if (!$this->runtimeInitialized) {
  4817. $this->initRuntime();
  4818. }
  4819. return $this->loadedTemplates[$cls] = new $cls($this);
  4820. }
  4821. public function isTemplateFresh($name, $time)
  4822. {
  4823. foreach ($this->extensions as $extension) {
  4824. $r = new ReflectionObject($extension);
  4825. if (filemtime($r->getFileName()) > $time) {
  4826. return false;
  4827. }
  4828. }
  4829. return $this->getLoader()->isFresh($name, $time);
  4830. }
  4831. public function resolveTemplate($names)
  4832. {
  4833. if (!is_array($names)) {
  4834. $names = array($names);
  4835. }
  4836. foreach ($names as $name) {
  4837. if ($name instanceof Twig_Template) {
  4838. return $name;
  4839. }
  4840. try {
  4841. return $this->loadTemplate($name);
  4842. } catch (Twig_Error_Loader $e) {
  4843. }
  4844. }
  4845. if (1 === count($names)) {
  4846. throw $e;
  4847. }
  4848. throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
  4849. }
  4850. public function clearTemplateCache()
  4851. {
  4852. $this->loadedTemplates = array();
  4853. }
  4854. public function clearCacheFiles()
  4855. {
  4856. if (false === $this->cache) {
  4857. return;
  4858. }
  4859. foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
  4860. if ($file->isFile()) {
  4861. @unlink($file->getPathname());
  4862. }
  4863. }
  4864. }
  4865. public function getLexer()
  4866. {
  4867. if (null === $this->lexer) {
  4868. $this->lexer = new Twig_Lexer($this);
  4869. }
  4870. return $this->lexer;
  4871. }
  4872. public function setLexer(Twig_LexerInterface $lexer)
  4873. {
  4874. $this->lexer = $lexer;
  4875. }
  4876. public function tokenize($source, $name = null)
  4877. {
  4878. return $this->getLexer()->tokenize($source, $name);
  4879. }
  4880. public function getParser()
  4881. {
  4882. if (null === $this->parser) {
  4883. $this->parser = new Twig_Parser($this);
  4884. }
  4885. return $this->parser;
  4886. }
  4887. public function setParser(Twig_ParserInterface $parser)
  4888. {
  4889. $this->parser = $parser;
  4890. }
  4891. public function parse(Twig_TokenStream $stream)
  4892. {
  4893. return $this->getParser()->parse($stream);
  4894. }
  4895. public function getCompiler()
  4896. {
  4897. if (null === $this->compiler) {
  4898. $this->compiler = new Twig_Compiler($this);
  4899. }
  4900. return $this->compiler;
  4901. }
  4902. public function setCompiler(Twig_CompilerInterface $compiler)
  4903. {
  4904. $this->compiler = $compiler;
  4905. }
  4906. public function compile(Twig_NodeInterface $node)
  4907. {
  4908. return $this->getCompiler()->compile($node)->getSource();
  4909. }
  4910. public function compileSource($source, $name = null)
  4911. {
  4912. try {
  4913. return $this->compile($this->parse($this->tokenize($source, $name)));
  4914. } catch (Twig_Error $e) {
  4915. $e->setTemplateFile($name);
  4916. throw $e;
  4917. } catch (Exception $e) {
  4918. throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
  4919. }
  4920. }
  4921. public function setLoader(Twig_LoaderInterface $loader)
  4922. {
  4923. $this->loader = $loader;
  4924. }
  4925. public function getLoader()
  4926. {
  4927. if (null === $this->loader) {
  4928. throw new LogicException('You must set a loader first.');
  4929. }
  4930. return $this->loader;
  4931. }
  4932. public function setCharset($charset)
  4933. {
  4934. $this->charset = strtoupper($charset);
  4935. }
  4936. public function getCharset()
  4937. {
  4938. return $this->charset;
  4939. }
  4940. public function initRuntime()
  4941. {
  4942. $this->runtimeInitialized = true;
  4943. foreach ($this->getExtensions() as $extension) {
  4944. $extension->initRuntime($this);
  4945. }
  4946. }
  4947. public function hasExtension($name)
  4948. {
  4949. return isset($this->extensions[$name]);
  4950. }
  4951. public function getExtension($name)
  4952. {
  4953. if (!isset($this->extensions[$name])) {
  4954. throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
  4955. }
  4956. return $this->extensions[$name];
  4957. }
  4958. public function addExtension(Twig_ExtensionInterface $extension)
  4959. {
  4960. if ($this->extensionInitialized) {
  4961. throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
  4962. }
  4963. $this->extensions[$extension->getName()] = $extension;
  4964. }
  4965. public function removeExtension($name)
  4966. {
  4967. if ($this->extensionInitialized) {
  4968. throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
  4969. }
  4970. unset($this->extensions[$name]);
  4971. }
  4972. public function setExtensions(array $extensions)
  4973. {
  4974. foreach ($extensions as $extension) {
  4975. $this->addExtension($extension);
  4976. }
  4977. }
  4978. public function getExtensions()
  4979. {
  4980. return $this->extensions;
  4981. }
  4982. public function addTokenParser(Twig_TokenParserInterface $parser)
  4983. {
  4984. if ($this->extensionInitialized) {
  4985. throw new LogicException('Unable to add a token parser as extensions have already been initialized.');
  4986. }
  4987. $this->staging->addTokenParser($parser);
  4988. }
  4989. public function getTokenParsers()
  4990. {
  4991. if (!$this->extensionInitialized) {
  4992. $this->initExtensions();
  4993. }
  4994. return $this->parsers;
  4995. }
  4996. public function getTags()
  4997. {
  4998. $tags = array();
  4999. foreach ($this->getTokenParsers()->getParsers() as $parser) {
  5000. if ($parser instanceof Twig_TokenParserInterface) {
  5001. $tags[$parser->getTag()] = $parser;
  5002. }
  5003. }
  5004. return $tags;
  5005. }
  5006. public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
  5007. {
  5008. if ($this->extensionInitialized) {
  5009. throw new LogicException('Unable to add a node visitor as extensions have already been initialized.');
  5010. }
  5011. $this->staging->addNodeVisitor($visitor);
  5012. }
  5013. public function getNodeVisitors()
  5014. {
  5015. if (!$this->extensionInitialized) {
  5016. $this->initExtensions();
  5017. }
  5018. return $this->visitors;
  5019. }
  5020. public function addFilter($name, $filter = null)
  5021. {
  5022. if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
  5023. throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter');
  5024. }
  5025. if ($name instanceof Twig_SimpleFilter) {
  5026. $filter = $name;
  5027. $name = $filter->getName();
  5028. }
  5029. if ($this->extensionInitialized) {
  5030. throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
  5031. }
  5032. $this->staging->addFilter($name, $filter);
  5033. }
  5034. public function getFilter($name)
  5035. {
  5036. if (!$this->extensionInitialized) {
  5037. $this->initExtensions();
  5038. }
  5039. if (isset($this->filters[$name])) {
  5040. return $this->filters[$name];
  5041. }
  5042. foreach ($this->filters as $pattern => $filter) {
  5043. $pattern = str_replace('\\*','(.*?)', preg_quote($pattern,'#'), $count);
  5044. if ($count) {
  5045. if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
  5046. array_shift($matches);
  5047. $filter->setArguments($matches);
  5048. return $filter;
  5049. }
  5050. }
  5051. }
  5052. foreach ($this->filterCallbacks as $callback) {
  5053. if (false !== $filter = call_user_func($callback, $name)) {
  5054. return $filter;
  5055. }
  5056. }
  5057. return false;
  5058. }
  5059. public function registerUndefinedFilterCallback($callable)
  5060. {
  5061. $this->filterCallbacks[] = $callable;
  5062. }
  5063. public function getFilters()
  5064. {
  5065. if (!$this->extensionInitialized) {
  5066. $this->initExtensions();
  5067. }
  5068. return $this->filters;
  5069. }
  5070. public function addTest($name, $test = null)
  5071. {
  5072. if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
  5073. throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest');
  5074. }
  5075. if ($name instanceof Twig_SimpleTest) {
  5076. $test = $name;
  5077. $name = $test->getName();
  5078. }
  5079. if ($this->extensionInitialized) {
  5080. throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
  5081. }
  5082. $this->staging->addTest($name, $test);
  5083. }
  5084. public function getTests()
  5085. {
  5086. if (!$this->extensionInitialized) {
  5087. $this->initExtensions();
  5088. }
  5089. return $this->tests;
  5090. }
  5091. public function getTest($name)
  5092. {
  5093. if (!$this->extensionInitialized) {
  5094. $this->initExtensions();
  5095. }
  5096. if (isset($this->tests[$name])) {
  5097. return $this->tests[$name];
  5098. }
  5099. return false;
  5100. }
  5101. public function addFunction($name, $function = null)
  5102. {
  5103. if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
  5104. throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction');
  5105. }
  5106. if ($name instanceof Twig_SimpleFunction) {
  5107. $function = $name;
  5108. $name = $function->getName();
  5109. }
  5110. if ($this->extensionInitialized) {
  5111. throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
  5112. }
  5113. $this->staging->addFunction($name, $function);
  5114. }
  5115. public function getFunction($name)
  5116. {
  5117. if (!$this->extensionInitialized) {
  5118. $this->initExtensions();
  5119. }
  5120. if (isset($this->functions[$name])) {
  5121. return $this->functions[$name];
  5122. }
  5123. foreach ($this->functions as $pattern => $function) {
  5124. $pattern = str_replace('\\*','(.*?)', preg_quote($pattern,'#'), $count);
  5125. if ($count) {
  5126. if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
  5127. array_shift($matches);
  5128. $function->setArguments($matches);
  5129. return $function;
  5130. }
  5131. }
  5132. }
  5133. foreach ($this->functionCallbacks as $callback) {
  5134. if (false !== $function = call_user_func($callback, $name)) {
  5135. return $function;
  5136. }
  5137. }
  5138. return false;
  5139. }
  5140. public function registerUndefinedFunctionCallback($callable)
  5141. {
  5142. $this->functionCallbacks[] = $callable;
  5143. }
  5144. public function getFunctions()
  5145. {
  5146. if (!$this->extensionInitialized) {
  5147. $this->initExtensions();
  5148. }
  5149. return $this->functions;
  5150. }
  5151. public function addGlobal($name, $value)
  5152. {
  5153. if ($this->extensionInitialized || $this->runtimeInitialized) {
  5154. if (null === $this->globals) {
  5155. $this->globals = $this->initGlobals();
  5156. }
  5157. }
  5158. if ($this->extensionInitialized || $this->runtimeInitialized) {
  5159. $this->globals[$name] = $value;
  5160. } else {
  5161. $this->staging->addGlobal($name, $value);
  5162. }
  5163. }
  5164. public function getGlobals()
  5165. {
  5166. if (!$this->runtimeInitialized && !$this->extensionInitialized) {
  5167. return $this->initGlobals();
  5168. }
  5169. if (null === $this->globals) {
  5170. $this->globals = $this->initGlobals();
  5171. }
  5172. return $this->globals;
  5173. }
  5174. public function mergeGlobals(array $context)
  5175. {
  5176. foreach ($this->getGlobals() as $key => $value) {
  5177. if (!array_key_exists($key, $context)) {
  5178. $context[$key] = $value;
  5179. }
  5180. }
  5181. return $context;
  5182. }
  5183. public function getUnaryOperators()
  5184. {
  5185. if (!$this->extensionInitialized) {
  5186. $this->initExtensions();
  5187. }
  5188. return $this->unaryOperators;
  5189. }
  5190. public function getBinaryOperators()
  5191. {
  5192. if (!$this->extensionInitialized) {
  5193. $this->initExtensions();
  5194. }
  5195. return $this->binaryOperators;
  5196. }
  5197. public function computeAlternatives($name, $items)
  5198. {
  5199. $alternatives = array();
  5200. foreach ($items as $item) {
  5201. $lev = levenshtein($name, $item);
  5202. if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
  5203. $alternatives[$item] = $lev;
  5204. }
  5205. }
  5206. asort($alternatives);
  5207. return array_keys($alternatives);
  5208. }
  5209. protected function initGlobals()
  5210. {
  5211. $globals = array();
  5212. foreach ($this->extensions as $extension) {
  5213. $extGlob = $extension->getGlobals();
  5214. if (!is_array($extGlob)) {
  5215. throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension)));
  5216. }
  5217. $globals[] = $extGlob;
  5218. }
  5219. $globals[] = $this->staging->getGlobals();
  5220. return call_user_func_array('array_merge', $globals);
  5221. }
  5222. protected function initExtensions()
  5223. {
  5224. if ($this->extensionInitialized) {
  5225. return;
  5226. }
  5227. $this->extensionInitialized = true;
  5228. $this->parsers = new Twig_TokenParserBroker();
  5229. $this->filters = array();
  5230. $this->functions = array();
  5231. $this->tests = array();
  5232. $this->visitors = array();
  5233. $this->unaryOperators = array();
  5234. $this->binaryOperators = array();
  5235. foreach ($this->extensions as $extension) {
  5236. $this->initExtension($extension);
  5237. }
  5238. $this->initExtension($this->staging);
  5239. }
  5240. protected function initExtension(Twig_ExtensionInterface $extension)
  5241. {
  5242. foreach ($extension->getFilters() as $name => $filter) {
  5243. if ($name instanceof Twig_SimpleFilter) {
  5244. $filter = $name;
  5245. $name = $filter->getName();
  5246. } elseif ($filter instanceof Twig_SimpleFilter) {
  5247. $name = $filter->getName();
  5248. }
  5249. $this->filters[$name] = $filter;
  5250. }
  5251. foreach ($extension->getFunctions() as $name => $function) {
  5252. if ($name instanceof Twig_SimpleFunction) {
  5253. $function = $name;
  5254. $name = $function->getName();
  5255. } elseif ($function instanceof Twig_SimpleFunction) {
  5256. $name = $function->getName();
  5257. }
  5258. $this->functions[$name] = $function;
  5259. }
  5260. foreach ($extension->getTests() as $name => $test) {
  5261. if ($name instanceof Twig_SimpleTest) {
  5262. $test = $name;
  5263. $name = $test->getName();
  5264. } elseif ($test instanceof Twig_SimpleTest) {
  5265. $name = $test->getName();
  5266. }
  5267. $this->tests[$name] = $test;
  5268. }
  5269. foreach ($extension->getTokenParsers() as $parser) {
  5270. if ($parser instanceof Twig_TokenParserInterface) {
  5271. $this->parsers->addTokenParser($parser);
  5272. } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
  5273. $this->parsers->addTokenParserBroker($parser);
  5274. } else {
  5275. throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
  5276. }
  5277. }
  5278. foreach ($extension->getNodeVisitors() as $visitor) {
  5279. $this->visitors[] = $visitor;
  5280. }
  5281. if ($operators = $extension->getOperators()) {
  5282. if (2 !== count($operators)) {
  5283. throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
  5284. }
  5285. $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
  5286. $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
  5287. }
  5288. }
  5289. protected function writeCacheFile($file, $content)
  5290. {
  5291. $dir = dirname($file);
  5292. if (!is_dir($dir)) {
  5293. if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
  5294. throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir));
  5295. }
  5296. } elseif (!is_writable($dir)) {
  5297. throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir));
  5298. }
  5299. $tmpFile = tempnam($dir, basename($file));
  5300. if (false !== @file_put_contents($tmpFile, $content)) {
  5301. if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
  5302. @chmod($file, 0666 & ~umask());
  5303. return;
  5304. }
  5305. }
  5306. throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file));
  5307. }
  5308. }
  5309. }
  5310. namespace
  5311. {
  5312. interface Twig_ExtensionInterface
  5313. {
  5314. public function initRuntime(Twig_Environment $environment);
  5315. public function getTokenParsers();
  5316. public function getNodeVisitors();
  5317. public function getFilters();
  5318. public function getTests();
  5319. public function getFunctions();
  5320. public function getOperators();
  5321. public function getGlobals();
  5322. public function getName();
  5323. }
  5324. }
  5325. namespace
  5326. {
  5327. abstract class Twig_Extension implements Twig_ExtensionInterface
  5328. {
  5329. public function initRuntime(Twig_Environment $environment)
  5330. {
  5331. }
  5332. public function getTokenParsers()
  5333. {
  5334. return array();
  5335. }
  5336. public function getNodeVisitors()
  5337. {
  5338. return array();
  5339. }
  5340. public function getFilters()
  5341. {
  5342. return array();
  5343. }
  5344. public function getTests()
  5345. {
  5346. return array();
  5347. }
  5348. public function getFunctions()
  5349. {
  5350. return array();
  5351. }
  5352. public function getOperators()
  5353. {
  5354. return array();
  5355. }
  5356. public function getGlobals()
  5357. {
  5358. return array();
  5359. }
  5360. }
  5361. }
  5362. namespace
  5363. {
  5364. if (!defined('ENT_SUBSTITUTE')) {
  5365. define('ENT_SUBSTITUTE', 0);
  5366. }
  5367. class Twig_Extension_Core extends Twig_Extension
  5368. {
  5369. protected $dateFormats = array('F j, Y H:i','%d days');
  5370. protected $numberFormat = array(0,'.',',');
  5371. protected $timezone = null;
  5372. protected $escapers = array();
  5373. public function setEscaper($strategy, $callable)
  5374. {
  5375. $this->escapers[$strategy] = $callable;
  5376. }
  5377. public function getEscapers()
  5378. {
  5379. return $this->escapers;
  5380. }
  5381. public function setDateFormat($format = null, $dateIntervalFormat = null)
  5382. {
  5383. if (null !== $format) {
  5384. $this->dateFormats[0] = $format;
  5385. }
  5386. if (null !== $dateIntervalFormat) {
  5387. $this->dateFormats[1] = $dateIntervalFormat;
  5388. }
  5389. }
  5390. public function getDateFormat()
  5391. {
  5392. return $this->dateFormats;
  5393. }
  5394. public function setTimezone($timezone)
  5395. {
  5396. $this->timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
  5397. }
  5398. public function getTimezone()
  5399. {
  5400. if (null === $this->timezone) {
  5401. $this->timezone = new DateTimeZone(date_default_timezone_get());
  5402. }
  5403. return $this->timezone;
  5404. }
  5405. public function setNumberFormat($decimal, $decimalPoint, $thousandSep)
  5406. {
  5407. $this->numberFormat = array($decimal, $decimalPoint, $thousandSep);
  5408. }
  5409. public function getNumberFormat()
  5410. {
  5411. return $this->numberFormat;
  5412. }
  5413. public function getTokenParsers()
  5414. {
  5415. return array(
  5416. new Twig_TokenParser_For(),
  5417. new Twig_TokenParser_If(),
  5418. new Twig_TokenParser_Extends(),
  5419. new Twig_TokenParser_Include(),
  5420. new Twig_TokenParser_Block(),
  5421. new Twig_TokenParser_Use(),
  5422. new Twig_TokenParser_Filter(),
  5423. new Twig_TokenParser_Macro(),
  5424. new Twig_TokenParser_Import(),
  5425. new Twig_TokenParser_From(),
  5426. new Twig_TokenParser_Set(),
  5427. new Twig_TokenParser_Spaceless(),
  5428. new Twig_TokenParser_Flush(),
  5429. new Twig_TokenParser_Do(),
  5430. new Twig_TokenParser_Embed(),
  5431. );
  5432. }
  5433. public function getFilters()
  5434. {
  5435. $filters = array(
  5436. new Twig_SimpleFilter('date','twig_date_format_filter', array('needs_environment'=> true)),
  5437. new Twig_SimpleFilter('date_modify','twig_date_modify_filter', array('needs_environment'=> true)),
  5438. new Twig_SimpleFilter('format','sprintf'),
  5439. new Twig_SimpleFilter('replace','strtr'),
  5440. new Twig_SimpleFilter('number_format','twig_number_format_filter', array('needs_environment'=> true)),
  5441. new Twig_SimpleFilter('abs','abs'),
  5442. new Twig_SimpleFilter('round','twig_round'),
  5443. new Twig_SimpleFilter('url_encode','twig_urlencode_filter'),
  5444. new Twig_SimpleFilter('json_encode','twig_jsonencode_filter'),
  5445. new Twig_SimpleFilter('convert_encoding','twig_convert_encoding'),
  5446. new Twig_SimpleFilter('title','twig_title_string_filter', array('needs_environment'=> true)),
  5447. new Twig_SimpleFilter('capitalize','twig_capitalize_string_filter', array('needs_environment'=> true)),
  5448. new Twig_SimpleFilter('upper','strtoupper'),
  5449. new Twig_SimpleFilter('lower','strtolower'),
  5450. new Twig_SimpleFilter('striptags','strip_tags'),
  5451. new Twig_SimpleFilter('trim','trim'),
  5452. new Twig_SimpleFilter('nl2br','nl2br', array('pre_escape'=>'html','is_safe'=> array('html'))),
  5453. new Twig_SimpleFilter('join','twig_join_filter'),
  5454. new Twig_SimpleFilter('split','twig_split_filter'),
  5455. new Twig_SimpleFilter('sort','twig_sort_filter'),
  5456. new Twig_SimpleFilter('merge','twig_array_merge'),
  5457. new Twig_SimpleFilter('batch','twig_array_batch'),
  5458. new Twig_SimpleFilter('reverse','twig_reverse_filter', array('needs_environment'=> true)),
  5459. new Twig_SimpleFilter('length','twig_length_filter', array('needs_environment'=> true)),
  5460. new Twig_SimpleFilter('slice','twig_slice', array('needs_environment'=> true)),
  5461. new Twig_SimpleFilter('first','twig_first', array('needs_environment'=> true)),
  5462. new Twig_SimpleFilter('last','twig_last', array('needs_environment'=> true)),
  5463. new Twig_SimpleFilter('default','_twig_default_filter', array('node_class'=>'Twig_Node_Expression_Filter_Default')),
  5464. new Twig_SimpleFilter('keys','twig_get_array_keys_filter'),
  5465. new Twig_SimpleFilter('escape','twig_escape_filter', array('needs_environment'=> true,'is_safe_callback'=>'twig_escape_filter_is_safe')),
  5466. new Twig_SimpleFilter('e','twig_escape_filter', array('needs_environment'=> true,'is_safe_callback'=>'twig_escape_filter_is_safe')),
  5467. );
  5468. if (function_exists('mb_get_info')) {
  5469. $filters[] = new Twig_SimpleFilter('upper','twig_upper_filter', array('needs_environment'=> true));
  5470. $filters[] = new Twig_SimpleFilter('lower','twig_lower_filter', array('needs_environment'=> true));
  5471. }
  5472. return $filters;
  5473. }
  5474. public function getFunctions()
  5475. {
  5476. return array(
  5477. new Twig_SimpleFunction('max','max'),
  5478. new Twig_SimpleFunction('min','min'),
  5479. new Twig_SimpleFunction('range','range'),
  5480. new Twig_SimpleFunction('constant','twig_constant'),
  5481. new Twig_SimpleFunction('cycle','twig_cycle'),
  5482. new Twig_SimpleFunction('random','twig_random', array('needs_environment'=> true)),
  5483. new Twig_SimpleFunction('date','twig_date_converter', array('needs_environment'=> true)),
  5484. new Twig_SimpleFunction('include','twig_include', array('needs_environment'=> true,'needs_context'=> true,'is_safe'=> array('all'))),
  5485. new Twig_SimpleFunction('source','twig_source', array('needs_environment'=> true,'is_safe'=> array('all'))),
  5486. );
  5487. }
  5488. public function getTests()
  5489. {
  5490. return array(
  5491. new Twig_SimpleTest('even', null, array('node_class'=>'Twig_Node_Expression_Test_Even')),
  5492. new Twig_SimpleTest('odd', null, array('node_class'=>'Twig_Node_Expression_Test_Odd')),
  5493. new Twig_SimpleTest('defined', null, array('node_class'=>'Twig_Node_Expression_Test_Defined')),
  5494. new Twig_SimpleTest('sameas', null, array('node_class'=>'Twig_Node_Expression_Test_Sameas')),
  5495. new Twig_SimpleTest('same as', null, array('node_class'=>'Twig_Node_Expression_Test_Sameas')),
  5496. new Twig_SimpleTest('none', null, array('node_class'=>'Twig_Node_Expression_Test_Null')),
  5497. new Twig_SimpleTest('null', null, array('node_class'=>'Twig_Node_Expression_Test_Null')),
  5498. new Twig_SimpleTest('divisibleby', null, array('node_class'=>'Twig_Node_Expression_Test_Divisibleby')),
  5499. new Twig_SimpleTest('divisible by', null, array('node_class'=>'Twig_Node_Expression_Test_Divisibleby')),
  5500. new Twig_SimpleTest('constant', null, array('node_class'=>'Twig_Node_Expression_Test_Constant')),
  5501. new Twig_SimpleTest('empty','twig_test_empty'),
  5502. new Twig_SimpleTest('iterable','twig_test_iterable'),
  5503. );
  5504. }
  5505. public function getOperators()
  5506. {
  5507. return array(
  5508. array('not'=> array('precedence'=> 50,'class'=>'Twig_Node_Expression_Unary_Not'),'-'=> array('precedence'=> 500,'class'=>'Twig_Node_Expression_Unary_Neg'),'+'=> array('precedence'=> 500,'class'=>'Twig_Node_Expression_Unary_Pos'),
  5509. ),
  5510. array('or'=> array('precedence'=> 10,'class'=>'Twig_Node_Expression_Binary_Or','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'and'=> array('precedence'=> 15,'class'=>'Twig_Node_Expression_Binary_And','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'b-or'=> array('precedence'=> 16,'class'=>'Twig_Node_Expression_Binary_BitwiseOr','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'b-xor'=> array('precedence'=> 17,'class'=>'Twig_Node_Expression_Binary_BitwiseXor','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'b-and'=> array('precedence'=> 18,'class'=>'Twig_Node_Expression_Binary_BitwiseAnd','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'=='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Equal','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'!='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_NotEqual','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'<'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Less','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'>'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Greater','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'>='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_GreaterEqual','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'<='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_LessEqual','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'not in'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_NotIn','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'in'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_In','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'matches'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Matches','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'starts with'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_StartsWith','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'ends with'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_EndsWith','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'..'=> array('precedence'=> 25,'class'=>'Twig_Node_Expression_Binary_Range','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'+'=> array('precedence'=> 30,'class'=>'Twig_Node_Expression_Binary_Add','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'-'=> array('precedence'=> 30,'class'=>'Twig_Node_Expression_Binary_Sub','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'~'=> array('precedence'=> 40,'class'=>'Twig_Node_Expression_Binary_Concat','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'*'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_Mul','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'/'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_Div','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'//'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_FloorDiv','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'%'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_Mod','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'is'=> array('precedence'=> 100,'callable'=> array($this,'parseTestExpression'),'associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'is not'=> array('precedence'=> 100,'callable'=> array($this,'parseNotTestExpression'),'associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'**'=> array('precedence'=> 200,'class'=>'Twig_Node_Expression_Binary_Power','associativity'=> Twig_ExpressionParser::OPERATOR_RIGHT),
  5511. ),
  5512. );
  5513. }
  5514. public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
  5515. {
  5516. return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
  5517. }
  5518. public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
  5519. {
  5520. $stream = $parser->getStream();
  5521. $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
  5522. $class = $this->getTestNodeClass($parser, $name, $node->getLine());
  5523. $arguments = null;
  5524. if ($stream->test(Twig_Token::PUNCTUATION_TYPE,'(')) {
  5525. $arguments = $parser->getExpressionParser()->parseArguments(true);
  5526. }
  5527. return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
  5528. }
  5529. protected function getTestNodeClass(Twig_Parser $parser, $name, $line)
  5530. {
  5531. $env = $parser->getEnvironment();
  5532. $testMap = $env->getTests();
  5533. $testName = null;
  5534. if (isset($testMap[$name])) {
  5535. $testName = $name;
  5536. } elseif ($parser->getStream()->test(Twig_Token::NAME_TYPE)) {
  5537. $name = $name.' '.$parser->getCurrentToken()->getValue();
  5538. if (isset($testMap[$name])) {
  5539. $parser->getStream()->next();
  5540. $testName = $name;
  5541. }
  5542. }
  5543. if (null === $testName) {
  5544. $message = sprintf('The test "%s" does not exist', $name);
  5545. if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) {
  5546. $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
  5547. }
  5548. throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
  5549. }
  5550. if ($testMap[$name] instanceof Twig_SimpleTest) {
  5551. return $testMap[$name]->getNodeClass();
  5552. }
  5553. return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() :'Twig_Node_Expression_Test';
  5554. }
  5555. public function getName()
  5556. {
  5557. return'core';
  5558. }
  5559. }
  5560. function twig_cycle($values, $position)
  5561. {
  5562. if (!is_array($values) && !$values instanceof ArrayAccess) {
  5563. return $values;
  5564. }
  5565. return $values[$position % count($values)];
  5566. }
  5567. function twig_random(Twig_Environment $env, $values = null)
  5568. {
  5569. if (null === $values) {
  5570. return mt_rand();
  5571. }
  5572. if (is_int($values) || is_float($values)) {
  5573. return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values);
  5574. }
  5575. if ($values instanceof Traversable) {
  5576. $values = iterator_to_array($values);
  5577. } elseif (is_string($values)) {
  5578. if (''=== $values) {
  5579. return'';
  5580. }
  5581. if (null !== $charset = $env->getCharset()) {
  5582. if ('UTF-8'!= $charset) {
  5583. $values = twig_convert_encoding($values,'UTF-8', $charset);
  5584. }
  5585. $values = preg_split('/(?<!^)(?!$)/u', $values);
  5586. if ('UTF-8'!= $charset) {
  5587. foreach ($values as $i => $value) {
  5588. $values[$i] = twig_convert_encoding($value, $charset,'UTF-8');
  5589. }
  5590. }
  5591. } else {
  5592. return $values[mt_rand(0, strlen($values) - 1)];
  5593. }
  5594. }
  5595. if (!is_array($values)) {
  5596. return $values;
  5597. }
  5598. if (0 === count($values)) {
  5599. throw new Twig_Error_Runtime('The random function cannot pick from an empty array.');
  5600. }
  5601. return $values[array_rand($values, 1)];
  5602. }
  5603. function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
  5604. {
  5605. if (null === $format) {
  5606. $formats = $env->getExtension('core')->getDateFormat();
  5607. $format = $date instanceof DateInterval ? $formats[1] : $formats[0];
  5608. }
  5609. if ($date instanceof DateInterval) {
  5610. return $date->format($format);
  5611. }
  5612. return twig_date_converter($env, $date, $timezone)->format($format);
  5613. }
  5614. function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
  5615. {
  5616. $date = twig_date_converter($env, $date, false);
  5617. $date->modify($modifier);
  5618. return $date;
  5619. }
  5620. function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null)
  5621. {
  5622. if (!$timezone) {
  5623. $defaultTimezone = $env->getExtension('core')->getTimezone();
  5624. } elseif (!$timezone instanceof DateTimeZone) {
  5625. $defaultTimezone = new DateTimeZone($timezone);
  5626. } else {
  5627. $defaultTimezone = $timezone;
  5628. }
  5629. if ($date instanceof DateTimeImmutable) {
  5630. return false !== $timezone ? $date->setTimezone($defaultTimezone) : $date;
  5631. }
  5632. if ($date instanceof DateTime || $date instanceof DateTimeInterface) {
  5633. $date = clone $date;
  5634. if (false !== $timezone) {
  5635. $date->setTimezone($defaultTimezone);
  5636. }
  5637. return $date;
  5638. }
  5639. $asString = (string) $date;
  5640. if (ctype_digit($asString) || (!empty($asString) &&'-'=== $asString[0] && ctype_digit(substr($asString, 1)))) {
  5641. $date ='@'.$date;
  5642. }
  5643. $date = new DateTime($date, $defaultTimezone);
  5644. if (false !== $timezone) {
  5645. $date->setTimezone($defaultTimezone);
  5646. }
  5647. return $date;
  5648. }
  5649. function twig_round($value, $precision = 0, $method ='common')
  5650. {
  5651. if ('common'== $method) {
  5652. return round($value, $precision);
  5653. }
  5654. if ('ceil'!= $method &&'floor'!= $method) {
  5655. throw new Twig_Error_Runtime('The round filter only supports the "common", "ceil", and "floor" methods.');
  5656. }
  5657. return $method($value * pow(10, $precision)) / pow(10, $precision);
  5658. }
  5659. function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
  5660. {
  5661. $defaults = $env->getExtension('core')->getNumberFormat();
  5662. if (null === $decimal) {
  5663. $decimal = $defaults[0];
  5664. }
  5665. if (null === $decimalPoint) {
  5666. $decimalPoint = $defaults[1];
  5667. }
  5668. if (null === $thousandSep) {
  5669. $thousandSep = $defaults[2];
  5670. }
  5671. return number_format((float) $number, $decimal, $decimalPoint, $thousandSep);
  5672. }
  5673. function twig_urlencode_filter($url, $raw = false)
  5674. {
  5675. if (is_array($url)) {
  5676. return http_build_query($url,'','&');
  5677. }
  5678. if ($raw) {
  5679. return rawurlencode($url);
  5680. }
  5681. return urlencode($url);
  5682. }
  5683. if (version_compare(PHP_VERSION,'5.3.0','<')) {
  5684. function twig_jsonencode_filter($value, $options = 0)
  5685. {
  5686. if ($value instanceof Twig_Markup) {
  5687. $value = (string) $value;
  5688. } elseif (is_array($value)) {
  5689. array_walk_recursive($value,'_twig_markup2string');
  5690. }
  5691. return json_encode($value);
  5692. }
  5693. } else {
  5694. function twig_jsonencode_filter($value, $options = 0)
  5695. {
  5696. if ($value instanceof Twig_Markup) {
  5697. $value = (string) $value;
  5698. } elseif (is_array($value)) {
  5699. array_walk_recursive($value,'_twig_markup2string');
  5700. }
  5701. return json_encode($value, $options);
  5702. }
  5703. }
  5704. function _twig_markup2string(&$value)
  5705. {
  5706. if ($value instanceof Twig_Markup) {
  5707. $value = (string) $value;
  5708. }
  5709. }
  5710. function twig_array_merge($arr1, $arr2)
  5711. {
  5712. if (!is_array($arr1) || !is_array($arr2)) {
  5713. throw new Twig_Error_Runtime('The merge filter only works with arrays or hashes.');
  5714. }
  5715. return array_merge($arr1, $arr2);
  5716. }
  5717. function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
  5718. {
  5719. if ($item instanceof Traversable) {
  5720. $item = iterator_to_array($item, false);
  5721. }
  5722. if (is_array($item)) {
  5723. return array_slice($item, $start, $length, $preserveKeys);
  5724. }
  5725. $item = (string) $item;
  5726. if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
  5727. return mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
  5728. }
  5729. return null === $length ? substr($item, $start) : substr($item, $start, $length);
  5730. }
  5731. function twig_first(Twig_Environment $env, $item)
  5732. {
  5733. $elements = twig_slice($env, $item, 0, 1, false);
  5734. return is_string($elements) ? $elements : current($elements);
  5735. }
  5736. function twig_last(Twig_Environment $env, $item)
  5737. {
  5738. $elements = twig_slice($env, $item, -1, 1, false);
  5739. return is_string($elements) ? $elements : current($elements);
  5740. }
  5741. function twig_join_filter($value, $glue ='')
  5742. {
  5743. if ($value instanceof Traversable) {
  5744. $value = iterator_to_array($value, false);
  5745. }
  5746. return implode($glue, (array) $value);
  5747. }
  5748. function twig_split_filter($value, $delimiter, $limit = null)
  5749. {
  5750. if (empty($delimiter)) {
  5751. return str_split($value, null === $limit ? 1 : $limit);
  5752. }
  5753. return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
  5754. }
  5755. function _twig_default_filter($value, $default ='')
  5756. {
  5757. if (twig_test_empty($value)) {
  5758. return $default;
  5759. }
  5760. return $value;
  5761. }
  5762. function twig_get_array_keys_filter($array)
  5763. {
  5764. if (is_object($array) && $array instanceof Traversable) {
  5765. return array_keys(iterator_to_array($array));
  5766. }
  5767. if (!is_array($array)) {
  5768. return array();
  5769. }
  5770. return array_keys($array);
  5771. }
  5772. function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false)
  5773. {
  5774. if (is_object($item) && $item instanceof Traversable) {
  5775. return array_reverse(iterator_to_array($item), $preserveKeys);
  5776. }
  5777. if (is_array($item)) {
  5778. return array_reverse($item, $preserveKeys);
  5779. }
  5780. if (null !== $charset = $env->getCharset()) {
  5781. $string = (string) $item;
  5782. if ('UTF-8'!= $charset) {
  5783. $item = twig_convert_encoding($string,'UTF-8', $charset);
  5784. }
  5785. preg_match_all('/./us', $item, $matches);
  5786. $string = implode('', array_reverse($matches[0]));
  5787. if ('UTF-8'!= $charset) {
  5788. $string = twig_convert_encoding($string, $charset,'UTF-8');
  5789. }
  5790. return $string;
  5791. }
  5792. return strrev((string) $item);
  5793. }
  5794. function twig_sort_filter($array)
  5795. {
  5796. asort($array);
  5797. return $array;
  5798. }
  5799. function twig_in_filter($value, $compare)
  5800. {
  5801. if (is_array($compare)) {
  5802. return in_array($value, $compare, is_object($value));
  5803. } elseif (is_string($compare)) {
  5804. if (!strlen($value)) {
  5805. return empty($compare);
  5806. }
  5807. return false !== strpos($compare, (string) $value);
  5808. } elseif ($compare instanceof Traversable) {
  5809. return in_array($value, iterator_to_array($compare, false), is_object($value));
  5810. }
  5811. return false;
  5812. }
  5813. function twig_escape_filter(Twig_Environment $env, $string, $strategy ='html', $charset = null, $autoescape = false)
  5814. {
  5815. if ($autoescape && $string instanceof Twig_Markup) {
  5816. return $string;
  5817. }
  5818. if (!is_string($string)) {
  5819. if (is_object($string) && method_exists($string,'__toString')) {
  5820. $string = (string) $string;
  5821. } else {
  5822. return $string;
  5823. }
  5824. }
  5825. if (null === $charset) {
  5826. $charset = $env->getCharset();
  5827. }
  5828. switch ($strategy) {
  5829. case'html':
  5830. static $htmlspecialcharsCharsets;
  5831. if (null === $htmlspecialcharsCharsets) {
  5832. if ('hiphop'=== substr(PHP_VERSION, -6)) {
  5833. $htmlspecialcharsCharsets = array('utf-8'=> true,'UTF-8'=> true);
  5834. } else {
  5835. $htmlspecialcharsCharsets = array('ISO-8859-1'=> true,'ISO8859-1'=> true,'ISO-8859-15'=> true,'ISO8859-15'=> true,'utf-8'=> true,'UTF-8'=> true,'CP866'=> true,'IBM866'=> true,'866'=> true,'CP1251'=> true,'WINDOWS-1251'=> true,'WIN-1251'=> true,'1251'=> true,'CP1252'=> true,'WINDOWS-1252'=> true,'1252'=> true,'KOI8-R'=> true,'KOI8-RU'=> true,'KOI8R'=> true,'BIG5'=> true,'950'=> true,'GB2312'=> true,'936'=> true,'BIG5-HKSCS'=> true,'SHIFT_JIS'=> true,'SJIS'=> true,'932'=> true,'EUC-JP'=> true,'EUCJP'=> true,'ISO8859-5'=> true,'ISO-8859-5'=> true,'MACROMAN'=> true,
  5836. );
  5837. }
  5838. }
  5839. if (isset($htmlspecialcharsCharsets[$charset])) {
  5840. return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
  5841. }
  5842. if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) {
  5843. $htmlspecialcharsCharsets[$charset] = true;
  5844. return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
  5845. }
  5846. $string = twig_convert_encoding($string,'UTF-8', $charset);
  5847. $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE,'UTF-8');
  5848. return twig_convert_encoding($string, $charset,'UTF-8');
  5849. case'js':
  5850. if ('UTF-8'!= $charset) {
  5851. $string = twig_convert_encoding($string,'UTF-8', $charset);
  5852. }
  5853. if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
  5854. throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
  5855. }
  5856. $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su','_twig_escape_js_callback', $string);
  5857. if ('UTF-8'!= $charset) {
  5858. $string = twig_convert_encoding($string, $charset,'UTF-8');
  5859. }
  5860. return $string;
  5861. case'css':
  5862. if ('UTF-8'!= $charset) {
  5863. $string = twig_convert_encoding($string,'UTF-8', $charset);
  5864. }
  5865. if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
  5866. throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
  5867. }
  5868. $string = preg_replace_callback('#[^a-zA-Z0-9]#Su','_twig_escape_css_callback', $string);
  5869. if ('UTF-8'!= $charset) {
  5870. $string = twig_convert_encoding($string, $charset,'UTF-8');
  5871. }
  5872. return $string;
  5873. case'html_attr':
  5874. if ('UTF-8'!= $charset) {
  5875. $string = twig_convert_encoding($string,'UTF-8', $charset);
  5876. }
  5877. if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
  5878. throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
  5879. }
  5880. $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su','_twig_escape_html_attr_callback', $string);
  5881. if ('UTF-8'!= $charset) {
  5882. $string = twig_convert_encoding($string, $charset,'UTF-8');
  5883. }
  5884. return $string;
  5885. case'url':
  5886. if (PHP_VERSION <'5.3.0') {
  5887. return str_replace('%7E','~', rawurlencode($string));
  5888. }
  5889. return rawurlencode($string);
  5890. default:
  5891. static $escapers;
  5892. if (null === $escapers) {
  5893. $escapers = $env->getExtension('core')->getEscapers();
  5894. }
  5895. if (isset($escapers[$strategy])) {
  5896. return call_user_func($escapers[$strategy], $env, $string, $charset);
  5897. }
  5898. $validStrategies = implode(', ', array_merge(array('html','js','url','css','html_attr'), array_keys($escapers)));
  5899. throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
  5900. }
  5901. }
  5902. function twig_escape_filter_is_safe(Twig_Node $filterArgs)
  5903. {
  5904. foreach ($filterArgs as $arg) {
  5905. if ($arg instanceof Twig_Node_Expression_Constant) {
  5906. return array($arg->getAttribute('value'));
  5907. }
  5908. return array();
  5909. }
  5910. return array('html');
  5911. }
  5912. if (function_exists('mb_convert_encoding')) {
  5913. function twig_convert_encoding($string, $to, $from)
  5914. {
  5915. return mb_convert_encoding($string, $to, $from);
  5916. }
  5917. } elseif (function_exists('iconv')) {
  5918. function twig_convert_encoding($string, $to, $from)
  5919. {
  5920. return iconv($from, $to, $string);
  5921. }
  5922. } else {
  5923. function twig_convert_encoding($string, $to, $from)
  5924. {
  5925. throw new Twig_Error_Runtime('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
  5926. }
  5927. }
  5928. function _twig_escape_js_callback($matches)
  5929. {
  5930. $char = $matches[0];
  5931. if (!isset($char[1])) {
  5932. return'\\x'.strtoupper(substr('00'.bin2hex($char), -2));
  5933. }
  5934. $char = twig_convert_encoding($char,'UTF-16BE','UTF-8');
  5935. return'\\u'.strtoupper(substr('0000'.bin2hex($char), -4));
  5936. }
  5937. function _twig_escape_css_callback($matches)
  5938. {
  5939. $char = $matches[0];
  5940. if (!isset($char[1])) {
  5941. $hex = ltrim(strtoupper(bin2hex($char)),'0');
  5942. if (0 === strlen($hex)) {
  5943. $hex ='0';
  5944. }
  5945. return'\\'.$hex.' ';
  5946. }
  5947. $char = twig_convert_encoding($char,'UTF-16BE','UTF-8');
  5948. return'\\'.ltrim(strtoupper(bin2hex($char)),'0').' ';
  5949. }
  5950. function _twig_escape_html_attr_callback($matches)
  5951. {
  5952. static $entityMap = array(
  5953. 34 =>'quot',
  5954. 38 =>'amp',
  5955. 60 =>'lt',
  5956. 62 =>'gt',
  5957. );
  5958. $chr = $matches[0];
  5959. $ord = ord($chr);
  5960. if (($ord <= 0x1f && $chr !="\t"&& $chr !="\n"&& $chr !="\r") || ($ord >= 0x7f && $ord <= 0x9f)) {
  5961. return'&#xFFFD;';
  5962. }
  5963. if (strlen($chr) == 1) {
  5964. $hex = strtoupper(substr('00'.bin2hex($chr), -2));
  5965. } else {
  5966. $chr = twig_convert_encoding($chr,'UTF-16BE','UTF-8');
  5967. $hex = strtoupper(substr('0000'.bin2hex($chr), -4));
  5968. }
  5969. $int = hexdec($hex);
  5970. if (array_key_exists($int, $entityMap)) {
  5971. return sprintf('&%s;', $entityMap[$int]);
  5972. }
  5973. return sprintf('&#x%s;', $hex);
  5974. }
  5975. if (function_exists('mb_get_info')) {
  5976. function twig_length_filter(Twig_Environment $env, $thing)
  5977. {
  5978. return is_scalar($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing);
  5979. }
  5980. function twig_upper_filter(Twig_Environment $env, $string)
  5981. {
  5982. if (null !== ($charset = $env->getCharset())) {
  5983. return mb_strtoupper($string, $charset);
  5984. }
  5985. return strtoupper($string);
  5986. }
  5987. function twig_lower_filter(Twig_Environment $env, $string)
  5988. {
  5989. if (null !== ($charset = $env->getCharset())) {
  5990. return mb_strtolower($string, $charset);
  5991. }
  5992. return strtolower($string);
  5993. }
  5994. function twig_title_string_filter(Twig_Environment $env, $string)
  5995. {
  5996. if (null !== ($charset = $env->getCharset())) {
  5997. return mb_convert_case($string, MB_CASE_TITLE, $charset);
  5998. }
  5999. return ucwords(strtolower($string));
  6000. }
  6001. function twig_capitalize_string_filter(Twig_Environment $env, $string)
  6002. {
  6003. if (null !== ($charset = $env->getCharset())) {
  6004. return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).
  6005. mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
  6006. }
  6007. return ucfirst(strtolower($string));
  6008. }
  6009. }
  6010. else {
  6011. function twig_length_filter(Twig_Environment $env, $thing)
  6012. {
  6013. return is_scalar($thing) ? strlen($thing) : count($thing);
  6014. }
  6015. function twig_title_string_filter(Twig_Environment $env, $string)
  6016. {
  6017. return ucwords(strtolower($string));
  6018. }
  6019. function twig_capitalize_string_filter(Twig_Environment $env, $string)
  6020. {
  6021. return ucfirst(strtolower($string));
  6022. }
  6023. }
  6024. function twig_ensure_traversable($seq)
  6025. {
  6026. if ($seq instanceof Traversable || is_array($seq)) {
  6027. return $seq;
  6028. }
  6029. return array();
  6030. }
  6031. function twig_test_empty($value)
  6032. {
  6033. if ($value instanceof Countable) {
  6034. return 0 == count($value);
  6035. }
  6036. return''=== $value || false === $value || null === $value || array() === $value;
  6037. }
  6038. function twig_test_iterable($value)
  6039. {
  6040. return $value instanceof Traversable || is_array($value);
  6041. }
  6042. function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false)
  6043. {
  6044. $alreadySandboxed = false;
  6045. $sandbox = null;
  6046. if ($withContext) {
  6047. $variables = array_merge($context, $variables);
  6048. }
  6049. if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) {
  6050. $sandbox = $env->getExtension('sandbox');
  6051. if (!$alreadySandboxed = $sandbox->isSandboxed()) {
  6052. $sandbox->enableSandbox();
  6053. }
  6054. }
  6055. try {
  6056. return $env->resolveTemplate($template)->render($variables);
  6057. } catch (Twig_Error_Loader $e) {
  6058. if (!$ignoreMissing) {
  6059. throw $e;
  6060. }
  6061. }
  6062. if ($isSandboxed && !$alreadySandboxed) {
  6063. $sandbox->disableSandbox();
  6064. }
  6065. }
  6066. function twig_source(Twig_Environment $env, $name)
  6067. {
  6068. return $env->getLoader()->getSource($name);
  6069. }
  6070. function twig_constant($constant, $object = null)
  6071. {
  6072. if (null !== $object) {
  6073. $constant = get_class($object).'::'.$constant;
  6074. }
  6075. return constant($constant);
  6076. }
  6077. function twig_array_batch($items, $size, $fill = null)
  6078. {
  6079. if ($items instanceof Traversable) {
  6080. $items = iterator_to_array($items, false);
  6081. }
  6082. $size = ceil($size);
  6083. $result = array_chunk($items, $size, true);
  6084. if (null !== $fill) {
  6085. $last = count($result) - 1;
  6086. if ($fillCount = $size - count($result[$last])) {
  6087. $result[$last] = array_merge(
  6088. $result[$last],
  6089. array_fill(0, $fillCount, $fill)
  6090. );
  6091. }
  6092. }
  6093. return $result;
  6094. }
  6095. }
  6096. namespace
  6097. {
  6098. class Twig_Extension_Escaper extends Twig_Extension
  6099. {
  6100. protected $defaultStrategy;
  6101. public function __construct($defaultStrategy ='html')
  6102. {
  6103. $this->setDefaultStrategy($defaultStrategy);
  6104. }
  6105. public function getTokenParsers()
  6106. {
  6107. return array(new Twig_TokenParser_AutoEscape());
  6108. }
  6109. public function getNodeVisitors()
  6110. {
  6111. return array(new Twig_NodeVisitor_Escaper());
  6112. }
  6113. public function getFilters()
  6114. {
  6115. return array(
  6116. new Twig_SimpleFilter('raw','twig_raw_filter', array('is_safe'=> array('all'))),
  6117. );
  6118. }
  6119. public function setDefaultStrategy($defaultStrategy)
  6120. {
  6121. if (true === $defaultStrategy) {
  6122. $defaultStrategy ='html';
  6123. }
  6124. $this->defaultStrategy = $defaultStrategy;
  6125. }
  6126. public function getDefaultStrategy($filename)
  6127. {
  6128. if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) {
  6129. return call_user_func($this->defaultStrategy, $filename);
  6130. }
  6131. return $this->defaultStrategy;
  6132. }
  6133. public function getName()
  6134. {
  6135. return'escaper';
  6136. }
  6137. }
  6138. function twig_raw_filter($string)
  6139. {
  6140. return $string;
  6141. }
  6142. }
  6143. namespace
  6144. {
  6145. class Twig_Extension_Optimizer extends Twig_Extension
  6146. {
  6147. protected $optimizers;
  6148. public function __construct($optimizers = -1)
  6149. {
  6150. $this->optimizers = $optimizers;
  6151. }
  6152. public function getNodeVisitors()
  6153. {
  6154. return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
  6155. }
  6156. public function getName()
  6157. {
  6158. return'optimizer';
  6159. }
  6160. }
  6161. }
  6162. namespace
  6163. {
  6164. interface Twig_LoaderInterface
  6165. {
  6166. public function getSource($name);
  6167. public function getCacheKey($name);
  6168. public function isFresh($name, $time);
  6169. }
  6170. }
  6171. namespace
  6172. {
  6173. class Twig_Markup implements Countable
  6174. {
  6175. protected $content;
  6176. protected $charset;
  6177. public function __construct($content, $charset)
  6178. {
  6179. $this->content = (string) $content;
  6180. $this->charset = $charset;
  6181. }
  6182. public function __toString()
  6183. {
  6184. return $this->content;
  6185. }
  6186. public function count()
  6187. {
  6188. return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content);
  6189. }
  6190. }
  6191. }
  6192. namespace
  6193. {
  6194. interface Twig_TemplateInterface
  6195. {
  6196. const ANY_CALL ='any';
  6197. const ARRAY_CALL ='array';
  6198. const METHOD_CALL ='method';
  6199. public function render(array $context);
  6200. public function display(array $context, array $blocks = array());
  6201. public function getEnvironment();
  6202. }
  6203. }
  6204. namespace
  6205. {
  6206. abstract class Twig_Template implements Twig_TemplateInterface
  6207. {
  6208. protected static $cache = array();
  6209. protected $parent;
  6210. protected $parents;
  6211. protected $env;
  6212. protected $blocks;
  6213. protected $traits;
  6214. public function __construct(Twig_Environment $env)
  6215. {
  6216. $this->env = $env;
  6217. $this->blocks = array();
  6218. $this->traits = array();
  6219. }
  6220. abstract public function getTemplateName();
  6221. public function getEnvironment()
  6222. {
  6223. return $this->env;
  6224. }
  6225. public function getParent(array $context)
  6226. {
  6227. if (null !== $this->parent) {
  6228. return $this->parent;
  6229. }
  6230. $parent = $this->doGetParent($context);
  6231. if (false === $parent) {
  6232. return false;
  6233. } elseif ($parent instanceof Twig_Template) {
  6234. $name = $parent->getTemplateName();
  6235. $this->parents[$name] = $parent;
  6236. $parent = $name;
  6237. } elseif (!isset($this->parents[$parent])) {
  6238. $this->parents[$parent] = $this->env->loadTemplate($parent);
  6239. }
  6240. return $this->parents[$parent];
  6241. }
  6242. protected function doGetParent(array $context)
  6243. {
  6244. return false;
  6245. }
  6246. public function isTraitable()
  6247. {
  6248. return true;
  6249. }
  6250. public function displayParentBlock($name, array $context, array $blocks = array())
  6251. {
  6252. $name = (string) $name;
  6253. if (isset($this->traits[$name])) {
  6254. $this->traits[$name][0]->displayBlock($name, $context, $blocks);
  6255. } elseif (false !== $parent = $this->getParent($context)) {
  6256. $parent->displayBlock($name, $context, $blocks);
  6257. } else {
  6258. throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
  6259. }
  6260. }
  6261. public function displayBlock($name, array $context, array $blocks = array())
  6262. {
  6263. $name = (string) $name;
  6264. if (isset($blocks[$name])) {
  6265. $template = $blocks[$name][0];
  6266. $block = $blocks[$name][1];
  6267. unset($blocks[$name]);
  6268. } elseif (isset($this->blocks[$name])) {
  6269. $template = $this->blocks[$name][0];
  6270. $block = $this->blocks[$name][1];
  6271. } else {
  6272. $template = null;
  6273. $block = null;
  6274. }
  6275. if (null !== $template) {
  6276. try {
  6277. $template->$block($context, $blocks);
  6278. } catch (Twig_Error $e) {
  6279. throw $e;
  6280. } catch (Exception $e) {
  6281. throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e);
  6282. }
  6283. } elseif (false !== $parent = $this->getParent($context)) {
  6284. $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks));
  6285. }
  6286. }
  6287. public function renderParentBlock($name, array $context, array $blocks = array())
  6288. {
  6289. ob_start();
  6290. $this->displayParentBlock($name, $context, $blocks);
  6291. return ob_get_clean();
  6292. }
  6293. public function renderBlock($name, array $context, array $blocks = array())
  6294. {
  6295. ob_start();
  6296. $this->displayBlock($name, $context, $blocks);
  6297. return ob_get_clean();
  6298. }
  6299. public function hasBlock($name)
  6300. {
  6301. return isset($this->blocks[(string) $name]);
  6302. }
  6303. public function getBlockNames()
  6304. {
  6305. return array_keys($this->blocks);
  6306. }
  6307. public function getBlocks()
  6308. {
  6309. return $this->blocks;
  6310. }
  6311. public function display(array $context, array $blocks = array())
  6312. {
  6313. $this->displayWithErrorHandling($this->env->mergeGlobals($context), $blocks);
  6314. }
  6315. public function render(array $context)
  6316. {
  6317. $level = ob_get_level();
  6318. ob_start();
  6319. try {
  6320. $this->display($context);
  6321. } catch (Exception $e) {
  6322. while (ob_get_level() > $level) {
  6323. ob_end_clean();
  6324. }
  6325. throw $e;
  6326. }
  6327. return ob_get_clean();
  6328. }
  6329. protected function displayWithErrorHandling(array $context, array $blocks = array())
  6330. {
  6331. try {
  6332. $this->doDisplay($context, $blocks);
  6333. } catch (Twig_Error $e) {
  6334. if (!$e->getTemplateFile()) {
  6335. $e->setTemplateFile($this->getTemplateName());
  6336. }
  6337. if (false === $e->getTemplateLine()) {
  6338. $e->setTemplateLine(-1);
  6339. $e->guess();
  6340. }
  6341. throw $e;
  6342. } catch (Exception $e) {
  6343. throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e);
  6344. }
  6345. }
  6346. abstract protected function doDisplay(array $context, array $blocks = array());
  6347. final protected function getContext($context, $item, $ignoreStrictCheck = false)
  6348. {
  6349. if (!array_key_exists($item, $context)) {
  6350. if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
  6351. return null;
  6352. }
  6353. throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName());
  6354. }
  6355. return $context[$item];
  6356. }
  6357. protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_Template::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
  6358. {
  6359. if (Twig_Template::METHOD_CALL !== $type) {
  6360. $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
  6361. if ((is_array($object) && array_key_exists($arrayItem, $object))
  6362. || ($object instanceof ArrayAccess && isset($object[$arrayItem]))
  6363. ) {
  6364. if ($isDefinedTest) {
  6365. return true;
  6366. }
  6367. return $object[$arrayItem];
  6368. }
  6369. if (Twig_Template::ARRAY_CALL === $type || !is_object($object)) {
  6370. if ($isDefinedTest) {
  6371. return false;
  6372. }
  6373. if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
  6374. return null;
  6375. }
  6376. if ($object instanceof ArrayAccess) {
  6377. $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object));
  6378. } elseif (is_object($object)) {
  6379. $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
  6380. } elseif (is_array($object)) {
  6381. $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
  6382. } elseif (Twig_Template::ARRAY_CALL === $type) {
  6383. $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
  6384. } else {
  6385. $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
  6386. }
  6387. throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
  6388. }
  6389. }
  6390. if (!is_object($object)) {
  6391. if ($isDefinedTest) {
  6392. return false;
  6393. }
  6394. if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
  6395. return null;
  6396. }
  6397. throw new Twig_Error_Runtime(sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
  6398. }
  6399. $class = get_class($object);
  6400. if (Twig_Template::METHOD_CALL !== $type) {
  6401. if (isset($object->$item) || array_key_exists((string) $item, $object)) {
  6402. if ($isDefinedTest) {
  6403. return true;
  6404. }
  6405. if ($this->env->hasExtension('sandbox')) {
  6406. $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
  6407. }
  6408. return $object->$item;
  6409. }
  6410. }
  6411. if (!isset(self::$cache[$class]['methods'])) {
  6412. self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
  6413. }
  6414. $call = false;
  6415. $lcItem = strtolower($item);
  6416. if (isset(self::$cache[$class]['methods'][$lcItem])) {
  6417. $method = (string) $item;
  6418. } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) {
  6419. $method ='get'.$item;
  6420. } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) {
  6421. $method ='is'.$item;
  6422. } elseif (isset(self::$cache[$class]['methods']['__call'])) {
  6423. $method = (string) $item;
  6424. $call = true;
  6425. } else {
  6426. if ($isDefinedTest) {
  6427. return false;
  6428. }
  6429. if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
  6430. return null;
  6431. }
  6432. throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
  6433. }
  6434. if ($isDefinedTest) {
  6435. return true;
  6436. }
  6437. if ($this->env->hasExtension('sandbox')) {
  6438. $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
  6439. }
  6440. try {
  6441. $ret = call_user_func_array(array($object, $method), $arguments);
  6442. } catch (BadMethodCallException $e) {
  6443. if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
  6444. return null;
  6445. }
  6446. throw $e;
  6447. }
  6448. if ($object instanceof Twig_TemplateInterface) {
  6449. return $ret ===''?'': new Twig_Markup($ret, $this->env->getCharset());
  6450. }
  6451. return $ret;
  6452. }
  6453. public static function clearCache()
  6454. {
  6455. self::$cache = array();
  6456. }
  6457. }
  6458. }