<?php

/**
 * @file
 * Allows users to store their birthdays and displays block of upcoming birthdays.
 * Sends out greating postcards if postcard module is installed or sends user e-mail on
 * their birthday automatically as cron job. Also sends admin reminder e-mails of upcoming
 * user's birthdays.
 * 
 * S M Mahbub Murshed (udvranto@yahoo.com) 
 * Updated to have a settings page, show during registration,
 * a new dynamic block, lots of bug fixing.
 */

/**
 * Implementation of hook_help().
 */

function birthdays_help($section = '') {
	$output = '';
	switch($section) {
		case 'admin/modules#description':
			$output = t("Displays & reminds of upcoming users birthdays");
			break;	
		case 'admin/help#birthdays':
			$output  = 'Allows users to store their birthdays and displays block of upcoming birthdays. ';
 			$output .= 'Sends out greating postcards if postcard module is installed or sends user e-mail on ';
 			$output .= "their birthday automatically as cron job. Also sends admin reminder e-mails of upcoming user's birthdays.";
			break;
	}
	
	return $output;
}

/**
 * Implementation of hook_menu().
 */

function birthdays_menu($may_cache) {
	$items = array();
	if ($may_cache) {
  	$items[] = array(
  		'path' => 'birthdays',
  		'title' => t('birthdays'),
  		'access' => user_access('access birthdays'),
  		'callback' => 'birthdays_page',
  		'type' => MENU_SUGGESTED_ITEM
  	);
  	$items[] = array(
  		'path' => 'admin/settings/birthdays',
  		'title' => t('birthdays setting'),
  		'access' => user_access('administer birthdays'),
  		'callback' => 'birthdays_settings_page',
  	);
	}
		
	return $items;
}

/**
 * Implementation of hook_perm().
 */

function birthdays_perm() {
	return array('administer birthdays', 'access birthdays', 'edit DOB');
}

/**
 * Implementation of hook_cron().
 */
 
 function birthdays_cron() {
 
 	// Perform these actions just once per day
	
	if (variable_get('birthdays_last_cron', 0) < (time() - 3600*24)) {
	    _birthdays_message();
	    variable_set('birthdays_last_cron', time());
  	}
 }

/**
 * Implementation of hook_block
 * - Block lists upcoming birthdays
 *
 * @param $op the operation that is being requested.  This defaults to 'list', which indicates that the method should
 *        return which blocks are available.
 * @param $delta the specific block to display.  This is actually the offset into an array.
 * @return one of two possibilities.  The first is an array of available blocks.  The other is an array containing a
 *
 */

function birthdays_block($op = 'list', $delta = 0, $edit = array()) {
	
	$block = array();
	
	if($op == 'list') {
		$block[0]['info'] = t('Birthdays Block');
		$block[1]['info'] = t('Birthdays Next');
	}
	elseif($op == 'configure') {
		// Configuration settings for block
		if($delta==0) {
  		$form["birthday_past_limit"] = array(
  		  '#type' => 'textfield',
  		  '#title' => t("List Number"),
  		  '#default_value' => variable_get("birthdays_list_number", 3),
  		  '#size' => 2,
  		  '#maxlength' => 2,
  		  '#description' => t("Number of upcoming birthdays to list in block"),);
		}
		else if($delta==1) {
  		$form["birthday_next_days"] = array(
  		  '#type' => 'textfield',
  		  '#title' => t("Days before birthday"),
  		  '#default_value' => variable_get("birthdays_day_before", 1),
  		  '#size' => 2,
  		  '#maxlength' => 2,
  		  '#description' => t("Number of days before a birthday should be reported"),);
  		$form["birthday_next_limit"] = array(
  		  '#type' => 'textfield',
  		  '#title' => t("List Number"),
  		  '#default_value' => variable_get("birthdays_next_list_number", -1),
  		  '#size' => 2,
  		  '#maxlength' => 2,
  		  '#description' => t("Number of upcoming birthdays to list in block"),);
		}

		return $form;
	}
  else if ($op == 'save') {
    if($delta==0) {
      variable_set('birthdays_list_number', $edit['birthday_past_limit']);
    }
    else if($delta==1) {
      variable_set('birthdays_day_before', $edit['birthday_next_days']);
      variable_set('birthdays_next_list_number', $edit['birthday_next_limit']);
    }
  }
	else {
		// Render block content
		if (user_access('access birthdays')) {
  		if($delta==0) {
    		$birthdays = _get_upcoming_birthdays(variable_get("birthdays_list_number", 3));
  		}
			else if($delta==1) {
  			$birthdays = _get_birthdays_next(variable_get("birthdays_day_before", 1),variable_get("birthdays_next_list_number", -1));
      }
      if($birthdays) {
 			  $blockContent = '<table width="100%">';
  			foreach ($birthdays as $user) {
  				$blockContent .= '<tr><td>' . l($user['name'], 'user/' . $user['uid']) . ' </td><td> ' . t($user['day']) . ' ' . t($user['month']) . '</td></tr>';
  			}
  			
  			$blockContent .= '</table>';
  			$blockContent .= '<div class="more-link">'.l(t('More').'...', t('birthdays')). '</div>';  			
  			$block['subject'] = t('Upcoming Birthdays');
  			$block['content'] = $blockContent;
  		}
		}
	}
		return $block;
}


