sometimes we have no relayEvents
[tine20] / tine20 / Tinebase / Exception.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Exception
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Philipp Schüle <p.schuele@metaways.de>
10  */
11
12 /**
13  * Addressbook exception
14  * 
15  * @package     Tinebase
16  * @subpackage  Exception
17  */
18 class Tinebase_Exception extends Exception
19 {
20     /**
21      * the name of the application, this exception belongs to
22      * 
23      * @var string
24      */
25     protected $_appName = NULL;
26     
27     /**
28      * the title of the Exception (may be shown in a dialog)
29      * 
30      * @var string
31      */
32     protected $_title = NULL;
33     
34     /**
35      * the constructor
36      * 
37      * @param message[optional]
38      * @param code[optional]
39      * @param previous[optional]
40      */
41     public function __construct($message = null, $code = null, $previous = null)
42     {
43         if (! $this->_appName) {
44             $c = explode('_', get_class($this));
45             $this->_appName = $c[0];
46         }
47         
48         if (! $this->_title) {
49             $this->_title = 'Exception ({0})'; // _('Exception ({0})')
50         }
51         
52         parent::__construct(($message ? $message : $this->message), $code, $previous);
53     }
54     
55     /**
56      * get exception trace as array (remove confidential information)
57      * 
58      * @param Exception $exception
59      * @return array
60      */
61     public static function getTraceAsArray(Exception $exception)
62     {
63         $trace = $exception->getTrace();
64         $traceArray = array();
65         
66         foreach($trace as $part) {
67             if ((isset($part['file']) || array_key_exists('file', $part))) {
68                 // don't send full paths to the client
69                 $part['file'] = self::_replaceBasePath($part['file']);
70             }
71             // unset args to make sure no passwords are shown
72             unset($part['args']);
73             $traceArray[] = $part;
74         }
75         
76         return $traceArray;
77     }
78     
79     /**
80      * replace base path in string
81      * 
82      * @param string|array $_string
83      * @return string
84      */
85     protected static function _replaceBasePath($_string)
86     {
87         $basePath = dirname(dirname(__FILE__));
88         return str_replace($basePath, '...', $_string);
89     }
90     
91     /**
92      * log exception (remove confidential information from trace)
93      * 
94      * @param Exception $exception
95      * @param boolean $suppressTrace
96      * @param mixed $additionalData
97      */
98     public static function log(Exception $exception, $suppressTrace = null, $additionalData = null)
99     {
100         if (! is_object(Tinebase_Core::getLogger())) {
101             // no logger -> exception happened very early
102             error_log($exception);
103         } else {
104             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' ' . get_class($exception) . ' -> ' . $exception->getMessage());
105             
106             if ($suppressTrace === null) {
107                 try {
108                     $config = Tinebase_Core::getConfig();
109                     $suppressTrace = (isset($config->suppressExceptionTraces)) ? $config->suppressExceptionTraces : true;
110                 } catch (Exception $e) {
111                     // catch all config exceptions here
112                     $suppressTrace = true;
113                 }
114             }
115             
116             if (Tinebase_Core::isLogLevel(Zend_Log::ERR) && ! $suppressTrace) {
117                 $traceString = $exception->getTraceAsString();
118                 $traceString = self::_replaceBasePath($traceString);
119                 $traceString = self::_removeCredentials($traceString);
120                  
121                 Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' ' . $traceString);
122             }
123             
124             if ($additionalData) {
125                 Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Data: ' . print_r($additionalData, true));
126             }
127         }
128     }
129     
130     /**
131      * remove credentials/passwords from trace 
132      * 
133      * @param string $_traceString
134      * @return string
135      */
136     protected static function _removeCredentials($_traceString)
137     {
138         $passwordPatterns = array(
139             "/->login\('([^']*)', '[^']*'/",
140             "/->loginFromPost\('([^']*)', '[^']*'/",
141             "/->validate\('([^']*)', '[^']*'/",
142             "/->(_{0,1})authenticate\('([^']*)', '[^']*'/",
143             "/->updateCredentialCache\('[^']*'/",
144         );
145         $replacements = array(
146             "->login('$1', '********'",
147             "->loginFromPost('$1', '********'",
148             "->validate('$1', '********'",
149             "->$1authenticate('$2', '********'",
150             "->updateCredentialCache('********'",
151         );
152         
153         return preg_replace($passwordPatterns, $replacements, $_traceString);
154     }
155     
156     /**
157      * returns the name of the application, this exception belongs to
158      * 
159      * @return string
160      */
161     public function getAppName()
162     {
163         return $this->_appName;
164     }
165     
166     /**
167      * returns the title of this exception
168      *
169      * @return string
170      */
171     public function getTitle()
172     {
173         return $this->_title;
174     }
175 }