* @version 1.1 */ class RecordLock { var $data = array(); // Store lock data from DB. var $timeout = 600; // 10 minutes var $auto_timeout = 1800; // 30 minutes var $_auth; // AuthSQL object from which to access a current user_id. /** * Constructor. Optionally select a lock in one swift move. * * @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 RecordLock($auth_object=null) { // Expire old locks. $this->_auto_timeout(); $this->_auth = $auth_object; // FIXME: why does passing by refernce not work here? } /** * 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) { if (is_numeric($record_table_or_lock_id) && !isset($record_key) && !isset($record_val)) { // Get lock data by lock_id. $qid = dbQuery(" SELECT * FROM lock_tbl WHERE lock_id = '" . mysql_real_escape_string($record_table_or_lock_id) . "' "); } else { // Get lock data by record specs $qid = dbQuery(" SELECT * FROM lock_tbl WHERE record_table = '" . mysql_real_escape_string($record_table_or_lock_id) . "' AND record_key = '" . mysql_real_escape_string($record_key) . "' AND record_val = '" . mysql_real_escape_string($record_val) . "' "); } if ($this->data = mysql_fetch_assoc($qid)) { // This could be integrated into the above query, but with the new auth system, this will be a $auth-> method call. // $qid = dbQuery("SELECT username FROM admin_tbl WHERE admin_id = '" . mysql_real_escape_string($this->data['set_by_admin_id']) . "'"); // list($this->data['editor']) = mysql_fetch_row($qid); $this->data['editor'] = $this->_auth->getUsername($this->data['set_by_admin_id']); return true; } else { 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() { if (isset($this->data['lock_id'])) { $qid = dbQuery("SELECT * FROM lock_tbl WHERE lock_id = '" . mysql_real_escape_string($this->data['lock_id']) . "'"); if ($lock = mysql_fetch_assoc($qid)) { return ($lock['set_by_admin_id'] == $this->_auth->getVal('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='') { // Remove previous locks if exist. Is this better than using a REPLACE INTO? dbQuery(" DELETE FROM lock_tbl WHERE record_table = '" . mysql_real_escape_string($record_table) . "' AND record_key = '" . mysql_real_escape_string($record_key) . "' AND record_val = '" . mysql_real_escape_string($record_val) . "' "); // Set new lock. dbQuery(" INSERT INTO lock_tbl ( record_table, record_key, record_val, title, set_by_admin_id, lock_datetime ) VALUES ( '" . mysql_real_escape_string($record_table) . "', '" . mysql_real_escape_string($record_key) . "', '" . mysql_real_escape_string($record_val) . "', '" . mysql_real_escape_string($title) . "', '" . mysql_real_escape_string($this->_auth->getVal('user_id')) . "', NOW() ) "); $lock_id = mysql_insert_id($GLOBALS['dbh']); // Must register this locked record as the current. $this->select($lock_id); return $lock_id; } /** * Unlock the currently selected record. */ function remove() { // Delete a specific lock. dbQuery(" DELETE FROM lock_tbl WHERE lock_id = '" . mysql_real_escape_string($this->data['lock_id']) . "' "); } /** * Unlock all records, or all records for a specified user. */ function removeAll($user_id=null) { if (isset($user_id)) { // Delete specific user's locks. dbQuery("DELETE FROM lock_tbl WHERE set_by_admin_id = '" . mysql_real_escape_string($user_id) . "'"); logMsg(sprintf('Record locks owned by %s %s have been deleted', $this->_auth->getVal('auth_name'), $this->_auth->getUsername($user_id)), LOG_INFO, __FILE__, __LINE__); } else { // Delete ALL locks. dbQuery("DELETE FROM lock_tbl"); logMsg(sprintf('All record locks deleted by %s %s', $this->_auth->getVal('auth_name'), $this->_auth->getVal('username')), LOG_INFO, __FILE__, __LINE__); } } /** * Delete's all locks that are older than auto_timeout. */ function _auto_timeout() { // Delete all old locks. dbQuery(" DELETE FROM lock_tbl WHERE DATE_ADD(lock_datetime, INTERVAL '" . $this->auto_timeout . "' SECOND) < NOW() "); } /** * Redirect to record lock error page. */ function dieErrorPage($boomerang_url=null) { global $CFG; dieURL($CFG->admin_url . '/record_lock.php?lock_id=' . $this->data['lock_id'] . '&boomerang=true'); } /** * Return lock_id of locked record. */ function getID() { return $this->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']) && $this->data['lock_datetime'] < time()) { return time() - strtotime($this->data['lock_datetime']); } else { return 0; } } } // End of class. ?>