Well, I'm new in this game and the world of drupal and I'm having some troubles to create a new module. I'm trying to build my own "birthday module". It needs the profile module where you have to create a birthday field. You must insert the id of this field in the settings of my module along with the number of days to look in the past and future.
Actually it works without a problem until I insert a number which result in a day of 1 january or later (47 days from now apparently). Then my block just don't come up as if there are no birthdays to display.
I suppose it has something to do with how I'm creating the dates but I don't see anything wrong:

      // Create today's date, remove the "/" and create a time from the resulting string
      // I use j because days smaller then 10 are stored as one digit
      $today = date('m/j'); 
      list($month,$day) = explode('/', $today); 
      $startTime = mktime(12, 0 , 0, $month, $day); 
   
      // Create the date from when you'll start the search for birthdays
      // also convert from string to time
      $from = date('m/j', $startTime - $daysPast*60*24*60);
      $converFrom = strtotime($from);
   
      // Create the last date to search for birthdays
      // also convert from string to time
      $until = date('m/j', $startTime + $daysFuture*60*24*60);
      $converUntil = strtotime($until);

Then I just do a query to get all the users, pull the birthday field and convert it also to an integer to check if it is between the two dates.

Comments

Horla’s picture

I guess it has something to do with the fact that I just look at the day and month. The today string of 11/15 is probably greater then 01/1. Stupid me, I guess that this thread could be closed.
edit: Is there any way to make sure that january xx comes after december xx in my list? Because I don't see any. My sql string is supposed to sort them but apparently it looks only at the first digits in the database (the month).

$result = db_query("SELECT users.uid, users.name, v.value FROM users INNER JOIN {profile_values} v ON users.uid = v.uid WHERE v.fid = '$id' ORDER BY v.value");
InterceptPoint’s picture

One way around this problem that is a real kludge but does work is to just put the birthdays in a table and run the records out for 10-15 years or so with "year" as a field in the table. Then you can use a date function like JulianDate() or DaysSince01Jan1970() and then Jan 5, 2007 will follow Nov 15, 2006. I wrote the code for this in C# on an asp.net site that I did some time ago.

But it would be much cleaner to do it your way if there is an algorithm that will place a date in January after a date in December if TimeNow() is after your January date. I posed a similar question a couple of weeks ago on this forum and drew a blank. It would be nice to have a module/code that does what you are trying to do. I would sure use it so I hope someone will jump in and give us a good solution.

-- InterceptPoint

Horla’s picture

I think I just solved it. Probably not the way it should be but hell, it seems to work.
First I get all the dates and users and put them in a multi-dimensional array.

$result = db_query("SELECT users.uid, users.name, v.value FROM users INNER JOIN {profile_values} v ON users.uid = v.uid WHERE v.fid = '$id' ORDER BY v.value");
$array[$counter][0] = "<li>"."{$u->{$name}{day}}/{$u->{$name}{month}}/{$u->{$name}{year}}"." ".l($u->name, "user/" . $u->uid)."</li>\n";
$array[$counter][1] = $counter;
$array[$counter][2] = $converDOB;
$counter = $counter + 1;

If I see that the end date is smaller then the start date then it indicates that I go from december to january. I flip the order with an usort function.

usort($array, 'cmp');
function cmp($a, $b)
{
   if($a[1] == $b[1])
   {
      return 0;
   }
   return ($b[1] < $a[1]) ? -1 : 1;
}

Then I read the array but since I flipped the order, february will come now before january so I check if the birthdate (month/day) is greater then the first february.

for ($i = 0; $i <= $counter; $i++)
{
        $febr = 31/1;
        	$converFebr = strtotime($febr);
        	
        	if ($array[$i][2] <= $converFrom && $array[$i][2] > $converFebr)
        	{
        		if ($array[$i][2] >= $converFrom || ($array[$i][2] >= $converFirstDay && $array[$i][2] <= $converUntil) )
        		{
        			$blockContent .= "{$array[($counter - $i + 1)][0]}";
        		}
        	}
        	else
        	{
        		if ($array[$i][2] >= $converFrom || ($array[$i][2] >= $converFirstDay && $array[$i][2] <= $converUntil) )
        		{
        			$blockContent .= "{$array[$i][0]}";
        		}
        	}
}
nautis’s picture

Here's the solution I'm using:

<?php
$monthnumber = date(n);
$monthstring = "%\\\"month\\\"\\;s\\:".strlen($monthnumber)."\\:\\\"".$monthnumber."%";
$sql = "SELECT u.uid, u.name, u.created, v.value FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = '5' and v.value LIKE '$monthstring'";
$birthdays = db_query($sql);
$users = db_num_rows($birthdays);
$num_bdays = 0;
if ($users > 0) {
for ($count = 1; $count <= $users; $count ++) {
$bdaydata = db_fetch_array($birthdays);
// new code to trap birthday = joined date here
$joinedday = date("j", $bdaydata['created']);
$joinedmonth = date("n", $bdaydata['created']);
$joinedyear = date("Y", $bdaydata['created']);
$joindate = "a:3:{s:5:\"month\";s:".strlen($joinedmonth);
$joindate .= ":\"".$joinedmonth."\";s:3:\"day\";s:";
$joindate .= strlen($joinedday).":\"".$joinedday."\";s:4:";
$joindate .= "\"year\";s:4:\"".$joinedyear."\";}";
if ($joindate != $bdaydata['value']) {
$num_bdays = $num_bdays + 1;
$bday_name[$count] = $bdaydata['name'];
$daystring = $bdaydata['value'];
$bdayarray = explode (";", $daystring);
$bdayday = explode (":", $bdayarray[3]);
$daystring = substr($bdayday[2], 1, strlen($bdayday[2])-2);
$daystring = strtotime($daystring." December 1979");
$bday_day[$count] = date(jS, $daystring);
$bday_uid[$count] = $bdaydata['uid'];
}
}
}
if ($num_bdays > 0) {
array_multisort($bday_day, SORT_ASC, SORT_NUMERIC, $bday_name, $bday_uid);
?>
<div class="block block-comment" id="block-comment-0"><div class="content"><div class="item-list"><ul>
<?php
for ($output = 0; $output < count($bday_name); $output++) {
if ($bday_day[$output] == $bday_day[$output-1]) {
$bday_day[$output] = " ";
}
echo "<li>".$bday_name[$output]."</li>\r\n";
}
?>
<ul></div></div></div>
<?php
} else {
}
?>

Someone here wrote this for me. I would have never figured it out. You can see it here: www.lassiter91.com

orick’s picture

Any chance of sharing that module? I am sure quite a few people could use that. :)

Horla’s picture

I've applied for a CVS account to share my module. I'll try to upload it to a temporary location later this evening.

Horla’s picture

http://webs.hogent.be/~023054bd/birthday.rar
Just extract the rar and put the birthday folder in your modules directory. You can then activate the block in the block section where you can also change the settings. The profile module and a date are required.

orick’s picture

Thanks for the follow up Horla. I will try it out this weekend.