* @since 26 Aug 2005 17:09:36
*/
function initDB($recreate_db=false)
{
$app =& App::getInstance();
$db =& DB::getInstance();
static $_db_tested = false;
if ($recreate_db || !$_db_tested && $this->getParam('create_table')) {
if ($recreate_db) {
$db->query("DROP TABLE IF EXISTS " . $this->getParam('db_table'));
$app->logMsg(sprintf('Dropping and recreating table %s.', $this->getParam('db_table')), LOG_INFO, __FILE__, __LINE__);
}
$db->query("CREATE TABLE IF NOT EXISTS " . $db->escapeString($this->getParam('db_table')) . " (
lock_id int NOT NULL auto_increment,
record_table varchar(255) NOT NULL default '',
record_key varchar(255) NOT NULL default '',
record_val varchar(255) NOT NULL default '',
title varchar(255) NOT NULL default '',
set_by_admin_id smallint(11) NOT NULL default '0',
lock_datetime datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (lock_id),
KEY record_table (record_table),
KEY record_key (record_key),
KEY record_val (record_val)
)");
if (!$db->columnExists($this->getParam('db_table'), array(
'lock_id',
'record_table',
'record_key',
'record_val',
'title',
'set_by_admin_id',
'lock_datetime',
), false, false)) {
$app->logMsg(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->getParam('db_table')), LOG_ALERT, __FILE__, __LINE__);
trigger_error(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->getParam('db_table')), E_USER_ERROR);
}
}
$_db_tested = true;
}
/**
* Set the params of this object.
*
* @param array $params Array of param keys and values to set.
*/
function setParam($params=null)
{
if (isset($params) && is_array($params)) {
// Merge new parameters with old overriding only those passed.
$this->_params = array_merge($this->_params, $params);
}
}
/**
* Return the value of a parameter, if it exists.
*
* @access public
* @param string $param Which parameter to return.
* @return mixed Configured parameter value.
*/
function getParam($param)
{
$app =& App::getInstance();
if (isset($this->_params[$param])) {
return $this->_params[$param];
} else {
$app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
return null;
}
}
/**
* Select the lock to manipulate.
*
* @param mixed $record_table_or_lock_id The table containing the record to lock,
* or a numeric lock_id.
* @param string $record_key The key column for the record to lock.
* @param string $record_val The value of the key column for the record to lock.
* @param string $title A title to apply to the lock, for display purposes.
*/
function select($record_table_or_lock_id, $record_key=null, $record_val=null)
{
$app =& App::getInstance();
$db =& DB::getInstance();
$this->initDB();
// Expire old locks.
$this->_auto_timeout();
if (is_numeric($record_table_or_lock_id) && !isset($record_key) && !isset($record_val)) {
// Get lock data by lock_id.
$qid = $db->query("
SELECT * FROM " . $db->escapeString($this->getParam('db_table')) . "
WHERE lock_id = '" . $db->escapeString($record_table_or_lock_id) . "'
");
} else {
// Get lock data by record specs
$qid = $db->query("
SELECT * FROM " . $db->escapeString($this->getParam('db_table')) . "
WHERE record_table = '" . $db->escapeString($record_table_or_lock_id) . "'
AND record_key = '" . $db->escapeString($record_key) . "'
AND record_val = '" . $db->escapeString($record_val) . "'
");
}
if ($this->data = mysql_fetch_assoc($qid)) {
$app->logMsg(sprintf('Selecting %slocked record: %s %s %s', ($this->data['set_by_admin_id'] == $this->_auth->get('user_id') ? 'self-' : ''), $record_table_or_lock_id, $record_key, $record_val), LOG_DEBUG, __FILE__, __LINE__);
/// FIX ME: What if admin set lock, but public user is current lock user?
$this->data['editor'] = $this->_auth->getUsername($this->data['set_by_admin_id']);
return true;
} else {
$app->logMsg(sprintf('No locked record: %s %s %s', $record_table_or_lock_id, $record_key, $record_val), LOG_DEBUG, __FILE__, __LINE__);
return false;
}
}
/**
* Returns true if the record we instantiated with is locked.
*
* @return bool True if locked.
*/
function isLocked()
{
return isset($this->data['lock_id']);
}
/**
* Returns the status of who set the lock. Use this to ignore locks set by
* the current user.
*
* @return bool True if current user set the lock.
*/
function isMine()
{
$db =& DB::getInstance();
$this->initDB();
if (isset($this->data['lock_id'])) {
$qid = $db->query("SELECT * FROM " . $db->escapeString($this->getParam('db_table')) . " WHERE lock_id = '" . $db->escapeString($this->data['lock_id']) . "'");
if ($lock = mysql_fetch_assoc($qid)) {
return ($lock['set_by_admin_id'] == $this->_auth->get('user_id'));
} else {
return false;
}
} else {
return false;
}
}
/**
* Create a new lock for the specified table/key/value.
*
* @param string $record_table The table containing the record to lock.
* @param string $record_key The key column for the record to lock.
* @param string $record_val The value of the key column for the record to lock.
* @param string $title A title to apply to the lock, for display purposes.
*
* @return int The id for the lock (mysql last insert id).
*/
function set($record_table, $record_key, $record_val, $title='')
{
$db =& DB::getInstance();
$this->initDB();
// Expire old locks.
$this->_auto_timeout();
// Remove previous locks if exist. Is this better than using a REPLACE INTO?
$db->query("
DELETE FROM " . $db->escapeString($this->getParam('db_table')) . "
WHERE record_table = '" . $db->escapeString($record_table) . "'
AND record_key = '" . $db->escapeString($record_key) . "'
AND record_val = '" . $db->escapeString($record_val) . "'
");
// Set new lock.
$db->query("
INSERT INTO " . $db->escapeString($this->getParam('db_table')) . " (
record_table,
record_key,
record_val,
title,
set_by_admin_id,
lock_datetime
) VALUES (
'" . $db->escapeString($record_table) . "',
'" . $db->escapeString($record_key) . "',
'" . $db->escapeString($record_val) . "',
'" . $db->escapeString($title) . "',
'" . $db->escapeString($this->_auth->get('user_id')) . "',
NOW()
)
");
$lock_id = mysql_insert_id($db->getDBH());
// Must register this locked record as the current.
$this->select($lock_id);
return $lock_id;
}
/**
* Unlock the currently selected record.
*/
function remove()
{
$app =& App::getInstance();
$db =& DB::getInstance();
$this->initDB();
// Expire old locks.
$this->_auto_timeout();
// Delete a specific lock.
$db->query("
DELETE FROM " . $db->escapeString($this->getParam('db_table')) . "
WHERE lock_id = '" . $db->escapeString($this->data['lock_id']) . "'
");
$app->logMsg(sprintf('Removing lock: %s', $this->data['lock_id']), LOG_DEBUG, __FILE__, __LINE__);
}
/**
* Unlock all records, or all records for a specified user.
*/
function removeAll($user_id=null)
{
$app =& App::getInstance();
$db =& DB::getInstance();
$this->initDB();
// Expire old locks.
$this->_auto_timeout();
if (isset($user_id)) {
// Delete specific user's locks.
$db->query("DELETE FROM " . $db->escapeString($this->getParam('db_table')) . " WHERE set_by_admin_id = '" . $db->escapeString($user_id) . "'");
$app->logMsg(sprintf('Record locks owned by user %s have been deleted', $this->_auth->getUsername($user_id)), LOG_DEBUG, __FILE__, __LINE__);
} else {
// Delete ALL locks.
$db->query("DELETE FROM " . $db->escapeString($this->getParam('db_table')) . "");
$app->logMsg(sprintf('All record locks deleted by user %s', $this->_auth->get('username')), LOG_DEBUG, __FILE__, __LINE__);
}
}
/**
* Deletes all locks that are older than auto_timeout.
*/
function _auto_timeout()
{
$db =& DB::getInstance();
static $_timeout_run = false;
$this->initDB();
if (!$_timeout_run) {
// Delete all old locks.
$db->query("
DELETE FROM " . $db->escapeString($this->getParam('db_table')) . "
WHERE DATE_ADD(lock_datetime, INTERVAL '" . $this->getParam('auto_timeout') . "' SECOND) < NOW()
");
$_timeout_run = true;
}
}
/**
* Redirect to record lock error page.
*/
function dieErrorPage()
{
$app =& App::getInstance();
$app->dieURL(sprintf('%s?lock_id=%s&boomerang=%s', $this->getParam('error_url'), $this->data['lock_id'], urlencode(absoluteMe())));
}
/**
* Print error page.
*/
function printErrorHTML()
{
$app =& App::getInstance();
?>
data['lock_id'];
}
/**
* Return title of locked record.
*/
function getTitle()
{
return $this->data['title'];
}
/**
* Return administrator username for locked record.
*/
function getEditor()
{
return $this->data['editor'];
}
/**
* Return total seconds since the record was locked.
*/
function getSecondsElapsed()
{
if (isset($this->data['lock_datetime']) && strtotime($this->data['lock_datetime']) < time()) {
return time() - strtotime($this->data['lock_datetime']);
} else {
return 0;
}
}
} // End of class.
?>