/
ApplicationError.php
executable file
·433 lines (412 loc) · 15.5 KB
/
ApplicationError.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
<?php
/** ---------------------------------------------------------------------
* app/lib/ApplicationError.php :
* ----------------------------------------------------------------------
* CollectiveAccess
* Open-source collections management software
* ----------------------------------------------------------------------
*
* Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
* Copyright 2000-2015 Whirl-i-Gig
*
* For more information visit http://www.CollectiveAccess.org
*
* This program is free software; you may redistribute it and/or modify it under
* the terms of the provided license as published by Whirl-i-Gig
*
* CollectiveAccess is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTIES whatsoever, including any implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* This source code is free and modifiable under the terms of
* GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See
* the "license.txt" file for details, or visit the CollectiveAccess web site at
* http://www.CollectiveAccess.org
*
* @package CollectiveAccess
* @subpackage Core
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License version 3
*
* ----------------------------------------------------------------------
*/
/**
*
*/
require_once(__CA_LIB_DIR__."/Configuration.php");
/**
* Standard error handling class. Each Error instance represents a single error that has occurred.
*
* Provides for halting on critical errors, localized and standardized error messages and codes and
* redirecting to "site down" page upon error.
*
*/
class ApplicationError {
/**
* Numeric code of current error
*
* @access private
*/
private $opn_error_number = 0; # standard error code (as defined in $error_messages hash)
/**
* Text description of current error
*
* @access private
*/
private $ops_error_description = ''; # instance-specific description of error (eg. MySQL error text)
/**
* Context of current error. This is typically the Class name and method name where the error occurred. Ex. "Configuration->new()"
*
* @access private
*/
private $ops_error_context = ''; # instance-specific context of error (eg. SQL code that caused MySQL error)
/**
* Source code for error. While it can be used as a general-purpose identifier for the cause of an error, it typically used to record which field in an input form the error is associated with.
*
* @access private
*/
private $ops_error_source = ''; # instance-specific source of error (eg. the field in a form this error is associated with)
/**
* Boolean indicating if we should halt request on this error
*
* @access private
*/
private $opb_halt_on_error = true;
/**
* Boolean indicating if we should emit visible (and quite ugly) output on this error
*
* @access private
*/
private $opb_report_on_error = true;
/**
* Boolean indicating if we should redirect to the url in $ops_redirect_on_error_page on this error
*
* @access private
*/
private $opb_redirect_on_error = true;
/**
* The current locale. Used to determine which set of localized error messages to use. Default is US English ("us_en")
*
* @access private
*/
private $ops_locale = "en_us"; # default locale is US English
/**
* URL of page to redirect to upon error, if $opb_redirect_on_error is set
*
* @access private
*/
private $ops_redirect_on_error_page = '';
/**
* Indexed array of error numbers to ignore opb_halt_on_error, opb_report_on_error and opb_redirect_on_error for
*
* @access private
*/
private $opa_dont_report_errors = array(251);
/**
* Configuration() object containing error messages
*
* @access private
*/
private $opo_error_messages;
/**
* Constructor takes optional parameters to create a new error. If parameters are omitted, an empty (non-error state)
* error object is created. An error state can subsequently be set using the setError() method
*
* @param integer $pn_error_number The numeric error code. Code should be defined in the error definition file
* @param string $ps_error_description Description of error condition
* @param string $ps_error_context Context where error occurred. This is typically the Class name and method name where the error occurred. Ex. "Configuration->new()"
* @param string $ps_error_source Source of error - typically a string identifying the field in a form where the error occurred.
* @param bool $pb_halt_on_error Whether or not to halt on error state (ie. whether do die()) [default is true]
* @param bool $pb_report_on_error Whether or not to emit a visible report of error state [default is true]
* @param string $ps_error_definition_file Path to error definition file; if omitted default file, based upon locale, is used
*/
public function __construct($pn_error_number=0, $ps_error_description='', $ps_error_context='', $ps_error_source='', $pb_halt_on_error = true, $pb_report_on_error = true, $ps_error_definition_file='') {
$this->opo_config = Configuration::load();
$this->ops_redirect_on_error_page = $this->opo_config->get("error_redirect_to_page");
# Set locale, if necessary
if (($vs_locale = $this->opo_config->get("locale")) && ((file_exists("Error/errors.".$vs_locale)) || ($this->file_exists_incpath("Error/errors.".$vs_locale)))) {
$this->ops_locale = $vs_locale;
}
# load error messages
$vs_error_definitions_loaded = 0;
if ($ps_error_definition_file) {
$vs_error_definitions_loaded = $this->setErrorDefinitionFile($ps_error_definition_file);
} else {
if ($vs_config_error_definition_file = $this->opo_config->get("error_definition_file")) {
$vs_error_definitions_loaded = $this->setErrorDefinitionFile($vs_config_error_definition_file);
}
}
if (!$vs_error_definitions_loaded) {
$vs_error_definitions_loaded = $this->setErrorDefinitionFile(__CA_LIB_DIR__."/Error/errors.".$this->ops_locale);
}
if (!$vs_error_definitions_loaded) {
$vs_error_definitions_loaded = $this->setErrorDefinitionFile(__CA_LIB_DIR__."/Error/errors.en_us");
}
if (!$vs_error_definitions_loaded) {
die("Error.php: Couldn't load error definitions!\n");
}
$this->opb_halt_on_error = $pb_halt_on_error;
$this->opb_report_on_error = $pb_report_on_error;
if ($pn_error_number) {
$this->setError($pn_error_number, $ps_error_description, $ps_error_context, $ps_error_source);
}
}
/**
* Sets an error state.
*
* Note: if the configuration directive 'error_email_notification_to' is set to an e-mail address in the application configuration file
* a notification of error will be sent.
*
* @param integer $pn_error_number The numeric error code. Code should be defined in the error definition file
* @param string $ps_error_description Description of error condition
* @param string $ps_error_context Context where error occurred. This is typically the Class name and method name where the error occurred. Ex. "Configuration->new()"
* @param string $ps_error_source Source of error - typically a string identifying the field in a form where the error occurred.
* @return integer Always returns 1
*/
public function setError ($pn_error_number, $ps_error_description='', $ps_error_context='', $ps_error_source='') {
$this->opn_error_number = (int)$pn_error_number;
$this->ops_error_description = $ps_error_description;
$this->ops_error_context = $ps_error_context;
$this->ops_error_source = $ps_error_source;
if (($this->opb_halt_on_error) || ($this->opb_report_on_error)) {
$this->halt();
}
return 1;
}
/**
* Set error output options: halt on error, report on error and redirect on error. Halt on error, well..., halts the request
* and prints a message. Report on error prints an error message but does not halt. This can be useful for debugging. Redirect
* on error redirects the request to a specified URL on error, passing basic information about the error in the URL query
* parameters. This can be useful for cleanly logging and handling errors in a production application.
*
* @param bool $pb_halt_and_report_on_error True if halt, report and redirect should be active, false if not. Generally this
* method is used to turn all options off in one shot.
* @return integer Always return 1
*/
public function setErrorOutput($pb_halt_and_report_on_error) {
$this->opb_halt_on_error = $pb_halt_and_report_on_error;
$this->opb_report_on_error = $pb_halt_and_report_on_error;
$this->opb_redirect_on_error = $pb_halt_and_report_on_error;
return 1;
}
/**
* Set halt on error option. If set to true, an error state will cause the request to halt.
*
* @param integer $pb_halt_on_error True to halt on error, false otherwise.
* @return integer Always returns 1
*/
public function setHaltOnError ($pb_halt_on_error) {
$this->opb_halt_on_error = $pb_halt_on_error;
return 1;
}
/**
* Set report on error option. If set to true, an error state will cause an error message to be printed.
*
* @param integer $pb_report_on_error True to print an error message on error, false otherwise.
* @return integer Always returns 1
*/
public function setReportOnError ($pb_report_on_error) {
$this->opb_report_on_error = $pb_report_on_error;
return 1;
}
/**
* Set redirect on error option. If set to true, an error state will the request to be redirected to a URL
* specified by the 'error_redirect_to_page' directive in the application configuration file. This
* URL can be overridden using the setRedirectOnErrorURL() method.
*
* Note that query parameters describing the error state will be appended to the redirect URL. These parameters are:
*
* - n = Error number [integer]
* - desc = Error description [string]
*
* @param integer $pb_redirect_on_error True to redirect to another URL on error, false otherwise.
* @return integer Always returns 1
*/
public function setRedirectOnError ($pb_redirect_on_error) {
$this->opb_redirect_on_error = $pb_redirect_on_error;
return 1;
}
/**
* Set URL to redirect to when redirect on error option is set. Normally, the URL is taken from the
* 'error_redirect_to_page' directive in the application configuration file. Use this method to override that
* value on a per-error basis.
*
* @param integer $ps_redirect_on_error_url The URL to redirect to. The URL should be absolute or root-relative
* without query parameters. Query parameters containing information about the error states will be appended to
* this URL.
*/
public function setRedirectOnErrorURL ($ps_redirect_on_error_url) {
$this->ops_redirect_on_error_page = $ps_redirect_on_error_url;
return 1;
}
/**
* Loads an error definition file. By default, the error definition file is a standard system error file for the current
* locale (if locale is set by the 'locale' directive in the application configuration file). If the locale is not set or
* there is no standard error definition file for the locale, the default en_us (US English) locale is used. You can override
* the use of standard locale-based error messages with your own error definitions by calling this method with the path to your error
* definition file.
*
* An error definition file is simply a standard configuration file containing one error message per line. The configuration directive (or "key")
* for each error is the error number. The value is the error message itself.
*
* All error numbers below 9999 are reserved for use by the WebLib libraries.
*
* @param string $ps_error_definition_file File path to error definition file
* @return integer Returns 1 on success, zero on failure
*/
public function setErrorDefinitionFile ($ps_error_definition_file) {
$this->opo_error_messages = Configuration::load($ps_error_definition_file);
if ($this->opo_error_messages->isError()) {
return 0;
}
return 1;
}
/**
* Returns an indexed array with a complete description of the current error state. The format of the array is:
*
* Index 0 = Error number
* Index 1 = Error message
* Index 2 = Error description
* Index 3 = Error context
* Index 4 = Error source code
*
* @return array Error description
*/
public function getError () {
return array($this->opn_error_number, $this->getErrorMessage($this->opn_error_number), $this->ops_error_description, $this->ops_error_context, $this->ops_error_source);
}
/**
* Returns the error number of the current error state.
*
* @return integer Error number
*/
public function getErrorNumber() {
return $this->opn_error_number;
}
/**
* Returns the error description of the current error state.
*
* @return string Error description
*/
public function getErrorDescription() {
return $this->ops_error_description;
}
/**
* Returns the context of the current error state.
*
* @return string Error context
*/
public function getErrorContext() {
return $this->ops_error_context;
}
/**
* Returns the error message of the current error state.
*
* @return string Error message
*/
public function getErrorMessage() {
$vs_error_message = $this->opo_error_messages->get($this->opn_error_number);
if ($vs_error_message) {
return $vs_error_message;
} else {
return "Unknown error: ".(int)$this->opn_error_number;
}
}
/**
* Returns the source of the current error.
*
* @return string Error source code
*/
public function getErrorSource() {
return $this->ops_error_source;
}
/**
* Returns true if halt on error is current set, false otherwise.
*
* @return bool Halt on error option setting
*/
public function getHaltOnError () {
return $this->opb_halt_on_error;
}
/**
* Returns true if report on error is current set, false otherwise.
*
* @return bool Report on error option setting
*/
public function getReportOnError () {
return $this->opb_report_on_error;
}
/**
* Sets the "dont report error" list to the supplied array.
*
* @param $pa_list array Indexed array of error number to ignore for halting, reporting or redirecting purposes.
* @return bool Halt on error option setting
*/
public function setDontReportErrorList ($pa_list) {
if (!is_array($pa_list))
return false;
$this->opa_dont_report_errors = $pa_list;
return true;
}
/**
* Returns array containing list of error numbers to ignore for reporting, halting or redirecting purposes.
*
* @return array Indexed array of ignored error numbers
*/
public function getDontReportErrorList () {
return $this->opa_dont_report_errors;
}
/**
* Clears error state.
*
*/
public function clearError() {
$this->opn_error_number = 0;
$this->ops_error_description = '';
$this->ops_error_context = '';
}
/**
* Handles halt on error.
*
* @access private
*/
public function halt() {
if (in_array($this->getErrorNumber(), $this->opa_dont_report_errors)) {
return false;
}
if ($this->opb_redirect_on_error) {
if ($vs_error_page = $this->ops_redirect_on_error_page) {
header("Location: ".$vs_error_page."?n=".$this->getErrorNumber()."&desc=".urlencode($this->getErrorDescription()));
exit;
}
}
if ($this->opb_report_on_error) {
$this->haltmsg($this->getErrorNumber().": ".$this->getErrorMessage()."<br/>".$this->getErrorDescription()." (in ".$this->getErrorContext().")");
}
if (!$this->opb_halt_on_error)
return;
die("Request halted.");
}
/**
* Prints message on halt.
*
* @access private
*/
public function haltmsg($msg) {
printf("</td></tr></table><b>Error</b> %s<br/>\n", $msg);
}
/**
* Determines whether file exists within include path
*
* @access private
*/
public function file_exists_incpath($ps_file) {
$va_paths = explode(PATH_SEPARATOR, get_include_path());
foreach ($va_paths as $vs_path) {
$vs_fullpath = $vs_path . DIRECTORY_SEPARATOR . $ps_file;
if (file_exists($vs_fullpath)) {
return true;
}
}
return false;
}
}