1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Document
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * DocumentError class, provides an easy interface to parse and display an error page
14 *
15 * @since 11.1
16 */
17 class JDocumentError extends JDocument
18 {
19 /**
20 * Document base URL
21 *
22 * @var string
23 * @since 11.1
24 */
25 public $baseurl = '';
26
27 /**
28 * Flag if debug mode has been enabled
29 *
30 * @var boolean
31 * @since 11.1
32 */
33 public $debug = false;
34
35 /**
36 * Error Object
37 *
38 * @var Exception|Throwable
39 * @since 11.1
40 */
41 public $error;
42
43 /**
44 * Name of the template
45 *
46 * @var string
47 * @since 11.1
48 */
49 public $template = null;
50
51 /**
52 * File name
53 *
54 * @var array
55 * @since 11.1
56 */
57 public $_file = null;
58
59 /**
60 * Error Object
61 *
62 * @var Exception|Throwable
63 * @since 11.1
64 */
65 protected $_error;
66
67 /**
68 * Class constructor
69 *
70 * @param array $options Associative array of attributes
71 *
72 * @since 11.1
73 */
74 public function __construct($options = array())
75 {
76 parent::__construct($options);
77
78 // Set mime type
79 $this->_mime = 'text/html';
80
81 // Set document type
82 $this->_type = 'error';
83 }
84
85 /**
86 * Set error object
87 *
88 * @param Exception|Throwable $error Error object to set
89 *
90 * @return boolean True on success
91 *
92 * @since 11.1
93 */
94 public function setError($error)
95 {
96 $expectedClass = PHP_MAJOR_VERSION >= 7 ? 'Throwable' : 'Exception';
97
98 if ($error instanceof $expectedClass)
99 {
100 $this->_error = & $error;
101
102 return true;
103 }
104
105 return false;
106 }
107
108 /**
109 * Render the document
110 *
111 * @param boolean $cache If true, cache the output
112 * @param array $params Associative array of attributes
113 *
114 * @return string The rendered data
115 *
116 * @since 11.1
117 */
118 public function render($cache = false, $params = array())
119 {
120 // If no error object is set return null
121 if (!isset($this->_error))
122 {
123 return;
124 }
125
126 // Set the status header
127 $status = $this->_error->getCode();
128
129 if ($status < 400 || $status > 599)
130 {
131 $status = 500;
132 }
133
134 $errorReporting = JFactory::getConfig()->get('error_reporting');
135
136 if ($errorReporting === "development" || $errorReporting === "maximum")
137 {
138 $status .= ' ' . str_replace("\n", ' ', $this->_error->getMessage());
139 }
140
141 JFactory::getApplication()->setHeader('status', $status);
142
143 $file = 'error.php';
144
145 // Check template
146 $directory = isset($params['directory']) ? $params['directory'] : 'templates';
147 $template = isset($params['template']) ? JFilterInput::getInstance()->clean($params['template'], 'cmd') : 'system';
148
149 if (!file_exists($directory . '/' . $template . '/' . $file))
150 {
151 $template = 'system';
152 }
153
154 // Set variables
155 $this->baseurl = JUri::base(true);
156 $this->template = $template;
157 $this->debug = isset($params['debug']) ? $params['debug'] : false;
158 $this->error = $this->_error;
159
160 // Load the language file for the template if able
161 if (JFactory::$language)
162 {
163 $lang = JFactory::getLanguage();
164
165 // 1.5 or core then 1.6
166 $lang->load('tpl_' . $template, JPATH_BASE, null, false, true)
167 || $lang->load('tpl_' . $template, $directory . '/' . $template, null, false, true);
168 }
169
170 // Load
171 $data = $this->_loadTemplate($directory . '/' . $template, $file);
172
173 parent::render();
174
175 return $data;
176 }
177
178 /**
179 * Load a template file
180 *
181 * @param string $directory The name of the template
182 * @param string $filename The actual filename
183 *
184 * @return string The contents of the template
185 *
186 * @since 11.1
187 */
188 public function _loadTemplate($directory, $filename)
189 {
190 $contents = '';
191
192 // Check to see if we have a valid template file
193 if (file_exists($directory . '/' . $filename))
194 {
195 // Store the file path
196 $this->_file = $directory . '/' . $filename;
197
198 // Get the file content
199 ob_start();
200 require_once $directory . '/' . $filename;
201 $contents = ob_get_contents();
202 ob_end_clean();
203 }
204
205 return $contents;
206 }
207
208 /**
209 * Render the backtrace
210 *
211 * @return string The contents of the backtrace
212 *
213 * @since 11.1
214 */
215 public function renderBacktrace()
216 {
217 // If no error object is set return null
218 if (!isset($this->_error))
219 {
220 return;
221 }
222
223 // The back trace
224 $backtrace = $this->_error->getTrace();
225
226 // Add the position of the actual file
227 array_unshift($backtrace, array('file' => $this->_error->getFile(), 'line' => $this->_error->getLine(), 'function' => ''));
228
229 return JLayoutHelper::render('joomla.error.backtrace', array('backtrace' => $backtrace));
230 }
231 }
232