You are here

uc_price_per_role.module in Ubercart Price Per Role 5

Same filename and directory in other branches
  1. 6 uc_price_per_role.module
  2. 7 uc_price_per_role.module

File

uc_price_per_role.module
View source
<?php

/**
 * Implementation of hook_perm().
 */
function uc_price_per_role_perm() {
  return array(
    'access price selection block',
  );
}

/**
 * Implementation of hook_menu().
 */
function uc_price_per_role_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/store/settings/price_per_role',
      'title' => t('Price per role settings'),
      'description' => t('Configure price per role settings.'),
      'access' => user_access('administer store'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_price_per_role_settings_form',
      ),
      'type' => MENU_NORMAL_ITEM,
    );
  }
  else {
    if (module_exists('uc_attribute') && arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'edit') {
      $node = node_load(arg(1));
      if ($node->nid && in_array($node->type, module_invoke_all('product_types'))) {
        $items[] = array(
          'path' => 'node/' . arg(1) . '/edit/option_prices',
          'title' => t('Option prices'),
          'callback' => 'drupal_get_form',
          'callback arguments' => array(
            'uc_price_per_role_option_prices_form',
            arg(1),
          ),
          'weight' => 2.1,
          'type' => MENU_LOCAL_TASK,
        );
      }
    }
  }
  return $items;
}
function uc_price_per_role_settings_form() {
  $enabled = variable_get('uc_price_per_role_enabled', array());
  $weights = variable_get('uc_price_per_role_weights', array());
  $roles = user_roles();
  foreach (array_keys($roles) as $rid) {
    if (!isset($weights[$rid])) {
      $weights[$rid] = 0;
    }
  }
  asort($weights);
  $form['help'] = array(
    '#value' => t('Enable roles that require separate pricing. For users with more than one matching role, the lightest weight role that has a price available will be used.'),
  );
  $form['fields']['#tree'] = TRUE;
  foreach ($weights as $rid => $weight) {
    $form['fields'][$rid]['role'] = array(
      '#value' => $roles[$rid],
    );
    $form['fields'][$rid]['enabled'] = array(
      '#type' => 'checkbox',
      '#default_value' => $enabled[$rid],
    );
    $form['fields'][$rid]['weight'] = array(
      '#type' => 'weight',
      '#delta' => 5,
      '#default_value' => $weight,
    );
  }
  $form['buttons']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save configuration'),
  );
  return $form;
}
function theme_uc_price_per_role_settings_form($form) {
  $output = drupal_render($form['help']);
  $header = array(
    t('Enable'),
    t('Role'),
    t('Weight'),
  );
  $rows = array();
  foreach (element_children($form['fields']) as $field) {
    $row = array();
    $row[] = drupal_render($form['fields'][$field]['enabled']);
    $row[] = drupal_render($form['fields'][$field]['role']);
    $row[] = drupal_render($form['fields'][$field]['weight']);
    $rows[] = $row;
  }
  $output .= theme('table', $header, $rows);
  $output .= drupal_render($form);
  return $output;
}
function uc_price_per_role_settings_form_submit($form_id, $form_values) {
  $enabled = array();
  $weights = array();
  foreach ($form_values['fields'] as $rid => $field) {
    $enabled[$rid] = $field['enabled'];
    $weights[$rid] = $field['weight'];
  }
  variable_set('uc_price_per_role_enabled', $enabled);
  variable_set('uc_price_per_role_weights', $weights);
}

/**
 * Implementation of hook_form_alter().
 */
