| 1 |
<?php |
<?php |
|
/** |
|
|
* @version $Id: database.php,v 1.3 2005/07/22 03:36:09 eddieajau Exp $ |
|
|
* @package Mambo |
|
|
* @subpackage Database |
|
|
* @copyright (C) 2000 - 2005 Miro International Pty Ltd |
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL |
|
|
* Mambo is Free Software |
|
|
*/ |
|
|
|
|
|
/** ensure this file is being included by a parent file */ |
|
|
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); |
|
| 2 |
|
|
| 3 |
/** |
/** |
| 4 |
* Database connector class |
* Database connector class |
| 20 |
var $_cursor=null; |
var $_cursor=null; |
| 21 |
/** @var boolean Debug option */ |
/** @var boolean Debug option */ |
| 22 |
var $_debug=0; |
var $_debug=0; |
|
/** @var int A counter for the number of queries performed by the object instance */ |
|
|
var $_ticker=0; |
|
| 23 |
/** @var array A log of queries */ |
/** @var array A log of queries */ |
| 24 |
var $_log=null; |
var $_log=array(); |
| 25 |
|
|
| 26 |
/** |
/** |
| 27 |
* Database object constructor |
* Database object constructor |
| 33 |
*/ |
*/ |
| 34 |
function database( $host='localhost', $user, $pass, $db, $table_prefix ) { |
function database( $host='localhost', $user, $pass, $db, $table_prefix ) { |
| 35 |
// perform a number of fatality checks, then die gracefully |
// perform a number of fatality checks, then die gracefully |
| 36 |
if (!function_exists( 'mysql_connect' )) { |
if (!function_exists( 'mysql_connect' )) $this->forceOffline(1); |
| 37 |
//or die( 'FATAL ERROR: MySQL support not available. Please check your configuration.' ); |
if (!($this->_resource = @mysql_connect( $host, $user, $pass ))) $this->forceOffline(2); |
| 38 |
$mosSystemError = 1; |
if (!mysql_select_db($db)) $this->forceOffline(3); |
| 39 |
$basePath = dirname( __FILE__ ); |
$this->_table_prefix = $table_prefix; |
|
include $basePath . '/../configuration.php'; |
|
|
include $basePath . '/../offline.php'; |
|
|
exit(); |
|
|
} |
|
|
if (!($this->_resource = @mysql_connect( $host, $user, $pass ))) { |
|
|
//or die( 'FATAL ERROR: Connection to database server failed.' ); |
|
|
$mosSystemError = 2; |
|
|
$basePath = dirname( __FILE__ ); |
|
|
include $basePath . '/../configuration.php'; |
|
|
include $basePath . '/../offline.php'; |
|
|
exit(); |
|
| 40 |
} |
} |
| 41 |
if (!mysql_select_db($db)) { |
|
| 42 |
//or die( "FATAL ERROR: Database not found. Operation failed with error: ".mysql_error()); |
function forceOffline ($error_number) { |
| 43 |
$mosSystemError = 3; |
$mosSystemError = $error_number; |
| 44 |
$basePath = dirname( __FILE__ ); |
$basePath = dirname( __FILE__ ); |
| 45 |
include $basePath . '/../configuration.php'; |
include $basePath . '/configuration.php'; |
| 46 |
include $basePath . '/../offline.php'; |
include $basePath . '/offline.php'; |
| 47 |
exit(); |
exit(); |
| 48 |
} |
} |
|
$this->_table_prefix = $table_prefix; |
|
|
$this->_ticker = 0; |
|
|
$this->_log = array(); |
|
|
} |
|
| 49 |
/** |
/** |
| 50 |
* @param int |
* @param int |
| 51 |
*/ |
*/ |
| 52 |
function debug( $level ) { |
function debug( $level ) { |
| 53 |
$this->_debug = intval( $level ); |
$this->_debug = intval( $level ); |
| 54 |
} |
} |
| 55 |
|
|
| 56 |
|
function debug_trace () { |
| 57 |
|
trigger_error( $this->_errorNum, E_USER_NOTICE ); |
| 58 |
|
//echo "<pre>" . $this->_sql . "</pre>\n"; |
| 59 |
|
if (function_exists('debug_backtrace')) { |
| 60 |
|
foreach(debug_backtrace() as $back) { |
| 61 |
|
if (@$back['file']) { |
| 62 |
|
echo '<br />'.$back['file'].':'.$back['line']; |
| 63 |
|
} |
| 64 |
|
} |
| 65 |
|
} |
| 66 |
|
} |
| 67 |
/** |
/** |
| 68 |
* @return int The error number for the most recent query |
* @return int The error number for the most recent query |
| 69 |
*/ |
*/ |
| 112 |
* @author thede, David McKinnis |
* @author thede, David McKinnis |
| 113 |
*/ |
*/ |
| 114 |
function replacePrefix( $sql, $prefix='#__' ) { |
function replacePrefix( $sql, $prefix='#__' ) { |
| 115 |
$sql = trim( $sql ); |
$done = ''; |
| 116 |
|
while (strlen($sql)) { |
| 117 |
$escaped = false; |
if ($double = preg_match('/\"([^\\\"]|\\.)*"/', $sql,$matches_double,PREG_OFFSET_CAPTURE) OR |
| 118 |
$quoteChar = ''; |
$single = preg_match("/\'([^\\\']|\\.)*'/", $sql,$matches_single,PREG_OFFSET_CAPTURE)) { |
| 119 |
|
if ($single == 0 OR ($double AND $matches_double[0][1] < $matches_single[0][1])) { |
| 120 |
$n = strlen( $sql ); |
$done .= str_replace($prefix, $this->_table_prefix, substr($sql,0,$matches_double[0][1])).$matches_double[0][0]; |
| 121 |
|
$sql = substr($sql,$matches_double[0][1]+strlen($matches_double[0][0])); |
| 122 |
$startPos = 0; |
} |
| 123 |
$literal = ''; |
else { |
| 124 |
while ($startPos < $n) { |
$done .= str_replace($prefix, $this->_table_prefix, substr($sql,0,$matches_single[0][1])).$matches_single[0][0]; |
| 125 |
$ip = strpos($sql, $prefix, $startPos); |
$sql = substr($sql,$matches_single[0][1]+strlen($matches_single[0][0])); |
|
if ($ip === false) { |
|
|
break; |
|
|
} |
|
|
|
|
|
$j = strpos( $sql, "'", $startPos ); |
|
|
$k = strpos( $sql, '"', $startPos ); |
|
|
if (($k !== FALSE) && (($k < $j) || ($j === FALSE))) { |
|
|
$quoteChar = '"'; |
|
|
$j = $k; |
|
|
} else { |
|
|
$quoteChar = "'"; |
|
| 126 |
} |
} |
|
|
|
|
if ($j === false) { |
|
|
$j = $n; |
|
| 127 |
} |
} |
| 128 |
|
else return $done.str_replace($prefix, $this->_table_prefix,$sql); |
|
$literal .= str_replace( $prefix, $this->_table_prefix, substr( $sql, $startPos, $j - $startPos ) ); |
|
|
$startPos = $j; |
|
|
|
|
|
$j = $startPos + 1; |
|
|
|
|
|
if ($j >= $n) { |
|
|
break; |
|
| 129 |
} |
} |
| 130 |
|
return $done; |
|
// quote comes first, find end of quote |
|
|
while (TRUE) { |
|
|
$k = strpos( $sql, $quoteChar, $j ); |
|
|
$escaped = false; |
|
|
if ($k === false) { |
|
|
break; |
|
|
} |
|
|
$l = $k - 1; |
|
|
while ($l >= 0 && $sql{$l} == '\\') { |
|
|
$l--; |
|
|
$escaped = !$escaped; |
|
|
} |
|
|
if ($escaped) { |
|
|
$j = $k+1; |
|
|
continue; |
|
|
} |
|
|
break; |
|
|
} |
|
|
if ($k === FALSE) { |
|
|
// error in the query - no end quote; ignore it |
|
|
break; |
|
|
} |
|
|
$literal .= substr( $sql, $startPos, $k - $startPos + 1 ); |
|
|
$startPos = $k+1; |
|
|
} |
|
|
if ($startPos < $n) { |
|
|
$literal .= substr( $sql, $startPos, $n - $startPos ); |
|
|
} |
|
|
return $literal; |
|
| 131 |
} |
} |
| 132 |
/** |
/** |
| 133 |
* @return string The current value of the internal SQL vairable |
* @return string The current value of the internal SQL vairable |
| 134 |
*/ |
*/ |
| 135 |
function getQuery() { |
function getQuery($sql='') { |
| 136 |
return "<pre>" . htmlspecialchars( $this->_sql ) . "</pre>"; |
if ($sql == '') $sql = $this->_sql; |
| 137 |
|
return "<pre>" . htmlspecialchars( $sql ) . "</pre>"; |
| 138 |
} |
} |
| 139 |
/** |
/** |
| 140 |
* Execute the query |
* Execute the query |
| 141 |
* @return mixed A database resource if successful, FALSE if not. |
* @return mixed A database resource if successful, FALSE if not. |
| 142 |
*/ |
*/ |
| 143 |
function query() { |
function query($sql = '') { |
| 144 |
global $mosConfig_debug; |
global $mosConfig_debug; |
| 145 |
if ($this->_debug) { |
if ($sql == '') $sql = $this->_sql; |
| 146 |
$this->_ticker++; |
if ($this->_debug) $this->_log[] = $sql; |
| 147 |
$this->_log[] = $this->_sql; |
if ($this->_cursor = mysql_query($sql, $this->_resource)) { |
|
} |
|
| 148 |
$this->_errorNum = 0; |
$this->_errorNum = 0; |
| 149 |
$this->_errorMsg = ''; |
$this->_errorMsg = ''; |
| 150 |
$this->_cursor = mysql_query( $this->_sql, $this->_resource ); |
return $this->_cursor; |
|
if (!$this->_cursor) { |
|
|
$this->_errorNum = mysql_errno( $this->_resource ); |
|
|
$this->_errorMsg = mysql_error( $this->_resource )." SQL=$this->_sql"; |
|
|
if ($this->_debug) { |
|
|
trigger_error( mysql_error( $this->_resource ), E_USER_NOTICE ); |
|
|
//echo "<pre>" . $this->_sql . "</pre>\n"; |
|
|
if (function_exists( 'debug_backtrace' )) { |
|
|
foreach( debug_backtrace() as $back) { |
|
|
if (@$back['file']) { |
|
|
echo '<br />'.$back['file'].':'.$back['line']; |
|
|
} |
|
|
} |
|
|
} |
|
| 151 |
} |
} |
| 152 |
|
else { |
| 153 |
|
$this->_errorNum = mysql_errno( $this->_resource ); |
| 154 |
|
$this->_errorMsg = mysql_error( $this->_resource )." SQL=$sql"; |
| 155 |
|
if ($this->_debug) $this->debug_trace(); |
| 156 |
return false; |
return false; |
| 157 |
} |
} |
|
return $this->_cursor; |
|
| 158 |
} |
} |
| 159 |
|
|
| 160 |
function query_batch( $abort_on_error=true, $p_transaction_safe = false) { |
function query_batch( $abort_on_error=true, $p_transaction_safe = false) { |
| 163 |
if ($p_transaction_safe) { |
if ($p_transaction_safe) { |
| 164 |
$si = mysql_get_server_info(); |
$si = mysql_get_server_info(); |
| 165 |
preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m ); |
preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m ); |
| 166 |
if ($m[1] >= 4) { |
$prefix = ''; |
| 167 |
$this->_sql = 'START TRANSACTION;' . $this->_sql . '; COMMIT;'; |
if ($m[1] >= 4) $prefix = 'START TRANSACTION; '; |
| 168 |
} else if ($m[2] >= 23 && $m[3] >= 19) { |
elseif ($m[2] >= 23) { |
| 169 |
$this->_sql = 'BEGIN WORK;' . $this->_sql . '; COMMIT;'; |
if ($m[3] >= 19) $prefix = 'BEGIN WORK; '; |
| 170 |
} else if ($m[2] >= 23 && $m[3] >= 17) { |
elseif ($m[3] >= 17) $prefix = 'BEGIN; '; |
|
$this->_sql = 'BEGIN;' . $this->_sql . '; COMMIT;'; |
|
| 171 |
} |
} |
| 172 |
|
if ($prefix) $this->_sql = $prefix.$this->_sql.'; COMMIT;'; |
| 173 |
} |
} |
| 174 |
$query_split = preg_split ("/[;]+/", $this->_sql); |
$query_split = preg_split ("/[;]+/", $this->_sql); |
| 175 |
$error = 0; |
$error = 0; |
| 176 |
foreach ($query_split as $command_line) { |
foreach ($query_split as $command_line) { |
| 177 |
$command_line = trim( $command_line ); |
$command_line = trim( $command_line ); |
| 178 |
if ($command_line != '') { |
if ($command_line != '') { |
| 179 |
$this->_cursor = mysql_query( $command_line, $this->_resource ); |
if (!$this->query($command_line)) { |
|
if (!$this->_cursor) { |
|
| 180 |
$error = 1; echo 'xxx '; |
$error = 1; echo 'xxx '; |
|
$this->_errorNum .= mysql_errno( $this->_resource ) . ' '; |
|
|
$this->_errorMsg .= mysql_error( $this->_resource )." SQL=$command_line <br />"; |
|
| 181 |
if ($abort_on_error) { |
if ($abort_on_error) { |
| 182 |
return $this->_cursor; |
return $this->_cursor; |
| 183 |
} |
} |
| 191 |
* Diagnostic function |
* Diagnostic function |
| 192 |
*/ |
*/ |
| 193 |
function explain() { |
function explain() { |
| 194 |
$temp = $this->_sql; |
if (!($cur = $this->query("EXPLAIN ".$this->_sql))) return null; |
| 195 |
$this->_sql = "EXPLAIN $this->_sql"; |
$headline = $header = $body = ''; |
| 196 |
$this->query(); |
$buf = '<table cellspacing="1" cellpadding="2" border="0" bgcolor="#000000" align="center">'; |
| 197 |
|
$buf .= $this->getQuery("EXPLAIN ".$this->_sql); |
|
if (!($cur = $this->query())) { |
|
|
return null; |
|
|
} |
|
|
$first = true; |
|
|
|
|
|
$buf = "<table cellspacing=\"1\" cellpadding=\"2\" border=\"0\" bgcolor=\"#000000\" align=\"center\">"; |
|
|
$buf .= $this->getQuery(); |
|
| 198 |
while ($row = mysql_fetch_assoc( $cur )) { |
while ($row = mysql_fetch_assoc( $cur )) { |
| 199 |
if ($first) { |
$body .= "<tr>"; |
|
$buf .= "<tr>"; |
|
| 200 |
foreach ($row as $k=>$v) { |
foreach ($row as $k=>$v) { |
| 201 |
$buf .= "<th bgcolor=\"#ffffff\">$k</th>"; |
if ($headline == '') $header .= "<th bgcolor=\"#ffffff\">$k</th>"; |
| 202 |
|
$body .= "<td bgcolor=\"#ffffff\">$v</td>"; |
| 203 |
} |
} |
| 204 |
$buf .= "</tr>"; |
$headline = $header; |
| 205 |
$first = false; |
$body .= "</tr>"; |
| 206 |
} |
} |
| 207 |
$buf .= "<tr>"; |
$buf .= "<tr>$headline</tr>$body</table><br /> "; |
|
foreach ($row as $k=>$v) { |
|
|
$buf .= "<td bgcolor=\"#ffffff\">$v</td>"; |
|
|
} |
|
|
$buf .= "</tr>"; |
|
|
} |
|
|
$buf .= "</table><br /> "; |
|
| 208 |
mysql_free_result( $cur ); |
mysql_free_result( $cur ); |
|
|
|
|
$this->_sql = $temp; |
|
|
|
|
| 209 |
return "<div style=\"background-color:#FFFFCC\" align=\"left\">$buf</div>"; |
return "<div style=\"background-color:#FFFFCC\" align=\"left\">$buf</div>"; |
| 210 |
} |
} |
| 211 |
/** |
/** |
| 216 |
} |
} |
| 217 |
|
|
| 218 |
/** |
/** |
| 219 |
|
* Load an array of retrieved database objects or values |
| 220 |
|
* @param int Database cursor |
| 221 |
|
* @param string The field name of a primary key |
| 222 |
|
* @return array If <var>key</var> is empty as sequential list of returned records. |
| 223 |
|
* If <var>key</var> is not empty then the returned array is indexed by the value |
| 224 |
|
* the database key. Returns <var>null</var> if the query fails. |
| 225 |
|
*/ |
| 226 |
|
function &retrieveResults ($key='', $max=0, $result_type='row') { |
| 227 |
|
$results = array(); |
| 228 |
|
$sql_function = 'mysql_fetch_'.$result_type; |
| 229 |
|
if ($cur = $this->query()) { |
| 230 |
|
while ($row = $sql_function($cur)) { |
| 231 |
|
if ($key != '') $results[$row->$key] = $row; |
| 232 |
|
else $results[] = $row; |
| 233 |
|
if ($max AND count($results) >= $max) break; |
| 234 |
|
} |
| 235 |
|
mysql_free_result($cur); |
| 236 |
|
} |
| 237 |
|
return $results; |
| 238 |
|
} |
| 239 |
|
/** |
| 240 |
* This method loads the first field of the first row returned by the query. |
* This method loads the first field of the first row returned by the query. |
| 241 |
* |
* |
| 242 |
* @return The value returned in the query or null if the query failed. |
* @return The value returned in the query or null if the query failed. |
| 243 |
*/ |
*/ |
| 244 |
function loadResult() { |
function loadResult() { |
| 245 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults('', 1, 'row'); |
| 246 |
return null; |
if (count($results)) return $results[0][0]; |
| 247 |
} |
else return null; |
|
$ret = null; |
|
|
if ($row = mysql_fetch_row( $cur )) { |
|
|
$ret = $row[0]; |
|
|
} |
|
|
mysql_free_result( $cur ); |
|
|
return $ret; |
|
| 248 |
} |
} |
| 249 |
|
|
| 250 |
/** |
/** |
| 251 |
* Load an array of single field results into an array |
* Load an array of single field results into an array |
| 252 |
*/ |
*/ |
| 253 |
function loadResultArray($numinarray = 0) { |
function loadResultArray($numinarray = 0) { |
| 254 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults('', 0, 'row'); |
| 255 |
return null; |
$values = array(); |
| 256 |
} |
foreach ($results as $result) $values[] = $result[$numinarray]; |
| 257 |
$array = array(); |
if (count($values)) return $values; |
| 258 |
while ($row = mysql_fetch_row( $cur )) { |
else return null; |
|
$array[] = $row[$numinarray]; |
|
|
} |
|
|
mysql_free_result( $cur ); |
|
|
return $array; |
|
| 259 |
} |
} |
| 260 |
/** |
/** |
| 261 |
* Load a assoc list of database rows |
* Load a assoc list of database rows |
| 263 |
* @return array If <var>key</var> is empty as sequential list of returned records. |
* @return array If <var>key</var> is empty as sequential list of returned records. |
| 264 |
*/ |
*/ |
| 265 |
function loadAssocList( $key='' ) { |
function loadAssocList( $key='' ) { |
| 266 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults($key, 0, 'assoc'); |
| 267 |
return null; |
if (count($results)) return $results[0][0]; |
| 268 |
|
else return null; |
| 269 |
|
} |
| 270 |
|
/** |
| 271 |
|
* Copy the named array content into the object as properties |
| 272 |
|
* only existing properties of object are filled. when undefined in hash, properties wont be deleted |
| 273 |
|
* @param array the input array |
| 274 |
|
* @param obj byref the object to fill of any class |
| 275 |
|
* @param string |
| 276 |
|
* @param boolean |
| 277 |
|
*/ |
| 278 |
|
function mosBindArrayToObject( $array, &$obj, $ignore='', $prefix=NULL, $checkSlashes=true ) { |
| 279 |
|
if (!is_array($array) OR !is_object($obj)) return false; |
| 280 |
|
if ($prefix == null) $prefix = ''; |
| 281 |
|
foreach (get_object_vars($obj) as $k => $v) { |
| 282 |
|
if( substr( $k, 0, 1 ) != '_' AND strpos($ignore, $k) === false) { |
| 283 |
|
if (isset($array[$prefix.$k])) { |
| 284 |
|
$obj->$k = ($checkSlashes AND get_magic_quotes_gpc()) ? $this->mosStripslashes( $array[$prefix.$k] ) : $array[$prefix.$k]; |
| 285 |
} |
} |
|
$array = array(); |
|
|
while ($row = mysql_fetch_assoc( $cur )) { |
|
|
if ($key) { |
|
|
$array[$row->$key] = $row; |
|
|
} else { |
|
|
$array[] = $row; |
|
| 286 |
} |
} |
| 287 |
} |
} |
| 288 |
mysql_free_result( $cur ); |
return true; |
|
return $array; |
|
| 289 |
} |
} |
| 290 |
|
|
| 291 |
|
/** |
| 292 |
|
* Strip slashes from strings or arrays of strings |
| 293 |
|
* @param value the input string or array |
| 294 |
|
*/ |
| 295 |
|
function mosStripslashes(&$value) { |
| 296 |
|
if (is_string($value)) $ret = stripslashes($value); |
| 297 |
|
else { |
| 298 |
|
if (is_array($value)) { |
| 299 |
|
$ret = array(); |
| 300 |
|
while (list($key,$val) = each($value)) { |
| 301 |
|
$ret[$key] = $this->mosStripslashes($val); |
| 302 |
|
} // while |
| 303 |
|
} else $ret = $value; |
| 304 |
|
} // if |
| 305 |
|
return $ret; |
| 306 |
|
} // mosStripSlashes |
| 307 |
|
|
| 308 |
/** |
/** |
| 309 |
* This global function loads the first row of a query into an object |
* This global function loads the first row of a query into an object |
| 310 |
* |
* |
| 315 |
*/ |
*/ |
| 316 |
function loadObject( &$object ) { |
function loadObject( &$object ) { |
| 317 |
if ($object != null) { |
if ($object != null) { |
| 318 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults('', 1, 'assoc'); |
| 319 |
return false; |
if (count($results)) { |
| 320 |
} |
$this->mosBindArrayToObject($results[0], $object, null, null, false); |
|
if ($array = mysql_fetch_assoc( $cur )) { |
|
|
mysql_free_result( $cur ); |
|
|
mosBindArrayToObject( $array, $object, null, null, false ); |
|
| 321 |
return true; |
return true; |
|
} else { |
|
|
return false; |
|
| 322 |
} |
} |
|
} else { |
|
|
if ($cur = $this->query()) { |
|
|
if ($object = mysql_fetch_object( $cur )) { |
|
|
mysql_free_result( $cur ); |
|
|
return true; |
|
|
} else { |
|
|
$object = null; |
|
|
return false; |
|
| 323 |
} |
} |
| 324 |
} else { |
else { |
| 325 |
return false; |
$results =& $this->retrieveResults('', 1, 'object'); |
| 326 |
|
if (count($results)) { |
| 327 |
|
$object = $results[0]; |
| 328 |
|
return true; |
| 329 |
} |
} |
| 330 |
|
else $object = null; |
| 331 |
} |
} |
| 332 |
|
return false; |
| 333 |
} |
} |
| 334 |
/** |
/** |
| 335 |
* Load a list of database objects |
* Load a list of database objects |
| 339 |
* the database key. Returns <var>null</var> if the query fails. |
* the database key. Returns <var>null</var> if the query fails. |
| 340 |
*/ |
*/ |
| 341 |
function loadObjectList( $key='' ) { |
function loadObjectList( $key='' ) { |
| 342 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults($key, 0, 'object'); |
| 343 |
return null; |
if (count($results)) return $results; |
| 344 |
} |
else return null; |
|
$array = array(); |
|
|
while ($row = mysql_fetch_object( $cur )) { |
|
|
if ($key) { |
|
|
$array[$row->$key] = $row; |
|
|
} else { |
|
|
$array[] = $row; |
|
|
} |
|
|
} |
|
|
mysql_free_result( $cur ); |
|
|
return $array; |
|
| 345 |
} |
} |
| 346 |
/** |
/** |
| 347 |
* @return The first row of the query. |
* @return The first row of the query. |
| 348 |
*/ |
*/ |
| 349 |
function loadRow() { |
function loadRow() { |
| 350 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults('', 1, 'row'); |
| 351 |
return null; |
if (count($results)) return $results[0]; |
| 352 |
} |
else return null; |
|
$ret = null; |
|
|
if ($row = mysql_fetch_row( $cur )) { |
|
|
$ret = $row; |
|
|
} |
|
|
mysql_free_result( $cur ); |
|
|
return $ret; |
|
| 353 |
} |
} |
| 354 |
/** |
/** |
| 355 |
* Load a list of database rows (numeric column indexing) |
* Load a list of database rows (numeric column indexing) |
| 359 |
* the database key. Returns <var>null</var> if the query fails. |
* the database key. Returns <var>null</var> if the query fails. |
| 360 |
*/ |
*/ |
| 361 |
function loadRowList( $key='' ) { |
function loadRowList( $key='' ) { |
| 362 |
if (!($cur = $this->query())) { |
$results =& $this->retrieveResults('', 0, 'row'); |
| 363 |
return null; |
if (count($results)) return $results; |
| 364 |
} |
else return null; |
|
$array = array(); |
|
|
while ($row = mysql_fetch_array( $cur )) { |
|
|
if ($key) { |
|
|
$array[$row[$key]] = $row; |
|
|
} else { |
|
|
$array[] = $row; |
|
|
} |
|
|
} |
|
|
mysql_free_result( $cur ); |
|
|
return $array; |
|
| 365 |
} |
} |
| 366 |
|
|
| 367 |
/** |
/** |
| 368 |
* Document::db_insertObject() |
* Document::db_insertObject() |
| 369 |
* |
* |
| 376 |
$fmtsql = "INSERT INTO $table ( %s ) VALUES ( %s ) "; |
$fmtsql = "INSERT INTO $table ( %s ) VALUES ( %s ) "; |
| 377 |
$fields = array(); |
$fields = array(); |
| 378 |
foreach (get_object_vars( $object ) as $k => $v) { |
foreach (get_object_vars( $object ) as $k => $v) { |
| 379 |
if (is_array($v) or is_object($v) or $v === NULL) { |
if (is_array($v) OR is_object($v) OR $v === NULL OR $k[0] == '_') continue; |
|
continue; |
|
|
} |
|
|
if ($k[0] == '_') { // internal field |
|
|
continue; |
|
|
} |
|
| 380 |
$fields[] = "`$k`"; |
$fields[] = "`$k`"; |
| 381 |
$values[] = "'" . $this->getEscaped( $v ) . "'"; |
$values[] = "'" . $this->getEscaped( $v ) . "'"; |
| 382 |
} |
} |
| 383 |
|
if (!isset($fields)) die ('class database method insertObject - no fields'); |
| 384 |
$this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) , implode( ",", $values ) ) ); |
$this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) , implode( ",", $values ) ) ); |
| 385 |
($verbose) && print "$sql<br />\n"; |
($verbose) && print "$sql<br />\n"; |
| 386 |
if (!$this->query()) { |
if (!$this->query()) return false; |
|
return false; |
|
|
} |
|
| 387 |
$id = mysql_insert_id(); |
$id = mysql_insert_id(); |
| 388 |
($verbose) && print "id=[$id]<br />\n"; |
($verbose) && print "id=[$id]<br />\n"; |
| 389 |
if ($keyName && $id) { |
if ($keyName && $id) $object->$keyName = $id; |
|
$object->$keyName = $id; |
|
|
} |
|
| 390 |
return true; |
return true; |
| 391 |
} |
} |
| 392 |
|
|
| 401 |
$fmtsql = "UPDATE $table SET %s WHERE %s"; |
$fmtsql = "UPDATE $table SET %s WHERE %s"; |
| 402 |
$tmp = array(); |
$tmp = array(); |
| 403 |
foreach (get_object_vars( $object ) as $k => $v) { |
foreach (get_object_vars( $object ) as $k => $v) { |
| 404 |
if( is_array($v) or is_object($v) or $k[0] == '_' ) { // internal or NA field |
if (is_array($v) OR is_object($v) OR $k[0] == '_' OR ($v === null AND !$updateNulls)) continue; |
|
continue; |
|
|
} |
|
| 405 |
if( $k == $keyName ) { // PK not to be updated |
if( $k == $keyName ) { // PK not to be updated |
| 406 |
$where = "$keyName='" . $this->getEscaped( $v ) . "'"; |
$where = "$keyName='" . $this->getEscaped( $v ) . "'"; |
| 407 |
continue; |
continue; |
| 408 |
} |
} |
| 409 |
if ($v === NULL && !$updateNulls) { |
if ($v) $v = $this->getEscaped($v); |
| 410 |
continue; |
$tmp[] = "`$k`='$v'"; |
|
} |
|
|
if( $v == '' ) { |
|
|
$val = "''"; |
|
|
} else { |
|
|
$val = "'" . $this->getEscaped( $v ) . "'"; |
|
|
} |
|
|
$tmp[] = "`$k`=$val"; |
|
| 411 |
} |
} |
| 412 |
|
if (!isset($tmp)) return true; |
| 413 |
|
if (!isset($where)) die ('database class updateObject method - no key value'); |
| 414 |
$this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) ); |
$this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) ); |
| 415 |
return $this->query(); |
return $this->query(); |
| 416 |
} |
} |
| 420 |
* @return string A standised error message |
* @return string A standised error message |
| 421 |
*/ |
*/ |
| 422 |
function stderr( $showSQL = false ) { |
function stderr( $showSQL = false ) { |
| 423 |
$errormsg = sprintf(T_('DB function failed with error number %d'),$this->_errorNum); |
return "DB function failed with error number $this->_errorNum" |
| 424 |
$errormsg .= '<br /><span style="color:red">'.$this->_errorMsg.'</span>'; |
."<br /><font color=\"red\">$this->_errorMsg</font>" |
| 425 |
$errormsg .= $showSQL ? "<br />SQL = <pre>$this->_sql</pre>" : ''; |
.($showSQL ? "<br />SQL = <pre>$this->_sql</pre>" : ''); |
|
return $errormsg; |
|
| 426 |
} |
} |
| 427 |
|
|
| 428 |
function insertid() |
function insertid() |
| 482 |
|
|
| 483 |
return $result; |
return $result; |
| 484 |
} |
} |
| 485 |
|
|
| 486 |
|
function displayLogged () { |
| 487 |
|
echo count($this->_log).' queries executed'; |
| 488 |
|
echo '<pre>'; |
| 489 |
|
foreach ($this->_log as $k=>$sql) { |
| 490 |
|
echo $k+1 . "\n" . $sql . '<hr />'; |
| 491 |
|
} |
| 492 |
|
} |
| 493 |
|
|
| 494 |
|
/* Helper method - maybe should go into database itself */ |
| 495 |
|
function doSQL ($sql) { |
| 496 |
|
$this->setQuery($sql); |
| 497 |
|
if (!$this->query()) { |
| 498 |
|
echo "<script> alert('".$this->getErrorMsg()."'); window.history.go(-1); </script>\n"; |
| 499 |
|
exit(); |
| 500 |
|
} |
| 501 |
|
} |
| 502 |
|
|
| 503 |
|
/* Helper method - maybe could go into database itself */ |
| 504 |
|
function &doSQLget ($sql, $classname) { |
| 505 |
|
$this->setQuery($sql); |
| 506 |
|
$rows = $this->loadObjectList(); |
| 507 |
|
$target = get_class_vars($classname); |
| 508 |
|
if ($rows) { |
| 509 |
|
foreach ($rows as $row) { |
| 510 |
|
$next =& new $classname(0); |
| 511 |
|
foreach ($target as $field=>$value) { |
| 512 |
|
if (isset($row->$field)) $next->$field = $row->$field; |
| 513 |
|
} |
| 514 |
|
$result[] = $next; |
| 515 |
|
} |
| 516 |
|
} |
| 517 |
|
else $result = array(); |
| 518 |
|
return $result; |
| 519 |
|
} |
| 520 |
|
|
| 521 |
|
|
| 522 |
} |
} |
| 523 |
|
|
| 524 |
|
class mamboDatabase extends database { |
| 525 |
|
|
| 526 |
|
function mamboDatabase () { |
| 527 |
|
$host = mamboCore::get('mosConfig_host'); |
| 528 |
|
$user = mamboCore::get('mosConfig_user'); |
| 529 |
|
$pw = mamboCore::get('mosConfig_password'); |
| 530 |
|
$db = mamboCore::get('mosConfig_db'); |
| 531 |
|
$prefix = mamboCore::get('mosConfig_dbprefix'); |
| 532 |
|
parent::database($host, $user, $pw, $db, $prefix); |
| 533 |
|
} |
| 534 |
|
|
| 535 |
|
function &getInstance () { |
| 536 |
|
static $instance; |
| 537 |
|
if (!is_object($instance)) $instance = new mamboDatabase(); |
| 538 |
|
return $instance; |
| 539 |
|
} |
| 540 |
|
} |
| 541 |
|
|
| 542 |
|
|
| 543 |
/** |
/** |
| 544 |
* mosDBTable Abstract Class. |
* mosDBTable Abstract Class. |
| 545 |
* @abstract |
* @abstract |
| 573 |
$this->_tbl_key = $key; |
$this->_tbl_key = $key; |
| 574 |
$this->_db =& $db; |
$this->_db =& $db; |
| 575 |
} |
} |
| 576 |
|
|
| 577 |
|
/** |
| 578 |
|
* @return bool True if DB query failed. Sets the error message |
| 579 |
|
*/ |
| 580 |
|
function queryTestFailure () { |
| 581 |
|
if ($this->_db->query()) return false; |
| 582 |
|
$this->_error = $this->_db->getErrorMsg(); |
| 583 |
|
return true; |
| 584 |
|
} |
| 585 |
/** |
/** |
| 586 |
* Filters public properties |
* Filters public properties |
| 587 |
* @access protected |
* @access protected |
| 588 |
* @param array List of fields to ignore |
* @param array List of fields to ignore |
| 589 |
*/ |
*/ |
| 590 |
function filter( $ignoreList=null ) { |
function filter( $ignoreList=null ) { |
| 591 |
$ignore = is_array( $ignoreList ); |
$callcheck = array('InputFilter', 'process'); |
| 592 |
|
if (!is_callable($callcheck)) require_once(mamboCore::get('mosConfig_absolute_path').'/includes/phpinputfilter/class.inputfilter.php'); |
| 593 |
$iFilter = new InputFilter(); |
// specific filters |
| 594 |
foreach ($this->getPublicProperties() as $k) { |
$iFilter =& new InputFilter(); |
| 595 |
if ($ignore && in_array( $k, $ignoreList ) ) { |
if (is_array($ignoreList)) foreach ($this->getPublicProperties() as $k) { |
| 596 |
continue; |
if (!in_array($k, $ignoreList)) $this->$k = $iFilter->process($this->$k); |
|
} |
|
|
$this->$k = $iFilter->process( $this->$k ); |
|
| 597 |
} |
} |
| 598 |
|
else foreach ($this->getPublicProperties() as $k) $this->$k = $iFilter->process($this->$k); |
| 599 |
} |
} |
| 600 |
/** |
/** |
| 601 |
* @return string Returns the error message |
* @return string Returns the error message |
| 609 |
* @return mixed The value of the class var (or null if no var of that name exists) |
* @return mixed The value of the class var (or null if no var of that name exists) |
| 610 |
*/ |
*/ |
| 611 |
function get( $_property ) { |
function get( $_property ) { |
| 612 |
if(isset( $this->$_property )) { |
if(isset( $this->$_property )) return $this->$_property; |
| 613 |
return $this->$_property; |
else return null; |
|
} else { |
|
|
return null; |
|
|
} |
|
| 614 |
} |
} |
| 615 |
/** |
/** |
| 616 |
* Returns an array of public properties |
* Returns an array of public properties |
| 629 |
return $cache; |
return $cache; |
| 630 |
} |
} |
| 631 |
/** |
/** |
| 632 |
|
* Checks if this object lacks the property given by the parameter |
| 633 |
|
* @param string The name of the property |
| 634 |
|
* @return bool |
| 635 |
|
*/ |
| 636 |
|
function lacks( $property ) { |
| 637 |
|
$thisclass = strtolower(get_class($this)); |
| 638 |
|
if (!array_key_exists( $property, get_class_vars($thisclass) )) { |
| 639 |
|
$this->_error = "WARNING: $thisclass does not support $property."; |
| 640 |
|
return true; |
| 641 |
|
} |
| 642 |
|
return false; |
| 643 |
|
} |
| 644 |
|
/** |
| 645 |
* Set the value of the class variable |
* Set the value of the class variable |
| 646 |
* @param string The name of the class variable |
* @param string The name of the class variable |
| 647 |
* @param mixed The value to assign to the variable |
* @param mixed The value to assign to the variable |
| 657 |
* @return null|string null is operation was satisfactory, otherwise returns an error |
* @return null|string null is operation was satisfactory, otherwise returns an error |
| 658 |
*/ |
*/ |
| 659 |
function bind( $array, $ignore="" ) { |
function bind( $array, $ignore="" ) { |
| 660 |
if (!is_array( $array )) { |
$database = mamboDatabase::getInstance(); |
| 661 |
$this->_error = sprintf(T_('%s failed.'), strtolower(get_class( $this ))."::bind()"); |
if (is_array($array)) return $database->mosBindArrayToObject($array, $this, $ignore); |
| 662 |
|
$this->_error = strtolower(get_class( $this ))."::bind failed."; |
| 663 |
return false; |
return false; |
|
} else { |
|
|
return mosBindArrayToObject( $array, $this, $ignore ); |
|
|
} |
|
| 664 |
} |
} |
| 665 |
|
|
| 666 |
/** |
/** |
| 670 |
*/ |
*/ |
| 671 |
function load( $oid=null ) { |
function load( $oid=null ) { |
| 672 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 673 |
if ($oid !== null) { |
if ($oid !== null) $this->$k = $oid; |
| 674 |
$this->$k = $oid; |
if ($this->$k === null) return false; |
| 675 |
} |
$this->_db->setQuery("SELECT * FROM $this->_tbl WHERE $this->_tbl_key='".$this->$k."'" ); |
|
$oid = $this->$k; |
|
|
if ($oid === null) { |
|
|
return false; |
|
|
} |
|
|
$this->_db->setQuery( "SELECT * FROM $this->_tbl WHERE $this->_tbl_key='$oid'" ); |
|
| 676 |
return $this->_db->loadObject( $this ); |
return $this->_db->loadObject( $this ); |
| 677 |
} |
} |
| 678 |
|
|
| 696 |
function store( $updateNulls=false ) { |
function store( $updateNulls=false ) { |
| 697 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 698 |
global $migrate; |
global $migrate; |
| 699 |
if( $this->$k && !$migrate) { |
if( $this->$k && !$migrate) $ret = $this->_db->updateObject( $this->_tbl, $this, $this->_tbl_key, $updateNulls ); |
| 700 |
$ret = $this->_db->updateObject( $this->_tbl, $this, $this->_tbl_key, $updateNulls ); |
else $ret = $this->_db->insertObject( $this->_tbl, $this, $this->_tbl_key ); |
|
} else { |
|
|
$ret = $this->_db->insertObject( $this->_tbl, $this, $this->_tbl_key ); |
|
|
} |
|
| 701 |
if( !$ret ) { |
if( !$ret ) { |
| 702 |
$this->_error = sprintf(T_('%s failed.'), strtolower(get_class( $this )).'::store()') .'<br />'.$this->_db->getErrorMsg(); |
$this->_error = strtolower(get_class( $this ))."::store failed <br />" . $this->_db->getErrorMsg(); |
| 703 |
return false; |
return false; |
| 704 |
} else { |
} else return true; |
| 705 |
return true; |
} |
| 706 |
|
|
| 707 |
|
/** |
| 708 |
|
* Determine from the direction parameter which operator and order to use in SQL |
| 709 |
|
*/ |
| 710 |
|
function orderCodes ($direction) { |
| 711 |
|
if ($direction < 0) { |
| 712 |
|
$relation = '<'; |
| 713 |
|
$ordering = ' ORDER BY ordering DESC'; |
| 714 |
|
} |
| 715 |
|
elseif ($direction > 0) { |
| 716 |
|
$relation = '>'; |
| 717 |
|
$ordering = ' ORDER BY ordering ASC'; |
| 718 |
|
} |
| 719 |
|
else { |
| 720 |
|
$relation = '='; |
| 721 |
|
$ordering = ''; |
| 722 |
} |
} |
| 723 |
|
return array ($relation, $ordering); |
| 724 |
} |
} |
| 725 |
/** |
/** |
| 726 |
*/ |
*/ |
| 727 |
function move( $dirn, $where='' ) { |
function move( $direction, $where='' ) { |
| 728 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 729 |
|
list ($relation, $ordering) = $this->orderCodes($direction); |
| 730 |
$sql = "SELECT $this->_tbl_key, ordering FROM $this->_tbl"; |
$sql = "SELECT $this->_tbl_key, ordering FROM $this->_tbl WHERE ordering $relation $this->ordering"; |
| 731 |
|
$sql .= ($where ? "\n AND $where" : '').$ordering.' LIMIT 1'; |
|
if ($dirn < 0) { |
|
|
$sql .= "\nWHERE ordering < $this->ordering"; |
|
|
$sql .= ($where ? "\n AND $where" : ''); |
|
|
$sql .= "\nORDER BY ordering DESC\nLIMIT 1"; |
|
|
} else if ($dirn > 0) { |
|
|
$sql .= "\nWHERE ordering > $this->ordering"; |
|
|
$sql .= ($where ? "\n AND $where" : ''); |
|
|
$sql .= "\nORDER BY ordering\nLIMIT 1"; |
|
|
} else { |
|
|
$sql .= "\nWHERE ordering = $this->ordering"; |
|
|
$sql .= ($where ? "\n AND $where" : ''); |
|
|
$sql .= "\nORDER BY ordering\nLIMIT 1"; |
|
|
} |
|
|
|
|
| 732 |
$this->_db->setQuery( $sql ); |
$this->_db->setQuery( $sql ); |
|
//echo 'A: ' . $this->_db->getQuery(); |
|
|
|
|
|
|
|
| 733 |
$row = null; |
$row = null; |
| 734 |
if ($this->_db->loadObject( $row )) { |
if ($this->_db->loadObject( $row )) { |
| 735 |
$this->_db->setQuery( "UPDATE $this->_tbl SET ordering='$row->ordering'" |
$sql = "UPDATE $this->_tbl SET ordering='$row->ordering' WHERE $this->_tbl_key='".$this->$k."'"; |
| 736 |
. "\nWHERE $this->_tbl_key='".$this->$k."'" |
$this->_db->doSQL($sql); |
|
); |
|
|
|
|
|
if (!$this->_db->query()) { |
|
|
$err = $this->_db->getErrorMsg(); |
|
|
die( $err ); |
|
|
} |
|
|
//echo 'B: ' . $this->_db->getQuery(); |
|
|
|
|
|
$this->_db->setQuery( "UPDATE $this->_tbl SET ordering='$this->ordering'" |
|
|
. "\nWHERE $this->_tbl_key='".$row->$k."'" |
|
|
); |
|
|
//echo 'C: ' . $this->_db->getQuery(); |
|
|
|
|
|
if (!$this->_db->query()) { |
|
|
$err = $this->_db->getErrorMsg(); |
|
|
die( $err ); |
|
|
} |
|
|
|
|
|
$this->ordering = $row->ordering; |
|
|
} else { |
|
|
$this->_db->setQuery( "UPDATE $this->_tbl SET ordering='$this->ordering'" |
|
|
. "\nWHERE $this->_tbl_key='".$this->$k."'" |
|
|
); |
|
|
//echo 'D: ' . $this->_db->getQuery(); |
|
|
|
|
|
|
|
|
if (!$this->_db->query()) { |
|
|
$err = $this->_db->getErrorMsg(); |
|
|
die( $err ); |
|
|
} |
|
| 737 |
} |
} |
| 738 |
|
$sql = "UPDATE $this->_tbl SET ordering='$this->ordering' WHERE $this->_tbl_key='".$row->$k."'"; |
| 739 |
|
if ($row) $this->ordering = $row->ordering; |
| 740 |
|
$this->_db->doSQL($sql); |
| 741 |
} |
} |
| 742 |
/** |
/** |
| 743 |
* Compacts the ordering sequence of the selected records |
* Compacts the ordering sequence of the selected records |
| 744 |
* @param string Additional where query to limit ordering to a particular subset of records |
* @param string Additional where query to limit ordering to a particular subset of records |
| 745 |
*/ |
*/ |
| 746 |
function updateOrder( $where='' ) { |
function updateOrder( $where='' ) { |
| 747 |
|
if ($this->lacks('ordering')) return false; |
| 748 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 749 |
|
if ($this->_tbl == "#__content_frontpage") $order2 = ", content_id DESC"; |
| 750 |
|
else $order2 = ""; |
| 751 |
|
|
| 752 |
if (!array_key_exists( 'ordering', get_class_vars( strtolower(get_class( $this )) ) )) { |
$sql = "SELECT $k, ordering FROM $this->_tbl " |
|
$this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support ordering."; |
|
|
return false; |
|
|
} |
|
|
|
|
|
if ($this->_tbl == "#__content_frontpage") { |
|
|
$order2 = ", content_id DESC"; |
|
|
} else { |
|
|
$order2 = ""; |
|
|
} |
|
|
|
|
|
$this->_db->setQuery( "SELECT $this->_tbl_key, ordering FROM $this->_tbl" |
|
| 753 |
. ($where ? "\nWHERE $where" : '') |
. ($where ? "\nWHERE $where" : '') |
| 754 |
. "\nORDER BY ordering".$order2 |
. "\nORDER BY ordering$order2"; |
| 755 |
); |
$this->_db->setQuery($sql); |
| 756 |
if (!($orders = $this->_db->loadObjectList())) { |
if (!$rows = $this->_db->loadObjectList()) { |
|
$this->_error = $this->_db->getErrorMsg(); |
|
|
return false; |
|
|
} |
|
|
// first pass, compact the ordering numbers |
|
|
for ($i=0, $n=count( $orders ); $i < $n; $i++) { |
|
|
if ($orders[$i]->ordering >= 0) { |
|
|
$orders[$i]->ordering = $i+1; |
|
|
} |
|
|
} |
|
|
|
|
|
$shift = 0; |
|
|
$n=count( $orders ); |
|
|
for ($i=0; $i < $n; $i++) { |
|
|
//echo "i=$i id=".$orders[$i]->$k." order=".$orders[$i]->ordering; |
|
|
if ($orders[$i]->$k == $this->$k) { |
|
|
// place 'this' record in the desired location |
|
|
$orders[$i]->ordering = min( $this->ordering, $n ); |
|
|
$shift = 1; |
|
|
} else if ($orders[$i]->ordering >= $this->ordering && $this->ordering > 0) { |
|
|
$orders[$i]->ordering++; |
|
|
} |
|
|
} |
|
|
//echo '<pre>';print_r($orders);echo '</pre>'; |
|
|
// compact once more until I can find a better algorithm |
|
|
for ($i=0, $n=count( $orders ); $i < $n; $i++) { |
|
|
if ($orders[$i]->ordering >= 0) { |
|
|
$orders[$i]->ordering = $i+1; |
|
|
$this->_db->setQuery( "UPDATE $this->_tbl" |
|
|
. "\nSET ordering='".$orders[$i]->ordering."' WHERE $k='".$orders[$i]->$k."'" |
|
|
); |
|
|
$this->_db->query(); |
|
|
//echo '<br />'.$this->_db->getQuery(); |
|
|
} |
|
|
} |
|
|
|
|
|
// if we didn't reorder the current record, make it last |
|
|
if ($shift == 0) { |
|
|
$order = $n+1; |
|
|
$this->_db->setQuery( "UPDATE $this->_tbl" |
|
|
. "\nSET ordering='$order' WHERE $k='".$this->$k."'" |
|
|
); |
|
|
$this->_db->query(); |
|
|
//echo '<br />'.$this->_db->getQuery(); |
|
|
} |
|
|
return true; |
|
|
} |
|
|
/** |
|
|
* Generic check for whether dependancies exist for this object in the db schema |
|
|
* |
|
|
* can be overloaded/supplemented by the child class |
|
|
* @param string $msg Error message returned |
|
|
* @param int Optional key index |
|
|
* @param array Optional array to compiles standard joins: format [label=>'Label',name=>'table name',idfield=>'field',joinfield=>'field'] |
|
|
* @return true|false |
|
|
*/ |
|
|
function canDelete( $oid=null, $joins=null ) { |
|
|
$k = $this->_tbl_key; |
|
|
if ($oid) { |
|
|
$this->$k = intval( $oid ); |
|
|
} |
|
|
if (is_array( $joins )) { |
|
|
$select = "$k"; |
|
|
$join = ""; |
|
|
foreach( $joins as $table ) { |
|
|
$select .= ",\nCOUNT(DISTINCT {$table['idfield']}) AS {$table['idfield']}"; |
|
|
$join .= "\nLEFT JOIN {$table['name']} ON {$table['joinfield']} = $k"; |
|
|
} |
|
|
$this->_db->setQuery( "SELECT $select\nFROM $this->_tbl\n$join\nWHERE $k = ".$this->$k." GROUP BY $k" ); |
|
|
|
|
|
if ($obj = $this->_db->loadObject()) { |
|
| 757 |
$this->_error = $this->_db->getErrorMsg(); |
$this->_error = $this->_db->getErrorMsg(); |
| 758 |
return false; |
return false; |
| 759 |
} |
} |
| 760 |
$msg = array(); |
$neworder = max(min($this->ordering, count($rows)), 1); |
| 761 |
foreach( $joins as $table ) { |
$i = 1; |
| 762 |
$k = $table['idfield']; |
foreach ($rows as $row) { |
| 763 |
if ($obj->$k) { |
$key = $row->$k; |
| 764 |
$msg[] = $AppUI->_( $table['label'] ); |
if ($i == $neworder) $i++; |
| 765 |
} |
if ($key == $this->$k) { |
| 766 |
} |
$i--; |
| 767 |
|
$ordering = $neworder; |
| 768 |
if (count( $msg )) { |
} |
| 769 |
$this->_error = "noDeleteRecord" . ": " . implode( ', ', $msg ); |
else $ordering = $i; |
| 770 |
return false; |
$sql = "UPDATE $this->_tbl SET ordering=$ordering WHERE $k = $key "; |
| 771 |
} else { |
$this->_db->doSQL($sql); |
| 772 |
return true; |
$i++; |
|
} |
|
| 773 |
} |
} |
|
|
|
| 774 |
return true; |
return true; |
| 775 |
} |
} |
| 776 |
|
|
| 781 |
* @return true if successful otherwise returns and error message |
* @return true if successful otherwise returns and error message |
| 782 |
*/ |
*/ |
| 783 |
function delete( $oid=null ) { |
function delete( $oid=null ) { |
|
//if (!$this->canDelete( $msg )) { |
|
|
// return $msg; |
|
|
//} |
|
|
|
|
| 784 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 785 |
if ($oid) { |
if ($oid) $this->$k = intval( $oid ); |
|
$this->$k = intval( $oid ); |
|
|
} |
|
|
|
|
| 786 |
$this->_db->setQuery( "DELETE FROM $this->_tbl WHERE $this->_tbl_key = '".$this->$k."'" ); |
$this->_db->setQuery( "DELETE FROM $this->_tbl WHERE $this->_tbl_key = '".$this->$k."'" ); |
| 787 |
|
if ($this->queryTestFailure()) return false; |
|
if ($this->_db->query()) { |
|
| 788 |
return true; |
return true; |
|
} else { |
|
|
$this->_error = $this->_db->getErrorMsg(); |
|
|
return false; |
|
|
} |
|
| 789 |
} |
} |
| 790 |
|
|
| 791 |
function checkout( $who, $oid=null ) { |
function checkout( $who, $oid=null ) { |
| 792 |
if (!array_key_exists( 'checked_out', get_class_vars( strtolower(get_class( $this )) ) )) { |
if ($this->lacks('checked_out')) return false; |
|
$this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support checkouts."; |
|
|
return false; |
|
|
} |
|
| 793 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 794 |
if ($oid !== null) { |
if ($oid !== null) $this->$k = $oid; |
|
$this->$k = $oid; |
|
|
} |
|
| 795 |
$time = date( "%Y-%m-%d H:i:s" ); |
$time = date( "%Y-%m-%d H:i:s" ); |
| 796 |
if (intval( $who )) { |
if (intval( $who )) { |
| 797 |
// new way of storing editor, by id |
// new way of storing editor, by id |
| 810 |
} |
} |
| 811 |
|
|
| 812 |
function checkin( $oid=null ) { |
function checkin( $oid=null ) { |
| 813 |
if (!array_key_exists( 'checked_out', get_class_vars( strtolower(get_class( $this )) ) )) { |
if ($this->lacks('checked_out')) return false; |
|
$this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support checkin."; |
|
|
return false; |
|
|
} |
|
| 814 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 815 |
if ($oid !== null) { |
if ($oid !== null) $this->$k = $oid; |
|
$this->$k = $oid; |
|
|
} |
|
| 816 |
$time = date("H:i:s"); |
$time = date("H:i:s"); |
| 817 |
$this->_db->setQuery( "UPDATE $this->_tbl" |
$this->_db->setQuery( "UPDATE $this->_tbl" |
| 818 |
. "\nSET checked_out='0', checked_out_time='0000-00-00 00:00:00'" |
. "\nSET checked_out='0', checked_out_time='0000-00-00 00:00:00'" |
| 822 |
} |
} |
| 823 |
|
|
| 824 |
function hit( $oid=null ) { |
function hit( $oid=null ) { |
|
global $mosConfig_enable_log_items; |
|
|
|
|
| 825 |
$k = $this->_tbl_key; |
$k = $this->_tbl_key; |
| 826 |
if ($oid !== null) { |
if ($oid !== null) $this->$k = intval( $oid ); |
| 827 |
$this->$k = intval( $oid ); |
$key = $this->$k; |
| 828 |
} |
$this->_db->setQuery( "UPDATE $this->_tbl SET hits=(hits+1) WHERE $this->_tbl_key='$key'" ); |
|
$this->_db->setQuery( "UPDATE $this->_tbl SET hits=(hits+1) WHERE $this->_tbl_key='$this->id'" ); |
|
| 829 |
$this->_db->query(); |
$this->_db->query(); |
| 830 |
|
|
| 831 |
if (@$mosConfig_enable_log_items) { |
if (mamboCore::get('mosConfig_enable_log_items')) { |
| 832 |
$now = date( "Y-m-d" ); |
$now = date( "Y-m-d" ); |
| 833 |
$this->_db->setQuery( "SELECT hits" |
$this->_db->setQuery( "SELECT hits" |
| 834 |
. "\nFROM #__core_log_items" |
. "\nFROM #__core_log_items" |
| 835 |
. "\nWHERE time_stamp='$now' AND item_table='$this->_tbl' AND item_id='".$this->$k."'" |
. "\nWHERE time_stamp='$now' AND item_table='$this->_tbl' AND item_id='$key'" |
| 836 |
); |
); |
| 837 |
$hits = intval( $this->_db->loadResult() ); |
$hits = intval( $this->_db->loadResult() ); |
| 838 |
if ($hits) { |
if ($hits) $this->_db->setQuery( "UPDATE #__core_log_items SET hits=(hits+1)" |
|
$this->_db->setQuery( "UPDATE #__core_log_items SET hits=(hits+1)" |
|
| 839 |
. "\nWHERE time_stamp='$now' AND item_table='$this->_tbl' AND item_id='".$this->$k."'" |
. "\nWHERE time_stamp='$now' AND item_table='$this->_tbl' AND item_id='".$this->$k."'" |
| 840 |
); |
); |
| 841 |
$this->_db->query(); |
else $this->_db->setQuery( "INSERT INTO #__core_log_items VALUES" |
|
} else { |
|
|
$this->_db->setQuery( "INSERT INTO #__core_log_items VALUES" |
|
| 842 |
. "\n('$now','$this->_tbl','".$this->$k."','1')" |
. "\n('$now','$this->_tbl','".$this->$k."','1')" |
| 843 |
); |
); |
| 844 |
$this->_db->query(); |
$this->_db->query(); |
| 845 |
} |
} |
| 846 |
} |
} |
|
} |
|
| 847 |
|
|
| 848 |
/** |
/** |
| 849 |
* Generic save function |
* Generic save function |
| 852 |
* @returns TRUE if completely successful, FALSE if partially or not succesful. |
* @returns TRUE if completely successful, FALSE if partially or not succesful. |
| 853 |
*/ |
*/ |
| 854 |
function save( $source, $order_filter ) { |
function save( $source, $order_filter ) { |
| 855 |
if (!$this->bind( $_POST )) { |
if (!$this->bind($_POST) OR !$this->check() OR !$this->store()OR !$this->checkin()) return false; |
|
return false; |
|
|
} |
|
|
if (!$this->check()) { |
|
|
return false; |
|
|
} |
|
|
if (!$this->store()) { |
|
|
return false; |
|
|
} |
|
|
if (!$this->checkin()) { |
|
|
return false; |
|
|
} |
|
| 856 |
$filter_value = $this->$order_filter; |
$filter_value = $this->$order_filter; |
| 857 |
$this->updateOrder( $order_filter ? "`$order_filter`='$filter_value'" : "" ); |
$this->updateOrder( $order_filter ? "`$order_filter`='$filter_value'" : "" ); |
| 858 |
$this->_error = ''; |
$this->_error = ''; |
| 866 |
* @param integer The id of the user performnig the operation |
* @param integer The id of the user performnig the operation |
| 867 |
*/ |
*/ |
| 868 |
function publish_array( $cid=null, $publish=1, $myid=0 ) { |
function publish_array( $cid=null, $publish=1, $myid=0 ) { |
| 869 |
if (!is_array( $cid ) || count( $cid ) < 1) { |
if (!is_array( $cid ) OR count( $cid ) < 1) { |
| 870 |
$this->_error = T_("No items selected."); |
$this->_error = "No items selected."; |
| 871 |
return false; |
return false; |
| 872 |
} |
} |
|
|
|
| 873 |
$cids = implode( ',', $cid ); |
$cids = implode( ',', $cid ); |
|
|
|
| 874 |
$this->_db->setQuery( "UPDATE $this->_tbl SET published='$publish'" |
$this->_db->setQuery( "UPDATE $this->_tbl SET published='$publish'" |
| 875 |
. "\nWHERE $this->_tbl_key IN ($cids) AND (checked_out=0 OR (checked_out='$myid'))" |
. "\nWHERE $this->_tbl_key IN ($cids) AND (checked_out=0 OR checked_out='$myid')" |
| 876 |
); |
); |
| 877 |
if (!$this->_db->query()) { |
if ($this->queryTestFailure()) return false; |
| 878 |
$this->_error = $this->_db->getErrorMsg(); |
if (count( $cid ) == 1) $this->checkin( $cid[0] ); |
|
return false; |
|
|
} |
|
|
|
|
|
if (count( $cid ) == 1) { |
|
|
$this->checkin( $cid[0] ); |
|
|
} |
|
|
$this->_error = ''; |
|
| 879 |
return true; |
return true; |
| 880 |
} |
} |
| 881 |
|
|
| 885 |
*/ |
*/ |
| 886 |
function toXML( $mapKeysToText=false ) { |
function toXML( $mapKeysToText=false ) { |
| 887 |
$xml = '<record table="' . $this->_tbl . '"'; |
$xml = '<record table="' . $this->_tbl . '"'; |
| 888 |
if ($mapKeysToText) { |
if ($mapKeysToText) $xml .= ' mapkeystotext="true"'; |
|
$xml .= ' mapkeystotext="true"'; |
|
|
} |
|
| 889 |
$xml .= '>'; |
$xml .= '>'; |
| 890 |
foreach (get_object_vars( $this ) as $k => $v) { |
foreach (get_object_vars( $this ) as $k => $v) { |
| 891 |
if (is_array($v) or is_object($v) or $v === NULL) { |
if ($v === null OR is_array($v) OR is_object($v)) continue; |
| 892 |
continue; |
if ($k[0] == '_') continue; // internal field |
|
} |
|
|
if ($k[0] == '_') { // internal field |
|
|
continue; |
|
|
} |
|
| 893 |
$xml .= '<' . $k . '><![CDATA[' . $v . ']]></' . $k . '>'; |
$xml .= '<' . $k . '><![CDATA[' . $v . ']]></' . $k . '>'; |
| 894 |
} |
} |
| 895 |
$xml .= '</record>'; |
$xml .= '</record>'; |
|
|
|
| 896 |
return $xml; |
return $xml; |
| 897 |
} |
} |
| 898 |
} |
} |
| 899 |
|
|
| 900 |
|
/** |
| 901 |
|
* Abstract class for classes where the objects of the class can be relatively easily |
| 902 |
|
* stored in a single database table. Can usually be adapted to more complex cases. |
| 903 |
|
* Requires child classes to implement: tableName(), notSQL(). |
| 904 |
|
* tableName() must return the name of the database table, using #__ in the usual Mambo way |
| 905 |
|
* notSQL() must return an array of strings, where each string is the name of a |
| 906 |
|
* variable that is NOT in the database table, or is not written explicitly, |
| 907 |
|
* e.g. the auto-increment key. If this is the ONLY non-SQL field, then the |
| 908 |
|
* child class need not implement it, as that it is already in the abstract class. |
| 909 |
|
* Child classes may implement timeStampField, in which case it must return the name |
| 910 |
|
* of a field that will have a timestamp placed in it whenever the DB is written. |
| 911 |
|
*/ |
| 912 |
|
|
| 913 |
|
class mosDBTableEntry { |
| 914 |
|
/** @var int ID for file record in database */ |
| 915 |
|
var $id = 0; |
| 916 |
|
var $database = ''; |
| 917 |
|
|
| 918 |
|
function mosDBTableEntry () { |
| 919 |
|
die ('Cannot instantiate mosDBTableEntry'); |
| 920 |
|
} |
| 921 |
|
|
| 922 |
|
function getDatabase () { |
| 923 |
|
if (!is_object($this->database)) $this->database = mamboDatabase::getInstance(); |
| 924 |
|
return $this->database; |
| 925 |
|
} |
| 926 |
|
|
| 927 |
|
/* Stores all POST data where the name matches an object variable name */ |
| 928 |
|
function addPostData () { |
| 929 |
|
foreach (get_class_vars(get_class($this)) as $field=>$value) { |
| 930 |
|
if ($field!='id' AND isset($_POST[$field])) { |
| 931 |
|
$this->$field = trim($_POST[$field]); |
| 932 |
|
} |
| 933 |
|
} |
| 934 |
|
$this->forceBools(); |
| 935 |
|
} |
| 936 |
|
|
| 937 |
|
/* Provided in case child class does not implement it. Can force any values */ |
| 938 |
|
/* within some limited range. In particular, can force bools to be 0 or 1 */ |
| 939 |
|
function forceBools () { |
| 940 |
|
return; |
| 941 |
|
} |
| 942 |
|
|
| 943 |
|
/* Updates an existing DB entry with the object's current values */ |
| 944 |
|
function updateObjectDB () { |
| 945 |
|
$this->prepareValues(); |
| 946 |
|
$database = $this->getDatabase(); |
| 947 |
|
$database->doSQL($this->updateSQL()); |
| 948 |
|
} |
| 949 |
|
|
| 950 |
|
/* Deletes the current object from the DB */ |
| 951 |
|
function delete () { |
| 952 |
|
$table = $this->tableName(); |
| 953 |
|
$sql = "DELETE FROM $table WHERE id=$this->id"; |
| 954 |
|
$database = $this->getDatabase(); |
| 955 |
|
$database->doSQL($sql); |
| 956 |
|
} |
| 957 |
|
|
| 958 |
|
/* Provided in case the child class does not provide a method for timeStampField */ |
| 959 |
|
function timeStampField () { |
| 960 |
|
return ''; |
| 961 |
|
} |
| 962 |
|
|
| 963 |
|
/* Provides SQL for updating the DB with the contents of the current object */ |
| 964 |
|
function updateSQL () { |
| 965 |
|
$tabname = $this->tableName(); |
| 966 |
|
$sql = "UPDATE $tabname SET %s WHERE id=$this->id"; |
| 967 |
|
$exclude = $this->notSQL(); |
| 968 |
|
foreach (get_class_vars(get_class($this)) as $field=>$value) { |
| 969 |
|
if (!in_array($field,$exclude)) $setter[] = $field."='".$this->$field."'"; |
| 970 |
|
} |
| 971 |
|
$timestamp = $this->timeStampField(); |
| 972 |
|
if ($timestamp) $setter[] = $timestamp."='".date('Y-m-d H:i:s')."'"; |
| 973 |
|
return sprintf($sql,implode(',', $setter)); |
| 974 |
|
} |
| 975 |
|
|
| 976 |
|
/* Default method for identifying fields not to be written to the DB */ |
| 977 |
|
/* The child classes may override this and return more items in the array */ |
| 978 |
|
function notSQL () { |
| 979 |
|
return array ('id'); |
| 980 |
|
} |
| 981 |
|
|
| 982 |
|
/* Provides SQL to insert the current object into the DB */ |
| 983 |
|
function insertSQL () { |
| 984 |
|
$tabname = $this->tableName(); |
| 985 |
|
$sql = "INSERT INTO $tabname (%s) VALUES (%s)"; |
| 986 |
|
$exclude = $this->notSQL(); |
| 987 |
|
foreach (get_class_vars(get_class($this)) as $field=>$value) { |
| 988 |
|
if (!in_array($field,$exclude)) { |
| 989 |
|
$infields[] = $field; |
| 990 |
|
$values[] = "'".$this->$field."'"; |
| 991 |
|
} |
| 992 |
|
} |
| 993 |
|
$timestamp = $this->timeStampField(); |
| 994 |
|
if ($timestamp) { |
| 995 |
|
$infields[] = $timestamp; |
| 996 |
|
$values[] = "'".date('Y-m-d H:i:s')."'"; |
| 997 |
|
} |
| 998 |
|
return sprintf($sql, implode(',', $infields), implode(',', $values)); |
| 999 |
|
} |
| 1000 |
|
|
| 1001 |
|
/* Copies any matching fields from some arbitrary object into the current object */ |
| 1002 |
|
function setValues (&$anObject) { |
| 1003 |
|
foreach (get_class_vars(get_class($this)) as $field=>$value) { |
| 1004 |
|
if ($field != 'id' AND isset($anObject->$field)) $this->$field = $anObject->$field; |
| 1005 |
|
} |
| 1006 |
|
} |
| 1007 |
|
|
| 1008 |
|
/* Ensures values can safely be written to DB; assumes magic quotes forced off */ |
| 1009 |
|
function prepareValues () { |
| 1010 |
|
$database = $this->getDatabase(); |
| 1011 |
|
foreach (get_class_vars(get_class($this)) as $field=>$value) { |
| 1012 |
|
if (!is_numeric($this->$field)) $this->$field = $database->getEscaped($this->$field); |
| 1013 |
|
} |
| 1014 |
|
} |
| 1015 |
|
|
| 1016 |
|
/* Takes some arbitrary SELECT type SQL and places the first or only result into the current object */ |
| 1017 |
|
function readDataBase($sql) { |
| 1018 |
|
$database = $this->getDatabase(); |
| 1019 |
|
$database->setQuery( $sql ); |
| 1020 |
|
if (!$database->loadObject($this)) $this->id = 0; |
| 1021 |
|
} |
| 1022 |
|
|
| 1023 |
|
} |
| 1024 |
|
|
| 1025 |
?> |
?> |