Last active
June 15, 2020 16:02
-
-
Save Magnacarter/b7d0741bf806cad2c0df40e51d3039fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Load the Placement API class | |
* These methods can be used to interact with | |
* the peta_placements db table | |
* | |
* @package PETA\Placement_Plugin\inc | |
* @since 4.0.0 | |
* @author adamc | |
* @licence GNU-2.0+ | |
*/ | |
namespace PETA\Plugin_Placement; | |
use PETA_Placement_Plugin; | |
use WP_Query; | |
/** | |
* Class Placement API | |
*/ | |
class Placement_API extends Custom_Tables { | |
/** | |
* @var int | |
*/ | |
protected $placement_id; | |
/** | |
* Hold instance of plugin's utility class | |
* @var object | |
*/ | |
protected $plugin; | |
/** | |
* @var string | |
*/ | |
protected $placement_name; | |
/** | |
* @var string | |
*/ | |
protected $placement_url; | |
/** | |
* @var string | |
*/ | |
protected $pos_order_number; | |
/** | |
* @var string | |
*/ | |
public $table_name; | |
/** | |
* Placement_API Constructor | |
*/ | |
public function __construct() { | |
parent::__construct(); | |
add_action( 'pre_get_posts', array( $this, 'exclude_suppress_from_search' ), 1 ); | |
} | |
/** | |
* Set our variables | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @return void | |
*/ | |
public function init( $placement_id ) { | |
// All our setters | |
$this->set_placement_id( $placement_id ); | |
$this->set_pos_order_number( $placement_id ); | |
$this->set_placement_url( $placement_id ); | |
} | |
/** | |
* Set menu id | |
* Get the menu id from the GET query | |
* | |
* @since 3.0.0 | |
* @return void | |
*/ | |
public function set_placement_id( $placement_id = null ) { | |
$this->placement_id = $placement_id; | |
} | |
/** | |
* Set pos order number | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @return void | |
*/ | |
public function set_pos_order_number( $placement_id ) { | |
$this->pos_order_number = 'pos_order_' . $placement_id; | |
} | |
/** | |
* Set placement name and url | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @return void | |
*/ | |
public function set_placement_url( $placement_id ) { | |
$this->placement_url = untrailingslashit( get_admin_url() ) . '?page=placements&action=manage&mid=' . $placement_id; | |
} | |
/** | |
* Get placement id | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @return int | |
*/ | |
public function get_placement_id() { | |
return $this->placement_id; | |
} | |
/** | |
* Get pos order number | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @return string | |
*/ | |
public function get_pos_order_number() { | |
return $this->pos_order_number; | |
} | |
/** | |
* Get placement url | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @return string | |
*/ | |
public function get_placement_url() { | |
return $this->placement_url; | |
} | |
/** | |
* Get placement name | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int $placement_id | |
* @return string $result | |
*/ | |
public function get_placement_name( $placement_id ) { | |
global $wpdb; | |
$table_name = $this->get_placement_table_name(); | |
$result = $wpdb->get_var( "SELECT placement_name FROM $table_name WHERE placement_id = $placement_id" ); | |
return $result; | |
} | |
/** | |
* Get placement categories | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int $placement_id | |
* @return array $result | |
*/ | |
public function get_placement_categories( $placement_id = '' ) { | |
if ( ! empty( $placement_id ) ) { | |
global $wpdb; | |
$table_name = $this->get_placement_table_name(); | |
$result = $wpdb->get_var( "SELECT categories FROM $table_name WHERE placement_id = $placement_id" ); | |
return json_decode( $result, true ); | |
} | |
} | |
/** | |
* Get placement post_types | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int | |
* @return array $result | |
*/ | |
public function get_placement_post_types( $placement_id = '' ) { | |
if ( ! empty( $placement_id ) ) { | |
global $wpdb; | |
$table_name = $this->get_placement_table_name(); | |
$result = $wpdb->get_var( "SELECT post_types FROM $table_name WHERE placement_id = $placement_id" ); | |
return json_decode( $result, true ); | |
} | |
} | |
/** | |
* Get placement psa type | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int $placement_id | |
* @return array $result | |
*/ | |
public function get_placement_taxonomies( $placement_id = '' ) { | |
if ( ! empty( $placement_id ) ) { | |
global $wpdb; | |
$table_name = $this->get_placement_table_name(); | |
$result = $wpdb->get_var( "SELECT taxonomies FROM $table_name WHERE placement_id = $placement_id" ); | |
return json_decode( $result, true ); | |
} | |
} | |
/** | |
* Generate a new placement id for peta_placements table | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @return int | |
*/ | |
public function get_new_placement_id() { | |
global $wpdb; | |
$table_name = $this->get_placement_table_name(); | |
$id = $wpdb->get_var( "SELECT placement_id FROM $table_name ORDER BY placement_id DESC limit 0,1" ); | |
return $id + 1; | |
} | |
/** | |
* Return all placements | |
* | |
* | |
* @return array $placements | |
*/ | |
public function get_placement_list() { | |
global $wpdb; | |
$table_name = $this->get_placement_table_name(); | |
$placements = $wpdb->get_results( "SELECT placement_name, placement_id, placement_url FROM $table_name", ARRAY_A ); | |
return $placements; | |
} | |
/** | |
* Get single post position | |
* Return the post published time if post is not in the top 40 placements positions | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int $post_id | |
* @return int $position | |
*/ | |
public function get_single_post_position( $post_id, $placement_id ) { | |
$order = $this->get_placement_order( $placement_id ); | |
if ( isset( $order ) ) { | |
foreach ( $order as $arr ) { | |
if ( $_GET['paged'] > 1 && $arr['post_id'] == $post_id ) { | |
return false; | |
} | |
if ( $arr['post_id'] == $post_id ) { | |
$position = $arr['position']; | |
break; | |
} | |
} | |
} | |
if ( isset( $position ) ) { | |
return $position; | |
} else { | |
return get_the_time( 'Y-m-d', $post_id ); | |
} | |
} | |
/** | |
* Get placement order | |
* Return array of post ids that contain each ones' placement position, | |
* then decode the json object | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int $placement_id | |
* @return array | |
*/ | |
public function get_placement_order( $placement_id ) { | |
global $wpdb; | |
$table_name = $this->table_name; | |
$entries = $wpdb->get_var( $wpdb->prepare( | |
" | |
SELECT placement_order | |
FROM $table_name | |
WHERE placement_id = %d | |
", | |
$placement_id | |
)); | |
// Convert the stdObject to an array | |
$placement_order = json_decode( $entries, true ); | |
return $placement_order; | |
} | |
/** | |
* Calculate the offset needed for the top 40 posts. | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @param array $top_forty | |
* @param int $offset | |
* @param int $total | |
* @return array $entries | |
*/ | |
public function adjust_top_40_offset( $top_forty_posts, $offset, $total ) { | |
// Put top 40 order posts into the array. | |
foreach ( $top_forty_posts as $pos ) { | |
$found_posts[] = $pos['post_id']; | |
} | |
// Offset the top 40 array. | |
$i = 1; | |
$j = 1; | |
foreach ( $found_posts as $key => $value ) { | |
if ( 0 !== $offset ) { | |
if ( $i <= $offset ) { | |
$i++; | |
continue; | |
} | |
} | |
if ( $j <= $total ) { | |
$entries[] = $value; | |
} | |
$j++; | |
} | |
return $entries; | |
} | |
/** | |
* Returns placement post ids starting with | |
* top 40 placements then moving to posts outside the saved top 40. | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @param string $name | |
* @param int $total | |
* @param int $offset | |
* @return array $entries | |
*/ | |
public function get_placement_posts( $name, $total = 5, $offset = 0 ) { | |
$placement_id = $this->plugin->get_placement_id_from_name( $name ); | |
$order = $this->get_placement_order( $placement_id ); | |
$order_count = count( $order ); | |
$settings = $this->get_placement_settings( $placement_id ); | |
// Use the top forty array as a post not in arg for the wp_query later. | |
foreach ( $order as $arr ) { | |
$post_not_in[] = $arr['post_id']; | |
} | |
$top_forty_posts = $order; | |
$entries = $this->adjust_top_40_offset( $top_forty_posts, $offset, $total ); | |
// If the entries are less than the total, start using placement posts outside the top 40. | |
if ( count( $entries ) < $total ) { | |
$adjust_total = $total - count( $entries ); | |
$query = $this->get_placement_wp_query( $settings, ' ', $adjust_total, 0, $post_not_in ); | |
$post_ids = wp_list_pluck( $query->posts, 'ID' ); | |
} | |
// If there are no more top 40 posts, use the other placement posts. | |
if ( 0 == count( $entries ) ) { | |
$adjust_offset = $offset - $order_count; | |
$query = $this->get_placement_wp_query( $settings, ' ', $total, $adjust_offset, $post_not_in ); | |
$post_ids = wp_list_pluck( $query->posts, 'ID' ); | |
} | |
// Put wp_query posts in the array if they are not in the top 40. | |
if ( isset( $post_ids ) ) { | |
foreach ( $post_ids as $p_id ) { | |
$entries[] = $p_id; | |
} | |
} | |
return $entries; | |
} | |
/** | |
* Return the total number of posts for a placement. | |
* This includes the top 40 and all posts that fit into a placement's settings. | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @param string $name | |
* @return int $total_records | |
*/ | |
public function get_total_placement_records( $name ) { | |
$placement_id = $this->plugin->get_placement_id_from_name( $name ); | |
$placement_settings = $this->get_placement_settings( $placement_id ); | |
$query = $this->get_placement_wp_query( $placement_settings ); | |
$total_records = $query->found_posts; | |
return $total_records; | |
} | |
/** | |
* Put together an array to save placement order row in the custom peta-placements db table | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param int $placement_id | |
* @param string $pos_order_number | |
* @param string $placement_name | |
* @param string $placement_url | |
* @param array $placement_order | |
* @return void | |
*/ | |
public function get_placement_args( $placement_id, $pos_order_number, $placement_name, $placement_url, $placement_order ) { | |
$last_update = date( 'Y-m-d h:i:sa' ); | |
$placement_order = wp_json_encode( $placement_order ); | |
$args = array( | |
'placement_id' => $placement_id, | |
'pos_order_number' => $pos_order_number, | |
'placement_name' => $placement_name, | |
'placement_order' => $placement_order, | |
'last_update' => $last_update, | |
'placement_url' => $placement_url, | |
); | |
return $args; | |
} | |
/** | |
* Get the current placement settings | |
* | |
* @author adamc | |
* @since 4.0.0 | |
* | |
* @param int $placement_id | |
* @return array $placement_settings | |
*/ | |
public function get_placement_settings( $placement_id ) { | |
if ( empty( $placement_id ) ) { | |
return; | |
} | |
$placement_settings['menu_label'] = $this->get_placement_name( $placement_id ); | |
$placement_settings['categories'] = $this->get_placement_categories( $placement_id ); | |
$placement_settings['post_types'] = $this->get_placement_post_types( $placement_id ); | |
$placement_settings['taxonomies'] = $this->get_placement_taxonomies( $placement_id ); | |
return $placement_settings; | |
} | |
/** | |
* Start the save process | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param string $placement_id | |
* @param array $order | |
* @return array $response | |
*/ | |
public function init_save_placement( $placement_id, $order, $args = array() ) { | |
$this->init( $placement_id ); | |
// Run the setters and save order to peta_placements | |
$pos_order_num = $this->get_pos_order_number(); | |
$placement_name = $this->get_placement_name( $placement_id ); | |
$url = $this->get_placement_url(); | |
if ( empty( $args ) ) { | |
// Setup the args to send it to the db. | |
$args = $this->get_placement_args( $placement_id, $pos_order_num, $placement_name, $url, $order ); | |
$response = $this->save_placement( $args ); | |
} else { | |
$meta['pos_order_number'] = $pos_order_num; | |
$meta['placement_name'] = $placement_name; | |
$meta['placement_url'] = $url; | |
$meta['last_update'] = date( 'Y-m-d h:i:sa' ); | |
$new_placement = array_merge( $meta, $args ); | |
$response = $this->save_placement( $new_placement ); | |
} | |
return $response; | |
} | |
/** | |
* Save placement | |
* Save to our peta_placements table | |
* Returns the args array so you can place it in your ajax response in save_placement_order() | |
* in class-placement-hooks.php for debugging. | |
* | |
* @since 4.0.0 | |
* @author acarter | |
* | |
* @param array $args | |
* @param string $table_name | |
* @return array $args | |
*/ | |
public function save_placement( $args, $table_name = null ) { | |
global $wpdb; | |
if ( ! isset( $table_name ) ) { | |
$table_name = $this->get_placement_table_name(); | |
} | |
$placement_id = $args['placement_id']; | |
$db_id = $wpdb->get_var( "SELECT placement_id FROM $table_name WHERE placement_id= $placement_id" ); | |
if ( NULL === $db_id ) { | |
$wpdb->insert( $table_name, $args ); | |
} else { | |
$wpdb->update( $table_name, $args, array( 'placement_id' => $db_id ) ); | |
} | |
$args['placement_url'] = $wpdb->get_var( "SELECT placement_url FROM $table_name WHERE placement_id = $placement_id" ); | |
return $args; | |
} | |
/** | |
* Delete top forty posts | |
* Delete the top forty posts by entering a null value | |
* | |
* @since 4.0.0 | |
* @author adamc | |
* | |
* @param int $placement_id | |
* @return void | |
*/ | |
public function delete_top_forty_posts( $placement_id ) { | |
$this->init_save_placement( $placement_id, $order = null ); | |
} | |
/** | |
* Exclude supress from search. | |
* | |
* @since 4.0 | |
* @param object $query | |
* @return void | |
*/ | |
public function exclude_suppress_from_search( $query ) { | |
if ( ! $query->is_search ) { | |
return $query; | |
} | |
if ( is_admin() ) { | |
$tax_query = array( | |
array( | |
'taxonomy' => 'placement', | |
'field' => 'slug', | |
'terms' => 'suppress-from-search-results', | |
'operator' => 'NOT IN', | |
), | |
); | |
$query->set( 'tax_query', $tax_query ); | |
} else { | |
$tax_query = array( | |
array( | |
'taxonomy' => 'placement', | |
'field' => 'slug', | |
'terms' => 'suppress-from-search-results-external', | |
'operator' => 'NOT IN', | |
), | |
); | |
$query->set( 'tax_query', $tax_query ); | |
} | |
} | |
/** | |
* Get a new wp_query based on a placement's settings. | |
* Build an agrs array for wp_query dynamically | |
* | |
* @author adamc | |
* @since 4.0.0 | |
* | |
* @param array $placment_settings | |
* @param string $search_term | |
* @param int $post_count | |
* @param int $offset | |
* @param array $post_not_in | |
* @return object $query | |
*/ | |
public function get_placement_wp_query( $placement_settings, $search_term = '', $post_count = 40, $offset = 0, $post_not_in = null ) { | |
$args['posts_per_page'] = $post_count; | |
$args['paged'] = $_GET['paged']; | |
$args['post_status'] = 'publish'; | |
if ( null !== $post_not_in ) { | |
$args['post__not_in'] = $post_not_in; | |
} | |
if ( $offset > 0 ) { | |
$args['offset'] = $offset; | |
} | |
if ( ! empty( $search_term ) ) { | |
$args['s'] = $search_term; | |
} | |
/** | |
* Put pts into an array. | |
* No empty check because posts will always have a post type | |
*/ | |
foreach ( $placement_settings['post_types'] as $k => $pt ) { | |
$args['post_type'][] .= $pt; | |
} | |
// Put cats into array | |
if ( ! empty( $placement_settings['categories'] ) ) { | |
foreach ( $placement_settings['categories'] as $index => $cat ) { | |
$args['category__in'][] .= $cat; | |
} | |
} | |
// Put taxonomy terms into an array | |
if ( ! empty( $placement_settings['taxonomies'] ) ) { | |
// Find out if there is more than one taxonomy to add | |
$i = 0; | |
foreach ( $placement_settings['taxonomies'] as $tax_name => $term_ids ) { | |
if ( ! empty( $tax_name ) ) { | |
$i++; | |
} | |
} | |
/** | |
* If there's more than one tax in the placement, | |
* make sure to add the OR relationship to see if any posts | |
* have that term. | |
*/ | |
if ( $i > 1 ) { | |
$args['tax_query']['relation'] = 'OR'; | |
} | |
// Build the taxonomy array | |
$j = 0; | |
foreach ( $placement_settings['taxonomies'] as $key => $tax ) { | |
if ( isset( $tax ) ) { | |
$tax_query[ $j ] = array( 'taxonomy' => str_replace( '_', '-', $key ), 'field' => 'term_id' ); | |
foreach ( $tax as $index => $term_id ) { | |
$tax_query[ $j ]['terms'] .= $term_id; | |
} | |
} | |
$j++; | |
} | |
} | |
$args['tax_query'] = $tax_query; | |
$args['suppress_filters'] = false; | |
$query = new WP_Query( $args ); | |
return $query; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment