1: <?php
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: namespace Flea;
28:
29: 30: 31: 32: 33:
34: class Debug {
35:
36: private static $_INSTANCE;
37: private $_errorList;
38: private $_timer;
39: private $_totalTime;
40: private $_timerList;
41: private $_errorBackNum = 10;
42: private $_errorJsAlert = false;
43: private $_errorEcho = true;
44: private $_errorFile = true;
45: private $_errorFileName = 'errors.log';
46:
47: 48: 49: 50: 51: 52:
53: public function setErrorBackNum($num) {
54: $this->_errorBackNum = $num;
55: }
56:
57: 58: 59: 60: 61:
62: public function getErrorBackNum() {
63: return $this->_errorBackNum;
64: }
65:
66: 67: 68: 69: 70:
71: public function setErrorJsAlert($errorJsAlert) {
72: $this->_errorJsAlert = $errorJsAlert;
73: }
74:
75: 76: 77: 78: 79:
80: public function getErrorJsAlert() {
81: return $this->_errorJsAlert;
82: }
83:
84: 85: 86: 87: 88:
89: public function setErrorEcho($errorEcho) {
90: $this->_errorEcho = $errorEcho;
91: }
92:
93: 94: 95: 96: 97:
98: public function getErrorEcho() {
99: return $this->_errorEcho;
100: }
101:
102: private $_errorJsLog = true;
103:
104: 105: 106: 107: 108:
109: public function setErrorJsLog($errorJsLog) {
110: $this->_errorJsLog = $errorJsLog;
111: }
112:
113: 114: 115: 116: 117:
118: public function getErrorJsLog() {
119: return $this->_errorJsLog;
120: }
121:
122: 123: 124: 125: 126:
127: public function addError($msg) {
128: $error = $msg . "\n" . $this->getDebugBacktrace(1, $this->_errorBackNum);
129: array_push($this->_errorList, $error);
130: }
131:
132: 133: 134: 135:
136: public function dispatchErrors() {
137: if (count($this->_errorList) > 0) {
138: if ($this->_errorFile) {
139: include_once _SYSTEM_DIRECTORY . 'helpers/miscellaneous/FileUtil.php';
140:
141: if (!file_exists(_CACHE_DIRECTORY)) {
142: FileUtil::writeProtectedDir(_CACHE_DIRECTORY);
143: }
144:
145: $fileName = _CACHE_DIRECTORY . $this->_errorFileName;
146: $file = fopen($fileName, 'a+');
147:
148: $page = General::getInstance()->getCurrentPage();
149: fputs($file, "\r\n");
150: fputs($file, "\r\n");
151: fputs($file, "url: " . $page->getPageUrl());
152: fputs($file, "\r\n");
153: fputs($file, "id: " . $page->getId());
154: fputs($file, "\r\n");
155:
156: foreach ($this->_errorList as $errorStr) {
157:
158: fputs($file, $errorStr);
159: fputs($file, "\r\n");
160:
161: }
162:
163:
164:
165: fclose($file);
166: }
167:
168: echo '<script>/*Errors*/';
169: if ($this->_errorJsAlert) {
170: echo 'alert("' . $this->delDoubleQuotes(implode('\n', $this->_errorList)) . '");';
171: }
172: if ($this->_errorJsLog) {
173: echo 'console.log("' . $this->delDoubleQuotes(implode('\n', $this->_errorList)) . '");';
174: }
175: echo '</script>';
176:
177: if ($this->_errorEcho) {
178: echo $this->getErrorsHtml();
179: }
180: }
181: }
182:
183: 184: 185: 186: 187:
188: public function getErrorsHtml() {
189: return $this->addHtmlReturns(implode('<br>', $this->_errorList));
190: }
191:
192: 193: 194: 195: 196:
197: public function addTimeMark($msg) {
198: $dt = microtime(true) - $this->_timer;
199: $this->_timer += $dt;
200: $this->_totalTime += $dt;
201: $this->_timerList[] = array('dt' => $dt, 'msg' => $msg);
202: }
203:
204: 205: 206: 207: 208: 209:
210: public function getTimes($msg) {
211: $this->_timerList[] = array('dt' => $this->_totalTime, 'msg' => 'total time: ' . $msg);
212:
213: $output = '';
214: foreach ($this->_timerList as $value) {
215: $output .= $value['msg'] . ': ' . number_format($value['dt'], 3) . 's' . "\n";
216: }
217: return $output;
218: }
219:
220: private function addHtmlReturns($str) {
221: return str_replace('\n', '<br>', $str);
222: }
223:
224: private function delDoubleQuotes($str) {
225: $str = str_replace(array('"', '\\'), array('\"', '\\\\'), $str);
226: $str = str_replace(array('\\\n'), array('\n'), $str);
227: return $str;
228: }
229:
230: 231: 232:
233: public function clear() {
234: $this->_errorList = array();
235: $this->_timerList = array();
236: }
237:
238: final private function __construct() {
239: $this->clear();
240: $this->_timer = microtime(true);
241: $this->_totalTime = 0;
242: }
243:
244: 245: 246:
247: final private function __clone() {
248: if (_DEBUG) {
249: Debug::getInstance()->addError('You can\'t clone a singleton');
250: }
251: }
252:
253: 254: 255: 256: 257:
258: final public static function getInstance() {
259: if (!isset(self::$_INSTANCE)) {
260: self::$_INSTANCE = new self();
261: }
262:
263: return self::$_INSTANCE;
264: }
265:
266: 267: 268: 269: 270: 271: 272:
273: protected function getDebugBacktrace($traces_to_ignore = 1, $max_trace = 1) {
274: $traces = debug_backtrace();
275: $ret = array();
276: foreach ($traces as $i => $call) {
277: if ($i < $traces_to_ignore || $i > $traces_to_ignore + $max_trace - 1) {
278: continue;
279: }
280:
281:
282: if (isset($call['file']) && isset($call['line'])) {
283: $str = '';
284: if ($max_trace > 1) {
285: $str .= ' #' . str_pad($i - $traces_to_ignore, 3, ' ');
286: }
287:
288: $str .= ' ' . $call['file'] . ':' . $call['line'];
289: $ret[] = $str;
290: }
291: }
292: return implode("\n", $ret);
293: }
294:
295: }
296: