<?php
/**
 * CLogRoute class file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link https://www.yiiframework.com/
 * @copyright 2008-2013 Yii Software LLC
 * @license https://www.yiiframework.com/license/
 */

/**
 * CLogRoute is the base class for all log route classes.
 *
 * A log route object retrieves log messages from a logger and sends it
 * somewhere, such as files, emails.
 * The messages being retrieved may be filtered first before being sent
 * to the destination. The filters include log level filter and log category filter.
 *
 * To specify level filter, set {@link levels} property,
 * which takes a string of comma-separated desired level names (e.g. 'Error, Debug').
 * To specify category filter, set {@link categories} property,
 * which takes a string of comma-separated desired category names (e.g. 'System.Web, System.IO').
 *
 * Level filter and category filter are combinational, i.e., only messages
 * satisfying both filter conditions will they be returned.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package system.logging
 * @since 1.0
 */
abstract class CLogRoute extends CComponent
{
	/**
	 * @var boolean whether to enable this log route. Defaults to true.
	 */
	public $enabled=true;
	/**
	 * @var string list of levels separated by comma or space. Defaults to empty, meaning all levels.
	 */
	public $levels='';
	/**
	 * @var mixed array of categories, or string list separated by comma or space. 
	 * Defaults to empty array, meaning all categories.
	 */
	public $categories=array();
	/**
	 * @var mixed array of categories, or string list separated by comma or space, to EXCLUDE from logs.
	 * Defaults to empty array, meaning no categories are excluded.
	 * This will exclude any categories after $categories has been ran.
	 */
	public $except=array();
	/**
	 * @var mixed the additional filter (eg {@link CLogFilter}) that can be applied to the log messages.
	 * The value of this property will be passed to {@link Yii::createComponent} to create
	 * a log filter object. As a result, this can be either a string representing the
	 * filter class name or an array representing the filter configuration.
	 * In general, the log filter class should implement {@link ILogFilter} interface.
	 * If you want to apply multiple filters you can use {@link CChainedLogFilter} to do so.
	 * Defaults to null, meaning no filter will be used.
	 */
	public $filter;
	/**
	 * @var array the logs that are collected so far by this log route.
	 * @since 1.1.0
	 */
	public $logs=array();


	/**
	 * Initializes the route.
	 * This method is invoked after the route is created by the route manager.
	 */
	public function init()
	{
	}

	/**
	 * Formats a log message given different fields.
	 * @param string $message message content
	 * @param integer $level message level
	 * @param string $category message category
	 * @param integer $time timestamp
	 * @return string formatted message
	 */
	protected function formatLogMessage($message,$level,$category,$time)
	{
		return @date('Y/m/d H:i:s',(int)$time)." [$level] [$category] $message\n";
	}

	/**
	 * Retrieves filtered log messages from logger for further processing.
	 * @param CLogger $logger logger instance
	 * @param boolean $processLogs whether to process the logs after they are collected from the logger
	 */
	public function collectLogs($logger, $processLogs=false)
	{
		$logs=$logger->getLogs($this->levels,$this->categories,$this->except);
		$this->logs=empty($this->logs) ? $logs : array_merge($this->logs,$logs);
		if($processLogs && !empty($this->logs))
		{
			if($this->filter!==null)
				Yii::createComponent($this->filter)->filter($this->logs);
			if($this->logs!==array())
				$this->processLogs($this->logs);
			$this->logs=array();
		}
	}

	/**
	 * Processes log messages and sends them to specific destination.
	 * Derived child classes must implement this method.
	 * @param array $logs list of messages. Each array element represents one message
	 * with the following structure:
	 * array(
	 *   [0] => message (string)
	 *   [1] => level (string)
	 *   [2] => category (string)
	 *   [3] => timestamp (float, obtained by microtime(true));
	 */
	abstract protected function processLogs($logs);
}
