shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Error.php (8271B)


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