It is quite easy to achieve this. Your answer is usort()
FEW NOTES:
Before we code, just a few notes
-
Requires PHP5.4+ due to the use of the short array syntax (
[]
). If you have an older version, you should really upgrade as older versions are a real security threat as all older versions prior to PHP 5.4 has been EOL’ed -
I will comment the code as I go along so you can easy follow it
-
Taxonomy terms and custom fields are cached, so you will not be doing extra db calls, so the solution is still very lean.
-
The code below is untested, so be sure to test this locally first
THE CODE:
public function automate_posts_to_send()
{
$value = get_option( 'email_settings_options');
$article_number = $value['number_of_articles_to_send'];
/**
* Add the tag ids here in the correct order you need your posts to be in
* In this example, posts from tag 2 will show first, then posts from tag 3 then tag 1
* As I said, I'm using short array syntax, so for older versions of PHP prior to 5.4,
* [2, 3, 1] would become array( 2, 3, 1 )
*/
$tag_order = [2, 3, 1];
$args = [
'tag__in' => $tag_order,
//'orderby' => $tag_order // This is invalid ordering, add valid value here according to needs
'posts_per_page' => $article_number,
'date_query' => [
[
'after' => '24 hours ago'
]
],
];
$posts_array = get_posts( $args );
/**
* Now we will sort the returned array of posts as we need them according to $tag_order. We will use usort()
*
* There is a bug in usort causing the following error:
* usort(): Array was modified by the user comparison function
* @see https://bugs.php.net/bug.php?id=50688
* This bug has yet to be fixed, when, no one knows. The only workaround is to suppress the error reporting
* by using the @ sign before usort
*/
@usort( $posts_array, function ( $a, $b ) use ( $tag_order )
{
// Store our post ids in an array. We will use that to get our post tags per post
$array = [
'a' => $a->ID, // Use only post ID
'b' => $b->ID // Same as above
];
// Define our two variables which will hold the desired tag id
$array_a = [];
$array_b = [];
// We will now get and store our post tags according to the tags in $tag_order
foreach ( $array as $k=>$v ) {
$tags = get_the_tags( $v );
if ( $tags ) {
foreach ( $tags as $tag ) {
if ( !in_array( $tag->term_id, $tag_order ) )
continue;
// If we found a tag that is in the $tag_order array, store it and break the foreach loop
${'array_' . $k}[] = $tag->term_id; // Will produce $array_a[] = $tag->term_id or $array_b[] = $tag->term_id
// If we found the tag we are looking for, break the foreach loop
break;
} // endforeach $tags
} // endif $tags
} // endforeach $array
// Flip the $tag_order array for sorting purposes
$flipped_tag_order = array_flip( $tag_order );
/**
* Lets sort our array now
*
* We will sort according to tag first. If the tags between two posts being compared are the same
* we will sort the posts by post date. Adjust this as necessary
*/
if ( $flipped_tag_order[$array_a] != $flipped_tag_order[$array_b] ) {
return $flipped_tag_order[$array_a] - $flipped_tag_order[$array_b];
} else {
return $a->post_date < $b->post_date; // Change to > if you need oldest posts first
}
}); // end our usort ordering
// We are done sorting, etc. Return our $posts_array
return $posts_array;
}