Skip to content
payment_webform.module 7.3 KiB
Newer Older
Bart Feenstra's avatar
Bart Feenstra committed
<?php

/**
 * @file
 * Hook implementations and shared functions.
/**
 * Implements hook_menu().
 */
function payment_webform_menu() {
  $item['payment_webform/finish'] = array(
    'title' => 'Payment for Webform finished',
    'page callback' => 'payment_webform_page_finish',
    'access callback' => 'payment_webform_page_finish_access',
    'type' => MENU_CALLBACK,
  );
  $item['payment_webform/pay/%node/%'] = array(
    'title' => 'Add a payment reference',
    'title callback' => 'node_page_title', 
    'title arguments' => array(2),
    'page callback' => 'payment_webform_page_payment',
    'page arguments' => array(2, 3),
    'access callback' => 'payment_webform_page_payment_access',
    'access arguments' => array(2, 3),
  );

  return $item;
}

/**
 * Implements hook_page_alter().
 */
function payment_webform_page_alter(&$page) {
  if (arg(0) == 'payment_webform') {
    $skip_regions = array_diff(element_children($page), array('content'));
    foreach ($skip_regions as $skip_region) {
      $page[$skip_region]['#access'] = FALSE;
    }
  }
}

/**
 * Implements hook_payment_line_item_info().
 */
function payment_webform_payment_line_item_info() {
  return array(
    new PaymentLineItemInfo(array(
      'callback' => 'payment_webform_line_item_get_all',
      'name' => 'payment_webform',
      'title' => t('All Payment for Webform items'),
    )),
  );
}

/**
 * Implements hook_webform_select_options_info().
 */
function payment_webform_webform_select_options_info() {
  $options['payment_method'] = array(
    'title' => t('Payment methods'),
    'options callback' => 'payment_method_options',
  );
  $options['payment_status'] = array(
    'title' => t('Payment statuses'),
    'options callback' => 'payment_status_options',
  );

  return $options;
}

/**
 * Implements hook_webform_component_info().
 */
function payment_webform_webform_component_info() {
  $components['payment_webform'] = array(
    'label' => t('Payment reference'),
    'description' => t('Basic textfield type.'),
    'features' => array(
      'default_value' => FALSE,
      'required' => TRUE,
    ),
    'file' => 'payment_webform.webform.inc',
  );

  return $components;
}

/**
 * Implements hook_webform_component_delete().
 */
function payment_webform_webform_component_delete($component) {
  payment_webform_delete_by_cid($component['cid']);
}

/**
 * Implements hook_ENTITY_TYPE_ACTION().
 */
function payment_webform_payment_delete($entity) {
  payment_webform_delete_by_pid($entity->pid);
}

/**
 * Implements PaymentLineItemInfo::callback.
 */
function payment_webform_line_item_get_all($name, Payment $payment) {
  $line_items = array();
  foreach ($payment->line_items as $line_item) {
    if (strpos($line_item->name, 'payment_webform_') === 0) {
      $line_items[$line_item->name] = $line_item;
    }
  }

  return $line_items;
}

/**
 * Load the Webform NID for a Payment.
 *
 * @param integer $pid
 *
 * @return integer|false
 */
function payment_webform_load_nid($pid) {
  return db_query("SELECT nid FROM {webform_component} wc LEFT JOIN {payment_webform} pw ON wc.cid = pw.cid WHERE pw.pid = :pid", array(
    ':pid' => $pid,
  ))->fetchField();
}

