birthdays.module

Tracking 6.x-1.x branch
  1. drupal
    1. 6 contributions/birthdays/birthdays.module

The Birthdays module allows users to add their birthday to their profile. It lists birthdays on a seperate page and in different blocks. Users can receive an e-mail on their birthday automatically, and the administrator can receive daily reminders of who are having their birthday. Requires Profile Module.

Globals

NameDescription
$_birthdays_fieldGlobal variable which contains the field that was selected as Birthdays field.

Constants

NameDescription
BIRTHDAYS_ADMIN_MAIL_DAILYAdmin e-mails should be sent dayly.
BIRTHDAYS_ADMIN_MAIL_DISABLEDAdmin e-mails disabled. Default.
BIRTHDAYS_ADMIN_MAIL_MONTHLYAdmin e-mails should be sent monthly, on the first day of the month.
BIRTHDAYS_ADMIN_MAIL_WEEKLYAdmin e-mails should be sent weekly, on the first day of the week defined by 'admin/settings/date-time'.
BIRTHDAYS_HIDE_YEAR_NODo not hide the year of birth and age of users. This goes for all pages generated by the Birthdays module. Default.
BIRTHDAYS_HIDE_YEAR_USERHiding or showing the year of birth and age is up to the user. This goes for all pages generated by the Birthdays module.
BIRTHDAYS_HIDE_YEAR_USER_NOUser does not want the birth year and age to be hidden. Used when hiding the year is an user option.
BIRTHDAYS_HIDE_YEAR_USER_YESUser wants birth year and age to be hidden. Used when hiding the year is an user option.
BIRTHDAYS_HIDE_YEAR_YESHide the year of birth and age of users. This goes for all pages generated by the Birthdays module.
BIRTHDAYS_PAGE_FILTER_SORT_DATEDo not show users without a birthday on the Birthdays listing and sort by birthday. Default.
BIRTHDAYS_PAGE_FILTER_SORT_USERDo not show users without a birthday on the Birthdays listing and sort by username.
BIRTHDAYS_PAGE_NOFILTER_SORT_USERShow all users on the Birthdays listing and sort by username.
BIRTHDAYS_STARSIGN_LINKShow starsigns, with link to Yahoo.
BIRTHDAYS_STARSIGN_NOLINKShow starsigns, image only.
BIRTHDAYS_STARSIGN_OFFDo not show starsigns. Default.
BIRTHDAYS_USER_MAIL_NODo not send an e-mail to the user on their birthday. Default.
BIRTHDAYS_USER_MAIL_USERSending an e-mail to the user depends on that user's preference.
BIRTHDAYS_USER_MAIL_USER_NOUser doesn't want to be e-mailed on their birthday.
BIRTHDAYS_USER_MAIL_USER_YESUser wants to be e-mailed on their birthday.
BIRTHDAYS_USER_MAIL_YESSend an e-mail to the user on their birthday.

Functions & methods

NameDescription
birthdays_blockImplementation of hook_block().
birthdays_cronImplementation of hook_cron().
birthdays_date_validateValidate the birthday field.
birthdays_form_alterImplementation of hook_form_alter().
birthdays_form_userAdds user options to the profile form which are saved in {users}.data and are loaded during a user_load().
birthdays_get_birthdaysGet the next X birthdays
birthdays_get_birthdays_by_daysGet all birthdays of the upcomming X days
birthdays_get_starsign_imageReturn the picture of a starsign, given the name. Links to Yahoo! when option is selected.
birthdays_get_todays_birthdaysHelper function for displaying only todays birthdays
birthdays_helpImplementation of hook_help().
birthdays_initImplementation of hook_init().
birthdays_load_userInject information on a user load.
birthdays_menuImplementation of hook_menu().
birthdays_permImplementation of hook_perm().
birthdays_profile_alterAlter the way the birthday is shown. This is fired after every module has filled the profile.
birthdays_save_userInject information and save birthday when editing or adding a user.
birthdays_themeImplementation of hook_theme().
birthdays_userImplementation of hook_user().
expand_birthdays_dateProcess the birthday field (based on a regular date element) to limit it to past birthdays and make it the entire element optional by adding empty options for days, months and years.
template_preprocess_birthdays_blockPreprocess variables to format the birthdays block.
_birthdays_calculate_ageCalculate age
_birthdays_get_ageGet age from a given date of birth
_birthdays_get_date_fieldsRetrieve all fields of type 'date' from the profile.module's tables
_birthdays_get_fieldRetrieve profile field object
_birthdays_get_starsignGet starsign based on date of birth
_birthdays_mail_textCheck which e-mail strings should be retreived, and fill in the default placeholders. Uses the same method as _user_mail_text().
_birthdays_show_ageReturn age if user has agreed to show it
_birthdays_show_dateFormat date array
_birthdays_show_date_2Format date, optionally hide year

File

