include/lcp-parameters.php
<?php
require_once LCP_PATH . 'lcp-utils.php';
require_once LCP_PATH . 'lcp-date-query.php';
require_once LCP_PATH . 'lcp-meta-query.php';
require_once LCP_PATH . 'lcp-taxonomies.php';
class LcpParameters{
// Singleton implementation
private static $instance = null;
private $starting_with = null;
private $utils;
private $params;
private $cat_sticky_posts;
// Use Trait for before/after date queries:
use LcpDateQuery;
// Use Trait for meta query
use LcpMetaQuery;
// Use Trait for custom taxonomies
use LcpTaxonomies;
public static function get_instance(){
if( !isset( self::$instance ) ){
self::$instance = new self;
}
return self::$instance;
}
public function get_query_params($params){
$this->params = $params;
# Essential parameters:
$args = array(
'numberposts' => $params['numberposts'],
'orderby' => $this->lcp_order_by($params['orderby']),
'order' => $this->lcp_order($params['order']),
'offset' => $params['offset']
);
$this->utils = new LcpUtils($params);
// Check posts to exclude
$args = $this->lcp_check_excludes($args);
// Check posts to include
if( $this->utils->lcp_not_empty('includeposts') ){
$args['post__in'] = explode(",", $this->params['includeposts']);
}
// Check type, status, parent params
$args = $this->lcp_types_and_statuses($args);
if($this->utils->lcp_not_empty('search')){
$args['s'] = $params['search'];
}
if($this->utils->lcp_not_empty('author_posts')):
$authors = $params['author_posts'];
if ($authors == 'current_user'){
$args['author'] = wp_get_current_user()->ID;
} else {
if( false !== strpos($authors,',')){
$args['author'] = $authors;
} else {
$args['author_name'] = $authors;
}
}
endif;
// Parameters which need to be checked simply, if they exist, add them to
// final return array ($args)
$args = $this->lcp_check_basic_params($args);
// Only generate date_query args if a before/after paramater was found
$args = $this->create_date_query_args($args, $params);
$args = $this->create_meta_query_args($args, $params);
//Get private posts
if( is_user_logged_in() ){
if ( !empty($args['post_status']) ){
$args['post_status'] = array_merge($args['post_status'], array('private'));
} else{
$args['post_status'] = array('private', 'publish');
}
}
if ( $this->utils->lcp_not_empty('exclude_tags') ){
$args = $this->lcp_excluded_tags($args);
}
// Current tags
$currenttags = $params['currenttags'];
if ( $currenttags === 'yes' || $currenttags === 'all' ) {
$tags = $this->lcp_get_current_terms( 'post_tag' );
if ( !empty($tags) ) {
// OR relationship
if ( 'yes' === $currenttags ) {
$args['tag__in'] = $tags;
} else {
// AND relationship
$args['tag__and'] = $tags;
}
} else {
/*
Display nothing when a post has no tags.
Note that this will not prevent sticky posts
from being shown if they match other query parameters,
e.g. when no category is specified or a sticky post's
category matches the one given in `id` or `name`.
#80
*/
$args['post__in'] = [0];
}
}
// Custom taxonomy support
$args = $this->create_tax_query($args, $params);
// Tag support
if ( $this->utils->lcp_not_empty('tags') ) {
$args['tag'] = $params['tags'];
}
if ( !empty($params['exclude'])){
$args['category__not_in'] = array($params['exclude']);
}
// Posts that start with a given letter:
if ( $this->utils->lcp_not_empty('starting_with') ){
$this->starting_with = $params['starting_with'];
add_filter('posts_where' , array( $this, 'starting_with') );
}
// Post stickiness
if ( 'yes' === $params['ignore_sticky_posts'] ) {
$args['ignore_sticky_posts'] = true;
}
if ( $params[ 'cat_sticky_posts' ] === 'yes' ) {
add_action( 'lcp_pre_run_query', [ $this, 'get_cat_sticky_posts' ] );
add_filter( 'the_posts', [ $this, 'move_sticky_to_top' ] );
}
return $args;
}
public function get_cat_sticky_posts( $args ) {
$sticky_ids = get_option( 'sticky_posts' );
$sticky_query = new WP_Query(
array_merge( $args, [ 'post__in' => $sticky_ids ] )
);
$this->cat_sticky_posts = $sticky_query->posts;
}
public function move_sticky_to_top( $posts ) {
remove_action( 'lcp_pre_run_query', [ $this, 'get_cat_sticky_posts' ] );
if ( null == $this->cat_sticky_posts ) return $posts;
$newposts = array_merge( $this->cat_sticky_posts, $posts );
$this->cat_sticky_posts = null;
return $newposts;
}
private function lcp_check_basic_params($args){
$simple_args = array('year', 'monthnum', 'after');
foreach($simple_args as $key){
if($this->utils->lcp_not_empty($key)){
$args[$key] = $this->params[$key];
}
}
return $args;
}
// Check posts to exclude
private function lcp_check_excludes($args){
if( $this->utils->lcp_not_empty('excludeposts') ){
$excludeposts = explode(',', $this->params['excludeposts']);
$this_index = array_search("this", $excludeposts);
if ($this_index > -1){
unset($excludeposts[$this_index]);
// If we are not on a page/post there is nothing to exclude.
if (true === is_singular()) {
$excludeposts = array_merge(
$excludeposts,
array($this->lcp_get_current_post_id())
);
}
}
$excludeposts = array(
'post__not_in' => $excludeposts
);
$args = array_merge($args, $excludeposts);
}
return $args;
}
private function lcp_types_and_statuses($args){
// Post type, status, parent params:
if($this->utils->lcp_not_empty('post_type')):
$args['post_type'] = explode( ',', $this->params['post_type'] );
endif;
if($this->utils->lcp_not_empty('post_status')):
$args['post_status'] = explode( ',', $this->params['post_status'] );
endif;
if( '' !== $this->params[ 'post_parent' ] ):
$args['post_parent'] = $this->params['post_parent'];
endif;
return $args;
}
private function lcp_excluded_tags($args){
$excluded_tags = explode(",", $this->params['exclude_tags']);
$tag_ids = array();
foreach ( $excluded_tags as $excluded){
$tag_ids[] = get_term_by('slug', $excluded, 'post_tag')->term_id;
}
$args['tag__not_in'] = $tag_ids;
return $args;
}
// Duplicated in LcpTaxonomies, for now.
private function lcp_get_current_terms($taxonomy) {
$terms = get_the_terms(0, $taxonomy);
$term_ids = array();
if( !empty( $terms ) ) {
foreach ( $terms as $term ) {
array_push( $term_ids, $term->term_id );
}
}
return $term_ids;
}
public function starting_with($where){
$letters = explode(',', $this->starting_with);
// Support for both utf8 and utf8mb4
global $wpdb;
$wp_posts_prefix = $wpdb->prefix . 'posts';
$charset = $wpdb->get_col_charset($wp_posts_prefix, 'post_title');
$where .= 'AND (' . $wp_posts_prefix . '.post_title ' .
'COLLATE ' . strtoupper($charset) . '_GENERAL_CI LIKE \'' . $letters[0] . "%'";
for ($i=1; $i <sizeof($letters); $i++) {
$where .= 'OR ' . $wp_posts_prefix . '.post_title ' .
'COLLATE ' . strtoupper($charset) . '_GENERAL_CI LIKE \'' . $letters[$i] . "%'";
}
$where.=')';
return $where;
}
private function lcp_get_current_post_id(){
global $post;
return $post->ID;
}
private function lcp_order_by($orderby) {
if( get_option('lcp_orderby') && $orderby === ''){
return get_option('lcp_orderby');
}
return $orderby;
}
private function lcp_order($order) {
if( get_option('lcp_order') && $order === '') {
return get_option('lcp_order');
}
return $order;
}
}