. July 2006 * This is a Drupal 4.7 module to dynamically generate PayPal buttons and * processes incoming PayPal IPN messages. * * This module is licensed under Gnu General Public License Version 2 * see the LICENSE.txt file for more details. */ define(LM_PAYPAL_DONATIONS, 'LM_PayPal_Donat'); // Don't change these here! Use the admin interface at admin/lm_paypal define(LM_PAYPAL_DONATIONS_THANKS_DEFAULT, '/lm_paypal/donations_thanks'); /** * Initialize global variables */ function _lm_paypal_donations_ini() { _lm_paypal_ini(); global $_lm_paypal_donations_thanks; // page user is directed to on donation static $inited = 0; if ($inited) { return; } $inited = 1; $_lm_paypal_donations_thanks = variable_get('lm_paypal_donations_thanks', LM_PAYPAL_DONATIONS_THANKS_DEFAULT); lm_paypal_web_accept_register('lm_paypal_process_in_donate', 0, 0); } /** * Implementation of hook_help(). */ function lm_paypal_donations_help($section) { _lm_paypal_donations_ini(); global $_lm_paypal_welcome; // Welcome message global $base_url; global $_lm_paypal_drupal_major; global $_lm_paypal_drupal_minor; if ($_lm_paypal_drupal_major > 4) { // Drupal 5 $c = '!'; // t() has changed and to use a link in it use '!' $admin = l('LM PayPal Admin', 'admin/lm_paypal/settings'); $access = l('access control', 'admin/user/access'); } else { // Drupal 4 $c = '%'; $admin = l('LM PayPal Admin', 'admin/settings/lm_paypal'); $access = l('access control', 'admin/access'); } $help = l('LM PayPal Help', 'admin/help/lm_paypal'); $help_dons = l('LM PayPal Donations Help', 'admin/help/lm_paypal_donations'); $view_dons = l(t('PayPal Donations'), 'lm_paypal/donations'); switch ($section) { case 'admin/help#lm_paypal_donations': // admin/help/lm_paypal_donations $output = $_lm_paypal_welcome; $output .= '

'. t('If you are not already familar with PayPal please go to there website and read up.') .'

'; $output .= '

'. t('Special Note') . ':'; $output .= '

'; $output .= '

' . t('If you are new to this module you need to:'); $output .= '

'; $output .= '

'; $output .= '

' . t("Ensure the right roles (usually everyone, so anonymous and authenticated!) can see the donation buttons by enabling this in ${c}access under lm_paypal_module 'access lm_paypal_donate'. You can allow roles to view everyones donations using 'view lm_paypal_all_donations'.", array("${c}access" => $access)) .'

'; $output .= '

'. t('Creating Donation Buttons') .'

'; $output .= '

'. t('Donations buttons are displayed with php like the following which display the three types of donation:') . '