View source
  1. <?php
  2. /**
  3. * @file
  4. * The Birthdays module allows users to add their birthday to their
  5. * profile. It lists birthdays on a seperate page and in different
  6. * blocks. Users can receive an e-mail on their birthday automatically,
  7. * and the administrator can receive daily reminders of who are having
  8. * their birthday. Requires Profile Module.
  9. */
  10. /**
  11. * Global variable which contains the field that was selected as Birthdays
  12. * field.
  13. */
  14. global $_birthdays_field;
  15. /**
  16. * Admin e-mails disabled. Default.
  17. */
  18. define('BIRTHDAYS_ADMIN_MAIL_DISABLED', '0');
  19. /**
  20. * Admin e-mails should be sent dayly.
  21. */
  22. define('BIRTHDAYS_ADMIN_MAIL_DAILY', '1');
  23. /**
  24. * Admin e-mails should be sent weekly, on the first day of the week defined
  25. * by 'admin/settings/date-time'.
  26. */
  27. define('BIRTHDAYS_ADMIN_MAIL_WEEKLY', '2');
  28. /**
  29. * Admin e-mails should be sent monthly, on the first day of the month.
  30. */
  31. define('BIRTHDAYS_ADMIN_MAIL_MONTHLY', '3');
  32. /**
  33. * Do not show starsigns. Default.
  34. */
  35. define('BIRTHDAYS_STARSIGN_OFF', '0');
  36. /**
  37. * Show starsigns, with link to Yahoo.
  38. */
  39. define('BIRTHDAYS_STARSIGN_LINK', '1');
  40. /**
  41. * Show starsigns, image only.
  42. */
  43. define('BIRTHDAYS_STARSIGN_NOLINK', '2');
  44. /**
  45. * Do not hide the year of birth and age of users. This goes for all pages
  46. * generated by the Birthdays module. Default.
  47. */
  48. define('BIRTHDAYS_HIDE_YEAR_NO', '0');
  49. /**
  50. * Hide the year of birth and age of users. This goes for all pages
  51. * generated by the Birthdays module.
  52. */
  53. define('BIRTHDAYS_HIDE_YEAR_YES', '1');
  54. /**
  55. * Hiding or showing the year of birth and age is up to the user. This goes
  56. * for all pages generated by the Birthdays module.
  57. */
  58. define('BIRTHDAYS_HIDE_YEAR_USER', '2');
  59. /**
  60. * User does not want the birth year and age to be hidden. Used when
  61. * hiding the year is an user option.
  62. */
  63. define('BIRTHDAYS_HIDE_YEAR_USER_NO', '0');
  64. /**
  65. * User wants birth year and age to be hidden. Used when
  66. * hiding the year is an user option.
  67. */
  68. define('BIRTHDAYS_HIDE_YEAR_USER_YES', '1');
  69. /**
  70. * Do not show users without a birthday on the Birthdays listing
  71. * and sort by birthday. Default.
  72. */
  73. define('BIRTHDAYS_PAGE_FILTER_SORT_DATE', '0');
  74. /**
  75. * Do not show users without a birthday on the Birthdays listing
  76. * and sort by username.
  77. */
  78. define('BIRTHDAYS_PAGE_FILTER_SORT_USER', '1');
  79. /**
  80. * Show all users on the Birthdays listing and sort by username.
  81. */
  82. define('BIRTHDAYS_PAGE_NOFILTER_SORT_USER', '2');
  83. /**
  84. * Do not send an e-mail to the user on their birthday. Default.
  85. */
  86. define('BIRTHDAYS_USER_MAIL_NO', '0');
  87. /**
  88. * Send an e-mail to the user on their birthday.
  89. */
  90. define('BIRTHDAYS_USER_MAIL_YES', '1');
  91. /**
  92. * Sending an e-mail to the user depends on that user's preference.
  93. */
  94. define('BIRTHDAYS_USER_MAIL_USER', '2');
  95. /**
  96. * User doesn't want to be e-mailed on their birthday.
  97. */
  98. define('BIRTHDAYS_USER_MAIL_USER_NO', '1');
  99. /**
  100. * User wants to be e-mailed on their birthday.
  101. */
  102. define('BIRTHDAYS_USER_MAIL_USER_YES', '0');
  103. /**
  104. * Implementation of hook_init().
  105. */
  106. function birthdays_init() {
  107. global $_birthdays_field;
  108. $_birthdays_field = _birthdays_get_field(variable_get('birthdays_field_id', NULL));
  109. }
  110. /**
  111. * Implementation of hook_help().
  112. */
  113. function birthdays_help($path, $arg) {
  114. global $_birthdays_field;
  115. switch ($path) {
  116. case 'admin/help#birthdays':
  117. $output = '<p>' . t("The Birthdays module allows a user to put in their birthday and display it in their profile, on a separate Birthdays page and in a block. It also has the option to send out e-mails on users's birthdays, and to notify the administrator periodically about upcoming birthdays via e-mail.") . '</p>';
  118. $output .= '<p>' . t('Some basic information about this module can be found below. For more information, support questions, feature requests and bug reports please visit the <a href="@project_url">Birthdays project page</a> and the <a href="@documentation_url">online documentation</a>.', array('@project_url' => 'http://drupal.org/project/birthdays', '@documentation_url' => 'http://drupal.org/node/315658')) . '</p>';
  119. $output .= '<h2>' . t('Configuring the module') . '</h2>';
  120. $output .= '<p>' . t('Configuring the module is done on a number of pages.') . '</p>';
  121. $output .= '<h3>' . t('Birthdays administration pages') . '</h3>';
  122. $output .= '<p>' . t('The <a href="@birthdays_admin">Birthdays administration pages</a> are where the actual features of the birthdays module are set. Some of the options are described below.', array('@birthdays_admin' => url('admin/settings/birthdays'))) . '</p>';
  123. $output .= '<ul><li><strong>' . t('Profile field') . '</strong>: ' . t('here you set which "date" field of the Profile module you want the Birthdays module to use.') . '</li>';
  124. $output .= '<li><strong>' . t('Show star signs') . '</strong>: ' . t('select whether you want to display the star sign icons on the profile and on the Birthdays page, and, if so, whether it should link to Yahoo Horoscopes.') . '</li>';
  125. $output .= '<li><strong>' . t('Hide year and age') . '</strong>: ' . t("some sites might want to protect the user's privacy by hiding their age and year of birth. The options are 'No', 'Yes' and 'User optional, defaults to No', where the latter gives the user the option to select whether he or she wants this information to be hidden. If enabled it still requires them to put the full date of birth in, but only the day and month will be displayed.") . '</li>';
  126. $output .= '<li><strong>' . t('Set Birthdays page settings') . '</strong>: ' . t('this influences how the listing of the Birthdays page is shown. Sorted by user name of date of birth (year not included) and users without a birthday shown or not.') . '</li>';
  127. $output .= '<li><strong>' . t('Show filter options') . '</strong>: ' . t("determine whether the buttons to filter by specific month and/or year should be displayed. When 'Hide year and age' is set to 'Yes', filtering by year is not possible.") . '</li>';
  128. $output .= '<li><strong>' . t('Send upcoming birthdays to admin') . '</strong>: ' . t("this one has 4 values 'Disabled', 'Dayly', 'Weekly, on the first day of the week' and 'Monthly'. This will send an e-mail to your site e-mail address at the given intervals, listing users that will have their birthday in that period. The first day of the week is controlled by the <a href=\"@date_settings\">date and time settings</a>.", array('@date_settings' => url('admin/settings/date-time'))) . '</li>';
  129. $output .= '<li><strong>' . t('Send user e-mail on day of birth') . '</strong>: ' . t("set whether users should receive an e-mail when they are having the birthday. Either 'No', 'Yes' or 'User optional, 'Yes' by default', where the latter leaves the decision up to the user.") . '</li></ul>';
  130. $output .= '<h3>' . t('Permissions') . '</h3>';
  131. $output .= '<p>' . t('To allow users to view birthdays of other people, the "access birthdays" <a href="@permissions_page">permissions</a> needs to be set for the appropriate role. This allows them to access the <a href="@birthdays_page">Birthdays page</a>, see activated blocks with birthdays and view the birthdays of users in the profiles.', array('@birthdays_page' => url('birthdays'), '@permissions_page' => url('admin/user/permissions', array('fragment' => 'module-birthdays')))) . '</p>';
  132. $output .= '<h3>' . t('Profile field settings') . '</h3>';
  133. $output .= '<p>' . t("Several things can be adjusted to the assigned profile field. To do so please visit the !profile_admin, and edit the field in question or add one if you haven't done so already. The following settings require extra attention.", array('!profile_admin' => l('Profile settings', 'admin/user/profile'))) . '</p>';
  134. $output .= '<ul><li><strong>' . t('The user must enter a value') . '</strong>: ' . t('force the user to fill in their date of birth. A once set birthday can not be deleted.') . '</li>';
  135. $output .= '<li><strong>' . t('Visible in user registration form') . '</strong>: ' . t('give new users the option to add their date of birth when registering to your website. If combined with the option above, they can not register without putting their date of birth.') . '</li>';
  136. $output .= '<li><strong>' . t('Visibility') . '</strong>: ' . t("this will influence the visibility of the field as described there, but the behavior might become erratic if not set to 'Public field, content shown on profile page but not used on member list pages'. So it is recommended to leave this as is.") . '</li></ul>';
  137. $output .= '<p>' . t('The other options on this page behave as described on the settings page.') . '</p>';
  138. $output .= '<h3>' . t('Date format') . '</h3>';
  139. $output .= '<p>' . t('The way the birthdays are formatted (e.g. <em>11 may 1934</em> or <em>5/11/1934</em>) is controlled by the <a href="@date_settings_page">date and time settings</a>. The Birthdays module uses the short date format as basis for displaying days and months in the blocks and the medium date format is used in the profile and on the Birthdays page.', array('!date_settings_page' => url('admin/settings/date-time'))) . '</p>';
  140. $output .= '<h2>' . t('Synchronizing') . '</h2>';
  141. $output .= '<p>' . t('The birthdays are saved to two different database tables. This is because the profile module saves the dates in a format which limits the ability to perform calculations on the dates. These two tables need to be in sync with each other.') . '</p>';
  142. $output .= '<p>' . t('Normally this is the case, but sometimes not. For example when you already collected birthdays with the Profile module, but later decided to switch to the birthdays module. Or when you accidentally (on intentionally) completely uninstalled the profile module, but left birthdays module merely disabled. To perform the synchronization you can use the <a href="@sync_pages">synchronization form</a>.', array('@sync_page' => url('admin/settings/birthdays/sync'))) . '</p>';
  143. $output .= '<p>' . t('In the first case you need to copy the Profile data to the (most likely empty) Birthdays table, which is done with the top button. In the latter you need the copy the birthdays in the Birthdays table back to the Profile module with the bottom button.') . '</p>';
  144. $output .= '<p>' . t('Please note that with a large amount of users this might take some time.') . '</p>';
  145. return $output;
  146. case 'admin/settings/birthdays':
  147. return t('Use this page to alter the settings of the Birthdays module.');
  148. }
  149. }
  150. /**
  151. * Implementation of hook_menu().
  152. */
  153. function birthdays_menu() {
  154. $items['admin/settings/birthdays'] = array(
  155. 'title' => 'Birthdays',
  156. 'description' => 'Set user birthday mail and toggle user mail, upcoming birthdays mail and more.',
  157. 'page callback' => 'drupal_get_form',
  158. 'page arguments' => array('birthdays_admin_settings'),
  159. 'access arguments' => array('administer site configuration'),
  160. 'file' => 'birthdays.admin.inc',
  161. );
  162. $items['admin/settings/birthdays/settings'] = array(
  163. 'title' => 'Settings',
  164. 'type' => MENU_DEFAULT_LOCAL_TASK,
  165. );
  166. $items['admin/settings/birthdays/sync'] = array(
  167. 'title' => 'Synchronize',
  168. 'description' => 'Synchronize birthdays information of Profile module and Birthdays module. Used either when updating to a newer version of Birthdays or when integrating with an existing Profile Field.',
  169. 'page callback' => 'drupal_get_form',
  170. 'page arguments' => array('birthdays_sync_form'),
  171. 'access arguments' => array('administer site configuration'),
  172. 'type' => MENU_LOCAL_TASK,
  173. 'file' => 'birthdays.sync.inc',
  174. );
  175. $items['birthdays'] = array(
  176. 'title' => 'Birthdays',
  177. 'description' => 'List the birthdays of all users.',
  178. 'page callback' => 'birthdays_view_page',
  179. 'access arguments' => array('access birthdays'),
  180. 'type' => MENU_SUGGESTED_ITEM,
  181. 'file' => 'birthdays.page.inc',
  182. );
  183. return $items;
  184. }
  185. /**
  186. * Implementation of hook_theme().
  187. */
  188. function birthdays_theme() {
  189. return array(
  190. 'birthdays_block' => array(
  191. 'arguments' => array('uids' => array(), 'amount' => 0, 'block_type' => NULL),
  192. 'template' => 'birthdays-block',
  193. ),
  194. 'birthdays_page' => array(
  195. 'arguments' => array('accounts' => array(), 'filter_month' => NULL, 'filter_year' => NULL),
  196. 'file' => 'birthdays.page.inc',
  197. 'template' => 'birthdays-page',
  198. ),
  199. );
  200. }
  201. /**
  202. * Implementation of hook_perm().
  203. */
  204. function birthdays_perm() {
  205. return array('access birthdays');
  206. }
  207. /**
  208. * Implementation of hook_cron().
  209. */
  210. function birthdays_cron() {
  211. global $_birthdays_field;
  212. // Either user mail or admin mail is activated, and the birthdays profile field has been set.
  213. if (isset($_birthdays_field) && (variable_get('birthdays_send_user', BIRTHDAYS_USER_MAIL_NO) != BIRTHDAYS_USER_MAIL_NO || variable_get('birthdays_remind', BIRTHDAYS_ADMIN_MAIL_DISABLED) != BIRTHDAYS_ADMIN_MAIL_DISABLED)) {
  214. // Perform the check just once a day
  215. $time = time();
  216. if (variable_get('birthdays_last_cron', 0) <= ($time - 24*3600)) {
  217. // The message functions are now necessary, lets include them.
  218. module_load_include('inc', 'birthdays', 'birthdays.mail');
  219. // Reset time limit, round to nearest 100 seconds.
  220. variable_set('birthdays_last_cron', floor($time/100)*100);
  221. $remind_frequency = variable_get('birthdays_remind', BIRTHDAYS_ADMIN_MAIL_DISABLED);
  222. // Send user e-mails.
  223. _birthdays_send_user_message();
  224. // Send admin message if frequency is daily.
  225. if ($remind_frequency == BIRTHDAYS_ADMIN_MAIL_DAILY) {
  226. _birthdays_send_admin_message(1);
  227. }// Send admin message if frequency is weekly and today is the first day of the week.
  228. elseif ($remind_frequency == BIRTHDAYS_ADMIN_MAIL_WEEKLY && date('w', $time) == variable_get('date_first_day', 0)) {
  229. _birthdays_send_admin_message(7);
  230. }// Send admin message if frequency is monthly and today is the first day of the month.
  231. elseif ($remind_frequency == BIRTHDAYS_ADMIN_MAIL_MONTHLY && date('j', $time) == 1) {
  232. _birthdays_send_admin_message(date('t', $time));
  233. }
  234. }
  235. }
  236. }
  237. /**
  238. * Implementation of hook_block().
  239. */
  240. function birthdays_block($op = 'list', $delta = 'by_days', $edit = array()) {
  241. global $_birthdays_field;
  242. if (isset($_birthdays_field)) {
  243. switch ($op) {
  244. // List the blocks on the blocks settings page
  245. case 'list':
  246. $blocks['by_days']['info'] = t('Birthdays Block: Next N days');
  247. $blocks['by_birthdays']['info'] = t('Birthdays Block: N upcoming birthdays');
  248. return $blocks;
  249. // Configure the blocks
  250. case 'configure':
  251. $form = array();
  252. switch ($delta) {
  253. case 'by_days':
  254. $form["birthdays_block_settings"] = array(
  255. '#type' => 'textfield',
  256. '#title' => t("Number of days to show"),
  257. '#default_value' => variable_get("birthdays_block_number_by_days", 7),
  258. '#size' => 2,
  259. '#maxlength' => 2,
  260. '#description' => t("Number of days looking forward for upcoming birthdays. Use 1 for today's birthdays only. Note: it might show more or less birthday items than the specified number of days, because not all days have birthdays, and some days have multiple birthdays."),
  261. '#required' => TRUE,
  262. );
  263. break;
  264. case 'by_birthdays':
  265. $form["birthdays_block_settings"] = array(
  266. '#type' => 'textfield',
  267. '#title' => t("Number of birthdays to show"),
  268. '#default_value' => variable_get("birthdays_block_number_by_birthdays", 6),
  269. '#size' => 2,
  270. '#maxlength' => 2,
  271. '#description' => t("Number of upcoming birthdays to list in the block. It will show exactly the specified number of birthdays, even if more people have their birthday on the same day. In that case, there will be people who will never be shown."),
  272. '#required' => TRUE,
  273. );
  274. break;
  275. }
  276. $form['birthdays_block_hide'] = array(
  277. '#type' => 'radios',
  278. '#title' => t('Hide block when no birthdays'),
  279. '#default_value' => variable_get("birthdays_block_hide_empty", 0),
  280. '#options' => array(t('No'), t('Yes')),
  281. '#description' => t("Should the block be hidden when there are no upcoming birthdays, or should it show a message."),
  282. );
  283. return $form;
  284. // Save the block's configuration
  285. case 'save':
  286. variable_set('birthdays_block_number_'. $delta, $edit['birthdays_block_settings']);
  287. variable_set('birthdays_block_hide_empty', $edit['birthdays_block_hide']);
  288. return;
  289. // View a block
  290. case 'view':
  291. $block = array();
  292. // Nothing to show when birthday_field_name is still empty
  293. // Don't show anything when the current user doesn't have the rights.
  294. if (user_access('access birthdays')) {
  295. switch ($delta) {
  296. case 'by_days':
  297. // Get desired amount of birthdays
  298. $amount = variable_get("birthdays_block_number_by_days", 7);
  299. $uids = birthdays_get_birthdays_by_days($amount);
  300. if (count($uids) > 0 || variable_get('birthdays_block_hide_empty', 0) == 0) {
  301. // Prepare block
  302. $block['subject'] = t('Upcoming Birthdays');
  303. $block['content'] = theme('birthdays_block', $uids, $amount, $delta);
  304. }
  305. break;
  306. case 'by_birthdays':
  307. // Get desired amount of birthdays
  308. $amount = variable_get("birthdays_block_number_by_birthdays", 6);
  309. $uids = birthdays_get_birthdays($amount);
  310. if (count($uids) > 0 || variable_get('birthdays_block_hide_empty', 0) == 0) {
  311. // Prepare block
  312. $block['subject'] = t('Upcoming Birthdays');
  313. $block['content'] = theme('birthdays_block', $uids, $amount, $delta);
  314. }
  315. break;
  316. }
  317. return $block;
  318. }
  319. }
  320. }
  321. }
  322. /**
  323. * Preprocess variables to format the birthdays block.
  324. *
  325. * $variables contains the following data:
  326. * - $uids
  327. * - $amount
  328. * - $block_type
  329. */
  330. function template_preprocess_birthdays_block(&$variables) {
  331. global $_birthdays_field;
  332. //dsm($variables);
  333. $variables['no_birthdays'] = TRUE;
  334. $variables['show_starsigns'] = (bool) variable_get('birthdays_show_starsign',BIRTHDAYS_STARSIGN_OFF);
  335. if (!empty($variables['uids'])) {
  336. $row = 0;
  337. $variables['no_birthdays'] = FALSE;
  338. foreach ($variables['uids'] as $uid) {
  339. $account = user_load(array('uid' => $uid));
  340. $birthdays[$row]['account'] = $account;
  341. $birthdays[$row]['username'] = theme('username', $account);
  342. // +1 when the birthday isn't today, because it shows the age the person will be on his/her birthday
  343. $account->age = ($account->age + !($account->{$_birthdays_field->name}['day'] == format_date(time(), 'custom', 'j') && $account->{$_birthdays_field->name}['month'] == format_date(time(), 'custom', 'n')));
  344. $birthdays[$row]['age'] = _birthdays_show_age($account);
  345. $birthdays[$row]['show_age'] = isset($birthdays[$row]['age']);
  346. $birthdays[$row]['starsign'] = birthdays_get_starsign_image($account->birthdays_starsign, variable_get('birthdays_show_starsign',BIRTHDAYS_STARSIGN_OFF));
  347. $account->{$_birthdays_field->name}['year'] = NULL; // Don't show the year in blocks
  348. $birthdays[$row]['date'] = _birthdays_show_date($account->{$_birthdays_field->name}, $account);
  349. $row++;
  350. }
  351. $variables['birthdays'] = $birthdays;
  352. }
  353. $variables['more'] = '<div class="more-link">'. l(t('more'), 'birthdays', array('attributes' => array('title' => t('Show all birthdays.')))) .'</div>';
  354. }
  355. /**
  356. * Helper function for displaying only todays birthdays
  357. * @return An array containing all user objects that have their birthday today
  358. */
  359. function birthdays_get_todays_birthdays() {
  360. return birthdays_get_birthdays_by_days(1);
  361. }
  362. /**
  363. * Get all birthdays of the upcomming X days
  364. *
  365. * @var $amount
  366. * Integer stating the amount of days to look forward, including today.
  367. * @return array
  368. * An array containing user objects meeting the criteria
  369. */
  370. function birthdays_get_birthdays_by_days($amount) {
  371. $birthdays = array();
  372. // Current user, needed for timezone information
  373. global $user;
  374. // $amount should be larger or equal to 1
  375. if ($amount < 1) {
  376. $amount = 1;
  377. }
  378. // Get user time zone
  379. // needed to determine what day 'today' is in the timezone of the user/website.
  380. if (variable_get('configurable_timezones', 1) && $user->uid && drupal_strlen($user->timezone)) {
  381. $timezone = $user->timezone;
  382. }
  383. else { // else use timezone of Drupal installation
  384. $timezone = variable_get('date_default_timezone', 0);
  385. }
  386. // MySQL prior to 4.1.1 has no option to use UTC, while drupal uses UTC.
  387. // This is compensated by subtracting the machines timezone from the Drupal timezone.
  388. // I believe the assumption is that the HTTP-server has the same timezone as the MySQL server.
  389. $timezone -= date('Z');
  390. // Hack to look further than the end of the year, if needed.
  391. $current_year = date('Y');
  392. $next_year = $current_year + 1;
  393. /* Query:
  394. - All dates are compensated for the timezone. This makes sure that someone in Asia will see the birthdays
  395. of day 2 while someone in America still sees day 1.
  396. - Blocked users are not shown
  397. - Users that haven't logged in yet are also not shown (Drupal prohibits accessing their profile, thus showing
  398. a link to the profile is unwanted). This is a anti spammers method.
  399. - First part selects all birthdays that are in the next year when the interval exceeds the end of this year.
  400. - Second part selects all birthdays that are between the begin and end date and are in the current year
  401. */
  402. switch ($GLOBALS['db_type']) {
  403. case 'mysql':
  404. case 'mysqli':
  405. $result = db_query(
  406. "SELECT {dob}.uid FROM {dob}, {users} WHERE {users}.uid = {dob}.uid AND {users}.status <> 0 AND {users}.access <> 0
  407. AND (
  408. (
  409. DATE_FORMAT({dob}.birthday,'$next_year%%m%%d') - DATE_FORMAT(ADDDATE(ADDDATE(NOW(),INTERVAL %d SECOND),INTERVAL %d DAY),'%%Y%%m%%d') < 0
  410. )
  411. OR
  412. (
  413. DATE_FORMAT({dob}.birthday,'$current_year%%m%%d') - DATE_FORMAT(ADDDATE(NOW(),INTERVAL %d SECOND),'%%Y%%m%%d') >= 0
  414. AND
  415. DATE_FORMAT({dob}.birthday,'$current_year%%m%%d') - DATE_FORMAT(ADDDATE(ADDDATE(NOW(),INTERVAL %d SECOND),INTERVAL %d DAY),'%%Y%%m%%d') < 0
  416. ) )
  417. ORDER BY MONTH({dob}.birthday), DAYOFMONTH({dob}.birthday), YEAR({dob}.birthday), {users}.name", $timezone, $amount, $timezone, $timezone, $amount
  418. );
  419. break;
  420. case 'pgsql':
  421. $result = db_query(
  422. "SELECT {dob}.uid FROM {dob}, {users} WHERE {users}.uid = {dob}.uid AND {users}.status <> 0 AND {users}.access <> 0
  423. AND (
  424. (
  425. cast(to_char({dob}.birthday,'{$next_year}MMDD') as integer) - cast(to_char(current_timestamp + INTERVAL '%d seconds' + INTERVAL '%d days','YYYYMMDD') as integer) < 0
  426. )
  427. OR
  428. (
  429. cast(to_char({dob}.birthday,'{$current_year}MMDD') as integer) - cast(to_char(current_timestamp + INTERVAL '%d seconds','YYYYMMDD') as integer) >= 0
  430. AND
  431. cast(to_char({dob}.birthday,'{$current_year}MMDD') as integer) - cast(to_char(current_timestamp + INTERVAL '%d seconds' + INTERVAL '%d days','YYYYMMDD') as integer) < 0
  432. ) )
  433. ORDER BY date_part('month', {dob}.birthday), date_part('day', {dob}.birthday), date_part('year', {dob}.birthday), {users}.name", $timezone, $amount, $timezone, $timezone, $amount
  434. );
  435. break;
  436. }
  437. while ($account = db_fetch_object($result)) {
  438. $birthdays[] = $account->uid;
  439. }
  440. // Return array of uids that have their birthday
  441. return $birthdays;
  442. }
  443. /**
  444. * Get the next X birthdays
  445. *
  446. * @var $amount
  447. * Integer stating the amount of birthdays to retrieve.
  448. * @return array
  449. * An array containing user objects meeting the criteria
  450. */
  451. function birthdays_get_birthdays($amount) {
  452. $birthdays = array();
  453. // Current logged in user
  454. global $user;
  455. // Get user time zone
  456. // Needed to determine what day 'today' is in the timezone of the user/website.
  457. if (variable_get('configurable_timezones', 1) && $user->uid && drupal_strlen($user->timezone)) {
  458. $timezone = $user->timezone;
  459. }
  460. else {
  461. $timezone = variable_get('date_default_timezone', 0);
  462. }
  463. // $amount should be larger or equal to 1
  464. if ($amount < 1) {
  465. $amount = 1;
  466. }
  467. // MySQL prior to 4.1.1 has no option to use UTC, while drupal uses UTC.
  468. // This is compensated by subtracting the machines timezone from the Drupal timezone.
  469. // I believe the assumption is that the HTTP-server has the same timezone as the MySQL server.
  470. $timezone -= date('Z');
  471. /* Query:
  472. - Select all active users that have their birthday today or in the future (stops at 31-12)
  473. - return at most $amount users
  474. - Don't show blocked users
  475. - Users that haven't logged in yet are also not shown (Drupal prohibits accessing their profile, thus showing
  476. a link to the profile is unwanted). This is a anti spammers method.
  477. */
  478. switch ($GLOBALS['db_type']) {
  479. case 'mysql':
  480. case 'mysqli':
  481. $result = db_query_range(
  482. "SELECT {dob}.uid FROM {dob}, {users} WHERE {users}.uid = {dob}.uid AND {users}.status <> 0 AND {users}.access <> 0
  483. AND DATE_FORMAT({dob}.birthday,'%%c%%d') - DATE_FORMAT(ADDDATE(NOW(),INTERVAL %d SECOND),'%%c%%d') >= 0
  484. ORDER BY MONTH({dob}.birthday), DAYOFMONTH({dob}.birthday), YEAR({dob}.birthday), {users}.name", $timezone, 0, $amount
  485. );
  486. break;
  487. case 'pgsql':
  488. $result = db_query_range(
  489. "SELECT {dob}.uid FROM {dob}, {users} WHERE {users}.uid = {dob}.uid AND {users}.status <> 0 AND {users}.access <> 0
  490. AND cast(to_char({dob}.birthday,'FMMMDD') as integer) - cast(to_char(current_timestamp + INTERVAL '%d seconds','FMMMDD') as integer) >= 0
  491. ORDER BY date_part('month', {dob}.birthday), date_part('day', {dob}.birthday), date_part('year', {dob}.birthday), {users}.name", $timezone, 0, $amount
  492. );
  493. break;
  494. }
  495. $count_rows = 0;
  496. while ($account = db_fetch_object($result)) {
  497. $birthdays[] = $account->uid;
  498. $count_rows++;
  499. }
  500. // If less than $amount results returned, look for more after 31-12
  501. // return at most the difference between the number already found and
  502. if ($count_rows < $amount) {
  503. switch ($GLOBALS['db_type']) {
  504. case 'mysql':
  505. case 'mysqli':
  506. $result = db_query_range(
  507. "SELECT {dob}.uid FROM {dob}, {users} WHERE {users}.uid = {dob}.uid AND {users}.status <> 0 AND {users}.access <> 0
  508. AND DATE_FORMAT({dob}.birthday,'%%c%%d') - DATE_FORMAT(ADDDATE(NOW(),INTERVAL %d SECOND),'%%c%%d') < 0
  509. ORDER BY MONTH({dob}.birthday), DAYOFMONTH({dob}.birthday), YEAR({dob}.birthday), {users}.name", $timezone, 0, $amount - $count_rows
  510. );
  511. break;
  512. case 'pgsql':
  513. $result = db_query_range(
  514. "SELECT {dob}.uid FROM {dob}, {users} WHERE {users}.uid = {dob}.uid AND {users}.status <> 0 AND {users}.access <> 0
  515. AND cast(to_char({dob}.birthday,'FMMMDD') as integer) - cast(to_char(current_timestamp + INTERVAL '%d seconds','FMMMDD') as integer) < 0
  516. ORDER BY date_part('month', {dob}.birthday), date_part('day', {dob}.birthday), date_part('year', {dob}.birthday), {users}.name", $timezone, 0, $amount - $count_rows
  517. );
  518. break;
  519. }
  520. while ($account = db_fetch_object($result)) {
  521. $birthdays[] = $account->uid;
  522. }
  523. }
  524. // Return array of uids that have their birthday
  525. return $birthdays;
  526. }
  527. /**
  528. * Implementation of hook_user().
  529. */
  530. function birthdays_user($op, &$edit, &$account, $category = NULL) {
  531. global $_birthdays_field;
  532. // Do nothing with user when _birthdays_field is not yet set
  533. if (!isset($_birthdays_field)) {
  534. return;
  535. }
  536. switch ($op) {
  537. case 'load':
  538. return birthdays_load_user($account);
  539. case 'update':
  540. case 'insert':
  541. return birthdays_save_user($edit, $account, $category);
  542. case 'form':
  543. return birthdays_form_user($edit, $account, $category);
  544. case 'register':
  545. return birthdays_form_user($edit, $account, $category, TRUE);
  546. case 'delete':
  547. // Delete from {dob} table, other information is handled by profile.module and user.module
  548. db_query('DELETE FROM {dob} WHERE uid = %d', $account->uid);
  549. break;
  550. }
  551. }
  552. /**
  553. * Inject information on a user load.
  554. *
  555. * @param object $account
  556. * User object passed by reference.
  557. */
  558. function birthdays_load_user(&$account) {
  559. global $_birthdays_field;
  560. // Pre-load birthday-information into $account
  561. profile_load_profile($account);
  562. // If it was set by the user
  563. if (!empty($account->{$_birthdays_field->name})) {
  564. // Set the user's age
  565. $account->age = _birthdays_get_age($account->{$_birthdays_field->name});
  566. }
  567. }
  568. /**
  569. * Inject information and save birthday when editing or adding a user.
  570. */
  571. function birthdays_save_user(&$edit, &$account, $category) {
  572. global $_birthdays_field;
  573. // Only continue when the field is present in the form results
  574. if (!empty($_birthdays_field->name) && array_key_exists($_birthdays_field->name, $edit)) {
  575. // Extract the date information
  576. if (is_array($edit[$_birthdays_field->name])) {
  577. extract($edit[$_birthdays_field->name]);
  578. }
  579. // Delete the old
  580. db_query("DELETE FROM {dob} where uid = %d", $account->uid);
  581. if ($day && $year && $month) {
  582. // Set the starsign for the user.module to save in the {users}.data field
  583. $edit['birthdays_starsign'] = _birthdays_get_starsign($day, $month);
  584. // Insert the new
  585. db_query("INSERT INTO {dob} (uid, birthday) VALUES (%d, '%d-%d-%d');", $account->uid, $year, $month, $day);
  586. }
  587. else {
  588. $edit['birthdays_starsign'] = '';
  589. unset($edit[$_birthdays_field->name]);
  590. }
  591. }
  592. }
  593. /**
  594. * Alter the way the birthday is shown. This is fired after every module has filled the profile.
  595. */
  596. function birthdays_profile_alter(&$account) {
  597. global $_birthdays_field;
  598. // If the _birthdays_field hasn't been set yet, do not continue
  599. if (!isset($_birthdays_field)) {
  600. return;
  601. }
  602. // If the field existed, and is amongst the profile fields to be shown, it is save to continue
  603. if (isset( $_birthdays_field ) && array_key_exists($_birthdays_field->category, $account->content) && array_key_exists($_birthdays_field->name, $account->content[$_birthdays_field->category])) {
  604. // Do you have access to see birthdays?
  605. if (user_access('access birthdays')) {
  606. // Show starsign (will be hidden when needed)
  607. $starsign = '<span class="birthdays-starsign">'.
  608. birthdays_get_starsign_image($account->birthdays_starsign, variable_get('birthdays_show_starsign', BIRTHDAYS_STARSIGN_OFF)) .
  609. '</span>&nbsp;&nbsp;&nbsp;';
  610. // Show age (when allowed by user and administrator)
  611. if (variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_NO || (variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_USER && $account->birthdays_user_hide_year != BIRTHDAYS_HIDE_YEAR_USER_YES)) {
  612. $age = '&nbsp;&nbsp;&nbsp;<span class="birthdays-age">('. $account->age .')</span>';
  613. }
  614. // Alter the profile field setup by profile.module. Show medium format in stead of short format
  615. $account->content[$_birthdays_field->category][$_birthdays_field->name]['#value'] = $starsign . _birthdays_show_date($account->{$_birthdays_field->name}, $account, 'medium') . $age ;
  616. }
  617. else {
  618. // No access? Remove from profile to show
  619. unset($account->content[$_birthdays_field->category][$_birthdays_field->name]);
  620. }
  621. }
  622. }
  623. /**
  624. * Adds user options to the profile form which are saved in {users}.data and
  625. * are loaded during a user_load().
  626. * @return fields for the form
  627. */
  628. function birthdays_form_user($edit, $account, $category, $register = FALSE) {
  629. global $_birthdays_field;
  630. drupal_add_css(drupal_get_path('module','birthdays') . '/birthdays.css', 'module');
  631. // If the called category is the category of the form field
  632. if ($category == $_birthdays_field->category || ($_birthdays_field->register && $register) || (module_exists('onepageprofile') && $category == 'account')) {
  633. // If the hiding of the year is a user option: show the option
  634. if (variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_USER) {
  635. $form[$_birthdays_field->category][$_birthdays_field->name]['birthdays_user_hide_year'] = array(
  636. '#type' => 'checkbox',
  637. '#title' => t("Hide age and birth year"),
  638. '#default_value' => (int) $account->birthdays_user_hide_year,
  639. '#description' => t("Do not show your age and your year of birth."),
  640. '#return_value' => BIRTHDAYS_HIDE_YEAR_USER_YES,
  641. '#weight' => 1,
  642. '#prefix' => '<div class="birthdays-container">',
  643. '#suffix' => '</div>',
  644. );
  645. }
  646. // If the birthday user mail is optionally, show the option
  647. if (variable_get('birthdays_send_user', BIRTHDAYS_USER_MAIL_NO) == BIRTHDAYS_USER_MAIL_USER) {
  648. $form[$_birthdays_field->category][$_birthdays_field->name]['birthdays_user_send_mail'] = array(
  649. '#type' => 'checkbox',
  650. '#title' => t("Do not send birthday mail"),
  651. '#default_value' => (int) $account->birthdays_user_send_mail,
  652. '#description' => t("Do not send me an e-mail or e-card when it's my birthday."),
  653. '#return_value' => BIRTHDAYS_USER_MAIL_USER_NO,
  654. '#weight' => 2,
  655. '#prefix' => '<div class="birthdays-container">',
  656. '#suffix' => '</div>',
  657. );
  658. }
  659. }
  660. return $form;
  661. }
  662. /**
  663. * Implementation of hook_form_alter().
  664. */
  665. function birthdays_form_alter(&$form, &$form_state, $form_id) {
  666. global $_birthdays_field;
  667. if (($form_id == 'user_profile_form' && isset($form[$_birthdays_field->category])) || ($form_id == 'user_register' && $_birthdays_field->register)) {
  668. $form[$_birthdays_field->category][$_birthdays_field->name]['#process'] = array('expand_birthdays_date');
  669. $form[$_birthdays_field->category][$_birthdays_field->name]['#element_validate'] = array('birthdays_date_validate');
  670. }
  671. }
  672. /**
  673. * Process the birthday field (based on a regular date element) to
  674. * limit it to past birthdays and make it the entire element optional
  675. * by adding empty options for days, months and years.
  676. */
  677. function expand_birthdays_date($element) {
  678. if (empty($element['#value'])) {
  679. $element['#value'] = array('day' => '', 'month' => '', 'year' => '');
  680. }
  681. $element = expand_date($element);
  682. $element['month']['#options'] = array('' => '--') + $element['month']['#options'];
  683. $element['day']['#options'] = array('' => '--') + $element['day']['#options'];
  684. $element['year']['#options'] = array('' => '--') + drupal_map_assoc(range(date('Y'), 1900));
  685. return $element;
  686. }
  687. /**
  688. * Validate the birthday field.
  689. */
  690. function birthdays_date_validate($element) {
  691. if (empty($element['#value'])) {
  692. return;
  693. }
  694. extract($element['#value']);
  695. if (empty($month) || empty($year) || empty($day)) {
  696. if ($element['#required']) {
  697. form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
  698. }
  699. elseif (!(empty($month) && empty($year) && empty($day))) {
  700. form_error($element, t('The specified date is invalid.'));
  701. }
  702. }
  703. elseif (!checkdate($month, $day, $year)) {
  704. form_error($element, t('The specified date is invalid.'));
  705. }
  706. }
  707. /**
  708. * Get starsign based on date of birth
  709. *
  710. * @var $day and $month, decribing date of birth
  711. * @return The name of the starsign
  712. */
  713. function _birthdays_get_starsign($day, $month) {
  714. switch ($month) {
  715. case 1:
  716. $starsign = $day < 20 ? 'capricorn' : 'aquarius';
  717. break;
  718. case 2:
  719. $starsign = $day < 19 ? 'aquarius' : 'pisces';
  720. break;
  721. case 3:
  722. $starsign = $day < 21 ? 'pisces' : 'aries';
  723. break;
  724. case 4:
  725. $starsign = $day < 20 ? 'aries' : 'taurus';
  726. break;
  727. case 5:
  728. $starsign = $day < 21 ? 'taurus' : 'gemini';
  729. break;
  730. case 6:
  731. $starsign = $day < 22 ? 'gemini' : 'cancer';
  732. break;
  733. case 7:
  734. $starsign = $day < 23 ? 'cancer' : 'leo';
  735. break;
  736. case 8:
  737. $starsign = $day < 23 ? 'leo' : 'virgo';
  738. break;
  739. case 9:
  740. $starsign = $day < 23 ? 'virgo' : 'libra';
  741. break;
  742. case 10:
  743. $starsign = $day < 23 ? 'libra' : 'scorpio';
  744. break;
  745. case 11:
  746. $starsign = $day < 23 ? 'scorpio' : 'sagittarius';
  747. break;
  748. case 12:
  749. $starsign = $day < 22 ? 'sagittarius' : 'capricorn';
  750. break;
  751. }
  752. return $starsign;
  753. }
  754. /**
  755. * Retrieve all fields of type 'date' from the profile.module's tables
  756. * @return array with fieldnames
  757. */
  758. function _birthdays_get_date_fields() {
  759. $options = array();
  760. $result = db_query("SELECT fid, name FROM {profile_fields} WHERE type = 'date'");
  761. while ($field = db_fetch_object($result)) {
  762. $options[$field->fid] = $field->name;
  763. }
  764. return $options;
  765. }
  766. /**
  767. * Retrieve profile field object
  768. *
  769. * @var string $fid
  770. * Id of field to retrieve
  771. * @return object
  772. * profile field object
  773. */
  774. function _birthdays_get_field($fid) {
  775. if (isset($fid)) {
  776. $field = db_fetch_object(db_query("SELECT * FROM {profile_fields} WHERE fid = %d", $fid));
  777. return empty($field) ? NULL : $field;
  778. }
  779. else {
  780. return NULL;
  781. }
  782. }
  783. /**
  784. * Return the picture of a starsign, given the name. Links to Yahoo! when option is selected.
  785. *
  786. * @param string starsign
  787. * name of the starsign to show (not translated)
  788. * @param int $show
  789. * Show starsigns for values > 0
  790. * @return string
  791. * HTML of a picture link to Yahoo horoscopes
  792. */
  793. function birthdays_get_starsign_image($starsign, $show = BIRTHDAYS_STARSIGN_OFF) {
  794. $output = '';
  795. // Only show starsign when enabled
  796. if ($show > BIRTHDAYS_STARSIGN_OFF && !empty($starsign)) {
  797. // Image based on thme path.
  798. $output = '<img src="'. base_path() . drupal_get_path('module', 'birthdays') .'/starsigns/'. $starsign .'.gif" alt="'. t($starsign) .'" />';
  799. // If link should be shown: update $output
  800. if ($show == BIRTHDAYS_STARSIGN_LINK) {
  801. $output = '<a href="http://astrology.yahoo.com/astrology/general/dailyoverview/'. $starsign .'" target="_blank" title="'. t($starsign) .'">'. $output .'</a>';
  802. }
  803. }
  804. // Return HTML
  805. return $output;
  806. }
  807. /**
  808. * Get age from a given date of birth
  809. *
  810. * @var array $date
  811. * array containing fields with keys 'year', 'month' and 'day'
  812. * @return int
  813. * age
  814. */
  815. function _birthdays_get_age($date) {
  816. // If date is not empty
  817. if (is_array($date)) {
  818. // extract date
  819. extract($date);
  820. // call main age function (no overloading in PHP)
  821. return _birthdays_calculate_age($day, $month, $year);
  822. }
  823. else {
  824. return NULL;
  825. }
  826. }
  827. /**
  828. * Calculate age
  829. *
  830. * @var $year, $month, $day as expected
  831. * @return int
  832. * age
  833. */
  834. function _birthdays_calculate_age($day, $month, $year) {
  835. if ($year && $month && $day) {
  836. // age = (current year - birthyear) - 1 (when the birthday hasn't arrived yet).
  837. return format_date(time(), 'custom', 'Y') - $year - (format_date(time(), 'custom', 'nd') < $month . str_pad($day, 2, 0, STR_PAD_LEFT));
  838. }
  839. else {
  840. return NULL;
  841. }
  842. }
  843. /**
  844. * Return age if user has agreed to show it
  845. *
  846. * @param object $account
  847. * a user object having attribute "age" set
  848. * @return int
  849. */
  850. function _birthdays_show_age($account) {
  851. $age = NULL;
  852. if (isset($account->age) && (variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_NO || (variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_USER && $account->birthdays_user_hide_year != BIRTHDAYS_HIDE_YEAR_USER_YES))) {
  853. $age = $account->age;
  854. }
  855. return $age;
  856. }
  857. /**
  858. * Format date array
  859. */
  860. function _birthdays_show_date($date, $account, $format = 'small') {
  861. if (is_array($date)) {
  862. // Extract date
  863. extract($date);
  864. // Call main format function
  865. return _birthdays_show_date_2($day, $month, $year, $account, $format);
  866. }
  867. else {
  868. return NULL;
  869. }
  870. }
  871. /**
  872. * Format date, optionally hide year
  873. */
  874. function _birthdays_show_date_2($day, $month, $year, $account, $type = 'small') {
  875. $output = '';
  876. // Determine format type
  877. switch ($type) {
  878. case 'medium':
  879. $format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
  880. break;
  881. case 'small':
  882. default:
  883. $format = variable_get('date_format_short', 'm/d/Y - H:i');
  884. }
  885. // remove time from (- H:i)
  886. //$format = substr($format, 0, -6);
  887. // If admin or user decide to hide the age&year: hide year
  888. if ($year && ( variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_YES || (variable_get('birthdays_hide_year', BIRTHDAYS_HIDE_YEAR_NO) == BIRTHDAYS_HIDE_YEAR_USER && $account->birthdays_user_hide_year == BIRTHDAYS_HIDE_YEAR_YES))) {
  889. $year = NULL;
  890. }
  891. // Replacement array (can't use date() because of 1970 limitations in e.g. Windows PHP4)
  892. $replace = array(
  893. 'd' => sprintf('%02d', $day),
  894. 'D' => NULL,
  895. 'j' => $day,
  896. 'm' => sprintf('%02d', $month),
  897. 'M' => map_month($month),
  898. 'Y' => $year,
  899. 'y' => $year,
  900. 'H:i' => NULL,
  901. 'G:i' => NULL,
  902. 'g:ia' => NULL,
  903. 'F' => t(gmdate('F', mktime(0, 0, 0, $month, 15, 2000))),
  904. );
  905. // Translate string to correct format
  906. $output .= strtr($format, $replace);
  907. $output = trim($output, '/ ,.:-');
  908. return $output;
  909. }
  910. /**
  911. * Check which e-mail strings should be retreived, and fill in the default
  912. * placeholders. Uses the same method as _user_mail_text().
  913. */
  914. function _birthdays_mail_text($key, $language = NULL, $variables = array()) {
  915. $langcode = isset($language) ? $language->language : NULL;
  916. // If the text is not the default, run it through strtr() to fill in the
  917. // placeholders.
  918. if ($text = variable_get('birthdays_send_user_' . $key, FALSE)) {
  919. return strtr($text, $variables);
  920. }
  921. else {
  922. // Which text do we want to retreive?
  923. switch ($key) {
  924. case 'subject':
  925. return t('Happy Birthday, !username!', $variables, $langcode);
  926. case 'message':
  927. return t("Hey !username,\n\nHappy birthday!\nWe hope you have a great day\n\nThe !site-team\n!uri_brief", $variables, $langcode);
  928. }
  929. }
  930. }