PHP Sorting Problem
Hey guys, it's good to be back!
I have a small problem with a code I wrote... I need to sort the output by the $days string (ascending) so once printed, will display with the smallest number to the top.
<?php
$result = db_query("SELECT uid FROM {users}");
while ($uid = db_fetch_object($result)) {
$uids[] = user_load($uid->uid);
}
foreach($uids as $data) {
$days = ($data->profile_details_birthdate['day']) - date("d");
$months = ($data->profile_details_birthdate['month']) - date("m");
if($months == "0" && $days <= "7") {
if($days > "0") {
print l($data->name,'user/'.$data->uid).'\'s birthday in '.format_plural($days, '1 day', '@count days').'<br />';
}
if($days == "0") {
print '<strong>'.l($data->name,'user/'.$data->uid).'\'s birthday is today!</strong>';
print ' (<a class="formdialog" href="/messages/new/'.$data->uid.'/Happy%20Birthday,%20'.$data->name.'!">Send Message</a>)<br />';
}
}
}
?>
Can anyone point me in the right direction?
Thanks!
All the best news here: https://newsbotnet.com
Greg K posted this at 02:44 — 6th May 2010.
He has: 2,145 posts
Joined: Nov 2003
This first version is if you need to have all the users in an array for some other reason besides just the birthday list. Please note the use of mktime to make sure time stamps are at midnight, and that they will be the correct values for leap years and for wrapping the end of the year till the next. Your code was only checking if the birthday was within the same month. What it if is May 29, a birthday on June 1 wouldn't list.
<?php
$aryBDkeys = array();
$aryUIDs = array();
$result = db_query("SELECT uid FROM {users}"); // Add an ORDER BY for any secondary sort after Days
// Load this into an array to lessen the number of calls
$intYear = date('Y');
$tsTodayMidnight = mktime(0,0,0,date('m'),date('d'),date('Y'));
$int24Hours = 24*60*60;
$ts7Days = $tsTodayMidnight + (7*$int24Hours);
$intRecCount = 0;
while ($uid = db_fetch_object($result)) {
$aryUIDs[$intRecCount] = user_load($uid->uid);
$tsBD = mktime(0,0,0,$aryUIDs[$intRecCount]->profile_details_birthdate['month'],$aryUIDs[$intRecCount]->profile_details_birthdate['day'],$intYear);
if ($tsBD < $tsTodayMidnight) {
// Birthday this calendar year already passed, so change to next calendar year
$tsBD = mktime(0,0,0,$aryUIDs[$intRecCount]->profile_details_birthdate['month'],$aryUIDs[$intRecCount]->profile_details_birthdate['day'],$intYear+1);
}
if ($tsBD <= $ts7Days) {
// it is between today and 7 days...
$aryBDkeys[$intRecCount] = ($tsBD - $tsTodayMidnight) / $int24Hours;
}
}
asort($aryBDkeys);
foreach($aryBDkeys as $intUIDkey=>$intDays) {
if($intDays > "0") {
print l($aryUIDs[$intUIDkey]->name,'user/'.$aryUIDs[$intUIDkey]->uid).'\'s birthday in '.format_plural($days, '1 day', '@count days').'<br />';
}
else {
print '<strong>'.l($aryUIDs[$intUIDkey]->name,'user/'.$aryUIDs[$intUIDkey]->uid).'\'s birthday is today!</strong>';
print ' (<a class="formdialog" href="/messages/new/'.$aryUIDs[$intUIDkey]->uid.'/Happy%20Birthday,%20'.$aryUIDs[$intUIDkey]->name.'!">Send Message</a>)<br />';
}
}
unset($aryBDkeys );
?>
ok, now a version for if you are just getting the records for the list of the birthdays:
<?php
$aryUIDs = array();
$result = db_query("SELECT uid FROM {users}"); // Add an ORDER BY for any secondary sort after Days
// Load this into an array to lessen the number of calls
$intYear = date('Y');
$tsTodayMidnight = mktime(0,0,0,date('m'),date('d'),date('Y'));
$int24Hours = 24*60*60;
$ts7Days = $tsTodayMidnight + (7*$int24Hours);
$intRecCount = 10000; // This will work up to 90,000 records
while ($uid = db_fetch_object($result)) {
$aryTemp = user_load($uid->uid);
$tsBD = mktime(0,0,0,$aryTemp->profile_details_birthdate['month'],$aryTemp->profile_details_birthdate['day'],$intYear);
if ($tsBD < $tsTodayMidnight) {
// Birthday this calendar year already passed, so change to next calendar year
$tsBD = mktime(0,0,0,$aryTemp->profile_details_birthdate['month'],$aryTemp->profile_details_birthdate['day'],$intYear+1);
}
if ($tsBD <= $ts7Days) {
// it is between today and 7 days...
$aryTemp['DaysToBD'] = ($tsBD - $tsTodayMidnight) / $int24Hours;
$aryUIDs[$aryTemp['DaysToBD'].($intRecCount++)] = $aryTemp; // use rec cound to make sure key unique
}
}
ksort($aryUIDs);
foreach($aryUIDs as $aryData) {
if($aryData['DaysToBD'] > "0") {
print l($aryData->name,'user/'.$aryData->uid).'\'s birthday in '.format_plural($aryData['DaysToBD'], '1 day', '@count days').'<br />';
}
else {
print '<strong>'.l($aryData->name,'user/'.$aryData->uid).'\'s birthday is today!</strong>';
print ' (<a class="formdialog" href="/messages/new/'.$aryData->uid.'/Happy%20Birthday,%20'.$aryData->name.'!">Send Message</a>)<br />';
}
}
unset($aryUIDs);
?>
However to be honest, if you are jsut listing the next 7 days worth, it is better find a way to just return it from the SQL query.
-Greg
DarkLight posted this at 12:19 — 6th May 2010.
He has: 287 posts
Joined: Oct 2007
Hey greg, thanks for the response. The code is great! And you alerted me to that issue with the same month check... I am having problems with both codes... The first, returns only one user... I'm guessing I have to loop it somewhere, but how? The second, returns a PHP Error. I remove the semicolon from the } and the page loads properly, but it screws up the content.
I'm no expert here, but I'm willing to learn
Thanks again.
All the best news here: https://newsbotnet.com
DarkLight posted this at 14:44 — 6th May 2010.
He has: 287 posts
Joined: Oct 2007
Hey, I appreciate your help, but I've decided to use the Birthday module for Drupal. It's more efficient and does exactly what I need. Plus it is easily themed.
All the best news here: https://newsbotnet.com
Greg K posted this at 16:17 — 6th May 2010.
He has: 2,145 posts
Joined: Nov 2003
Ahh, on the first one I forgot to put in the $intRecCount++; inside the while loop.
Even though you went with another method, where did you remove the ; from ont he second one?
DarkLight posted this at 16:43 — 6th May 2010.
He has: 287 posts
Joined: Oct 2007
Hey Greg... Sorry about that, I was wrong, my eyes are a pain in the backside... It wasn't a } it was a )
*embarassed* Now I feel stupid
Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.