Dotclear

source: inc/libs/Twig/Error.php @ 1149:1657e862089c

Revision 1149:1657e862089c, 6.7 KB checked in by dsls, 12 years ago (diff)

Fixed unix case-sensitive twig directory

Line 
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 * @package    twig
33 * @author     Fabien Potencier <fabien@symfony.com>
34 */
35class Twig_Error extends Exception
36{
37    protected $lineno;
38    protected $filename;
39    protected $rawMessage;
40    protected $previous;
41
42    /**
43     * Constructor.
44     *
45     * Set both the line number and the filename to false to
46     * disable automatic guessing of the original template name
47     * and line number.
48     *
49     * Set the line number to -1 to enable its automatic guessing.
50     * Set the filename to null to enable its automatic guessing.
51     *
52     * By default, automatic guessing is enabled.
53     *
54     * @param string    $message  The error message
55     * @param integer   $lineno   The template line where the error occurred
56     * @param string    $filename The template file name where the error occurred
57     * @param Exception $previous The previous exception
58     */
59    public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
60    {
61        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
62            $this->previous = $previous;
63            parent::__construct('');
64        } else {
65            parent::__construct('', 0, $previous);
66        }
67
68        $this->lineno = $lineno;
69        $this->filename = $filename;
70
71        if (-1 === $this->lineno || null === $this->filename) {
72            $this->guessTemplateInfo();
73        }
74
75        $this->rawMessage = $message;
76
77        $this->updateRepr();
78    }
79
80    /**
81     * Gets the raw message.
82     *
83     * @return string The raw message
84     */
85    public function getRawMessage()
86    {
87        return $this->rawMessage;
88    }
89
90    /**
91     * Gets the filename where the error occurred.
92     *
93     * @return string The filename
94     */
95    public function getTemplateFile()
96    {
97        return $this->filename;
98    }
99
100    /**
101     * Sets the filename where the error occurred.
102     *
103     * @param string $filename The filename
104     */
105    public function setTemplateFile($filename)
106    {
107        $this->filename = $filename;
108
109        $this->updateRepr();
110    }
111
112    /**
113     * Gets the template line where the error occurred.
114     *
115     * @return integer The template line
116     */
117    public function getTemplateLine()
118    {
119        return $this->lineno;
120    }
121
122    /**
123     * Sets the template line where the error occurred.
124     *
125     * @param integer $lineno The template line
126     */
127    public function setTemplateLine($lineno)
128    {
129        $this->lineno = $lineno;
130
131        $this->updateRepr();
132    }
133
134    public function guess()
135    {
136        $this->guessTemplateInfo();
137        $this->updateRepr();
138    }
139
140    /**
141     * For PHP < 5.3.0, provides access to the getPrevious() method.
142     *
143     * @param string $method    The method name
144     * @param array  $arguments The parameters to be passed to the method
145     *
146     * @return Exception The previous exception or null
147     *
148     * @throws BadMethodCallException
149     */
150    public function __call($method, $arguments)
151    {
152        if ('getprevious' == strtolower($method)) {
153            return $this->previous;
154        }
155
156        throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
157    }
158
159    protected function updateRepr()
160    {
161        $this->message = $this->rawMessage;
162
163        $dot = false;
164        if ('.' === substr($this->message, -1)) {
165            $this->message = substr($this->message, 0, -1);
166            $dot = true;
167        }
168
169        if ($this->filename) {
170            if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
171                $filename = sprintf('"%s"', $this->filename);
172            } else {
173                $filename = json_encode($this->filename);
174            }
175            $this->message .= sprintf(' in %s', $filename);
176        }
177
178        if ($this->lineno && $this->lineno >= 0) {
179            $this->message .= sprintf(' at line %d', $this->lineno);
180        }
181
182        if ($dot) {
183            $this->message .= '.';
184        }
185    }
186
187    protected function guessTemplateInfo()
188    {
189        $template = null;
190        foreach (debug_backtrace() as $trace) {
191            if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
192                if (null === $this->filename || $this->filename == $trace['object']->getTemplateName()) {
193                    $template = $trace['object'];
194                }
195            }
196        }
197
198        // update template filename
199        if (null !== $template && null === $this->filename) {
200            $this->filename = $template->getTemplateName();
201        }
202
203        if (null === $template || $this->lineno > -1) {
204            return;
205        }
206
207        $r = new ReflectionObject($template);
208        $file = $r->getFileName();
209
210        $exceptions = array($e = $this);
211        while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
212            $exceptions[] = $e;
213        }
214
215        while ($e = array_pop($exceptions)) {
216            $traces = $e->getTrace();
217            while ($trace = array_shift($traces)) {
218                if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
219                    continue;
220                }
221
222                foreach ($template->getDebugInfo() as $codeLine => $templateLine) {
223                    if ($codeLine <= $trace['line']) {
224                        // update template line
225                        $this->lineno = $templateLine;
226
227                        return;
228                    }
229                }
230            }
231        }
232    }
233}
Note: See TracBrowser for help on using the repository browser.

Sites map