bibhamrokhanpin/wp-content/plugins/top-10/includes/class-top-ten-query.php
2024-04-10 17:46:06 +05:45

517 lines
15 KiB
PHP

<?php
/**
* Query API: Top_Ten_Query class
*
* @package Top_Ten
* @subpackage Top_Ten_Query
* @since 3.0.0
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( ! class_exists( 'Top_Ten_Query' ) ) :
/**
* Query API: Top_Ten_Query class.
*
* @since 3.0.0
*/
class Top_Ten_Query extends WP_Query {
/**
* Query vars, before parsing.
*
* @since 3.0.2
* @var int[]
*/
public $blog_id;
/**
* Cache set flag.
*
* @since 3.0.0
* @var bool
*/
public $in_cache = false;
/**
* Daily flag.
*
* @since 3.0.0
* @var bool
*/
public $is_daily = false;
/**
* Query vars, before parsing.
*
* @since 3.0.2
* @var array
*/
public $input_query_args = array();
/**
* Query vars, after parsing.
*
* @since 3.0.0
* @var array
*/
public $query_args = array();
/**
* Top Ten table name being queried.
*
* @since 3.0.0
* @var string
*/
public $table_name;
/**
* Main constructor.
*
* @since 3.0.0
*
* @param array|string $args The Query variables. Accepts an array or a query string.
*/
public function __construct( $args = array() ) {
$this->prepare_query_args( $args );
add_filter( 'posts_fields', array( $this, 'posts_fields' ), 10, 2 );
add_filter( 'posts_join', array( $this, 'posts_join' ), 10, 2 );
add_filter( 'posts_where', array( $this, 'posts_where' ), 10, 2 );
add_filter( 'posts_orderby', array( $this, 'posts_orderby' ), 10, 2 );
add_filter( 'posts_groupby', array( $this, 'posts_groupby' ), 10, 2 );
add_filter( 'posts_pre_query', array( $this, 'posts_pre_query' ), 10, 2 );
add_filter( 'the_posts', array( $this, 'the_posts' ), 10, 2 );
parent::__construct( $this->query_args );
// Remove filters after use.
remove_filter( 'posts_fields', array( $this, 'posts_fields' ) );
remove_filter( 'posts_join', array( $this, 'posts_join' ) );
remove_filter( 'posts_where', array( $this, 'posts_where' ) );
remove_filter( 'posts_orderby', array( $this, 'posts_orderby' ) );
remove_filter( 'posts_groupby', array( $this, 'posts_groupby' ) );
remove_filter( 'posts_pre_query', array( $this, 'posts_pre_query' ) );
remove_filter( 'the_posts', array( $this, 'the_posts' ) );
}
/**
* Prepare the query variables.
*
* @since 3.0.0
* @see WP_Query::parse_query()
* @see tptn_get_registered_settings()
*
* @param string|array $args {
* Optional. Array or string of Query parameters.
*
* @type array|string $blog_id An array or comma-separated string of blog IDs.
* @type bool $daily Set to true to get the daily/custom period posts. False for overall.
* @type array|string $include_cat_ids An array or comma-separated string of category/custom taxonomy term_taxonomy_ids.
* @type array|string $include_post_ids An array or comma-separated string of post IDs.
* @type bool $offset Offset the related posts returned by this number.
* @type bool $strict_limit If this is set to false, then it will fetch 3x posts.
* }
*/
public function prepare_query_args( $args = array() ) {
global $wpdb;
$tptn_settings = tptn_get_settings();
$defaults = array(
'blog_id' => get_current_blog_id(),
'daily' => false,
'include_cat_ids' => 0,
'include_post_ids' => 0,
'offset' => 0,
'strict_limit' => true,
);
$defaults = array_merge( $defaults, $tptn_settings );
$args = wp_parse_args( $args, $defaults );
// Set necessary variables.
$args['top_ten_query'] = true;
$args['suppress_filters'] = false;
$args['ignore_sticky_posts'] = true;
$args['no_found_rows'] = true;
// Store query args before we manipulate them.
$this->input_query_args = $args;
if ( $args['daily'] ) {
$this->table_name = $wpdb->base_prefix . 'top_ten_daily';
$this->is_daily = true;
} else {
$this->table_name = $wpdb->base_prefix . 'top_ten';
$this->is_daily = false;
}
// Set the number of posts to be retrieved.
$args['posts_per_page'] = ( $args['strict_limit'] ) ? $args['limit'] : ( $args['limit'] * 3 );
// If post_types is empty or contains a query string then use parse_str else consider it comma-separated.
if ( ! empty( $args['post_types'] ) && is_array( $args['post_types'] ) ) {
$post_types = $args['post_types'];
} elseif ( ! empty( $args['post_types'] ) && false === strpos( $args['post_types'], '=' ) ) {
$post_types = explode( ',', $args['post_types'] );
} else {
parse_str( $args['post_types'], $post_types ); // Save post types in $post_types variable.
}
// If post_types is empty or if we want all the post types.
if ( empty( $post_types ) || 'all' === $args['post_types'] ) {
$post_types = get_post_types(
array(
'public' => true,
)
);
}
/**
* Filter the post_types passed to the query.
*
* @since 2.2.0
* @since 3.0.0 Changed second argument from post ID to WP_Post object.
*
* @param array $post_types Array of post types to filter by.
* @param array $args Arguments array.
*/
$args['post_type'] = apply_filters( 'tptn_posts_post_types', $post_types, $args );
// Parse the blog_id argument to get an array of IDs.
$this->blog_id = wp_parse_id_list( $args['blog_id'] );
// Tax Query.
if ( ! empty( $args['tax_query'] ) && is_array( $args['tax_query'] ) ) {
$tax_query = $args['tax_query'];
} else {
$tax_query = array();
}
if ( ! empty( $args['include_cat_ids'] ) ) {
$tax_query[] = array(
'field' => 'term_taxonomy_id',
'terms' => wp_parse_id_list( $args['include_cat_ids'] ),
'include_children' => false,
);
}
if ( ! empty( $args['exclude_categories'] ) ) {
$tax_query[] = array(
'field' => 'term_taxonomy_id',
'terms' => wp_parse_id_list( $args['exclude_categories'] ),
'operator' => 'NOT IN',
'include_children' => false,
);
}
/**
* Filter the tax_query passed to the query.
*
* @since 3.0.0
*
* @param array $tax_query Array of tax_query parameters.
* @param array $args Arguments array.
*/
$tax_query = apply_filters( 'top_ten_query_tax_query', $tax_query, $args );
// Add a relation key if more than one $tax_query.
if ( count( $tax_query ) > 1 ) {
$tax_query['relation'] = 'AND';
}
$args['tax_query'] = $tax_query; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
// Set date_query.
$args['date_query'] = array(
array(
'after' => $args['how_old'] ? tptn_get_from_date( null, $args['how_old'] + 1, 0 ) : '',
'before' => current_time( 'mysql' ),
'inclusive' => true,
),
);
// Set post_status.
$args['post_status'] = empty( $args['post_status'] ) ? array( 'publish', 'inherit' ) : $args['post_status'];
// Set post__not_in for WP_Query using exclude_post_ids.
$exclude_post_ids = empty( $args['exclude_post_ids'] ) ? array() : wp_parse_id_list( $args['exclude_post_ids'] );
/**
* Filter exclude post IDs array.
*
* @since 2.2.0
* @since 3.0.0 Added $args
*
* @param int[] $exclude_post_ids Array of post IDs.
* @param array $args Arguments array.
*/
$exclude_post_ids = apply_filters( 'tptn_exclude_post_ids', $exclude_post_ids, $args );
$args['post__not_in'] = $exclude_post_ids;
// Unset what we don't need.
unset( $args['title'] );
unset( $args['title_daily'] );
unset( $args['blank_output'] );
unset( $args['blank_output_text'] );
unset( $args['show_excerpt'] );
unset( $args['excerpt_length'] );
unset( $args['show_date'] );
unset( $args['show_author'] );
unset( $args['disp_list_count'] );
unset( $args['title_length'] );
unset( $args['link_new_window'] );
unset( $args['link_nofollow'] );
unset( $args['before_list'] );
unset( $args['after_list'] );
unset( $args['before_list_item'] );
unset( $args['after_list_item'] );
/**
* Filters the arguments of the query.
*
* @since 3.0.0
*
* @param array $args The arguments of the query.
* @param Top_Ten_Query $this The Top_Ten_Query instance (passed by reference).
*/
$this->query_args = apply_filters_ref_array( 'top_ten_query_args', array( $args, &$this ) );
}
/**
* Modify the SELECT clause - posts_fields.
*
* @since 3.0.0
*
* @param string $fields The SELECT clause of the query.
* @param WP_Query $query The WP_Query instance.
* @return string Updated Fields
*/
public function posts_fields( $fields, $query ) {
global $wpdb;
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $fields;
}
$_fields[] = "{$this->table_name}.postnumber";
$_fields[] = $this->is_daily ? "SUM({$this->table_name}.cntaccess) as visits" : "{$this->table_name}.cntaccess as visits";
$_fields = implode( ', ', $_fields );
$fields .= ',' . $_fields;
return $fields;
}
/**
* Modify the posts_join clause.
*
* @since 3.0.0
*
* @param string $join The JOIN clause of the query.
* @param WP_Query $query The WP_Query instance.
* @return string Updated JOIN
*/
public function posts_join( $join, $query ) {
global $wpdb;
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $join;
}
$join .= " INNER JOIN {$this->table_name} ON {$this->table_name}.postnumber={$wpdb->posts}.ID ";
return $join;
}
/**
* Modify the posts_where clause.
*
* @since 3.0.0
*
* @param string $where The WHERE clause of the query.
* @param WP_Query $query The WP_Query instance.
* @return string Updated WHERE
*/
public function posts_where( $where, $query ) {
global $wpdb;
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $where;
}
$where .= " AND {$this->table_name}.blog_id IN ('" . join( "', '", $this->blog_id ) . "') "; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if ( $this->is_daily ) {
if ( isset( $this->query_args['from_date'] ) ) {
$from_date = tptn_get_from_date( $this->query_args['from_date'], 0, 0 );
} else {
$from_date = tptn_get_from_date( null, $this->query_args['daily_range'], $this->query_args['hour_range'] );
}
$where .= $wpdb->prepare( " AND {$this->table_name}.dp_date >= %s ", $from_date ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if ( isset( $this->query_args['to_date'] ) ) {
$to_date = tptn_get_from_date( $this->query_args['to_date'], 0, 0 );
$where .= $wpdb->prepare( " AND {$this->table_name}.dp_date <= %s ", $to_date ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}
}
return $where;
}
/**
* Modify the posts_orderby clause.
*
* @since 3.0.0
*
* @param string $orderby The ORDER BY clause of the query.
* @param WP_Query $query The WP_Query instance.
* @return string Updated ORDER BY
*/
public function posts_orderby( $orderby, $query ) {
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $orderby;
}
// If orderby is set, then this was done intentionally and we don't make any modifications.
if ( ! empty( $query->get( 'orderby' ) ) ) {
return $orderby;
}
$orderby = ' visits DESC ';
return $orderby;
}
/**
* Modify the posts_groupby clause.
*
* @since 3.0.0
*
* @param string $groupby The GROUP BY clause of the query.
* @param WP_Query $query The WP_Query instance.
* @return string Updated GROUP BY
*/
public function posts_groupby( $groupby, $query ) {
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $groupby;
}
if ( $this->is_daily ) {
$groupby = " {$this->table_name}.postnumber ";
}
return $groupby;
}
/**
* Filter posts_pre_query to allow caching to work.
*
* @since 3.0.0
*
* @param string $posts Array of post data.
* @param WP_Query $query The WP_Query instance.
* @return string Updated Array of post objects.
*/
public function posts_pre_query( $posts, $query ) {
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $posts;
}
// Check the cache if there are any posts saved.
if ( ! empty( $this->query_args['cache_posts'] ) && ! ( is_preview() || is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) ) {
$cache_name = tptn_cache_get_key( $this->input_query_args );
$post_ids = get_transient( $cache_name );
if ( ! empty( $post_ids ) ) {
$posts = get_posts(
array(
'post__in' => $post_ids,
'fields' => $query->get( 'fields' ),
'orderby' => 'post__in',
'post_type' => $query->get( 'post_type' ),
)
);
$query->found_posts = count( $posts );
$query->max_num_pages = ceil( $query->found_posts / $query->get( 'posts_per_page' ) );
$this->in_cache = true;
}
}
return $posts;
}
/**
* Modify the array of retrieved posts.
*
* @since 3.0.0
*
* @param WP_Post[] $posts Array of post objects.
* @param WP_Query $query The WP_Query instance (passed by reference).
* @return string Updated Array of post objects.
*/
public function the_posts( $posts, $query ) {
// Return if it is not a Top_Ten_Query.
if ( true !== $query->get( 'top_ten_query' ) ) {
return $posts;
}
// Support caching to speed up retrieval.
if ( ! empty( $this->query_args['cache_posts'] ) && ! $this->in_cache && ! ( is_preview() || is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) ) {
/** This filter is defined in display-posts.php */
$cache_time = apply_filters( 'tptn_cache_time', $this->query_args['cache_time'], $this->query_args );
$cache_name = tptn_cache_get_key( $this->input_query_args );
$post_ids = wp_list_pluck( $query->posts, 'ID' );
set_transient( $cache_name, $post_ids, $cache_time );
}
if ( ! empty( $this->query_args['include_post_ids'] ) ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
$include_post_ids = wp_parse_id_list( $this->query_args['include_post_ids'] );
}
if ( ! empty( $include_post_ids ) ) {
$extra_posts = get_posts(
array(
'post__in' => $include_post_ids,
'fields' => $query->get( 'fields' ),
'orderby' => 'post__in',
'post_type' => $query->get( 'post_type' ),
)
);
$posts = array_merge( $extra_posts, $posts );
}
// Shuffle posts if random order is set.
if ( $this->random_order ) {
shuffle( $posts );
}
/**
* Filter array of WP_Post objects before it is returned to the Top_Ten_Query instance.
*
* @since 3.0.0
*
* @param WP_Post[] $posts Array of post objects.
* @param array $args Arguments array.
*/
return apply_filters( 'top_ten_query_the_posts', $posts, $this->query_args );
}
}
endif;