/**
 * Implementation of hook_form_alter()
 * Mahbub 
 */
function birthdays_form_alter($form_id, &$form) {
  switch ($form_id) {
    case 'user_register':
			$form['DOB'] = array('#type' => 'date',
			          '#title' => t('Date of Birth'),
			          '#default_value' => array('year' => 1900, 'month' => 1, 'day' => 1),
			          '#description' => t('Enter your date of birth.'),
			          '#required' => false,);

      // Put the form field in the account fieldset if it exists.
      if (isset($form['account'])) {
        $form['account']['DOB'] = $form['DOB'];
        unset($form['DOB']);
      }
      break;
  }
}

/**
 * Implementation of hook_user().
 */

function birthdays_user($op, &$edit, &$user, $category = null) {
		switch($op) {
			case 'update':
				if($category != 'account') break;
				$year = $edit['DOB']['year'];
				$month = $edit['DOB']['month'];
				$day = $edit['DOB']['day'];
				
				$query = "SELECT uid FROM {dob} WHERE uid = $user->uid";
				$result = db_query($query);
				if (db_num_rows($result) == 0) {
					$query = "INSERT INTO {dob} (uid, birthday) VALUES ($user->uid, '{$year}-{$month}-{$day}');";
					db_query($query);
				} else {
				
					$query = "UPDATE {dob} SET birthday = '{$year}-{$month}-{$day}' WHERE uid = $user->uid";
					db_query($query);
				}
				
				break;
			case 'view':
			   // print_r($form);
				$query = "SELECT birthday FROM {dob} WHERE uid = $user->uid";
				$queryResult = db_query($query);
				$birthday = db_fetch_object($queryResult);
				
				if ($birthday->birthday != null)
				{
				
					$year = substr($birthday->birthday, 0, 4);
					$month = substr($birthday->birthday, 5, 2);
					$day = substr($birthday->birthday, 8, 2);
					$DOB = $month . '/' . $day . '/' . $year;
					
				  $show_starsign = variable_get('no_show_starsign', 0)?false:true;
          $show_age = variable_get('no_show_ages', 0)?false:true;

          if($show_age)
					 $age = _birthdays_calc_age($DOB);
				
					$content = "";					
          if($show_starsign)
            $content .= _get_starsign($day, $month);
          if($show_age)
            $content .= t($day) . ' ' . t(_get_month($month)) . ' (' . t($age) . ')';
          else
  				  $content .= t($day) . ' ' . t(_get_month($month));
						
 					$form['account'][] = array('title' => t('Birthday'),'value' => $content);
 					return $form;
 				}
 			break;
			case 'form':
				if($category != 'account') break;
				if (user_access('edit DOB') || user_access('administer users'))
				{
					$query = "SELECT birthday FROM {dob} WHERE uid = $user->uid";
					$queryResult = db_query($query);
					$birthday = db_fetch_object($queryResult);
					$dob = array('day' => substr($birthday->birthday, 8, 2),
					             'month' => substr($birthday->birthday, 5, 2),
					             'year' => substr($birthday->birthday, 0, 4));
				
					$year = substr($birthday->birthday, 0, 4);
					$month = substr($birthday->birthday, 5, 2);
					$day = substr($birthday->birthday, 8, 2);
          $form = array(); 
					$form['account']['DOB'] = array(
            '#type' => 'date',
	          '#title' => t('Date of Birth'),
	          '#default_value' => $dob,
	          '#description' => t('Enter your date of birth.'),
	          '#required' => false,
	          '#weight' => 9,
          );
					return $form;
				}
			break;
		}
}

