PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Twig/Error.php

https://gitlab.com/ShizuoLamperouge/Dashboard
PHP | 272 lines | 144 code | 37 blank | 91 comment | 41 complexity | 0ca36d5b5c3974d1c39d4469b3d4fe7f MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) 2009 Fabien Potencier
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * Twig base exception.
  12. *
  13. * This exception class and its children must only be used when
  14. * an error occurs during the loading of a template, when a syntax error
  15. * is detected in a template, or when rendering a template. Other
  16. * errors must use regular PHP exception classes (like when the template
  17. * cache directory is not writable for instance).
  18. *
  19. * To help debugging template issues, this class tracks the original template
  20. * name and line where the error occurred.
  21. *
  22. * Whenever possible, you must set these information (original template name
  23. * and line number) yourself by passing them to the constructor. If some or all
  24. * these information are not available from where you throw the exception, then
  25. * this class will guess them automatically (when the line number is set to -1
  26. * and/or the filename is set to null). As this is a costly operation, this
  27. * can be disabled by passing false for both the filename and the line number
  28. * when creating a new instance of this class.
  29. *
  30. * @author Fabien Potencier <fabien@symfony.com>
  31. */
  32. class Twig_Error extends Exception
  33. {
  34. protected $lineno;
  35. protected $filename;
  36. protected $rawMessage;
  37. protected $previous;
  38. /**
  39. * Constructor.
  40. *
  41. * Set both the line number and the filename to false to
  42. * disable automatic guessing of the original template name
  43. * and line number.
  44. *
  45. * Set the line number to -1 to enable its automatic guessing.
  46. * Set the filename to null to enable its automatic guessing.
  47. *
  48. * By default, automatic guessing is enabled.
  49. *
  50. * @param string $message The error message
  51. * @param int $lineno The template line where the error occurred
  52. * @param string $filename The template file name where the error occurred
  53. * @param Exception $previous The previous exception
  54. */
  55. public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
  56. {
  57. if (PHP_VERSION_ID < 50300) {
  58. $this->previous = $previous;
  59. parent::__construct('');
  60. } else {
  61. parent::__construct('', 0, $previous);
  62. }
  63. $this->lineno = $lineno;
  64. $this->filename = $filename;
  65. if (-1 === $this->lineno || null === $this->filename) {
  66. $this->guessTemplateInfo();
  67. }
  68. $this->rawMessage = $message;
  69. $this->updateRepr();
  70. }
  71. /**
  72. * Gets the raw message.
  73. *
  74. * @return string The raw message
  75. */
  76. public function getRawMessage()
  77. {
  78. return $this->rawMessage;
  79. }
  80. /**
  81. * Gets the filename where the error occurred.
  82. *
  83. * @return string The filename
  84. */
  85. public function getTemplateFile()
  86. {
  87. return $this->filename;
  88. }
  89. /**
  90. * Sets the filename where the error occurred.
  91. *
  92. * @param string $filename The filename
  93. */
  94. public function setTemplateFile($filename)
  95. {
  96. $this->filename = $filename;
  97. $this->updateRepr();
  98. }
  99. /**
  100. * Gets the template line where the error occurred.
  101. *
  102. * @return int The template line
  103. */
  104. public function getTemplateLine()
  105. {
  106. return $this->lineno;
  107. }
  108. /**
  109. * Sets the template line where the error occurred.
  110. *
  111. * @param int $lineno The template line
  112. */
  113. public function setTemplateLine($lineno)
  114. {
  115. $this->lineno = $lineno;
  116. $this->updateRepr();
  117. }
  118. public function guess()
  119. {
  120. $this->guessTemplateInfo();
  121. $this->updateRepr();
  122. }
  123. /**
  124. * For PHP < 5.3.0, provides access to the getPrevious() method.
  125. *
  126. * @param string $method The method name
  127. * @param array $arguments The parameters to be passed to the method
  128. *
  129. * @return Exception The previous exception or null
  130. *
  131. * @throws BadMethodCallException
  132. */
  133. public function __call($method, $arguments)
  134. {
  135. if ('getprevious' == strtolower($method)) {
  136. return $this->previous;
  137. }
  138. throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
  139. }
  140. public function appendMessage($rawMessage)
  141. {
  142. $this->rawMessage .= $rawMessage;
  143. $this->updateRepr();
  144. }
  145. /**
  146. * @internal
  147. */
  148. protected function updateRepr()
  149. {
  150. $this->message = $this->rawMessage;
  151. $dot = false;
  152. if ('.' === substr($this->message, -1)) {
  153. $this->message = substr($this->message, 0, -1);
  154. $dot = true;
  155. }
  156. $questionMark = false;
  157. if ('?' === substr($this->message, -1)) {
  158. $this->message = substr($this->message, 0, -1);
  159. $questionMark = true;
  160. }
  161. if ($this->filename) {
  162. if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
  163. $filename = sprintf('"%s"', $this->filename);
  164. } else {
  165. $filename = json_encode($this->filename);
  166. }
  167. $this->message .= sprintf(' in %s', $filename);
  168. }
  169. if ($this->lineno && $this->lineno >= 0) {
  170. $this->message .= sprintf(' at line %d', $this->lineno);
  171. }
  172. if ($dot) {
  173. $this->message .= '.';
  174. }
  175. if ($questionMark) {
  176. $this->message .= '?';
  177. }
  178. }
  179. /**
  180. * @internal
  181. */
  182. protected function guessTemplateInfo()
  183. {
  184. $template = null;
  185. $templateClass = null;
  186. if (PHP_VERSION_ID >= 50306) {
  187. $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
  188. } else {
  189. $backtrace = debug_backtrace();
  190. }
  191. foreach ($backtrace as $trace) {
  192. if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
  193. $currentClass = get_class($trace['object']);
  194. $isEmbedContainer = 0 === strpos($templateClass, $currentClass);
  195. if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
  196. $template = $trace['object'];
  197. $templateClass = get_class($trace['object']);
  198. }
  199. }
  200. }
  201. // update template filename
  202. if (null !== $template && null === $this->filename) {
  203. $this->filename = $template->getTemplateName();
  204. }
  205. if (null === $template || $this->lineno > -1) {
  206. return;
  207. }
  208. $r = new ReflectionObject($template);
  209. $file = $r->getFileName();
  210. // hhvm has a bug where eval'ed files comes out as the current directory
  211. if (is_dir($file)) {
  212. $file = '';
  213. }
  214. $exceptions = array($e = $this);
  215. while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
  216. $exceptions[] = $e;
  217. }
  218. while ($e = array_pop($exceptions)) {
  219. $traces = $e->getTrace();
  220. array_unshift($traces, array('file' => $e->getFile(), 'line' => $e->getLine()));
  221. while ($trace = array_shift($traces)) {
  222. if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
  223. continue;
  224. }
  225. foreach ($template->getDebugInfo() as $codeLine => $templateLine) {
  226. if ($codeLine <= $trace['line']) {
  227. // update template line
  228. $this->lineno = $templateLine;
  229. return;
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }