Commit realizado el 12:13:52 08-04-2024
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* The clauses functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Clauses class.
|
||||
*/
|
||||
trait Clauses {
|
||||
|
||||
/**
|
||||
* List of SQL clauses.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $sql_clauses = [];
|
||||
|
||||
/**
|
||||
* SQL clause merge filters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $sql_filters = [
|
||||
'where' => [
|
||||
'where',
|
||||
'where_time',
|
||||
],
|
||||
'join' => [
|
||||
'right_join',
|
||||
'join',
|
||||
'left_join',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Check has SQL clause.
|
||||
*
|
||||
* @param string $type Clause type.
|
||||
*
|
||||
* @return boolean True if set and not empty.
|
||||
*/
|
||||
public function has_sql_clause( $type ) {
|
||||
return isset( $this->sql_clauses[ $type ] ) && ! empty( $this->sql_clauses[ $type ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a SQL clause to be included when get_data is called.
|
||||
*
|
||||
* @param string $type Clause type.
|
||||
* @param string $clause SQL clause.
|
||||
*/
|
||||
public function add_sql_clause( $type, $clause ) {
|
||||
if ( isset( $this->sql_clauses[ $type ] ) && ! empty( $clause ) ) {
|
||||
$this->sql_clauses[ $type ][] = $clause;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear SQL clauses by type.
|
||||
*
|
||||
* @param string|array $types Clause type.
|
||||
*/
|
||||
protected function clear_sql_clause( $types ) {
|
||||
foreach ( (array) $types as $type ) {
|
||||
if ( isset( $this->sql_clauses[ $type ] ) ) {
|
||||
$this->sql_clauses[ $type ] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SQL clause by type.
|
||||
*
|
||||
* @param string $type Clause type.
|
||||
* @param string $filtered Whether to filter the return value. Default unfiltered.
|
||||
*
|
||||
* @return string SQL clause.
|
||||
*/
|
||||
protected function get_sql_clause( $type, $filtered = false ) {
|
||||
if ( ! isset( $this->sql_clauses[ $type ] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$separator = ' ';
|
||||
if ( in_array( $type, [ 'select', 'order_by', 'group_by' ], true ) ) {
|
||||
$separator = ', ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Default to bypassing filters for clause retrieval internal to data stores.
|
||||
* The filters are applied when the full SQL statement is retrieved.
|
||||
*/
|
||||
if ( false === $filtered ) {
|
||||
return implode( $separator, $this->sql_clauses[ $type ] );
|
||||
}
|
||||
|
||||
if ( isset( $this->sql_filters[ $type ] ) ) {
|
||||
$clauses = [];
|
||||
foreach ( $this->sql_filters[ $type ] as $subset ) {
|
||||
$clauses = array_merge( $clauses, $this->sql_clauses[ $subset ] );
|
||||
}
|
||||
} else {
|
||||
$clauses = $this->sql_clauses[ $type ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter SQL clauses by type and context.
|
||||
*
|
||||
* @param array $clauses The original arguments for the request.
|
||||
* @param string $context The data store context.
|
||||
*/
|
||||
$clauses = apply_filters( "rank_math_clauses_{$type}", $clauses, $this->context );
|
||||
/**
|
||||
* Filter SQL clauses by type and context.
|
||||
*
|
||||
* @param array $clauses The original arguments for the request.
|
||||
*/
|
||||
$clauses = apply_filters( "rank_math_clauses_{$type}_{$this->context}", $clauses );
|
||||
|
||||
return implode( $separator, $clauses );
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* The Database.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Database class.
|
||||
*/
|
||||
class Database {
|
||||
|
||||
/**
|
||||
* Array of all databases objects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $instances = [];
|
||||
|
||||
/**
|
||||
* Retrieve a Database instance by table name.
|
||||
*
|
||||
* @param string $table_name A Database instance id.
|
||||
*
|
||||
* @return Database Database object instance.
|
||||
*/
|
||||
public static function table( $table_name ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( self::$instances ) || empty( self::$instances[ $table_name ] ) ) {
|
||||
self::$instances[ $table_name ] = new Query_Builder( $wpdb->prefix . $table_name );
|
||||
}
|
||||
|
||||
return self::$instances[ $table_name ];
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* The escape functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Escape class.
|
||||
*/
|
||||
trait Escape {
|
||||
|
||||
/**
|
||||
* Escape array values for sql
|
||||
*
|
||||
* @param array $arr Array to escape.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function esc_array( $arr ) {
|
||||
return array_map( [ $this, 'esc_value' ], $arr );
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape value for sql
|
||||
*
|
||||
* @param mixed $value Value to escape.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function esc_value( $value ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( is_int( $value ) ) {
|
||||
return $wpdb->prepare( '%d', $value );
|
||||
}
|
||||
|
||||
if ( is_float( $value ) ) {
|
||||
return $wpdb->prepare( '%f', $value );
|
||||
}
|
||||
|
||||
return 'NULL' === $value ? $value : $wpdb->prepare( '%s', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape value for like statement
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $value Value for like statement.
|
||||
* @param string $start (Optional) The start of like query.
|
||||
* @param string $end (Optional) The end of like query.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function esc_like( $value, $start = '%', $end = '%' ) {
|
||||
global $wpdb;
|
||||
return $start . $wpdb->esc_like( $value ) . $end;
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* The groupby functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* GroupBy class.
|
||||
*/
|
||||
trait GroupBy {
|
||||
|
||||
/**
|
||||
* Add an group by statement to the current query
|
||||
*
|
||||
* ->groupBy('created_at')
|
||||
*
|
||||
* @param array|string $columns Columns.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function groupBy( $columns ) { // @codingStandardsIgnoreLine
|
||||
if ( is_string( $columns ) ) {
|
||||
$columns = $this->argument_to_array( $columns );
|
||||
}
|
||||
|
||||
foreach ( $columns as $column ) {
|
||||
$this->add_sql_clause( 'group_by', $column );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Having clause
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param mixed $param1 Operator or value depending if $param2 isset.
|
||||
* @param mixed $param2 The value if $param1 is an operator.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function having( $column, $param1 = null, $param2 = null ) {
|
||||
$this->add_sql_clause( 'having', $this->generateWhere( $column, $param1, $param2, 'HAVING' ) );
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* The joins functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Joins class.
|
||||
*/
|
||||
trait Joins {
|
||||
|
||||
/**
|
||||
* Generate left join clause.
|
||||
*
|
||||
* @param string $table The SQL table.
|
||||
* @param mixed $column1 The SQL Column.
|
||||
* @param mixed $column2 The SQL Column.
|
||||
* @param string $operator The Operator.
|
||||
* @param string $alias The table alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function leftJoin( $table, $column1, $column2, $operator = '=', $alias = '' ) { // @codingStandardsIgnoreLine
|
||||
if ( empty( $table ) || empty( $column1 ) || empty( $column2 ) ) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( ! empty( $alias ) ) {
|
||||
$table = "{$table} AS {$alias}";
|
||||
}
|
||||
|
||||
$this->add_sql_clause( 'left_join', "LEFT JOIN {$table} ON {$column1} {$operator} {$column2}" );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate right join clause.
|
||||
*
|
||||
* @param string $table The SQL table.
|
||||
* @param mixed $column1 The SQL Column.
|
||||
* @param mixed $column2 The SQL Column.
|
||||
* @param string $operator The Operator.
|
||||
* @param string $alias The table alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function rightJoin( $table, $column1, $column2, $operator = '=', $alias = '' ) { // @codingStandardsIgnoreLine
|
||||
if ( empty( $table ) || empty( $column1 ) || empty( $column2 ) ) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( ! empty( $alias ) ) {
|
||||
$table = "{$table} AS {$alias}";
|
||||
}
|
||||
|
||||
$this->add_sql_clause( 'right_join', "RIGHT JOIN {$table} ON {$column1} {$operator} {$column2}" );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate left join clause.
|
||||
*
|
||||
* @param string $table The SQL table.
|
||||
* @param mixed $column1 The SQL Column.
|
||||
* @param mixed $column2 The SQL Column.
|
||||
* @param string $operator The Operator.
|
||||
* @param string $alias The table alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function join( $table, $column1, $column2, $operator = '=', $alias = '' ) { // @codingStandardsIgnoreLine
|
||||
if ( empty( $table ) || empty( $column1 ) || empty( $column2 ) ) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( ! empty( $alias ) ) {
|
||||
$table = "{$table} AS {$alias}";
|
||||
}
|
||||
|
||||
$this->add_sql_clause( 'join', "JOIN {$table} ON {$column1} {$operator} {$column2}" );
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* The orderby functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
use RankMath\Helpers\Arr;
|
||||
|
||||
/**
|
||||
* OrderBy class.
|
||||
*/
|
||||
trait OrderBy {
|
||||
|
||||
/**
|
||||
* Add an order by statement to the current query
|
||||
*
|
||||
* ->orderBy('created_at')
|
||||
* ->orderBy('modified_at', 'desc')
|
||||
*
|
||||
* // multiple order clauses
|
||||
* ->orderBy(['firstname', 'lastname'], 'desc')
|
||||
*
|
||||
* // muliple order clauses with diffrent directions
|
||||
* ->orderBy(['firstname' => 'asc', 'lastname' => 'desc'])
|
||||
*
|
||||
* @param array|string $columns Columns.
|
||||
* @param string $direction Direction.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orderBy( $columns, $direction = 'ASC' ) { // @codingStandardsIgnoreLine
|
||||
if ( is_string( $columns ) ) {
|
||||
$columns = $this->argument_to_array( $columns );
|
||||
}
|
||||
|
||||
$direction = $this->sanitize_direction( $direction );
|
||||
|
||||
foreach ( $columns as $key => $column ) {
|
||||
if ( is_numeric( $key ) ) {
|
||||
$this->add_sql_clause( 'order_by', "{$column}{$direction}" );
|
||||
continue;
|
||||
}
|
||||
|
||||
$column = $this->sanitize_direction( $column );
|
||||
$this->add_sql_clause( 'order_by', "{$key}{$column}" );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize direction
|
||||
*
|
||||
* @param string $direction Value to sanitize.
|
||||
*
|
||||
* @return string Sanitized value
|
||||
*/
|
||||
protected function sanitize_direction( $direction ) {
|
||||
if ( empty( $direction ) || 'ASC' === $direction || 'asc' === $direction ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return ' ' . \strtoupper( $direction );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an string argument as parsed array if possible
|
||||
*
|
||||
* @param string $argument Argument to validate.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function argument_to_array( $argument ) {
|
||||
if ( false !== strpos( $argument, ',' ) ) {
|
||||
return Arr::from_string( $argument );
|
||||
}
|
||||
|
||||
return [ $argument ];
|
||||
}
|
||||
}
|
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* The Query Builder.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Query_Builder class.
|
||||
*/
|
||||
class Query_Builder {
|
||||
|
||||
use Escape;
|
||||
use Select;
|
||||
use Where;
|
||||
use Joins;
|
||||
use GroupBy;
|
||||
use OrderBy;
|
||||
use Clauses;
|
||||
use Translate;
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $table = '';
|
||||
|
||||
/**
|
||||
* Save last query.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $last_query = '';
|
||||
|
||||
/**
|
||||
* Make a distinct selection
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $distinct = false;
|
||||
|
||||
/**
|
||||
* Make SQL_CALC_FOUND_ROWS in selection
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $found_rows = false;
|
||||
|
||||
/**
|
||||
* Data store context used to pass to filters.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $table The table name.
|
||||
* @param string $context Optional context passed to filters. Default empty string.
|
||||
*/
|
||||
public function __construct( $table, $context = '' ) {
|
||||
$this->table = $table;
|
||||
$this->context = $context;
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the given query object and return the results
|
||||
*
|
||||
* @param string $output (Optional) Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get( $output = \OBJECT ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->last_query = $this->translateSelect();
|
||||
$this->reset();
|
||||
|
||||
return $wpdb->get_results( $this->last_query, $output ); // phpcs:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the given query object and return the results
|
||||
*
|
||||
* @param string $output (Optional) Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function one( $output = \OBJECT ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->limit( 1 );
|
||||
$this->last_query = $this->translateSelect();
|
||||
$this->reset();
|
||||
|
||||
return $wpdb->get_row( $this->last_query, $output ); // phpcs:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the given query object and return one variable from the database
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getVar() { // @codingStandardsIgnoreLine
|
||||
$row = $this->one( \ARRAY_A );
|
||||
|
||||
return is_null( $row ) ? false : current( $row );
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a row into a table
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @see wpdb::insert()
|
||||
*
|
||||
* @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
|
||||
* @param array $format (Optional) An array of formats to be mapped to each of the value in $data.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function insert( $data, $format = null ) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->insert( $this->table, $data, $format );
|
||||
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a row into a table
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update() {
|
||||
|
||||
$query = $this->translateUpdate();
|
||||
$this->reset();
|
||||
|
||||
return $this->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete data from table
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete() {
|
||||
|
||||
$query = $this->translateDelete();
|
||||
$this->reset();
|
||||
|
||||
return $this->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate table.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function truncate() {
|
||||
return $this->query( "truncate table {$this->table};" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get found rows.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_found_rows() {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_var( 'SELECT FOUND_ROWS();' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a MySQL database query, using current database connection.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @see wpdb::query
|
||||
*
|
||||
* @param string $query Database query.
|
||||
*
|
||||
* @return int|false Number of rows affected|selected or false on error.
|
||||
*/
|
||||
public function query( $query ) {
|
||||
global $wpdb;
|
||||
$this->last_query = $query;
|
||||
|
||||
return $wpdb->query( $query ); // phpcs:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the limit clause.
|
||||
*
|
||||
* @param int $limit Limit size.
|
||||
* @param int $offset Offeset.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function limit( $limit, $offset = 0 ) {
|
||||
global $wpdb;
|
||||
$limit = \absint( $limit );
|
||||
$offset = \absint( $offset );
|
||||
|
||||
$this->clear_sql_clause( 'limit' );
|
||||
$this->add_sql_clause( 'limit', $wpdb->prepare( 'LIMIT %d, %d', $offset, $limit ) );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an query limit based on a page and a page size
|
||||
*
|
||||
* @param int $page Page number.
|
||||
* @param int $size Page size.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function page( $page, $size = 25 ) {
|
||||
$size = \absint( $size );
|
||||
$offset = $size * \absint( $page );
|
||||
|
||||
$this->limit( $size, $offset );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set values for insert/update
|
||||
*
|
||||
* @param string|array $name Key of pair.
|
||||
* @param string|array $value Value of pair.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function set( $name, $value = null ) {
|
||||
if ( is_array( $name ) ) {
|
||||
$this->sql_clauses['values'] = $this->sql_clauses['values'] + $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->sql_clauses['values'][ $name ] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all vaiables.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
private function reset() {
|
||||
$this->distinct = false;
|
||||
$this->found_rows = false;
|
||||
$this->sql_clauses = [
|
||||
'select' => [],
|
||||
'from' => [],
|
||||
'left_join' => [],
|
||||
'join' => [],
|
||||
'right_join' => [],
|
||||
'where' => [],
|
||||
'where_time' => [],
|
||||
'group_by' => [],
|
||||
'having' => [],
|
||||
'limit' => [],
|
||||
'order_by' => [],
|
||||
'values' => [],
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* The select functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Select class.
|
||||
*/
|
||||
trait Select {
|
||||
|
||||
/**
|
||||
* Set the selected fields
|
||||
*
|
||||
* @param array $fields Fields to select.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function select( $fields = '' ) {
|
||||
if ( empty( $fields ) ) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( is_string( $fields ) ) {
|
||||
$this->add_sql_clause( 'select', $fields );
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach ( $fields as $key => $field ) {
|
||||
$this->add_sql_clause( 'select', is_string( $key ) ? "$key AS $field" : $field );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to add a count function
|
||||
*
|
||||
* ->selectCount('id')
|
||||
* ->selectCount('id', 'count')
|
||||
*
|
||||
* @param string $field Column name.
|
||||
* @param string $alias (Optional) Column alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function selectCount( $field = '*', $alias = null ) { // @codingStandardsIgnoreLine
|
||||
return $this->selectFunc( 'count', $field, $alias );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to add a sum function
|
||||
*
|
||||
* ->selectSum('id')
|
||||
* ->selectSum('id', 'total')
|
||||
*
|
||||
* @param string $field Column name.
|
||||
* @param string $alias (Optional) Column alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function selectSum( $field, $alias = null ) { // @codingStandardsIgnoreLine
|
||||
return $this->selectFunc( 'sum', $field, $alias );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to add a avg function
|
||||
*
|
||||
* ->selectAvg('id')
|
||||
* ->selectAvg('id', 'average')
|
||||
*
|
||||
* @param string $field Column name.
|
||||
* @param string $alias (Optional) Column alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function selectAvg( $field, $alias = null ) { // @codingStandardsIgnoreLine
|
||||
return $this->selectFunc( 'avg', $field, $alias );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to add a function
|
||||
*
|
||||
* @param string $func Function name.
|
||||
* @param string $field Column name.
|
||||
* @param string $alias (Optional) Column alias.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function selectFunc( $func, $field, $alias = null ) { // @codingStandardsIgnoreLine
|
||||
$func = \strtoupper( $func );
|
||||
$field = "$func({$field})";
|
||||
if ( ! is_null( $alias ) ) {
|
||||
$field .= " AS {$alias}";
|
||||
}
|
||||
|
||||
$this->add_sql_clause( 'select', $field );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Distinct select setter
|
||||
*
|
||||
* @param bool $distinct Is disticnt.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function distinct( $distinct = true ) {
|
||||
$this->distinct = $distinct;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL_CALC_FOUND_ROWS select setter
|
||||
*
|
||||
* @param bool $found_rows Should get found rows.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function found_rows( $found_rows = true ) {
|
||||
$this->found_rows = $found_rows;
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* The translate functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Translate class.
|
||||
*/
|
||||
trait Translate {
|
||||
|
||||
/**
|
||||
* Translate the current query to an SQL select statement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateSelect() { // @codingStandardsIgnoreLine
|
||||
$query = [ 'SELECT' ];
|
||||
|
||||
if ( $this->found_rows ) {
|
||||
$query[] = 'SQL_CALC_FOUND_ROWS';
|
||||
}
|
||||
|
||||
if ( $this->distinct ) {
|
||||
$query[] = 'DISTINCT';
|
||||
}
|
||||
|
||||
$query[] = $this->has_sql_clause( 'select' ) ? $this->get_sql_clause( 'select', true ) : '*';
|
||||
$query[] = $this->translateFrom();
|
||||
$query[] = $this->get_sql_clause( 'join', true );
|
||||
$query[] = $this->get_sql_clause( 'where', true );
|
||||
$query[] = $this->translateGroupBy();
|
||||
$query[] = $this->translateOrderBy();
|
||||
$query[] = $this->translateLimit();
|
||||
|
||||
return join( ' ', array_filter( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the current query to an SQL update statement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateUpdate() { // @codingStandardsIgnoreLine
|
||||
$query = [ "UPDATE {$this->table} SET" ];
|
||||
|
||||
// Add the values.
|
||||
$values = [];
|
||||
foreach ( $this->sql_clauses['values'] as $key => $value ) {
|
||||
$values[] = $key . ' = ' . $this->esc_value( $value );
|
||||
}
|
||||
|
||||
if ( ! empty( $values ) ) {
|
||||
$query[] = join( ', ', $values );
|
||||
}
|
||||
|
||||
$query[] = $this->get_sql_clause( 'where', true );
|
||||
$query[] = $this->translateLimit();
|
||||
|
||||
return join( ' ', array_filter( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the current query to an SQL delete statement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateDelete() { // @codingStandardsIgnoreLine
|
||||
$query = [ 'DELETE' ];
|
||||
$query[] = $this->translateFrom();
|
||||
$query[] = $this->get_sql_clause( 'where', true );
|
||||
$query[] = $this->translateLimit();
|
||||
|
||||
return join( ' ', array_filter( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the from statement.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateFrom() { // @codingStandardsIgnoreLine
|
||||
if ( ! $this->has_sql_clause( 'from' ) ) {
|
||||
$this->add_sql_clause( 'from', $this->table );
|
||||
}
|
||||
|
||||
return 'FROM ' . $this->get_sql_clause( 'from', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the order by statement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function translateOrderBy() { // @codingStandardsIgnoreLine
|
||||
if ( ! $this->has_sql_clause( 'order_by' ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return 'ORDER BY ' . $this->get_sql_clause( 'order_by', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the group by clauses.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateGroupBy() { // @codingStandardsIgnoreLine
|
||||
if ( ! $this->has_sql_clause( 'group_by' ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$group_by = 'GROUP BY ' . $this->get_sql_clause( 'group_by', true );
|
||||
|
||||
if ( $this->has_sql_clause( 'having' ) ) {
|
||||
$group_by .= ' ' . $this->get_sql_clause( 'having', true );
|
||||
}
|
||||
|
||||
return $group_by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build offset and limit.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateLimit() { // @codingStandardsIgnoreLine
|
||||
return $this->get_sql_clause( 'limit', true );
|
||||
}
|
||||
}
|
@@ -0,0 +1,366 @@
|
||||
<?php
|
||||
/**
|
||||
* The where functions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Admin\Database
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Admin\Database;
|
||||
|
||||
/**
|
||||
* Where class.
|
||||
*/
|
||||
trait Where {
|
||||
|
||||
/**
|
||||
* Create a where statement
|
||||
*
|
||||
* ->where('name', 'ladina')
|
||||
* ->where('age', '>', 18)
|
||||
* ->where('name', 'in', ['charles', 'john', 'jeffry'])
|
||||
*
|
||||
* @throws \Exception If $type is not 'AND', 'OR', 'WHERE'.
|
||||
*
|
||||
* @param mixed $column The SQL column.
|
||||
* @param mixed $param1 Operator or value depending if $param2 isset.
|
||||
* @param mixed $param2 The value if $param1 is an operator.
|
||||
* @param string $type the where type ( AND, OR ).
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function where( $column, $param1 = null, $param2 = null, $type = 'AND' ) {
|
||||
|
||||
$this->is_valid_type( $type );
|
||||
|
||||
$sub_type = is_null( $param1 ) ? $type : $param1;
|
||||
if ( ! $this->has_sql_clause( 'where' ) ) {
|
||||
$type = 'WHERE';
|
||||
}
|
||||
|
||||
// When column is an array we assume to make a bulk and where.
|
||||
if ( is_array( $column ) ) {
|
||||
$this->bulk_where( $column, $type, $sub_type );
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->add_sql_clause( 'where', $this->generateWhere( $column, $param1, $param2, $type ) );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an or where statement
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param mixed $param1 Operator or value depending if $param2 isset.
|
||||
* @param mixed $param2 The value if $param1 is an operator.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhere( $column, $param1 = null, $param2 = null ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, $param1, $param2, 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where in statement
|
||||
*
|
||||
* ->whereIn('id', [42, 38, 12])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereIn( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'IN', $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where in statement
|
||||
*
|
||||
* ->orWhereIn('id', [42, 38, 12])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereIn( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'IN', $options, 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where not in statement
|
||||
*
|
||||
* ->whereNotIn('id', [42, 38, 12])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereNotIn( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'NOT IN', $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where not in statement
|
||||
*
|
||||
* ->orWhereNotIn('id', [42, 38, 12])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereNotIn( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'NOT IN', $options, 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where between statement
|
||||
*
|
||||
* ->whereBetween('id', [10, 100])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereBetween( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'BETWEEN', $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where between statement
|
||||
*
|
||||
* ->orWhereBetween('id', [10, 100])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereBetween( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'BETWEEN', $options, 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where not between statement
|
||||
*
|
||||
* ->whereNotBetween('id', [10, 100])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereNotBetween( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'NOT BETWEEN', $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where not between statement
|
||||
*
|
||||
* ->orWhereNotBetween('id', [10, 100])
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param array $options Array of values for in statement.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereNotBetween( $column, $options ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'NOT BETWEEN', $options, 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where like statement
|
||||
*
|
||||
* ->whereLike('id', 'value')
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param string $value Value for like statement.
|
||||
* @param string $start (Optional) The start of like query.
|
||||
* @param string $end (Optional) The end of like query.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereLike( $column, $value, $start = '%', $end = '%' ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'LIKE', $this->esc_like( $value, $start, $end ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where like statement
|
||||
*
|
||||
* ->orWhereLike('id', 'value')
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param string $value Value for like statement.
|
||||
* @param string $start (Optional) The start of like query.
|
||||
* @param string $end (Optional) The end of like query.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereLike( $column, $value, $start = '%', $end = '%' ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'LIKE', $this->esc_like( $value, $start, $end ), 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where not like statement
|
||||
*
|
||||
* ->whereNotLike('id', 'value' )
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param mixed $value Value for like statement.
|
||||
* @param string $start (Optional) The start of like query.
|
||||
* @param string $end (Optional) The end of like query.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereNotLike( $column, $value, $start = '%', $end = '%' ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'NOT LIKE', $this->esc_like( $value, $start, $end ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where not like statement
|
||||
*
|
||||
* ->orWhereNotLike('id', 'value' )
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param mixed $value Value for like statement.
|
||||
* @param string $start (Optional) The start of like query.
|
||||
* @param string $end (Optional) The end of like query.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereNotLike( $column, $value, $start = '%', $end = '%' ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'NOT LIKE', $this->esc_like( $value, $start, $end ), 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where is null statement
|
||||
*
|
||||
* ->whereNull( 'name' )
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereNull( $column ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'IS', 'NULL' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where is null statement
|
||||
*
|
||||
* ->orWhereNull( 'name' )
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereNull( $column ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'IS', 'NULL', 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where is not null statement
|
||||
*
|
||||
* ->whereNotNull( 'name' )
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function whereNotNull( $column ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'IS NOT', 'NULL' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a where is not null statement
|
||||
*
|
||||
* ->orWhereNotNull( 'name' )
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
*
|
||||
* @return self The current query builder.
|
||||
*/
|
||||
public function orWhereNotNull( $column ) { // @codingStandardsIgnoreLine
|
||||
return $this->where( $column, 'IS NOT', 'NULL', 'OR' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Where clause
|
||||
*
|
||||
* @param string $column The SQL column.
|
||||
* @param mixed $param1 Operator or value depending if $param2 isset.
|
||||
* @param mixed $param2 The value if $param1 is an operator.
|
||||
* @param string $type the where type ( AND, or ).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateWhere( $column, $param1 = null, $param2 = null, $type = 'AND' ) { // @codingStandardsIgnoreLine
|
||||
|
||||
// when param2 is null we replace param2 with param one as the
|
||||
// value holder and make param1 to the = operator.
|
||||
if ( is_null( $param2 ) ) {
|
||||
$param2 = $param1;
|
||||
$param1 = '=';
|
||||
}
|
||||
|
||||
// When param2 is an array we probably
|
||||
// have an "in" or "between" statement which has no need for duplicates.
|
||||
if ( is_array( $param2 ) ) {
|
||||
$param2 = $this->esc_array( array_unique( $param2 ) );
|
||||
$param2 = in_array( $param1, [ 'BETWEEN', 'NOT BETWEEN' ], true ) ? join( ' AND ', $param2 ) : '(' . join( ', ', $param2 ) . ')';
|
||||
} elseif ( is_scalar( $param2 ) ) {
|
||||
$param2 = $this->esc_value( $param2 );
|
||||
}
|
||||
|
||||
return join( ' ', [ $type, $column, $param1, $param2 ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the where type is valid.
|
||||
*
|
||||
* @param string $type Value to check.
|
||||
*
|
||||
* @throws \Exception If not a valid type.
|
||||
*/
|
||||
private function is_valid_type( $type ) {
|
||||
if ( ! in_array( $type, [ 'AND', 'OR', 'WHERE' ], true ) ) {
|
||||
throw new \Exception( 'Invalid where type "' . $type . '"' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create bulk where statement.
|
||||
*
|
||||
* @param array $where Array of statments.
|
||||
* @param string $type Statement type.
|
||||
* @param string $sub_type Statement sub-type.
|
||||
*/
|
||||
private function bulk_where( $where, $type, $sub_type ) {
|
||||
$subquery = [];
|
||||
foreach ( $where as $value ) {
|
||||
if ( ! isset( $value[2] ) ) {
|
||||
$value[2] = $value[1];
|
||||
$value[1] = '=';
|
||||
}
|
||||
$subquery[] = $this->generateWhere( $value[0], $value[1], $value[2], empty( $subquery ) ? '' : $sub_type );
|
||||
}
|
||||
|
||||
$this->add_sql_clause( 'where', $type . ' ( ' . trim( join( ' ', $subquery ) ) . ' )' );
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
Reference in New Issue
Block a user