/******************************************************************************
 * Pages
 */

// mahbub
function birthdays_settings_page() 
{
		$form['birthdays']['no_show_ages'] = array(
      '#type' => 'checkbox',
      '#title' => t('Do not show ages'),
      '#default_value' => variable_get('no_show_ages', 0),
      '#description' => t('Do not show ages in profile or birthday listing pages.'),
    );
		$form['birthdays']['no_show_starsign'] = array(
      '#type' => 'checkbox',
      '#title' => t('Do not show star signs'),
      '#default_value' => variable_get('no_show_starsign', 0),
      '#description' => t('Do not show star signs in profile or birthday listing pages.'),
    );
  
  return system_settings_form('birthdays_settings_page', $form);
}

/**
 * VIEW PAGE
 */
function birthdays_page() {

  if (user_access('access birthdays')) {

	drupal_set_title(t('User Birthdays'));

	$result = db_query('SELECT u.uid, u.name, u.picture, substring(birthday,6,2) as `month`, right(birthday, 2) as `day`, year(birthday) as `year` FROM {dob} d, {users} u WHERE d.uid=u.uid ORDER BY month, day');
  $show_starsign = variable_get('no_show_starsign', 0)?false:true;
  $show_age = variable_get('no_show_ages', 0)?false:true;
	$content = '<p>';
	if($show_starsign && $show_age)
	  $header = array(t('User'), t('Birthday'), t('Age'), t('Starsign'), t('Picture'));
	else if($show_starsign && !$show_age)
	  $header = array(t('User'), t('Birthday'), t('Starsign'), t('Picture'));
	else if(!$show_starsign && $show_age)
		$header = array(t('User'), t('Birthday'), t('Age'), t('Picture'));
	else if(!$show_starsign && !$show_age)
	 $header = array(t('User'), t('Birthday'), t('Picture'));

	$rows = array();

	while ($object = db_fetch_object($result)) {

		$DOB = $object->month . '/' . $object->day . '/' . $object->year;

		if($show_age)
  		$age = _birthdays_calc_age($DOB);
    
    $starsign = ' ';		
		if($show_starsign && $object->day && $object->month)
		  $starsign = _get_starsign($object->day, $object->month);

		$month = _get_month($object->month);

		$account = user_load(array('uid' => $object->uid));
		$picture = theme_user_picture($account);

		if($show_starsign && $show_age)
		  $rows[] = array(l($object->name, 'user/'.$object->uid), t($object->day) . ' ' . t($month), t($age), $starsign, $picture);
		else if($show_starsign && !$show_age)
		  $rows[] = array(l($object->name, 'user/'.$object->uid), t($object->day) . ' ' . t($month), $starsign, $picture);
		else if(!$show_starsign && $show_age)
  		$rows[] = array(l($object->name, 'user/'.$object->uid), t($object->day) . ' ' . t($month), t($age), $picture);
		else if(!$show_starsign && !$show_age)
		  $rows[] = array(l($object->name, 'user/'.$object->uid), t($object->day) . ' ' . t($month), $picture);
	}

	 $content .= theme("table", $header, $rows);
    print theme('page', $content);
  }
  else {
	drupal_access_denied();
  }
}

/******************************************************************************
 * Functions
 */

/**
 * _get_upcoming_birthdays()
 *
 * @param $limit Number of users to fetch from database
 * @return Returns an array of users for displaying upcoming birthdays
 *
 * - Returns an array of users that have birthdays upcoming up to a limit
 */
 
