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