You are here

class pay_form in Pay 7

Same name and namespace in other branches
  1. 6 includes/handlers/pay_form.inc \pay_form

@file The base class for payment activities. All payment form classes should extend this.

Hierarchy

Expanded class hierarchy of pay_form

16 string references to 'pay_form'
pay::permissions_settings in includes/handlers/pay.inc
pay_admin_pay_form_list in includes/pay.admin.inc
List payment forms
pay_form_load in ./pay.module
API Function: Load a payment form object.
pay_handler_field_amount::query in includes/views/pay_handler_field_amount.inc
Called to add the field to a query.
pay_handler_field_count::query in includes/views/pay_handler_field_count.inc
Called to add the field to a query.

... See full list

File

includes/handlers/pay_form.inc, line 9
The base class for payment activities. All payment form classes should extend this.

View source
class pay_form extends pay {
  var $pfid;
  var $title;
  var $status = 1;
  var $embeddable = FALSE;
  var $uid;
  var $min_amount = 1.0;
  var $max_amount = 1000.0;
  var $menu_path;
  var $total_goal;
  var $currency;
  var $pay_methods = array();
  var $notes_title = 'Comments';
  var $notes_format = NULL;
  var $notes_description = '';
  var $user_register = FALSE;
  var $table = 'pay_form';
  var $key = 'pfid';
  function title() {
    return check_plain($this->title);
  }
  function set_notes_format() {
    $this->notes_format = filter_fallback_format();
    return $this->notes_format;
  }
  function set_transaction($values) {
    module_load_include('inc', 'pay', 'includes/handlers/pay_transaction');
    $this->transaction = new pay_transaction($values);
    if (!$this->transaction->pfid) {
      $this->transaction->pfid = $this->pfid;
    }
    $this->transaction
      ->save($values);
    return $this->transaction;
  }

  /**
   * Modify the list of payment actions that are valid for a given transaction.
   *
   * @param $pay_transaction
   *  An existing transaction that is using this pay_form.
   * @param $actions
   *  An array of default actions, passed by reference. Modify or augment this
   *  as needed.
   */
  function set_valid_actions($pay_transaction, &$actions) {
    foreach ($this
      ->pay_methods() as $pay_method) {
      $pay_method
        ->set_valid_actions($this, $actions);
    }
  }

  /**
   * List of all currencies available for this form.
   */
  function currency_list() {
    if (!isset($this->currency_list)) {

      // By default, return the one globally-selected currency.
      $global = pay_currency_list();
      $this->currency_list = array(
        $this
          ->currency() => $global[$this
          ->currency()],
      );

      // Multiple currency support is handled by a separate module that must
      // set this variable and deal with the conversion fallout responsibly.
      if (variable_get('pay_currency_multiple', FALSE)) {
        foreach ($this
          ->pay_methods() as $method) {
          foreach ($method
            ->available_currencies() as $currency) {
            if (!isset($this->currency_list[$currency])) {
              $this->currency_list[$currency] = $currency;
            }
          }
        }
      }
      drupal_alter('pay_currency_list', $this->currency_list);
    }
    return $this->currency_list;
  }

  /**
   * Set the currency for this payment form.
   */
  function set_currency($value = NULL) {
    if (!$value) {
      $value = variable_get('pay_currency', NULL);
    }
    $this->currency = $value;
  }
  function currency() {
    if (!isset($this->currency)) {
      $this
        ->set_currency();
    }
    return $this->currency;
  }
  function user_register() {
    global $user;
    if ($user->uid) {
      return FALSE;
    }
    if ($this->user_register == 'none') {
      return FALSE;
    }
    return $this->user_register;
  }
  function set_user_register($value = FALSE) {
    if (in_array($value, array(
      FALSE,
      'optional',
      'required',
    ))) {
      $this->user_register = $value;
    }
    else {
      $this->user_register = FALSE;
    }
  }