function _get_upcoming_birthdays($limit = 6) {

	$query = 'SELECT dob.uid, users.name, substring(birthday,6,2) as `month`, right(birthday, 2) as `day`'; 
	$query .= 'FROM {dob}, {users} WHERE users.uid = dob.uid AND DAYOFYEAR(birthday) >= DAYOFYEAR(curdate())';
	$query .= 'order by month, day limit 0,' . $limit;
	
	$result = db_query($query);
	
	$birthdays = array();
	
	while ($user = db_fetch_object($result)) {
	        
	        
	        $month = _get_shortmonth($user->month);
	        	        
		$birthdays[] = array('name' => $user->name, 'uid' => $user->uid, 'day' => $user->day, 'month' => $month);
	}
	
	if (db_num_rows($result) < $limit) {
	
		// If less than $limit results returned, look at next year
		
		$query = 'SELECT dob.uid, users.name, substring(birthday,6,2) as `month`, right(birthday, 2) as `day`'; 
		$query .= 'FROM {dob}, {users} WHERE users.uid = dob.uid AND DAYOFYEAR(birthday) >= 0 ';
		$query .= 'order by month, day limit 0,' . ($limit - db_num_rows($result));
	
		$result = db_query($query);
		
		while ($user = db_fetch_object($result)) {
			        
			$month = _get_shortmonth($user->month);
			        
			$birthdays[] = array('name' => $user->name, 'day' => $user->day, 'month' => $month);
		}
	}
	
	return $birthdays;
}


/**
 * _get_birthdays_next()
 *
 * @param $days Number of days before the birthday
 * @return Returns an array of users for displaying upcoming birthdays
 *
 * - Returns an array of users that have birthdays upcoming up to a limit
 */
 
function _get_birthdays_next($days = 1, $limit = -1) {

  if($limit<1) {
  	$query = 'SELECT dob.uid, users.name, substring(birthday,6,2) as `month`, right(birthday, 2) as `day`'; 
  	$query .= 'FROM {dob}, {users} WHERE users.uid = dob.uid AND DAYOFYEAR(birthday) >= DAYOFYEAR(curdate()) AND DAYOFYEAR(birthday) < DAYOFYEAR(curdate())+'.$days;
  	$query .= ' order by month, day';
	} else {
  	$query = 'SELECT dob.uid, users.name, substring(birthday,6,2) as `month`, right(birthday, 2) as `day`'; 
  	$query .= 'FROM {dob}, {users} WHERE users.uid = dob.uid AND DAYOFYEAR(birthday) >= DAYOFYEAR(curdate()) AND DAYOFYEAR(birthday) < DAYOFYEAR(curdate())+'.$days;
  	$query .= ' order by month, day limit 0,' . $limit;
	}
	
	$result = db_query($query);
	
	$birthdays = array();
	
	while ($user = db_fetch_object($result)) {
    $month = _get_shortmonth($user->month);
		$birthdays[] = array('name' => $user->name, 'uid' => $user->uid, 'day' => $user->day, 'month' => $month);
	}

	
	return $birthdays;
}

/**
  * Returns starsign of user (with symbol and link to Yahoo horoscopes)
  *
  * @param $dob_day The day.
  * @param $dob_month The month.
  * @return A picture link to Yahoo horoscopes
  */

function _get_starsign($dob_day, $dob_month) {

	switch($dob_month) {

		case 1: if ($dob_day < 20) {$starsign = 'capricorn';} else {$starsign = 'aquarius';} break;
		case 2: if ($dob_day < 20) {$starsign = 'aquarius';} else {$starsign = 'pisces';} break;
		case 3: if ($dob_day < 21) {$starsign = 'pisces';} else {$starsign = 'aries';} break;
		case 4: if ($dob_day < 20) {$starsign = 'aries';} else {$starsign = 'taurus';} break;
		case 5: if ($dob_day < 21) {$starsign = 'taurus';} else {$starsign = 'gemini';} break;
		case 6: if ($dob_day < 22) {$starsign = 'gemini';} else {$starsign = 'cancer';} break;
		case 7: if ($dob_day < 23) {$starsign = 'cancer';} else {$starsign = 'leo';} break;
		case 8: if ($dob_day < 23) {$starsign = 'leo';} else {$starsign = 'virgo';} break;
		case 9: if ($dob_day < 23) {$starsign = 'virgo';} else {$starsign = 'libra';} break;
		case 10: if ($dob_day < 23) {$starsign = 'libra';} else {$starsign = 'scorpio';} break;
		case 11: if ($dob_day < 22) {$starsign = 'scorpio';} else {$starsign = 'sagittarius';} break;
		case 12: if ($dob_day < 22) {$starsign = 'sagittarius';} else {$starsign = 'capricorn';} break;
	}

  if(!$starsign)
    return '';

	$link = '<a href="http://astrology.yahoo.com/astrology/general/dailyoverview/' . $starsign . '" target="_blank" title="' . $starsign . '">';
	$link .= '<img src='.url(drupal_get_path('module', 'birthdays'). '/starsigns/' . $starsign . '.gif').' border=0>';
	$link .= '</a>';

	return $link;
}

