9bef31324f5822b6a53de30e22de783d9b67bcce
[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      */
97     public static function log(Exception $exception, $suppressTrace = null)
98     {
99         if (! is_object(Tinebase_Core::getLogger())) {
100             // no logger -> exception happened very early
101             error_log($exception);
102         } else {
103             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' ' . get_class($exception) . ' -> ' . $exception->getMessage());
104             
105             if ($suppressTrace === null) {
106                 try {
107                     $suppressTrace = Tinebase_Core::getConfig()->suppressExceptionTraces;
108                 } catch (Exception $e) {
109                     // catch all config exceptions here
110                     $suppressTrace = true;
111                 }
112             }
113             
114             if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE) && ! $suppressTrace) {
115                 $traceString = $exception->getTraceAsString();
116                 $traceString = self::_replaceBasePath($traceString);
117                 $traceString = self::_removeCredentials($traceString);
118                  
119                 Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' ' . $traceString);
120             }
121         }
122     }
123     
124     /**
125      * remove credentials/passwords from trace 
126      * 
127      * @param string $_traceString
128      * @return string
129      */
130     protected static function _removeCredentials($_traceString)
131     {
132         $passwordPatterns = array(
133             "/->login\('([^']*)', '[^']*'/",
134             "/->loginFromPost\('([^']*)', '[^']*'/",
135             "/->validate\('([^']*)', '[^']*'/",
136             "/->(_{0,1})authenticate\('([^']*)', '[^']*'/",
137         );
138         $replacements = array(
139             "->login('$1', '********'",
140             "->loginFromPost('$1', '********'",
141             "->validate('$1', '********'",
142             "->$1authenticate('$2', '********'",
143         );
144         
145         return preg_replace($passwordPatterns, $replacements, $_traceString);
146     }
147     
148     /**
149      * returns the name of the application, this exception belongs to
150      * 
151      * @return string
152      */
153     public function getAppName()
154     {
155         return $this->_appName;
156     }
157     
158     /**
159      * returns the title of this exception
160      *
161      * @return string
162      */
163     public function getTitle()
164     {
165         return $this->_title;
166     }
167 }