View source
<?php
define('UC_OUT_OF_STOCK_DEFAULT_HTML', t('<span style="color: red;">Out of stock</span>'));
function uc_out_of_stock_form_alter(&$form, $form_state, $form_id) {
$forms = array(
'uc_product_add_to_cart_form',
'uc_catalog_buy_it_now_form',
);
foreach ($forms as $id) {
if (substr($form_id, 0, strlen($id)) == $id) {
drupal_add_js(drupal_get_path('module', 'uc_out_of_stock') . '/uc_out_of_stock.js');
drupal_add_css(drupal_get_path('module', 'uc_out_of_stock') . '/uc_out_of_stock.css');
$form['#validate'][] = 'uc_out_of_stock_validate_form_addtocart';
}
}
if ($form_id == 'uc_cart_view_form') {
$form['#validate'][] = 'uc_out_of_stock_validate_form_cart';
}
if ($form_id == 'uc_cart_checkout_form' || $form_id == 'uc_cart_checkout_review_form') {
$form['#validate'][] = 'uc_out_of_stock_validate_form_checkout';
}
}
function uc_out_of_stock_menu() {
$items = array();
$items['admin/store/settings/uc_out_of_stock'] = array(
'title' => 'Out of Stock Settings',
'access arguments' => array(
'administer store',
),
'description' => 'Configure out of stock settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_out_of_stock_settings',
),
'type' => MENU_NORMAL_ITEM,
);
$items['uc_out_of_stock/query'] = array(
'title' => 'stock query',
'page callback' => 'uc_out_of_stock_query',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function uc_out_of_stock_getstockinfo_from_model($model) {
$stock = db_result(db_query("SELECT ups.stock FROM {uc_product_stock} ups WHERE ups.active = 1 AND ups.sku = '%s'", $model));
if (is_numeric($stock)) {
$stockinfo['stock'] = $stock;
$stockinfo['model'] = $model;
}
return $stockinfo;
}
function uc_out_of_stock_getstockinfo($nid, $attrs) {
$query_main_sku = TRUE;
if (module_exists('uc_attribute')) {
$post_attrs = count($attrs);
$sql = "SELECT %s FROM {uc_product_adjustments} upa LEFT JOIN {uc_product_stock} ups ON ups.sku = upa.model WHERE upa.nid = %d";
$db_attrs = db_result(db_query($sql, 'COUNT(*)', $nid));
if ($post_attrs && $db_attrs > 0) {
$result = db_query($sql, '*', $nid);
while ($row = db_fetch_object($result)) {
$combination = unserialize($row->combination);
if (isset($row->sku) && $combination == $attrs) {
$query_main_sku = FALSE;
if ($row->active) {
$stockinfo['stock'] = $row->stock;
$stockinfo['model'] = $row->model;
}
}
}
}
else {
if ($post_attrs == 0 && $db_attrs > 0) {
$query_main_sku = FALSE;
}
}
}
if ($query_main_sku) {
$result = db_query("SELECT * FROM {uc_products} up LEFT JOIN {uc_product_stock} ups ON ups.sku = up.model WHERE up.nid = %d AND ups.active = 1", $nid);
while ($row = db_fetch_object($result)) {
$stockinfo['stock'] = $row->stock;
$stockinfo['model'] = $row->model;
}
}
return $stockinfo;
}
function uc_out_of_stock_query() {
$response = array();
$attrs = array();
$nid = $_POST['nid'];
foreach ($_POST as $key => $value) {
if (substr($key, 0, 4) == 'attr') {
$attrs[substr($key, 4)] = $value;
}
}
$stockinfo = uc_out_of_stock_getstockinfo($nid, $attrs);
if ($stockinfo) {
$response['stock'] = $stockinfo['stock'];
if ($response['stock'] <= 0) {
$response['html'] = check_markup(variable_get('uc_out_of_stock_text', UC_OUT_OF_STOCK_DEFAULT_HTML), variable_get('uc_out_of_stock_format', FILTER_FORMAT_DEFAULT), FALSE);
}
}
if (count($response)) {
print implode('|', $response);
}
}
function uc_out_of_stock_settings() {
$text = check_markup(variable_get('uc_out_of_stock_text', UC_OUT_OF_STOCK_DEFAULT_HTML), variable_get('uc_out_of_stock_format', FILTER_FORMAT_DEFAULT), FALSE);
$description = t('<div class="description">This is the value below rendered as you would expect to see it</div>');
$text = '<div style="border: 1px solid lightgrey; padding: 10px;">' . $text . '</div>' . $description;
$form['uc_out_of_stock_demo'] = array(
'#type' => 'markup',
'#value' => $text,
);
$form['uc_out_of_stock_text'] = array(
'#type' => 'textarea',
'#title' => t('Out of stock replacement HTML'),
'#default_value' => variable_get('uc_out_of_stock_text', UC_OUT_OF_STOCK_DEFAULT_HTML),
'#description' => t('The HTML that will replace the Add To Cart button if no stock is available.'),
);
$form['uc_out_of_stock_format'] = filter_form(variable_get('uc_out_of_stock_format', FILTER_FORMAT_DEFAULT), NULL, array(
'uc_out_of_stock_format',
));
return system_settings_form($form);
}
function uc_out_of_stock_validate_addtocart($nid, $attrs, $qty_add) {
$error = FALSE;
$stockinfo = uc_out_of_stock_getstockinfo($nid, $attrs);
if ($stockinfo) {
if ($stockinfo['stock'] <= 0) {
$error = _uc_out_of_stock_get_error('out_of_stock', $nid, $attrs, $stockinfo['stock']);
}
else {
$qty = 0;
$items = uc_cart_get_contents();
foreach ($items as $item) {
if ($item->nid == $nid && $stockinfo['model'] == $item->model) {
$qty += $item->qty;
}
}
if ($stockinfo['stock'] - ($qty + $qty_add) < 0) {
$error = _uc_out_of_stock_get_error('not_enough', $nid, $attrs, $stockinfo['stock'], $qty);
}
}
}
return $error;
}
function uc_out_of_stock_validate_form_addtocart($form, &$form_state) {
$class = $form_state['clicked_button']['#attributes']['class'];
if ($class == 'node-add-to-cart' || $class == 'list-add-to-cart') {
$attrs = $form_state['values']['attributes'];
$nid = $form_state['values']['nid'];
$qty = $form_state['values']['qty'] ? $form_state['values']['qty'] : 1;
$error = uc_out_of_stock_validate_addtocart($nid, $attrs, $qty);
if ($error !== FALSE) {
form_set_error('uc_out_of_stock', $error['msg']);
}
}
}
function uc_out_of_stock_validate_cart_items($items, $page = 'cart') {
if (!is_array($items)) {
return;
}
$cart_items = array();
$stored_cart_items = uc_cart_get_contents();
foreach ($items as $k => $item) {
$item = (object) $item;
if (!is_numeric($item->remove) || !$item->remove) {
if (is_string($item->data)) {
$item->data = unserialize($item->data);
}
if (!isset($item->model)) {
$stored_item = $stored_cart_items[$k];
if ($item->nid == $stored_item->nid && $item->data == $stored_item->data) {
$model = $stored_item->model;
}
else {
foreach ($stored_cart_items as $stored_item) {
if ($item->nid == $stored_item->nid && $item->data == $stored_item->data) {
$model = $stored_item->model;
}
}
}
$item->model = $model;
}
$cart_items[$item->model]['item'] = $item;
$cart_items[$item->model]['qty'] += $item->qty;
$cart_items[$item->model]['key'] = $k;
}
}
foreach ($cart_items as $model => $cart_item) {
$item = $cart_item['item'];
$stockinfo = uc_out_of_stock_getstockinfo_from_model($model);
if ($stockinfo) {
if ($stockinfo['stock'] - $cart_item['qty'] < 0) {
$qty = 0;
if ($page == 'checkout') {
$qty = $cart_item['qty'];
}
$error = _uc_out_of_stock_get_error('not_enough', $item->nid, $item->data['attributes'], $stockinfo['stock'], $qty);
form_set_error("items][{$cart_item['key']}][qty", $error['msg']);
}
}
}
}
function uc_out_of_stock_validate_form_checkout($form, &$form_state) {
$items = uc_cart_get_contents();
uc_out_of_stock_validate_cart_items($items, 'checkout');
}
function uc_out_of_stock_validate_form_cart($form, &$form_state) {
$items = $form_state['values']['items'];
uc_out_of_stock_validate_cart_items($items, 'cart');
}
function _uc_out_of_stock_get_error($type, $nid, $attrs, $stock, $qty = 0) {
$product = node_load($nid);
if (count($attrs)) {
foreach ($attrs as $attr_id => $option_id) {
$attr = uc_attribute_load($attr_id);
$option = uc_attribute_option_load($option_id);
$attr_names[] = $attr->name;
$option_names[] = $option->name;
}
}
$error['stock'] = $stock;
$error['qty_in_cart'] = $qty;
$error['type'] = $type;
$error['product'] = $product->title;
if (count($attrs)) {
$error['attributes'] = implode('/', $attr_names);
$error['options'] = implode('/', $option_names);
}
if ($type == 'out_of_stock') {
if (count($attrs)) {
$error['msg'] = t("We're sorry. The product @product (@options) is out of stock. Please consider trying this product with a different @attributes.", array(
'@product' => $error['product'],
'@attributes' => $error['attributes'],
'@options' => $error['options'],
));
}
else {
$error['msg'] = t("We're sorry. The product @product is out of stock.", array(
'@product' => $error['product'],
));
}
}
if ($type == 'not_enough') {
if (count($attrs)) {
$error['msg'] = t("We're sorry. We have now only @qty of the product @product (@options) left in stock.", array(
'@qty' => format_plural($error['stock'], '1 unit', '@count units'),
'@product' => $error['product'],
'@options' => $error['options'],
));
}
else {
$error['msg'] = t("We're sorry. We have now only @qty of the product @product left in stock.", array(
'@qty' => format_plural($error['stock'], '1 unit', '@count units'),
'@product' => $error['product'],
));
}
if ($error['qty_in_cart']) {
$error['msg'] .= ' ' . t("You have currently @qty in your <a href=\"@cart-url\">shopping cart</a>.", array(
'@qty' => format_plural($error['qty_in_cart'], '1 unit', '@count units'),
'@cart-url' => url('cart'),
));
}
}
return $error;
}