: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
protected function add_where( $fragment, $values = [] ) {
return $this->add_condition( 'where', $fragment, $values );
* Adds a WHERE condition to the query. Internal method.
* @param string|array $column_name The table column.
* @param string $separator The separator.
* @param mixed $value The value.
protected function add_simple_where( $column_name, $separator, $value ) {
return $this->add_simple_condition( 'where', $column_name, $separator, $value );
* Adds a WHERE clause with multiple values (like IN and NOT IN).
* @param string|array $column_name The table column.
* @param string $separator The separator.
* @param array $values The values.
public function add_where_placeholder( $column_name, $separator, $values ) {
if ( ! \is_array( $column_name ) ) {
$data = [ $column_name => $values ];
foreach ( $data as $key => $val ) {
$column = $result->quote_identifier( $key );
$placeholders = $result->create_placeholders( $val );
$result = $result->add_where( "{$column} {$separator} ({$placeholders})", $val );
* Adds a WHERE clause with no parameters(like IS NULL and IS NOT NULL).
* @param string $column_name The column name.
* @param string $operator The operator.
public function add_where_no_value( $column_name, $operator ) {
$conditions = \is_array( $column_name ) ? $column_name : [ $column_name ];
foreach ( $conditions as $column ) {
$column = $this->quote_identifier( $column );
$result = $result->add_where( "{$column} {$operator}" );
* Adds a HAVING or WHERE condition to the query. Internal method.
* @param string $type The type.
* @param string $fragment The fragment.
* @param array $values The values. Defaults to empty array.
protected function add_condition( $type, $fragment, $values = [] ) {
$conditions_class_property_name = "{$type}_conditions";
if ( ! \is_array( $values ) ) {
$this->{$conditions_class_property_name},
self::CONDITION_FRAGMENT => $fragment,
self::CONDITION_VALUES => $values,
* Compiles a simple COLUMN SEPARATOR VALUE style HAVING or WHERE condition into a string and value ready to be
* passed to the add_condition method.
* Avoids duplication of the call to quote_identifier.
* If column_name is an associative array, it will add a condition for each column.
* @param string $type The type.
* @param string|array $column_name The table column.
* @param string $separator The separator.
* @param mixed $value The value.
protected function add_simple_condition( $type, $column_name, $separator, $value ) {
$multiple = \is_array( $column_name ) ? $column_name : [ $column_name => $value ];
foreach ( $multiple as $key => $val ) {
// Add the table name in case of ambiguous columns.
if ( \count( $result->join_sources ) > 0 && \strpos( $key, '.' ) === false ) {
$table = $result->table_name;
if ( ! \is_null( $result->table_alias ) ) {
$table = $result->table_alias;
$key = "{$table}.{$key}";
$key = $result->quote_identifier( $key );
$placeholder = ( $val === null ) ? 'NULL' : '%s';
$result = $result->add_condition( $type, "{$key} {$separator} {$placeholder}", $val );
* Returns a string containing the given number of question marks, separated by commas. Eg "?, ?, ?".
* @param array $fields Fields to create placeholder for.
protected function create_placeholders( $fields ) {
if ( ! empty( $fields ) ) {
foreach ( $fields as $key => $value ) {
// Process expression fields directly into the query.
if ( \array_key_exists( $key, $this->expr_fields ) ) {
$db_fields[] = ( $value === null ) ? 'NULL' : '%s';
return \implode( ', ', $db_fields );
* Filters a column/value array returning only those columns that belong to a compound primary key.
* If the key contains a column that does not exist in the given array, a null value will be returned for it.
* @param mixed $value The value.
protected function get_compound_id_column_values( $value ) {
foreach ( $this->get_id_column_name() as $key ) {
$filtered[ $key ] = ( $value[ $key ] ?? null );
* Filters an array containing compound column/value arrays.
* @param array $values The values.
protected function get_compound_id_column_values_array( $values ) {
foreach ( $values as $value ) {
$filtered[] = $this->get_compound_id_column_values( $value );
* Add a WHERE column = value clause to your query. Each time this is called in the chain, an additional WHERE will
* be added, and these will be ANDed together when the final query is built.
* If you use an array in $column_name, a new clause will be added for each element. In this case, $value is
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where( $column_name, $value = null ) {
return $this->where_equal( $column_name, $value );
* More explicitly named version of for the where() method. Can be used if preferred.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_equal( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, '=', $value );
* Add a WHERE column != value clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_not_equal( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, '!=', $value );
* Queries the table by its primary key. Special method.
* If primary key is compound, only the columns that belong to they key will be used for the query.
* @param string $id The ID.
public function where_id_is( $id ) {
return \is_array( $this->get_id_column_name() ) ? $this->where( $this->get_compound_id_column_values( $id ), null ) : $this->where( $this->get_id_column_name(), $id );
* Allows adding a WHERE clause that matches any of the conditions specified in the array. Each element in the
* associative array will be a different condition, where the key will be the column name.
* By default, an equal operator will be used against all columns, but it can be overriden for any or every column
* using the second parameter.
* Each condition will be ORed together when added to the final query.
* @param array $values The values.
* @param string $operator The operator.
public function where_any_is( $values, $operator = '=' ) {
foreach ( $values as $value ) {
foreach ( $value as $key => $item ) {
$op = \is_string( $operator ) ? $operator : ( $operator[ $key ] ?? '=' );
if ( $op === '=' && $item === null ) {
$query[] = $this->quote_identifier( $key );
$query[] = ( ( $item === null ) ? 'NULL' : '%s' );
return $this->where_raw( \implode( ' ', $query ), $data );
* Queries the table by its primary key.
* Similar to where_id_is() but allowing multiple primary keys.
* If primary key is compound, only the columns that belong to they key will be used for the query.
* @param string[] $ids The IDs.
public function where_id_in( $ids ) {
return \is_array( $this->get_id_column_name() ) ? $this->where_any_is( $this->get_compound_id_column_values_array( $ids ) ) : $this->where_in( $this->get_id_column_name(), $ids );
* Adds a WHERE ... LIKE clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_like( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, 'LIKE', $value );
* Adds where WHERE ... NOT LIKE clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_not_like( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, 'NOT LIKE', $value );
* Adds a WHERE ... > clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_gt( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, '>', $value );
* Adds a WHERE ... < clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_lt( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, '<', $value );
* Adds a WHERE ... >= clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_gte( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, '>=', $value );
* Adds a WHERE ... <= clause to your query.
* @param string|array $column_name The table column.
* @param mixed|null $value The value. Defaults to null.
public function where_lte( $column_name, $value = null ) {
return $this->add_simple_where( $column_name, '<=', $value );
* Adds a WHERE ... IN clause to your query.
* @param string|array $column_name The table column.
* @param array $values The values.
public function where_in( $column_name, $values ) {
return $this->add_where_placeholder( $column_name, 'IN', $values );
* Adds a WHERE ... NOT IN clause to your query.
* @param string|array $column_name The table column.
* @param array $values The values.
public function where_not_in( $column_name, $values ) {
return $this->add_where_placeholder( $column_name, 'NOT IN', $values );
* Adds a WHERE column IS NULL clause to your query.
* @param string|array $column_name The table column.
public function where_null( $column_name ) {
return $this->add_where_no_value( $column_name, 'IS NULL' );
* Adds a WHERE column IS NOT NULL clause to your query.
* @param string|array $column_name The table column.
public function where_not_null( $column_name ) {
return $this->add_where_no_value( $column_name, 'IS NOT NULL' );
* Adds a raw WHERE clause to the query. The clause should contain question mark placeholders, which will be bound
* to the parameters supplied in the second argument.
* @param string $clause The clause that should contain question mark placeholders.
* @param array $parameters The parameters to include in the query.
public function where_raw( $clause, $parameters = [] ) {
return $this->add_where( $clause, $parameters );
* Adds a LIMIT to the query.
* @param int $limit The limit.
public function limit( $limit ) {
* Adds an OFFSET to the query.
* @param int $offset The offset.
public function offset( $offset ) {
* Adds an ORDER BY clause to the query.
* @param string $column_name The column name.
* @param string $ordering The ordering. DESC or ASC.
protected function add_order_by( $column_name, $ordering ) {
$column_name = $this->quote_identifier( $column_name );
$this->order_by[] = "{$column_name} {$ordering}";
* Adds an ORDER BY column DESC clause.
* @param string|array $column_name The table column.
public function order_by_desc( $column_name ) {
return $this->add_order_by( $column_name, 'DESC' );
* Adds an ORDER BY column ASC clause.
* @param string|array $column_name The table column.
public function order_by_asc( $column_name ) {
return $this->add_order_by( $column_name, 'ASC' );
* Adds an unquoted expression as an ORDER BY clause.
* @param string $clause The clause.
public function order_by_expr( $clause ) {
$this->order_by[] = $clause;