I am looking for a way to extend our default logging class without making changes to the whole application or library. We have a number of places where we write logs. E.g:
App_Log::getInstance()->write(
$name,
$type,
"LOGOUT",
$url
);
Auth_Log
<?php
class App_Auth_Log {
/**
* Singleton instance
*
* Marked only as protected to allow extension of the class. To extend,
* simply override {@link getInstance()}.
*
* @var App_Auth_Log
*/
protected static $_instance = null;
/**
* Auth logging enabled flag.
*
* @var boolean
*/
protected $_enabled = false;
/**
* If flag is true then cleanup will not remove login records.
*
* @var boolean
*/
protected $_keepLoginRecords = false;
/**
* Class constructor.
*/
public function __construct() {
if(App_Front::getInstance()->hasParam("withAuthLog"))
$this->_enabled = true;
if(App_Front::getInstance()->hasParam("withKeepLoginRecords"))
$this->_keepLoginRecords = true;
$this->cleanup();
}
/**
* Singleton instance
*
* @return App_Auth_Log
*/
public static function getInstance() {
if (is_null(self::$_instance))
self::$_instance = new self();
return self::$_instance;
}
/**
* Write new auth log record with given details. if succesful then method
* returns true otherwise returns false.
*
* @param string $class
* @param string $ident
* @param string $action
* @param string $url
* @param string $ipaddr
* @return boolean
* @throws Exception
*/
public function write($class,$ident,$action,$url,$ipaddr=null) {
if($this->isEnabled()) {
$db = App_Db_Connections::getInstance()->getConnection();
try {
// if address not specificed get remote addr
$ipaddr = ($ipaddr == null) ? $_SERVER['REMOTE_ADDR'] : $ipaddr;
// manual insert so we can take advantage of insert delayed
$stmnt = "INSERT INTO accesslogs
VALUES('',NOW(),'$class','$ident','$action','$url','$ipaddr')";
// execute insert
$db->query($stmnt);
} catch (Exception $e) {
throw $e;
}
return true;
}
return false;
}
/**
* Cleanup old accesslog records. Cached to run once a day.
*
* @return boolean - returns true if run false if not.
*/
public function cleanup() {
$cache = App_Cache::getInstance()->newObject(86400);
if($this->isEnabled()) {
if (!$res = $cache->load(App_Cache::getCacheName(__CLASS__. "cleanup"))) {
// add cache
$db = App_Db_Connections::getInstance()->getConnection();
try {
$where = $db->quoteInto("DATEDIFF(NOW(),accesslog_datetime) > ?", 6);
$and = ($this->_keepLoginRecords) ? " AND accesslog_action != 'LOGIN'" : "";
$db->query("DELETE LOW_PRIORITY FROM accesslogs WHERE $where $and");
} catch (Exception $e) {
throw $e;
}
$cache->save($res,App_Cache::getCacheName(__CLASS__. "cleanup"));
} // end cache
}
return;
}
/**
* Returns boolean check if auth log enabled.
*
* @return boolean
*/
public function isEnabled() {
return ($this->_enabled) ? true : false;
}
/**
* Enabled disable the auth log process.
*
* @param boolean $boolean
* @return App_Auth_Log
*/
public function setEnabled($boolean) {
$this->_enabled = ($boolean) ? true : false;
return $this;
}
}
?>
This is the default behaviour of the core code. But for this specific project I need to be able to extend/overwrite the write
method, e.g with extra parameters.
Q: How can I make changes to this App_Auth_Log class so that its backwards compatible with previous projects that call App_Log::getInstance()->write
?
How I think it should work(but dont know how to do it).
If App_Front::getInstance()->hasParam("withAuthLog")
passes a custom class name e.g: My_Custom_Auth_Log
which overwrites the original write method. Just not sure how to modify the singleton part