You are here

function uc_coupon_add_form in Ubercart Discount Coupons 7.3

Same name and namespace in other branches
  1. 5 uc_coupon.module \uc_coupon_add_form()
  2. 6 uc_coupon.admin.inc \uc_coupon_add_form()
  3. 7.2 uc_coupon.admin.inc \uc_coupon_add_form()

Coupon add/edit form.

Parameters

$coupon object: Coupon object, or NULL to add a new coupon.

2 string references to 'uc_coupon_add_form'
UcCouponTestCase::createCoupon in tests/uc_coupon.test
uc_coupon_menu in ./uc_coupon.module
Implements hook_menu().

File

./uc_coupon.admin.inc, line 245
Discount Coupons administration pages.

Code

function uc_coupon_add_form($form, &$form_state, $coupon = NULL) {
  _uc_coupon_paypal_check();
  drupal_add_css(drupal_get_path('module', 'uc_coupon') . '/uc_coupon.css');
  drupal_add_js(drupal_get_path('module', 'uc_coupon') . '/uc_coupon.admin.js');
  if ($coupon) {
    $value = $coupon;
    $usage = uc_coupon_count_usage($coupon->cid);
    $used = array_sum($usage['codes']);
    $form['#uc_coupon_cid'] = $value->cid;
    $form['#uc_coupon'] = $value;
    $form['#uc_coupon_used'] = $used;
    $use_validity = $value->valid_until;
  }
  else {
    $use_validity = FALSE;
    $value = new stdClass();
    $value->minimum_order = 0;
    $value->data['apply_to'] = 'subtotal';
    $value->max_uses = variable_get('uc_coupon_default_usage', 'single') == 'single' ? 1 : 0;
    $used = 0;
  }
  if (!$use_validity) {
    $value->valid_from = REQUEST_TIME;
    $value->valid_until = REQUEST_TIME;
  }

  // Handle AJAX functionality.
  $ajax_fields = array(
    'products' => 'admin/store/coupons/autocomplete/node',
    'skus' => '',
    'terms' => 'admin/store/coupons/autocomplete/term',
    'users' => 'admin/store/coupons/autocomplete/user',
    'roles' => 'admin/store/coupons/autocomplete/role',
  );
  if (empty($form_state['ajax_submission'])) {

    // Set the initial field count.
    foreach (array_keys($ajax_fields) as $field) {
      $form_state['storage']['field_count'][$field] = isset($value->data[$field]) ? count($value->data[$field]) + 3 : 3;
    }
  }
  else {

    // Use data from the AJAX submission.
    $value->data = $form_state['coupon_data'];

    // Increase the count for the selected field.
    $form_state['storage']['field_count'][$form_state['ajax_submission']] += 3;

    // Reset form action, otherwise validation errors go wrong.
    $form['#action'] = $form_state['action'];
  }
  foreach (array_keys($ajax_fields) as $field) {
    if (!isset($value->data[$field])) {
      $value->data[$field] = array();
    }
  }
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Coupon name'),
    '#default_value' => isset($value->name) ? $value->name : '',
    '#required' => TRUE,
    '#weight' => -15,
  );
  $form['code'] = array(
    '#type' => 'textfield',
    '#title' => t('Coupon code'),
    '#description' => t('Coupon codes cannot be changed once they have been used in an order.'),
    '#default_value' => isset($value->code) ? $value->code : '',
    '#size' => 25,
    '#required' => !$used,
    '#maxlength' => 50,
    '#disabled' => $used,
    '#weight' => -10,
  );
  $form['bulk'] = array(
    '#type' => 'fieldset',
    '#title' => t('Bulk coupon codes'),
    '#description' => t('The coupon code entered above will be used to prefix each generated code.'),
    '#collapsible' => TRUE,
    '#collapsed' => isset($value->bulk) ? !$value->bulk : TRUE,
    '#weight' => -5,
  );
  $form['bulk']['bulk_generate'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable bulk generation of coupon codes.'),
    '#default_value' => isset($value->bulk) ? $value->bulk : FALSE,
    '#disabled' => $used,
  );
  $form['bulk']['bulk_number'] = array(
    '#type' => 'textfield',
    '#title' => t('Number of codes to generate'),
    '#default_value' => isset($value->data['bulk_number']) ? $value->data['bulk_number'] : NULL,
    '#size' => 10,
    '#maxlength' => 10,
    '#description' => $used ? t('You cannot decrease this number, because this coupon has already been used.') : '',
  );
  $form['bulk']['bulk_length'] = array(
    '#type' => 'select',
    '#title' => t('Code length'),
    '#description' => t('The number of characters selected here will be appended to the code entered above when generating bulk coupons.'),
    '#default_value' => isset($value->data['bulk_length']) ? $value->data['bulk_length'] : NULL,
    '#options' => drupal_map_assoc(range(8, 30)),
    '#disabled' => $used,
  );
  $form['status'] = array(
    '#type' => 'checkbox',
    '#title' => t('Coupon is active.'),
    '#description' => t('Only active coupons can be used at checkout.'),
    '#default_value' => isset($value->status) ? $value->status : FALSE,
  );
  $form['discount'] = array(
    '#type' => 'textfield',
    '#title' => t('Discount'),
    '#default_value' => isset($coupon->value) ? _uc_coupon_format_discount($value, FALSE) : '',
    '#size' => 6,
    '#description' => t('Four discount types are possible:') . theme('item_list', array(
      'items' => array(
        t('Fixed value discount; enter "15" for @p off.', array(
          '@p' => uc_currency_format(15),
        )),
        t('Store credit coupons; enter "15" and check the box below for store credit of @p.', array(
          '@p' => uc_currency_format(15),
        )),
        t('Percentage discount; enter "15%" for 15% off.'),
        t('Set product price; enter "=15" to make all matching products @p after discount.', array(
          '@p' => uc_currency_format(15),
        )),
      ),
    )),
    '#field_prefix' => variable_get('uc_sign_after_amount', FALSE) ? '' : variable_get('uc_currency_sign', '$'),
    '#field_suffix' => variable_get('uc_sign_after_amount', FALSE) ? variable_get('uc_currency_sign', '$') : '',
    '#required' => TRUE,
  );
  $form['store_credit'] = array(
    '#type' => 'checkbox',
    '#title' => t('Store Credit'),
    '#default_value' => !empty($value->type) && $value->type === 'credit' ? 1 : 0,
    '#description' => t('When checked, the coupon value is applied cumulatively across multiple orders,
          and the coupon is valid until this has been exhausted. There are no additional limits
          on the number of times the coupon can be used. Usage is always reckoned per-code,
          (i.e., each bulk code is good for the full face value of the coupon).  '),
    '#prefix' => '<div id="store-credit-wrapper">',
    '#suffix' => '</div>',
  );
  $form['apply_to'] = array(
    '#type' => 'radios',
    '#title' => t('Apply discount to'),
    '#options' => array(
      'subtotal' => t('Order subtotal.'),
      'products_total' => t('Total of all matching products and line items.'),
      'products' => t('All matching products and line items.  Face value will be applied to each.'),
      'cheapest' => t('The cheapest matching products and all matching line items.  Face value will be applied to each.'),
      'expensive' => t('The most expensive matching products and all matching line items. Face value will be applied to each.'),
    ),
    '#description' => t('Coupons with no restrictions (as specified below) will match all products. However, you must explicitly specify any line items you wish to discount.'),
    '#default_value' => $value->data['apply_to'],
  );
  $form['apply_count'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum number of products to discount'),
    '#description' => t('Note: this number applies only to products. Applicable line items (as specified below) will always be discounted.'),
    '#default_value' => isset($value->data['apply_count']) ? $value->data['apply_count'] : '',
    '#size' => 5,
  );
  $form['require_match_all'] = array(
    '#type' => 'checkbox',
    '#title' => t('Require all products to match'),
    '#default_value' => isset($value->data['require_match_all']) ? TRUE : FALSE,
    '#description' => t('If checked, the coupon will be rejected if an order contains any non-applicable products as configured below.'),
  );
  $form['date_restrictions'] = array(
    '#type' => 'fieldset',
    '#title' => t('Date restrictions'),
    '#collapsible' => TRUE,
    '#collapsed' => $use_validity == 0,
  );
  $form['date_restrictions']['use_validity'] = array(
    '#type' => 'checkbox',
    '#title' => t('Restrict coupon by date.'),
    '#default_value' => $use_validity != 0,
  );
  $zone = variable_get('uc_coupon_expiry_timezone', 0) ? '(local time)' : '(UTC)';
  $hour = _uc_coupon_format_hour(variable_get('uc_coupon_expiry_hour', 0));
  $link = l('store-wide coupon settings page', 'admin/store/settings/coupon', array(
    'query' => array(
      'destination' => $_GET['q'],
    ),
  ));
  $form['date_restrictions']['valid_from'] = array(
    '#type' => 'date',
    '#title' => t('Start date'),
    '#default_value' => array(
      'year' => _uc_coupon_format_date($value->valid_from, 'Y'),
      'month' => _uc_coupon_format_date($value->valid_from, 'n'),
      'day' => _uc_coupon_format_date($value->valid_from, 'j'),
    ),
    '#description' => t('Coupon will activate at @hour @zone on the specified date. The time/zone may be changed on the !link', array(
      '@hour' => $hour,
      '@zone' => $zone,
      '!link' => $link,
    )),
    '#after_build' => array(
      '_uc_coupon_date_range',
    ),
  );
  $form['date_restrictions']['valid_until'] = array(
    '#type' => 'date',
    '#title' => t('Expiry date'),
    '#default_value' => array(
      'year' => _uc_coupon_format_date($value->valid_until, 'Y'),
      'month' => _uc_coupon_format_date($value->valid_until, 'n'),
      'day' => _uc_coupon_format_date($value->valid_until, 'j'),
    ),
    '#description' => t('Coupon will expire at @hour @zone on the specified date. The time/zone may be changed on the !link', array(
      '@hour' => $hour,
      '@zone' => $zone,
      '!link' => $link,
    )),
    '#after_build' => array(
      '_uc_coupon_date_range',
    ),
  );
  $form['usage_limits'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => empty($value->max_uses) && empty($value->data['max_uses_per_user']),
    '#title' => t('Coupon usage limits'),
    '#tree' => FALSE,
  );
  $form['usage_limits']['max_uses'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum number of redemptions (per code)'),
    '#default_value' => $value->max_uses ? $value->max_uses : '',
    '#description' => t('If set, the coupon can only be used this number of times. For bulk coupons, this applies to each available code.'),
    '#size' => 5,
  );
  $form['usage_limits']['max_uses_per_user'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum number of redemptions (per user)'),
    '#default_value' => isset($value->data['max_uses_per_user']) ? $value->data['max_uses_per_user'] : '',
    '#description' => t('If set, each user can only use the coupon this number of times.'),
    '#size' => 5,
  );
  $form['order'] = array(
    '#type' => 'fieldset',
    '#title' => t('Minimum order limits'),
    '#collapsible' => TRUE,
    '#collapsed' => $value->minimum_order < 0.01 && !isset($value->data['minimum_qty']),
  );
  $form['order']['minimum_order'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum order total'),
    '#default_value' => $value->minimum_order < 0.01 ? '' : $value->minimum_order,
    '#size' => 6,
    '#description' => t('If set, the subtotal of products must be at least this amount for the coupon to be accepted.'),
    '#field_prefix' => variable_get('uc_sign_after_amount', FALSE) ? '' : variable_get('uc_currency_sign', '$'),
    '#field_suffix' => variable_get('uc_sign_after_amount', FALSE) ? variable_get('uc_currency_sign', '$') : '',
  );
  $form['order']['minimum_qty'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum order quantity'),
    '#default_value' => isset($value->data['minimum_qty']) ? $value->data['minimum_qty'] : '',
    '#size' => 5,
    '#description' => t('If set, at least this many products must be in the cart for the coupon to be accepted.'),
  );
  $form['order']['minimum_qty_restrict'] = array(
    '#type' => 'checkbox',
    '#title' => t('Only count applicable products'),
    '#default_value' => isset($value->data['minimum_qty_restrict']) ? TRUE : FALSE,
    '#description' => t('If checked, only applicable products as configured below will count towards the minimum quantity or total.'),
  );
  $form['line_items'] = array(
    '#type' => 'fieldset',
    '#title' => t('Applicable line items'),
    '#description' => t('Select any line items to which this coupon should apply.'),
    '#collapsible' => TRUE,
    '#collapsed' => empty($value->data['line_items']),
  );
  $options = array();
  foreach (_uc_line_item_list() as $id => $line_item) {
    if (!in_array($id, array(
      'subtotal',
      'tax_subtotal',
      'total',
      'tax_display',
      'coupon',
      'tax',
    ))) {
      $options[$id] = $line_item['title'];
    }
  }
  $form['line_items']['line_items'] = array(
    '#type' => 'checkboxes',
    '#options' => $options,
    '#default_value' => isset($value->data['line_items']) ? $value->data['line_items'] : array(),
  );
  $form['product_types'] = array(
    '#type' => 'fieldset',
    '#title' => t('Applicable product classes'),
    '#description' => t('Selecting a class will apply this coupon to <strong>all</strong> products of the class, overriding other restrictions except for products or terms explicitly excluded below.'),
    '#collapsible' => TRUE,
    '#collapsed' => empty($value->data['product_types']),
  );
  $form['product_types']['product_types'] = array(
    '#type' => 'checkboxes',
    '#options' => array_map('check_plain', array_intersect_key(node_type_get_names(), drupal_map_assoc(uc_product_types()))),
    '#default_value' => isset($value->data['product_types']) ? $value->data['product_types'] : array(),
  );
  $form['products'] = array(
    '#type' => 'fieldset',
    '#title' => t('Applicable products'),
    '#description' => t('Enter one or more products below to restrict this coupon to a set of products, regardless of any product attributes. Discounts will apply to each matching product.'),
  );
  $form['products']['negate_products'] = array(
    '#type' => 'radios',
    '#default_value' => isset($value->data['negate_products']) ? 1 : 0,
    '#options' => array(
      0 => t('Apply coupon to products listed below.'),
      1 => t('Apply coupon to all products except those listed below.'),
    ),
    '#tree' => FALSE,
  );
  foreach ($value->data['products'] as $nid) {
    $title = db_query('SELECT title FROM {node} WHERE nid = :nid', array(
      ':nid' => $nid,
    ))
      ->fetchField();
    $form['products'][] = array(
      '#type' => 'textfield',
      '#default_value' => $title . ' [nid:' . $nid . ']',
      '#autocomplete_path' => 'admin/store/coupons/autocomplete/node',
      '#maxlength' => 300,
    );
  }
  $form['skus'] = array(
    '#type' => 'fieldset',
    '#title' => t('Applicable SKUs'),
    '#description' => t('Enter one or more SKUs below to restrict this coupon to a set of SKUs, allowing coupons to apply to specific products or attribute options. Discounts will apply to matching SKUs. Wildcards are supported, e.g. "E*" will match all products with SKUs beginning with E.'),
  );
  foreach ($value->data['skus'] as $sku) {
    $form['skus'][] = array(
      '#type' => 'textfield',
      '#default_value' => $sku,
    );
  }
  $form['terms'] = array(
    '#type' => 'fieldset',
    '#title' => t('Applicable taxonomy terms'),
    '#description' => t('Enter one or more taxonomy terms (categories) below to restrict this coupon to a set of products. Discounts will apply to all matching products with these terms.'),
    '#maxlength' => 300,
  );
  $form['terms']['negate_terms'] = array(
    '#type' => 'radios',
    '#default_value' => isset($value->data['negate_terms']) ? 1 : 0,
    '#options' => array(
      0 => t('Apply coupon to products with terms listed below.'),
      1 => t('Apply coupon to all products except those with terms listed below.'),
    ),
    '#tree' => FALSE,
  );
  foreach ($value->data['terms'] as $tid) {
    $name = db_query('SELECT name FROM {taxonomy_term_data} WHERE tid = :tid', array(
      ':tid' => $tid,
    ))
      ->fetchField();
    $form['terms'][] = array(
      '#type' => 'textfield',
      '#default_value' => $name . ' [tid:' . $tid . ']',
      '#autocomplete_path' => 'admin/store/coupons/autocomplete/term',
    );
  }
  $form['users'] = array(
    '#type' => 'fieldset',
    '#title' => t('User restrictions'),
    '#description' => t('Enter one or more user names and/or "anonymous users" below to restrict this coupon by user.'),
  );
  $form['users']['negate_users'] = array(
    '#type' => 'radios',
    '#default_value' => isset($value->data['negate_users']) ? 1 : 0,
    '#options' => array(
      0 => t('Allow this coupon only for users listed below.'),
      1 => t('Allow this coupon for all users except those listed below.'),
    ),
    '#tree' => FALSE,
  );
  foreach ($value->data['users'] as $uid) {
    $username = $uid ? db_query('SELECT name FROM {users} WHERE uid = :uid', array(
      ':uid' => $uid,
    ))
      ->fetchField() : t('anonymous users');
    $form['users'][] = array(
      '#type' => 'textfield',
      '#default_value' => $username . ' [uid:' . $uid . ']',
      '#autocomplete_path' => 'admin/store/coupons/autocomplete/user',
    );
  }
  $form['roles'] = array(
    '#type' => 'fieldset',
    '#title' => t('Role restrictions'),
    '#description' => t('Enter one or more role names below to restrict this coupon based on a user\'s roles.'),
  );
  $form['roles']['negate_roles'] = array(
    '#type' => 'radios',
    '#default_value' => isset($value->data['negate_roles']) ? 1 : 0,
    '#options' => array(
      0 => t('Allow this coupon only for users with the roles listed below.'),
      1 => t('Allow this coupon for users with all roles except those listed below.'),
    ),
    '#tree' => FALSE,
  );
  foreach ($value->data['roles'] as $role) {
    $form['roles'][] = array(
      '#type' => 'textfield',
      '#default_value' => $role,
      '#autocomplete_path' => 'admin/store/coupons/autocomplete/role',
    );
  }
  $form['combinations'] = array(
    '#type' => 'fieldset',
    '#title' => t('Combinations'),
    '#description' => t('Restrict the way this coupon may be combined with other coupons.'),
    '#collapsible' => TRUE,
    '#collapsed' => empty($value->data['combinations']) && !isset($value->data['negate_combinations']),
  );
  $form['combinations']['negate_combinations'] = array(
    '#type' => 'radios',
    '#default_value' => isset($value->data['negate_combinations']) ? 1 : 0,
    '#options' => array(
      0 => t('Allow this coupon to be combined only with those selected below. If you do not select any coupons, this coupon may not be combined.'),
      1 => t('Allow this coupon to be combined with all coupons except those selected below.'),
    ),
    '#tree' => FALSE,
  );
  $form['combinations']['combinations'] = array(
    '#type' => 'select',
    '#multiple' => 'true',
    '#options' => db_query('SELECT cid, name FROM {uc_coupons}')
      ->fetchAllKeyed(),
    '#default_value' => isset($value->data['combinations']) ? $value->data['combinations'] : array(),
  );

  // Add common settings and ajax functionality to restriction fieldsets.
  foreach ($ajax_fields as $field => $path) {
    $form[$field] = array_merge($form[$field], array(
      '#tree' => TRUE,
      '#collapsible' => TRUE,
      '#collapsed' => empty($value->data[$field]) && empty($form_state['ajax_submission']),
      '#prefix' => '<div id="ajax-' . $field . '">',
      '#suffix' => '</div>',
      'more_' . $field => array(
        '#type' => 'submit',
        '#value' => t('Add more items'),
        '#weight' => 1,
        '#name' => 'op_' . $field,
        '#limit_validation_errors' => array(),
        '#submit' => array(
          'uc_coupon_add_form_submit',
        ),
        '#ajax' => array(
          'callback' => 'uc_coupon_ajax_callback',
          'wrapper' => 'ajax-' . $field,
          'effect' => 'fade',
        ),
        '#tree' => FALSE,
      ),
    ));

    // Add blank fields if needed.
    for ($i = count($value->data[$field]); $i < $form_state['storage']['field_count'][$field]; $i++) {
      $form[$field][] = array(
        '#type' => 'textfield',
        '#autocomplete_path' => $path ? $path : NULL,
        '#maxlength' => $field == 'products' || $field == 'terms' ? 300 : 128,
      );
    }
  }
  $form['display'] = array(
    '#type' => 'fieldset',
    '#title' => t('Display options'),
    '#description' => t('Options governing the way this coupon appears to users.'),
    '#collapsible' => TRUE,
    '#collapsed' => empty($value->data['line_item_format']) || empty($value->data['apply_message']),
  );
  $form['display']['line_item_format'] = array(
    '#type' => 'textfield',
    '#size' => 60,
    '#title' => t('Line item title format.'),
    '#description' => t('The title for this coupon when displayed in the cart and as a line-item.
    		Leave blank to use the default format as specified on the main coupon settings page.'),
    '#default_value' => empty($value->data['line_item_format']) ? '' : $value->data['line_item_format'],
  );
  $form['display']['apply_message'] = array(
    '#type' => 'textarea',
    '#rows' => 3,
    '#title' => t('Message'),
    '#description' => t('The message to be displayed when this coupon is applied. Leave blank for a default message.'),
    '#default_value' => empty($value->data['apply_message']) ? '' : $value->data['apply_message'],
  );
  if (module_exists('token')) {
    $form['display']['replacement_patterns'] = array(
      '#type' => 'item',
      '#title' => t('Replacement Patterns'),
      '#markup' => theme('token_tree', array(
        'token_types' => array(
          'uc_coupon',
        ),
      )),
    );
  }
  $form['fields'] = array(
    '#type' => 'fieldset',
    '#title' => t('Custom fields'),
    '#description' => t('Custom fields can be configured at !link.', array(
      '!link' => l('admin/store/settings/coupon/fields', 'admin/store/settings/coupon/fields'),
    )),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  if (count(field_info_instances('uc_coupon', 'uc_coupon')) == 0) {
    $form['fields']['#description'] = t('There are no custom fields defined.') . ' ' . $form['fields']['#description'];
    $form['fields']['#collapsed'] = TRUE;
  }
  field_attach_form('uc_coupon', $coupon, $form['fields'], $form_state);
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save coupon'),
    '#weight' => 10,
  );
  return $form;
}