forceOffline(1); if (!($this->_resource = @mysql_connect( $host, $user, $pass ))) $this->forceOffline(2); if (!mysql_select_db($db)) $this->forceOffline(3); $this->_table_prefix = $table_prefix; } function forceOffline ($error_number) { $mosSystemError = $error_number; $basePath = dirname( __FILE__ ); include $basePath . '/../configuration.php'; include $basePath . '/../offline.php'; exit(); } /** * @param int */ function debug( $level ) { $this->_debug = intval( $level ); } function debug_trace () { trigger_error( $this->_errorNum, E_USER_NOTICE ); //echo "
" . $this->_sql . "\n"; if (function_exists('debug_backtrace')) { foreach(debug_backtrace() as $back) { if (@$back['file']) { echo '
" . htmlspecialchars( $sql ) . ""; } /** * Execute the query * @return mixed A database resource if successful, FALSE if not. */ function query($sql = '') { global $mosConfig_debug; if ($sql == '') $sql = $this->_sql; if ($this->_debug) $this->_log[] = $sql; if ($this->_cursor = mysql_query($sql, $this->_resource)) { $this->_errorNum = 0; $this->_errorMsg = ''; return $this->_cursor; } else { $this->_errorNum = mysql_errno( $this->_resource ); $this->_errorMsg = mysql_error( $this->_resource )." SQL=$sql"; if ($this->_debug) $this->debug_trace(); return false; } } function query_batch( $abort_on_error=true, $p_transaction_safe = false) { $this->_errorNum = 0; $this->_errorMsg = ''; if ($p_transaction_safe) { $si = mysql_get_server_info(); preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m ); $prefix = ''; if ($m[1] >= 4) $prefix = 'START TRANSACTION; '; elseif ($m[2] >= 23) { if ($m[3] >= 19) $prefix = 'BEGIN WORK; '; elseif ($m[3] >= 17) $prefix = 'BEGIN; '; } if ($prefix) $this->_sql = $prefix.$this->_sql.'; COMMIT;'; } $query_split = preg_split ("/[;]+/", $this->_sql); $error = 0; foreach ($query_split as $command_line) { $command_line = trim( $command_line ); if ($command_line != '') { if (!$this->query($command_line)) { $error = 1; echo 'xxx '; if ($abort_on_error) { return $this->_cursor; } } } } return $error ? false : true; } /** * Diagnostic function */ function explain() { if (!($cur = $this->query("EXPLAIN ".$this->_sql))) return null; $headline = $header = $body = ''; $buf = '
| $k | "; $body .= "$v | "; } $headline = $header; $body .= "
|---|---|
$this->_sql" : ''); } function insertid() { return mysql_insert_id(); } function getVersion() { return mysql_get_server_info(); } /** * Fudge method for ADOdb compatibility */ function GenID( $foo1=null, $foo2=null ) { return '0'; } /** * @return array A list of all the tables in the database */ function getTableList() { $this->setQuery( 'SHOW tables' ); $this->query(); return $this->loadResultArray(); } /** * @param array A list of table names * @return array A list the create SQL for the tables */ function getTableCreate( $tables ) { $result = array(); foreach ($tables as $tblval) { $this->setQuery( 'SHOW CREATE table ' . $tblval ); $this->query(); $result[$tblval] = $this->loadResultArray( 1 ); } return $result; } /** * @param array A list of table names * @return array An array of fields by table */ function getTableFields( $tables ) { $result = array(); foreach ($tables as $tblval) { $this->setQuery( 'SHOW FIELDS FROM ' . $tblval ); $this->query(); $fields = $this->loadObjectList(); foreach ($fields as $field) { $result[$tblval][$field->Field] = preg_replace("/[(0-9)]/",'', $field->Type ); } } return $result; } function displayLogged () { echo count($this->_log).' queries executed'; echo '
';
foreach ($this->_log as $k=>$sql) {
echo $k+1 . "\n" . $sql . '
';
}
}
/* Helper method - maybe should go into database itself */
function doSQL ($sql) {
$this->setQuery($sql);
if (!$this->query()) {
echo "\n";
exit();
}
}
/* Helper method - maybe could go into database itself */
function &doSQLget ($sql, $classname) {
$this->setQuery($sql);
$rows = $this->loadObjectList();
$target = get_class_vars($classname);
if ($rows) {
foreach ($rows as $row) {
$next = new $classname(0);
foreach ($target as $field=>$value) {
if (isset($row->$field)) $next->$field = $row->$field;
}
$result[] = $next;
}
}
else $result = array();
return $result;
}
}
class mamboDatabase extends database {
function mamboDatabase () {
$host = mamboCore::get('mosConfig_host');
$user = mamboCore::get('mosConfig_user');
$pw = mamboCore::get('mosConfig_password');
$db = mamboCore::get('mosConfig_db');
$prefix = mamboCore::get('mosConfig_dbprefix');
parent::database($host, $user, $pw, $db, $prefix);
}
function &getInstance () {
static $instance;
if (!is_object($instance)) $instance = new mamboDatabase();
return $instance;
}
}
/**
* mosDBTable Abstract Class.
* @abstract
* @package Mambo
* @subpackage Database
*
* Parent classes to all database derived objects. Customisation will generally
* not involve tampering with this object.
* @package Mambo
* @author Andrew Eddie _tbl = $table;
$this->_tbl_key = $key;
$this->_db =& $db;
}
/**
* @return bool True if DB query failed. Sets the error message
*/
function queryTestFailure () {
if ($this->_db->query()) return false;
$this->_error = $this->_db->getErrorMsg();
return true;
}
/**
* Filters public properties
* @access protected
* @param array List of fields to ignore
*/
function filter( $ignoreList=null ) {
$callcheck = array('InputFilter', 'process');
if (!is_callable($callcheck)) require_once(mamboCore::get('mosConfig_absolute_path').'/includes/phpInputFilter/class.inputfilter.php');
// specific filters
$iFilter =& new InputFilter();
if (is_array($ignoreList)) foreach ($this->getPublicProperties() as $k) {
if (!in_array($k, $ignoreList)) $this->$k = $iFilter->process($this->$k);
}
else foreach ($this->getPublicProperties() as $k) $this->$k = $iFilter->process($this->$k);
}
/**
* @return string Returns the error message
*/
function getError() {
return $this->_error;
}
/**
* Gets the value of the class variable
* @param string The name of the class variable
* @return mixed The value of the class var (or null if no var of that name exists)
*/
function get( $_property ) {
if(isset( $this->$_property )) return $this->$_property;
else return null;
}
/**
* Returns an array of public properties
* @return array
*/
function getPublicProperties() {
static $cache = null;
if (is_null( $cache )) {
$cache = array();
foreach (get_class_vars( get_class( $this ) ) as $key=>$val) {
if (substr( $key, 0, 1 ) != '_') {
$cache[] = $key;
}
}
}
return $cache;
}
/**
* Checks if this object lacks the property given by the parameter
* @param string The name of the property
* @return bool
*/
function lacks( $property ) {
$thisclass = strtolower(get_class($this));
if (!array_key_exists( $property, get_class_vars($thisclass) )) {
$this->_error = "WARNING: $thisclass does not support $property.";
return true;
}
return false;
}
/**
* Set the value of the class variable
* @param string The name of the class variable
* @param mixed The value to assign to the variable
*/
function set( $_property, $_value ) {
$this->$_property = $_value;
}
/**
* binds a named array/hash to this object
*
* can be overloaded/supplemented by the child class
* @param array $hash named array
* @return null|string null is operation was satisfactory, otherwise returns an error
*/
function bind( $array, $ignore="" ) {
$database =& mamboDatabase::getInstance();
if (is_array($array)) return $database->mosBindArrayToObject($array, $this, $ignore);
$this->_error = strtolower(get_class( $this ))."::bind failed.";
return false;
}
/**
* binds an array/hash to this object
* @param int $oid optional argument, if not specifed then the value of current key is used
* @return any result from the database operation
*/
function load( $oid=null ) {
$k = $this->_tbl_key;
if ($oid !== null) $this->$k = $oid;
if ($this->$k === null) return false;
$this->_db->setQuery("SELECT * FROM $this->_tbl WHERE $this->_tbl_key='".$this->$k."'" );
return $this->_db->loadObject($this);
}
/**
* generic check method
*
* can be overloaded/supplemented by the child class
* @return boolean True if the object is ok
*/
function check() {
return true;
}
/**
* Inserts a new row if id is zero or updates an existing row in the database table
*
* Can be overloaded/supplemented by the child class
* @param boolean If false, null object variables are not updated
* @return null|string null if successful otherwise returns and error message
*/
function store( $updateNulls=false ) {
$k = $this->_tbl_key;
global $migrate;
if( $this->$k && !$migrate) $ret = $this->_db->updateObject( $this->_tbl, $this, $this->_tbl_key, $updateNulls );
else $ret = $this->_db->insertObject( $this->_tbl, $this, $this->_tbl_key );
if( !$ret ) {
$this->_error = strtolower(get_class( $this ))."::store failed
" . $this->_db->getErrorMsg();
return false;
} else return true;
}
/**
* Determine from the direction parameter which operator and order to use in SQL
*/
function orderCodes ($direction) {
if ($direction < 0) {
$relation = '<';
$ordering = ' ORDER BY ordering DESC';
}
elseif ($direction > 0) {
$relation = '>';
$ordering = ' ORDER BY ordering ASC';
}
else {
$relation = '=';
$ordering = '';
}
return array ($relation, $ordering);
}
/**
*/
function move( $direction, $where='' ) {
$k = $this->_tbl_key;
list ($relation, $ordering) = $this->orderCodes($direction);
$sql = "SELECT $this->_tbl_key, ordering FROM $this->_tbl WHERE ordering $relation $this->ordering";
$sql .= ($where ? "\n AND $where" : '').$ordering.' LIMIT 1';
$this->_db->setQuery( $sql );
$row = null;
if ($this->_db->loadObject($row)) {
$sql = "UPDATE $this->_tbl SET ordering='$row->ordering' WHERE $this->_tbl_key='".$this->$k."'";
$this->_db->doSQL($sql);
}
$sql = "UPDATE $this->_tbl SET ordering='$this->ordering' WHERE $this->_tbl_key='".$row->$k."'";
if ($row) $this->ordering = $row->ordering;
$this->_db->doSQL($sql);
}
/**
* Compacts the ordering sequence of the selected records
* @param string Additional where query to limit ordering to a particular subset of records
*/
function updateOrder( $where='' ) {
if ($this->lacks('ordering')) return false;
$k = $this->_tbl_key;
if ($this->_tbl == "#__content_frontpage") $order2 = ", content_id DESC";
else $order2 = "";
$sql = "SELECT $k, ordering FROM $this->_tbl "
. ($where ? "\nWHERE $where" : '')
. "\nORDER BY ordering$order2";
$this->_db->setQuery($sql);
if (!$rows = $this->_db->loadObjectList()) {
$this->_error = $this->_db->getErrorMsg();
return false;
}
$i = 1;
foreach ($rows as $row) {
$sql = "UPDATE $this->_tbl SET ordering=$i WHERE $k = ".$row->$k;
$this->_db->doSQL($sql);
$i++;
}
return true;
}
/**
* Default delete method
*
* can be overloaded/supplemented by the child class
* @return true if successful otherwise returns and error message
*/
function delete( $oid=null ) {
$k = $this->_tbl_key;
if ($oid) $this->$k = intval( $oid );
$this->_db->setQuery( "DELETE FROM $this->_tbl WHERE $this->_tbl_key = '".$this->$k."'" );
if ($this->queryTestFailure()) return false;
return true;
}
function checkout( $who, $oid=null ) {
if ($this->lacks('checked_out')) return false;
$k = $this->_tbl_key;
if ($oid !== null) $this->$k = $oid;
$time = date( "%Y-%m-%d H:i:s" );
if (intval( $who )) {
// new way of storing editor, by id
$this->_db->setQuery( "UPDATE $this->_tbl"
. "\nSET checked_out='$who', checked_out_time='$time'"
. "\nWHERE $this->_tbl_key='".$this->$k."'"
);
} else {
// old way of storing editor, by name
$this->_db->setQuery( "UPDATE $this->_tbl"
. "\nSET checked_out='1', checked_out_time='$time', editor='".$who."' "
. "\nWHERE $this->_tbl_key='".$this->$k."'"
);
}
return $this->_db->query();
}
function checkin( $oid=null ) {
if ($this->lacks('checked_out')) return false;
$k = $this->_tbl_key;
if ($oid !== null) $this->$k = $oid;
$time = date("H:i:s");
$this->_db->setQuery( "UPDATE $this->_tbl"
. "\nSET checked_out='0', checked_out_time='0000-00-00 00:00:00'"
. "\nWHERE $this->_tbl_key='".$this->$k."'"
);
return $this->_db->query();
}
function hit( $oid=null ) {
$k = $this->_tbl_key;
if ($oid !== null) $this->$k = intval( $oid );
$key = $this->$k;
$this->_db->setQuery( "UPDATE $this->_tbl SET hits=(hits+1) WHERE $this->_tbl_key='$key'" );
$this->_db->query();
if (mamboCore::get('mosConfig_enable_log_items')) {
$now = date( "Y-m-d" );
$this->_db->setQuery( "SELECT hits"
. "\nFROM #__core_log_items"
. "\nWHERE time_stamp='$now' AND item_table='$this->_tbl' AND item_id='$key'"
);
$hits = intval( $this->_db->loadResult() );
if ($hits) $this->_db->setQuery( "UPDATE #__core_log_items SET hits=(hits+1)"
. "\nWHERE time_stamp='$now' AND item_table='$this->_tbl' AND item_id='".$this->$k."'"
);
else $this->_db->setQuery( "INSERT INTO #__core_log_items VALUES"
. "\n('$now','$this->_tbl','".$this->$k."','1')"
);
$this->_db->query();
}
}
/**
* Generic save function
* @param array Source array for binding to class vars
* @param string Filter for the order updating
* @returns TRUE if completely successful, FALSE if partially or not succesful.
*/
function save( $source, $order_filter ) {
if (!$this->bind($_POST) OR !$this->check() OR !$this->store()OR !$this->checkin()) return false;
$filter_value = $this->$order_filter;
$this->updateOrder( $order_filter ? "`$order_filter`='$filter_value'" : "" );
$this->_error = '';
return true;
}
/**
* Generic Publish/Unpublish function
* @param array An array of id numbers
* @param integer 0 if unpublishing, 1 if publishing
* @param integer The id of the user performnig the operation
*/
function publish_array( $cid=null, $publish=1, $myid=0 ) {
if (!is_array( $cid ) OR count( $cid ) < 1) {
$this->_error = "No items selected.";
return false;
}
$cids = implode( ',', $cid );
$this->_db->setQuery( "UPDATE $this->_tbl SET published='$publish'"
. "\nWHERE $this->_tbl_key IN ($cids) AND (checked_out=0 OR checked_out='$myid')"
);
if ($this->queryTestFailure()) return false;
if (count( $cid ) == 1) $this->checkin( $cid[0] );
return true;
}
/**
* Export item list to xml
* @param boolean Map foreign keys to text values
*/
function toXML( $mapKeysToText=false ) {
$xml = ' $v) {
if ($v === null OR is_array($v) OR is_object($v)) continue;
if ($k[0] == '_') continue; // internal field
$xml .= '<' . $k . '>' . $k . '>';
}
$xml .= ' ';
return $xml;
}
}
/**
* Abstract class for classes where the objects of the class can be relatively easily
* stored in a single database table. Can usually be adapted to more complex cases.
* Requires child classes to implement: tableName(), notSQL().
* tableName() must return the name of the database table, using #__ in the usual Mambo way
* notSQL() must return an array of strings, where each string is the name of a
* variable that is NOT in the database table, or is not written explicitly,
* e.g. the auto-increment key. If this is the ONLY non-SQL field, then the
* child class need not implement it, as that it is already in the abstract class.
* Child classes may implement timeStampField, in which case it must return the name
* of a field that will have a timestamp placed in it whenever the DB is written.
*/
class mosDBTableEntry {
function mosDBTableEntry () {
die ('Cannot instantiate mosDBTableEntry');
}
/* Stores all POST data where the name matches an object variable name */
function addPostData () {
foreach (get_class_vars(get_class($this)) as $field=>$value) {
if ($field!='id' AND isset($_POST[$field])) {
$this->$field = trim($_POST[$field]);
}
}
$this->forceBools();
}
/* Provided in case child class does not implement it. Can force any values */
/* within some limited range. In particular, can force bools to be 0 or 1 */
function forceBools () {
return;
}
/* Updates an existing DB entry with the object's current values */
function updateObjectDB () {
$this->prepareValues();
$database = mamboDatabase::getInstance();
$database->doSQL($this->updateSQL());
}
/* Deletes the current object from the DB */
function delete () {
$table = $this->tableName();
$sql = "DELETE FROM $table WHERE id=$this->id";
$database = mamboDatabase::getInstance();
$database->doSQL($sql);
}
/* Provided in case the child class does not provide a method for timeStampField */
function timeStampField () {
return '';
}
/* Provides SQL for updating the DB with the contents of the current object */
function updateSQL () {
$tabname = $this->tableName();
$sql = "UPDATE $tabname SET %s WHERE id=$this->id";
$exclude = $this->notSQL();
foreach (get_class_vars(get_class($this)) as $field=>$value) {
if (!in_array($field,$exclude)) $setter[] = $field."='".$this->$field."'";
}
$timestamp = $this->timeStampField();
if ($timestamp) $setter[] = $timestamp."='".date('Y-m-d H:i:s')."'";
return sprintf($sql,implode(',', $setter));
}
/* Default method for identifying fields not to be written to the DB */
/* The child classes may override this and return more items in the array */
function notSQL () {
return array ('id');
}
/* Provides SQL to insert the current object into the DB */
function insertSQL () {
$tabname = $this->tableName();
$sql = "INSERT INTO $tabname (%s) VALUES (%s)";
$exclude = $this->notSQL();
foreach (get_class_vars(get_class($this)) as $field=>$value) {
if (!in_array($field,$exclude)) {
$infields[] = $field;
$values[] = "'".$this->$field."'";
}
}
$timestamp = $this->timeStampField();
if ($timestamp) {
$infields[] = $timestamp;
$values[] = "'".date('Y-m-d H:i:s')."'";
}
return sprintf($sql, implode(',', $infields), implode(',', $values));
}
/* Copies any matching fields from some arbitrary object into the current object */
function setValues (&$anObject) {
foreach (get_class_vars(get_class($this)) as $field=>$value) {
if ($field != 'id' AND isset($anObject->$field)) $this->$field = $anObject->$field;
}
}
/* Ensures values can safely be written to DB; assumes magic quotes forced off */
function prepareValues () {
$database = mamboDatabase::getInstance();
foreach (get_class_vars(get_class($this)) as $field=>$value) {
if (!is_numeric($this->$field) AND is_string($this->$field)) $this->$field = $database->getEscaped($this->$field);
}
}
/* Takes some arbitrary SELECT type SQL and places the first or only result into the current object */
function readDataBase($sql) {
$database = mamboDatabase::getInstance();
$database->setQuery( $sql );
if (!$database->loadObject($this)) $this->id = 0;
}
}
?>