How to order multidimensional arrays PHP - php

I've been stuck for hours in trying to order get_pages() object from wordpress.
I need to order the pages by menu_order (get_pages->menu_order);
I've been trying several PHP functions but none worked in such purpose.
PHP
foreach(get_pages(pll_current_language()) as $page) {
// Somewhere here each page should go up/down in order to be DESC/ASC
$template = get_post_meta( $page->ID, '_wp_page_template', true );
include_once($template);
}
My question is, How can I order this object by one of its values,
example:
I want to order get_pages() by get_pages()->menu_order
Any help will be appreciated.

just use the $args options array and set the sort_order, sort_column on whatever you need, check the docs https://codex.wordpress.org/Function_Reference/get_pages
$args = [
'sort_order' => 'asc',
'sort_column' => 'menu_order'
];
$pages = get_pages($args);

You probably want to use the usort function. You provide it with a comparison function (in your case a function that compares $a->menu_order to $b->menu_order) and it will then use it to sort the elements in your array.

Related

Query all pages including subpages of child pages in Wordpress

I have following structure
Services
-Page_1
-Page_2
--Page_3
--Page_4
I use Wp-query to get pages. This is my args:
<?php $args = array(
'post_type' => 'page',
'post_parent' => '45'
); ?>
45 is ID of Services page.
But I only get first level Page_1 and Page_2. How do I get all pages? I'm using Advanced Custom Fields plugin so using get_pages() is not a good option, is it?
As mentioned in your comments, the easiest solutions is to actually use get_pages(). You can still grab meta data of posts if you are able to get the the ID of the page (which you can with get_pages()) so you should still be able to ACF's custom fields.
Here's an example of get_pages():
$args = array(
'child_of' => 45,
'post_type' => 'page',
);
$pages = get_pages($args);
The main difference between get_pages() and WP_Query that we want to focus on here is the 'child-of'=>45 paramater vs the 'post_parent'=>45.
The child-of argument will grab ALL children throughout the hierarchy, i.e. children and children's children etc.
In contrast, the post-parent argument of WP_Query will only grab direct children of the page.
Using in conjunction with ACF
If you need to grab custom fields from ACF, you will still be able to use get_post_meta().
If your custom field includes an array of values, you will need to unserialize it first and then loop through the values like this:
$meta = get_post_meta( $post->ID, 'acf_meta_key', true ); //grab the post meta using WordPress core function
$array = unserialize( $meta ); //unserialize the field into an array
foreach ( $array as $value ) { //loop through the array
echo $value .'<br>';
}

Wordpress WP_Query category__in with order

Hi I'm trying to make a query to get posts from a specific categories like this:
$args = array('category__in' => array(8,3,12,7));
$posts = new WP_Query($args);
But I need the posts to be displayed in that specific order ( cat id 8 first, then 3, etc ), I can't get it to work properly, posts are displayed according to ASC or DESC names.
Any Help?
You can sort by post__in to use the order of the input values, but with category__in it is a many to many relationship, so using it order by is considerably more difficult and is not supported as far as I know. Also note that WP_Query() does not return an array of posts.
If you have your specific set of ordering rules you can take the results from get_posts() using the category argument, and then use a custom sorting function to order the results using usort() and get_categories().
// function used by usort() to sort your array of posts
function sort_posts_by_categories( $a, $b ){
// $a and $b are post object elements from your array of posts
$a_cats = get_categories( $a->ID );
$b_cats = get_categories( $b->ID );
// determine how you want to compare these two arrays of categories...
// perhaps if the categories are the same you want to follow it by title, etc
// return -1 if you want $a before $b
// return 1 if you want $b before $a
// return 0 if they are equal
}
// get an array of post objects in the 'category' IDs provided
$posts = get_posts( array( 'category' => '8,3,12,7' ) );
// sort $posts using your custom function which compares the categories.
usort( $posts, 'sort_posts_by_categories' );
To my knowledge the best approach here is to make 4 separate queries.

Natural sort Wordpress post titles (alphabetically and numerically)?