function uc_price_per_role_form_alter($form_id, &$form) {
  global $user;
  if ($form['#base'] == 'node_form' && isset($form['base']['prices'])) {
    $enabled = variable_get('uc_price_per_role_enabled', array());
    $form['base']['role_prices'] = array(
      '#weight' => 6,
      '#theme' => 'uc_price_per_role_product_prices',
      '#tree' => TRUE,
    );
    foreach (user_roles() as $rid => $role) {
      if ($enabled[$rid]) {
        $form['base']['role_prices'][$rid] = array(
          '#type' => 'textfield',
          '#title' => t('%role price', array(
            '%role' => $role,
          )),
          '#default_value' => $form['#node']->role_prices[$rid],
          '#description' => t('Purchase price for %role users.', array(
            '%role' => $role,
          )),
          '#size' => 20,
          '#maxlength' => 35,
          '#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', '$') : '',
        );
      }
    }
  }
  else {
    if (strpos($form_id, 'add_to_cart_form')) {

      // Modify product form attribute option prices.
      if (module_exists('uc_attribute') && variable_get('uc_attribute_option_price_format', 'adjustment') != 'none') {
        $nid = intval($form['nid']['#value']);
        $qty = intval($form['qty']['#value']);
        if (!$qty) {
          $qty = 1;
        }
        $priced_attributes = uc_attribute_priced_attributes($nid);
        $role_prices = uc_price_per_role_load_option_prices($nid);
        foreach (element_children($form['attributes']) as $aid) {
          if (isset($form['attributes'][$aid]['#options'])) {
            $attribute = uc_attribute_load($aid, $nid, 'product');
            foreach (array_keys($form['attributes'][$aid]['#options']) as $oid) {
              $price = uc_price_per_role_find_price($role_prices[$oid]);
              if ($price !== FALSE) {
                switch (variable_get('uc_attribute_option_price_format', 'adjustment')) {
                  case 'total':
                    $display_price = in_array($aid, $priced_attributes) ? ', ' . uc_currency_format(($node->sell_price + $price) * $qty) : '';
                    if (count($priced_attributes) == 1) {
                      break;
                    }
                  case 'adjustment':
                    $display_price = $price != 0 ? ', ' . ($price > 0 ? '+' : '') . uc_currency_format($price * $qty) : '';
                    break;
                }
                $form['attributes'][$aid]['#options'][$oid] = $attribute->options[$oid]->name . $display_price;
              }
            }
          }
        }
      }
    }
  }
}
function theme_uc_price_per_role_product_prices($prices) {
  $output = '<table><tr>';
  foreach (element_children($prices) as $rid) {
    $output .= '<td>' . drupal_render($prices[$rid]) . '</td>';
  }
  $output .= "</table>\n";
  return $output;
}

/**
 * Implementation of hook_nodeapi().
 */
function uc_price_per_role_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  global $user;
  if (in_array($node->type, module_invoke_all('product_types'))) {
    switch ($op) {
      case 'validate':
        foreach ($node->role_prices as $rid => $price) {
          if (!empty($price) && !is_numeric($price)) {
            form_set_error('role_prices][' . $rid, t('Price must be a number.'));
          }
        }
        break;
      case 'insert':
      case 'update':
        db_query("DELETE FROM {uc_price_per_role_prices} WHERE nid = %d", $node->nid);
        if (is_array($node->role_prices)) {
          foreach ($node->role_prices as $rid => $price) {
            if (is_numeric($price)) {
              $rpid = db_next_id('{uc_price_per_role_prices}_rpid');
              db_query("INSERT INTO {uc_price_per_role_prices} (rpid, vid, nid, rid, price) VALUES (%d, %d, %d, %d, %f)", $rpid, $node->vid, $node->nid, $rid, $price);
            }
          }
        }
        break;
      case 'load':
        $result = db_query("SELECT rid, price FROM {uc_price_per_role_prices} WHERE vid = %d", $node->vid);
        $prices = array();
        while ($row = db_fetch_object($result)) {
          $prices[$row->rid] = $row->price;
        }
        $price = uc_price_per_role_find_price($prices);
        if ($price !== FALSE) {
          $node->sell_price = $price;
        }
        return array(
          'role_prices' => $prices,
        );
      case 'prepare':

        // Reload original price for editing.
        $node->sell_price = db_result(db_query('SELECT sell_price FROM {uc_products} WHERE vid = %d', $node->vid));
        break;
      case 'delete':
        db_query("DELETE FROM {uc_price_per_role_prices} WHERE nid = %d", $node->nid);
        break;
      case 'delete revision':
        db_query("DELETE FROM {uc_price_per_role_prices} WHERE vid = %d", $node->vid);
        break;
    }
  }
}

/**
 * Implementation of hook_cart_item().
 */
