-
Notifications
You must be signed in to change notification settings - Fork 0
Post Collections
Post collections are an abstraction for WP_Query. They allow you to create a post query without submitting it to the database, and derive new variations of that query through a fluent interface.
This is useful for creating a query that you want to use in multiple places, or for creating a "base" query for a set of posts that you want to modify in different ways later on.
Post collections are created using a query arguments array, just like WP_Query.
use RebelCode\WpSdk\Wp\PostCollection;
$collection = new PostCollection([
'post_type' => 'books',
'post_status' => 'publish',
'posts_per_page' => 10,
'meta_query' => [
[
'key' => 'author',
'value' => 'J.K. Rowling',
],
]
]);
$posts = $collection->get();The query is not executed until you call a method that requires the results, such as:
Iterate over collection
foreach ($collection as $post) {
// ...
}Get array of posts
$posts = $collection->get();Get Iterator for posts
$iterator = $collection->getIterator();Get the number of posts
$count = $collection->count();Get a post with a specific ID
$post = $collection->getById(123);
if ($post === null) {
// Post not found
}Note: this will only retrieve posts that have the given ID and also satisfy the collection's query.
Get the first post
$first = $collection->first();Map the posts
$titles = $collection->map(function ($post) {
return $post->post_title;
});Filter the posts
$filtered = $collection->filter(function ($post) {
return strpos($post->post_title, 'News:') === 0;
});Reduce the posts
$comments = $collection->reduce(0, function ($total, $post) {
return $total + $post->comment_count;
}, []);The following methods do not execute the query, but instead return a new collection with modified query arguments:
Add query arguments
$collection = new PostCollection([
'post_type' => 'books',
'post_status' => 'publish',
]);
$collection2 = $collection->with([
'meta_query' => [
[
'key' => 'author',
'value' => 'J.K. Rowling',
],
]
]);Set a post limit
// Limit to 10 posts
$collection2 = $collection->limit(10);
// Remove the limit
$collection3 = $collection2->limit(null);Set a post offset
// Offset by 10 posts
$collection2 = $collection->offset(10);Set the page
// Get the second page of posts
$collection2 = $collection->page(2);The fluent interface allows you to chain methods together to create a new collection with modified query arguments, and get its result immediately.
Example 1:
$collection = new PostCollection(['post_type' => 'books']);
$publishedBooks = $collection
->with(['post_status' => 'publish'])
->limit(10)
->page(2)
->get();Example 2: Pagination
Pagination is a common task with post queries. With post collections, pagination can be easily achieved by using the
limit() method to create a new collection with a fixed page size, and then calling page()->get() on that collection
to get each individual page.
$paginated = $collection->limit(20);
$page1 = $paginated->page(1)->get(); // First page
$page2 = $paginated->page(2)->get(); // Second page
$page3 = $paginated->page(3)->get(); // Third pageYou can easily create a post collection factory service using the PostCollection::factory() static method. It accepts
the query arguments array as its only argument, like the constructor.
use RebelCode\WpSdk\Module;
use RebelCode\WpSdk\Wp\PostCollection;
class MyModule extends Module
{
public function getFactories() : array
{
return [
'books' => PostCollection::factory([
'post_type' => 'books',
'post_status' => 'publish',
]),
];
}
}