1 <?php
2 /**
3 * XAO_Exceptions.php
4 *
5 * This script provides exception-specific messaging for content based classes.
6 * It is designed to be used in conjunction with DomDoc based classes. There is
7 * no need for the developer to concern themselves with this class since DomDoc
8 * uses it in DomDoc::Throw(). However, it is possible to
9 * use this class from anywhere - even outside XAO. It is well encapsulated and
10 * decoupled.
11 *
12 * @see DomDoc::Throw()
13 */
14
15 /**
16 * Import the root (base) XAO class.
17 *
18 * All classes in the XAO library should have this class at the top of their
19 * inheritance tree. See documentation on the class itself for more details.
20 * Including the following DomDoc class will automatically include the XaoRoot
21 * definition, however, it is included here for clarity and completeness.
22 *
23 * @import XaoRoot
24 */
25 include_once "XAO_XaoRoot.php";
26
27 /**
28 * Utility for managing massages relating to exceptional conditions (errors)
29 *
30 * This class is used to produce and manage error messages for exceptional
31 * conditions as XML data in a DomDoc based object. It also stores debugging
32 * data wich may optionally be displayed by an appropriate stylesheet. All data
33 * is managed directly on the DOM tree (rather than maintaining a dedicated
34 * stack) of the calling object to ensure it's availability without having to
35 * notify a separate stack manager when the application needs the data.
36 * As such, this class requires a stub (node) on the DOM tree represending the
37 * "errors" element where it will mainatain error data.
38 *
39 * @author Terence Kearns
40 * @version 0.0
41 * @copyright Terence Kearns 2003
42 * @license LGPL
43 * @package XAO
44 * @link http://xao-php.sourceforge.net
45 */
46 class Exceptions extends XaoRoot {
47
48 var $objDoc;
49 var $ndErrors;
50
51 var $blnCreateStackTrace = true;
52
53 /**
54 * XML Namespace Prefix
55 *
56 * Element name to use for each exception.
57 *
58 * @access public
59 * @var string
60 */
61 var $strElName;
62
63 /**
64 * Hash list of metadata to provide supportive context for error messages
65 *
66 * This is intended to be used by methods that override $this->Throw().
67 *
68 * @access public
69 * @var array
70 */
71 var $arrErrAttribs = array();
72
73 /**
74 * Exceptions constructor
75 *
76 * Simply obtain references to the calling document and keep them locally
77 * (global to the class).
78 *
79 * @param dom ref document where the error data is to be grafted.
80 * @param node ref the stub onto which the error grafted
81 * @return void
82 * @access public
83 */
84 function Exceptions(
85 &$objDoc,
86 &$ndErrors,
87 $strElName = "exception",
88 $idNamespace = ""
89 ) {
90 $this->objDoc =& $objDoc;
91 $this->ndErrors =& $ndErrors;
92 $this->strElName = $strElName;
93 }
94
95 /**
96 * Exceptional message setter method
97 *
98 * @param string current message for current exceptional condition
99 * @return void
100 * @access public
101 */
102 function SetMessage($strMsg) {
103 $strMsg = trim($strMsg);
104 if(strlen($strMsg)) {
105 $this->strError = $strMsg;
106 }
107 else {
108 $this->strError =
109 "Exceptions::SetMessage - The error message was empty.";
110 }
111 }
112
113 /**
114 * Exceptional message setter method
115 *
116 * This method resets the current array of error message attributes to the
117 * associative array passed in the first argument. The array is NOT
118 * appended.
119 *
120 * @param array copy associative array of error message attributes
121 * @return void
122 * @access public
123 */
124 function SetMsgAttribs($arrAttribs) {
125 $this->arrErrAttribs = $arrAttribs;
126 }
127
128 /**
129 * General purpose attribute setting utility
130 *
131 * @param string name of the attribute to be set
132 * @param string value of the attribute to be set
133 * @return void
134 * @access private
135 */
136 function SetMsgAttrib($strAttName,$strAttVal) {
137 $strAttVal = trim($strAttVal);
138 if(strlen($strAttVal)) $this->arrErrAttribs[$strAttName] = $strAttVal;
139 }
140
141 /**
142 * Execution method for created the actual error data
143 *
144 * @return node A reference to the new DOM node created.
145 * @access public
146 */
147 function &ndCreateError() {
148 // create the document node for this
149 // error
150 $elError =& $this->objDoc->create_element($this->strElName);
151 $ndError =& $this->ndErrors->append_child($elError);
152 $elMsg =& $this->objDoc->create_element("msg");
153 $ndMsg =& $ndError->append_child($elMsg);
154 // populate it with the main message
155 if(strlen($this->strError)) {
156 $ndMsg->set_content($this->strError);
157 }
158 else {
159 $strMsg =
160 "Exceptions::ndCreateError - No error message has been set.";
161 $ndMsg->set_content($strMsg);
162 }
163 // set up any attributes
164 foreach($this->arrErrAttribs AS $attName => $attVal) {
165 if(strlen($this->arrErrAttribs[$attName])) {
166 $ndError->set_attribute($attName,$attVal);
167 }
168 }
169 // include stack trace if required
170 if($this->blnCreateStackTrace) $this->_CreateStackTrace($ndError);
171
172 return $ndError;
173 }
174
175 /**
176 * Method for creating verbose stack trace data on DOM tree
177 *
178 * @return node A reference to the error DOM node.
179 * @return void
180 * @access public
181 */
182 function _CreateStackTrace(&$ndErr) {
183 $elBt =& $this->objDoc->create_element("stack");
184 $ndBt =& $ndErr->append_child($elBt);
185 $arrBt = debug_backtrace();
186 // this will create a nested call
187 // element for each function call stored
188 // in the backtrace array.
189 foreach($arrBt AS $arrCall) {
190 $elCall =& $this->objDoc->create_element("call");
191 foreach($arrCall AS $attCall=>$valCall) {
192 if(is_array($valCall)) {
193 if(count($valCall)) {
194 $elArgs =& $this->objDoc->create_element($attCall);
195 $ndArgs =& $elCall->append_child($elArgs);
196 foreach($valCall AS $attArg=>$valArg) {
197 if(!is_string($valArg))
198 // delve no further
199 $valArg = "[".@(string)$valArg."]";
200 if(strlen(trim($valArg)) && $valArg != "[]") {
201 // attempt to show content of argument
202 $elItem =
203 $this->objDoc->create_element("item");
204 if(strlen($valArg) > 256)
205 $valArg = substr($valArg,0,255)."...";
206 $elItem->set_content($valArg);
207 $ndItem =& $ndArgs->append_child($elItem);
208 }
209 } // end foreach on call arguments
210 }
211 }
212 else {
213 // translate backtrace array keys/vals
214 // to atribute name/vals for each CALL
215 // element
216 $elCall->set_attribute($attCall,$valCall);
217 }
218 } // end foreach on call attributes
219 // attache the CALL element to the
220 // stack element.
221 if(isset($ndCall)) {
222 // nest this element under the previous
223 // CALL element if one already exists
224 $ndCall =& $ndCall->append_child($elCall);
225 }
226 else {
227 // create the start CALL element node.
228 $ndCall =& $ndBt->append_child($elCall);
229 }
230 } // end backtrace foreach on calls
231 }
232 }
233 ?>