/**
  * Returns short month name based on DOB month
  *
  * @param $dob_month The month.
  * @return String of short month name
  */

function _get_shortmonth($dob_month) {
	
	switch ($dob_month) {
				        	
		case 1: $month = 'Jan'; break;
		case 2: $month = 'Feb'; break;
		case 3: $month = 'Mar'; break;
		case 4: $month = 'Apr'; break;
		case 5: $month = 'May'; break;
		case 6: $month = 'Jun'; break;
		case 7: $month = 'Jul'; break;
		case 8: $month = 'Aug'; break;
		case 9: $month = 'Sep'; break;
		case 10: $month = 'Oct'; break;
		case 11: $month = 'Nov'; break;
		case 12: $month = 'Dec'; break;
	}

	return $month;
}


/**
  * Returns month name based on DOB month
  *
  * @param $dob_month The month.
  * @return String of short month name
  * S M Mahbub Murshed  
  */

function _get_month($dob_month) {
	
	switch ($dob_month) {
				        	
		case 1: $month = 'January'; break;
		case 2: $month = 'February'; break;
		case 3: $month = 'March'; break;
		case 4: $month = 'April'; break;
		case 5: $month = 'May'; break;
		case 6: $month = 'June'; break;
		case 7: $month = 'July'; break;
		case 8: $month = 'August'; break;
		case 9: $month = 'September'; break;
		case 10: $month = 'October'; break;
		case 11: $month = 'November'; break;
		case 12: $month = 'December'; break;
	}

	return $month;
}

/**
  * Calculates current age of user from DOB in years
  */

function _birthdays_calc_age($DOB) {

	$DOBtime = strtotime($DOB);
	$today = time();
	
	$age = floor((($today - $DOBtime) / 31557600));

	return $age;
}

/**
  * Sends e-mail to administrator as reminder and to users on birthday and e-mail users who's birthdays it is
  */

function _birthdays_message() {
	
	if (variable_get('birthday_remind', true)) {
		
		$users = db_query("SELECT uid FROM {dob} WHERE DAYOFYEAR(birthday) = (DAYOFYEAR(curdate()) + 7)");
		
		while ($user = db_fetch_object($users)) {
					
			$account = user_load(array('uid' => $user->uid));
			$message = "The following users birthdays are coming up in 7 days:";
		
			$message .= $account->name . ' ';
		}
		
		if (db_num_rows($users) != 0) {
			
			// Get site e-mail to send reminder to and from
				
			$from = variable_get('site_mail', ini_get('sendmail_from'));
			$subject = "Upcoming Birthdays";
				
			user_mail($from, $subject, $message, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
		}
	}
	
	if (variable_get('birthdays_send_user', true)) {
		
		$users = db_query("SELECT uid FROM {dob} WHERE DAYOFYEAR(birthday) = DAYOFYEAR(curdate())");
				
		while ($user = db_fetch_object($users)) {
			
			$account = user_load(array('uid' => $user->uid));
			
			list($firstname, $lastname) = split(" ", $account->profile_fullname);

			$message  = '<p>'.t('Hey %user!', array('%user'=>$firstname)). '</p>';
			$message .= '<p align="center"><h1><font color="red"><b>'.t('Happy Birthday!!').'</b></font></h1></p>';
			$message .= '<p>'.t('Hope you age as gracefully as The Hoff and you have a great day!!').'</p><p>'.t('Take care').',</p><p>'.t('Sachalayatan').'</p>';

			if (function_exists('postcard_send')) {
		
				// If postcard module installed, send postcard
				
				$postcard = array('field_sndr' => t('Sachalayatan'),
						  'field_from' => 'birthdays@sachalayatan.com',
						  'field_nid'  => 49,
						  'field_rcpt' => $firstname,
						  'field_to'   => $account->mail,
						  'field_body' => $message);
			
				$postid = postcard_send($postcard);
				
				watchdog('Birthdays', $firstname . ' sent birthday postcard', WATCHDOG_NOTICE, l('postcard', 'postcard/45/'. $postid));
				
			} else {
			
				// Send e-mail
				
				watchdog('Birthdays', $firstname . ' sent birthday e-mail', WATCHDOG_NOTICE, '&#160;');
			}			
		}
	}
}

?>