pay.module in Pay 6
Same filename and directory in other branches
Pay module allows for accepting payments using pluggable payment backends.
File
pay.moduleView source
<?php
/**
* @file
* Pay module allows for accepting payments using pluggable payment backends.
*/
/**
* Implementation of hook_init().
*/
function pay_init() {
if (module_exists('trigger')) {
include_once dirname(__FILE__) . '/includes/pay.trigger.inc';
}
if (module_exists('token')) {
include_once dirname(__FILE__) . '/includes/pay.token.inc';
}
include_once dirname(__FILE__) . '/includes/pay.action.inc';
}
/**
* Implementation of hook_menu().
*/
function pay_menu() {
module_load_include('menu.inc', 'pay', 'includes/pay');
return pay_menu_menu();
}
/**
* Implementation of hook_perm().
*/
function pay_perm() {
// Permissions based on form types and global settings.
$permissions = array(
'view reports for any payment form',
'administer pay',
'administer payments for any form',
'make payments on any form',
);
foreach (pay_handlers('pay_form') as $name => $info) {
$permissions[] = 'administer payments for ' . $name . ' forms';
$permissions[] = 'make payments on ' . $name . ' forms';
$permissions[] = 'view reports for ' . $name . ' forms';
}
return $permissions;
}
/**
* Implementation of hook_theme().
*/
function pay_theme() {
module_load_include('theme.inc', 'pay', 'theme/pay');
return pay_theme_theme();
}
/**
* Implementation of hook_user().
*/
function pay_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'categories':
// Return only a modes 'category' entry - the real work happens in the
// page callback for payment settings. See also hook_menu.
return array(
array(
'name' => 'pay',
),
);
case 'delete':
// Deactivate any payment forms this user may have created.
db_query("UPDATE {pay_form} SET status = 0, uid = 0 WHERE uid = %d", $account->uid);
// Remove reference to this user's uid in transaction history.
db_query("UPDATE {pay_transaction} SET uid = 0 WHERE uid = %d", $account->uid);
db_query("UPDATE {pay_activity} SET uid = 0 WHERE uid = %d", $account->uid);
break;
}
}
/**
* An access callback for access to user-specific Payment settings form.
*/
function pay_user_settings_access($account) {
// Permit access if any module returns TRUE in hook_pay_user_settings_access()
foreach (module_implements('pay_user_settings_access') as $module) {
$func = $module . '_pay_user_settings_access';
if ($func($account)) {
return TRUE;
}
}
// Return FALSE by default, thus hiding the 'Payment settings' form.
return FALSE;
}
/**
* Form builder; Present the form to edit a user's payment settings.
*
* @ingroup forms
*/
function pay_user_settings_page($account, $category = 'default') {
drupal_set_title(check_plain($account->name));
return drupal_get_form('pay_user_settings_form', $account, $category);
}
/**
* A form callback for a user's 'Payment settings' page.
*/
function pay_user_settings_form(&$form_state, $account, $category = 'default') {
$form = array();
// Rely on whatever the underlying hooks might return.
foreach (module_implements('pay_user_settings_form') as $module) {
$func = $module . '_pay_user_settings_form';
$func($form, $form_state, $account);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Implementation of hook_views_api().
*/
function pay_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'pay') . '/includes/views',
);
}
/**
* API Function: All available payment handlers.
*/
function pay_handlers($type, $handler_name = NULL, $refresh = FALSE) {
static $handlers = array();
if ($refresh || !isset($handlers[$type])) {
module_load_include('handlers.inc', 'pay', 'includes/pay');
$handlers[$type] = module_invoke_all($type . '_handler_info');
foreach ($handlers[$type] as $name => $info) {
if (!isset($info['module'])) {
$handlers[$type][$name]['module'] = $name;
}
if (!isset($info['handler'])) {
$handlers[$type][$name]['handler'] = $name;
}
}
}
if ($handler_name) {
return $handlers[$type][$handler_name];
}
return $handlers[$type];
}
/**
* API Function: Include a handler file for a payment object.
*/
function pay_load_handler($type, $name) {
static $cache = array();
if (!isset($cache[$type])) {
// Base classes for handlers.
module_load_include('inc', 'pay', 'includes/handlers/pay');
module_load_include('inc', 'pay', 'includes/handlers/' . $type);
$cache[$type] = array();
}
// This is a pay primitive class, so we're done.
if ($type == $name) {
return TRUE;
}
// Already loaded.
if (isset($cache[$type][$name])) {
return $cache[$type][$name];
}
if ($name && ($handler = pay_handlers($type, $name))) {
// Ensure the parent is loaded.
if (isset($handler['parent'])) {
pay_load_handler($type, $handler['parent']);
}
// Respect the 'path' element that may have been specified.
$file = isset($handler['path']) ? $handler['path'] . '/' : '';
$file .= $name . '.inc';
// Require the file, if it exists.
if ($cache[$type][$name] = is_file($file)) {
require_once $file;
}
return $cache[$type][$name];
}
}
/**
* API Function: Load a payment class.
*/
function pay_load($type, $values = NULL) {
if (is_scalar($values)) {
if (is_numeric($values)) {
if ($type == 'pay_form') {
$key = 'pfid';
}
if ($type == 'pay_method') {
$key = 'pmid';
}
if ($type == 'pay_item') {
$key = 'piid';
}
if ($type == 'pay_transaction') {
$key = 'pxid';
}
if ($type == 'pay_activity') {
$key = 'paid';
}
if ($values = db_fetch_object(db_query("SELECT * from {%s}\n WHERE {$key} = %d", $type, $values))) {
$handler = isset($values->handler) ? $values->handler : $type;
}
else {
return FALSE;
}
}
else {
// It's just the name of a handler. Load it with defaults.
$handler = $values;
$values = NULL;
}
}
else {
$values = (object) $values;
if (isset($values->handler)) {
$handler = $values->handler;
}
elseif (isset($values->pmid)) {
$handler_values = pay_load($type, $values->pmid);
$handler = get_class($handler_values);
$values = array_merge((array) $handler_values, (array) $values);
}
else {
// Allow return of a generic object of the type requested.
$handler = $type;
}
}
if (pay_load_handler($type, $handler)) {
return new $handler($values);
}
}
/**
* API Function: Load a payment form object.
*/
function pay_form_load($values = NULL) {
return pay_load('pay_form', $values);
}
/**
* API Function: Load a payment method object.
*/
function pay_method_load($values = NULL) {
return pay_load('pay_method', $values);
}
/**
* API Function: Load a payment transaction object.
*/
function pay_transaction_load($values = NULL) {
return pay_load('pay_transaction', $values);
}
/**
* API Function: Load a payment item object.
*/
function pay_item_load($values = NULL) {
return pay_load('pay_item', $values);
}
/**
* API Function: Load a payment activity object.
*/
function pay_activity_load($values = NULL) {
return pay_load('pay_activity', $values);
}
/**
* A simple form any type of pay element.
* If you want to build a module with a standalone payment form, you would
* do so by passing this function to the drupal_get_form page handler in your
* hook_menu() funcion.
*
* Alternatively, you can manually add payment form capabilities by including
* the code from this function in your form builder or form_alter code.
*/
function pay_form(&$form_state, $pay, $type = NULL, $form_type = 'default') {
if ($type) {
$pay = pay_load($type, $pay);
}
// Add a "build mode" to $form_state so that the form handlers can render
// forms differently based on user-defined context.
$form_state['pay_form_type'] = $form_type;
// Allow this handler to alter in all of its form fields. This will also
// add the appropriate validate and submit callbacks for the Payment API.
$pay
->form($form, $form_state);
// Add a submit button, if we think it's necessary.
if (!isset($form['submit']) && !isset($form[$pay
->handler()]['submit'])) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit payment'),
);
}
return $form;
}
/**
* A FAPI after_build handler for any type of pay form.
*/
function pay_after_build($form, &$form_state) {
// Ensure that the pay_submit handler is added to the form after the others.
$form['#validate'][] = 'pay_validate';
$form['#submit'][] = 'pay_submit';
return $form;
}
/**
* Implementation of hook_form_alter().
* Pass the form to any applicable pay handlers in case they have some input.
*/
function pay_form_alter(&$form, &$form_state, $form_id) {
pay_form_callback('alter', $form, $form_state);
}
/**
* A FAPI validate handler for any type of pay form.
*/
function pay_validate($form, &$form_state) {
pay_form_callback('validate', $form, $form_state);
}
/**
* A FAPI submit handler for any type of pay form.
*/
function pay_submit($form, &$form_state) {
pay_form_callback('submit', $form, $form_state);
}
/**
* A helper function for FAPI validate/submit callbacks.
* Locates any pay elements in a form and calls thier handler code.
*/
function pay_form_callback($callback, &$form, &$form_state) {
if (isset($form['#pay'])) {
foreach ($form['#pay'] as $key => $item) {
if ($pay = pay_load($item['type'], $item)) {
$func = isset($item['form']) ? $item['form'] : 'form';
$func .= '_' . $callback;
if (method_exists($pay, $func)) {
$pay
->{$func}($form, $form_state);
}
$form_state['pay'][$key] = $pay;
}
}
}
}
/**
* A helper function to be used as a #pre_render callback: Sets an element to
* "required" for rendering. The calling code should handle validation
* responsibly.
*/
function pay_element_set_required($element) {
$element['#required'] = TRUE;
return $element;
}
/**
* List of meaningful ways in which a payment form can appear.
*/
function pay_form_displays() {
static $displays = array();
if (!$displays) {
$displays['pay_form_default'] = array(
'title' => t('Default display of entire form'),
);
$displays['pay_form_amount'] = array(
'title' => t('Amount only, with link to payment form'),
);
$displays['pay_form_link'] = array(
'title' => t('Link to payment form'),
);
drupal_alter('pay_form_displays', $displays);
}
return $displays;
}
/**
* Name/value List of meaningful ways in which a payment form can appear.
*/
function pay_form_displays_list() {
$list = array();
foreach (pay_form_displays($handler) as $key => $info) {
$list[$key] = $info['title'];
}
return $list;
}
/**
* List available payment forms.
*/
function pay_forms($handler = NULL, $embeddable = NULL, $status = 1) {
$where = $args = array();
if (!is_null($handler)) {
$where[] = "handler = '%s'";
$args[] = $handler;
}
if (!is_null($status)) {
$where[] = "status = %d";
$args[] = $status;
}
if (!is_null($embeddable)) {
$where[] = "embeddable = %d";
$args[] = $embeddable;
}
$sql = "SELECT * FROM {pay_form}";
if ($where) {
$sql .= ' WHERE ' . join(' AND ', $where);
}
$sql .= " ORDER BY title";
$forms = array();
$res = db_query($sql, $args);
while ($row = db_fetch_object($res)) {
if ($pay_form = pay_form_load($row)) {
$forms[$row->pfid] = $pay_form;
}
}
return $forms;
}
/**
* Helper function to list all payment methods available.
*/
function pay_method_list() {
$list = array();
$res = db_query("SELECT * FROM {pay_method} WHERE STATUS = 1 ORDER BY title");
while ($row = db_fetch_object($res)) {
$list[$row->pmid] = pay_method_load($row);
}
return $list;
}
/**
* Helper function to list all possible currencies.
*
* This function returns a superset of all currencies supported by all payment
* methods installed on this site.
*/
function pay_currency_list() {
static $list;
if (!isset($list)) {
// Gather a list of all supported currencies.
$currencies = $list = array();
foreach (pay_handlers('pay_method') as $name => $info) {
if ($method = pay_method_load($name)) {
$currencies = array_merge($currencies, $method
->available_currencies());
}
}
// Create a sorted key => value array.
foreach ($currencies as $item) {
$list[$item] = $item;
}
ksort($list);
drupal_alter('pay_currency_list', $list);
}
return $list;
}
/**
* Callback for pay activity responses.
*/
function pay_gateway_response($pay_activity) {
// Add an additional activity to the transaction to track the response.
$new_activity = $pay_activity
->pay_transaction()
->add_activity($pay_activity
->pay_method());
$new_activity
->do_activity('response', $_REQUEST);
}
/**
* Return a list of available transaction states.
*/
function pay_transaction_states($state = NULL) {
static $states;
if (!isset($states)) {
$states = array();
foreach (pay_transaction_load()
->states() as $name => $info) {
$states[$name] = $info['title'];
}
}
if (isset($state)) {
return $states[$state];
}
return $states;
}
/**
* Return the 'nice' name for payment transaction states.
*/
function pay_transaction_state_name($state) {
// It's a transaction object? Function as a wrapper for its state() method.
if (is_object($state)) {
return $state
->state(TRUE);
}
// Or else just return the label based on this name.
return pay_transaction_states($state);
}
/**
* Wrapper for $pay_transaction->valid_action(), to be used as a menu callback.
*/
function pay_transaction_valid_action($pay_transaction, $action) {
// Not a valid action for this transaction. Skip it and return FALSE.
if (!$pay_transaction
->valid_action($action)) {
return FALSE;
}
// Return TRUE for payment administrators for this/all forms.
if (user_access('administer payments for any form')) {
return TRUE;
}
$handler = $pay_transaction
->pay_form()
->handler();
if (user_access('administer payments for ' . $handler . ' forms')) {
return TRUE;
}
// Give up and return false.
return FALSE;
}
/**
* Wrapper for $pay_transaction->do_action(), to be used as a menu callback.
*/
function pay_transaction_do_action($transaction, $action, $path = FALSE) {
if ($transaction
->do_action($action)) {
$info = $transaction->valid_actions[$action];
if ($info['message']) {
drupal_set_message($info['message']);
}
}
// Redirect to the transaction page or the front page if it has been deleted.
if ($path) {
if ($path === TRUE) {
$path = 'pay/transaction/' . $transaction->pxid;
if ($action == 'delete') {
$path = '<front>';
}
}
drupal_goto($path);
}
}
/**
* Title callback for a page that effects a payment transaction action.
*/
function pay_transaction_action_title($pay_transaction, $action) {
if ($info = $pay_transaction
->valid_actions($action)) {
return t('@title transaction', array(
'@title' => $info['title'],
));
}
}
Functions
Name | Description |
---|---|
pay_activity_load | API Function: Load a payment activity object. |
pay_after_build | A FAPI after_build handler for any type of pay form. |
pay_currency_list | Helper function to list all possible currencies. |
pay_element_set_required | A helper function to be used as a #pre_render callback: Sets an element to "required" for rendering. The calling code should handle validation responsibly. |
pay_form | A simple form any type of pay element. If you want to build a module with a standalone payment form, you would do so by passing this function to the drupal_get_form page handler in your hook_menu() funcion. |
pay_forms | List available payment forms. |
pay_form_alter | Implementation of hook_form_alter(). Pass the form to any applicable pay handlers in case they have some input. |
pay_form_callback | A helper function for FAPI validate/submit callbacks. Locates any pay elements in a form and calls thier handler code. |
pay_form_displays | List of meaningful ways in which a payment form can appear. |
pay_form_displays_list | Name/value List of meaningful ways in which a payment form can appear. |
pay_form_load | API Function: Load a payment form object. |
pay_gateway_response | Callback for pay activity responses. |
pay_handlers | API Function: All available payment handlers. |
pay_init | Implementation of hook_init(). |
pay_item_load | API Function: Load a payment item object. |
pay_load | API Function: Load a payment class. |
pay_load_handler | API Function: Include a handler file for a payment object. |
pay_menu | Implementation of hook_menu(). |
pay_method_list | Helper function to list all payment methods available. |
pay_method_load | API Function: Load a payment method object. |
pay_perm | Implementation of hook_perm(). |
pay_submit | A FAPI submit handler for any type of pay form. |
pay_theme | Implementation of hook_theme(). |
pay_transaction_action_title | Title callback for a page that effects a payment transaction action. |
pay_transaction_do_action | Wrapper for $pay_transaction->do_action(), to be used as a menu callback. |
pay_transaction_load | API Function: Load a payment transaction object. |
pay_transaction_states | Return a list of available transaction states. |
pay_transaction_state_name | Return the 'nice' name for payment transaction states. |
pay_transaction_valid_action | Wrapper for $pay_transaction->valid_action(), to be used as a menu callback. |
pay_user | Implementation of hook_user(). |
pay_user_settings_access | An access callback for access to user-specific Payment settings form. |
pay_user_settings_form | A form callback for a user's 'Payment settings' page. |
pay_user_settings_page | Form builder; Present the form to edit a user's payment settings. |
pay_validate | A FAPI validate handler for any type of pay form. |
pay_views_api | Implementation of hook_views_api(). |