  /**
   * @todo Please document this function.
   * @see http://drupal.org/node/1354
   */
  function pay_method_list() {
    $list = array();
    $result = db_query("SELECT * FROM {pay_method} WHERE STATUS = 1 ORDER BY title");
    while ($row = $result
      ->fetchObject()) {
      $list[$row->pmid] = $row->title;
    }
    return $list;
  }
  function set_embeddable($value = FALSE) {
    $this->embeddable = (bool) $value;
  }
  function embeddable() {
    return (bool) $this->embeddable;
  }
  function settings_form(&$form, &$form_state) {
    parent::settings_form($form, $form_state);
    $group = $this
      ->handler();

    // If the parent form has not supplied a title, add one.
    if (!isset($form['title'])) {
      $form[$group]['title'] = array(
        '#type' => 'textfield',
        '#title' => t('Title'),
        '#default_value' => $this->title,
        '#required' => TRUE,
        '#description' => t('This title will appear as the title of the form page and in listings.'),
      );
    }
    $form[$group]['min_amount'] = array(
      '#type' => 'textfield',
      '#size' => 10,
      '#title' => t('Minimum amount'),
      '#description' => t('The minimum allowed payment on this form. If there are service fees or other costs associated with receiving payments, you will want this to set this amount higher than those costs.'),
      '#default_value' => $this->min_amount,
    );
    $form[$group]['max_amount'] = array(
      '#type' => 'textfield',
      '#size' => 10,
      '#title' => t('Maximum amount'),
      '#description' => t('The maximum allowed amount for this form. If your payment method has a limit, this setting should reflect it.'),
      '#default_value' => $this->max_amount,
    );
    $form[$group]['pay_methods'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Available payment methods'),
      '#description' => t('Payment methods available for this form.'),
      '#options' => $this
        ->pay_method_list(),
      '#default_value' => $this->pay_methods,
    );

    /**
    * @todo Disable this until it's ready for prime time.
    *
    $form[$group]['user_register'] = array(
    '#type' => 'radios',
    '#title' => t('Provide a user registration form'),
    '#description' => t('Allow users to register or login while making a payment.'),
    '#options' => array(
    'none' => t('No: Transactions will be recorded anonymously.'),
    'optional' => t('Optional: If users do not register or login, their transaction will be recorded anonymously.'),
    'required' => t('Required: Users must register or login and payments will be associated with their account.'),
    ),
    '#default_value' => $this->user_register,
    );
    */
  }

  /**
   * @todo Please document this function.
   * @see http://drupal.org/node/1354
   */
  function pay_methods() {
    $methods = array();
    foreach ($this->pay_methods as $pmid => $status) {
      if ($status && ($pay_method = pay_method_load($pmid))) {
        if ($pay_method
          ->access('default')) {
          $pay_method->pay_form = $this;
          $methods[$pmid] = $pay_method;
        }
      }
    }
    return $methods;
  }

