Version 4.2.0

This commit is contained in:
Neo committed 2025-12-19 05:44:59 -08:00
1 parent 0dc2aee5ed
commit 96997ddd8e
2074 files changed
+125454 -55780

No files matched your search

+4 -5
View File
@@ -1,12 +1,11 @@
<?php
/**
* @brief Binding Class for Prepared Statements
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\Db;
+19 -20
View File
@@ -1,12 +1,11 @@
<?php
/**
* @brief Database Class
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS;
@@ -937,7 +936,7 @@ class _Db extends \mysqli
foreach ( $joins as $join )
{
$type = ( isset( $join['type'] ) and in_array( \strtoupper( $join['type'] ), array( 'LEFT', 'INNER', 'RIGHT' ) ) ) ? \strtoupper( $join['type'] ) : 'LEFT';
$type = ( isset( $join['type'] ) and in_array( mb_strtoupper( $join['type'] ), array( 'LEFT', 'INNER', 'RIGHT' ) ) ) ? mb_strtoupper( $join['type'] ) : 'LEFT';
$_table = is_array( $join['from'] ) ? "`{$this->prefix}{$join['from'][0]}` {$this->prefix}{$join['from'][1]}" : "`{$this->prefix}{$join['from']}` {$join['from']}";
$on = $this->compileWhereClause( $join['where'] );
@@ -1224,22 +1223,22 @@ class _Db extends \mysqli
public function compileColumnDefinition( $data )
{
/* Specify name and type */
$definition = "`{$data['name']}` " . \strtoupper( $data['type'] ) . ' ';
$definition = "`{$data['name']}` " . mb_strtoupper( $data['type'] ) . ' ';
/* Some types specify length */
if(
in_array( \strtoupper( $data['type'] ), array( 'VARCHAR', 'VARBINARY' ) )
in_array( mb_strtoupper( $data['type'] ), array( 'VARCHAR', 'VARBINARY' ) )
or
(
isset( $data['length'] ) and $data['length']
and
in_array( \strtoupper( $data['type'] ), array( 'BIT', 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'REAL', 'DOUBLE', 'FLOAT', 'DECIMAL', 'NUMERIC', 'CHAR', 'BINARY' ) )
in_array( mb_strtoupper( $data['type'] ), array( 'BIT', 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'REAL', 'DOUBLE', 'FLOAT', 'DECIMAL', 'NUMERIC', 'CHAR', 'BINARY' ) )
)
) {
$definition .= "({$data['length']}";
/* And some of those specify decimals (which may or may not be optional) */
if( in_array( \strtoupper( $data['type'] ), array( 'REAL', 'DOUBLE', 'FLOAT' ) ) or ( in_array( \strtoupper( $data['type'] ), array( 'DECIMAL', 'NUMERIC' ) ) and isset( $data['decimals'] ) ) )
if( in_array( mb_strtoupper( $data['type'] ), array( 'REAL', 'DOUBLE', 'FLOAT' ) ) or ( in_array( mb_strtoupper( $data['type'] ), array( 'DECIMAL', 'NUMERIC' ) ) and isset( $data['decimals'] ) ) )
{
$definition .= ',' . $data['decimals'];
}
@@ -1248,7 +1247,7 @@ class _Db extends \mysqli
}
/* Numeric types can be UNSIGNED and ZEROFILL */
if( in_array( \strtoupper( $data['type'] ), array( 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'REAL', 'DOUBLE', 'FLOAT', 'DECIMAL', 'NUMERIC' ) ) )
if( in_array( mb_strtoupper( $data['type'] ), array( 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'REAL', 'DOUBLE', 'FLOAT', 'DECIMAL', 'NUMERIC' ) ) )
{
if( isset( $data['unsigned'] ) and $data['unsigned'] === TRUE )
{
@@ -1261,7 +1260,7 @@ class _Db extends \mysqli
}
/* ENUM and SETs have values */
if( in_array( \strtoupper( $data['type'] ), array( 'ENUM', 'SET' ) ) )
if( in_array( mb_strtoupper( $data['type'] ), array( 'ENUM', 'SET' ) ) )
{
$values = array();
foreach ( $data['values'] as $v )
@@ -1273,13 +1272,13 @@ class _Db extends \mysqli
}
/* Some types can be binary or not */
if( isset( $data['binary'] ) and $data['binary'] === TRUE and in_array( \strtoupper( $data['type'] ), array( 'CHAR', 'VARCHAR', 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT' ) ) )
if( isset( $data['binary'] ) and $data['binary'] === TRUE and in_array( mb_strtoupper( $data['type'] ), array( 'CHAR', 'VARCHAR', 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT' ) ) )
{
$definition .= 'BINARY ';
}
/* Text types specify a character set and collation */
if( in_array( \strtoupper( $data['type'] ), array( 'CHAR', 'VARCHAR', 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'ENUM', 'SET' ) ) )
if( in_array( mb_strtoupper( $data['type'] ), array( 'CHAR', 'VARCHAR', 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'ENUM', 'SET' ) ) )
{
$definition .= "CHARACTER SET {$this->charset} COLLATE {$this->collation} ";
}
@@ -1302,7 +1301,7 @@ class _Db extends \mysqli
else
{
/* Default value */
if( isset( $data['default'] ) and !in_array( \strtoupper( $data['type'] ), array( 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'BLOB', 'MEDIUMBLOB', 'BIGBLOB', 'LONGBLOB' ) ) )
if( isset( $data['default'] ) and !in_array( mb_strtoupper( $data['type'] ), array( 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'BLOB', 'MEDIUMBLOB', 'BIGBLOB', 'LONGBLOB' ) ) )
{
if( $data['type'] == 'BIT' )
{
@@ -1310,7 +1309,7 @@ class _Db extends \mysqli
}
else
{
$defaultValue = in_array( \strtoupper( $data['type'] ), array( 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'REAL', 'DOUBLE', 'FLOAT', 'DECIMAL', 'NUMERIC' ) ) ? floatval( $data['default'] ) : ( ! in_array( $data['default'], array( 'CURRENT_TIMESTAMP', 'BIT' ) ) ? '\'' . $this->escape_string( $data['default'] ) . '\'' : $data['default'] );
$defaultValue = in_array( mb_strtoupper( $data['type'] ), array( 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'REAL', 'DOUBLE', 'FLOAT', 'DECIMAL', 'NUMERIC' ) ) ? floatval( $data['default'] ) : ( ! in_array( $data['default'], array( 'CURRENT_TIMESTAMP', 'BIT' ) ) ? '\'' . $this->escape_string( $data['default'] ) . '\'' : $data['default'] );
$definition .= "DEFAULT {$defaultValue} ";
}
}
@@ -1502,7 +1501,7 @@ class _Db extends \mysqli
{
/* If this is a fulltext index, set engine to myisam but only if engine is something besides innodb or myisam OR the mysql version is less than 5.6 - in
this case we assume the default engine is most likely either myisam or innodb */
if( !$this->_innoDbSupportsFulltextIndexes() OR ( isset( $data['engine'] ) AND !in_array( \strtoupper( $data['engine'] ), array( 'INNODB', 'MYISAM' ) ) ) )
if( !$this->_innoDbSupportsFulltextIndexes() OR ( isset( $data['engine'] ) AND !in_array( mb_strtoupper( $data['engine'] ), array( 'INNODB', 'MYISAM' ) ) ) )
{
$data['engine'] = 'MYISAM';
}
@@ -1607,7 +1606,7 @@ class _Db extends \mysqli
while( $engine = $result->fetch_assoc() )
{
if( \strtoupper( $engine['Support'] ) == 'DEFAULT' )
if( mb_strtoupper( $engine['Support'] ) == 'DEFAULT' )
{
return $engine['Engine'];
}
@@ -2214,7 +2213,7 @@ class _Db extends \mysqli
/* Prevent conflicts when schema says DEFAULT '0' but it is DEFAULT 0 and an INT type column as this is always set as a 0 anyway */
foreach( $definition['columns'] as $name => $data )
{
if ( in_array( \strtoupper( $data['type'] ), array_keys( static::$dataTypes['database_column_type_numeric'] ) ) and ( ! in_array( \strtoupper( $data['type'] ), array( 'DECIMAL', 'FLOAT', 'BIT' ) ) ) and is_numeric( $data['default'] ) )
if ( in_array( mb_strtoupper( $data['type'] ), array_keys( static::$dataTypes['database_column_type_numeric'] ) ) and ( ! in_array( mb_strtoupper( $data['type'] ), array( 'DECIMAL', 'FLOAT', 'BIT' ) ) ) and is_numeric( $data['default'] ) )
{
$definition['columns'][ $name ]['default'] = intval( $data['default'] );
}
@@ -2250,7 +2249,7 @@ class _Db extends \mysqli
{
/* If this is a fulltext index, set engine to myisam but only if engine is something besides innodb or myisam OR the mysql version is less than 5.6 - in
this case we assume the default engine is most likely either myisam or innodb */
if( !$this->_innoDbSupportsFulltextIndexes() OR ( isset( $definition['engine'] ) AND !in_array( \strtoupper( $definition['engine'] ), array( 'INNODB', 'MYISAM' ) ) ) )
if( !$this->_innoDbSupportsFulltextIndexes() OR ( isset( $definition['engine'] ) AND !in_array( mb_strtoupper( $definition['engine'] ), array( 'INNODB', 'MYISAM' ) ) ) )
{
$definition['engine'] = 'myisam';
}
+10 -5
View File
@@ -1,12 +1,11 @@
<?php
/**
* @brief Exception class for database errors
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\Db;
@@ -72,6 +71,12 @@ class _Exception extends \RuntimeException
return TRUE;
}
/* Our custom error code */
if ( $this->getCode() === -1 )
{
return TRUE;
}
return FALSE;
}
+27 -11
View File
@@ -1,12 +1,11 @@
<?php
/**
* @brief Database SELECT Statement
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 28 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\Db;
@@ -118,11 +117,11 @@ class _Select implements \Iterator, \Countable
{
case 'INNER':
case 'CROSS':
$query .= 'INNER JOIN ';
$query .= ' INNER JOIN ';
break;
case 'STRAIGHT_JOIN':
$query .= 'STRAIGHT_JOIN';
$query .= ' STRAIGHT_JOIN';
if ( $using )
{
throw new \InvalidArgumentException; // USING cannot be used with STRAIGHT_JOIN
@@ -131,7 +130,7 @@ class _Select implements \Iterator, \Countable
case 'LEFT':
case 'RIGHT':
$query .= $type . ' JOIN';
$query .= ' ' . $type . ' JOIN';
$joinConditionIsOptional = FALSE;
break;
case 'JOIN':
@@ -197,7 +196,17 @@ class _Select implements \Iterator, \Countable
{
throw new \InvalidArgumentException;
}
/* If we are joining on a sub-query already, remove it temporarily to ensure our regex below works correctly */
$subqueries = array();
while( preg_match( "/JOIN\( SELECT(.+?)\) AS .+? ON .+?/", $this->query, $matches ) )
{
$key = md5( $matches[0] );
$subqueries[ $key ] = $matches[0];
$this->query = str_replace( $matches[0], $key, $this->query );
}
if ( mb_strstr( $this->query, 'UNION' ) )
{
$this->query = str_replace( 'derivedTable', "derivedTable {$query}", $this->query );
@@ -206,7 +215,13 @@ class _Select implements \Iterator, \Countable
{
$this->query = preg_replace( '/(WHERE|GROUP BY|HAVING|LIMIT|ORDER BY|$)/', $query . ' $1', $this->query, 1 );
}
/* Now put our subquery joins back in */
foreach( $subqueries as $k => $v )
{
$this->query = str_replace( $k, $v, $this->query );
}
return $this;
}
@@ -362,7 +377,7 @@ class _Select implements \Iterator, \Countable
if ( !$meta )
{
throw new \IPS\Db\Exception( "Something went wrong. Please try again.", $this->stmt->errno, NULL, $this->query, array_merge( $this->joinBinds, $this->binds ) );
throw new \IPS\Db\Exception( "No result metadata - possible table crash", -1, NULL, $this->query, array_merge( $this->joinBinds, $this->binds ) );
}
while ( $field = $meta->fetch_field() )
@@ -556,6 +571,7 @@ class _Select implements \Iterator, \Countable
if ( !$this->stmt )
{
$this->runQuery();
$this->rewound = FALSE;
}
if ( $allRows )