PageRenderTime 10ms CodeModel.GetById 2ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/administrator/components/com_virtuemart/classes/Log/file.php

http://vanphongphamdm.googlecode.com/
PHP | 363 lines | 146 code | 48 blank | 169 comment | 34 complexity | 91b4ccb39eb48cdfe3705acce8f69a5a MD5 | raw file
  1<?php
  2if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3/**
  4*
  5* @version $Id: file.php 1868 2009-08-17 09:38:24Z soeren_nb $
  6* @package VirtueMart
  7* @subpackage Log
  8* @copyright Copyright (C) 2004-2008 soeren - All rights reserved.
  9* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
 10* VirtueMart is free software. This version may have been modified pursuant
 11* to the GNU General Public License, and as distributed it includes or
 12* is derivative of works licensed under the GNU General Public License or
 13* other free or open source software licenses.
 14* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
 15*
 16* http://virtuemart.net
 17*/
 18
 19/**
 20 * $Header$
 21 *
 22 * @version $ Revision: 1.44 $
 23 * @package Log
 24 */
 25
 26/**
 27 * The vmLog_file class is a concrete implementation of the Log abstract
 28 * class that logs messages to a text file.
 29 * 
 30 * @author  Jon Parise <jon@php.net>
 31 * @author  Roman Neuhauser <neuhauser@bellavista.cz>
 32 * @since   Log 1.0
 33 * @package Log
 34 *
 35 * @example file.php    Using the file handler.
 36 */
 37class vmLog_file extends vmLog
 38{
 39    /**
 40     * String containing the name of the log file.
 41     * @var string
 42     * @access private
 43     */
 44    var $_filename = 'php.log';
 45
 46    /**
 47     * Handle to the log file.
 48     * @var resource
 49     * @access private
 50     */
 51    var $_fp = false;
 52
 53    /**
 54     * Should new log entries be append to an existing log file, or should the
 55     * a new log file overwrite an existing one?
 56     * @var boolean
 57     * @access private
 58     */
 59    var $_append = true;
 60
 61    /**
 62     * Should advisory file locking (i.e., flock()) be used?
 63     * @var boolean
 64     * @access private
 65     */
 66    var $_locking = false;
 67
 68    /**
 69     * Integer (in octal) containing the log file's permissions mode.
 70     * @var integer
 71     * @access private
 72     */
 73    var $_mode = 0644;
 74
 75    /**
 76     * Integer (in octal) specifying the file permission mode that will be
 77     * used when creating directories that do not already exist.
 78     * @var integer
 79     * @access private
 80     */
 81    var $_dirmode = 0755;
 82
 83    /**
 84     * String containing the format of a log line.
 85     * @var string
 86     * @access private
 87     */
 88    var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
 89
 90    /**
 91     * String containing the timestamp format.  It will be passed directly to
 92     * strftime().  Note that the timestamp string will generated using the
 93     * current locale.
 94     * @var string
 95     * @access private
 96     */
 97    var $_timeFormat = '%b %d %H:%M:%S';
 98
 99    /**
100     * Hash that maps canonical format keys to position arguments for the
101     * "line format" string.
102     * @var array
103     * @access private
104     */
105    /*@MWM1:Add additional format keys {remoteip}, {username}, {vmsessionid}*/
106    var $_formatMap = array('%{timestamp}'  => '%1$s',
107                            '%{ident}'      => '%2$s',
108                            '%{priority}'   => '%3$s',
109                            '%{message}'    => '%4$s',
110                            '%{remoteip}'   => '%5$s',
111                            '%{username}'   => '%6$s',
112                            '%{vmsessionid}'   => '%7$s',
113                            '%\{'           => '%%{');
114
115    /**
116     * String containing the end-on-line character sequence.
117     * @var string
118     * @access private
119     */
120    var $_eol = "\n";
121
122    /**
123     * Constructs a new vmLog_file object.
124     *
125     * @param string $name     Ignored.
126     * @param string $ident    The identity string.
127     * @param array  $conf     The configuration array.
128     * @param int    $level    Log messages up to and including this level.
129     * @access public
130     */
131    function vmLog_file($name, $ident = '', $conf = array(),
132                      $level = PEAR_LOG_DEBUG)
133    {
134        $this->_id = md5(microtime());
135        $this->_filename = $name;
136        $this->_ident = $ident;
137        $this->_mask = vmLog::UPTO($level);
138
139        if (isset($conf['append'])) {
140            $this->_append = $conf['append'];
141        }
142
143        if (isset($conf['locking'])) {
144            $this->_locking = $conf['locking'];
145        }
146
147        if (!empty($conf['mode'])) {
148            if (is_string($conf['mode'])) {
149                $this->_mode = octdec($conf['mode']);
150            } else {
151                $this->_mode = $conf['mode'];
152            }
153        }
154
155        if (!empty($conf['dirmode'])) {
156            if (is_string($conf['dirmode'])) {
157                $this->_dirmode = octdec($conf['dirmode']);
158            } else {
159                $this->_dirmode = $conf['dirmode'];
160            }
161        }
162
163        if (!empty($conf['lineFormat'])) {
164            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
165                                             array_values($this->_formatMap),
166                                             $conf['lineFormat']);
167        }
168
169        if (!empty($conf['timeFormat'])) {
170            $this->_timeFormat = $conf['timeFormat'];
171        }
172
173        if (!empty($conf['eol'])) {
174            $this->_eol = $conf['eol'];
175        } else {
176            $this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
177        }
178
179        register_shutdown_function(array(&$this, '_vmLog_file'));
180    }
181
182    /**
183     * Destructor
184     */
185    function _vmLog_file()
186    {
187        if ($this->_opened) {
188            $this->close();
189        }
190    }
191
192    /**
193     * Creates the given directory path.  If the parent directories don't
194     * already exist, they will be created, too.
195     *
196     * This implementation is inspired by Python's os.makedirs function.
197     *
198     * @param   string  $path       The full directory path to create.
199     * @param   integer $mode       The permissions mode with which the
200     *                              directories will be created.
201     *
202     * @return  True if the full path is successfully created or already
203     *          exists.
204     *
205     * @access  private
206     */
207    function _mkpath($path, $mode = 0700)
208    {
209        /* Separate the last pathname component from the rest of the path. */
210        $head = dirname($path);
211        $tail = basename($path);
212
213        /* Make sure we've split the path into two complete components. */
214        if (empty($tail)) {
215            $head = dirname($path);
216            $tail = basename($path);
217        }
218
219        /* Recurse up the path if our current segment does not exist. */
220        if (!empty($head) && !empty($tail) && !is_dir($head)) {
221            $this->_mkpath($head, $mode);
222        }
223
224        /* Create this segment of the path. */
225        return @mkdir($head, $mode);
226    }
227
228    /**
229     * Opens the log file for output.  If the specified log file does not
230     * already exist, it will be created.  By default, new log entries are
231     * appended to the end of the log file.
232     *
233     * This is implicitly called by log(), if necessary.
234     *
235     * @access public
236     */
237    function open()
238    {
239        if (!$this->_opened) {
240        	if( empty( $this->_filename )) {
241        		return false;
242        	}
243            /* If the log file's directory doesn't exist, create it. */
244            if (!is_dir(dirname($this->_filename))) {
245                $this->_mkpath($this->_filename, $this->_dirmode);
246            }
247
248            /* Determine whether the log file needs to be created. */
249            $creating = !file_exists($this->_filename);
250
251            /* Obtain a handle to the log file. */
252            $this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w');
253
254            /* We consider the file "opened" if we have a valid file pointer. */
255            $this->_opened = ($this->_fp !== false);
256
257            /* Attempt to set the file's permissions if we just created it. */
258            if ($creating && $this->_opened) {
259                chmod($this->_filename, $this->_mode);
260            }
261        }
262
263        return $this->_opened;
264    }
265
266    /**
267     * Closes the log file if it is open.
268     *
269     * @access public
270     */
271    function close()
272    {
273        /* If the log file is open, close it. */
274        if ($this->_opened && fclose($this->_fp)) {
275            $this->_opened = false;
276        }
277
278        return ($this->_opened === false);
279    }
280
281    /**
282     * Flushes all pending data to the file handle.
283     *
284     * @access public
285     * @since Log 1.8.2
286     */
287    function flush()
288    {
289        return is_resource($this->_fp) ? fflush($this->_fp) : false;
290    }
291
292    /**
293     * Logs $message to the output window.  The message is also passed along
294     * to any Log_observer instances that are observing this Log.
295     *
296     * @param mixed  $message  String or object containing the message to log.
297     * @param string $priority The priority of the message.  Valid
298     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
299     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
300     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
301     * @return boolean  True on success or false on failure.
302     * @access public
303     */
304    function log($message, $priority = null)
305    {
306        /* If a priority hasn't been specified, use the default value. */
307        if ($priority === null) {
308            $priority = $this->_priority;
309        }
310
311        /* Abort early if the priority is above the maximum logging level. */
312        if (!$this->_isMasked($priority)) {
313            return false;
314        }
315
316        /* If the log file isn't already open, open it now. */
317        if (!$this->_opened && !$this->open()) {
318            return false;
319        }
320
321        /* Extract the string representation of the message. */
322        $message = $this->_extractMessage($message);
323
324        /* #B@MWM1: Add additional info that can be logged */
325        if (!empty($_SERVER['REMOTE_ADDR']))
326            $remoteip = $_SERVER['REMOTE_ADDR'];
327        else
328            $remoteip = 'unknown IP';
329
330        if (!empty($_SESSION['auth']["username"]))
331            $username = $_SESSION['auth']["username"];
332        else
333            $username = 'unknown user';
334
335        $vmsessionid = session_id();
336        /*#E@MWM1*/
337
338        /* Build the string containing the complete log line. */
339        /* @MWM1 Logging changes...*/
340        $line = sprintf($this->_lineFormat, strftime($this->_timeFormat),
341                $this->_ident, $this->priorityToShortStringPEAR($priority),
342                $message, $remoteip, $username, $vmsessionid) . $this->_eol;
343
344        /* If locking is enabled, acquire an exclusive lock on the file. */
345        if ($this->_locking) {
346            flock($this->_fp, LOCK_EX);
347        }
348
349        /* Write the log line to the log file. */
350        $success = (fwrite($this->_fp, $line) !== false);
351
352        /* Unlock the file now that we're finished writing to it. */ 
353        if ($this->_locking) {
354            flock($this->_fp, LOCK_UN);
355        }
356
357        /* Notify observers about this log message. */
358        $this->_announce(array('priority' => $priority, 'message' => $message));
359
360        return $success;
361    }
362
363}