Is there any possible way to sort a new Wordpress post query by the title, but numerically instead of alphabetically?
I have some titles that have a lot of the same name alphabetically, then have a number afterwards, so of course for example Wordpress is putting title12 ahead of title1.
$args = array(
'orderby'=> 'title',
'order' => 'ASC',
);
$loop = new WP_Query( $args );
I know we have this functionality to sort titles in ascending order, but it does not sort titles like that:
Title 1
Title 2
Please let me know if we any work around using WP query ?
Thanks for your help in advance :)
Try adding this immediately after your code above:
usort($loop->posts, function($a,$b) {
return strnatcmp($a->title, $b->post_title);
});

Dynamically add_action() based upon number of posts

I have a wp_cron which I run every hour.
The cron calls a function which iterates through a custom post type. The title and some meta data is then used to scrape results from a remote server.
The problem is that the scraping takes a long because of the number of posts. I want to split the scraping into chunks by only iterating through 25 posts at a time. This is easy using the offset parameter in query_posts, but how do I dynamically add_action() and pass the offset variable?
In functions.php
if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}
add_action( 'my_task_hook', 'rock_n_roll' );
My scraper.php looks something like this
function rock_n_roll($offset) {
query_posts(array(
'post_type' => 'wine',
'order' => 'ASC',
'posts_per_page' => -1,
'offset' => $offset
));
while (have_posts()) : the_post();
//compare values against scraped results
//write results to DB with update_post_meta
endwhile;
}
Basically I need a way to dynamically add_action(), incrementing the value of $offset by 25 each time.
You can pass a variable to your add_action():
add_action( $tag, $function_to_add, $arg );
But you can also use do_action() instead of adding action every time your cron runs:
do_action( $tag, $arg )
Anyway, is good to store your $offset somewhere, so I see two options:
Store your persistent values in WP_Object_Cache. Maybe reading this documentation, you can find another elegant solution for your performance with large query results.
Recording in the database your actual $offset value using add_option() and get_option().
If you store your $offset variable, your rock_and_roll function don't need to receive a parameter anymore, you just need to retrieve it inside the function.
function rock_n_roll() {
// Retrieve $offset value from WP_Object_Cache
// or from database with get_option()
query_posts(array(
'post_type' => 'wine',
'order' => 'ASC',
'posts_per_page' => -1,
'offset' => $offset
));
while (have_posts()) : the_post();
//compare values against scraped results
//write results to DB with update_post_meta
endwhile;
}
Your $Offset is passed to the function from another source.. So I could imagine, something like:
$Var = $Pre_definedoffset;
$Var = $Pre_definedoffset + 25;
rock_n_roll($var);
This is just assumptions from what I can see from your code.
You will need to modify the variable containing the integer which is passed through to your function, before the code pushes it through the function.

Get Authors Randomly

how to get authors details and author page permalink randomly. I have checked the new get_users() function for wordpress which is returning the author but i can not sorting them randomly.
here is the site i am using the code: http://citystir.com
Any help?
Solution: Thanks to theomega i have solved the isse. Here is the code just for community sharing:
$args = array('role' => 'author');
$authors = get_users($args);
shuffle($authors);
$i = 0;
foreach ($authors as $author):
if($i == 4) break;
//do stuff
$i++;
endforeach;
Did not set the limit on the $args because i need the shuffle in all users. Hope it will help someone out there, in the wild. :D Thanks!
Try
$users = get_users('ciriteria');
shuffle($users)
//users is now shuffled
Using the PHP Shuffle-Function.
We can use the get_users() to get a list of authors, users with a specific role, user with specific meta, etc. The function returns users which can be ordered by ID, login, nicename, email, url, registered, display_name, post_count, or meta_value. But there is no random option such as what get_posts() function provides to shows posts randomly.
Since the get_users() function uses WP_User_Query class, there is an action hook pre_user_query we can use to modify the class variable. The idea is using our own ‘rand’ order by parameter. If we put “rand” to the orderby parameter, “user_login” will be used instead. In this case, we need to replace it with RAND() to result users randomly. In this example below, we I ‘rand’ and you can use your own order by name.
add_action( 'pre_user_query', 'my_random_user_query' );
function my_random_user_query( $class ) {
if( 'rand' == $class->query_vars['orderby'] )
$class->query_orderby = str_replace( 'user_login', 'RAND()', $class->query_orderby );
return $class;
}
The WP_User_Query contains order by query and the our arguments. Now, we have a new order by parameter to WordPress.
$users = get_users( array(
'orderby' => 'rand',
'number' => 5
));
print_r( $users );
Reference: http://www.codecheese.com/2014/05/order-wordpress-users-random/

Categories