<?php
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *	   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * An Appender that automatically creates a new logfile each day.
 *
 * The file is rolled over once a day. That means, for each day a new file 
 * is created. A formatted version of the date pattern is used as to create 
 * the file name using the {@link PHP_MANUAL#sprintf} function.
 *
 * This appender uses a layout.
 * 
 * ##Configurable parameters:##
 * 
 * - **datePattern** - Format for the date in the file path, follows formatting
 *     rules used by the PHP date() function. Default value: "Ymd".
 * - **file** - Path to the target file. Should contain a %s which gets 
 *     substituted by the date.
 * - **append** - If set to true, the appender will append to the file, 
 *     otherwise the file contents will be overwritten. Defaults to true.
 * 
 * @package log4php
 * @subpackage appenders
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @link http://logging.apache.org/log4php/docs/appenders/daily-file.html Appender documentation
 */
class LoggerAppenderDailyFile extends LoggerAppenderFile {

	/**
	 * The 'datePattern' parameter.
	 * Determines how date will be formatted in file name.
	 * @var string
	 */
	protected $datePattern = "Ymd";
	
	/**
	 * Current date which was used when opening a file.
	 * Used to determine if a rollover is needed when the date changes.
	 * @var string
	 */
	protected $currentDate;

	/** Additional validation for the date pattern. */
	public function activateOptions() {
		parent::activateOptions();
	
		if (empty($this->datePattern)) {
			$this->warn("Required parameter 'datePattern' not set. Closing appender.");
			$this->closed = true;
			return;
		}
	}

	/**
	 * Appends a logging event.
	 * 
	 * If the target file changes because of passage of time (e.g. at midnight) 
	 * the current file is closed. A new file, with the new date, will be 
	 * opened by the write() method. 
	 */
	public function append(LoggerLoggingEvent $event) {
		$eventDate = $this->getDate($event->getTimestamp());
		
		// Initial setting of current date
		if (!isset($this->currentDate)) {
			$this->currentDate = $eventDate;
		} 
		
		// Check if rollover is needed
		else if ($this->currentDate !== $eventDate) {
			$this->currentDate = $eventDate;
			
			// Close the file if it's open.
			// Note: $this->close() is not called here because it would set
			//       $this->closed to true and the appender would not recieve
			//       any more logging requests
			if (is_resource($this->fp)) {
				$this->write($this->layout->getFooter());
				fclose($this->fp);
			}
			$this->fp = null;
		}
	
		parent::append($event);
	}
	
	/** Renders the date using the configured <var>datePattern<var>. */
	protected function getDate($timestamp = null) {
		return date($this->datePattern, $timestamp);
	}
	
	/**
	 * Determines target file. Replaces %s in file path with a date. 
	 */
	protected function getTargetFile() {
		return str_replace('%s', $this->currentDate, $this->file);
	}
	
	/**
	 * Sets the 'datePattern' parameter.
	 * @param string $datePattern
	 */
	public function setDatePattern($datePattern) {
		$this->setString('datePattern', $datePattern);
	}
	
	/**
	 * Returns the 'datePattern' parameter.
	 * @return string
	 */
	public function getDatePattern() {
		return $this->datePattern;
	}
}
