LLMS_Database_Query
Database Query abstract class.
Source Source
File: includes/abstracts/abstract.llms.database.query.php
abstract class LLMS_Database_Query extends LLMS_Abstract_Query { /** * Identify the extending query. * * @var string */ protected $id = 'database'; /** * Retrieve query argument default values. * * @since 6.0.0 * * @return array */ protected function default_arguments() { return wp_parse_args( array( 'per_page' => 25, 'sort' => array( 'id' => 'ASC', ), ), parent::default_arguments() ); } /** * Escape and add quotes to a string, useful for array mapping when building queries. * * @since 3.8.0 * @since 6.0.0 Use {@see llms_esc_and_quote_str()}. * * @param mixed $input Input data. * @return string */ public function escape_and_quote_string( $input ) { return llms_esc_and_quote_str( $input ); } /** * Retrieve default arguments for the query. * * @since 3.8.0 * @since 4.5.1 Added new default arg `no_found_rows` set to false. * @since 6.0.0 Call parent method. * * @todo This should be removed in favor of the parent method only when the * `llms_db_query_get_default_args` hook is removed. * * @return array */ protected function get_default_args() { if ( $this->get( 'suppress_filters' ) ) { return $this->default_arguments(); } // Get them from the parent with the new replacement filter. $args = parent::get_default_args(); /** * Filters the query default args. * * @since 3.8.0 * @deprecated 6.0.0 Filter `llms_db_query_get_default_args` is deprecated in favor of `llms_{$this->id}_query_get_default_args`. * * @param array $args Array of default arguments to set up the query with. */ return apply_filters_deprecated( 'llms_db_query_get_default_args', array( $args ), '6.0.0', "llms_{$this->id}_query_get_default_args" ); } /** * Get a string used as filter names unique to the extending query. * * @since 3.8.0 * * @todo Deprecate. * * @param string $filter Filter name. * @return string */ protected function get_filter( $filter ) { return 'llms_' . $this->id . '_query_' . $filter; } /** * Get the number of results to skip for the query based on the current page and per_page vars. * * @since 3.8.0 * * @return int */ protected function get_skip() { return absint( ( $this->get( 'page' ) - 1 ) * $this->get( 'per_page' ) ); } /** * Performs the SQL query. * * @since 6.0.0 * * @return array An integer-keyed array of row objects. */ protected function perform_query() { global $wpdb; return $wpdb->get_results( $this->query ); // phpcs:ignore: WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared } /** * Set variables related to total number of results and pages possible with supplied arguments. * * @since 3.8.0 * @since 4.5.1 Bail early if the query arg `no_found_rows` is true, b/c no reason to calculate anything. * @deprecated 6.0.0 `LLMS_Database_Query::set_found_results()` is deprecated. * * @return void */ protected function set_found_results() { _deprecated_function( 'LLMS_Database_Query::set_found_results()', '6.0.0' ); // If no results, or found rows not required, bail early b/c no reason to calculate anything. if ( ! $this->number_results || $this->get( 'no_found_rows' ) ) { return; } $this->found_results = $this->found_results(); $this->max_pages = absint( ceil( $this->found_results / $this->get( 'per_page' ) ) ); } /** * Perform a SQL to retrieve the total number of found results for the given query. * * @since 6.0.0 * * @return int */ protected function found_results() { global $wpdb; return (int) $wpdb->get_var( 'SELECT FOUND_ROWS()' ); // db call ok; no-cache ok. } /** * Retrieve the prepared SQL for the SELECT clause. * * @since 4.5.1 * * @param string $select_columns Optional. Columns to select. Default '*'. * @return string */ protected function sql_select_columns( $select_columns = '*' ) { if ( ! $this->get( 'no_found_rows' ) ) { $select_columns = 'SQL_CALC_FOUND_ROWS ' . $select_columns; } if ( $this->get( 'suppress_filters' ) ) { return $select_columns; } /** * Filters the query SELECT columns. * * The dynamic part of the filter `$this->id` identifies the extending query. * * @since 4.5.1 * * @param string $select_columns Columns to select. * @param LLMS_Database_Query $db_query Instance of LLMS_Database_Query. */ return apply_filters( "llms_{$this->id}_query_select_columns", $select_columns, $this ); } /** * Retrieve the prepared SQL for the LIMIT clause. * * @since 3.16.0 * @since 4.5.1 Drop use of `$this->get_filter('limit')` in favor of `"llms_{$this->id}_query_limit"`. * * @return string */ protected function sql_limit() { global $wpdb; $sql = $wpdb->prepare( 'LIMIT %d, %d', $this->get_skip(), $this->get( 'per_page' ) ); /** * Filters the query LIMIT clause. * * The dynamic part of the filter `$this->id` identifies the extending query. * * @since 3.16.0 * * @param string $sql The LIMIT clause of the query. * @param LLMS_Database_Query $db_query The LLMS_Database_Query instance. */ return apply_filters( "llms_{$this->id}_query_limit", $sql, $this ); } /** * Retrieve the prepared SQL for the ORDER BY clause. * * @since 3.8.0 * @since 3.34.0 Returns an empty string if no sort fields are available. * @since 4.5.1 Drop use of `$this->get_filter('orderby')` in favor of `"llms_{$this->id}_query_orderby"`. * * @return string */ protected function sql_orderby() { $sql = ''; $sort = $this->get( 'sort' ); if ( $sort ) { $sql = 'ORDER BY'; $comma = false; foreach ( $sort as $orderby => $order ) { $pre = ( $comma ) ? ', ' : ' '; $sql .= $pre . "{$orderby} {$order}"; $comma = true; } } if ( $this->get( 'suppress_filters' ) ) { return $sql; } /** * Filters the query ORDER BY clause. * * The dynamic part of the filter `$this->id` identifies the extending query. * * @since 3.8.0 * * @param string $sql The ORDER BY clause of the query. * @param LLMS_Database_Query $db_query The LLMS_Database_Query instance. */ return apply_filters( "llms_{$this->id}_query_orderby", $sql, $this ); } /** * Gets information about properties that used to be public and have been replaced with public getters. * * Used by `__get()` and `__set()` and will be removed when these are properly removed in the next * major release. * * @since 6.0.0 * * @return array */ private function legacy_public_props() { return array( // Property => $0 = alternative prop or method, $1 = has replacement. 'found_results' => array( 'get_found_results', true ), 'max_pages' => array( 'get_max_pages', true ), 'number_results' => array( 'get_number_results', true ), 'query_vars' => array( 'query_vars', false ), 'results' => array( 'get_results', true ), ); } /** * Throws a deprecation message when a formerly public property is accessed directly. * * @since 6.0.0 * * @param string $prop Property name. * @return void */ private function public_prop_deprecation( $prop ) { $legacy_props = $this->legacy_public_props(); list( $val, $has_replacement ) = $legacy_props[ $prop ]; $class = get_called_class(); $is_method = method_exists( $this, $val ); $suffix = $is_method ? '()' : ''; _deprecated_function( "Public access to property {$class}::{$prop}", '6.0.0', $has_replacement ? "{$class}::{$val}{$suffix}" : '' ); } /** * Preserve backwards compat for read access to formerly public and removed class properties. * * @since 6.0.0 * * @param string $key Property key name. * @return mixed */ public function __get( $key ) { // Handle formerly public properties. $legacy_props = $this->legacy_public_props(); if ( array_key_exists( $key, $legacy_props ) ) { $this->public_prop_deprecation( $key ); $val = $legacy_props[ $key ][0]; return method_exists( $this, $val ) ? $this->$val() : $this->$val; } elseif ( 'sql' === $key ) { $class = get_called_class(); _deprecated_function( "Property {$class}::sql", '6.0.0', "{$class}::get_query()" ); return $this->query; } } /** * Preserve backwards compat for write access to formerly public and removed class properties. * * @since 6.0.0 * * @param string $key Property name. * @param mixed $val Property value. * @return void */ public function __set( $key, $val ) { $legacy_props = $this->legacy_public_props(); if ( array_key_exists( $key, $legacy_props ) ) { $this->public_prop_deprecation( $key ); $this->$key = $val; } elseif ( 'sql' === $key ) { $class = get_called_class(); _deprecated_function( "Property {$class}::sql", '6.0.0', "{$class}::query" ); $this->query = $val; } } /** * Handle backwards compatibility for the misspelled (and removed) method `preprare_query()`. * * @since 6.0.0 * * @param string $name Method name. * @param array $args Arguments passed to the method. * @return void|string */ public function __call( $name, $args ) { if ( 'preprare_query' === $name ) { $class = get_called_class(); _deprecated_function( "{$class}::preprare_query()", '6.0.0', "{$class}::prepare_query()" ); return $this->prepare_query(); } } /** * Prepare the query. * * Should return the query which will be used by `query()`. * * This *should* be an abstract method but is defined here for backwards compatibility * to preserve the previous method, `preprare_query()` (notice the misspelling). * * Once the `preprare_query()` method is fully removed in the next major release this * method can be removed in favor of the abstract from the parent class. * * @since 6.0.0 * * @return mixed */ protected function prepare_query() { if ( method_exists( $this, 'preprare_query' ) ) { $class = get_called_class(); _deprecated_function( "{$class}::preprare_query()", '6.0.0', "{$class}::prepare_query()" ); return $this->preprare_query(); } else { _doing_it_wrong( __METHOD__, sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'lifterlms' ), __METHOD__ ), '6.0.0' ); } } }
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __call — Handle backwards compatibility for the misspelled (and removed) method `preprare_query()`.
- __construct — Constructor.
- __get — Preserve backwards compat for read access to formerly public and removed class properties.
- __set — Preserve backwards compat for write access to formerly public and removed class properties.
- default_arguments — Retrieve query argument default values.
- escape_and_quote_string — Escape and add quotes to a string, useful for array mapping when building queries.
- found_results — Perform a SQL to retrieve the total number of found results for the given query.
- get — Retrieve a query variable with an optional fallback / default.
- get_default_args — Retrieve default arguments for the query.
- get_filter — Get a string used as filter names unique to the extending query.
- get_results — Retrieve an array of results for the given query.
- get_skip — Get the number of results to skip for the query based on the current page and per_page vars.
- has_results — Determine if the query has at least one result.
- is_first_page — Determine if we're on the first page of results.
- is_last_page — Determine if we're on the last page of results.
- legacy_public_props — Gets information about properties that used to be public and have been replaced with public getters.
- parse_args — Parse arguments needed for the query.
- perform_query — Performs the SQL query.
- prepare_query — Prepare the query.
- preprare_query — Prepare the SQL for the query.
- public_prop_deprecation — Throws a deprecation message when a formerly public property is accessed directly.
- query — Execute a query.
- sanitize_id_array — Sanitize input to ensure an array of absints.
- sanitize_sort — Removes any invalid sort fields before preparing a query.
- set — Sets a query variable.
- set_found_results — Set variables related to total number of results and pages possible with supplied arguments. — deprecated
- setup_args — Setup arguments prior to a query.
- sql_limit — Retrieve the prepared SQL for the LIMIT clause.
- sql_orderby — Retrieve the prepared SQL for the ORDER BY clause.
- sql_select_columns — Retrieve the prepared SQL for the SELECT clause.
Changelog Changelog
Version | Description |
---|---|
3.8.0 | |
3.34.0 | Sanitizes sort parameters. |
3.30.3 | Introduced. |