158 lines
3.9 KiB
PHP
158 lines
3.9 KiB
PHP
<?php
|
|
/**
|
|
* Base Custom Database Table Compare Query Class.
|
|
*
|
|
* @package Database
|
|
* @subpackage Compare
|
|
* @copyright Copyright (c) 2020
|
|
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
|
* @since 1.0.0
|
|
*/
|
|
namespace EDD\Database\Queries;
|
|
|
|
// Exit if accessed directly
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* Class used for generating SQL for compare clauses.
|
|
*
|
|
* This class is used to generate the SQL when a `compare` argument is passed to
|
|
* the `Base` query class. It extends `Meta` so the `compare` key accepts
|
|
* the same parameters as the ones passed to `Meta`.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
class Compare extends Meta {
|
|
|
|
/**
|
|
* Generate SQL WHERE clauses for a first-order query clause.
|
|
*
|
|
* "First-order" means that it's an array with a 'key' or 'value'.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param array $clause Query clause (passed by reference).
|
|
* @param array $parent_query Parent query array.
|
|
* @param string $clause_key Optional. The array key used to name the clause in the original `$meta_query`
|
|
* parameters. If not provided, a key will be generated automatically.
|
|
* @return array {
|
|
* Array containing WHERE SQL clauses to append to a first-order query.
|
|
*
|
|
* @type string $where SQL fragment to append to the main WHERE clause.
|
|
* }
|
|
*/
|
|
public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) {
|
|
global $wpdb;
|
|
|
|
$sql_chunks = array(
|
|
'where' => array(),
|
|
'join' => array(),
|
|
);
|
|
|
|
if ( isset( $clause['compare'] ) ) {
|
|
$clause['compare'] = strtoupper( $clause['compare'] );
|
|
} else {
|
|
$clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '=';
|
|
}
|
|
|
|
if ( ! in_array(
|
|
$clause['compare'], array(
|
|
'=',
|
|
'!=',
|
|
'>',
|
|
'>=',
|
|
'<',
|
|
'<=',
|
|
'LIKE',
|
|
'NOT LIKE',
|
|
'IN',
|
|
'NOT IN',
|
|
'BETWEEN',
|
|
'NOT BETWEEN',
|
|
'EXISTS',
|
|
'NOT EXISTS',
|
|
'REGEXP',
|
|
'NOT REGEXP',
|
|
'RLIKE',
|
|
), true
|
|
) ) {
|
|
$clause['compare'] = '=';
|
|
}
|
|
|
|
if ( isset( $clause['compare_key'] ) && 'LIKE' === strtoupper( $clause['compare_key'] ) ) {
|
|
$clause['compare_key'] = strtoupper( $clause['compare_key'] );
|
|
} else {
|
|
$clause['compare_key'] = '=';
|
|
}
|
|
|
|
$compare = $clause['compare'];
|
|
$compare_key = $clause['compare_key'];
|
|
|
|
// Build the WHERE clause.
|
|
|
|
// Column name and value.
|
|
if ( array_key_exists( 'key', $clause ) && array_key_exists( 'value', $clause ) ) {
|
|
$column = sanitize_key( $clause['key'] );
|
|
$value = $clause['value'];
|
|
|
|
if ( in_array( $compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ), true ) ) {
|
|
if ( ! is_array( $value ) ) {
|
|
$value = preg_split( '/[,\s]+/', $value );
|
|
}
|
|
} else {
|
|
$value = trim( $value );
|
|
}
|
|
|
|
switch ( $compare ) {
|
|
case 'IN':
|
|
case 'NOT IN':
|
|
$compare_string = '(' . substr( str_repeat( ',%s', count( $value ) ), 1 ) . ')';
|
|
$where = $wpdb->prepare( $compare_string, $value );
|
|
break;
|
|
|
|
case 'BETWEEN':
|
|
case 'NOT BETWEEN':
|
|
$value = array_slice( $value, 0, 2 );
|
|
$where = $wpdb->prepare( '%s AND %s', $value );
|
|
break;
|
|
|
|
case 'LIKE':
|
|
case 'NOT LIKE':
|
|
$value = '%' . $wpdb->esc_like( $value ) . '%';
|
|
$where = $wpdb->prepare( '%s', $value );
|
|
break;
|
|
|
|
// EXISTS with a value is interpreted as '='.
|
|
case 'EXISTS':
|
|
$compare = '=';
|
|
$where = $wpdb->prepare( '%s', $value );
|
|
break;
|
|
|
|
// 'value' is ignored for NOT EXISTS.
|
|
case 'NOT EXISTS':
|
|
$where = '';
|
|
break;
|
|
|
|
default:
|
|
$where = $wpdb->prepare( '%s', $value );
|
|
break;
|
|
|
|
}
|
|
|
|
if ( $where ) {
|
|
$sql_chunks['where'][] = "{$column} {$compare} {$where}";
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Multiple WHERE clauses (for meta_key and meta_value) should
|
|
* be joined in parentheses.
|
|
*/
|
|
if ( 1 < count( $sql_chunks['where'] ) ) {
|
|
$sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' );
|
|
}
|
|
|
|
return $sql_chunks;
|
|
}
|
|
}
|