function uc_price_per_role_cart_item($op, &$item) {
  global $user;
  if (module_exists('uc_attribute')) {
    switch ($op) {
      case 'load':
        $role_prices = uc_price_per_role_load_option_prices($item->nid);
        foreach (_uc_cart_product_get_options($item) as $option) {
          $oid = $option['oid'];
          $price = uc_price_per_role_find_price($role_prices[$oid]);
          if ($price !== FALSE) {
            $item->price += $price - $option['price'];
          }
        }
    }
  }
}
function uc_price_per_role_option_prices_form($nid) {
  $product = node_load($nid);
  drupal_set_title(check_plain($product->title));
  $role_prices = uc_price_per_role_load_option_prices($nid);
  $enabled = array_keys(array_filter(variable_get('uc_price_per_role_enabled', array())));
  $form['help'] = array(
    '#value' => t('Leave any box blank to use the standard price for the option.'),
  );
  foreach (uc_product_get_attributes($nid) as $aid => $attribute) {
    $form['attributes'][$aid]['name'] = array(
      '#value' => $attribute->name,
    );
    $form['attributes'][$aid]['aid'] = array(
      '#type' => 'hidden',
      '#value' => $attribute->aid,
    );
    $form['attributes'][$aid]['ordering'] = array(
      '#type' => 'value',
      '#value' => $attribute->ordering,
    );
    $form['attributes'][$aid]['options'] = array(
      '#weight' => 2,
    );
    $base_attr = uc_attribute_load($attribute->aid);
    if ($base_attr->options) {
      $result = db_query("SELECT ao.aid, ao.oid, ao.name, ao.price AS default_price, ao.ordering AS default_ordering, po.price, po.ordering, po.ordering IS NULL AS null_order FROM {uc_attribute_options} AS ao LEFT JOIN {uc_product_options} AS po ON ao.oid = po.oid AND po.nid = %d WHERE aid = %d ORDER BY null_order, po.ordering, default_ordering, ao.name", $nid, $attribute->aid);
      while ($option = db_fetch_object($result)) {
        $oid = $option->oid;
        $form['attributes'][$aid]['options'][$oid]['name'] = array(
          '#value' => $option->name,
        );
        $form['attributes'][$aid]['options'][$oid]['price'] = array(
          '#value' => uc_currency_format(is_null($option->price) ? $option->default_price : $option->price),
        );
        foreach ($enabled as $rid) {
          $form['attributes'][$aid]['options'][$oid]['role_prices'][$rid] = array(
            '#type' => 'textfield',
            '#default_value' => isset($role_prices[$oid][$rid]) ? $role_prices[$oid][$rid] : '',
            '#size' => 6,
          );
        }
      }
    }
    else {
      $form['attributes'][$aid]['default'] = array(
        '#value' => t('This attribute does not have any options.'),
      );
    }
  }
  if (!empty($form['attributes'])) {
    $form['attributes']['#tree'] = TRUE;
    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Submit'),
      '#weight' => 10,
    );
  }
  $form['nid'] = array(
    '#type' => 'value',
    '#value' => $nid,
  );
  return $form;
}
function theme_uc_price_per_role_option_prices_form($form) {
  $roles = user_roles();
  $enabled = array_keys(array_filter(variable_get('uc_price_per_role_enabled', array())));
  $header = array(
    t('Attribute'),
    t('Option'),
    t('Standard price'),
  );
  foreach ($enabled as $rid) {
    $header[] = t('%role price', array(
      '%role' => $roles[$rid],
    ));
  }
  foreach (element_children($form['attributes']) as $key) {
    $row = array();
    $row[] = array(
      'data' => drupal_render($form['attributes'][$key]['aid']) . drupal_render($form['attributes'][$key]['name']),
      'class' => 'attribute',
    );
    if (element_children($form['attributes'][$key]['options'])) {
      foreach (element_children($form['attributes'][$key]['options']) as $oid) {
        $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['name']);
        $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['price']);
        foreach ($enabled as $rid) {
          $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['role_prices'][$rid]);
        }
        $rows[] = $row;
        $row = array(
          '',
        );
      }
      unset($form['attributes'][$key]['default']);
    }
    else {
      $row[] = array(
        'data' => drupal_render($form['attributes'][$key]['default']),
        'colspan' => count($enabled) + 3,
      );
      $rows[] = $row;
    }
    $rows[] = array(
      array(
        'data' => '<hr />',
        'colspan' => count($enabled) + 3,
      ),
    );
  }
  if (count($rows) == 0) {
    $rows[] = array(
      array(
        'data' => t('This product does not have any attributes.'),
        'colspan' => count($enabled) + 3,
      ),
    );
  }
  $output = drupal_render($form['help']) . theme('table', $header, $rows, array(
    'class' => 'product_attributes',
  )) . drupal_render($form);
  return $output;
}
function uc_price_per_role_option_prices_form_submit($form_id, $form_values) {
  foreach ($form_values['attributes'] as $attribute) {
    if (is_array($attribute['options'])) {
      foreach ($attribute['options'] as $oid => $option) {
        db_query("DELETE FROM {uc_price_per_role_option_prices} WHERE nid = %d AND oid = %d", $form_values['nid'], $oid);
        foreach ($option['role_prices'] as $rid => $price) {
          if (is_numeric($price)) {
            $opid = db_next_id('{uc_price_per_role_option_prices}_opid');
            db_query("INSERT INTO {uc_price_per_role_option_prices} (opid, nid, oid, rid, price) VALUES (%d, %d, %d, %d, %f)", $opid, $form_values['nid'], $oid, $rid, $price);
          }
        }
      }
    }
  }
  drupal_set_message(t('The option prices have been saved.'));
}