/**
 * Loads a PID of a Payment available for referencing.
function payment_webform_load($cid, $uid) {
  $query = db_select('payment_webform', 'pw');
  $query->addJoin('INNER', 'payment', 'p', 'p.pid = pw.pid');
  $query->addJoin('INNER', 'payment_status_item', 'psi', 'p.psiid_last = psi.psiid');
  $query->fields('pw', array('pid'))
    ->condition('status', array_merge(payment_status_info(PAYMENT_STATUS_SUCCESS)->descendants(), array(PAYMENT_STATUS_SUCCESS)))
    ->condition('uid', $uid)
    // Order by pid ASC, so we use the oldest payment first.
    ->orderBy('pid')
    ->range(0, 1);

  return $query->execute()->fetchField();
}

/**
 * Insert a Payment available for referencing through a Webform component.
 *
 * @param integer $cid
 *   The CID of the component the reference is available for.
 * @param integer $pid
 *   The PID of the available payment.
 *
 * @return integer
 *   SAVED_NEW
 */
function payment_webform_insert($cid, $pid) {
  $data = array(
    'pid' => $pid,
  );

  return drupal_write_record('payment_webform', $data);
}

/**
 *
 * @param integer $pid
 */
  db_delete('payment_webform')
    ->condition('pid', $pid)
    ->execute();
}

/**
 * Delete a Payment from the queue by CID.
 *
 * @param integer $cid
 */
function payment_webform_delete_by_cid($cid) {
  db_delete('payment_webform')
    ->condition('cid', $cid)
    ->execute();
}

/**
 * Check if a user has access to the redirect page.
 *
 * @param stdClass $node
 *   The node to which the webform component belongs.
 * @param integer $cid
 *   The ID of the webform component to check access to.
 * @param stdClass|null $account
 *   The account whose access to check. Use NULL to default to the currently
 *   logged in user.
 *
 * @return boolean
 */
function payment_webform_page_payment_access($node, $cid, $account = NULL) {
  global $user;

  if (!$account) {
    $account = $user;
  }

  return node_access('view', $node, $account)
    && isset($node->webform['components'][$cid])
    && !payment_webform_load($cid, $account->uid);
}

/**
 * Return a payment page for a field instance.
 *
 * @param stdClass $node
 * @param integer $cid
 *
 * @return array
 *   A Drupal build array.
 */
function payment_webform_page_payment($node, $cid) {
  $component = $node->webform['components'][$cid];
  $payment = new Payment(array(
    'context' => 'payment_webform_' . $node->nid . '_' . $cid,
    'currency_code' => $component['extra']['payment_currency_code'],
    'description' => $component['extra']['payment_description'],
    'finish_callback' => 'payment_webform_payment_finish',
  ));
  foreach ($component['extra']['payment_line_items'] as $line_item) {
    $line_item->name = 'payment_webform_' . $line_item->name;
    $payment->setLineItem($line_item);
  }

  return drupal_get_form('payment_form_standalone', $payment);
}

/**
 * Implements Payment::finish_callback.
 */
function payment_webform_payment_finish(Payment $payment) {
  payment_webform_insert($payment->context_data['cid'], $payment->pid);
  $_SESSION['payment_webform_pid'] = $payment->pid;
  drupal_goto('payment_webform/finish');
}

/**
 * Menu page callback to call after a payment reference payment has finished.
 *
 * @return integer|array
 */
function payment_webform_page_finish() {
  $pid = $_SESSION['payment_webform_pid'];
  unset($_SESSION['payment_webform_pid']);

  $payment = entity_load_single('payment', $pid);
  $node = node_load(payment_webform_load_nid($pid));
  drupal_set_title(node_page_title($node));
  return array(
    '#type' => 'markup',
    '#markup' => t('Your payment is %status. You can now <span class="paymentreference-window-close">close this window</span>.', array(
      '%status' => payment_status_info($payment->getStatus()->status, TRUE)->title,
    )),
    '#attached' => array(
      'js' => array(drupal_get_path('module', 'paymentreference') . '/js/paymentreference.js'),
    ),
  );
}

/**
 * Check if a user has access to the finish page.
 *
 * @return boolean
 */
function payment_webform_page_finish_access() {
  return isset($_SESSION['payment_webform_pid']) && payment_webform_load_nid($_SESSION['payment_webform_pid']);