PageRenderTime 495ms CodeModel.GetById 121ms app.highlight 184ms RepoModel.GetById 141ms app.codeStats 1ms

/libraries/joomla/log/log.php

https://bitbucket.org/organicdevelopment/joomla-2.5
PHP | 422 lines | 165 code | 51 blank | 206 comment | 19 complexity | 6b61d5efa69b19e9ba452a74981ddecb MD5 | raw file
  1<?php
  2/**
  3 * @package     Joomla.Platform
  4 * @subpackage  Log
  5 *
  6 * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7 * @license     GNU General Public License version 2 or later; see LICENSE
  8 */
  9
 10defined('JPATH_PLATFORM') or die;
 11
 12jimport('joomla.log.logger');
 13
 14JLoader::register('LogException', JPATH_PLATFORM . '/joomla/log/logexception.php');
 15
 16JLoader::discover('JLogger', dirname(__FILE__) . '/loggers');
 17
 18// @deprecated  12.1
 19jimport('joomla.filesystem.path');
 20
 21/**
 22 * Joomla! Log Class
 23 *
 24 * This class hooks into the global log configuration settings to allow for user configured
 25 * logging events to be sent to where the user wishes them to be sent. On high load sites
 26 * SysLog is probably the best (pure PHP function), then the text file based loggers (CSV, W3C
 27 * or plain FormattedText) and finally MySQL offers the most features (e.g. rapid searching)
 28 * but will incur a performance hit due to INSERT being issued.
 29 *
 30 * @package     Joomla.Platform
 31 * @subpackage  Log
 32 * @since       11.1
 33 */
 34class JLog
 35{
 36	/**
 37	 * All log priorities.
 38	 * @var    integer
 39	 * @since  11.1
 40	 */
 41	const ALL = 30719;
 42
 43	/**
 44	 * The system is unusable.
 45	 * @var    integer
 46	 * @since  11.1
 47	 */
 48	const EMERGENCY = 1;
 49
 50	/**
 51	 * Action must be taken immediately.
 52	 * @var    integer
 53	 * @since  11.1
 54	 */
 55	const ALERT = 2;
 56
 57	/**
 58	 * Critical conditions.
 59	 * @var    integer
 60	 * @since  11.1
 61	 */
 62	const CRITICAL = 4;
 63
 64	/**
 65	 * Error conditions.
 66	 * @var    integer
 67	 * @since  11.1
 68	 */
 69	const ERROR = 8;
 70
 71	/**
 72	 * Warning conditions.
 73	 * @var    integer
 74	 * @since  11.1
 75	 */
 76	const WARNING = 16;
 77
 78	/**
 79	 * Normal, but significant condition.
 80	 * @var    integer
 81	 * @since  11.1
 82	 */
 83	const NOTICE = 32;
 84
 85	/**
 86	 * Informational message.
 87	 * @var    integer
 88	 * @since  11.1
 89	 */
 90	const INFO = 64;
 91
 92	/**
 93	 * Debugging message.
 94	 * @var    integer
 95	 * @since  11.1
 96	 */
 97	const DEBUG = 128;
 98
 99	/**
100	 * The global JLog instance.
101	 * @var    JLog
102	 * @since  11.1
103	 */
104	protected static $instance;
105
106	/**
107	 * The array of instances created through the deprecated getInstance method.
108	 * @var         array
109	 * @since       11.1
110	 * @see         JLog::getInstance()
111	 * @deprecated  12.1
112	 */
113	public static $legacy = array();
114
115	/**
116	 * Container for JLogger configurations.
117	 * @var    array
118	 * @since  11.1
119	 */
120	protected $configurations = array();
121
122	/**
123	 * Container for JLogger objects.
124	 * @var    array
125	 * @since  11.1
126	 */
127	protected $loggers = array();
128
129	/**
130	 * Lookup array for loggers.
131	 * @var    array
132	 * @since  11.1
133	 */
134	protected $lookup = array();
135
136	/**
137	 * Constructor.
138	 *
139	 * @since   11.1
140	 */
141	protected function __construct()
142	{
143	}
144
145	/**
146	 * Method to add an entry to the log.
147	 *
148	 * @param   mixed    $entry     The JLogEntry object to add to the log or the message for a new JLogEntry object.
149	 * @param   integer  $priority  Message priority.
150	 * @param   string   $category  Type of entry
151	 * @param   string   $date      Date of entry (defaults to now if not specified or blank)
152	 *
153	 * @return  void
154	 *
155	 * @since   11.1
156	 */
157	public static function add($entry, $priority = JLog::INFO, $category = '', $date = null)
158	{
159		// Automatically instantiate the singleton object if not already done.
160		if (empty(self::$instance))
161		{
162			self::setInstance(new JLog);
163		}
164
165		// If the entry object isn't a JLogEntry object let's make one.
166		if (!($entry instanceof JLogEntry))
167		{
168			$entry = new JLogEntry((string) $entry, $priority, $category, $date);
169		}
170
171		self::$instance->addLogEntry($entry);
172	}
173
174	/**
175	 * Method to set the way the JError will handle different error levels.
176	 * Use this if you want to override the default settings.
177	 *
178	 * @param   array    $options     The object configuration array.
179	 * @param   integer  $priorities  Message priority
180	 * @param   array    $categories  Types of entry
181	 *
182	 * @return  void
183	 *
184	 * @since   11.1
185	 */
186	public static function addLogger(array $options, $priorities = JLog::ALL, $categories = array())
187	{
188		// Automatically instantiate the singleton object if not already done.
189		if (empty(self::$instance))
190		{
191			self::setInstance(new JLog);
192		}
193
194		// The default logger is the formatted text log file.
195		if (empty($options['logger']))
196		{
197			$options['logger'] = 'formattedtext';
198		}
199		$options['logger'] = strtolower($options['logger']);
200
201		// Generate a unique signature for the JLog instance based on its options.
202		$signature = md5(serialize($options));
203
204		// Register the configuration if it doesn't exist.
205		if (empty(self::$instance->configurations[$signature]))
206		{
207			self::$instance->configurations[$signature] = $options;
208		}
209
210		self::$instance->lookup[$signature] = (object) array(
211			'priorities' => $priorities,
212			'categories' => array_map('strtolower', (array) $categories));
213	}
214
215	/**
216	 * Returns a JLog object for a given log file/configuration, only creating it if it doesn't already exist.
217	 *
218	 * This method must be invoked as:
219	 * <code>$log = JLog::getInstance($file, $options, $path);</code>
220	 *
221	 * @param   string  $file     The filename of the log file.
222	 * @param   array   $options  The object configuration array.
223	 * @param   string  $path     The base path for the log file.
224	 *
225	 * @return  JLog
226	 *
227	 * @since   11.1
228	 *
229	 * @deprecated  12.1
230	 */
231	public static function getInstance($file = 'error.php', $options = null, $path = null)
232	{
233		// Deprecation warning.
234		JLog::add('JLog::getInstance() is deprecated.  See JLog::addLogger().', JLog::WARNING, 'deprecated');
235
236		// Get the system configuration object.
237		$config = JFactory::getConfig();
238
239		// Set default path if not set and sanitize it.
240		if (!$path)
241		{
242			$path = $config->get('log_path');
243		}
244
245		// If no options were explicitly set use the default from configuration.
246		if (empty($options))
247		{
248			$options = (array) $config->get('log_options');
249		}
250
251		// Fix up the options so that we use the w3c format.
252		$options['text_entry_format'] = empty($options['format']) ? null : $options['format'];
253		$options['text_file'] = $file;
254		$options['text_file_path'] = $path;
255		$options['logger'] = 'w3c';
256
257		// Generate a unique signature for the JLog instance based on its options.
258		$signature = md5(serialize($options));
259
260		// Only create the object if not already created.
261		if (empty(self::$legacy[$signature]))
262		{
263			self::$legacy[$signature] = new JLog;
264
265			// Register the configuration.
266			self::$legacy[$signature]->configurations[$signature] = $options;
267
268			// Setup the lookup to catch all.
269			self::$legacy[$signature]->lookup[$signature] = (object) array('priorities' => JLog::ALL, 'categories' => array());
270		}
271
272		return self::$legacy[$signature];
273	}
274
275	/**
276	 * Returns a reference to the a JLog object, only creating it if it doesn't already exist.
277	 * Note: This is principally made available for testing and internal purposes.
278	 *
279	 * @param   JLog  $instance  The logging object instance to be used by the static methods.
280	 *
281	 * @return  void
282	 *
283	 * @since   11.1
284	 */
285	public static function setInstance($instance)
286	{
287		if (($instance instanceof JLog) || $instance === null)
288		{
289			self::$instance = & $instance;
290		}
291	}
292
293	/**
294	 * Method to add an entry to the log file.
295	 *
296	 * @param   array  $entry  Array of values to map to the format string for the log file.
297	 *
298	 * @return  boolean  True on success.
299	 *
300	 * @since         11.1
301	 *
302	 * @deprecated    12.1  Use JLog::add() instead.
303	 */
304	public function addEntry($entry)
305	{
306		// Deprecation warning.
307		JLog::add('JLog::addEntry() is deprecated, use JLog::add() instead.', JLog::WARNING, 'deprecated');
308
309		// Easiest case is we already have a JLogEntry object to add.
310		if ($entry instanceof JLogEntry)
311		{
312			return $this->addLogEntry($entry);
313		}
314		// We have either an object or array that needs to be converted to a JLogEntry.
315		elseif (is_array($entry) || is_object($entry))
316		{
317			$tmp = new JLogEntry('');
318			foreach ((array) $entry as $k => $v)
319			{
320				switch ($k)
321				{
322					case 'c-ip':
323						$tmp->clientIP = $v;
324						break;
325					case 'status':
326						$tmp->category = $v;
327						break;
328					case 'level':
329						$tmp->priority = $v;
330						break;
331					case 'comment':
332						$tmp->message = $v;
333						break;
334					default:
335						$tmp->$k = $v;
336						break;
337				}
338			}
339		}
340		// Unrecognized type.
341		else
342		{
343			return false;
344		}
345
346		return $this->addLogEntry($tmp);
347	}
348
349	/**
350	 * Method to add an entry to the appropriate loggers.
351	 *
352	 * @param   JLogEntry  $entry  The JLogEntry object to send to the loggers.
353	 *
354	 * @return  void
355	 *
356	 * @since   11.1
357	 * @throws  LogException
358	 */
359	protected function addLogEntry(JLogEntry $entry)
360	{
361		// Find all the appropriate loggers based on priority and category for the entry.
362		$loggers = $this->findLoggers($entry->priority, $entry->category);
363
364		foreach ((array) $loggers as $signature)
365		{
366			// Attempt to instantiate the logger object if it doesn't already exist.
367			if (empty($this->loggers[$signature]))
368			{
369
370				$class = 'JLogger' . ucfirst($this->configurations[$signature]['logger']);
371				if (class_exists($class))
372				{
373					$this->loggers[$signature] = new $class($this->configurations[$signature]);
374				}
375				else
376				{
377					throw new LogException(JText::_('Unable to create a JLogger instance: '));
378				}
379			}
380
381			// Add the entry to the logger.
382			$this->loggers[$signature]->addEntry($entry);
383		}
384	}
385
386	/**
387	 * Method to find the loggers to use based on priority and category values.
388	 *
389	 * @param   integer  $priority  Message priority.
390	 * @param   string   $category  Type of entry
391	 *
392	 * @return  array  The array of loggers to use for the given priority and category values.
393	 *
394	 * @since   11.1
395	 */
396	protected function findLoggers($priority, $category)
397	{
398		// Initialize variables.
399		$loggers = array();
400
401		// Sanitize inputs.
402		$priority = (int) $priority;
403		$category = strtolower($category);
404
405		// Let's go iterate over the loggers and get all the ones we need.
406		foreach ((array) $this->lookup as $signature => $rules)
407		{
408			// Check to make sure the priority matches the logger.
409			if ($priority & $rules->priorities)
410			{
411
412				// If either there are no set categories (meaning all) or the specific category is set, add this logger.
413				if (empty($category) || empty($rules->categories) || in_array($category, $rules->categories))
414				{
415					$loggers[] = $signature;
416				}
417			}
418		}
419
420		return $loggers;
421	}
422}