'; $output .= '
'. t('
<?php
if (function_exists(\'lm_paypal_donate\')) {
  // 10 = amount, \'USD\' is the currency followed by a description
  print \'We would really like a $10 donation \' .
    lm_paypal_donate(10, \'USD\', \'donation to example.com\') .\'<br>\';
  // The amount is a one element array so an text input with the one value as
  //  default
  print \'Write your own amount to give, we suggest $5\' .
    lm_paypal_donate(array(5), \'USD\', \'donation to example.com\') . \'<br>\';
  // The amount is a multi element array so a select will be used. Note if one
  //   of the elements is itself an array that will be the default selection
  // The final two parameters are an alternative button (here we use the default)
  //   and a replacement label before the amount
  print \'We would really like a $10, or more, donation \' .
    lm_paypal_donate(array(5,array(10),15), \'USD\', \'donation to example.com\', \'\', \'Donation\') .\'<br>\';
}
?>
        ') . '
'; $output .= '

'. t('It is best to check that the lm_paypal_donate function exists before using it just in case the module has been disabled.') . '

'; $output .= '

'. t('If the button is clicked by a logged in user when the payment arrives the amount will be associated with them. Otherwise an attempt will be made to match the payers email with user emails.') . '

'; $output .= '

'. t('Viewing Donations') .'

'; $output .= '

'. t("To view all the donations that have arrived use ${c}view_dons.", array("${c}view_dons" => $view_dons)) . '

'; return $output; // This is the brief description of the module displayed on the modules page case 'admin/modules#description': // New to Drupal 5 (because the page has moved) case 'admin/settings/modules#description': return t('Provides PayPal donation buttons (requires lm_paypal).'); // This is the brief description of the module displayed on the help page case 'admin/help#lm_paypal_donations': $output = '

'. t('The lm_paypal_donations module. ') .'

'; return $output; // This appears at the start of the module admin page before the options case 'admin/settings/lm_paypal_donations': // This appears at the start of the admin page before the options case 'admin/lm_paypal/donations': // New to Drupal 5 - settings has moved case 'admin/lm_paypal/donations_settings': $output .= $_lm_paypal_welcome; $output .= '

'. t("For detailed help please read ${c}help_dons", array("${c}help_dons" => $help_dons)) . '

'; return $output; } } /** * Implementation of hook_perm(). * Return a list of the access control permissions that this module defines */ function lm_paypal_donations_perm() { return array('access lm_paypal_donate', 'view lm_paypal_all_donations'); } /** * Implementation of hook_menu(). */ function lm_paypal_donations_menu($may_cache) { _lm_paypal_donations_ini(); global $_lm_paypal_drupal_major; global $_lm_paypal_drupal_minor; $items = array(); if ($may_cache) { if ($_lm_paypal_drupal_major > 4) { // New to Drupal 5 - hook_settings gone so settings is a normal page $items[] = array( 'path' => 'admin/lm_paypal/donations_settings', 'title' => t('LM PayPal Donations Settings'), 'callback' => 'drupal_get_form', 'callback arguments' => array('lm_paypal_donations_admin_settings'), 'access' => user_access('administer site configuration'), 'type' => MENU_NORMAL_ITEM, 'weight' => 3, // New to Drupal 5 - every path has a description 'description' => t('PayPal donations interface configuration.'), ); } // admin - print all donations $items[] = array( 'path' => 'lm_paypal/donations', 'title' => t('PayPal Donations'), 'callback' => 'lm_paypal_all_donations', 'access' => user_access('view lm_paypal_all_donations'), // New to Drupal 5 - every path has a description 'description' => t('PayPal view All Donations'), ); // By default we tell Paypal to redirect users here after donating $items[] = array( 'path' => 'lm_paypal/donations_thanks', 'title' => t('LM PayPal Donation Thanks'), 'type' => MENU_CALLBACK, 'callback' => 'lm_paypal_donations_thanks', 'access' => user_access('access lm_paypal_donate'), ); } return $items; } // Ugly magic to hide lm_paypal_settings from Drupal 5.0 as it spots its // existance and refuses to access the real page. if (strncmp(VERSION, '4', 1) == 0) { /** * Implementation of hook_settings() * Note: hook_settings not used in Drupal 5. */ function lm_paypal_donations_settings() { return lm_paypal_donations_settings_form(); } } /** * Provide the admin settings page. * Note: New to Drupal 5 */ function lm_paypal_donations_admin_settings() { $form = lm_paypal_donations_settings_form(); return system_settings_form($form); } /** * Implementation of hook_settings() */ function lm_paypal_donations_settings_form() { _lm_paypal_donations_ini(); global $_lm_paypal_donations_thanks; global $_lm_paypal_drupal_major; global $_lm_paypal_drupal_minor; if (!user_access('administer lm_paypal')) { drupal_access_denied(); return; } $form ['lm_paypal_donations_thanks'] = array( '#type' => 'textfield', '#title' => t('LM PayPal donation thanks page'), '#default_value' => $_lm_paypal_donations_thanks, '#maxlength' => 100, '#required' => TRUE, '#description' => t('The page the user is sent to by paypal after a donation. The default is %link but you might want to point it at a page you have created yourself.', array('%link' => LM_PAYPAL_DONATIONS_THANKS_DEFAULT)), ); return $form; } /** * Process a newly arrived donation ipn message * * @param $ipn * The IPN message * @link * html link to the the IPN to display in watchdog reports * @uid * The uid of the user associated with this IPN, zero if the user is unknown * @other * The extra integer passed with the uid * @item_number * The PayPal item_number */ function lm_paypal_process_in_donate($ipn, $link, $uid, $other, $item_number) { _lm_paypal_donations_ini(); global $_lm_paypal_debug; if ($_lm_paypal_debug) { watchdog(LM_PAYPAL_DONATIONS, 'in donate'); } $sql = "INSERT INTO {lm_paypal_donations} SET "; $sql .= "uid = %d, "; $sql .= "datepaid = %d,"; $sql .= "item_name = '%s',"; $sql .= "mc_gross = '%s',"; $sql .= "mc_fee = '%s',"; $sql .= "mc_currency = '%s',"; $sql .= "txn_id = '%s'"; $insert = db_query( $sql, $uid, time(), $ipn->item_name, $ipn->mc_gross, $ipn->mc_fee, $ipn->mc_currency, $ipn->txn_id); if (!$insert) { watchdog(LM_PAYPAL_DONATIONS, t('Failed to add to donations (uid %uid)', array('%uid' => $uid)), WATCHDOG_ERROR); } } /** * Display a dynamically generated PayPal donate button. * * @param $amount * Required. * If a number it is the amount of the donation. User not asked. * If a single element array then a text input will appear with * this as the default value for the amount. * If a multi element array then a select will appear with the given * values. If one of the values is itself an array that will be the * default. * @param $ccc * A PayPal 3 letter currency code for the donation (e.g: USD). * @param $name * The name of the donation, displayed on PayPal donate form * @param $button_url * The url of button to click on to make the donation * @param $amount_label * Label to put before the amount if asking the user * @param $ret_url * If non empty it is the url the user is returned to after the transaction * @return * The html string representing the button. */ function lm_paypal_donate($amount = '', $ccc = '', $name = '', $button_url = '', $amount_label = '', $ret_url = '') { _lm_paypal_donations_ini(); global $user; global $_lm_paypal_debug; global $_lm_paypal_host; global $_lm_paypal_business; global $_lm_paypal_donations_thanks; global $_lm_paypal_js_hide_email; if (!user_access('access lm_paypal_donate')) { return t('Access to PayPal donation buttons denied'); } if ($button_url == '') { // This is the default paypal donate button $button_url = 'http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif'; } $button_url = check_url($button_url); $ccc = check_plain($ccc); if (is_array($amount)) { if (count($amount) == 1) { $a = $amount[0]; $cs = lm_paypal_ccc2symbol($ccc); $sa = "$cs \n"; } else { $sa .= '\n"; $form .= "\n"; $form .= "\n"; $form .= "\n"; // item_number 0 is a donation // The only downside of setting the item number is that PayPal may display // it on the user form ("My item\nItem_number0") //$form .= "\n"; if (!isset($sa)) { $form .= "\n"; } $form .= "\n"; $form .= "\n"; if ($ccc) { $form .= "\n"; } $form .= "\n"; $form .= "uid\">\n"; $form .= "\n"; if (isset($sa)) { $form .= "\n"; } $form .= "\n"; $output .= $form; return $output; } /** * Returns the default page that users are sent to by PayPal after donating. * * @return * A string containing the page contents. */ function lm_paypal_donations_thanks() { return t('

Thank you!

If the system is not too busy then your donation will arrive shortly. At worse it will only take a few hours.

Once again, thanks!

'); } /** * Implementation of hook_user(). */ function lm_paypal_donations_user($op, &$edit, &$account, $category = NULL) { _lm_paypal_donations_ini(); global $_lm_paypal_debug; $uid = $account->uid; // In the "my account" view area show all donations if ($op == 'view' && (user_access('administer lm_paypal') || $user->uid == $account->uid)) { $output .= lm_paypal_donations($uid, $per_page = 10); $ditems [] = array( 'title' => '', 'value' => $output); $ret_dons = array(t('Paypal Donations') => $ditems); return $ret_dons; } } /** * Implementation of hook_form_alter(). */ function lm_paypal_donations_form_alter($form_id, $form) { if ($form_id == 'system_modules' && !$_POST) { // Check that lm_paypal is enabled $me = 'lm_paypal_donations'; $dep = array('lm_paypal'); lm_paypal_system_module_validate($form,$me,$dep); } } /** * View all donations */ function lm_paypal_all_donations() { return lm_paypal_donations(0); } /** * View donations from one user */ function lm_paypal_my_donations($uid) { return lm_paypal_donations($uid); } /** * View donations * * @param * if a uid is passed then just print out details of that donation */ function lm_paypal_donations($uid, $per_page = 50) { global $user; if ($uid == null || !is_numeric($uid) || intval($uid) != $uid) { $uid = 0; } if (!($user->uid == $uid || user_access('view lm_paypal_all_donations'))) { return t('You do not have permission to view donations'); /* drupal_access_denied(); return ''; */ } $header = array( array('data' => t('User'), 'field' => 'u.name'), array('data' => t('Item Name'), 'field' => 'd.item_name'), array('data' => t('Date Paid'), 'field' => 'd.datepaid', 'sort' => 'desc'), array('data' => t('Amount'), 'field' => 'd.mc_gross'), array('data' => t('Currency'), 'field' => 'd.mc_currency'), ); $sql = "SELECT u.name, d.item_name, d.uid, d.datepaid, d.mc_gross, d.mc_currency FROM {lm_paypal_donations} d INNER JOIN {users} u ON d.uid = u.uid"; $tablesort = tablesort_sql($header); // If not sorting by datepaid then make that the 2nd field to sort on if (strpos($tablesort,'datepaid') === FALSE) { $tablesort .= ', datepaid DESC'; } // placeholder until I figure out what would be good to filter on $status = $_SESSION['lm_paypal_dons_filter']; $status = 'all'; if ($status != 'all') { if ($uid != 0) { $sql .= " WHERE d.uid = $uid AND s.status = '%s'"; } else { $sql .= " WHERE s.status = '%s'"; } $result = pager_query($sql . $tablesort, $per_page, 0, NULL, $status); } else { if ($uid != 0) { $sql .= " WHERE d.uid = $uid"; } $result = pager_query($sql . $tablesort, $per_page); } while ($don = db_fetch_object($result)) { $rows[] = array('data' => array( l(check_plain($don->name), "user/$sub->uid"), check_plain($don->item_name), format_date($don->datepaid, 'small'), check_plain($don->mc_gross), check_plain($don->mc_currency), ), ); } if (!$rows) { $rows[] = array(array('data' => t('No donations found.'), 'colspan' => 3)); } $output .= theme('table', $header, $rows); $output .= theme('pager', NULL, $per_page, 0); return $output; }