: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Returns the select query as SQL.
* @return string The select query in SQL.
public function get_sql() {
return $this->build_select();
* Returns the update query as SQL.
* @return string The update query in SQL.
public function get_update_sql() {
return $this->build_update();
* Executes an aggregate query on the current connection.
* @param string $sql_function The aggregate function to call eg. MIN, COUNT, etc.
* @param string $column The column to execute the aggregate query against.
protected function call_aggregate_db_function( $sql_function, $column ) {
$alias = \strtolower( $sql_function );
$sql_function = \strtoupper( $sql_function );
$column = $this->quote_identifier( $column );
$result_columns = $this->result_columns;
$this->result_columns = [];
$this->select_expr( "{$sql_function}({$column})", $alias );
$result = $this->find_one();
$this->result_columns = $result_columns;
if ( $result !== false && isset( $result->{$alias} ) ) {
if ( ! \is_numeric( $result->{$alias} ) ) {
$return_value = $result->{$alias};
// phpcs:ignore Universal.Operators.StrictComparisons -- Reason: This loose comparison seems intentional.
elseif ( (int) $result->{$alias} == (float) $result->{$alias} ) {
$return_value = (int) $result->{$alias};
$return_value = (float) $result->{$alias};
* Hydrates (populate) this instance of the class from an associative array of data. This will usually be called
* only from inside the class, but it's public in case you need to call it directly.
* @param array $data Data to populate table.
public function hydrate( $data = [] ) {
* Forces the ORM to flag all the fields in the $data array as "dirty" and therefore update them when save() is
public function force_all_dirty() {
$this->dirty_fields = $this->data;
* Performs a raw query. The query can contain placeholders in either named or question mark style. If placeholders
* are used, the parameters should be an array of values which will be bound to the placeholders in the query.
* If this method is called, all other query building methods will be ignored.
* @param array $query The query.
* @param array $parameters The parameters. Defaults to an empty array.
public function raw_query( $query, $parameters = [] ) {
$this->is_raw_query = true;
$this->raw_query = $query;
$this->raw_parameters = $parameters;
* Adds an alias for the main table to be used in SELECT queries.
* @param string $alias The alias.
public function table_alias( $alias ) {
$this->table_alias = $alias;
* Adds an unquoted expression to the set of columns returned by the SELECT query. Internal method.
* @param string $expr The expression.
* @param string|null $alias The alias to return the expression as. Defaults to null.
protected function add_result_column( $expr, $alias = null ) {
if ( ! \is_null( $alias ) ) {
$expr .= ' AS ' . $this->quote_identifier( $alias );
if ( $this->using_default_result_columns ) {
$this->result_columns = [ $expr ];
$this->using_default_result_columns = false;
$this->result_columns[] = $expr;
* Counts the number of columns that belong to the primary key and their value is null.
* @return int The amount of null columns.
* @throws Exception Primary key ID contains null value(s).
* @throws Exception Primary key ID missing from row or is null.
public function count_null_id_columns() {
if ( \is_array( $this->get_id_column_name() ) ) {
return \count( \array_filter( $this->id(), 'is_null' ) );
return \is_null( $this->id() ) ? 1 : 0;
* Adds a column to the list of columns returned by the SELECT query.
* @param string $column The column. Defaults to '*'.
* @param string|null $alias The alias to return the column as. Defaults to null.
public function select( $column, $alias = null ) {
$column = $this->quote_identifier( $column );
return $this->add_result_column( $column, $alias );
* Adds an unquoted expression to the list of columns returned by the SELECT query.
* @param string $expr The expression.
* @param string|null $alias The alias to return the column as. Defaults to null.
public function select_expr( $expr, $alias = null ) {
return $this->add_result_column( $expr, $alias );
* Adds columns to the list of columns returned by the SELECT query.
* Many columns can be supplied as either an array or as a list of parameters to the method.
* Note that the alias must not be numeric - if you want a numeric alias then prepend it with some alpha chars. eg.
* @example select_many(array('column', 'column2', 'column3'), 'column4', 'column5');
* @example select_many(array('alias' => 'column', 'column2', 'alias2' => 'column3'), 'column4', 'column5');
* @example select_many('column', 'column2', 'column3');
public function select_many() {
$columns = \func_get_args();
if ( ! empty( $columns ) ) {
$columns = $this->normalise_select_many_columns( $columns );
foreach ( $columns as $alias => $column ) {
if ( \is_numeric( $alias ) ) {
$this->select( $column, $alias );
* Adds an unquoted expression to the list of columns returned by the SELECT query.
* Many columns can be supplied as either an array or as a list of parameters to the method.
* Note that the alias must not be numeric - if you want a numeric alias then prepend it with some alpha chars. eg.
* @example select_many_expr(array('alias' => 'column', 'column2', 'alias2' => 'column3'), 'column4', 'column5')
* @example select_many_expr('column', 'column2', 'column3')
* @example select_many_expr(array('column', 'column2', 'column3'), 'column4', 'column5')
public function select_many_expr() {
$columns = \func_get_args();
if ( ! empty( $columns ) ) {
$columns = $this->normalise_select_many_columns( $columns );
foreach ( $columns as $alias => $column ) {
if ( \is_numeric( $alias ) ) {
$this->select_expr( $column, $alias );
* Takes a column specification for the select many methods and convert it into a normalised array of columns and
* It is designed to turn the following styles into a normalised array:
* array(array('alias' => 'column', 'column2', 'alias2' => 'column3'), 'column4', 'column5'))
* @param array $columns The columns.
protected function normalise_select_many_columns( $columns ) {
foreach ( $columns as $column ) {
if ( \is_array( $column ) ) {
foreach ( $column as $key => $value ) {
if ( ! \is_numeric( $key ) ) {
$return[ $key ] = $value;
* Adds a DISTINCT keyword before the list of columns in the SELECT query.
public function distinct() {
* Add a JOIN source to the query. Internal method.
* The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this
* will be prepended to JOIN.
* The table should be the name of the table to join to.
* The constraint may be either a string or an array with three elements. If it
* is a string, it will be compiled into the query as-is, with no escaping. The
* recommended way to supply the constraint is as an array with three elements:
* first_column, operator, second_column
* Example: array('user.id', '=', 'profile.user_id')
* ON `user`.`id` = `profile`.`user_id`
* The final (optional) argument specifies an alias for the joined table.
* @param string $join_operator The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be
* @param string $table The table should be the name of the table to join to.
* @param string $constraint The constraint.
* @param string|null $table_alias The alias for the joined table. Defaults to null.
protected function add_join_source( $join_operator, $table, $constraint, $table_alias = null ) {
$join_operator = \trim( "{$join_operator} JOIN" );
$table = $this->quote_identifier( $table );
// Add table alias if present.
if ( ! \is_null( $table_alias ) ) {
$table_alias = $this->quote_identifier( $table_alias );
$table .= " {$table_alias}";
if ( \is_array( $constraint ) ) {
list( $first_column, $operator, $second_column ) = $constraint;
$first_column = $this->quote_identifier( $first_column );
$second_column = $this->quote_identifier( $second_column );
$constraint = "{$first_column} {$operator} {$second_column}";
$this->join_sources[] = "{$join_operator} {$table} ON {$constraint}";
* Adds a RAW JOIN source to the query.
* @param string $table The table name.
* @param string $constraint The constraint.
* @param string $table_alias The table alias.
* @param array $parameters The parameters. Defaults to an empty array.
public function raw_join( $table, $constraint, $table_alias, $parameters = [] ) {
// Add table alias if present.
if ( ! \is_null( $table_alias ) ) {
$table_alias = $this->quote_identifier( $table_alias );
$table .= " {$table_alias}";
$this->values = \array_merge( $this->values, $parameters );
if ( \is_array( $constraint ) ) {
list( $first_column, $operator, $second_column ) = $constraint;
$first_column = $this->quote_identifier( $first_column );
$second_column = $this->quote_identifier( $second_column );
$constraint = "{$first_column} {$operator} {$second_column}";
$this->join_sources[] = "{$table} ON {$constraint}";
* Adds a simple JOIN source to the query.
* @param string $table The table name.
* @param string $constraint The constraint.
* @param string|null $table_alias The table alias. Defaults to null.
public function join( $table, $constraint, $table_alias = null ) {
return $this->add_join_source( '', $table, $constraint, $table_alias );
* Adds an INNER JOIN source to the query.
* @param string $table The table name.
* @param string $constraint The constraint.
* @param string|null $table_alias The table alias. Defaults to null.
public function inner_join( $table, $constraint, $table_alias = null ) {
return $this->add_join_source( 'INNER', $table, $constraint, $table_alias );
* Adds a LEFT OUTER JOIN source to the query.
* @param string $table The table name.
* @param string $constraint The constraint.
* @param string|null $table_alias The table alias. Defaults to null.
public function left_outer_join( $table, $constraint, $table_alias = null ) {
return $this->add_join_source( 'LEFT OUTER', $table, $constraint, $table_alias );
* Adds a RIGHT OUTER JOIN source to the query.
* @param string $table The table name.
* @param string $constraint The constraint.
* @param string|null $table_alias The table alias. Defaults to null.
public function right_outer_join( $table, $constraint, $table_alias = null ) {
return $this->add_join_source( 'RIGHT OUTER', $table, $constraint, $table_alias );
* Adds a FULL OUTER JOIN source to the query.
* @param string $table The table name.
* @param string $constraint The constraint.
* @param string|null $table_alias The table alias. Defaults to null.
public function full_outer_join( $table, $constraint, $table_alias = null ) {
return $this->add_join_source( 'FULL OUTER', $table, $constraint, $table_alias );
* Adds a HAVING condition to the query. Internal method.
* @param string $fragment The fragment.
* @param array $values The values. Defaults to an empty array.
protected function add_having( $fragment, $values = [] ) {
return $this->add_condition( 'having', $fragment, $values );
* Adds a HAVING condition to the query. Internal method.
* @param string $column_name The table column.
* @param string $separator The separator.
* @param mixed $value The value.
protected function add_simple_having( $column_name, $separator, $value ) {
return $this->add_simple_condition( 'having', $column_name, $separator, $value );
* Adds a HAVING clause with multiple values (like IN and NOT IN). Internal method.
* @param string|array $column_name The table column.
* @param string $separator The separator.
* @param array $values The values.
public function add_having_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_having( "{$column} {$separator} ({$placeholders})", $val );
* Adds a HAVING clause with no parameters(like IS NULL and IS NOT NULL). Internal method.
* @param string $column_name The column name.
* @param string $operator The operator.
public function add_having_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_having( "{$column} {$operator}" );
* Adds a WHERE condition to the query. Internal method.
* @param string $fragment The fragment.
* @param array $values The values. Defaults to an empty array.