Files
old-v2-backend/wordpress/wp-content/plugins/wp-graphql/src/Data/Config.php
2018-06-25 00:00:37 +02:00

204 lines
6.8 KiB
PHP
Executable File

<?php
namespace WPGraphQL\Data;
/**
* Class Config
*
* This class contains configurations for various data-related things, such as query filters for cursor pagination.
*
* @package WPGraphQL\Data
*/
class Config {
/**
* Config constructor.
*/
public function __construct() {
/**
* Filter the term_clauses in the WP_Term_Query to allow for cursor pagination support where a Term ID
* can be used as a point of comparison when slicing the results to return.
*/
add_filter( 'comments_clauses', [ $this, 'graphql_wp_comments_query_cursor_pagination_support' ], 10, 2 );
/**
* Filter the WP_Query to support cursor based pagination where a post ID can be used
* as a point of comparison when slicing the results to return.
*/
add_filter( 'posts_where', [ $this, 'graphql_wp_query_cursor_pagination_support' ], 10, 2 );
/**
* Filter the term_clauses in the WP_Term_Query to allow for cursor pagination support where a Term ID
* can be used as a point of comparison when slicing the results to return.
*/
add_filter( 'terms_clauses', [ $this, 'graphql_wp_term_query_cursor_pagination_support' ], 10, 3 );
}
/**
* This filters the WPQuery 'where' $args, enforcing the query to return results before or
* after the referenced cursor
*
* @param string $where The WHERE clause of the query.
* @param \WP_Query $query The WP_Query instance (passed by reference).
*
* @return string
*/
public function graphql_wp_query_cursor_pagination_support( $where, \WP_Query $query ) {
/**
* Access the global $wpdb object
*/
global $wpdb;
/**
* If there's a graphql_cursor_offset in the query, we should check to see if
* it should be applied to the query
*/
if ( defined( 'GRAPHQL_REQUEST' ) && GRAPHQL_REQUEST ) {
$cursor_offset = ! empty( $query->query_vars['graphql_cursor_offset'] ) ? $query->query_vars['graphql_cursor_offset'] : 0;
/**
* Ensure the cursor_offset is a positive integer
*/
if ( is_integer( $cursor_offset ) && 0 < $cursor_offset ) {
$compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>';
$compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>';
$compare_opposite = ( '<' === $compare ) ? '>' : '<';
// Get the $cursor_post
$cursor_post = get_post( $cursor_offset );
/**
* If the $cursor_post exists (hasn't been deleted), modify the query to compare based on the ID and post_date values
* But if the $cursor_post no longer exists, we're forced to just compare with the ID
*
*/
if ( ! empty( $cursor_post ) && ! empty( $cursor_post->post_date ) ) {
$orderby = $query->get( 'orderby' );
if ( ! empty( $orderby ) && is_array( $orderby ) ) {
foreach ( $orderby as $by => $order ) {
$order_compare = ( 'ASC' === $order ) ? '>' : '<';
$value = $cursor_post->{$by};
if ( ! empty( $by ) && ! empty( $value ) ) {
$where .= $wpdb->prepare( " AND {$wpdb->posts}.{$by} {$order_compare} %s", $value );
}
}
} else {
$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date {$compare}= %s AND {$wpdb->posts}.ID != %d", esc_sql( $cursor_post->post_date ), absint( $cursor_offset ) );
}
} else {
$where .= $wpdb->prepare( " AND {$wpdb->posts}.ID {$compare} %d", $cursor_offset );
}
}
}
return $where;
}
/**
* This filters the term_clauses in the WP_Term_Query to support cursor based pagination, where we can
* move forward or backward from a particular record, instead of typical offset pagination which can be
* much more expensive and less accurate.
*
* @param array $pieces Terms query SQL clauses.
* @param array $taxonomies An array of taxonomies.
* @param array $args An array of terms query arguments.
*
* @return array $pieces
*/
public function graphql_wp_term_query_cursor_pagination_support( array $pieces, $taxonomies, $args ) {
/**
* Access the global $wpdb object
*/
global $wpdb;
if ( defined( 'GRAPHQL_REQUEST' ) && GRAPHQL_REQUEST && ! empty( $args['graphql_cursor_offset'] ) ) {
$cursor_offset = $args['graphql_cursor_offset'];
/**
* Ensure the cursor_offset is a positive integer
*/
if ( is_integer( $cursor_offset ) && 0 < $cursor_offset ) {
$compare = ! empty( $args['graphql_cursor_compare'] ) ? $args['graphql_cursor_compare'] : '>';
$compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>';
$order_by = ! empty( $args['orderby'] ) ? $args['orderby'] : 'comment_date';
$order = ! empty( $args['order'] ) ? $args['order'] : 'DESC';
$order_compare = ( 'ASC' === $order ) ? '>' : '<';
// Get the $cursor_post
$cursor_term = get_term( $cursor_offset );
if ( ! empty( $cursor_term ) && ! empty( $cursor_term->name ) ) {
$pieces['where'] .= $wpdb->prepare( " AND t.{$order_by} {$order_compare} %s", $cursor_term->{$order_by} );
} else {
$pieces['where'] .= $wpdb->prepare( ' AND t.term_id %1$s %2$d', $compare, $cursor_offset );
}
}
}
return $pieces;
}
/**
* This returns a modified version of the $pieces of the comment query clauses if the request
* is a GRAPHQL_REQUEST and the query has a graphql_cursor_offset defined
*
* @param array $pieces A compacted array of comment query clauses.
* @param \WP_Comment_Query $query Current instance of WP_Comment_Query, passed by reference.
*
* @return array $pieces
*/
public function graphql_wp_comments_query_cursor_pagination_support( array $pieces, \WP_Comment_Query $query ) {
/**
* Access the global $wpdb object
*/
global $wpdb;
if (
defined( 'GRAPHQL_REQUEST' ) && GRAPHQL_REQUEST &&
( is_array( $query->query_vars ) && array_key_exists( 'graphql_cursor_offset', $query->query_vars ) )
) {
$cursor_offset = $query->query_vars['graphql_cursor_offset'];
/**
* Ensure the cursor_offset is a positive integer
*/
if ( is_integer( $cursor_offset ) && 0 < $cursor_offset ) {
$compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>';
$compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>';
$order_by = ! empty( $query->query_vars['order_by'] ) ? $query->query_vars['order_by'] : 'comment_date';
$order = ! empty( $query->query_vars['order'] ) ? $query->query_vars['order'] : 'DESC';
$order_compare = ( 'ASC' === $order ) ? '>' : '<';
// Get the $cursor_post
$cursor_comment = get_comment( $cursor_offset );
if ( ! empty( $cursor_comment ) ) {
$pieces['where'] .= $wpdb->prepare( " AND {$order_by} {$order_compare} %s", $cursor_comment->{$order_by} );
} else {
$pieces['where'] .= $wpdb->prepare( ' AND comment_ID %1$s %2$d', $compare, $cursor_offset );
}
}
}
return $pieces;
}
}