You are here

uc_coupon_purchase.module in Ubercart Discount Coupons 6

File

uc_coupon_purchase/uc_coupon_purchase.module
View source
<?php

require_once 'uc_coupon_purchase.ca.inc';

/**
 * Implementation of hook_perm().
 */
function uc_coupon_purchase_perm() {
  return array(
    'view purchased coupons',
  );
}

/**
 * Implementation of hook_menu().
 */
function uc_coupon_purchase_menu() {
  $items = array();
  $items['user/%user/coupons'] = array(
    'title' => 'Coupons',
    'description' => 'View your purchased coupons.',
    'page callback' => 'uc_coupon_purchase_view',
    'access callback' => 'uc_coupon_purchase_can_view',
    'page arguments' => array(
      1,
    ),
    'access arguments' => array(
      1,
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'uc_coupon_purchase.pages.inc',
    'weight' => 5,
  );
  $items['user/%user/coupons/%uc_coupon'] = array(
    'title' => 'Print preview',
    'page callback' => 'uc_coupon_purchase_print',
    'access callback' => 'uc_coupon_purchase_can_view',
    'page arguments' => array(
      1,
      3,
    ),
    'access arguments' => array(
      1,
      3,
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'uc_coupon_purchase.pages.inc',
    'weight' => 5,
  );
  $items['user/%user/coupons/%uc_coupon/codes'] = array(
    'title' => 'Download codes',
    'page callback' => 'uc_coupon_codes_csv',
    'access callback' => 'uc_coupon_purchase_can_view',
    'page arguments' => array(
      3,
    ),
    'access arguments' => array(
      1,
      3,
    ),
    'type' => MENU_CALLBACK,
    'file' => 'uc_coupon.admin.inc',
    'file path' => drupal_get_path('module', 'uc_coupon'),
    'weight' => 5,
  );
  return $items;
}

/**
 * Access callback for user/%/coupons.
 * 
 * User must have "view purchased coupons" permission, current user must have a
 * coupon to view, other users must have "administer users" permission.
 *
 * If a coupon is specified, user must have purchased that coupon.
 */
function uc_coupon_purchase_can_view($account, $coupon = NULL) {
  global $user;
  if (user_access('view purchased coupons')) {
    if (user_access('administer users') || $account->uid == $user->uid && uc_coupon_purchase_has_coupon($account, $coupon)) {
      return TRUE;
    }
  }
  return FALSE;
}

/*
 * Implementation of hook_uc_coupon_actions for purchased coupons
 */
function uc_coupon_purchase_uc_coupon_actions($coupon) {
  $actions = array();
  if (!user_access('manage store coupons')) {
    global $user;
    $account = arg(0) == 'user' ? user_load(arg(1)) : $user;
    if (uc_coupon_purchase_can_view($account, $coupon)) {
      $actions[] = array(
        'url' => "user/{$account->uid}/coupons/{$coupon->cid}/view",
        'icon' => drupal_get_path('module', 'uc_store') . '/images/order_view.gif',
        'title' => t('View coupon: @name', array(
          '@name' => $coupon->name,
        )),
      );
      $actions[] = array(
        'url' => "user/{$account->uid}/coupons/{$coupon->cid}/print",
        'icon' => drupal_get_path('module', 'uc_store') . '/images/print.gif',
        'title' => t('Print coupon: @name', array(
          '@name' => $coupon->name,
        )),
      );
      if ($coupon->bulk) {
        $actions[] = array(
          'url' => 'admin/store/coupons/' . $coupon->cid . '/codes',
          'icon' => drupal_get_path('module', 'uc_store') . '/images/menu_reports_small.gif',
          'title' => t('Download codes as CSV: @name', array(
            '@name' => $coupon->name,
          )),
        );
      }
    }
  }
  return $actions;
}

/**
 * Check whether a given user has purchased any coupon, or the specific supplied coupon.
 */
function uc_coupon_purchase_has_coupon($account, $coupon = NULL) {
  $sql = 'SELECT COUNT(*) FROM {uc_coupon_purchase_users} WHERE uid = %d';

  // Make sure coupon is valid before looking for it.
  if (!empty($coupon) && !empty($coupon->cid)) {
    $sql .= ' AND cid = %d';
    $coupon = $coupon->cid;
  }
  return db_result(db_query($sql, $account->uid, $coupon));
}

/**
 * Implementation of hook_product_feature().
 */
function uc_coupon_purchase_product_feature() {
  $features[] = array(
    'id' => 'coupon',
    'title' => t('Coupon creation'),
    'callback' => 'uc_coupon_purchase_feature_form',
    'delete' => 'uc_coupon_purchase_feature_delete',
    'settings' => 'uc_coupon_purchase_feature_settings',
  );
  return $features;
}

/**
 * Form builder for hook_product_feature().
 */
function uc_coupon_purchase_feature_form($form_state, $node, $feature) {
  $models = array(
    NULL => t('Any'),
    $node->model => $node->model,
  );
  if (module_exists('uc_attribute')) {
    $adjustments = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = %d", $node->nid);
    while ($adjustment = db_fetch_object($adjustments)) {
      if (!in_array($adjustment->model, $models)) {
        $models[$adjustment->model] = $adjustment->model;
      }
    }
  }
  if (!empty($feature)) {
    $data = db_fetch_object(db_query("SELECT * FROM {uc_coupon_purchase} WHERE pfid = %d", $feature['pfid']));
    $form['pfid'] = array(
      '#type' => 'value',
      '#value' => $feature['pfid'],
    );
  }
  else {
    $data = new stdClass();
  }
  $coupons = array();
  $result = db_query("SELECT cid, name, code FROM {uc_coupons} WHERE status = 0");
  while ($coupon = db_fetch_object($result)) {
    $coupons[$coupon->cid] = $coupon->name . ' (' . $coupon->code . ')';
  }
  if (!$coupons) {
    drupal_set_message(t('No inactive coupons found. Please <a href="!url">create an inactive coupon</a> to use as a base coupon for purchases.', array(
      '!url' => url('admin/store/coupons/add'),
    )), 'error');
    drupal_goto('node/' . arg(1) . '/edit/features');
  }
  $form['title'] = array(
    '#type' => 'markup',
    '#value' => '<h2>' . t('Coupon creation') . '</h2>',
  );
  $form['nid'] = array(
    '#type' => 'value',
    '#value' => $node->nid,
  );
  $form['model'] = array(
    '#type' => 'select',
    '#title' => t('Model/SKU'),
    '#default_value' => $data->model,
    '#description' => t('Select the model/SKU of the product that cause a coupon to be created.'),
    '#options' => $models,
  );
  $form['base_cid'] = array(
    '#type' => 'select',
    '#title' => t('Base coupon'),
    '#default_value' => $data->base_cid,
    '#description' => t('Select the coupon that will be cloned when a user purchases this product. Only inactive coupons are listed; the purchased coupon will automatically be activated.'),
    '#options' => $coupons,
  );
  return uc_product_feature_form($form);
}
function uc_coupon_purchase_feature_form_submit($form, &$form_state) {
  $coupon = uc_coupon_load($form_state['values']['base_cid']);
  $description = empty($form_state['values']['model']) ? t('<strong>SKU:</strong> Any<br/>') : t('<strong>SKU:</strong> !sku<br/>', array(
    '!sku' => $form_state['values']['model'],
  ));
  $description .= t('<strong>Base coupon:</strong> !coupon<br/>', array(
    '!coupon' => $coupon->name . ' (' . $coupon->code . ')',
  ));
  $data = array(
    'pfid' => $form_state['values']['pfid'],
    'nid' => $form_state['values']['nid'],
    'fid' => 'coupon',
    'description' => $description,
  );
  $form_state['redirect'] = uc_product_feature_save($data);
  if ($form_state['values']['pfid'] == 0) {
    $pfid = db_last_insert_id('uc_product_features', 'pfid');
  }
  else {
    $pfid = $form_state['values']['pfid'];
    db_query("DELETE FROM {uc_coupon_purchase} WHERE pfid = %d", $pfid);
  }
  db_query("INSERT INTO {uc_coupon_purchase} (pfid, nid, model, base_cid) VALUES (%d, %d, '%s', %d)", $pfid, $form_state['values']['nid'], $form_state['values']['model'], $form_state['values']['base_cid']);
}

/**
 * Delete callback for product feature.
 */
function uc_coupon_purchase_feature_delete($pfid) {
  db_query("DELETE FROM {uc_coupon_purchase} WHERE pfid = %d", $pfid);
}

/**
 * Form builder for feature settings.
 */
function uc_coupon_purchase_feature_settings() {
  foreach (uc_order_status_list('general') as $status) {
    $statuses[$status['id']] = $status['title'];
  }
  $form['uc_coupon_purchase_order_status'] = array(
    '#type' => 'select',
    '#title' => t('Order status'),
    '#default_value' => variable_get('uc_coupon_purchase_order_status', 'completed'),
    '#description' => t('Select the order status that will cause the coupon to be created. Be aware that if payments are processed automatically, this happens before anonymous customers have an account created. This order status should not be reached before the user account exists.'),
    '#options' => $statuses,
  );
  return $form;
}

/**
 * Implementation of hook_uc_message().
 */
function uc_coupon_purchase_uc_message() {
  $messages['uc_coupon_purchase_single_subject'] = t('[store-name]: coupon purchase');
  $messages['uc_coupon_purchase_single_message'] = t("[order-first-name] [order-last-name], \n\nThanks to your order, [order-link], at [store-name] you now have a new coupon available to use with the code [coupon-code].\n\nThanks again, \n\n[store-name]\n[site-slogan]");
  $messages['uc_coupon_purchase_bulk_subject'] = t('[store-name]: bulk coupon purchase');
  $messages['uc_coupon_purchase_bulk_message'] = t("[order-first-name] [order-last-name], \n\nThanks to your order, [order-link], at [store-name] you now have a new set of coupons available to use with the following codes:\n\n[coupon-bulk-codes]\n\nThanks again, \n\n[store-name]\n[site-slogan]");
  return $messages;
}

/**
 * Implementation of hook_form_FORM_ID_alter() for uc_coupon_add_form().
 *
 * Modify the coupon add form to include coupon purchase options.
 */
function uc_coupon_purchase_form_uc_coupon_add_form_alter(&$form) {
  $value = $form['#uc_coupon'];
  $form['uc_coupon_purchase'] = array(
    '#type' => 'fieldset',
    '#title' => t('Coupon purchase options'),
    '#description' => t('These settings alter the generation of purchased coupons based on this coupon.'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#weight' => -1,
  );
  $form['uc_coupon_purchase']['purchase_suffix_length'] = array(
    '#type' => 'select',
    '#title' => t('Purchased coupon code suffix length'),
    '#default_value' => isset($value->data['purchase_suffix_length']) ? $value->data['purchase_suffix_length'] : 12,
    '#description' => t('A random string of at least this many characters will be appended to the base coupon code to ensure uniqueness.'),
    '#options' => drupal_map_assoc(range(4, 30)),
  );
  $form['uc_coupon_purchase']['purchase_relative'] = array(
    '#type' => 'checkbox',
    '#title' => t('Alter coupon date restrictions relative to the purchase date.'),
    '#description' => t('Checking this box will make purchased coupons valid for the same time span as the base coupon, otherwise coupons will always be valid between the same dates.'),
    '#default_value' => isset($value->data['purchase_relative']) ? $value->data['purchase_relative'] : FALSE,
  );
  $form['status']['#description'] .= '<br />' . t('Only inactive coupons can be selected as the base for a purchased coupon, subsequent purchased coupons will automatically be activated.');
  $form['#validate'][] = 'uc_coupon_purchase_uc_coupon_add_form_validate';
}
function uc_coupon_purchase_uc_coupon_add_form_validate($form, &$form_state) {
  if ($form_state['values']['purchase_relative'] && !$form_state['values']['use_validity']) {
    form_set_error('purchase_relative', t('You must specify date restrictions to use the relative date feature with purchased coupons.'));
  }
}

/**
 * Implementation of hook_uc_coupon_presave().
 */
function uc_coupon_purchase_uc_coupon_presave(&$coupon, $edit) {
  if (isset($edit['purchase_suffix_length'])) {
    $coupon->data['purchase_suffix_length'] = $edit['purchase_suffix_length'];
  }
  if (isset($edit['purchase_relative']) && $edit['purchase_relative']) {
    $coupon->data['purchase_relative'] = TRUE;
  }
}

/**
 * Implementation of hook_uc_coupon_delete().
 */
function uc_coupon_purchase_uc_coupon_delete($coupon) {
  db_query('DELETE FROM {uc_coupon_purchase_users} WHERE cid = %d', $coupon->cid);
}

/**
 * Implementation of hook_order().
 */
function uc_coupon_purchase_order($op, $order, $status) {
  switch ($op) {
    case 'update':
      if ($status == variable_get('uc_coupon_purchase_order_status', 'completed') && $order->order_status != $status && $order->uid > 0 && ($order_user = user_load(array(
        'uid' => $order->uid,
      ))) !== FALSE) {
        foreach ($order->products as $product) {
          $result = db_query("SELECT * FROM {uc_coupon_purchase} WHERE nid = %d", $product->nid);
          while ($row = db_fetch_object($result)) {
            if ($row->model == $product->model || empty($row->model)) {
              $coupon = uc_coupon_load($row->base_cid);

              // Append purchaser data to the coupon name.
              $purchaser = $order->billing_company ? $order->billing_company : $order->billing_first_name . ' ' . $order->billing_last_name;
              $coupon->name .= ' ' . t('purchased by !name', array(
                '!name' => $purchaser,
              ));
              $coupon->data['order_id'] = $order->order_id;

              // Create new coupon and link to purchaser.
              $new_coupon = uc_coupon_purchase_create($coupon, $product->qty, $order->uid);
              uc_order_comment_save($order->order_id, 0, t('Coupon created with code %code.', array(
                '%code' => $new_coupon->code,
              )));

              // Fire hook and conditional actions to send emails for this coupon purchase.
              module_invoke_all('uc_coupon_purchase', $order, $new_coupon);
              ca_pull_trigger('uc_coupon_purchase', $order, $new_coupon);
            }
          }
        }
      }
      break;
  }
}

/**
 * Create newly purchased coupons, based on the supplied coupon object.
 */
function uc_coupon_purchase_create($coupon, $qty, $uid = NULL) {
  $suffix_length = isset($coupon->data['purchase_suffix_length']) ? $coupon->data['purchase_suffix_length'] : 12;

  // If more than one coupon will be generated, ensure it is a bulk coupon.
  if ($qty > 1 || $coupon->bulk) {
    $coupon->bulk = TRUE;
    if (!isset($coupon->data['bulk_number'])) {
      $coupon->data['bulk_number'] = 1;
    }
    $coupon->data['bulk_number'] *= $qty;
    if (!isset($coupon->data['bulk_length'])) {
      $coupon->data['bulk_length'] = 8;
    }

    // Adjust the suffix so single and bulk coupons are the same length where possible.
    $suffix_length = max($suffix_length - $coupon->data['bulk_length'], 4);
  }

  // Adjust the validity dates.
  if (isset($coupon->data['purchase_relative'])) {
    $diff = $coupon->valid_until - $coupon->valid_from;
    $coupon->valid_from = gmmktime();
    $coupon->valid_until = $coupon->valid_from + $diff;
  }

  // Create a new, active coupon with the suffix applied.
  $coupon->data['base_cid'] = $coupon->cid;
  unset($coupon->cid);
  $coupon->code .= strtoupper(user_password($suffix_length));
  $coupon->status = TRUE;
  uc_coupon_save($coupon);

  // Associate this coupon with its owner.
  if (!is_null($uid)) {
    db_query("INSERT INTO {uc_coupon_purchase_users} (uid, cid) VALUES (%d, %d)", $uid, $coupon->cid);
  }
  return $coupon;
}

/**
 * Implementation of hook_views_api()
 */
function uc_coupon_purchase_views_api() {
  return array(
    'api' => '2.0',
    'path' => drupal_get_path('module', 'uc_coupon_purchase') . '/views',
  );
}

Functions

Namesort descending Description
uc_coupon_purchase_can_view Access callback for user/%/coupons.
uc_coupon_purchase_create Create newly purchased coupons, based on the supplied coupon object.
uc_coupon_purchase_feature_delete Delete callback for product feature.
uc_coupon_purchase_feature_form Form builder for hook_product_feature().
uc_coupon_purchase_feature_form_submit
uc_coupon_purchase_feature_settings Form builder for feature settings.
uc_coupon_purchase_form_uc_coupon_add_form_alter Implementation of hook_form_FORM_ID_alter() for uc_coupon_add_form().
uc_coupon_purchase_has_coupon Check whether a given user has purchased any coupon, or the specific supplied coupon.
uc_coupon_purchase_menu Implementation of hook_menu().
uc_coupon_purchase_order Implementation of hook_order().
uc_coupon_purchase_perm Implementation of hook_perm().
uc_coupon_purchase_product_feature Implementation of hook_product_feature().
uc_coupon_purchase_uc_coupon_actions
uc_coupon_purchase_uc_coupon_add_form_validate
uc_coupon_purchase_uc_coupon_delete Implementation of hook_uc_coupon_delete().
uc_coupon_purchase_uc_coupon_presave Implementation of hook_uc_coupon_presave().
uc_coupon_purchase_uc_message Implementation of hook_uc_message().
uc_coupon_purchase_views_api Implementation of hook_views_api()