Skip to content

Commit d3cdbc0

Browse files
committed
Create index.php
1 parent 38aa4d0 commit d3cdbc0

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

index.php

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<?php
2+
/**
3+
* @package Unique_WP_Query
4+
* @version 1.0.0
5+
*/
6+
/*
7+
Plugin Name: Unique WP Query
8+
Plugin URI: https://github.com/firstandthird/unique_wp_query
9+
Description: A plugin for doing unique WP_Query
10+
Author: firstandthird
11+
Version: 1.0.0
12+
*/
13+
// adapted & taken from from https://gist.github.com/jameswburke/d0776d742ab74c469cd8af8dacd916fc
14+
15+
/**
16+
* Wrapper for WP_Query
17+
* Interacts directly with WP_Query_Manager to ensure
18+
* only unique posts are ever returned.
19+
*
20+
* Known issues:
21+
* Won't work with offset values
22+
*/
23+
class Unique_WP_Query extends WP_Query {
24+
function __construct($args) {
25+
// Act as a flag for pre_get_posts
26+
$args['unique_wp_query'] = true;
27+
28+
// Initialize the WP_Query object like normal
29+
parent::__construct($args);
30+
31+
// Track used posts, and remove duplicates
32+
Unique_WP_Query_Manager::process_posts($this->posts, $this->post_count, $this->get('original_posts_per_page'));
33+
}
34+
}
35+
36+
/**
37+
* Keeps track of which posts have already appeared and
38+
* removes them from future Unique_WP_Query objects.
39+
*/
40+
class Unique_WP_Query_Manager {
41+
42+
/**
43+
* Keep track of which post_ids have already been used
44+
* @var array
45+
*/
46+
public static $used_post_ids = [];
47+
48+
/**
49+
* Keeps track of how many used_posts_ids exist
50+
* @var integer
51+
*/
52+
public static $used_post_count = 0;
53+
54+
/**
55+
* Helper to make sure no duplicate ids are added
56+
* useful for content outside of the normal query
57+
*/
58+
public static function add_post_id($id) {
59+
if (!in_array($id, Unique_WP_Query_Manager::$used_post_ids, true)) {
60+
Unique_WP_Query_Manager::$used_post_ids[] = $id;
61+
Unique_WP_Query_Manager::$used_post_count = count(Unique_WP_Query_Manager::$used_post_ids);
62+
}
63+
}
64+
65+
/**
66+
* Takes the posts and post count of a WP_Query object and
67+
* ensures that it removes posts that have already been used,
68+
* and then trims it to the necessary size.
69+
*
70+
* @param array &$posts
71+
* @param integer &$post_count
72+
*/
73+
public static function process_posts(&$posts, &$post_count, $original_posts_per_page) {
74+
75+
// Keep track of how many posts are acceptable to return
76+
$current_accepted_post_count = 0;
77+
78+
// Make sure we have posts
79+
if (empty((array) $posts)) {
80+
return;
81+
}
82+
83+
// Loop through all the found posts
84+
foreach ((array) $posts as $key => $post) {
85+
86+
// If we have enough acceptable posts, break the loop
87+
// Otherwise, determine if we've already used this post
88+
if ($original_posts_per_page > $current_accepted_post_count) {
89+
90+
// Has this post already been used?
91+
if (in_array($post->ID, Unique_WP_Query_Manager::$used_post_ids, true)) {
92+
// Remove from $posts
93+
unset($posts[$key]);
94+
95+
// And update count
96+
$post_count--;
97+
} else {
98+
// If not, add it to the list of used ids
99+
Unique_WP_Query_Manager::$used_post_ids[] = $post->ID;
100+
101+
// Update how many accepted posts we have
102+
$current_accepted_post_count++;
103+
}
104+
} else {
105+
// If we have enough acceptable posts, break the foreach
106+
// This prevents extra results from accidently being added to $used_post_ids
107+
break;
108+
}
109+
}
110+
111+
// Reindex the array correctly
112+
$posts = array_values($posts);
113+
114+
// Update the $used_post_count
115+
Unique_WP_Query_Manager::$used_post_count = count(Unique_WP_Query_Manager::$used_post_ids);
116+
117+
// Trim any excess posts and update $post_count
118+
if (count($posts) > $original_posts_per_page) {
119+
120+
// Remove extra posts
121+
$posts = array_slice($posts, 0, $original_posts_per_page);
122+
123+
// Update post count to our new value
124+
$post_count = $original_posts_per_page;
125+
}
126+
}
127+
}
128+
129+
if (!function_exists('unique_wp_query_pre_get_posts')) {
130+
/**
131+
* Increase the posts_per_page value by the number of posts that have
132+
* already been used. Executes as the last pre_get_posts action.
133+
*/
134+
function unique_wp_query_pre_get_posts(&$query) {
135+
if (true === $query->get('unique_wp_query')) {
136+
$posts_per_page = $query->get('posts_per_page');
137+
138+
// Increase posts_per_page by the amount of used post_ids
139+
$query->set('original_posts_per_page', min($posts_per_page, 200));
140+
$query->set('posts_per_page', min($posts_per_page + Unique_WP_Query_Manager::$used_post_count, 200));
141+
}
142+
}
143+
144+
add_action('pre_get_posts', 'unique_wp_query_pre_get_posts', PHP_INT_MAX);
145+
}

0 commit comments

Comments
 (0)