  /**
   * @todo Please document this function.
   * @see http://drupal.org/node/1354
   */
  function pay_method_form(&$form, &$form_state) {
    $group = $this
      ->handler();
    $methods = $this
      ->pay_methods();
    $form[$group]['pay_method']['selected'] = array();
    foreach ($methods as $pmid => $pay_method) {
      $options[$pmid] = $pay_method->title;
      $pay_method
        ->form($form, $form_state);

      // Make sure each payment method has a total.
      if (!isset($form[$group]['pay_method'][$pmid]['total'])) {
        $form[$group]['pay_method'][$pmid]['total'] = array(
          '#type' => 'value',
          '#value' => 0.0,
        );
      }
    }
    $form[$group]['pay_method']['selected'] = array(
      '#type' => 'radios',
      '#options' => $options,
      '#required' => TRUE,
      '#access' => count($methods) > 1,
      '#default_value' => count($methods) == 1 ? $methods : NULL,
    );
  }
  function form(&$form, &$form_state) {
    parent::form($form, $form_state);
    $group = $this
      ->handler();

    // If an amount-only form was submitted, get the amount from $_GET.
    if (isset($_GET[$group]['amount'])) {
      $this
        ->set_amount($_GET[$group]['amount']);
    }
    $form[$group]['total'] = array(
      '#type' => 'textfield',
      '#size' => 6,
      '#title' => t('Amount'),
    );

    // Include a user registration form, if necessary.
    if ($this
      ->user_register()) {
      $required = $this
        ->user_register() == 'required';
      $register = drupal_retrieve_form('user_register', $form_state);
      drupal_prepare_form('user_register', $register, $form_state);
      $exclude = array(
        'form_id',
        '#build_id',
        '#id',
        '#method',
        '#action',
        'submit',
      );
      foreach ($register as $key => $value) {
        if (!in_array($key, $exclude)) {
          if ($key[0] != '#' && is_array($value)) {

            // Manage 'required' if the account registration isn't.
            if (!$required && isset($value['#required'])) {
              $value['#user_register_required'] = $value['#required'];
              unset($value['#required']);
            }

            // Set #parents so that the value can be located by pay.
            $value['#parents'] = array(
              $group,
              'register',
              $key,
            );
          }

          // Add the registration form's field to a user registration element.
          $form[$group]['register'][$key] = $value;
        }
      }
    }

    // Add a payment method selection form.
    $this
      ->pay_method_form($form, $form_state);
    $form[$group]['notes'] = array(
      '#type' => 'textarea',
      '#title' => $this->notes_title,
      '#description' => $this->notes_description,
    );
  }
  function form_alter(&$form, &$form_state) {
    $group = $this
      ->handler();

    // Special handling for "amount-only" forms.
    if ($form_state['pay_form_type'] == 'amount') {
      $visible = array();
      foreach (element_children($form[$group]) as $key) {
        if (!in_array($key, array(
          'amount',
          'amount_other',
          'total',
        ))) {
          $form[$group][$key]['#access'] = FALSE;
        }

        // Keep track of any visible elements.
        if ($form[$group][$key]['#access'] !== FALSE) {
          $visible[] = $key;
        }

        // Change the 'action' to the ultimate destination for the form.
        $form['#action'] = url($this
          ->menu_path());

        // Change the 'method' to GET ...?
        $form['#method'] = 'get';
      }
    }

    // If only one field is visible, hide its label.
    if (isset($visible) && count($visible) == 1) {
      unset($form[$group][$visible[0]]['#title']);
    }
  }
  function form_validate($form, &$form_state) {
    parent::form_validate($form, $form_state);
    $values = $this
      ->form_values($form_state);
    $group = $this
      ->handler();
    if ($this
      ->user_register()) {

      // Copy & overwrite form values so it looks like a user_registration form.
      $register_state = $form_state;
      $register_state['values'] = $values['register'];

      // Execute all of the user_registration form's submit handlers.
      $register = $form[$this
        ->handler()]['register'];
      form_execute_handlers('validate', $register, $register_state);

      // Copy any new $register_state values into $form_state.
      $form_state = array_merge($register_state, $form_state);
    }

    // Remove non-numeric characters from the total.
    $total = (double) preg_replace('/[^\\d\\.]/', '', $values['total']);

    // Confirm that the amount falls within our min/max settings.
    if ($total < $this->min_amount || $total > $this->max_amount) {
      $error = t('Please enter an amount between %min and %max', array(
        '%min' => $this->min_amount,
        '%max' => $this->max_amount,
      ));
      form_set_error('total', $error);
    }

    // If there is no total value per payment method, set the global total.
    foreach ($values['pay_method']['selected'] as $pmid => $status) {
      if (!$status) {
        continue;
      }
      $method_values = $values['pay_method'][$pmid];
      $method_values['pmid'] = $pmid;
      $method_element = $form[$group]['pay_method'][$pmid];
      if (!$method_values['total']) {
        form_set_value($method_element['total'], (double) $total, $form_state);
        $method_values['total'] = $total;
      }
      $pay_method = pay_method_load($method_values);
      $pay_method
        ->pay_method_validate($form, $form_state, $method_element);
    }
  }
  function form_submit($form, &$form_state) {
    global $user;
    parent::form_submit($form, $form_state);
    $values = $this
      ->form_values($form_state);
    if ($this
      ->user_register()) {

      // Copy & overwrite form values so it looks like a user_registration form.
      $register_state = $form_state;
      $register_state['values'] = $values['register'];

      // Execute all of the user_registration form's submit handlers.
      $register = $form[$this
        ->handler()]['register'];
      form_execute_handlers('submit', $register, $register_state);

      // Copy any new $register_state values into $form_state.
      $form_state = array_merge($register_state, $form_state);

      // Did the new user get logged in? If not, we need to temporarily log her
      // in so that the transaction/actions/etc are associated with the account.
      if (!$user->uid && isset($form_state['user'])) {
        $user_anonymous = $user;
        $user = $form_state['user'];
      }
    }

    // Add a new transaction for this form with status as default of 'pending'.
    $transaction = $this
      ->set_transaction($values);

    // Run payment activities for the 1 or more selected payment methods.
    $selected = $values['pay_method']['selected'];
    if (!is_array($selected)) {
      $selected = array(
        $selected => 1,
      );
    }
    foreach ($selected as $pmid => $status) {
      if (!$status) {
        continue;
      }
      $method_values = $values['pay_method'][$pmid];
      $method_values['pmid'] = $pmid;
      $pay_method = pay_method_load($method_values);
      $transaction
        ->save($method_values);
      $activity = $transaction
        ->add_activity($pay_method);
      $activity
        ->do_activity($pay_method->pay_form_action, $method_values);

      // Add this activity to form_state for other modules to use.
      $form_state['pay_activity'][] = $activity;
    }

    // Trigger a special hook if there's a goal amount and we have reached it.
    if ($this
      ->total_goal() && $this
      ->total_paid() >= $this
      ->total_goal()) {
      $this
        ->drupal_invoke('pay_form_goal', $form_state);
    }

    // Leave the user object the way we found it.
    if (isset($user_anonymous)) {
      $user = $user_anonymous;
    }
    unset($form_state['rebuild'], $form_state['storage']);
  }
  function set_menu_path($val = NULL) {
    $this->menu_path = $val;
  }
  function menu_path() {
    return check_plain($this->menu_path);
  }
  function total() {
    return (double) db_query("SELECT SUM(total) as total FROM {pay_transaction} WHERE pfid = :pfid", array(
      ':pfid' => $this->pfid,
    ))
      ->fetchField();
  }
  function total_paid() {
    return (double) db_query("SELECT SUM(total_paid) as total FROM {pay_transaction} WHERE pfid = :pfid", array(
      ':pfid' => $this->pfid,
    ))
      ->fetchField();
  }
  function total_goal() {
    return (double) $this->total_goal;
  }
  function transaction_count() {
    return (int) db_query("SELECT COUNT(*) FROM {pay_transaction} WHERE pfid = :pfid", array(
      ':pfid' => $this->pfid,
    ))
      ->fetchField();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
pay::$permissions property
pay::access function
pay::disable function 1
pay::drupal_invoke function Execute an named Drupal hook function, passing $this as the first parameter.
pay::enable function
pay::form_setup function
pay::form_values function
pay::handler function
pay::handler_title function
pay::notes function
pay::pay_activity function @todo Please document this function.
pay::pay_form function @todo Please document this function.
pay::pay_transaction function @todo Please document this function. 1
pay::permissions_settings function
pay::save function
pay::settings_form_submit function
pay::settings_form_validate function
pay::set_completed function
pay::set_created function
pay::set_handler function
pay::set_hostname function
pay::set_identifer function
pay::set_key function Do not allow this value to be automatically set.
pay::set_mail function
pay::set_notes function
pay::set_status function
pay::set_table function Do not allow this value to be automatically set.
pay::set_timestamp function
pay::set_total function
pay::set_total_paid function
pay::set_uid function
pay::timestamp_value function
pay::uid function
pay::user function
pay::__construct function
pay_form::$currency property
pay_form::$embeddable property
pay_form::$key property Overrides pay::$key
pay_form::$max_amount property
pay_form::$menu_path property
pay_form::$min_amount property
pay_form::$notes_description property
pay_form::$notes_format property
pay_form::$notes_title property
pay_form::$pay_methods property
pay_form::$pfid property
pay_form::$status property
pay_form::$table property Overrides pay::$table
pay_form::$title property
pay_form::$total_goal property
pay_form::$uid property
pay_form::$user_register property
pay_form::currency function
pay_form::currency_list function List of all currencies available for this form.
pay_form::embeddable function
pay_form::form function Overrides pay::form
pay_form::form_alter function
pay_form::form_submit function Overrides pay::form_submit
pay_form::form_validate function Overrides pay::form_validate
pay_form::menu_path function Overrides pay::menu_path
pay_form::pay_methods function @todo Please document this function.
pay_form::pay_method_form function @todo Please document this function.
pay_form::pay_method_list function @todo Please document this function.
pay_form::settings_form function Overrides pay::settings_form
pay_form::set_currency function Set the currency for this payment form.
pay_form::set_embeddable function
pay_form::set_menu_path function
pay_form::set_notes_format function
pay_form::set_transaction function
pay_form::set_user_register function
pay_form::set_valid_actions function Modify the list of payment actions that are valid for a given transaction.
pay_form::title function Overrides pay::title
pay_form::total function Overrides pay::total
pay_form::total_goal function
pay_form::total_paid function
pay_form::transaction_count function
pay_form::user_register function