Version 4.1.19

This commit is contained in:
Neo committed 2025-12-19 05:38:56 -08:00
1 parent 28bd025b35
commit 2bd5025018
2674 files changed
+233518 -77766

No files matched your search

+100 -47
View File
@@ -2,9 +2,9 @@
/**
* @brief Table Builder using a database table datasource
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
@@ -58,10 +58,15 @@ class _Db extends Table
*/
public $keyField = NULL;
/**
* @brief Restrict select columns to only those listed - useful when grouping
*/
public $onlySelected = NULL;
/**
* Constructor
*
* @param array $table Database table
* @param array|string $table Database table
* @param \IPS\Http\Url $baseUrl Base URL
* @param array|null $where WHERE clause
* @param string|null $group GROUP clause
@@ -106,7 +111,7 @@ class _Db extends Table
$columns = is_array( $this->quickSearch ) ? $this->quickSearch[0] : $this->quickSearch;
$columns = is_array( $columns ) ? $columns : array( $columns );
$_where = '';
$_where = array();
foreach ( $columns as $c )
{
$_where[] = "LOWER(`{$c}`) LIKE CONCAT( '%', ?, '%' )";
@@ -121,7 +126,7 @@ class _Db extends Table
{
foreach ( $advancedSearchValues as $k => $v )
{
if ( isset( $this->advancedSearch[ $k ] ) )
if ( isset( $this->advancedSearch[ $k ] ) AND $v !== '' )
{
$type = $this->advancedSearch[ $k ];
@@ -151,14 +156,39 @@ class _Db extends Table
case SEARCH_CONTAINS_TEXT:
$where[] = array( "{$k} LIKE ?", '%' . $v . '%' );
break;
case SEARCH_QUERY_TEXT:
switch ( $v[0] )
{
case 'c':
$where[] = array( "{$k} LIKE ?", '%' . $v[1] . '%' );
break;
case 'bw':
$where[] = array( "{$k} LIKE ?", $v[1] . '%' );
break;
case 'eq':
$where[] = array( "{$k}=?", $v[1] );
break;
}
break;
case SEARCH_DATE_RANGE:
$timezone = ( \IPS\Member::loggedIn()->timezone ? new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) : NULL );
if ( $v['start'] )
{
if( !( $v['start'] instanceof \IPS\DateTime ) )
{
$v['start'] = new \IPS\DateTime( $v['start'], $timezone );
}
$where[] = array( "{$k}>?", $v['start']->getTimestamp() );
}
if ( $v['end'] )
{
if( !( $v['end'] instanceof \IPS\DateTime ) )
{
$v['end'] = new \IPS\DateTime( $v['end'], $timezone );
}
$where[] = array( "{$k}<?", $v['end']->getTimestamp() );
}
break;
@@ -175,7 +205,10 @@ class _Db extends Table
break;
case SEARCH_MEMBER:
$where[] = array( "{$k}=?", $v->member_id );
if( $v instanceof \IPS\Member )
{
$where[] = array( "{$k}=?", $v->member_id );
}
break;
case SEARCH_NODE:
@@ -211,6 +244,7 @@ class _Db extends Table
break;
case SEARCH_NUMERIC:
case SEARCH_NUMERIC_TEXT:
switch ( $v[0] )
{
case 'gt':
@@ -230,40 +264,55 @@ class _Db extends Table
break;
}
}
else
{
unset( $advancedSearchValues[ $k ] );
}
}
}
$selects = $this->selects;
if ( count( $this->joins ) )
if( $this->onlySelected !== NULL )
{
foreach( $this->joins as $join )
foreach( $this->onlySelected as $column )
{
if ( isset( $join['select'] ) )
$selects[] = $column;
}
if( $this->group !== NULL )
{
$this->group = is_array( $this->group ) ? $this->group : array( $this->group );
$this->group = array_unique( array_merge( $this->group, $this->onlySelected ) );
}
}
else
{
if ( count( $this->joins ) )
{
foreach( $this->joins as $join )
{
$selects[] = $join['select'];
if ( isset( $join['select'] ) )
{
$selects[] = $join['select'];
}
}
}
}
/* Count results (for pagination) */
if ( $this->group === null )
$count = \IPS\Db::i()->select( 'count(*)', $this->table, $where );
if ( count( $this->joins ) )
{
$count = \IPS\Db::i()->select( 'count(*)', $this->table, $where );
if ( count( $this->joins ) )
foreach( $this->joins as $join )
{
foreach( $this->joins as $join )
{
$count->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), 'LEFT' );
}
$count->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
}
$count = $count->first();
}
$count = $count->first();
$query = \IPS\Db::i()->select( '*' . ( count( $selects ) ? ', ' . implode( ', ', $selects ) : '' ), $this->table, $where, NULL, array( 0, 1 ) );
}
else
{
$query = \IPS\Db::i()->select( '*, count(DISTINCT( '.$this->table.'.' . $this->group . ')) as _count' . ( count( $selects ) ? ', ' . implode( ', ', $selects ) : '' ), $this->table, $where, NULL, array( 0, 1 ) );
}
/* Now get column headers */
$query = \IPS\Db::i()->select( $this->onlySelected ? implode( ', ', $selects ) : '*', $this->table, $where, NULL, array( 0, 1 ), $this->group );
if ( count( $this->joins ) )
{
@@ -277,23 +326,14 @@ class _Db extends Table
{
$query->forceIndex( $this->index );
}
if ( $this->group === null )
try
{
try
{
$results = $query->first();
}
catch( \UnderflowException $e )
{
$results = array();
}
$results = $query->first();
}
else
catch( \UnderflowException $e )
{
$count = $query->first();
$results = $count;
$count = $count['_count'];
$results = array();
}
$this->pages = ceil( $count / $this->limit );
@@ -304,15 +344,20 @@ class _Db extends Table
{
$orderBy = implode( ',', array_map( function( $v )
{
/* This gives you something like "g`.`g_id" which is then turned into "`g`.`g_id`" below */
$v = str_replace( '.', "`.`", $v );
if ( ! mb_strstr( trim( $v ), ' ' ) )
{
return '`' . trim( $v ) . '`';
$return = ( isset( $this->advancedSearch[$v] ) and $this->advancedSearch[$v] == SEARCH_NUMERIC_TEXT ) ? 'LENGTH(' . '`' . trim( $v ) . '`' . ') ' . $this->sortDirection . ', ' . '`' . trim( $v ) . '` ' : '`' . trim( $v ) . '` ';
}
else
{
list( $field, $direction ) = explode( ' ', $v );
return '`' . trim( $field ) . '` ' . $direction;
$return = ( isset( $this->advancedSearch[$v] ) and $this->advancedSearch[$v] == SEARCH_NUMERIC_TEXT ) ? 'LENGTH(' . '`' . trim( $field ) . '`' . ') ' . mb_strtolower( $direction ) == 'asc' ? 'asc' : 'desc' . ', ' . '`' . trim( $field ) . '` ' : '`' . trim( $field ) . '` ';
$return .= ( mb_strtolower( $direction ) == 'asc' ? 'asc' : 'desc' );
}
return $return;
}, explode( ',', $this->sortBy ) ) );
$orderBy .= $this->sortDirection == 'asc' ? ' asc' : ' desc';
@@ -321,13 +366,14 @@ class _Db extends Table
/* Run query */
$rows = array();
$select = \IPS\Db::i()->select(
( count( $selects ) ) ? $this->table . '.*, ' . implode( ', ', $selects ) : '*',
$this->onlySelected ? implode( ', ', $selects ) : ( ( count( $selects ) ) ? $this->table . '.*, ' . implode( ', ', $selects ) : '*' ),
$this->table,
$where,
$orderBy,
array( ( $this->limit * ( $this->page - 1 ) ), $this->limit ), $this->group
array( ( $this->limit * ( $this->page - 1 ) ), $this->limit ),
$this->group
);
if ( $this->index )
{
$select->forceIndex( $this->index );
@@ -337,14 +383,14 @@ class _Db extends Table
{
foreach( $this->joins as $join )
{
$select->join( $join['from'], $join['where'], 'LEFT' );
$select->join( $join['from'], $join['where'], ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
}
}
if ( $this->keyField !== NULL )
{
$select->setKeyField( $this->keyField );
}
foreach ( $select as $rowId => $row )
{
/* Add in any 'custom' fields */
@@ -437,6 +483,13 @@ class _Db extends Table
{
foreach( explode( ',', $this->sortBy ) as $field )
{
/* Get rid of table alias if there is one */
if( mb_strpos( $field, '.' ) !== FALSE )
{
$field = explode( '.', $field );
$field = $field[1];
}
$field = trim($field);
if ( mb_strstr( $field, ' ' ) )
@@ -452,7 +505,7 @@ class _Db extends Table
return true;
}
elseif ( array_key_exists( $this->sortBy, $count ) )
elseif ( array_key_exists( preg_replace( "/^.+?\.(.+?)$/", "$1", $this->sortBy ), $count ) )
{
return true;
}