'', // the table name suffix
'version' => '1.0.0',
'across_network' => true, // whether to share the table in across the multi-site network.
// Arguments automatically set
'table_name' => '', // determined in the formatting method
);
/**
* Sets up properties.
* @since 1.1.0
*/
public function __construct() {
$this->aArguments = $this->_getArgumentsFormatted( $this->_getArguments() );
}
/**
* Returns the class arguments.
* @remark This should be overridden in the extended class.
* @since 1.1.0
* @return array
*/
protected function _getArguments() {
return $this->aArguments;
}
/**
* Formats the arguments.
* @since 1.1.0
* @return array
*/
protected function _getArgumentsFormatted( array $aArguments ) {
$aArguments[ 'table_name' ] = $aArguments[ 'across_network' ]
? $GLOBALS[ 'wpdb' ]->base_prefix . $aArguments[ 'name' ]
: $GLOBALS[ 'wpdb' ]->prefix . $aArguments[ 'name' ];
return $aArguments + array(
'name' => __CLASS__,
);
}
/**
* Upgrade the table.
* @return array Strings containing the results of the various update queries.
* @since 1.1.0
*/
public function upgrade() {
$_sExistingVersion = get_option(
$this->aArguments[ 'name' ] . '_version',
'0'
);
// If the existent version is above or equal to the set version in the argument, do not upgrade.
if ( version_compare( $_sExistingVersion, $this->aArguments[ 'version' ], '>=' ) ) {
return array();
}
return $this->install( true );
}
/**
* Installs a table.
*
* @since 1.1.0
* @return array Strings containing the results of the various update queries.
*/
public function install( $bForce=false ) {
// If already exists, return.
if ( ! $bForce && $this->___hasTable() ) {
return array();
}
return $this->___install();
}
/**
* Checks whether the table exists or not.
* @return boolean
* @since 1.1.0
*/
private function ___hasTable() {
$_sExistingTableName = $GLOBALS[ 'wpdb' ]->get_var(
"SHOW TABLES LIKE '"
. $this->aArguments[ 'table_name' ]
. "'"
);
return $_sExistingTableName === $this->aArguments[ 'table_name' ];
}
/**
* Installs the database table.
* @return array Strings containing the results of the various update queries.
* @since 1.1.0
*/
private function ___install() {
// The method should be overridden in the extended class.
$_sSQLQuery = $this->getCreationQuery();
if ( ! $_sSQLQuery ) {
return;
}
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$_aResult = dbDelta( $_sSQLQuery );
if ( $this->aArguments[ 'version' ] ) {
update_option(
$this->aArguments[ 'name' ] . '_version', // key
$this->aArguments[ 'version' ] // data
);
}
return $_aResult;
}
/**
* Drops a table.
* @since 1.1.0
*/
public function uninstall() {
if ( $this->aArguments[ 'version' ] ) {
delete_option( $this->aArguments[ 'name' ] . '_version' );
}
$GLOBALS[ 'wpdb' ]->query(
"DROP TABLE IF EXISTS " . $this->aArguments[ 'table_name' ]
);
}
/**
* Override this method in the extended class.
*
* @return string
* @since 1.1.0
*/
public function getCreationQuery() {
return '';
}
/**
* @return string
* @since 1.1.0
*/
protected function _getCharactersetCollation() {
$_sDefaultCharset = $GLOBALS[ 'wpdb' ]->charset
? 'DEFAULT CHARACTER SET ' . $GLOBALS[ 'wpdb' ]->charset . ' '
: '';
$_sCollation = $GLOBALS[ 'wpdb' ]->collate
? 'COLLATE ' . $GLOBALS[ 'wpdb' ]->collate
: '';
return trim( $_sDefaultCharset . $_sCollation );
}
/**
* Inserts a row.
*
*
Example
* `
* $_oTable->insert(
* array(
* 'column1' => 'value1',
* 'column2' => 123
* ),
* array(
* '%s',
* '%d'
* )
* );
* `
* @see https://codex.wordpress.org/Class_Reference/wpdb#INSERT_rows
* @since 1.1.0
*/
public function insert( $aRow, $asFormat=null ) {
return $GLOBALS[ 'wpdb' ]->insert(
$this->aArguments[ 'table_name' ],
$aRow,
null === $asFormat // row format
? $this->_getPlaceHolders( $aRow )
: $asFormat
);
}
/**
* ```
* $wpdb->delete(
* 'table',
* array( 'ID' => 1 ), array( '%d' )
* );
* ```
*
* @param array $aWhere An array which defines the where SQL query part.
* If empty, it attempts to delete all rows.
* @param array|string $asFormat
* @return void
* @since 1.1.0
*/
public function delete( $aWhere=array(), $asFormat=null ) {
if ( empty( $aWhere ) ) {
$GLOBALS[ 'wpdb' ]->query(
"TRUNCATE TABLE `{$this->aArguments[ 'table_name' ]}`"
);
return;
}
$GLOBALS[ 'wpdb' ]->delete(
$this->aArguments[ 'table_name' ],
$aWhere,
null === $asFormat // row format
? $this->_getPlaceHolders( $aWhere )
: $asFormat
);
}
/**
*
* @see https://codex.wordpress.org/Class_Reference/wpdb#REPLACE_row
* @since 1.1.0
*/
public function replace( $aRow, $asFormat=null ) {
$aRow = $this->_getSanitizedRow( $aRow );
return $GLOBALS[ 'wpdb' ]->replace(
$this->aArguments[ 'table_name' ],
$aRow,
null === $asFormat // row format
? $this->_getPlaceHolders( $aRow )
: $asFormat
);
}
/**
*
* @see https://codex.wordpress.org/Class_Reference/wpdb#REPLACE_row
* @since 1.1.0
*/
public function update( $aRow, $aWhere=array(), $asFormat=null, $asWhereFormat=null ) {
$aRow = $this->_getSanitizedRow( $aRow );
return $GLOBALS[ 'wpdb' ]->update(
$this->aArguments[ 'table_name' ],
$aRow, // the new data to update
$aWhere, // e.g. array( 'id' => ... ) which updates the row whose id is ...
null === $asFormat // row format
? $this->_getPlaceHolders( $aRow )
: $asFormat,
null === $asWhereFormat
? $this->_getPlaceHolders( $aWhere )
: $asWhereFormat
);
}
/**
* @return array
* @since 1.1.0
*/
private function _getSanitizedRow( array $aRow ) {
foreach( $aRow as $_sColumnName => $_mValue ) {
$aRow[ $_sColumnName ] = maybe_serialize( $_mValue );
}
return $aRow;
}
/**
* @return array The placefolders such as %s, %d, %f for the format parameter of the above methods.
* @see https://codex.wordpress.org/Class_Reference/wpdb#Placeholders
* @since 1.1.0
*/
private function _getPlaceHolders( $aRow ) {
$_aPlaceHolders = array();
foreach ( $aRow as $_sColumn => $_mData ) {
$_aPlaceHolders[] = $this->_getPlaceHolder( $_mData );
}
return $_aPlaceHolders;
}
private function _getPlaceHolder( $mData ) {
switch ( gettype( $mData ) ) {
case 'integer':
return '%d';
case 'float':
case 'double':
return '%f';
case 'boolean':
case 'string':
default:
return '%s';
}
}
/**
* Retrieves a value.
* @remark Returns `null` if no item is found.
* @since 1.1.0
*/
public function getVariable( $sSQLQuery, $iColumnOffset=0, $iRowOffset=0 ) {
$_mResult = $GLOBALS[ 'wpdb' ]->get_var(
$sSQLQuery,
$iColumnOffset,
$iRowOffset
);
return maybe_unserialize( $_mResult );
}
/**
* Selects a single row.
* @since 1.1.0
*/
public function getRow( $sSQLQuery, $sFormat='ARRAY_A', $iRowOffset=0 ) {
$_aRow = $GLOBALS[ 'wpdb' ]->get_row(
$sSQLQuery,
$sFormat,
$iRowOffset
);
// A user can set own format with $sFormat so if it's not array, return as it is.
if ( ! is_array( $_aRow ) ) {
return $_aRow;
}
// When an array is returned, unserialize serialized arrays.
foreach( $_aRow as $_sColumnName => $_mValue ) {
$_aRow[ $_sColumnName ] = maybe_unserialize( $_mValue );
}
return $_aRow;
}
/**
* Selects multiple rows.
* @since 1.1.0
*/
public function getRows( $sSQLQuery, $sFormat='ARRAY_A' ) {
$_aRows = $GLOBALS[ 'wpdb' ]->get_results(
$sSQLQuery,
$sFormat
);
foreach( $_aRows as &$_aRow ) {
foreach( $_aRow as $_sColumnName => $_mValue ) {
$_aRow[ $_sColumnName ] = maybe_unserialize( $_mValue );
}
}
return $_aRows;
}
/**
* Retrieves a total count of rows.
* @sine 2.5.3
* @return integer The total row count.
*/
public function getTotalItemCount() {
return ( integer ) $this->getVariable(
"SELECT COUNT(*) FROM `{$this->aArguments[ 'table_name' ]}`"
);
}
/**
* Retrieves the table name.
* @since 2.5.3
* @return string
*/
public function getTableName() {
return $this->aArguments[ 'table_name' ];
}
/**
* @since 2.5.0
* @since 3.7.3 Added an option to get the value as integer
* @param boolean $bNumeric Whether the return value is a numeric value (integer|float) or not. The unit is megabyte.
* @return string|integer|float
*/
public function getTableSize( $bNumeric=false ) {
$_aResult = $GLOBALS[ 'wpdb' ]->get_results(
"SELECT
table_name AS `Table`,
round(((data_length + index_length) / 1024 / 1024), 2) `Size_in_MB`
FROM information_schema.TABLES
WHERE table_schema = (SELECT DATABASE())
AND table_name = '{$this->aArguments[ 'table_name' ]}'",
'ARRAY_A'
);
if ( $bNumeric ) {
return isset( $_aResult[ 0 ][ 'Size_in_MB' ] )
? $_aResult[ 0 ][ 'Size_in_MB' ]
: 0;
}
return isset( $_aResult[ 0 ][ 'Size_in_MB' ] )
? $_aResult[ 0 ][ 'Size_in_MB' ] . ' MB'
: 'n/a';
}
}