<?php

/**
 * @file
 * Written by Henri MEDOT <henri.medot[AT]absyx[DOT]fr>
 * http://www.absyx.fr
 */



require_once dirname(__FILE__) .'/uc_cmcic.inc';
define('UC_CMCIC_URL_CM_TEST', 'https://paiement.creditmutuel.fr/test/paiement.cgi');

/*******************************************************************************
 * Drupal Hooks
 ******************************************************************************/

/**
 * Implementation of hook_menu().
 */
function uc_cmcic_menu() {
  $items['cart/cmcic/response'] = array(
    'title' => 'CM-CIC p@iement response',
    'page callback' => 'uc_cmcic_response',
    'access callback' => 'uc_cmcic_response_access',
    'type' => MENU_CALLBACK,
  );
  $items['cart/cmcic/success'] = array(
    'title' => 'CM-CIC p@iement payment success',
    'page callback' => 'uc_cmcic_success',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
  $items['cart/cmcic/cancel'] = array(
    'title' => 'CM-CIC p@iement payment cancelled',
    'page callback' => 'uc_cmcic_cancel',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
  $items['cart/cmcic/return'] = array(
    'title' => 'CM-CIC p@iement payment return',
    'page callback' => 'uc_cmcic_return',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

// Make sure CM-CIC p@iement always has access to send responses.
function uc_cmcic_response_access() {
  return TRUE;
}



/*******************************************************************************
 * Ubercart Hooks
 ******************************************************************************/

/**
 * Implementation of hook_uc_payment_method().
 */
function uc_cmcic_uc_payment_method() {
  $title = variable_get('uc_cmcic_method_title', t('Credit card with CM-CIC p@iement'))
    .'<br />'. theme('image', array('path' => drupal_get_path('module', 'uc_cmcic') .'/images/logo_cm-paiement-pt.jpg'));

  $methods['cmcic'] = array(
    'name' => t('CM-CIC p@iement'),
    'title' => $title,
    'desc' => t('Redirect users to submit payments through CM-CIC p@iement.'),
    'callback' => 'uc_payment_method_cmcic',
    'redirect' => 'uc_cmcic_form',
    'weight' => 3,
    'checkout' => TRUE,
    'no_gateway' => TRUE,
  );

  return $methods;
}



/*******************************************************************************
 * Callback and Helper Functions
 ******************************************************************************/

/**
 * Add CM-CIC p@iement settings to the payment method settings form.
 */
function uc_payment_method_cmcic($op, &$arg1) {
  switch ($op) {
    case 'settings':
      $form['uc_cmcic_url'] = array(
        '#type' => 'textfield',
        '#title' => t('CM-CIC p@iement URL'),
        '#description' => t('The URL to the CM-CIC p@iement payment platform.'),
        '#default_value' => variable_get('uc_cmcic_url', UC_CMCIC_URL_CM_TEST),
      );
      $form['uc_cmcic_tpe'] = array(
        '#type' => 'textfield',
        '#title' => t('POS terminal number'),
        '#description' => t('The 7-character virtual POS terminal number your site was assigned when subscribing to CM-CIC p@iement.'),
        '#default_value' => variable_get('uc_cmcic_tpe', ''),
        '#size' => 10,
        '#maxlength' => 7,
      );
      $form['uc_cmcic_key'] = array(
        '#type' => 'textfield',
        '#title' => t('Merchant security key'),
        '#description' => t('The 40-character key your site was assigned when subscribing to CM-CIC p@iement.'),
        '#default_value' => variable_get('uc_cmcic_key', ''),
        '#maxlength' => 40,
      );
      $form['uc_cmcic_site_code'] = array(
        '#type' => 'textfield',
        '#title' => t('Site code'),
        '#description' => t('The 20-character code your site was assigned when subscribing to CM-CIC p@iement.'),
        '#default_value' => variable_get('uc_cmcic_site_code', ''),
        '#size' => 25,
        '#maxlength' => 20,
      );
      $form['uc_cmcic_response_url'] = array(
        '#type' => 'item',
        '#title' => t('Return interface URL'),
        '#markup' => url('cart/cmcic/response', array('absolute' => TRUE)),
        '#description' => 'You have to provide your bank with this URL for CM-CIC p@iement to function properly.',
      );
      return $form;
  }
}



/**
 * Form to build the submission to CM-CIC p@iement.
 */
function uc_cmcic_form($form, &$form_state, $order) {
  global $language;

  $fields = array(
    'TPE' => variable_get('uc_cmcic_tpe', ''),
    'date' => date('d/m/Y:H:i:s', time()),
    'montant' => round($order->order_total, 2) . variable_get('uc_currency_code', 'USD'),
    'reference' => $order->order_id,
    'texte-libre' => md5(uniqid(rand(), TRUE)),
    'mail' => $order->primary_email,
    'lgue' => in_array(strtoupper($language->language), uc_cmcic_languages()) ? strtoupper($language->language) : 'EN',
    'societe' => variable_get('uc_cmcic_site_code', ''),
    'url_retour' => url('cart/cmcic/cancel', array('absolute' => TRUE)),
    'url_retour_ok' => url('cart/cmcic/success', array('absolute' => TRUE)),
    'url_retour_err' => url('cart/cmcic/return', array('absolute' => TRUE)),
  );
  $fields = uc_cmcic_complete_request(variable_get('uc_cmcic_key', ''), $fields);

  // Add the transaction ID to the order's data array.
  $order->data['cmcic']['texte-libre'] = $fields['texte-libre'];

  // Save the updated data array to the database.
  uc_cmcic_save_order_data($order);

  $form['#action'] = variable_get('uc_cmcic_url', UC_CMCIC_URL_CM_TEST);

  foreach ($fields as $name => $value) {
    $form[$name] = array('#type' => 'hidden', '#value' => $value);
  }

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit order'),
  );

  return $form;
}



/**
 * Save order's updated data array to the database.
 */
function uc_cmcic_save_order_data($order) {
  db_update('uc_orders')
    ->fields(array('data' => serialize($order->data)))
    ->condition('order_id', $order->order_id)
    ->execute();
}



/**
 * Handle an incoming payment.
 */
function uc_cmcic_response() {
  if (empty($_POST)) {
    watchdog('uc_cmcic', 'Response attempted without any POST data.', array(), WATCHDOG_WARNING);
    return;
  }

  unset($mac_ok);
  $order = uc_cmcic_get_order($mac_ok);
  if (!$order) {
    watchdog('uc_cmcic', 'Invalid response.', array(), WATCHDOG_ERROR);
    uc_cmcic_receipt_exit($mac_ok);
  }

  $order_id = $order->order_id;
  if (($_POST['code-retour'] != 'paiement') && ($_POST['code-retour'] != 'payetest')) {
    uc_order_comment_save($order_id, 0, t("The customer's attempted payment from a bank account may have failed. Authorisation result is @result.", array('@result' => $_POST['motifrefus'])), 'admin');
    uc_cmcic_receipt_exit(TRUE);
  }

  $amount = substr($_POST['montant'], 0, -3);
  $currency = substr($_POST['montant'], -3);

  $comment = t('CM-CIC p@iement authorisation #: @number', array('@number' => $_POST['numauto']));
  uc_payment_enter($order_id, 'cmcic', $amount, $order->uid, $_POST, $comment);
  uc_cart_complete_sale($order);

  uc_order_comment_save($order_id, 0, t('Payment of @amount @currency submitted through CM-CIC p@iement.', array('@amount' => uc_currency_format($amount, FALSE), '@currency' => $currency)), 'order', 'payment_received');
  uc_order_comment_save($order_id, 0, t('CM-CIC p@iement response reported a payment of @amount @currency.', array('@amount' => uc_currency_format($amount, FALSE), '@currency' => $currency)));

  uc_cmcic_receipt_exit(TRUE);
}

// Return the receipt to the bank then exit cleanly.
function uc_cmcic_receipt_exit($mac_ok) {
  print uc_cmcic_receipt($mac_ok);
  module_invoke_all('exit');
  exit;
}



/**
 * Handle a successful payment.
 */
function uc_cmcic_success() {
  if (empty($_SESSION['cart_order'])) {
    drupal_goto('cart');
  }

  // This lets us know it's a legitimate access of the complete page.
  $_SESSION['uc_checkout'][$_SESSION['cart_order']]['do_complete'] = TRUE;

  drupal_goto('cart/checkout/complete');
}



/**
 * Handle a cancelled payment.
 */
function uc_cmcic_cancel() {
  unset($_SESSION['cart_order']);

  drupal_set_message(t('Your payment was cancelled. Please feel free to continue shopping or contact us for assistance.'));

  drupal_goto('cart');
}



/**
 * Handle an unsuccessful payment.
 */
function uc_cmcic_return() {
  unset($_SESSION['cart_order']);

  drupal_set_message(t('Sorry, your payment could not be processed. Please try again or contact us for assistance.'));

  drupal_goto('cart');
}



function uc_cmcic_get_order(&$mac_ok) {
  $mac_ok = FALSE;
  if (!uc_cmcic_validate_response(variable_get('uc_cmcic_key', ''), $_POST)) {
    return FALSE;
  }

  $mac_ok = TRUE;
  if (isset($_POST['reference']) && ($order = uc_order_load(intval($_POST['reference'])))) {
    if (isset($order->data['cmcic']['texte-libre']) && ($_POST['texte-libre'] == $order->data['cmcic']['texte-libre'])) {
      return $order;
    }
  }

  return FALSE;
}