/**
 * Load per-role option price data for the supplied node ID.
 */
function uc_price_per_role_load_option_prices($nid) {
  $prices = array();
  $result = db_query("SELECT oid, rid, price FROM {uc_price_per_role_option_prices} WHERE nid = %d", $nid);
  while ($row = db_fetch_object($result)) {
    $prices[$row->oid][$row->rid] = $row->price;
  }
  return $prices;
}

/**
 * Find the price for the current user from the supplied price array, or return FALSE if no price was found.
 */
function uc_price_per_role_find_price($prices) {
  global $user;
  $enabled = variable_get('uc_price_per_role_enabled', array());
  $weights = variable_get('uc_price_per_role_weights', array());
  asort($weights);

  // Check for a chosen role in the price selection block first.
  if (user_access('access price selection block') && $_SESSION['price_role'] && isset($prices[$_SESSION['price_role']])) {
    return $prices[$_SESSION['price_role']];
  }

  // Otherwise, look for a matching role.
  foreach ($weights as $rid => $weight) {
    if (isset($user->roles[$rid]) && $enabled[$rid] && isset($prices[$rid])) {
      return $prices[$rid];
    }
  }
  return FALSE;
}

/**
 * Implementation of hook_block().
 */
function uc_price_per_role_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0]['info'] = t('Pricing selection');
    return $blocks;
  }
  else {
    if ($op == 'view' && $delta == 0 && user_access('access price selection block')) {
      $block = array(
        'subject' => t('Pricing selection'),
        'content' => drupal_get_form('uc_price_per_role_switch_form'),
      );
      return $block;
    }
  }
}

/**
 * Form to allow authorised users to select which role is used for pricing.
 */
function uc_price_per_role_switch_form() {
  $enabled = variable_get('uc_price_per_role_enabled', array());
  $weights = variable_get('uc_price_per_role_weights', array());
  $roles = user_roles();
  asort($weights);
  $options = array(
    '' => 'Default',
  );
  foreach ($weights as $rid => $weight) {
    if ($enabled[$rid]) {
      $options[$rid] = $roles[$rid];
    }
  }
  $form['role'] = array(
    '#type' => 'select',
    '#title' => 'Role',
    '#options' => $options,
    '#default_value' => $_SESSION['price_role'],
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Select pricing role'),
  );
  return $form;
}
function uc_price_per_role_switch_form_submit($form_id, $form_values) {
  if (user_access('access price selection block')) {
    $_SESSION['price_role'] = $form_values['role'];
  }
}

Functions