<?PHP
/**
* @name mru_manager.php
* Defines class CMRUManager that manages "Most Recently Used" objects
* PHP required: 5.2+
* Uses as_dbutiles.php module for MySQL data access
* @version 1.01 build 0002 2010-12-30
* @Author Alexander Selifonov, <alex [at] selifan {dot} ru>
* @Link: http://www.selifan.ru
* @license http://www.opensource.org/licenses/bsd-license.php BSD
*
**/
class CMRUManager {
private $_MRUlength = 4; # how many events to remember (default value for all item types)
private $_MRUlengths = array(); # assoc/array with max lengths for registered item types
private $_tableName = 'mru_data'; # SQL table name that will store MRU lists
private $_userid = null; # permament logged user id
/**
* Class constructor
*
* @param mixed $options - assoc.array with all options, or "user id" value
* @param mixed $mru_length - MRU capacity (how many items to store per "document/object type"
* @return CMRUManager
*/
function __construct($options=false, $mru_length=0){
global $as_dbengine;
if(is_array($options)) {
if(!empty($options['mrulength'])) $this->_MRUlength = (int) $options['mrulength'];
if(isset($options['mrulengths']) && is_array($options['mrulengths'])) $this->_MRUlengths = $options['mrulengths'];
if(!empty($options['tablename'])) $this->_tableName = (string) $options['tablename'];
if(!empty($options['userid'])) $this->_userid = (string) $options['userid'];
}
else { # if not an array, parameters treated as : first - user id, second - MRU length
if(is_scalar($options)) $this->_userid = $options;
if((int)$mru_length>0 ) $this->_MRUlength = (int) $mru_length;
}
}
/**
* Stores "access to document" event, placing it on "top" of the MRU list
*
* @param mixed $itemid accessed Document ID (or file name)
* @param string/int $userid logged user Id (or unique login)
* @param string/int $itemtype document/object type
*/
public function RegisterEvent($itemid, $itemtype='', $userid=false) {
global $as_dbengine;
$MRUlength = empty($this->_MRUlengths[$itemtype]) ? $this->_MRUlength : (int)$this->_MRUlengths[$itemtype];
if(empty($userid) && !empty($this->_userid)) $userid = $this->_userid;
$curevt = $as_dbengine->GetQueryResult($this->_tableName,'recid,itemid, eventdate',"userid='$userid' AND itemtype='$itemtype'",1,1,0,'eventdate DESC');
if(!is_array($curevt)) {
$curevt = array();
if($as_dbengine->sql_errno()) {
if(stripos($as_dbengine->sql_error(),"doesn't exist") or 1146==$as_dbengine->sql_errno()) {
if( !$this->createMRUtable() ) return false;
# OR: throw new Exception('Cannot create MRU holder table '.$this->_tableName.', check Your DB connection params');
}
}
}
$inMRU = -1;
for($ii=0; $ii<count($curevt); $ii++) { # seekeing if this item is already in MRU
if($curevt[$ii]['itemid'] === $itemid) {
$inMRU = $ii;
break;
}
}
if($inMRU==-1) { # no this item in MRU yet, so insert a record
$as_dbengine->sql_query("INSERT INTO {$this->_tableName} (itemtype,itemid,userid) VALUES('$itemtype','$itemid','$userid')");
if(count($curevt) >= $MRUlength) { # delete obsolete records for this event type/user (push from MRU stack)
for($ii=$MRUlength-1; $ii<count($curevt); $ii++) {
$as_dbengine->sql_query("DELETE FROM {$this->_tableName} WHERE recid=".$curevt[$ii]['recid']);
}
}
}
else { # this item is somewhere in MRU stack, move it to the top by updating eventdate to current time
$as_dbengine->sql_query("UPDATE {$this->_tableName} SET eventdate=NOW() WHERE recid={$curevt[$inMRU]['recid']}");
}
return true;
}
/**
* Get current MRU list for desired user id [and itemtype]
*
* @param mixed $userid int/string user id
* @param mixed $itemtype optional item type
* @return array (may be empty), assoc.array with data: 'itemid'=>item id, 'itemtype'
*/
public function GetMRUList($itemtype='', $uri_pattern=false, $userid=false) {
global $as_dbengine;
if(empty($userid) && !empty($this->_userid)) $userid = $this->_userid;
$addcond = $itemtype ? " AND itemtype='$itemtype'" : '';
$curevt = $as_dbengine->GetQueryResult($this->_tableName,'itemid, itemtype, eventdate',"userid='$userid' $addcond",1,1,0,'eventdate DESC');
if(!is_array($curevt)) $curevt = array();
if(is_string($uri_pattern) && stripos($uri_pattern, '{id}')!==false) {
foreach($curevt as $cno => $item) {
$curevt[$cno]['uri'] = str_ireplace('{id}',urlencode($item['itemid']), $uri_pattern);
}
}
return $curevt;
}
/**
* Clears all MRU list for passed user id and/or item type
*
* @param mixed $userid
* @param mixed $itemtype
*/
public function ClearMRUData($itemtype=false, $itemid=false, $userid=false) {
global $as_dbengine;
if(empty($userid) && !empty($this->_userid)) $userid = $this->_userid;
if(!$userid and !$itemtype and !$itemid) $as_dbengine->sql_query('TRUNCATE TABLE ' . $this->_tableName);
else {
$cond = array();
if($userid) $cond[] = "userid='$userid'";
if($itemtype) $cond[] = "itemtype='$itemtype'";
if($itemid) $cond[] = "itemid='$itemid'";
$as_dbengine->sql_query("DELETE FROM ". $this->_tableName . ' WHERE '. implode(' AND ', $cond));
}
}
/**
* creates table for storing MRU data, returns true if table created, false otherwise
*/
private function createMRUtable() {
global $as_dbengine;
$create_sql = <<<EOSQL
CREATE TABLE {$this->_tableName} (
recid INT(20) not null auto_increment, itemtype CHAR(20) not null default '',
itemid CHAR(80) not null default '', userid CHAR(20) not null default '',
eventdate TIMESTAMP not null, primary key(recid), KEY ix_userid (userid)
)
EOSQL;
$as_dbengine->sql_query($create_sql);
return (0==$as_dbengine->sql_errno());
}
} # CMRUManager definition end