Mar 27 2008
array_multisort is your friend
More and more these days I’ve been using Wordpress as the base for web projects. The code base is fantastic, elegant, and simple, and they care about web standards and proper XHTML output. Plugins and themes are easy to write, and the documentation is excellent.
So, for sites that lend themselves to a certain blogginess – sites that are mainly content, updated regularly, and where the content falls within a few different categories – it’s a good fit. You can update a core code base from the maintainers, while your plugins and themes for that site remain in separate folders and that’s the only stuff you have to maintain.
But, sometimes you need to do non-bloggy stuff. For example, on a site for media lawyers I’m working on, we want a list of all the member lawyers. These lawyers will be able to log on and post things in a contributor or author role, and so they all have accounts on the site. It seemed natural, then, to expand the information stored for each user and use the accounts to generate the member list.
The first thing I did was download or create a plugin which allowed me to store more information about each author than I could with the stock registration form. I found WP User Manager, so instead of writing my own I plugged that in.
Next, I created a page (not a post) called “Media Lawyers” and assigned to that a template of my own creation. I called mine “author-list.php” and stuck it in the folder for the theme I created especially for the site. This file needs to have these magic lines somewhere near the top:
< ?php /* Template Name: Member List */ ?>
That tells Wordpress that this is a template available for use with pages.
Now in this file you write the code for displaying the member list. Wordpress provides a handy function for this: wp_list_authors(). But there’s a rub. No, two rubs. The first is that it won’t list any authors who have not yet written anything. That would make it useless as a member directory, since not even half of them have written stuff for the site yet. The second problem is that we wanted the lawyers to sort by province. A custom function was required.
WP User Manager stores all extra information about authors in the wp_usermeta table, which consists of four columns: id, user id, meta_key, and meta_ value. That’s logical, because that way the info gets pulled into the author queries that the Wordpress core does, and also your work won’t be changed or erased the next time you update Wordpress.
Each user might have any number of entries in that table, like 131, 5, compname, My Big Lawyer Firm. So you know right away we’re going to be in to a loop of database calls and some array manipulation. Messy, but no way around it. So let’s get started:
$sql = "SELECT * FROM {$wpdb->users}"; $res = mysql_query($sql);
That’s going to pull all the user data out of the main user table, but there’s no good way to join to the user meta table and get the associated data for each user. So we just have to do another table query as we loop through that list.
while($user = mysql_fetch_assoc($res)) { $users[$user['ID']] = $user; $sql = "SELECT * FROM {$wpdb->usermeta} WHERE {$wpdb->usermeta}.user_id = {$user['ID']}"; $res2 = mysql_query($sql); while($datum = mysql_fetch_assoc($res2)) { $users[$user['ID']][$datum['meta_key']] = $datum['meta_value']; } }
Now we have all our user data in one place, one entry per user in our $users array.
But wait, how do we sort it? We want the lawyers to sort first by province, then by last name. array_multisort to the rescue. But first, because we have an array of rows, and array_multisort needs an array of columns, we have to create a couple of arrays for array_multisort to sort against. Here comes another loop:
foreach ($users as $key => $row) { $prov[$key] = $row['wpum_compprov']; $last_name[$key] = $row['last_name']; }
And now we’re ready for the magic of multisorting:
array_multisort($prov, SORT_ASC, $last_name, SORT_ASC, $users);
And bingo, I’ve got a nice sorted array of users with all their data. Now I can loop through that and display it any way I want.
Leave a Reply
Additional comments powered by BackType