2019-02-08 13:29:02 -08:00
< ? php
/**
2020-01-19 14:33:11 +01:00
* e107 website system
*
* Copyright ( C ) 2008 - 2020 e107 Inc ( e107 . org )
* Released under the terms and conditions of the
* GNU General Public License ( http :// www . gnu . org / licenses / gpl . txt )
*
* PDO MySQL Handler
2019-02-08 13:29:02 -08:00
*/
2019-02-11 12:22:10 -08:00
// Legacy Fix.
2020-01-19 12:30:23 +01:00
defined ( 'MYSQL_ASSOC' ) or define ( 'MYSQL_ASSOC' , 1 );
defined ( 'MYSQL_NUM' ) or define ( 'MYSQL_NUM' , 2 );
defined ( 'MYSQL_BOTH' ) or define ( 'MYSQL_BOTH' , 3 );
2019-06-03 15:27:36 -07:00
require_once ( 'e_db_interface.php' );
require_once ( 'e_db_legacy_trait.php' );
2019-02-08 13:29:02 -08:00
/**
* PDO MySQL class . All legacy mysql_ methods removed .
* Class e_db_pdo
*/
class e_db_pdo implements e_db
{
use e_db_legacy ;
// TODO switch to protected vars where needed
public $mySQLserver ;
public $mySQLuser ;
protected $mySQLpassword ;
protected $mySQLdefaultdb ;
protected $mySQLport = 3306 ;
public $mySQLPrefix ;
/** @var PDO */
protected $mySQLaccess ;
public $mySQLresult ;
2019-02-09 13:07:34 -08:00
protected $mySQLrows ;
protected $mySQLerror = false ; // Error reporting mode - TRUE shows messages
2019-02-08 13:29:02 -08:00
protected $mySQLlastErrNum = 0 ; // Number of last error - now protected, use getLastErrorNumber()
protected $mySQLlastErrText = '' ; // Text of last error - now protected, use getLastErrorText()
protected $mySQLlastQuery = '' ;
2019-02-13 21:26:17 -08:00
protected $mySQLcurTable ;
2019-02-08 13:29:02 -08:00
public $mySQLlanguage ;
public $mySQLinfo ;
public $tabset ;
public $mySQLtableList = array (); // list of all Db tables.
public $mySQLtableListLanguage = array (); // Db table list for the currently selected language
public $mySQLtablelist = array ();
protected $dbFieldDefs = array (); // Local cache - Field type definitions for _FIELD_DEFS and _NOTNULL arrays
public $mySQLcharset ;
2019-02-11 14:54:09 -08:00
protected $mySqlServerInfo = '?' ; // Server info - needed for various things
2019-02-08 13:29:02 -08:00
public $total_results = false ; // Total number of results
2019-02-09 13:07:34 -08:00
private $pdo = true ; // using PDO or not.
private $pdoBind = false ;
2019-02-08 13:29:02 -08:00
2019-02-10 16:19:25 -08:00
/** @var e107_traffic */
2019-02-10 14:51:51 -08:00
private $traffic ;
2019-02-10 16:19:25 -08:00
/** @var e107_db_debug */
private $dbg ;
private $debugMode = false ;
private $queryCount = 0 ;
2019-02-08 13:29:02 -08:00
2019-02-13 13:54:05 -08:00
2019-02-08 13:29:02 -08:00
/**
* Constructor - gets language options from the cookie or session
* @ access public
*/
public function __construct ()
{
2019-02-10 14:51:51 -08:00
$this -> traffic = e107 :: getSingleton ( 'e107_traffic' );
$this -> traffic -> BumpWho ( 'Create db object' , 1 );
2019-02-13 13:54:05 -08:00
// Set the default prefix - may be overridden
$config = e107 :: getMySQLConfig ();
$this -> mySQLserver = $config [ 'mySQLserver' ];
$this -> mySQLuser = $config [ 'mySQLuser' ];
$this -> mySQLpassword = $config [ 'mySQLpassword' ];
$this -> mySQLdefaultdb = $config [ 'mySQLdefaultdb' ];
$this -> mySQLport = varset ( $config [ 'port' ], 3306 );
$this -> mySQLPrefix = varset ( $config [ 'mySQLprefix' ], 'e107_' );
/*
2019-02-08 13:29:02 -08:00
if ( $port = e107 :: getMySQLConfig ( 'port' ))
{
$this -> mySQLport = intval ( $port );
2019-02-13 13:54:05 -08:00
} */
2019-02-08 13:29:02 -08:00
// Detect is already done in language handler, use it if not too early
2019-02-10 16:19:25 -08:00
if ( defined ( 'e_LANGUAGE' ))
{
$this -> mySQLlanguage = e107 :: getLanguage () -> e_language ;
}
if ( E107_DEBUG_LEVEL > 0 )
{
$this -> debugMode = true ;
}
$this -> dbg = e107 :: getDebug ();
2019-02-08 13:29:02 -08:00
}
2022-04-04 10:54:24 -07:00
/**
* @ return bool
*/
2019-02-08 13:29:02 -08:00
function getPDO ()
{
return true ;
}
2022-04-04 10:54:24 -07:00
/**
* @ param $bool
* @ return void
*/
2019-02-10 16:19:25 -08:00
function debugMode ( $bool )
{
$this -> debugMode = ( bool ) $bool ;
}
2019-02-08 13:29:02 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ return mixed
*/
2019-02-08 13:29:02 -08:00
function getMode ()
{
$this -> gen ( 'SELECT @@sql_mode' );
$row = $this -> fetch ();
return $row [ '@@sql_mode' ];
}
/**
* Connect ONLY - used in v2 . x
* @ param string $mySQLserver IP Or hostname of the MySQL server
* @ param string $mySQLuser MySQL username
* @ param string $mySQLpassword MySQL Password
2020-08-04 09:28:48 -05:00
* @ param bool $newLink force a new link connection if TRUE . Default false
2019-02-08 13:29:02 -08:00
* @ return boolean true on success , false on error .
*/
public function connect ( $mySQLserver , $mySQLuser , $mySQLpassword , $newLink = false )
{
2019-02-10 14:51:51 -08:00
$this -> traffic -> BumpWho ( 'db Connect' , 1 );
2019-02-08 13:29:02 -08:00
$this -> mySQLserver = $mySQLserver ;
$this -> mySQLuser = $mySQLuser ;
$this -> mySQLpassword = $mySQLpassword ;
$this -> mySQLerror = false ;
if ( strpos ( $mySQLserver , ':' ) !== false && substr_count ( $mySQLserver , ':' ) === 1 )
{
list ( $this -> mySQLserver , $this -> mySQLport ) = explode ( ':' , $mySQLserver , 2 );
}
// if($this->mySQLserver === 'localhost') // problematic.
{
// $this->mySQLserver = '127.0.0.1'; // faster by almost 1 second.
}
try
{
2020-08-04 09:28:48 -05:00
$this -> mySQLaccess = new PDO ( " mysql:host= { $this -> mySQLserver } ;port= { $this -> mySQLport } " , $this -> mySQLuser , $this -> mySQLpassword , array ( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION ));
2019-02-08 13:29:02 -08:00
}
catch ( PDOException $ex )
{
$this -> mySQLlastErrText = $ex -> getMessage ();
$this -> mySQLLastErrNum = $ex -> getCode ();
2019-02-13 21:26:17 -08:00
$this -> dbg -> log ( $this -> mySQLlastErrText );
2019-02-08 13:29:02 -08:00
return false ;
}
2019-02-09 12:31:27 -08:00
$this -> setCharset ();
2019-02-08 13:29:02 -08:00
$this -> setSQLMode ();
return true ;
}
/**
* Get Server Info
* @ return mixed
*/
public function getServerInfo ()
{
2019-02-11 14:54:09 -08:00
// var_dump($this->mySQLaccess);
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-11 14:54:09 -08:00
$this -> mySqlServerInfo = $this -> mySQLaccess -> query ( 'select version()' ) -> fetchColumn ();
// $this->mySqlServerInfo = $this->mySQLaccess->getAttribute(PDO::ATTR_SERVER_VERSION);
2019-02-08 13:29:02 -08:00
return $this -> mySqlServerInfo ;
}
/**
* Select the database to use .
* @ param string $database name
2022-04-04 10:54:24 -07:00
* @ param string $prefix prefix . eg . e107_
2019-02-08 13:29:02 -08:00
* @ param boolean $multiple set to maintain connection to a secondary database .
* @ return boolean true when database selection was successful otherwise false .
*/
public function database ( $database , $prefix = MPREFIX , $multiple = false )
{
$this -> mySQLdefaultdb = $database ;
$this -> mySQLPrefix = $prefix ;
if ( $multiple === true )
{
$this -> mySQLPrefix = " ` " . $database . " `. " . $prefix ;
return true ;
}
try
{
2021-01-24 17:16:49 -08:00
$this -> mySQLaccess -> exec ( " use ` " . $database . " ` " );
2019-02-08 13:29:02 -08:00
// $this->mySQLaccess->select_db($database); $dbh->query("use newdatabase");
}
catch ( PDOException $e )
{
$this -> mySQLlastErrText = $e -> getMessage ();
$this -> mySQLlastErrNum = $e -> getCode ();
return false ;
}
return true ;
}
/**
* Get system config
* @ return e_core_pref
*/
public function getConfig ()
{
return e107 :: getConfig ( 'core' , false );
}
/**
2019-02-11 16:56:37 -08:00
*
2019-02-08 13:29:02 -08:00
* @ param string $sMarker
* @ desc Enter description here ...
2019-02-11 16:56:37 -08:00
* @ return null | true
2019-02-08 13:29:02 -08:00
*/
2019-02-11 16:56:37 -08:00
public function markTime ( $sMarker )
2019-02-08 13:29:02 -08:00
{
2019-02-10 16:19:25 -08:00
if ( $this -> debugMode !== true )
2019-02-08 13:29:02 -08:00
{
2019-02-10 16:19:25 -08:00
return null ;
2019-02-08 13:29:02 -08:00
}
2019-02-10 16:19:25 -08:00
$this -> dbg -> Mark_Time ( $sMarker );
2019-02-11 16:56:37 -08:00
return true ;
2019-02-08 13:29:02 -08:00
}
/**
* @ return void
* @ desc add query to dblog table
* @ access private
*/
2019-02-09 12:31:27 -08:00
function log ( $log_type = '' , $log_remark = '' , $log_query = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-09 12:31:27 -08:00
$tp = e107 :: getParser ();
2019-02-08 13:29:02 -08:00
list ( $time_usec , $time_sec ) = explode ( " " , microtime ());
$uid = ( USER ) ? USERID : '0' ;
$userstring = ( USER === true ? USERNAME : " LAN_ANONYMOUS " );
2019-02-11 16:32:41 -08:00
$ip = e107 :: getIPHandler () -> getIP ( false );
2019-02-08 13:29:02 -08:00
$qry = $tp -> toDB ( $log_query );
2019-02-09 12:31:27 -08:00
$insert = array (
// 'dblog_id' => 0,
'dblog_datestamp' => $time_sec ,
'dblog_microtime' => $time_usec ,
'dblog_type' => $log_type ,
'dblog_eventcode' => 'DBDEBUG' ,
'dblog_user_id' => $uid ,
'dblog_user_name' => $userstring ,
'dblog_ip' => $ip ,
'dblog_caller' => '' ,
'dblog_title' => $log_remark ,
2021-02-08 18:23:36 -08:00
'dblog_remarks' => is_array ( $qry ) ? e107 :: serialize ( $qry ) : $qry
2019-02-09 12:31:27 -08:00
);
$this -> insert ( 'dblog' , $insert );
// $this->insert('dblog', "0, {$time_sec}, {$time_usec}, '{$log_type}', 'DBDEBUG', {$uid}, '{$userstring}', '{$ip}', '', '{$log_remark}', '{$qry}'");
2019-02-08 13:29:02 -08:00
}
/**
2019-02-21 17:29:49 -08:00
* This is the 'core' routine which handles much of the interface between other functions and the DB
*
* If a SELECT query includes SQL_CALC_FOUND_ROWS , the value of FOUND_ROWS () is retrieved and stored in $this -> total_results
*
* @ param string | array $query [ 'BIND' ] eg . array [ 'my_field' ] = array ( 'value' => 'whatever' , 'type' => 'str' );
* @ param object $rli connection resource .
* @ param string $qry_from eg . SELECT , INSERT , UPDATE mode .
* @ param bool $debug
* @ param string $log_type
* @ param string $log_remark
2021-12-03 14:58:33 -08:00
* @ return boolean | int | PDOStatement - as mysql_query () function .
2019-02-21 17:29:49 -08:00
* false indicates an error
* For SELECT , SHOW , DESCRIBE , EXPLAIN and others returning a result set , returns a resource
* TRUE indicates success in other cases
*/
2019-02-11 16:32:41 -08:00
public function db_Query ( $query , $rli = NULL , $qry_from = '' , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-10 16:19:25 -08:00
global $db_time , $queryinfo ;
$this -> queryCount ++ ;
2019-02-08 13:29:02 -08:00
2019-02-13 21:26:17 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
$this -> mySQLlastQuery = $query ;
if ( $debug == 'now' )
{
2019-02-13 11:35:28 -08:00
$this -> dbg -> log ( $query );
2019-02-08 13:29:02 -08:00
}
2020-12-20 11:50:10 -08:00
if ( $debug !== false || strpos ( $_SERVER [ 'QUERY_STRING' ], 'showsql' ) !== false )
2019-02-08 13:29:02 -08:00
{
$debugQry = is_array ( $query ) ? print_a ( $query , true ) : $query ;
$queryinfo [] = " <b> { $qry_from } </b>: " . $debugQry ;
}
if ( $log_type != '' )
{
2019-02-09 12:31:27 -08:00
$this -> log ( $log_type , $log_remark , $query );
2019-02-08 13:29:02 -08:00
}
$b = microtime ();
2019-02-21 17:29:49 -08:00
if ( is_array ( $query ) && ! empty ( $query [ 'PREPARE' ]))
2019-02-08 13:29:02 -08:00
{
/** @var PDOStatement $prep */
$prep = $this -> mySQLaccess -> prepare ( $query [ 'PREPARE' ]);
2019-02-21 17:29:49 -08:00
if ( ! empty ( $query [ 'BIND' ]))
2019-02-08 13:29:02 -08:00
{
2019-02-21 17:29:49 -08:00
foreach ( $query [ 'BIND' ] as $k => $v )
{
2021-02-08 18:23:36 -08:00
$prep -> bindValue ( ':' . $k , $v [ 'value' ], $v [ 'type' ]);
2019-02-21 17:29:49 -08:00
}
2019-02-08 13:29:02 -08:00
}
2019-02-21 17:29:49 -08:00
$execute = ! empty ( $query [ 'EXECUTE' ]) ? $query [ 'EXECUTE' ] : null ;
2019-02-08 13:29:02 -08:00
try
{
2019-02-21 17:29:49 -08:00
$prep -> execute ( $execute );
$sQryRes = ( $qry_from == 'db_Select' ) ? $prep : $prep -> rowCount ();
2019-02-08 13:29:02 -08:00
}
catch ( PDOException $ex )
{
$sQryRes = false ;
$this -> mySQLlastErrText = $ex -> getMessage ();
$this -> mySQLlastErrNum = $ex -> getCode ();
}
}
else
{
try
{
if ( preg_match ( '#^(CREATE TABLE|DROP TABLE|ALTER TABLE|RENAME TABLE|CREATE DATABASE|CREATE INDEX)#' , $query , $matches ))
{
/** @var PDO $rli */
$sQryRes = is_null ( $rli ) ? $this -> mySQLaccess -> exec ( $query ) : $rli -> exec ( $query );
if ( $sQryRes !== false )
{
$sQryRes = true ; // match with non-PDO results.
}
}
else
{
/** @var PDO $rli */
$sQryRes = is_null ( $rli ) ? $this -> mySQLaccess -> query ( $query ) : $rli -> query ( $query );
}
}
catch ( PDOException $ex )
{
$sQryRes = false ;
$this -> mySQLlastErrText = $ex -> getMessage ();
$this -> mySQLlastErrNum = $ex -> getCode ();
}
}
$e = microtime ();
2019-02-10 14:51:51 -08:00
$this -> traffic -> Bump ( 'db_Query' , $b , $e );
$mytime = $this -> traffic -> TimeDelta ( $b , $e );
2019-02-08 13:29:02 -08:00
$db_time += $mytime ;
$this -> mySQLresult = $sQryRes ;
2019-02-10 16:19:25 -08:00
if ( $this -> debugMode !== true )
2019-02-08 13:29:02 -08:00
{
$this -> total_results = false ;
}
// Need to get the total record count as well. Return code is a resource identifier
// Have to do this before any debug action, otherwise this bit gets messed up
if ( ! is_array ( $query ) && ( strpos ( $query , 'EXPLAIN' ) !== 0 ) && ( strpos ( $query , 'SQL_CALC_FOUND_ROWS' ) !== false ) && ( strpos ( $query , 'SELECT' ) !== false ))
{
$rc = $this -> mySQLaccess -> query ( 'SELECT FOUND_ROWS();' ) -> fetch ( PDO :: FETCH_COLUMN );
$this -> total_results = intval ( $rc );
}
2019-02-10 16:19:25 -08:00
if ( $this -> debugMode === true )
2019-02-08 13:29:02 -08:00
{
$aTrace = debug_backtrace ();
2021-09-04 15:06:19 +02:00
$pTable = ( string ) $this -> mySQLcurTable ;
2019-02-10 16:19:25 -08:00
if ( ! strlen ( $pTable ))
{
2019-02-08 13:29:02 -08:00
$pTable = '(complex query)' ;
2019-02-10 16:19:25 -08:00
}
else
{
2019-02-08 13:29:02 -08:00
$this -> mySQLcurTable = '' ; // clear before next query
}
2019-02-10 16:19:25 -08:00
if ( is_object ( $this -> dbg ))
2019-02-08 13:29:02 -08:00
{
$buglink = is_null ( $rli ) ? $this -> mySQLaccess : $rli ;
if ( is_array ( $query ))
{
2020-01-17 20:23:13 +01:00
$query [ 'BIND' ] = isset ( $query [ 'BIND' ]) ? $query [ 'BIND' ] : null ;
2019-02-10 16:19:25 -08:00
$query = " PREPARE: " . $query [ 'PREPARE' ] . " <br />BIND: " . print_a ( $query [ 'BIND' ], true ); // ,true);
2019-02-08 13:29:02 -08:00
}
if ( isset ( $ex ) && is_object ( $ex ))
{
$query = $ex -> getMessage ();
2019-02-13 21:26:17 -08:00
// $arr = $ex->getTrace(); // @todo runs out of memory when tested.
// $query .= print_a($arr, true);
2019-02-08 13:29:02 -08:00
}
if ( $buglink instanceof PDO )
{
2019-02-10 16:19:25 -08:00
$this -> dbg -> Mark_Query ( $query , 'PDO' , $sQryRes , $aTrace , $mytime , $pTable );
2019-02-08 13:29:02 -08:00
}
}
2019-02-10 16:19:25 -08:00
2019-02-08 13:29:02 -08:00
}
return $sQryRes ;
}
/**
* Query and fetch at once
*
* Examples :
* < code >
* < ? php
*
* // Get single value, $multi and indexField are ignored
* $string = e107 :: getDb () -> retrieve ( 'user' , 'user_email' , 'user_id=1' );
*
* // Get single row set, $multi and indexField are ignored
* $array = e107 :: getDb () -> retrieve ( 'user' , 'user_email, user_name' , 'user_id=1' );
*
* // Fetch all, don't append WHERE to the query, index by user_id, noWhere auto detected (string starts with upper case ORDER)
* $array = e107 :: getDb () -> retrieve ( 'user' , 'user_id, user_email, user_name' , 'ORDER BY user_email LIMIT 0,20' , true , 'user_id' );
*
* // Same as above but retrieve() is only used to fetch, not useable for single return value
* if ( e107 :: getDb () -> select ( 'user' , 'user_id, user_email, user_name' , 'ORDER BY user_email LIMIT 0,20' , true ))
* {
* $array = e107 :: getDb () -> retrieve ( null , null , null , true , 'user_id' );
* }
*
2020-03-13 15:06:26 -07:00
* // Using whole query example, in this case default mode is 'one'
2019-02-08 13:29:02 -08:00
* $array = e107 :: getDb () -> retrieve ( ' SELECT
* p .* , u . user_email , u . user_name FROM `#user` AS u
* LEFT JOIN `#myplug_table` AS p ON p . myplug_table = u . user_id
* ORDER BY u . user_email LIMIT 0 , 20 '
* );
*
* // Using whole query example, multi mode - $fields argument mapped to $multi
* $array = e107 :: getDb () -> retrieve ( 'SELECT u.user_email, u.user_name FROM `#user` AS U ORDER BY user_email LIMIT 0,20' , true );
*
* // Using whole query example, multi mode with index field
* $array = e107 :: getDb () -> retrieve ( 'SELECT u.user_email, u.user_name FROM `#user` AS U ORDER BY user_email LIMIT 0,20' , null , null , true , 'user_id' );
* </ code >
*
* @ param string $table if empty , enter fetch only mode
* @ param string $fields comma separated list of fields or * or single field name ( get one ); if $fields is of type boolean and $where is not found , $fields overrides $multi
* @ param string $where WHERE / ORDER / LIMIT etc clause , empty to disable
* @ param boolean $multi if true , fetch all ( multi mode )
* @ param string $indexField field name to be used for indexing when in multi mode
* @ param boolean $debug
2019-02-10 16:19:25 -08:00
* @ return mixed
2019-02-08 13:29:02 -08:00
*/
2019-02-11 17:15:00 -08:00
public function retrieve ( $table = null , $fields = null , $where = null , $multi = false , $indexField = null , $debug = false )
2019-02-08 13:29:02 -08:00
{
// fetch mode
if ( empty ( $table ))
{
2019-02-11 17:55:16 -08:00
if ( ! $multi )
{
return $this -> fetch ();
}
2019-02-08 13:29:02 -08:00
$ret = array ();
while ( $row = $this -> fetch ())
{
2019-02-11 17:55:16 -08:00
if ( null !== $indexField )
{
$ret [ $row [ $indexField ]] = $row ;
}
else
{
$ret [] = $row ;
}
2019-02-08 13:29:02 -08:00
}
return $ret ;
}
// detect mode
$mode = 'one' ;
if ( $table && ! $where && is_bool ( $fields ))
{
// table is the query, fields used for multi
2019-02-11 17:55:16 -08:00
if ( $fields )
{
$mode = 'multi' ;
}
else
{
$mode = 'single' ;
}
2019-02-08 13:29:02 -08:00
$fields = null ;
}
elseif ( $fields && '*' !== $fields && strpos ( $fields , ',' ) === false && $where )
{
$mode = 'single' ;
}
2019-02-11 17:55:16 -08:00
2019-02-08 13:29:02 -08:00
if ( $multi )
{
$mode = 'multi' ;
}
// detect query type
$select = true ;
$noWhere = false ;
if ( ! $fields && ! $where )
{
// gen()
$select = false ;
2020-03-13 15:06:26 -07:00
if ( $mode == 'one' && ! preg_match ( '/[,*]+[\s\S]*FROM/im' , $table )) // if a comma or astericks is found before "FROM" then leave it in 'one' row mode.
{
$mode = 'single' ;
}
2019-02-08 13:29:02 -08:00
}
// auto detect noWhere - if where string starts with upper case LATIN word
elseif ( ! $where || preg_match ( '/^[A-Z]+\S.*$/' , trim ( $where )))
{
// FIXME - move auto detect to select()?
$noWhere = true ;
}
2020-03-13 15:06:26 -07:00
2019-02-08 13:29:02 -08:00
// execute & fetch
switch ( $mode )
{
2020-03-13 15:06:26 -07:00
case 'single' : // single field value returned.
2019-02-08 13:29:02 -08:00
if ( $select && ! $this -> select ( $table , $fields , $where , $noWhere , $debug ))
{
return null ;
}
elseif ( ! $select && ! $this -> gen ( $table , $debug ))
{
return null ;
}
$rows = $this -> fetch ();
return array_shift ( $rows );
break ;
2020-03-13 15:06:26 -07:00
case 'one' : // one row returned.
2019-02-08 13:29:02 -08:00
if ( $select && ! $this -> select ( $table , $fields , $where , $noWhere , $debug ))
{
return array ();
}
elseif ( ! $select && ! $this -> gen ( $table , $debug ))
{
return array ();
}
return $this -> fetch ();
break ;
case 'multi' :
if ( $select && ! $this -> select ( $table , $fields , $where , $noWhere , $debug ))
{
return array ();
}
elseif ( ! $select && ! $this -> gen ( $table , $debug ))
{
return array ();
}
$ret = array ();
while ( $row = $this -> fetch ())
{
if ( null !== $indexField ) $ret [ $row [ $indexField ]] = $row ;
else $ret [] = $row ;
}
return $ret ;
break ;
}
2019-02-10 16:19:25 -08:00
return null ;
2019-02-08 13:29:02 -08:00
}
/**
2019-02-21 17:29:49 -08:00
* Perform a SELECT using the arguments suplpied by calling db :: db_Query ()
*
* @ param string $table
* @ param string $fields
* @ param string | array $arg ;
2019-02-08 13:29:02 -08:00
*
2019-02-21 17:29:49 -08:00
* @ example e107 :: getDb () -> select ( " comments " , " * " , " comment_item_id = ' $id ' AND comment_type = '1' ORDER BY comment_datestamp " );
* @ example e107 :: getDb ( 'sql2' ) -> select ( " chatbox " , " * " , " ORDER BY cb_datestamp DESC LIMIT $from , " . $view , true ); </ code >
* @ example select ( 'user' , 'user_id, user_name' , 'user_id=:id OR user_name=:name ORDER BY user_name' , array ( 'id' => 999 , 'name' => 'e107' )); // bind support.
2019-02-08 13:29:02 -08:00
* @ return integer Number of rows or false on error
*/
2019-02-11 16:32:41 -08:00
public function select ( $table , $fields = '*' , $arg = '' , $noWhere = false , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-08 14:06:52 -08:00
$table = $this -> hasLanguage ( $table );
2019-02-08 13:29:02 -08:00
$this -> mySQLcurTable = $table ;
2019-02-21 17:29:49 -08:00
// e107 v2.2 PDO bind params.
if ( ! empty ( $arg ) && is_array ( $noWhere ))
{
$query = array (
'PREPARE' => 'SELECT ' . $fields . ' FROM ' . $this -> mySQLPrefix . $table . ' WHERE ' . $arg ,
'EXECUTE' => $noWhere
);
if ( $this -> mySQLresult = $this -> db_Query ( $query , null , 'db_Select' , $debug , $log_type , $log_remark ))
{
$this -> dbError ( 'dbQuery' );
return $this -> rowCount ();
}
else
{
$this -> dbError ( 'select() with prepare/execute' );
return false ;
}
}
if ( ! empty ( $arg ) && ( $noWhere === false || $noWhere === 'default' )) // 'default' for BC.
2019-02-08 13:29:02 -08:00
{
if ( $this -> mySQLresult = $this -> db_Query ( 'SELECT ' . $fields . ' FROM ' . $this -> mySQLPrefix . $table . ' WHERE ' . $arg , NULL , 'db_Select' , $debug , $log_type , $log_remark ))
{
$this -> dbError ( 'dbQuery' );
return $this -> rowCount ();
}
else
{
$this -> dbError ( " db_Select (SELECT $fields FROM " . $this -> mySQLPrefix . " { $table } WHERE { $arg } ) " );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
elseif ( $arg != '' && ( $noWhere !== false ) && ( $noWhere !== 'default' )) // 'default' for BC.
{
if ( $this -> mySQLresult = $this -> db_Query ( 'SELECT ' . $fields . ' FROM ' . $this -> mySQLPrefix . $table . ' ' . $arg , NULL , 'db_Select' , $debug , $log_type , $log_remark ))
{
$this -> dbError ( 'dbQuery' );
return $this -> rowCount ();
}
else
{
$this -> dbError ( " db_Select (SELECT { $fields } FROM " . $this -> mySQLPrefix . " { $table } { $arg } ) " );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
else
{
if ( $this -> mySQLresult = $this -> db_Query ( 'SELECT ' . $fields . ' FROM ' . $this -> mySQLPrefix . $table , NULL , 'db_Select' , $debug , $log_type , $log_remark ))
{
$this -> dbError ( 'dbQuery' );
return $this -> rowCount ();
}
else
{
$this -> dbError ( " db_Select (SELECT { $fields } FROM " . $this -> mySQLPrefix . " { $table } ) " );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
}
2019-02-08 14:06:52 -08:00
2019-02-08 13:29:02 -08:00
/**
* @ param string $tableName - Name of table to access , without any language or general DB prefix
* @ param $arg
* @ param bool $debug
* @ param string $log_type
* @ param string $log_remark
* @ return int Last insert ID or false on error . When using '_DUPLICATE_KEY_UPDATE' return ID , true on update , 0 on no change and false on error .
* @ desc Insert a row into the table < br />
* < br />
* Example :< br />
* < code > e107 :: getDb () -> insert ( " links " , " 0, 'News', 'news.php', '', '', 1, 0, 0, 0 " ); </ code >
*
* @ access public
*/
2019-02-11 16:32:41 -08:00
function insert ( $tableName , $arg , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-08 14:06:52 -08:00
$table = $this -> hasLanguage ( $tableName );
2019-02-08 13:29:02 -08:00
$this -> mySQLcurTable = $table ;
$REPLACE = false ; // kill any PHP notices
$DUPEKEY_UPDATE = false ;
$IGNORE = '' ;
if ( is_array ( $arg ))
{
if ( isset ( $arg [ 'WHERE' ])) // use same array for update and insert.
{
unset ( $arg [ 'WHERE' ]);
}
if ( isset ( $arg [ '_REPLACE' ]))
{
$REPLACE = TRUE ;
unset ( $arg [ '_REPLACE' ]);
}
if ( isset ( $arg [ '_DUPLICATE_KEY_UPDATE' ]))
{
$DUPEKEY_UPDATE = true ;
unset ( $arg [ '_DUPLICATE_KEY_UPDATE' ]);
}
if ( isset ( $arg [ '_IGNORE' ]))
{
$IGNORE = ' IGNORE' ;
unset ( $arg [ '_IGNORE' ]);
}
if ( ! isset ( $arg [ '_FIELD_TYPES' ]) && ! isset ( $arg [ 'data' ]))
{
//Convert data if not using 'new' format
$_tmp = array ();
$_tmp [ 'data' ] = $arg ;
$arg = $_tmp ;
unset ( $_tmp );
}
if ( ! isset ( $arg [ 'data' ])) { return false ; }
// See if we need to auto-add field types array
2020-01-17 15:54:56 +01:00
if ( ! isset ( $arg [ '_FIELD_TYPES' ]))
2019-02-08 13:29:02 -08:00
{
2020-01-17 17:24:06 +01:00
$fieldDefs = $this -> getFieldDefs ( $tableName );
if ( is_array ( $fieldDefs )) $arg = array_merge ( $arg , $fieldDefs );
2019-02-08 13:29:02 -08:00
}
$argUpdate = $arg ; // used when DUPLICATE_KEY_UPDATE is active;
// Handle 'NOT NULL' fields without a default value
if ( isset ( $arg [ '_NOTNULL' ]))
{
foreach ( $arg [ '_NOTNULL' ] as $f => $v )
{
if ( ! isset ( $arg [ 'data' ][ $f ]))
{
$arg [ 'data' ][ $f ] = $v ;
}
}
}
$fieldTypes = $this -> _getTypes ( $arg );
$keyList = '`' . implode ( '`,`' , array_keys ( $arg [ 'data' ])) . '`' ;
$tmp = array ();
$bind = array ();
foreach ( $arg [ 'data' ] as $fk => $fv )
{
$tmp [] = ':' . $fk ;
2020-01-17 17:24:06 +01:00
$fieldType = isset ( $fieldTypes [ $fk ]) ? $fieldTypes [ $fk ] : null ;
$bind [ $fk ] = array ( 'value' => $this -> _getPDOValue ( $fieldType , $fv ), 'type' => $this -> _getPDOType ( $fieldType , $this -> _getPDOValue ( $fieldType , $fv )));
2019-02-08 13:29:02 -08:00
}
$valList = implode ( ', ' , $tmp );
unset ( $tmp );
if ( $REPLACE === false )
{
$query = " INSERT " . $IGNORE . " INTO " . $this -> mySQLPrefix . " { $table } ( { $keyList } ) VALUES ( { $valList } ) " ;
if ( $DUPEKEY_UPDATE === true )
{
$query .= " ON DUPLICATE KEY UPDATE " ;
$query .= $this -> _prepareUpdateArg ( $tableName , $argUpdate );
}
}
else
{
$query = " REPLACE INTO " . $this -> mySQLPrefix . " { $table } ( { $keyList } ) VALUES ( { $valList } ) " ;
}
$query = array (
'PREPARE' => $query ,
'BIND' => $bind ,
);
}
else
{
$query = 'INSERT INTO ' . $this -> mySQLPrefix . " { $table } VALUES ( { $arg } ) " ;
}
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
$this -> mySQLresult = $this -> db_Query ( $query , NULL , 'db_Insert' , $debug , $log_type , $log_remark );
if ( $DUPEKEY_UPDATE === true )
{
$result = false ; // ie. there was an error.
if ( $this -> mySQLresult === 1 ) // insert.
{
$result = $this -> lastInsertId ();
}
elseif ( $this -> mySQLresult === 2 || $this -> mySQLresult === true ) // updated
{
$result = true ;
2019-02-25 18:51:49 -08:00
// reset auto-increment to prevent gaps.
$this -> db_Query ( " ALTER TABLE " . $this -> mySQLPrefix . $table . " AUTO_INCREMENT=1 " , NULL , 'db_Insert' , $debug , $log_type , $log_remark );
2019-02-08 13:29:02 -08:00
}
elseif ( $this -> mySQLresult === 0 ) // updated (no change)
{
$result = 0 ;
}
$this -> dbError ( 'db_Insert' );
return $result ;
}
if ( $this -> mySQLresult )
{
if ( true === $REPLACE )
{
$tmp = $this -> mySQLresult ;
$this -> dbError ( 'db_Replace' );
// $tmp == -1 (error), $tmp == 0 (not modified), $tmp == 1 (added), greater (replaced)
if ( $tmp == - 1 ) { return false ; } // mysql_affected_rows error
return $tmp ;
}
// $tmp = ($this->pdo) ? $this->mySQLaccess->lastInsertId() : mysql_insert_id($this->mySQLaccess);
$tmp = $this -> lastInsertId ();
$this -> dbError ( 'db_Insert' );
return ( $tmp ) ? $tmp : TRUE ; // return true even if table doesn't have auto-increment.
}
else
{
// $this->dbError("db_Insert ({$query})");
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
2022-04-04 10:54:24 -07:00
/**
* @ return bool | int
*/
2019-02-08 13:29:02 -08:00
public function lastInsertId ()
{
$tmp = ( int ) $this -> mySQLaccess -> lastInsertId ();
return ( $tmp ) ? $tmp : true ; // return true even if table doesn't have auto-increment.
}
/**
* Return the total number of results on the last query regardless of the LIMIT value when SELECT SQL_CALC_FOUND_ROWS is used .
* @ return bool
*/
public function foundRows ()
{
return $this -> total_results ;
}
2022-04-04 10:54:24 -07:00
/**
* @ param $result
* @ return int
*/
2019-02-08 13:29:02 -08:00
public function rowCount ( $result = null )
{
if ( ! $this -> mySQLresult )
{
return - 1 ;
}
/** @var PDOStatement $resource */
$resource = $this -> mySQLresult ;
$rows = $this -> mySQLrows = $resource -> rowCount ();
$this -> dbError ( 'db_Rows' );
return $rows ;
}
2019-02-08 14:06:52 -08:00
2019-02-08 13:29:02 -08:00
/**
* @ param string $table
* @ param array $arg
* @ param bool $debug
* @ param string $log_type
* @ param string $log_remark
* @ return int Last insert ID or false on error
* @ desc Insert / REplace a row into the table < br />
* < br />
* Example :< br />
* < code > e107 :: getDb () -> replace ( " links " , $array ); </ code >
*
* @ access public
*/
2019-02-11 16:32:41 -08:00
function replace ( $table , $arg , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
$arg [ '_REPLACE' ] = TRUE ;
return $this -> insert ( $table , $arg , $debug , $log_type , $log_remark );
}
2019-02-08 14:06:52 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ param $tableName
* @ param $arg
* @ return false | mixed | string
*/
2019-02-08 13:29:02 -08:00
private function _prepareUpdateArg ( $tableName , $arg )
{
$this -> pdoBind = array ();
if ( is_array ( $arg )) // Remove the need for a separate db_UpdateArray() function.
{
if ( ! isset ( $arg [ '_FIELD_TYPES' ]) && ! isset ( $arg [ 'data' ]))
{
//Convert data if not using 'new' format
$_tmp = array ();
if ( isset ( $arg [ 'WHERE' ]))
{
$_tmp [ 'WHERE' ] = $arg [ 'WHERE' ];
unset ( $arg [ 'WHERE' ]);
}
$_tmp [ 'data' ] = $arg ;
$arg = $_tmp ;
unset ( $_tmp );
}
if ( ! isset ( $arg [ 'data' ])) { return false ; }
// See if we need to auto-add field types array
2020-01-17 15:54:56 +01:00
if ( ! isset ( $arg [ '_FIELD_TYPES' ]))
2019-02-08 13:29:02 -08:00
{
2020-01-17 17:24:06 +01:00
$fieldDefs = $this -> getFieldDefs ( $tableName );
if ( is_array ( $fieldDefs )) $arg = array_merge ( $arg , $fieldDefs );
2019-02-08 13:29:02 -08:00
}
$fieldTypes = $this -> _getTypes ( $arg );
$new_data = '' ;
//$this->pdoBind = array(); // moved up to the beginning of the method to make sure it is initialized properly
foreach ( $arg [ 'data' ] as $fn => $fv )
{
$new_data .= ( $new_data ? ', ' : '' );
$ftype = isset ( $fieldTypes [ $fn ]) ? $fieldTypes [ $fn ] : 'str' ;
$new_data .= ( $ftype != 'cmd' ) ? " ` { $fn } `= : " . $fn : " ` { $fn } `= " . $this -> _getFieldValue ( $fn , $fv , $fieldTypes );
if ( $fv === '_NULL_' )
{
$ftype = 'null' ;
}
if ( $ftype != 'cmd' )
{
$this -> pdoBind [ $fn ] = array ( 'value' => $this -> _getPDOValue ( $ftype , $fv ), 'type' => $this -> _getPDOType ( $ftype , $this -> _getPDOValue ( $ftype , $fv )));
}
}
$arg = $new_data . ( isset ( $arg [ 'WHERE' ]) ? ' WHERE ' . $arg [ 'WHERE' ] : '' );
}
return $arg ;
}
/**
* @ return int number of affected rows , or false on error
* @ param string $tableName - Name of table to access , without any language or general DB prefix
* @ param array | string $arg ( array preferred )
* @ param bool $debug
* @ desc Update fields in ONE table of the database corresponding to your $arg variable < br />
* < br />
* Think to call it if you need to do an update while retrieving data .< br />
* < br />
* Example using a unique connection to database :< br />
* < code > e107 :: getDb () -> update ( " user " , " user_viewed=' $u_new ' WHERE user_id=' " . USERID . " ' " ); </ code >
* < br />
* OR as second connection < br />
* < code >
* e107 :: getDb ( 'sql2' ) -> update ( " user " , " user_viewed = ' $u_new ' WHERE user_id = ' " . USERID . " ' " ); </ code >< br />
*
* @ access public
*/
2019-02-11 16:32:41 -08:00
function update ( $tableName , $arg , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-08 14:06:52 -08:00
$table = $this -> hasLanguage ( $tableName );
2019-02-08 13:29:02 -08:00
$this -> mySQLcurTable = $table ;
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
$arg = $this -> _prepareUpdateArg ( $tableName , $arg );
$query = 'UPDATE ' . $this -> mySQLPrefix . $table . ' SET ' . $arg ;
if ( ! empty ( $this -> pdoBind ))
{
$query = array (
'PREPARE' => $query ,
'BIND' => $this -> pdoBind ,
);
}
$result = $this -> mySQLresult = $this -> db_Query ( $query , NULL , 'db_Update' , $debug , $log_type , $log_remark );
if ( $result !== false )
{
if ( is_object ( $result ))
{
// make sure to return the number of records affected, instead of an object
$result = $this -> rowCount ();
}
$this -> dbError ( 'db_Update' );
if ( $result === - 1 ) { return false ; } // Error return from mysql_affected_rows
return $result ;
}
else
{
2021-03-04 16:12:01 -08:00
$this -> dbError ( 'db_Update (' . print_r ( $query , true ) . ')' );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
2019-02-08 14:06:52 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ param $arg
* @ return array | mixed
*/
2019-02-09 12:31:27 -08:00
private function _getTypes ( & $arg )
2019-02-08 13:29:02 -08:00
{
if ( isset ( $arg [ '_FIELD_TYPES' ]))
{
if ( ! isset ( $arg [ '_FIELD_TYPES' ][ '_DEFAULT' ]))
{
$arg [ '_FIELD_TYPES' ][ '_DEFAULT' ] = 'string' ;
}
$fieldTypes = $arg [ '_FIELD_TYPES' ];
unset ( $arg [ '_FIELD_TYPES' ]);
}
else
{
$fieldTypes = array ();
$fieldTypes [ '_DEFAULT' ] = 'string' ;
}
return $fieldTypes ;
}
/**
* @ param string | array $fieldValue
2021-12-03 14:58:33 -08:00
* @ desc Return new field value in proper format < br />
2019-02-08 13:29:02 -08:00
*
* @ access private
2021-12-03 14:58:33 -08:00
*@ return array | float | int | string
2019-02-08 13:29:02 -08:00
*/
2019-02-09 12:31:27 -08:00
private function _getFieldValue ( $fieldKey , $fieldValue , & $fieldTypes )
2019-02-08 13:29:02 -08:00
{
if ( $fieldValue === '_NULL_' ) { return 'NULL' ;}
$type = ( isset ( $fieldTypes [ $fieldKey ]) ? $fieldTypes [ $fieldKey ] : $fieldTypes [ '_DEFAULT' ]);
switch ( $type )
{
case 'int' :
case 'integer' :
return ( int ) $fieldValue ;
break ;
case 'cmd' :
return $fieldValue ;
break ;
case 'safestr' :
return " ' { $fieldValue } ' " ;
break ;
case 'str' :
case 'string' :
//return "'{$fieldValue}'";
return " ' " . $this -> escape ( $fieldValue , false ) . " ' " ;
break ;
case 'float' :
// fix - convert localized float numbers
// $larr = localeconv();
// $search = array($larr['decimal_point'], $larr['mon_decimal_point'], $larr['thousands_sep'], $larr['mon_thousands_sep'], $larr['currency_symbol'], $larr['int_curr_symbol']);
// $replace = array('.', '.', '', '', '', '');
// return str_replace($search, $replace, floatval($fieldValue));
return e107 :: getParser () -> toNumber ( $fieldValue );
break ;
case 'null' :
//return ($fieldValue && $fieldValue !== 'NULL' ? "'{$fieldValue}'" : 'NULL');
return ( $fieldValue && $fieldValue !== 'NULL' ? " ' " . $this -> escape ( $fieldValue , false ) . " ' " : 'NULL' );
break ;
case 'array' :
if ( is_array ( $fieldValue ))
{
2019-06-03 15:27:36 -07:00
return " ' " . e107 :: serialize ( $fieldValue , true ) . " ' " ;
2019-02-08 13:29:02 -08:00
}
return " ' " . ( string ) $fieldValue . " ' " ;
break ;
case 'todb' : // using as default causes serious BC issues.
if ( $fieldValue == '' ) { return " '' " ; }
return " ' " . e107 :: getParser () -> toDB ( $fieldValue ) . " ' " ;
break ;
case 'escape' :
default :
return " ' " . $this -> escape ( $fieldValue , false ) . " ' " ;
break ;
}
}
/**
* Return a value for use in PDO bindValue () - based on field - type .
* @ param $type
* @ param $fieldValue
* @ return int | string
*/
private function _getPDOValue ( $type , $fieldValue )
{
if ( is_string ( $fieldValue ) && ( $fieldValue === '_NULL_' ))
{
$type = 'null' ;
}
switch ( $type )
{
case " int " :
case " integer " :
return ( int ) $fieldValue ;
break ;
case 'float' :
// fix - convert localized float numbers
// $larr = localeconv();
// $search = array($larr['decimal_point'], $larr['mon_decimal_point'], $larr['thousands_sep'], $larr['mon_thousands_sep'], $larr['currency_symbol'], $larr['int_curr_symbol']);
// $replace = array('.', '.', '', '', '', '');
// return str_replace($search, $replace, floatval($fieldValue));
return e107 :: getParser () -> toNumber ( $fieldValue );
break ;
case 'null' :
return (
is_string ( $fieldValue ) && (
( $fieldValue !== '_NULL_' ) && ( $fieldValue !== '' )
)
) ? $fieldValue : null ;
break ;
case 'array' :
if ( is_array ( $fieldValue ))
{
return e107 :: serialize ( $fieldValue );
}
return $fieldValue ;
break ;
case 'todb' : // using as default causes serious BC issues.
if ( $fieldValue == '' ) { return '' ; }
return e107 :: getParser () -> toDB ( $fieldValue );
break ;
case 'cmd' :
case 'safestr' :
case 'str' :
case 'string' :
case 'escape' :
default :
return $fieldValue ;
break ;
}
}
/**
* Convert FIELD_TYPE to PDO compatible Field - Type
* @ param $type
2021-12-03 14:58:33 -08:00
* @ param null $value
2019-02-08 13:29:02 -08:00
* @ return int
*/
private function _getPDOType ( $type , $value = null )
{
switch ( $type )
{
case " int " :
case " integer " :
return PDO :: PARAM_INT ;
break ;
case 'null' :
return ( $value === null ) ? PDO :: PARAM_NULL : PDO :: PARAM_STR ;
break ;
case 'cmd' :
case 'safestr' :
case 'str' :
case 'string' :
case 'escape' :
case 'array' :
case 'todb' :
case 'float' :
return PDO :: PARAM_STR ;
break ;
}
// e107::getMessage()->addDebug("MySQL Missing Field-Type: ".$type);
return PDO :: PARAM_STR ;
}
/**
* Truncate a table
* @ param string $table - table name without e107 prefix
*/
function truncate ( $table = null )
{
if ( $table == null ){ return null ; }
return $this -> gen ( " TRUNCATE TABLE " . $this -> mySQLPrefix . $table );
}
/**
* @ param string $type assoc | num | both
* @ return array | bool MySQL row
* @ desc Fetch an array containing row data ( see PHP ' s mysql_fetch_array () docs ) < br />
* @ example
* Example :< br />
* < code > while ( $row = $sql -> fetch ()){
* $text .= $row [ 'username' ];
* } </ code >
*
* @ access public
*/
function fetch ( $type = null )
{
2019-02-11 16:56:37 -08:00
switch ( $type )
{
case 'both' :
case 3 : // MYSQL_BOTH:
$type = PDO :: FETCH_BOTH ; // 3
break ;
2019-02-08 13:29:02 -08:00
2019-02-11 16:56:37 -08:00
case 'num' :
case 2 ; // MYSQL_NUM: // 2
$type = PDO :: FETCH_NUM ;
break ;
2019-02-08 13:29:02 -08:00
2019-02-11 16:56:37 -08:00
default :
case 'assoc' :
case 1 ; // MYSQL_ASSOC // 1
$type = PDO :: FETCH_ASSOC ;
break ;
2019-02-08 13:29:02 -08:00
}
$b = microtime ();
if ( $this -> mySQLresult )
{
/** @var PDOStatement $resource */
$resource = $this -> mySQLresult ;
$row = $resource -> fetch ( $type );
2019-02-10 14:51:51 -08:00
$this -> traffic -> Bump ( 'db_Fetch' , $b );
2019-02-11 16:56:37 -08:00
2019-02-08 13:29:02 -08:00
if ( $row )
{
$this -> dbError ( 'db_Fetch' );
return $row ; // Success - return data
}
}
2019-02-11 16:56:37 -08:00
2019-02-08 13:29:02 -08:00
$this -> dbError ( 'db_Fetch' );
2019-02-11 16:56:37 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
2019-02-08 14:06:52 -08:00
2019-02-08 13:29:02 -08:00
/**
* @ param string $table
* @ param string $fields
* @ param string $arg
* @ param bool $debug
* @ param string $log_type
* @ param string $log_remark
* @ return int number of affected rows or false on error
* @ desc Count the number of rows in a select < br />
* < br />
* Example :< br />
* < code > $topics = e107 :: getDb () -> count ( " forum_thread " , " (*) " , " thread_forum_id=' " . $forum_id . " ' AND thread_parent='0' " ); </ code >
*
* @ access public
*/
2019-02-11 16:32:41 -08:00
function count ( $table , $fields = '(*)' , $arg = '' , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-08 14:06:52 -08:00
$table = $this -> hasLanguage ( $table );
2019-02-08 13:29:02 -08:00
if ( $fields == 'generic' )
{
$query = $table ;
if ( $this -> mySQLresult = $this -> db_Query ( $query , NULL , 'db_Count' , $debug , $log_type , $log_remark ))
{
$rows = $this -> mySQLrows = $this -> mySQLresult -> fetch ( PDO :: FETCH_ASSOC );
$this -> dbError ( 'db_Count' );
return ( int ) $rows [ 'COUNT(*)' ];
}
else
{
$this -> dbError ( " db_Count ( { $query } ) " );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
$this -> mySQLcurTable = $table ;
// normalize query arguments - only COUNT expected 'WHERE', not anymore
if ( $arg && stripos ( trim ( $arg ), 'WHERE' ) !== 0 )
{
$arg = 'WHERE ' . $arg ;
}
$query = 'SELECT COUNT' . $fields . ' FROM ' . $this -> mySQLPrefix . $table . ' ' . $arg ;
if ( $this -> mySQLresult = $this -> db_Query ( $query , NULL , 'db_Count' , $debug , $log_type , $log_remark ))
{
$rows = $this -> mySQLrows = $this -> mySQLresult -> fetch ( PDO :: FETCH_NUM );
$this -> dbError ( 'db_Count' );
return ( int ) $rows [ 0 ];
}
else
{
$this -> dbError ( " db_Count( { $query } ) " );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
/**
* @ desc Closes the mySQL server connection .< br />
* < br />
* Only required if you open a second connection .< br />
* Native e107 connection is closed in the footer . php file < br />
* < br />
* Example :< br />
* < code > $sql -> db_Close (); </ code >
*
* @ access public
* @ return void
*/
function close ()
{
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-10 14:51:51 -08:00
$this -> traffic -> BumpWho ( 'db Close' , 1 );
2019-02-13 21:26:17 -08:00
$this -> mySQLaccess = null ; // correct way to do it when using shared links.
2019-02-08 13:29:02 -08:00
$this -> dbError ( 'dbClose' );
}
2019-02-08 14:06:52 -08:00
2019-02-08 13:29:02 -08:00
/**
* @ return int number of affected rows , or false on error
* @ param string $table
* @ param string $arg
* @ desc Delete rows from a table < br />
* < br />
* Example :
* < code > $sql -> delete ( " tmp " , " tmp_ip=' $ip ' " ); </ code >< br />
* < br />
* @ access public
*/
2019-02-11 16:32:41 -08:00
function delete ( $table , $arg = '' , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-08 14:06:52 -08:00
$table = $this -> hasLanguage ( $table );
2019-02-08 13:29:02 -08:00
$this -> mySQLcurTable = $table ;
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
if ( ! $arg )
{
if ( $result = $this -> mySQLresult = $this -> db_Query ( 'DELETE FROM ' . $this -> mySQLPrefix . $table , NULL , 'db_Delete' , $debug , $log_type , $log_remark ))
{
// return the number of records deleted instead of an object
$tmp = $this -> mySQLresult -> rowCount ();
$this -> dbError ( 'db_Delete' );
return $tmp ;
}
else
{
$this -> dbError ( " db_Delete( { $arg } ) " );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
else
{
if ( $result = $this -> mySQLresult = $this -> db_Query ( 'DELETE FROM ' . $this -> mySQLPrefix . $table . ' WHERE ' . $arg , NULL , 'db_Delete' , $debug , $log_type , $log_remark ))
{
$tmp = $this -> mySQLresult -> rowCount ();
$this -> dbError ( 'db_Delete' );
return $tmp ;
}
else
{
$this -> dbError ( 'db_Delete (' . $arg . ')' );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
}
}
/**
* @ return void
* @ param bool $mode
* @ desc Enter description here ...
* @ access private
*/
2019-02-09 13:07:34 -08:00
function setErrorReporting ( $mode )
2019-02-08 13:29:02 -08:00
{
$this -> mySQLerror = $mode ;
}
/**
* Function to handle any MySQL query
* @ param string $query - the MySQL query string , where '#' represents the database prefix in front of table names .
* Strongly recommended to enclose all table names in backticks , to minimise the possibility of erroneous substitutions - its
* likely that this will become mandatory at some point
* @ return boolean | integer
2019-02-11 16:32:41 -08:00
* Returns false if there is an error in the query
2019-02-08 13:29:02 -08:00
* Returns TRUE if the query is successful , and it does not return a row count
* Returns the number of rows added / updated / deleted for DELETE , INSERT , REPLACE , or UPDATE
*/
2019-02-11 16:32:41 -08:00
public function gen ( $query , $debug = false , $log_type = '' , $log_remark = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-11 16:32:41 -08:00
$this -> tabset = false ;
2019-02-08 13:29:02 -08:00
$query .= " " ; // temp fix for failing regex below, when there is no space after the table name;
2019-02-11 16:32:41 -08:00
if ( strpos ( $query , '`#' ) !== false )
2019-02-08 13:29:02 -08:00
{
//$query = str_replace('`#','`'.$this->mySQLPrefix,$query); // This simple substitution should be OK when backticks used
// SecretR - reverted back - breaks multi-language
$query = preg_replace_callback ( " / \ s`#([ \ w]*?)` \ W/ " , array ( $this , 'ml_check' ), $query );
}
2019-02-11 16:32:41 -08:00
elseif ( strpos ( $query , '#' ) !== false )
2019-02-08 13:29:02 -08:00
{ // Deprecated scenario - caused problems when '#' appeared in data - hence use of backticks
$query = preg_replace_callback ( " / \ s#([ \ w]*?) \ W/ " , array ( $this , 'ml_check' ), $query );
}
//$query = str_replace("#",$this->mySQLPrefix,$query); //FIXME - quick fix for those that slip-thru - but destroys
// the point of requiring backticks round table names - wrecks ', for example
2019-02-11 16:32:41 -08:00
if (( $this -> mySQLresult = $this -> db_Query ( $query , NULL , 'db_Select_gen' , $debug , $log_type , $log_remark )) === false )
2019-02-08 13:29:02 -08:00
{ // Failed query
$this -> dbError ( 'db_Select_gen(' . $query . ')' );
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
elseif ( $this -> mySQLresult === TRUE )
{ // Successful query which may return a row count (because it operated on a number of rows without returning a result set)
if ( preg_match ( '#^(DELETE|INSERT|REPLACE|UPDATE)#' , $query , $matches ))
2019-02-11 17:55:16 -08:00
{
2019-02-08 13:29:02 -08:00
/** @var PDOStatement $resource */
$resource = $this -> mySQLresult ;
$tmp = $resource -> rowCount ();
$this -> dbError ( 'db_Select_gen' );
return $tmp ;
}
$this -> dbError ( 'db_Select_gen' ); // No row count here
return TRUE ;
}
else
{ // Successful query which does return a row count - get the count and return it
$this -> dbError ( 'db_Select_gen' );
return $this -> rowCount ();
}
}
2019-02-08 14:06:52 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ param $matches
* @ return string
*/
2019-02-08 13:29:02 -08:00
function ml_check ( $matches )
{
2019-02-08 14:06:52 -08:00
$table = $this -> hasLanguage ( $matches [ 1 ]);
2019-02-08 13:29:02 -08:00
if ( $this -> tabset == false )
{
$this -> mySQLcurTable = $table ;
$this -> tabset = true ;
}
return " " . $this -> mySQLPrefix . $table . substr ( $matches [ 0 ], - 1 );
}
/**
* Check for the existence of a matching language table when multi - language tables are active .
* @ param string | array $table Name of table , without the prefix . or an array of table names .
* @ access private
2021-12-03 14:58:33 -08:00
* @ return array | false | string the name of the language table ( eg . lan_french_news ) or an array of all matching language tables . ( with mprefix )
2019-02-08 13:29:02 -08:00
*/
2019-02-11 16:19:07 -08:00
public function hasLanguage ( $table , $multiple = false )
2019-02-08 13:29:02 -08:00
{
//When running a multi-language site with english included. English must be the main site language.
2019-02-11 16:32:41 -08:00
// WARNING!!! false is critical important - if missed, expect dead loop (prefs are calling db handler as well when loading)
2019-02-08 13:29:02 -08:00
// Temporary solution, better one is needed
$core_pref = $this -> getConfig ();
2019-02-11 16:32:41 -08:00
//if ((!$this->mySQLlanguage || !$pref['multilanguage'] || $this->mySQLlanguage=='English') && $multiple==false)
if (( ! $this -> mySQLlanguage || ! $core_pref -> get ( 'multilanguage' ) || ! $core_pref -> get ( 'sitelanguage' ) /*|| $this->mySQLlanguage==$core_pref->get('sitelanguage')*/ ) && $multiple == false )
2019-02-08 13:29:02 -08:00
{
return $table ;
}
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
2019-02-11 16:32:41 -08:00
if ( $multiple == false )
2019-02-08 13:29:02 -08:00
{
$mltable = " lan_ " . strtolower ( $this -> mySQLlanguage . '_' . $table );
return ( $this -> isTable ( $table , $this -> mySQLlanguage ) ? $mltable : $table );
}
else // return an array of all matching language tables. eg [french]->e107_lan_news
{
if ( ! is_array ( $table ))
{
$table = array ( $table );
}
if ( ! $this -> mySQLtableList )
{
2019-02-11 14:54:09 -08:00
$this -> mySQLtableList = $this -> _getTableList ();
2019-02-08 13:29:02 -08:00
}
$lanlist = array ();
foreach ( $this -> mySQLtableList as $tab )
{
2020-12-20 11:50:10 -08:00
if ( strpos ( $tab , " lan_ " ) === 0 )
2019-02-08 13:29:02 -08:00
{
list ( $tmp , $lng , $tableName ) = explode ( " _ " , $tab , 3 );
foreach ( $table as $t )
{
if ( $tableName == $t )
{
$lanlist [ $lng ][ $this -> mySQLPrefix . $t ] = $this -> mySQLPrefix . $tab ; // prefix needed.
}
}
}
}
if ( empty ( $lanlist ))
{
return false ;
}
else
{
return $lanlist ;
}
}
// -------------------------
}
/**
* @ return array
* @ param string fields to retrieve
* @ desc returns fields as structured array
* @ access public
2019-02-09 12:31:27 -08:00
* @ return array rows of the database as an array .
2019-02-08 13:29:02 -08:00
*/
2019-02-11 16:32:41 -08:00
function rows ( $fields = 'ALL' , $amount = false , $maximum = false , $ordermode = false )
2019-02-08 13:29:02 -08:00
{
$list = array ();
$counter = 1 ;
while ( $row = $this -> fetch ())
{
foreach ( $row as $key => $value )
{
if ( is_string ( $key ))
{
if ( strtoupper ( $fields ) == 'ALL' || in_array ( $key , $fields ))
{
if ( ! $ordermode )
{
$list [ $counter ][ $key ] = $value ;
}
else
{
$list [ $row [ $ordermode ]][ $key ] = $value ;
}
}
}
}
if ( $amount && $amount == $counter || ( $maximum && $counter > $maximum ))
{
break ;
}
$counter ++ ;
}
return $list ;
}
/**
* Return the maximum value for a given table / field
* @ param $table ( without the prefix )
* @ param $field
* @ param string $where ( optional )
2019-02-13 14:06:00 -08:00
* @ return mixed
2019-02-08 13:29:02 -08:00
*/
public function max ( $table , $field , $where = '' )
{
2019-02-13 14:06:00 -08:00
$qry = " SELECT MAX( " . $field . " ) FROM " . $this -> mySQLPrefix . $table ;
2019-02-08 13:29:02 -08:00
if ( ! empty ( $where ))
{
2019-02-18 12:54:43 -08:00
$qry .= " WHERE " . $where ;
2019-02-08 13:29:02 -08:00
}
return $this -> retrieve ( $qry );
}
/**
* Return a sorted list of parent / child tree with an optional where clause .
* @ param string $table Name of table ( without the prefix )
* @ param string $parent Name of the parent field
* @ param string $pid Name of the primary id
* @ param string $where ( Optional ) where condition .
* @ param string $order Name of the order field .
* @ todo Add extra params to each procedure so we only need 2 of them site - wide .
* @ return boolean | integer with the addition of _treesort and _depth fields in the results .
*/
public function selectTree ( $table , $parent , $pid , $order , $where = null )
{
if ( empty ( $table ) || empty ( $parent ) || empty ( $pid ))
{
$this -> mySQLlastErrText = " missing variables in sql->categories() " ;
return false ;
}
$sql = " DROP FUNCTION IF EXISTS `getDepth` ; " ;
$this -> gen ( $sql );
$sql = "
CREATE FUNCTION `getDepth` ( project_id INT ) RETURNS int
BEGIN
DECLARE depth INT ;
SET depth = 1 ;
WHILE project_id > 0 DO
SELECT IFNULL ( " . $parent . " , - 1 )
INTO project_id
FROM ( SELECT " . $parent . " FROM `#".$table."` WHERE " . $pid . " = project_id ) AS t ;
IF project_id > 0 THEN
SET depth = depth + 1 ;
END IF ;
END WHILE ;
RETURN depth ;
END
;
" ;
$this -> gen ( $sql );
$sql = " DROP FUNCTION IF EXISTS `getTreeSort`; " ;
$this -> gen ( $sql );
$sql = "
CREATE FUNCTION getTreeSort ( incid INT )
RETURNS CHAR ( 255 )
BEGIN
SET @ parentstr = CONVERT ( incid , CHAR );
SET @ parent = - 1 ;
label1 : WHILE @ parent != 0 DO
SET @ parent = ( SELECT " . $parent . " FROM `#".$table."` WHERE " . $pid . " = incid );
SET @ order = ( SELECT " . $order . " FROM `#".$table."` WHERE " . $pid . " = incid );
SET @ parentstr = CONCAT ( if ( @ parent = 0 , '' , @ parent ), LPAD ( @ order , 4 , 0 ), @ parentstr );
SET incid = @ parent ;
END WHILE label1 ;
RETURN @ parentstr ;
END
;
" ;
$this -> gen ( $sql );
$qry = " SELECT SQL_CALC_FOUND_ROWS *, getTreeSort( " . $pid . " ) as _treesort, getDepth( " . $pid . " ) as _depth FROM `# " . $table . " ` " ;
if ( $where !== null )
{
$qry .= " WHERE " . $where ;
}
$qry .= " ORDER BY _treesort " ;
return $this -> gen ( $qry );
}
/**
* @ return integer
* @ desc returns total number of queries made so far
* @ access public
*/
2019-02-09 12:31:27 -08:00
public function queryCount ()
2019-02-08 13:29:02 -08:00
{
2019-02-10 16:19:25 -08:00
return $this -> queryCount ;
2019-02-08 13:29:02 -08:00
}
/**
* Multi - language Query Function . Run a query on the same table across all languages .
* @ param $query
* @ param bool $debug
* @ return bool
*/
2019-02-09 12:31:27 -08:00
public function db_Query_all ( $query , $debug = false )
2019-02-08 13:29:02 -08:00
{
$error = " " ;
$query = str_replace ( " # " , $this -> mySQLPrefix , $query );
if ( ! $this -> db_Query ( $query ))
{ // run query on the default language first.
$error .= $query . " failed " ;
}
$table = array ();
$search = array ();
$tmp = explode ( " " , $query ); // split the query
foreach ( $tmp as $val )
{
if ( strpos ( $val , $this -> mySQLPrefix ) !== false ) // search for table names references using the mprefix
{
$table [] = str_replace ( array ( $this -> mySQLPrefix , " ` " ), " " , $val );
$search [] = str_replace ( " ` " , " " , $val );
}
}
if ( empty ( $table ) || empty ( $search ))
{
return false ;
}
// Loop thru relevant language tables and replace each tablename within the query.
2019-02-08 14:06:52 -08:00
if ( $tablist = $this -> hasLanguage ( $table , true ))
2019-02-08 13:29:02 -08:00
{
foreach ( $tablist as $key => $tab )
{
$querylan = $query ;
foreach ( $search as $find )
{
$replace = ( $tab [ $find ] != " " ) ? $tab [ $find ] : $find ;
$querylan = str_replace ( $find , $replace , $querylan );
}
if ( ! $this -> db_Query ( $querylan )) // run query on other language tables.
{
$error .= $querylan . " failed for language " ;
}
if ( $debug ){ echo " <br />** lang= " . $querylan ; }
}
}
return ( $error ) ? false : true ;
}
/**
* Return a list of the field names in a table .
*
* @ param string $table - table name ( no prefix )
* @ param string $prefix - table prefix to apply . If empty , MPREFIX is used .
2019-02-11 16:32:41 -08:00
* @ param boolean $retinfo = false - just returns array of field names . TRUE - returns all field info
* @ return array | boolean - false on error , field list array on success
2019-02-08 13:29:02 -08:00
*/
2019-02-11 16:32:41 -08:00
public function fields ( $table , $prefix = '' , $retinfo = false )
2019-02-08 13:29:02 -08:00
{
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
2019-02-11 14:54:09 -08:00
if ( $prefix == '' )
{
$prefix = $this -> mySQLPrefix ;
}
2019-02-08 13:29:02 -08:00
2019-02-11 14:54:09 -08:00
if ( false === ( $result = $this -> gen ( 'SHOW COLUMNS FROM ' . $prefix . $table )))
2019-02-08 13:29:02 -08:00
{
2019-02-11 14:54:09 -08:00
return false ; // Error return
2019-02-08 13:29:02 -08:00
}
$ret = array ();
if ( $this -> rowCount () > 0 )
{
2019-02-11 14:54:09 -08:00
while ( $row = $this -> fetch ())
2019-02-08 13:29:02 -08:00
{
if ( $retinfo )
{
$ret [ $row [ 'Field' ]] = $row [ 'Field' ];
}
else
{
$ret [] = $row [ 'Field' ];
}
}
}
return $ret ;
}
2019-02-11 10:08:42 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ return int
*/
2019-02-08 13:29:02 -08:00
function columnCount ()
{
/** @var PDOStatement $resource */
$resource = $this -> mySQLresult ;
return $resource -> columnCount ();
}
/**
* Determines if a plugin field ( and key ) exist . OR if fieldid is numeric - return the field name in that position .
*
* @ param string $table - table name ( no prefix )
* @ param string $fieldid - Numeric offset or field / key name
* @ param string $key - PRIMARY | INDEX | UNIQUE - type of key when searching for key name
2019-02-11 16:32:41 -08:00
* @ param boolean $retinfo = false - just returns true | false . TRUE - returns all field info
* @ return array | boolean - false on error , field information on success
2019-02-08 13:29:02 -08:00
*/
2019-02-11 16:32:41 -08:00
function field ( $table , $fieldid = " " , $key = " " , $retinfo = false )
2019-02-08 13:29:02 -08:00
{
2019-02-13 13:54:05 -08:00
2019-02-08 13:29:02 -08:00
$convert = array ( " PRIMARY " => " PRI " , " INDEX " => " MUL " , " UNIQUE " => " UNI " );
$key = ( isset ( $convert [ $key ])) ? $convert [ $key ] : " OFF " ;
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
$result = $this -> gen ( " SHOW COLUMNS FROM " . $this -> mySQLPrefix . $table );
if ( $result && ( $this -> rowCount () > 0 ))
{
$c = 0 ;
while ( $row = $this -> fetch ())
{
if ( is_numeric ( $fieldid ))
{
if ( $c == $fieldid )
{
if ( $retinfo ) return $row ;
return $row [ 'Field' ]; // field number matches.
}
}
else
{ // Check for match of key name - and allow that key might not be used
if (( $fieldid == $row [ 'Field' ]) && (( $key == " OFF " ) || ( $key == $row [ 'Key' ])))
{
if ( $retinfo ) return $row ;
return true ;
}
}
$c ++ ;
}
}
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
/**
* Determines if a table index ( key ) exist .
*
* @ param string $table - table name ( no prefix )
* @ param string $keyname - Name of the key to
* @ param array $fields - OPTIONAL list of fieldnames , the index ( key ) must contain
2019-02-11 16:32:41 -08:00
* @ param boolean $retinfo = false - just returns true | false . TRUE - returns all key info
* @ return array | boolean - false on error , key information on success
2019-02-08 13:29:02 -08:00
*/
2019-02-11 16:32:41 -08:00
function index ( $table , $keyname , $fields = null , $retinfo = false )
2019-02-08 13:29:02 -08:00
{
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
if ( ! empty ( $fields ) && ! is_array ( $fields ))
{
$fields = explode ( ',' , str_replace ( ' ' , '' , $fields ));
}
elseif ( empty ( $fields ))
{
$fields = array ();
}
$check_field = count ( $fields ) > 0 ;
$info = array ();
$result = $this -> gen ( " SHOW INDEX FROM " . $this -> mySQLPrefix . $table );
if ( $result && ( $this -> rowCount () > 0 ))
{
$c = 0 ;
while ( $row = $this -> fetch ())
{
// Check for match of key name - and allow that key might not be used
if ( $keyname == $row [ 'Key_name' ])
{
// a key can contain severeal fields which are returned as 1 row per field
if ( ! $check_field )
{ // Check only for keyname
$info [] = $row ;
}
elseif ( $check_field && in_array ( $row [ 'Column_name' ], $fields ))
{ // Check also for fieldnames
$info [] = $row ;
}
$c ++ ;
}
}
if ( count ( $info ) > 0 )
{
// Kex does not consist of all keys
if ( $check_field && $c != count ( $fields )) return false ;
// Return full information
if ( $retinfo ) return $info ;
// Return only if index was found
return true ;
}
}
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
2019-02-16 12:40:25 -08:00
/**
* @ param $table
* @ return array field name => key name
*/
private function _getUnique ( $table )
{
$unique = array ();
$result = $this -> retrieve ( " SHOW INDEXES FROM # " . $table , true );
foreach ( $result as $row )
{
$notUnique = ( int ) $row [ 'Non_unique' ];
if ( ! $notUnique )
{
$field = $row [ 'Column_name' ];
$unique [ $field ] = $row [ 'Key_name' ];
}
}
return $unique ;
}
2019-02-08 13:29:02 -08:00
/**
* A pointer to mysql_real_escape_string () - see http :// www . php . net / mysql_real_escape_string
*
* @ param string $data
* @ return string
*/
function escape ( $data , $strip = true )
{
2020-12-22 14:48:28 -08:00
/*
2019-02-08 13:29:02 -08:00
if ( $strip )
{
$data = strip_if_magic ( $data );
2020-12-22 14:48:28 -08:00
} */
2019-02-08 13:29:02 -08:00
2019-02-13 13:54:05 -08:00
$this -> _getMySQLaccess ();
2019-02-08 13:29:02 -08:00
return $data ;
}
/**
* Verify whether a table exists , without causing an error
*
* @ param string $table Table name without the prefix
* @ param string $language ( optional ) leave blank to search for a regular table , or language - name to search for a language table .
* @ example $sql -> isTable ( 'news' , 'Spanish' );
* @ return boolean TRUE if exists
*
* NOTES : Slower ( 28 ms ) than " SELECT 1 FROM " ( 4 - 5 ms ), but doesn ' t produce MySQL errors .
* Multiple checks on a single page will only use 1 query . ie . faster on multiple calls .
*/
public function isTable ( $table , $language = '' )
{
2019-02-13 13:54:05 -08:00
2019-02-08 13:29:02 -08:00
$table = strtolower ( $table ); // precaution for multilanguage
if ( ! empty ( $language )) //ie. is it a language table?
{
$sitelanguage = $this -> getConfig () -> get ( 'sitelanguage' );
if ( $language == $sitelanguage )
{
return false ;
}
if ( ! isset ( $this -> mySQLtableListLanguage [ $language ]))
{
2019-02-11 14:54:09 -08:00
$this -> mySQLtableListLanguage = $this -> _getTableList ( $language );
2019-02-08 13:29:02 -08:00
}
return in_array ( 'lan_' . strtolower ( $language ) . " _ " . $table , $this -> mySQLtableListLanguage [ $language ]);
}
else // regular search
{
if ( ! $this -> mySQLtableList )
{
2019-02-11 14:54:09 -08:00
$this -> mySQLtableList = $this -> _getTableList ();
2019-02-08 13:29:02 -08:00
}
return in_array ( $table , $this -> mySQLtableList );
}
}
/**
* Check if a database table is empty or not .
* @ param $table
* @ return bool
*/
2019-02-11 12:22:10 -08:00
function isEmpty ( $table = null )
2019-02-08 13:29:02 -08:00
{
if ( empty ( $table ))
{
return false ;
}
$result = $this -> gen ( " SELECT NULL FROM " . $this -> mySQLPrefix . $table . " LIMIT 1 " );
if ( $result === 0 )
{
return true ;
}
return false ;
}
/**
* Populate mySQLtableList and mySQLtableListLanguage
* TODO - better runtime cache - use e107 :: getRegistry () && e107 :: setRegistry ()
* @ return array
*/
2019-02-11 14:54:09 -08:00
private function _getTableList ( $language = '' )
2019-02-08 13:29:02 -08:00
{
2019-02-11 14:54:09 -08:00
2019-05-28 10:49:32 -07:00
$database = ! empty ( $this -> mySQLdefaultdb ) ? " FROM ` " . $this -> mySQLdefaultdb . " ` " : " " ;
2019-02-11 14:54:09 -08:00
$prefix = $this -> mySQLPrefix ;
if ( strpos ( $prefix , " . " ) !== false ) // eg. `my_database`.$prefix
{
$tmp = explode ( " . " , $prefix );
$prefix = $tmp [ 1 ];
}
2019-02-08 13:29:02 -08:00
if ( $language )
{
if ( ! isset ( $this -> mySQLtableListLanguage [ $language ]))
{
$table = array ();
2019-02-11 14:54:09 -08:00
if ( $res = $this -> db_Query ( " SHOW TABLES " . $database . " LIKE ' " . $prefix . " lan_ " . strtolower ( $language ) . " %' " ))
2019-02-08 13:29:02 -08:00
{
while ( $rows = $this -> fetch ( 'num' ))
{
2019-02-11 14:54:09 -08:00
$table [] = str_replace ( $prefix , " " , $rows [ 0 ]);
2019-02-08 13:29:02 -08:00
}
}
2021-01-24 17:00:02 -08:00
return array ( $language => $table );
2019-02-08 13:29:02 -08:00
}
else
{
return $this -> mySQLtableListLanguage [ $language ];
}
}
if ( ! $this -> mySQLtableList )
{
$table = array ();
2019-02-11 14:54:09 -08:00
if ( $res = $this -> db_Query ( " SHOW TABLES " . $database . " LIKE ' " . $prefix . " %' " ))
2019-02-08 13:29:02 -08:00
{
2019-02-11 14:54:09 -08:00
$length = strlen ( $prefix );
2019-02-08 13:29:02 -08:00
while ( $rows = $this -> fetch ( 'num' ))
{
$table [] = substr ( $rows [ 0 ], $length );
}
}
return $table ;
}
else
{
return $this -> mySQLtableList ;
}
}
2019-02-08 14:06:52 -08:00
2019-02-09 12:31:27 -08:00
/**
*
*/
public function resetTableList ()
2019-02-08 13:29:02 -08:00
{
$this -> mySQLtableList = array ();
$this -> mySQLtableListLanguage = array ();
}
2019-02-08 14:06:52 -08:00
2019-02-08 13:29:02 -08:00
/**
* Return a filtered list of DB tables .
* @ param object $mode [ optional ] all | lan | nolan | nologs
* @ return array
*/
public function tables ( $mode = 'all' )
{
if ( ! $this -> mySQLtableList )
{
2019-02-11 14:54:09 -08:00
$this -> mySQLtableList = $this -> _getTableList ();
2019-02-08 13:29:02 -08:00
}
if ( $mode == 'nologs' )
{
$ret = array ();
foreach ( $this -> mySQLtableList as $table )
{
if ( substr ( $table , - 4 ) != '_log' && $table != 'download_requests' )
{
$ret [] = $table ;
}
}
return $ret ;
}
if ( $mode == 'all' )
{
return $this -> mySQLtableList ;
}
if ( $mode == 'lan' || $mode == 'nolan' )
{
$nolan = array ();
$lan = array ();
foreach ( $this -> mySQLtableList as $tab )
{
2020-12-20 11:50:10 -08:00
if ( strpos ( $tab , 'lan_' ) === 0 )
2019-02-08 13:29:02 -08:00
{
2020-12-20 11:50:10 -08:00
$lan [] = $tab ;
2019-02-08 13:29:02 -08:00
}
else
{
2020-12-20 11:50:10 -08:00
$nolan [] = $tab ;
2019-02-08 13:29:02 -08:00
}
}
return ( $mode == 'lan' ) ? $lan : $nolan ;
}
2019-02-10 16:19:25 -08:00
return array ();
2019-02-08 13:29:02 -08:00
}
/**
* Duplicate a Table Row in a table .
*/
2019-02-11 14:54:09 -08:00
function copyRow ( $table , $fields = '*' , $args = '' )
2019-02-08 13:29:02 -08:00
{
if ( ! $table || ! $args )
{
return false ;
}
2019-12-27 21:54:11 +01:00
for ( $retries = 0 ; $retries < 3 ; $retries ++ ) {
2019-12-28 10:48:16 +01:00
list ( $fieldList , $fieldList2 ) = $this -> generateCopyRowFieldLists ( $table , $fields );
2019-02-16 12:40:25 -08:00
2019-12-27 21:54:11 +01:00
if ( empty ( $fieldList )) {
$this -> mysqlLastErrText = " copyRow \$ fields list was empty " ;
return false ;
}
2019-02-08 13:29:02 -08:00
2019-12-27 21:54:11 +01:00
$beforeLastInsertId = $this -> lastInsertId ();
2019-12-28 10:48:16 +01:00
$query = " INSERT INTO " . $this -> mySQLPrefix . $table .
2019-12-27 21:54:11 +01:00
" ( " . $fieldList . " ) SELECT " .
$fieldList2 .
" FROM " . $this -> mySQLPrefix . $table .
2019-12-28 10:48:16 +01:00
" WHERE " . $args ;
$id = $this -> gen ( $query );
2019-12-27 21:54:11 +01:00
$lastInsertId = $this -> lastInsertId ();
if ( $beforeLastInsertId !== $lastInsertId ) break ;
2019-02-11 14:54:09 -08:00
}
2019-02-08 13:29:02 -08:00
return ( $id && $lastInsertId ) ? $lastInsertId : false ;
2019-12-28 10:48:16 +01:00
}
/**
* Determine before and after fields for a table
* @ param $table string Table name , without the prefix
* @ param $fields string Field list in query format ( i . e . separated by commas ) or all of them ( " * " )
* @ return array Index 0 is before and index 1 is after
*/
private function generateCopyRowFieldLists ( $table , $fields )
{
if ( $fields !== '*' ) return array ( $fields , $fields );
$fieldList = $this -> db_FieldList ( $table );
$unique = $this -> _getUnique ( $table );
$flds = array ();
// randomize fields that must be unique.
foreach ( $fieldList as $fld ) {
if ( isset ( $unique [ $fld ])) {
$flds [] = $unique [ $fld ] === 'PRIMARY' ? 0 :
" 'rand- " . e107 :: getUserSession () -> generateRandomString ( '***********' ) . " ' " ;
continue ;
}
$flds [] = $fld ;
}
2019-02-08 13:29:02 -08:00
2019-12-28 10:48:16 +01:00
$fieldList = implode ( " , " , $fieldList );
$fieldList2 = implode ( " , " , $flds );
return array ( $fieldList , $fieldList2 );
2019-02-08 13:29:02 -08:00
}
2019-02-09 12:31:27 -08:00
/**
* @ param string $oldtable
* @ param string $newtable
* @ param bool $drop
* @ param bool $data
2022-04-04 10:54:24 -07:00
* @ return bool | int
2019-02-09 12:31:27 -08:00
*/
2019-02-11 10:08:42 -08:00
public function copyTable ( $oldtable , $newtable , $drop = false , $data = false )
2019-02-08 13:29:02 -08:00
{
$old = $this -> mySQLPrefix . strtolower ( $oldtable );
$new = $this -> mySQLPrefix . strtolower ( $newtable );
if ( $drop )
{
$this -> gen ( " DROP TABLE IF EXISTS { $new } " );
}
//Get $old table structure
$this -> gen ( 'SET SQL_QUOTE_SHOW_CREATE = 1' );
$qry = " SHOW CREATE TABLE { $old } " ;
if ( $this -> gen ( $qry ))
{
$row = $this -> fetch ( 'num' );
$qry = $row [ 1 ];
// $qry = str_replace($old, $new, $qry);
2020-12-17 13:13:29 -08:00
$qry = preg_replace ( " #CREATE \ sTABLE \ s`? " . $old . " `? \ s# " , " CREATE TABLE { $new } " , $qry , 1 ); // More selective search
2019-02-08 13:29:02 -08:00
}
else
{
2019-02-11 16:32:41 -08:00
return false ;
2019-02-08 13:29:02 -08:00
}
if ( ! $this -> isTable ( $newtable ))
{
$result = $this -> db_Query ( $qry );
}
if ( $data ) //We need to copy the data too
{
$qry = " INSERT INTO { $new } SELECT * FROM { $old } " ;
$result = $this -> gen ( $qry );
}
return $result ;
}
2019-02-11 16:19:07 -08:00
/**
* Drop / delete table and all it ' s data
* @ param string $table name without the prefix
* @ return bool | int
*/
public function dropTable ( $table )
{
$name = $this -> mySQLPrefix . strtolower ( $table );
return $this -> gen ( " DROP TABLE IF EXISTS " . $name );
}
2019-02-08 13:29:02 -08:00
/**
* Dump MySQL Table ( s ) to a file in the Backup folder .
* @ param $table string - name without the prefix or '*' for all
* @ param $file string - optional file name . or leave blank to generate .
* @ param $options - additional preferences .
* @ return string | bool backup file path .
*/
function backup ( $table = '*' , $file = '' , $options = null )
{
/*
if ( $this -> pdo === false )
{
$this -> mysqlLastErrText = " PDO is required to use the mysql backup() method " ;
return false ;
} */
// $dbtable = $this->mySQLdefaultdb;
$fileName = ( $table == '*' ) ? str_replace ( " " , " _ " , SITENAME ) : $table ;
2020-12-20 11:50:10 -08:00
$fileName = preg_replace ( '/[\W]/' , " " , $fileName );
2019-02-08 13:29:02 -08:00
$backupFile = ( $file ) ? e_BACKUP . $file : e_BACKUP . strtolower ( $fileName ) . " _ " . $this -> mySQLPrefix . date ( " Y-m-d-H-i-s " ) . " .sql " ;
if ( $table === '*' )
{
$nolog = vartrue ( $options [ 'nologs' ]) ? 'nologs' : 'all' ;
$tableList = $this -> tables ( $nolog );
}
else
{
$tableList = explode ( " , " , $table );
}
if ( ! empty ( $options [ 'gzip' ]))
{
$backupFile .= '.gz' ;
}
2020-02-29 11:56:05 -08:00
// include_once(dirname(__FILE__) . '/Ifsnop/Mysqldump/Mysqldump.php');
2019-02-08 13:29:02 -08:00
$dumpSettings = array (
'compress' => ! empty ( $options [ 'gzip' ]) ? Ifsnop\Mysqldump\Mysqldump :: GZIP : Ifsnop\Mysqldump\Mysqldump :: NONE ,
'include-tables' => array (),
'no-data' => false ,
'add-drop-table' => ! empty ( $options [ 'droptable' ]) ? true : false ,
'single-transaction' => true ,
'lock-tables' => true ,
'add-locks' => true ,
'extended-insert' => true ,
'disable-foreign-keys-check' => true ,
'skip-triggers' => false ,
'add-drop-trigger' => true ,
'databases' => false ,
'add-drop-database' => false ,
'hex-blob' => true ,
'reset-auto-increment' => false ,
);
foreach ( $tableList as $tab )
{
2020-08-04 09:28:48 -05:00
$dumpSettings [ 'include-tables' ][] = $this -> mySQLPrefix . trim ( $tab );
2019-02-08 13:29:02 -08:00
}
2019-02-18 13:08:46 -08:00
try
{
2020-08-04 09:28:48 -05:00
$dump = new Ifsnop\Mysqldump\Mysqldump ( " mysql:host= { $this -> mySQLserver } ;port= { $this -> mySQLport } ;dbname= { $this -> mySQLdefaultdb } " , $this -> mySQLuser , $this -> mySQLpassword , $dumpSettings );
2019-02-08 13:29:02 -08:00
$dump -> start ( $backupFile );
return $backupFile ;
}
catch ( \Exception $e )
{
$this -> mysqlLastErrText = 'mysqldump-php error: ' . $e -> getMessage ();
return false ;
}
}
/**
* @ return string relating to error ( empty string if no error )
* @ param string $from
* @ desc Calling method from within this class
* @ access private
*/
function dbError ( $from )
{
$this -> mySQLerror = true ;
2019-02-09 12:31:27 -08:00
if ( $this -> mySQLlastErrNum === 0 )
2019-02-08 13:29:02 -08:00
{
return null ;
}
2019-02-09 12:31:27 -08:00
return $from . " :: " . $this -> mySQLlastErrText ;
2019-02-08 13:29:02 -08:00
}
// Return error number for last operation
2022-04-04 10:54:24 -07:00
/**
* @ return int
*/
2019-02-08 13:29:02 -08:00
function getLastErrorNumber ()
{
return $this -> mySQLlastErrNum ; // Number of last error
}
// Return error text for last operation
2022-04-04 10:54:24 -07:00
/**
* @ return string
*/
2019-02-08 13:29:02 -08:00
function getLastErrorText ()
{
return $this -> mySQLlastErrText ; // Text of last error (empty string if no error)
}
2022-04-04 10:54:24 -07:00
/**
* @ return void
*/
2019-02-08 13:29:02 -08:00
function resetLastError ()
{
$this -> mySQLlastErrNum = 0 ;
$this -> mySQLlastErrText = '' ;
}
2019-02-11 16:19:07 -08:00
/**
* Returns the last database query used .
* @ return string
*/
public function getLastQuery ()
2019-02-08 13:29:02 -08:00
{
return $this -> mySQLlastQuery ;
}
2019-02-11 16:19:07 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ return void
*/
2019-02-08 13:29:02 -08:00
private function setSQLMode ()
{
$this -> db_Query ( " SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION'; " );
2021-09-04 15:06:19 +02:00
/**
* Disable PHP 8.1 PDO result set typing casting for consistency with PHP 5.6 through 8.0
* @ link https :// github . com / php / php - src / blob / 4025 cf2875f895e9f7193cebb1c8efa4290d052e / UPGRADING #L130-L134
*/
$this -> mySQLaccess -> setAttribute ( PDO :: ATTR_STRINGIFY_FETCHES , true );
2019-02-08 13:29:02 -08:00
}
/**
2019-02-09 12:31:27 -08:00
* Set Database charset to utf8
2019-02-08 13:29:02 -08:00
*
2019-02-09 12:31:27 -08:00
* @ access private
2019-02-08 13:29:02 -08:00
*/
2019-02-09 12:31:27 -08:00
public function setCharset ( $charset = 'utf8' )
2019-02-08 13:29:02 -08:00
{
2019-02-09 12:31:27 -08:00
$this -> db_Query ( " SET NAMES ` $charset ` " );
2019-02-08 13:29:02 -08:00
$this -> mySQLcharset = $charset ;
}
2022-04-04 10:54:24 -07:00
/**
* @ return mixed
*/
2019-02-09 12:31:27 -08:00
public function getCharset ()
{
return $this -> mySQLcharset ;
}
2019-02-08 13:29:02 -08:00
2019-02-11 16:19:07 -08:00
/**
* Set the database language
* @ param string $lang French , German etc .
*/
public function setLanguage ( $lang )
{
$this -> mySQLlanguage = $lang ;
}
/**
* Get the current database language . eg . English , French etc .
* @ return string
*/
public function getLanguage ()
{
return $this -> mySQLlanguage ;
}
2019-02-08 13:29:02 -08:00
/**
* Get the _FIELD_DEFS and _NOTNULL definitions for a table
*< code >
* The information is sought in a specific order :
* a ) In our internal cache
* b ) in the directory e_CACHE_DBDIR - file name $tableName . php
* c ) An override file for a core or plugin - related table . If found , the information is copied to the cache directory
* For core overrides , e_ADMIN . 'core_sql/db_field_defs.php' is searched
* For plugins , $pref [ 'e_sql_list' ] is used as a search list - any file 'db_field_defs.php' in the plugin directory is earched
* d ) The table structure is read from the DB , and a definition created :
* AUTOINCREMENT fields - ignored ( or integer )
* integer type fields - 'int' processing
* character / string type fields - todb processing
* fields which are 'NOT NULL' but have no default are added to the '_NOTNULL' list
*</ code >
* @ param string $tableName - table name , without any prefixes ( language or general )
2019-02-11 16:32:41 -08:00
* @ return boolean | array - false if not found / not to be used . Array of field names and processing types and null overrides if found
2019-02-08 13:29:02 -08:00
*/
public function getFieldDefs ( $tableName )
{
if ( ! isset ( $this -> dbFieldDefs [ $tableName ]))
{
if ( is_readable ( e_CACHE_DB . $tableName . '.php' ))
{
2021-09-04 15:06:19 +02:00
$temp = file_get_contents ( e_CACHE_DB . $tableName . '.php' );
2019-02-11 16:32:41 -08:00
if ( $temp !== false )
2019-02-08 13:29:02 -08:00
{
$typeDefs = e107 :: unserialize ( $temp );
unset ( $temp );
$this -> dbFieldDefs [ $tableName ] = $typeDefs ;
}
}
else
{ // Need to try and find a table definition
$searchArray = array ( e_CORE . 'sql/db_field_defs.php' );
2019-02-08 14:06:52 -08:00
// e107::getPref() shouldn't be used inside db handler! See hasLanguage() comments
2019-02-08 13:29:02 -08:00
$sqlFiles = ( array ) $this -> getConfig () -> get ( 'e_sql_list' , array ()); // kill any PHP notices
foreach ( $sqlFiles as $p => $f )
{
$searchArray [] = e_PLUGIN . $p . '/db_field_defs.php' ;
}
unset ( $sqlFiles );
2019-02-11 16:32:41 -08:00
$found = false ;
2019-02-08 13:29:02 -08:00
foreach ( $searchArray as $defFile )
{
//echo "Check: {$defFile}, {$tableName}<br />";
if ( $this -> loadTableDef ( $defFile , $tableName ))
{
$found = TRUE ;
break ;
}
}
if ( ! $found )
{ // Need to read table structure from DB and create the file
$this -> makeTableDef ( $tableName );
}
}
}
return $this -> dbFieldDefs [ $tableName ];
}
/**
* Search the specified file for a field type definition of the specified table .
* If found , generate and save a cache file in the e_CACHE_DB directory ,
2019-02-11 16:32:41 -08:00
* Always also update $this -> dbFieldDefs [ $tableName ] - false if not found , data if found
2019-02-08 13:29:02 -08:00
* @ param string $defFile - file name , including path
* @ param string $tableName - name of table sought
2019-02-11 16:32:41 -08:00
* @ return boolean TRUE on success , false on not found ( some errors intentionally ignored )
2019-02-08 13:29:02 -08:00
*/
protected function loadTableDef ( $defFile , $tableName )
{
$result = false ;
if ( is_readable ( $defFile ))
{
// Read the file using the array handler routines
2019-02-11 16:32:41 -08:00
// File structure is a nested array - first level is table name, second level is either false (for do nothing) or array(_FIELD_DEFS => array(), _NOTNULL => array())
2019-02-08 13:29:02 -08:00
$temp = file_get_contents ( $defFile );
// Strip any comments (only /*...*/ supported)
2020-12-20 11:50:10 -08:00
$temp = preg_replace ( " # \ / \ *.*? \ * \ /#ms " , '' , $temp );
2019-02-08 13:29:02 -08:00
//echo "Check: {$defFile}, {$tableName}<br />";
if ( $temp !== false )
{
// $array = e107::getArrayStorage();
$typeDefs = e107 :: unserialize ( $temp );
unset ( $temp );
if ( isset ( $typeDefs [ $tableName ]))
{
$this -> dbFieldDefs [ $tableName ] = $typeDefs [ $tableName ];
$fileData = e107 :: serialize ( $typeDefs [ $tableName ], false );
if ( false === file_put_contents ( e_CACHE_DB . $tableName . '.php' , $fileData ))
2019-02-11 16:32:41 -08:00
{ // Could do something with error - but mustn't return false - would trigger auto-generated structure
2019-02-08 13:29:02 -08:00
}
$result = true ;
}
}
}
if ( ! $result )
{
$this -> dbFieldDefs [ $tableName ] = false ;
}
return $result ;
}
/**
* Creates a field type definition from the structure of the table in the DB
* Generate and save a cache file in the e_CACHE_DB directory ,
2019-02-11 16:32:41 -08:00
* Also update $this -> dbFieldDefs [ $tableName ] - false if error , data if found
2019-02-08 13:29:02 -08:00
* @ param string $tableName - name of table sought
2019-06-03 15:27:36 -07:00
* @ return array | boolean array on success , false on not found ( some errors intentionally ignored )
2019-02-08 13:29:02 -08:00
*/
protected function makeTableDef ( $tableName )
{
require_once ( e_HANDLER . 'db_table_admin_class.php' );
$dbAdm = new db_table_admin ();
$baseStruct = $dbAdm -> get_current_table ( $tableName );
2020-01-18 18:52:20 +01:00
$baseStruct = isset ( $baseStruct [ 0 ][ 2 ]) ? $baseStruct [ 0 ][ 2 ] : null ;
$fieldDefs = $dbAdm -> parse_field_defs ( $baseStruct ); // Required definitions
2020-01-17 17:24:06 +01:00
if ( ! $fieldDefs ) return false ;
2019-02-08 13:29:02 -08:00
2020-11-29 14:05:14 -08:00
$outDefs = $dbAdm -> make_field_types ( $fieldDefs );
2019-02-08 13:29:02 -08:00
$this -> dbFieldDefs [ $tableName ] = $outDefs ;
$toSave = e107 :: serialize ( $outDefs , false ); // 2nd parameter to TRUE if needs to be written to DB
2019-02-11 16:32:41 -08:00
if ( false === file_put_contents ( e_CACHE_DB . $tableName . '.php' , $toSave ))
{ // Could do something with error - but mustn't return false - would trigger auto-generated structure
2019-02-08 13:29:02 -08:00
$mes = e107 :: getMessage ();
$mes -> addDebug ( " Error writing file: " . e_CACHE_DB . $tableName . '.php' ); //Fix for during v1.x -> 2.x upgrade.
// echo "Error writing file: ".e_CACHE_DB.$tableName.'.php'.'<br />';
}
2019-06-03 15:27:36 -07:00
return empty ( $outDefs ) ? false : $outDefs ;
2019-02-08 13:29:02 -08:00
}
/**
* In case e_db_mysql :: $mySQLaccess is not set , set it .
*
* Uses the global variable $db_ConnectionID if available .
*
* When the global variable has been unset like in https :// github . com / e107inc / e107 - test / issues / 6 ,
* use the " mySQLaccess " from the default e_db_mysql instance singleton .
*/
2019-02-13 13:54:05 -08:00
private function _getMySQLaccess ()
2019-02-08 13:29:02 -08:00
{
2019-02-13 13:54:05 -08:00
if ( ! $this -> mySQLaccess )
{
2020-05-26 18:55:47 -05:00
$success = $this -> connect ( $this -> mySQLserver , $this -> mySQLuser , $this -> mySQLpassword );
if ( $success ) $success = $this -> database ( $this -> mySQLdefaultdb , $this -> mySQLPrefix );
if ( ! $success ) throw new PDOException ( $this -> mySQLlastErrText );
2019-02-08 13:29:02 -08:00
}
}
2019-02-18 13:08:46 -08:00
2019-02-08 13:29:02 -08:00
}
2019-06-03 15:27:36 -07:00
/**
* Backwards compatibility
*/
class db extends e_db_pdo
{
2019-02-08 13:29:02 -08:00
2019-06-03 15:27:36 -07:00
}