Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
+86
-67
@@ -11,83 +11,99 @@
|
||||
namespace IPS\Helpers\Table;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db as IPSDb;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Request;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_callable;
|
||||
use function is_object;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* List Table Builder using a database table datasource
|
||||
*/
|
||||
class _Db extends Table
|
||||
class Db extends Table
|
||||
{
|
||||
/**
|
||||
* @brief Database Table
|
||||
*/
|
||||
protected $table;
|
||||
protected ?string $table = NULL;
|
||||
|
||||
/**
|
||||
* @brief Selects
|
||||
*/
|
||||
public $selects = array();
|
||||
public array $selects = array();
|
||||
|
||||
/**
|
||||
* @brief Initial WHERE clause
|
||||
*/
|
||||
public $where;
|
||||
public mixed $where = NULL;
|
||||
|
||||
/**
|
||||
* @brief Force index clause
|
||||
*/
|
||||
protected $index;
|
||||
protected mixed $index = NULL;
|
||||
|
||||
/**
|
||||
* @brief Primary sort column
|
||||
*/
|
||||
public $primarySortBy;
|
||||
public ?string $primarySortBy = NULL;
|
||||
|
||||
/**
|
||||
* @brief Direction of primary sort
|
||||
*/
|
||||
public $primarySortDirection;
|
||||
public ?string $primarySortDirection = NULL;
|
||||
|
||||
/**
|
||||
* @brief Joins
|
||||
*/
|
||||
public $joins = array();
|
||||
public array $joins = array();
|
||||
|
||||
/**
|
||||
* @brief Key field
|
||||
*/
|
||||
public $keyField = NULL;
|
||||
public mixed $keyField = NULL;
|
||||
|
||||
/**
|
||||
* @brief Group by key
|
||||
*/
|
||||
public $groupBy = NULL;
|
||||
public string|array|null $groupBy = NULL;
|
||||
|
||||
/**
|
||||
* @brief The database we will query against
|
||||
*/
|
||||
public $db;
|
||||
public ?IPSDb $db = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $table Database table
|
||||
* @param \IPS\Http\Url $baseUrl Base URL
|
||||
* @param array|null $where WHERE clause
|
||||
* @param array|null $forceIndex Index to force
|
||||
* @param \IPS\Db|null $database An instance of \IPS\Db to run the queries against (defaults to current connection)
|
||||
* @return void
|
||||
* @param string $table Database table
|
||||
* @param Url $baseUrl Base URL
|
||||
* @param array|string|null $where WHERE clause
|
||||
* @param array|null $forceIndex Index to force
|
||||
* @param IPSDb|null $database An instance of \IPS\Db to run the queries against (defaults to current connection)
|
||||
*/
|
||||
public function __construct( $table, \IPS\Http\Url $baseUrl, $where=NULL, $forceIndex=NULL, $database=NULL )
|
||||
public function __construct( string $table, Url $baseUrl, array|string $where=null, mixed $forceIndex=null, IPSDb $database=null )
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->where = $where;
|
||||
$this->index = $forceIndex;
|
||||
$this->db = $database ?? \IPS\Db::i();
|
||||
$this->db = $database ?? IPSDb::i();
|
||||
|
||||
return parent::__construct( $baseUrl );
|
||||
}
|
||||
@@ -96,31 +112,32 @@ class _Db extends Table
|
||||
* Get rows
|
||||
* @note This method is called twice, so if there'some expensive operation happening, or if you're calculating something, make sure to cache it.
|
||||
*
|
||||
* @param array $advancedSearchValues Values from the advanced search form
|
||||
* @return array
|
||||
* @param array|null $advancedSearchValues Values from the advanced search form
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRows( $advancedSearchValues )
|
||||
public function getRows( array $advancedSearchValues = null ): array
|
||||
{
|
||||
/* Specify filter in where clause */
|
||||
$where = $this->where ? \is_array( $this->where ) ? $this->where : array( $this->where ) : array();
|
||||
$where = $this->where ? is_array( $this->where ) ? $this->where : array( $this->where ) : array();
|
||||
|
||||
if ( $this->filter and isset( $this->filters[ $this->filter ] ) )
|
||||
{
|
||||
$where[] = \is_array( $this->filters[ $this->filter ] ) ? $this->filters[ $this->filter ] : array( $this->filters[ $this->filter ] );
|
||||
$where[] = is_array( $this->filters[ $this->filter ] ) ? $this->filters[ $this->filter ] : array( $this->filters[ $this->filter ] );
|
||||
}
|
||||
|
||||
|
||||
/* Add quick search term to where clause if necessary */
|
||||
if ( $this->quickSearch !== NULL and \IPS\Request::i()->quicksearch )
|
||||
if ( $this->quickSearch !== NULL and Request::i()->quicksearch )
|
||||
{
|
||||
if ( \is_callable( $this->quickSearch ) )
|
||||
if ( is_callable( $this->quickSearch ) )
|
||||
{
|
||||
$quickSearchFunc = $this->quickSearch;
|
||||
$where[] = $quickSearchFunc( trim( \IPS\Request::i()->quicksearch ) );
|
||||
$where[] = $quickSearchFunc( trim( Request::i()->quicksearch ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$columns = \is_array( $this->quickSearch ) ? $this->quickSearch[0] : $this->quickSearch;
|
||||
$columns = \is_array( $columns ) ? $columns : array( $columns );
|
||||
$columns = is_array( $this->quickSearch ) ? $this->quickSearch[0] : $this->quickSearch;
|
||||
$columns = is_array( $columns ) ? $columns : array( $columns );
|
||||
|
||||
$_where = array();
|
||||
foreach ( $columns as $c )
|
||||
@@ -128,7 +145,7 @@ class _Db extends Table
|
||||
$_where[] = "LOWER(`{$c}`) LIKE CONCAT( '%', ?, '%' )";
|
||||
}
|
||||
|
||||
$where[] = array_merge( array( '(' . implode( ' OR ', $_where ) . ')' ), array_fill( 0, \count( $_where ), mb_strtolower( trim( \IPS\Request::i()->quicksearch ) ) ) );
|
||||
$where[] = array_merge( array( '(' . implode( ' OR ', $_where ) . ')' ), array_fill( 0, count( $_where ), mb_strtolower( trim( Request::i()->quicksearch ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,11 +154,11 @@ class _Db extends Table
|
||||
{
|
||||
foreach ( $advancedSearchValues as $k => $v )
|
||||
{
|
||||
if ( isset( $this->advancedSearch[ $k ] ) AND $v !== '' AND ( !\is_array( $v ) OR !empty( $v ) ) )
|
||||
if ( isset( $this->advancedSearch[ $k ] ) AND $v !== '' AND ( !is_array( $v ) OR !empty( $v ) ) )
|
||||
{
|
||||
$type = $this->advancedSearch[ $k ];
|
||||
|
||||
if ( \is_array( $type ) )
|
||||
if ( is_array( $type ) )
|
||||
{
|
||||
if ( isset( $type[2] ) )
|
||||
{
|
||||
@@ -193,7 +210,7 @@ class _Db extends Table
|
||||
}
|
||||
break;
|
||||
case SEARCH_DATE_RANGE:
|
||||
$timezone = ( \IPS\Member::loggedIn()->timezone ? new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) : NULL );
|
||||
$timezone = ( Member::loggedIn()->timezone ? new DateTimeZone( Member::loggedIn()->timezone ) : NULL );
|
||||
|
||||
if( !$v['start'] AND !$v['end'] )
|
||||
{
|
||||
@@ -202,18 +219,18 @@ class _Db extends Table
|
||||
|
||||
if ( $v['start'] )
|
||||
{
|
||||
if( !( $v['start'] instanceof \IPS\DateTime ) )
|
||||
if( !( $v['start'] instanceof DateTime ) )
|
||||
{
|
||||
$v['start'] = new \IPS\DateTime( $v['start'], $timezone );
|
||||
$v['start'] = new DateTime( $v['start'], $timezone );
|
||||
}
|
||||
|
||||
$where[] = array( "{$k}>?", $v['start']->getTimestamp() );
|
||||
}
|
||||
if ( $v['end'] )
|
||||
{
|
||||
if( !( $v['end'] instanceof \IPS\DateTime ) )
|
||||
if( !( $v['end'] instanceof DateTime ) )
|
||||
{
|
||||
$v['end'] = new \IPS\DateTime( $v['end'], $timezone );
|
||||
$v['end'] = new DateTime( $v['end'], $timezone );
|
||||
}
|
||||
|
||||
$where[] = array( "{$k}<?", $v['end']->getTimestamp() );
|
||||
@@ -235,7 +252,7 @@ class _Db extends Table
|
||||
case SEARCH_MEMBER:
|
||||
if ( $v )
|
||||
{
|
||||
$where[] = array( "{$k}=?", ( $v instanceof \IPS\Member ) ? $v->member_id : $v );
|
||||
$where[] = array( "{$k}=?", ( $v instanceof Member ) ? $v->member_id : $v );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -245,8 +262,8 @@ class _Db extends Table
|
||||
|
||||
case SEARCH_NODE:
|
||||
$nodeClass = $options['class'];
|
||||
$prop = isset( $options['searchProp'] ) ? $options['searchProp'] : '_id';
|
||||
if ( !\is_array( $v ) )
|
||||
$prop = $options['searchProp'] ?? '_id';
|
||||
if ( !is_array( $v ) )
|
||||
{
|
||||
$v = array( $v );
|
||||
}
|
||||
@@ -254,7 +271,7 @@ class _Db extends Table
|
||||
$values = array();
|
||||
foreach ( $v as $_v )
|
||||
{
|
||||
if ( !\is_object( $_v ) )
|
||||
if ( !is_object( $_v ) )
|
||||
{
|
||||
if ( mb_substr( $_v, 0, 2 ) === 's.' )
|
||||
{
|
||||
@@ -265,7 +282,7 @@ class _Db extends Table
|
||||
{
|
||||
$_v = $nodeClass::load( $_v );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -306,7 +323,7 @@ class _Db extends Table
|
||||
$selects = $this->selects;
|
||||
$isOtherJoin = false;
|
||||
|
||||
if ( \count( $this->joins ) )
|
||||
if ( count( $this->joins ) )
|
||||
{
|
||||
foreach( $this->joins as $join )
|
||||
{
|
||||
@@ -315,7 +332,7 @@ class _Db extends Table
|
||||
$selects[] = $join['select'];
|
||||
}
|
||||
|
||||
if ( isset( $join['type'] ) and \mb_strtolower( $join['type'] ) != 'left' )
|
||||
if ( isset( $join['type'] ) and mb_strtolower( $join['type'] ) != 'left' )
|
||||
{
|
||||
/* Inner join or straight join which will affect the query results */
|
||||
$isOtherJoin = true;
|
||||
@@ -325,13 +342,15 @@ class _Db extends Table
|
||||
|
||||
/* Count results (for pagination) */
|
||||
$count = $this->db->select( 'count(*)', $this->table, $where, NULL, NULL, $this->groupBy );
|
||||
|
||||
/* Add the joins if we have a where statement and all joins are left for the count */
|
||||
if ( ( $isOtherJoin or \count( $where ) ) and \count( $this->joins ) )
|
||||
if ( count( $this->joins ) )
|
||||
{
|
||||
foreach( $this->joins as $join )
|
||||
/* Add the joins if we have a where statement and all joins are left for the count */
|
||||
if ( ( $isOtherJoin or count( $where ) ) and count( $this->joins ) )
|
||||
{
|
||||
$count->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
|
||||
foreach ( $this->joins as $join )
|
||||
{
|
||||
$count->join( $join['from'], ( $join['where'] ?? null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,13 +359,13 @@ class _Db extends Table
|
||||
$selectPrefix = ( $this->groupBy ) ? '' : $this->table . '.*, ';
|
||||
|
||||
/* Now get column headers */
|
||||
$query = $this->db->select( ( \count( $selects ) ) ? $selectPrefix . implode( ', ', $selects ) : '*', $this->table, NULL, NULL, array( 0, 1 ), $this->groupBy );
|
||||
$query = $this->db->select( ( count( $selects ) ) ? $selectPrefix . implode( ', ', $selects ) : '*', $this->table, NULL, NULL, array( 0, 1 ), $this->groupBy );
|
||||
|
||||
if ( \count( $this->joins ) )
|
||||
if ( count( $this->joins ) )
|
||||
{
|
||||
foreach( $this->joins as $join )
|
||||
{
|
||||
$query->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
|
||||
$query->join( $join['from'], ( $join['where'] ?? null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +373,7 @@ class _Db extends Table
|
||||
{
|
||||
$results = $query->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
catch( UnderflowException $e )
|
||||
{
|
||||
$results = array();
|
||||
}
|
||||
@@ -393,12 +412,12 @@ class _Db extends Table
|
||||
}
|
||||
|
||||
/* Are we downloading? Bypass Table Limit */
|
||||
$limit = \IPS\Request::i()->download ? $count : $this->limit;
|
||||
$limit = Request::i()->download ? $count : $this->limit;
|
||||
|
||||
/* Run query */
|
||||
$rows = array();
|
||||
$select = $this->db->select(
|
||||
( \count( $selects ) ) ? $selectPrefix . implode( ', ', $selects ) : '*',
|
||||
( count( $selects ) ) ? $selectPrefix . implode( ', ', $selects ) : '*',
|
||||
$this->table,
|
||||
$where,
|
||||
$orderBy,
|
||||
@@ -411,7 +430,7 @@ class _Db extends Table
|
||||
$select->forceIndex( $this->index );
|
||||
}
|
||||
|
||||
if ( \count( $this->joins ) )
|
||||
if ( count( $this->joins ) )
|
||||
{
|
||||
foreach( $this->joins as $join )
|
||||
{
|
||||
@@ -432,14 +451,14 @@ class _Db extends Table
|
||||
$row = array();
|
||||
foreach ( $this->include as $k )
|
||||
{
|
||||
$row[ $k ] = isset( $_row[ $k ] ) ? $_row[ $k ] : NULL;
|
||||
$row[ $k ] = $_row[$k] ?? NULL;
|
||||
}
|
||||
|
||||
if( !empty( $advancedSearchValues ) AND !isset( \IPS\Request::i()->noColumn ) )
|
||||
if( !empty( $advancedSearchValues ) AND !isset( Request::i()->noColumn ) )
|
||||
{
|
||||
foreach ( $advancedSearchValues as $k => $v )
|
||||
{
|
||||
$row[ $k ] = isset( $_row[ $k ] ) ? $_row[ $k ] : NULL;
|
||||
$row[ $k ] = $_row[$k] ?? NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,7 +478,7 @@ class _Db extends Table
|
||||
}
|
||||
|
||||
/* Are we including this one? */
|
||||
if( ( ( $this->include !== NULL and !\in_array( $k, $this->include ) ) or ( $this->exclude !== NULL and \in_array( $k, $this->exclude ) ) ) and !array_key_exists( $k, $advancedSearchValues ) )
|
||||
if( ( ( $this->include !== NULL and !in_array( $k, $this->include ) ) or ( $this->exclude !== NULL and in_array( $k, $this->exclude ) ) ) and !array_key_exists( $k, $advancedSearchValues ) )
|
||||
{
|
||||
unset( $row[ $k ] );
|
||||
continue;
|
||||
@@ -518,17 +537,17 @@ class _Db extends Table
|
||||
|
||||
/**
|
||||
* User set sortBy is suitable for an SQL sort operation
|
||||
* @param array $count Result of count(*) query with field names included
|
||||
* @param array $count Result of count(*) query with field names included
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _isSqlSort( $count )
|
||||
protected function _isSqlSort( array $count ): bool
|
||||
{
|
||||
if ( !$this->sortBy )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !\is_array( $count ) )
|
||||
if( !is_array( $count ) )
|
||||
{
|
||||
$count = array( $count );
|
||||
}
|
||||
@@ -572,7 +591,7 @@ class _Db extends Table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function customActions()
|
||||
public function customActions(): array
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user